嗨,大家好,我是萍乡李兴球。在萍乡专业教青少儿的Python计算机语言。
话说公元3721年2月5号,一艘编号为1024768的“人造地球”飞船在宇宙中游荡。所谓的“人造地球”,就是完美地模拟了地球上的生态环境,人们在里面可以自给自足,只要输入能量就能全自动运行的一艘宇宙飞船,其内核是迷你黑洞,能源源不断地产生能量。它已经实现量产,有一个火星般大的3D打印机在不断地生产着人造地球。巧合的是,这台3D打印机的后台运维程序是用Python编写的。那个时候,Python已经发展到了32768版本了。为了纪念Python计算机语言的设计者,所以并没有改变Python计算机语言的名字。更为奇妙的是,Python32768版竟然还能兼容2021年2月5号的程序。这是由于它早已经实现了超级人工智能,只要一扫,它就能调用相应年代版本的编译器对程序进行解释,从而运行出程序的结果。
那个时候的人造地球,有的只有100个足球场那么大,有的有一个萍乡那么大,萍乡有多大?自己百度一下吧。还有的有一个江西省那么大。不过它们模拟的重力都是地球的重力,还模拟了春夏秋冬。当然,是全自动运行的程序在控制着。如果距离恒星太近了,那么会改变方向。如果离黑洞到了一定的距离,还会对黑洞进行分析。对规模不大的黑洞会采取捕获措施,即把它的能量吸光!下面是一个原始人编写的Python程序。在程序中,就会判断是否离太阳太近,如果太近,就会反弹回去。当然,读者可以把碰到黑洞的情形也自己发挥一下,我这里就抛个砖,希望引个玉出来。程序如下所示:
""" 流浪地球作业之类的练习。 在下面的程序中,新建了一个叫Earth的类。它继承自Turtle。 实例化Earth后,让它不断地移动,碰到边缘会反弹,碰到红色的小太阳们也会反转方向。 这4个红色的点,表示太阳。这4个太阳的代码非常相似,由于没有给它们写一个类,导致代码较长。 请读者新建一个叫Sun太阳的类,让所有的太阳都从这个类进行实例化。 """ import time from random import uniform,randint from turtle import Turtle,Screen class Earth(Turtle): def __init__(self): Turtle.__init__(self,visible=False,shape='circle') self.penup() # 抬起笔来 self.speed(0) # 速度最快 self.color('blue') # 蓝 色 的 self.setheading(uniform(1,360)) # 随机方向 self.sw = self.screen.window_width() # 屏幕宽度 self.sh = self.screen.window_height() # 屏幕高度 self.showturtle() def detect(self,tag): """检测同一类标签的对象,返回最短距离值""" # 所有的有label属性的海龟对象 objs = [t for t in self.screen.turtles() if hasattr(t,'label')] # 所有的label属性的值为tag的对象 objs = [t for t in objs if t.label==tag] # 所有的sun和它们到self的距离所形成的字典 d = {sun: sun.distance(self) for sun in objs} suns = sorted(d, key=d.get) # 按值排序,返回suns列表 return d.get(suns[0]) # 返回最小距离 def bounce_on_edge(self): """碰到边缘就反弹""" if abs(self.ycor()) > self.sh/2: # 超过上下边缘 self.setheading(-self.heading()) if abs(self.xcor()) > self.sw/2: # 超过左右边缘 self.setheading(180-self.heading()) if __name__ == "__main__": screen = Screen() screen.bgcolor('black') screen.delay(0) sun1 = Turtle(shape='circle') sun1.penup() sun1.goto(132,76) sun1.label = 'sun' sun1.color('red') sun2 = Turtle(shape='circle') sun2.penup() sun2.goto(-132,76) sun2.label = 'sun' sun2.color('red') sun3 = Turtle(shape='circle') sun3.penup() sun3.goto(-132,-76) sun3.label = 'sun' sun3.color('red') sun4 = Turtle(shape='circle') sun4.penup() sun4.goto(132,-76) sun4.label = 'sun' sun4.color('red') e = Earth() while True: e.fd(1) e.bounce_on_edge() 到恒星的距离 = e.detect('sun') if 到恒星的距离 < 20: a = 180 + randint(-10,10) e.right(a) time.sleep(0.001)
我们看到,在这个Python程序中,设计了一个Earth类。这个类是继承自海龟即Turtle类的。在这个类中最复杂的方法是detect方法。它有一个叫tag的参数。哎呀呀,这是什么意思。这个tag是标签的意思。它是检测同一类“标签”的对象的。如果离哪个最近,就返回到那个对象的距离。在这个方法中的第一个列表推导式,是把所有的有label属性的海龟对象形成一个列表。第二个列表推导式是把所有的label属性的值为tag的海龟对象形成一个列表。在这个方法中接下来有一个字典推导式。它的意思是每一个有label属性并且其值为tag的海龟对象,它们到self的距离的一一映射。在本例中,这些是一个个的太阳,也就是检测每个太阳到地球的距离,所形成的字典。键是太阳,值是它们到地球的距离。为了返回最小的值,对字典进行了排序,其实对字典进行排序是没有意义的。因为它天生无序。在detect方法中,用的b = sorted(d, key=d.get)语句。sorted命令是对序列进行排序的。它的关键词参数key指定用哪个值进行排序,返回的是一个列表。这个列表中就是一个个的小太阳了。其中列表的第一太阳,它离地球的距离就是最近的!
设计好了Earth类后。对它进行了测试,用Turtle命令新建了4个红色的小太阳。它们其实都是一个个海龟对象。注意给每个小太阳都自定义了一个叫label的属性。这代表的就是它的标签,在程序中是给它赋值为’sun’。在进入while循环之前,实例化了一个叫e的地球。在while循环中,让e不断地移动,碰到边缘就反弹。还会判断e到每个太阳的距离,如果到其中之一的距离小于20,那么就让e大概向后转。
好了,今天的程序讲解到这里大概结束了。我们在祖国的青山上继续等你哟。
看看你编写的类是不是像下面这样的,下面参考答案:
""" 流浪地球作业参考答案。 在下面的程序中,新建了一个叫Earth的类。它继承自Turtle。 实例化Earth后,让它不断地移动,碰到边缘会反弹,碰到红色的小太阳们也会反转方向。 有一个叫Sun太阳的类,所有的太阳都是从这个类进行实例化的。 更多Python创意程序: https://www.lixingqiu.com """ import time from random import uniform,randint from turtle import Turtle,Screen class Earth(Turtle): """继承自Turtle类的Earth类""" def __init__(self): Turtle.__init__(self,visible=False,shape='circle') self.penup() # 抬起笔来 self.speed(0) # 速度最快 self.color('blue') # 蓝 色 的 self.setheading(uniform(1,360)) # 随机方向 self.sw = self.screen.window_width() # 屏幕宽度 self.sh = self.screen.window_height() # 屏幕高度 self.showturtle() def detect(self,tag): """检测同一类标签的对象,返回最短距离值""" # 所有的有label属性的海龟对象 objs = [t for t in self.screen.turtles() if hasattr(t,'label')] # 所有的label属性的值为tag的对象 objs = [t for t in objs if t.label==tag] # 所有的sun和它们到self的距离所形成的字典 d = {sun: sun.distance(self) for sun in objs} suns = sorted(d, key=d.get) # 按值排序,返回suns列表 return d.get(suns[0]) # 返回最小距离 def bounce_on_edge(self): """碰到边缘就反弹""" if abs(self.ycor()) > self.sh/2: # 超过上下边缘 self.setheading(-self.heading()) if abs(self.xcor()) > self.sw/2: # 超过左右边缘 self.setheading(180-self.heading()) class Sun(Turtle): """继承自Turtle类的Sun类""" def __init__(self,x,y): Turtle.__init__(self,shape='circle',visible=False) self.penup() self.speed(0) self.label='sun' self.color('red') self.goto(x,y) self.showturtle() def main(): """主要执行函数""" cors = [(132,76),(-132,76),(-132,-76),(132,-76)] [Sun(x,y) for x,y in cors] # 按坐标实例化太阳 screen = Screen() screen.delay(0) screen.bgcolor('black') e = Earth() # 实例化一个地球 while True: e.fd(1) e.bounce_on_edge() 到恒星的距离 = e.detect('sun') # 检测到每一个太阳的距离 if 到恒星的距离 < 20: a = 180 + randint(-10,10) e.right(a) time.sleep(0.001) if __name__ == "__main__": main()
发表评论