《Think Python 2e》作业实现(五): 条件和递归
文章目录
这是什么?
这里是《Think Python 2e》作业实现 !在这里将记录《Think Python 2e》作业的练习记录、终端信息和结果分析。
- 这是《Think Python 2e》哪个版本的作业?
《Think Python:如何像计算机科学家一样思考》第二版。这里主要参考了一个中文网页版《Think Python 2e》中译本。- 可以当成《Think Python 2e》参考答案吗?
这里主要记录了我自己完成作业时所产生的成果及习题总结,基本未参考教材所提供的答案,未免有失规范,参考答案建议还是以 绿茶出版社官方代码 为准。- 不同的解释器版本结果不尽相同,这里用的哪个版本Python解释器?
这里用了Python 3.8.6版解释器,部分用安卓Pydroid 4.01_arm64中的3.8.3版Python解释器,在线解释器用教程推荐的PythonAnywhere中的3.8版Python解释器。
习题5-1:转化格林威治时间
请写一个脚本读取当前格林威治标准时间,并且将其转换为纪元以来经过了多少天、小时、分钟和秒
- 练习记录:
import time
s = time.time()
day = s // (60 * 60 * 24)
hour = (s - day * (60 * 60 * 24)) // (60 * 60)
minute = (s - day * (60 * 60 * 24) - hour * (60 * 60)) // 60
second = s - day * (60 * 60 * 24) - hour * (60 * 60) - minute * 60
print('time_now ',s)
print('days ',day)
print('hours ',hour)
print('minutes ',minute)
print('seconds ',second)
PS C:\Users\Administrator> python D:\WorkSpace\thinkpython2e\5_1.py
time_now 1609513414.5685637
days 18628.0
hours 15.0
minutes 3.0
seconds 34.56856369972229
习题5-2:检验费马大定理
【习题5.2.1】 写一个名为check_fermat的函数,接受四个形参——a,b,c以及n ——检查费马大定理是否成立。 如果 n 大于2且等式 an + bn = cn 成立,程序应输出“Holy smokes, Fermat was wrong!”, 否则程序应输出“No, that doesn’t work.”
- 练习记录:
def check_fermat(a,b,c,n):
if n > 2 and a**n + b**n == c**n:
print('Holy smokes,Fermat was wrong!')
else:
print("No, that doesn't work.")
check_fermat(200, 300, 400, 3)
No, that doesnt work.
- 结果分析:
- 单引号或者双引号都可以用于表示字符串,但字符串里面有字符
'
的必须用双引号,如语句print("No,that doesn't work!")
中,用单引号表示字符串就会出错
Traceback (most recent call last): File "/data/user/0/ru.iiec.pydroid3/files/accomp_files/iiec_run/iiec_run.py", line 31, in <module> start(fakepyfile,mainpyfile) File "/data/user/0/ru.iiec.pydroid3/files/accomp_files/iiec_run/iiec_run.py", line 30, in start exec(open(mainpyfile).read(), __main__.__dict__) File "<string>", line 5 print('No, that doesn't work.') ^ SyntaxError: invalid syntax
- 单引号或者双引号都可以用于表示字符串,但字符串里面有字符
【习题5.2.2】 写一个函数提示用户输入a,b,c以及n的值,将它们转换成整型数, 然后使用check_fermat检查他们是否会违反了费马大定理
- 练习记录:
def check_fermat(a,b,c,n):
if n > 2 and a**n + b**n == c**n:
print('Holy smokes,Fermat was wrong!')
else:
print("No, that doesn't work.")
prompt = 'Please enter the value of a.\n'
a = int(input(prompt))
prompt = 'Please enter the value of b.\n'
b = int(input(prompt))
prompt = 'Please enter the value of c.\n'
c = int(input(prompt))
prompt = 'Please enter the value of n.\n'
n = int(input(prompt))
check_fermat(a, b, c, n)
Please enter the value of a.
32
Please enter the value of b.
78
Please enter the value of c.
99
Please enter the value of n.
4
No, that doesn't work.
- 结果分析:
- 内置函数 input 输入的实参 prompt 等会作为提示信息会被显示;
- 内置函数 input 接受见键盘输入后,返回的值是字符串,如果要得到一个整数或者实数,需要用 int 、float 等函数转换;
>>> a = input('Enter a value:\n') Enter a value: 32.8 >>> a '32.8' >>> float(a) 32.8
习题5-3:三根棒能搭三角形?
【习题5.3.1】 一个名为is_triangle的函数,其接受三个整数作为形参, 能够根据给定的三个长度的棒能否构成三角形来打印“Yes”或“No”
- 练习记录:
def is_triangle(a, b, c):
if a + b > c and a + c > b and b + c > a:
print('Yes')
else:
print('No')
is_triangle(3, 4, 5)
PS C:\Users\Administrator> python D:\WorkSpace\thinkpython2e\new11.py
Yes
【习题5.3.2】 写一个函数,提示用户输入三根棍子的长度,将它们转换成整型数,然后使用 is_triangle检查给定长度的棒能否构成三角形
- 练习记录:
def is_triangle(a, b, c):
if a + b > c and a + c > b and b + c > a:
print('Yes')
else:
print('No')
prompt = 'Enter the length of the first stick: '
A = int(input(prompt))
prompt = 'Enter the length of the second stick: '
B = int(input(prompt))
prompt = 'Enter the length of the third stick: '
C = int(input(prompt))
is_triangle(A, B, C)
PS C:\Users\Administrator> python D:\WorkSpace\thinkpython2e\new12.py
Enter the length of the first stick: 1
Enter the length of the second stick: 2
Enter the length of the third stick: 3
No
习题5-4:递归函数的输出
def recurse(n, s):
if n == 0:
print(s)
else:
recurse(n-1, n+s)
recurse(3, 0)
【习题 5.4.1】 如果你这样调用函数: recurse(-1,0) ,会有什么结果?
- 练习记录:
PS C:\Users\Administrator> python D:\WorkSpace\thinkpython2e\new13.py
Traceback (most recent call last):
File "D:\WorkSpace\thinkpython2e\new13.py", line 7, in <module>
recurse(-1, 0)
File "D:\WorkSpace\thinkpython2e\new13.py", line 5, in recurse
recurse(n-1, n+s)
File "D:\WorkSpace\thinkpython2e\new13.py", line 5, in recurse
recurse(n-1, n+s)
File "D:\WorkSpace\thinkpython2e\new13.py", line 5, in recurse
recurse(n-1, n+s)
[Previous line repeated 995 more times]
File "D:\WorkSpace\thinkpython2e\new13.py", line 2, in recurse
if n == 0:
RecursionError: maximum recursion depth exceeded in comparison
- 结果分析:这样调用函数
recurse(-1,0)
,递归永远不会达到基础情形,所以进入无限递归,直到达到 Python 的最大递归深度
【习题 5.4.2】 请写一个文档字符串,解释调用该函数时需要了解的全部信息(仅此而已)
- 练习记录:
def recurse(n, s):
""" n>=0
"""
if n == 0:
print(s)
else:
recurse(n-1, n+s)
- 结果分析:
- 为了不进入无限递归,对输入的实参 n 必须大于或者等于0的要求,用文档字符串形式予以说明
习题5-5:小乌龟画的树枝图
【习题】 阅读如下的函数,看看你能否看懂它是做什么的
- 练习记录:
import turtle
tom = turtle.Turtle()
def fd(t, length):
t.fd(length)
def bk(t, length):
t.bk(length)
def lt(t, angle):
t.lt(angle)
def rt(t, angle):
t.rt(angle)
def draw(t, length, n):
print("调用层数:", m + 1 - n)
if n == 0:
print("回到层数:", m - n)
return
angle = 50
fd(t, length*n)
lt(t, angle)
draw(t, length, n-1)
rt(t, 2*angle)
draw(t, length, n-1)
lt(t, angle)
bk(t, length*n)
if m -n == 0:
print("回到主程序")
else:
print("回到层数:", m - n)
t = tom
length = 20
n = 2
m = n
print("开始主程序")
draw(t, length, n)
turtle.mainloop()
- 结果分析:
-
在分析函数递归调用时,必须分析清楚是什么时候 “递” 的,也就是必须分析清楚调用该函数的上一个函数的各形参、变量的值以及调用的语句(在本题的函数中,有两个语句调用下一个函数)
-
“归”(return) ,必须返回调用该函数的上一个函数,且返回到发生调用的语句的下一句,形参、变量的值保持调用时的值
-
画函数堆栈图是分析函数状态比较好的方式,本题的函数堆栈图(忽略函数 lt、rt、fd 和 bk,附加了程序递归调用行号 ):
-
在程序中增加打印语句,例如
print("调用层数:", m + 1 - n)
,让程序运行时在命令行窗口显示相关信息(如下图),是追踪函数递归调用的好方法:
-
- 变形练习:(画四个或多个分岔的图形)
import turtle
tom = turtle.Turtle()
def fd(t, length):
t.fd(length)
def bk(t, length):
t.bk(length)
def lt(t, angle):
t.lt(angle)
def rt(t, angle):
t.rt(angle)
def draw(t, length, n):
print("调用层数:", m + 1 - n)
if n == 0:
print("回到层数:", m - n)
return
angle = 70
fd(t, length*n)
lt(t, angle)
draw(t, length, n-1)
rt(t, 2/3*angle)
draw(t, length, n-1)
rt(t, 2/3*angle)
draw(t, length, n-1)
rt(t, 2/3*angle)
draw(t, length, n-1)
lt(t, angle)
bk(t, length*n)
if m - n == 0:
print("回到主程序")
else:
print("回到层数:", m - n)
t = tom
length = 20
n = 3
m = n
print("开始主程序")
draw(t, length, n)
turtle.mainloop()
习题5-6:画科赫曲线和雪花
【习题5.6.1】 写一个名为 koch 的函数,接受一个海龟和一个长度作为形参,然后 使用海龟画一条给定长度的科赫曲线
- 练习记录:
import turtle
bob = turtle.Turtle()
def koch(t,n):
if n < 5:
t.fd(n)
return
n = n/3
koch(t, n)
t.lt(60)
koch(t, n)
t.rt(120)
koch(t, n)
t.lt(60)
koch(t, n)
bob.pu()
bob.goto(-150, 90)
bob.pd()
koch(bob, 300)
bob.ht()
turtle.mainloop()
【习题5.6.2】 写一个名为 snowflake 的函数,画出三条科赫曲线,构成雪花的轮廓
- 练习记录:
import turtle
bob = turtle.Turtle()
def koch(t,n):
if n < 5:
t.fd(n)
return
n = n/3
koch(t, n)
t.lt(60)
koch(t,n)
t.rt(120)
koch(t,n)
t.lt(60)
koch(t,n)
def snowflake(t, n):
for i in range(3):
koch(t, n)
t.rt(120)
bob.pu()
bob.goto(-150, 90)
bob.pd()
snowflake(bob, 300)
bob.ht()
turtle.mainloop()