楼主: 爱错星座
12645 7

[Python] 自学《Think Python》之第二个程序——用“海龟”画一个圆弧 [推广有奖]

  • 2关注
  • 2粉丝

大专生

71%

还不是VIP/贵宾

-

威望
0
论坛币
555 个
通用积分
0
学术水平
15 点
热心指数
16 点
信用等级
13 点
经验
3181 点
帖子
53
精华
0
在线时间
57 小时
注册时间
2012-3-17
最后登录
2021-2-20

相似文件 换一批

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

求职就业群
赵安豆老师微信:zhaoandou666

经管之家联合CDA

送您一个全额奖学金名额~ !

感谢您参与论坛问题回答

经管之家送您两个论坛币!

+2 论坛币

源代码+代码解释+小结



       要用这个程序,首先需要下载一个叫swampy的包(package),也就是一个文件夹或者说是一套模块,其中包含了很多的函数。关于package的安装只需提一点,由于模块不大,最好直接安装默认的路径(也就是直接打开shell或者dos提示符的工作路径)里,确保只有一个叫swampy文件夹,里面都是相应的py文件。

      好,开始我们的问题,在书中的第四章,整章作为一个接口学习的案例。

      问题:用下载的swampy中的TurtleWorld模块画出一个正方形,正多边形,圆形,一段弧。

      分析:在这里的过程中,我们发现问题不断被推广,从一个简单的由4条边的正方形,被推广到n条边的正多边形,进而推广到n=∞的时候(实际上做不到无穷大,只是取一个比较大的n近似),最后再从圆形中取一小段,即一段圆弧。

这里涉及函数,前进fd(t,length)和左转lt(t,angle),其中t表示turtle,就是我们是拿“海龟”来画出一条路径。

这里直接把源代码附上。



1、源代码




  1. """This module contains code from
  2. Think Python by Allen B. Downey
  3. http://thinkpython.com

  4. Copyright 2012 Allen B. Downey
  5. License: GNU GPLv3 http://www.gnu.org/licenses/gpl.html

  6. """

  7. import math

  8. try:
  9.     # see if Swampy is installed as a package
  10.     from swampy.TurtleWorld import *
  11. except ImportError:
  12.     # otherwise see if the modules are on the PYTHONPATH
  13.     from TurtleWorld import *


  14. def square(t, length):
  15.     """Draws a square with sides of the given length.

  16.     Returns the Turtle to the starting position and location.
  17.     """
  18.     for i in range(4):
  19.         fd(t, length)
  20.         lt(t)


  21. def polyline(t, n, length, angle):
  22.     """Draws n line segments.

  23.     t: Turtle object
  24.     n: number of line segments
  25.     length: length of each segment
  26.     angle: degrees between segments
  27.     """
  28.     for i in range(n):
  29.         fd(t, length)
  30.         lt(t, angle)


  31. def polygon(t, n, length):
  32.     """Draws a polygon with n sides.

  33.     t: Turtle
  34.     n: number of sides
  35.     length: length of each side.
  36.     """
  37.     angle = 360.0/n
  38.     polyline(t, n, length, angle)


  39. def arc(t, r, angle):
  40.     """Draws an arc with the given radius and angle.

  41.     t: Turtle
  42.     r: radius
  43.     angle: angle subtended by the arc, in degrees
  44.     """
  45.     arc_length = 2 * math.pi * r * abs(angle) / 360
  46.     n = int(arc_length / 4) + 1
  47.     step_length = arc_length / n
  48.     step_angle = float(angle) / n

  49.     # making a slight left turn before starting reduces
  50.     # the error caused by the linear approximation of the arc
  51.     lt(t, step_angle/2)
  52.     polyline(t, n, step_length, step_angle)
  53.     rt(t, step_angle/2)


  54. def circle(t, r):
  55.     """Draws a circle with the given radius.

  56.     t: Turtle
  57.     r: radius
  58.     """
  59.     arc(t, r, 360)


  60. # the following condition checks whether we are
  61. # running as a script, in which case run the test code,
  62. # or being imported, in which case don't.

  63. if __name__ == '__main__':
  64.     world = TurtleWorld()   

  65.     bob = Turtle()
  66.     bob.delay = 0.001

  67.     # draw a circle centered on the origin
  68.     radius = 100
  69.     pu(bob)
  70.     fd(bob, radius)
  71.     lt(bob)
  72.     pd(bob)
  73.     circle(bob, radius)

  74.     wait_for_user()
复制代码


2、源代码解释




首先,square这个函数是画正方形,比较简单,就是重复“前进+左拐”四次就得到了。

其次,polyline这个函数,这个函数是之后几个函数的基础,也就是画若干条直线,更准确的说是画出某个正m边形中的连续的n条直线(m>=n)。毫无疑问,这个是一切图形的基础,任何图形都可以拿线段去逼近(稍微卖弄一下数学)~

之后的polygon这个函数只是刚好是n=m的情形,就是画出所有的正m边形的边。(注:程序中没有出现过m,但是实际上任何一个angle都可以唯一对应一个m,满足angle=360°/m)

接着,也就是我们的目标要画出circle。但是,上述程序是先给了关于arc即圆弧的函数,因为弧长对应的圆周角取360°就是一个完整的圆了。(注:当然,我们也可以按照数学中从特殊到一般的角度,先确定定如何画圆,然后再按照一个百分比,即angle/360°来画一个弧。)画圆,就是用一个足够大的正n边形去逼近。




