《Think Python 2e》作业实现(五): 条件和递归

《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()

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_41217917/article/details/112073806