3、小结



      最后,这里给个点评。程序是以polyline函数作为基本函数,来得到其他的函数,进而用其他的函数来表示目标函数。这种方法对于接口的设计起到了很好的练习和提升作用,即把大问题化成小问题,再把小问题分成几个基本的问题去解决,其中polyline这个函数反复使用的频率很高,这也就是这一章所强调的代码的重用性。

      但是,作为代价,当你发现了一个很好的代码作为一个基函数,那么之前的代码可能就要重写。但就像书里提到的 “Once you start coding, you understand the problem better. Sometimes refactoring (重构)is a sign that you have learned something.”
      (refactoring 就是重新整理一个程序以改进函数接口和促进代码的重用性。)这说的很清楚,代码可以不断被改“正”,当一个program被你用封装好的一系列函数所搞定之后,我们也就学到了东西。


二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

关键词:python think Thin Understand factoring Think Python 海龟 椭圆 python

已有 3 人评分经验 论坛币 学术水平 热心指数 信用等级 收起 理由
xddlovejiao1314 + 50 + 50 + 2 + 2 + 2 精彩帖子
niuniuyiwan + 60 + 60 + 5 + 5 + 5 精彩帖子
我的素质低 + 60 + 20 + 2 + 3 精彩帖子

总评分: 经验 + 170  论坛币 + 130  学术水平 + 9  热心指数 + 10  信用等级 + 7   查看全部评分

本帖被以下文库推荐

沙发
爱错星座 学生认证  发表于 2014-12-19 20:19:57 |只看作者 |坛友微信交流群
利用"海龟"程序画七叶草~只需修改__main__中的语句即可。
  1. if __name__ == '__main__':
  2.     world = TurtleWorld()   

  3.     bob = Turtle()
  4.     bob.delay = 0.001

  5.     # draw a circle centered on the origin
  6.     radius = 100
  7.     #pu(bob)
  8.     #fd(bob, radius)
  9.     #lt(bob)
  10.     #pd(bob)
  11.     n = 7
  12.     angle = 360.0 / n
  13.     theta = 180 - angle
  14.     for i in range(n):
  15.         arc(bob, radius, angle)
  16.         lt(bob, theta)
  17.         arc(bob, radius, angle)
  18.         lt(bob,180)

  19.     wait_for_user()
复制代码

七叶草.png (19.54 KB)

七叶草

七叶草

使用道具

藤椅
爱错星座 学生认证  发表于 2014-12-19 20:31:24 |只看作者 |坛友微信交流群
10叶.png
  1. if __name__ == '__main__':
  2.     world = TurtleWorld()   

  3.     bob = Turtle()
  4.     bob.delay = 0.001

  5.     # draw a circle centered on the origin
  6.     radius = 100
  7.     #pu(bob)
  8.     #fd(bob, radius)
  9.     #lt(bob)
  10.     #pd(bob)
  11.     n = 5
  12.     angle = 360.0 / n
  13.     theta = 180 - angle
  14.     for i in range(n):
  15.         arc(bob, radius, angle)
  16.         lt(bob, theta)
  17.         arc(bob, radius, angle)
  18.         lt(bob,180)

  19.     lt(bob,angle / 2.0)
  20.     for i in range(n):
  21.         arc(bob, radius, angle)
  22.         lt(bob, theta)
  23.         arc(bob, radius, angle)
  24.         lt(bob,180)
  25.         
  26.     wait_for_user()
复制代码

使用道具

板凳
爱错星座 学生认证  发表于 2014-12-21 14:03:38 |只看作者 |坛友微信交流群
画分形,利用递归。
  1. def Koch(t, length):
  2.     if length < 3:
  3.         fd(t, length)
  4.         return
  5.     Koch(t, length/3)
  6.     lt(t, 60)
  7.     Koch(t , length/3)
  8.     rt(t, 120)
  9.     Koch(t, length/3)
  10.     lt(t, 60)
  11.     Koch(t, length/3)
复制代码

分形.png (5.55 KB)

分形.png

使用道具

报纸
爱错星座 学生认证  发表于 2014-12-21 14:16:47 |只看作者 |坛友微信交流群
雪花 雪花
  1. def snowflake(t, n):
  2.     """Draws a snowflake (a triangle with a Koch curve for each side)."""
  3.     for i in range(3):
  4.         Koch(t, n)
  5.         rt(t, 120)
复制代码


使用道具

地板
zhaoxiaoming 发表于 2014-12-25 12:20:54 |只看作者 |坛友微信交流群
好东西,正好要学,感谢楼主!

使用道具

7
niuniuyiwan 在职认证  发表于 2015-8-10 17:39:44 |只看作者 |坛友微信交流群
好厉害,感谢分享

使用道具

8
xddlovejiao1314 学生认证  发表于 2015-8-10 17:51:36 |只看作者 |坛友微信交流群
好贴,谢谢分享。

使用道具

您需要登录后才可以回帖 登录 | 我要注册

本版微信群
加好友,备注jltj
拉您入交流群

京ICP备16021002-2号 京B2-20170662号 京公网安备 11010802022788号 论坛法律顾问:王进律师 知识产权保护声明   免责及隐私声明

GMT+8, 2024-4-19 11:25