《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解释器。
习题7-1:复核牛顿法计算的平方根
【习题】 复制平方根一节中的循环,将其封装进一个叫 mysqrt 的函数中,这个函数接受 a 作为形参,选择一个合适的 x 值,并返回 a 的平方根估算值,为测试上面的函数,编写一个名为 test_squre_root 的函数,打印出如下表格:
a mysqrt(a) math.sqrt(a) diff
- --------- ------------ ----
1.0 1.0 1.0 0.0
2.0 1.41421356237 1.41421356237 2.22044604925e-16
3.0 1.73205080757 1.73205080757 0.0
4.0 2.0 2.0 0.0
5.0 2.2360679775 2.2360679775 0.0
6.0 2.44948974278 2.44948974278 0.0
7.0 2.64575131106 2.64575131106 0.0
8.0 2.82842712475 2.82842712475 4.4408920985e-16
9.0 3.0 3.0 0.0
- 练习记录:
import math
def mysqrt(a):
x = a/2
while True:
y = (x + a/x) / 2
if abs(y-x) < 0.0000000000000000000000001:
break
x = y
return x
def test_squre_root(a):
nat = "{:<4}\t{:<16}\t{:<16}\t{:<16}"
mat = "{:.1f}\t{:<16}\t{:<16}\t{:<16}"
print(nat.format('a', 'mysqrt(a)', 'math.sqrt(a)', 'diff'))
print(nat.format('-', '---------', '------------', '----'))
for i in range(a):
my_sqrt = mysqrt(i+1)
math_sqrt = math.sqrt(i+1)
diff = abs(my_sqrt - math_sqrt)
print(mat.format(i+1, my_sqrt, math_sqrt, diff))
test_squre_root(9)
PS C:\Users\Administrator> python D:\WorkSpace\thinkpython2e\test_squre_root.py
a mysqrt(a) math.sqrt(a) diff
- --------- ------------ ----
1.0 1.0 1.0 0.0
2.0 1.414213562373095 1.4142135623730951 2.220446049250313e-16
3.0 1.7320508075688772 1.7320508075688772 0.0
4.0 2.0 2.0 0.0
5.0 2.23606797749979 2.23606797749979 0.0
6.0 2.449489742783178 2.449489742783178 0.0
7.0 2.6457513110645907 2.6457513110645907 0.0
8.0 2.82842712474619 2.8284271247461903 4.440892098500626e-16
9.0 3.0 3.0 0.0
- 结果分析:
- 格式化函数 format 的应用参见 Python format 格式化函数 ,只用 print 函数无法实现习题要求的列宽度固定的输出
x = a/2
,这行代码的作用是把牛顿法求平方根的 x 初始值设为 a 的一半,在这个习题中应该合适,哪怕直接把 x 值设为 a 也无妨- 再次强调 ,循环语句
for i in range(a):
中 i 是从0开始计数的,即 i = 0, 1, 2, …, (a-1),循环次数为 a
习题7-2 :计算 input 的算式的值
【习题】 编写一个名为 eval_loop 的函数,迭代式地提示用户输入,获取输入的内容,并利用 eval 来计算其值,最后打印该值,该程序应持续运行,直到用户输入 ‘done’,然后返回它最后一次计算的表达式的值
- 练习记录:
def eval_loop():
e = None
while True:
text = input('Please enter a calculation:')
if text == 'done':
break
e = eval(text)
print(e)
print('Done!')
return e
print(eval_loop())
PS C:\Users\Administrator> python D:\WorkSpace\thinkpython2e\eval.py
Please enter a calculation:done
Done!
None
PS C:\Users\Administrator> python D:\WorkSpace\thinkpython2e\eval.py
Please enter a calculation:3**5+2*8+9
268
Please enter a calculation:done
Done!
268
e = None
语句的加入是为了避免首次即输入 ‘done’ 导致返回值 e 未赋值而出错
习题7-3 :计算 pi 近似值
【习题】 编写一个名为 estimate_pi 的函数,利用拉马努金公式来估算并返回 pi 的值,这个函数应该使用 while 循环来计算所有项的和,直到最后一项小于1e-15时终止循环,将该值与 math.pi 进行比较,检测是否准确
- 练习记录:
import math
def factorial(k):
f = 1
i = 1
while True:
f = f*i
i = i + 1
if i > k:
break
return f
def delta(k):
d = (factorial(4*k)*(1103 + 26390*k)) / ((factorial(k))**4*396**(4*k))
return d
def xigama():
i = 0
x = 0
while True:
if delta(i) < 1e-15:
break
x = x + delta(i)
i = i + 1
return x
def estimate_pi():
estimate_pi = 9801/(2*math.sqrt(2)*xigama())
return estimate_pi
print('estimate_pi =',estimate_pi())
print('epsilon =', (math.pi-estimate_pi()))
PS C:\Users\Administrator> python D:\WorkSpace\thinkpython2e\estimate_pi.py
estimate_pi = 3.141592653589793
epsilon = 0.0
- 结果分析:自定义阶乘函数 factorial 可以用 math 模块中的函数 math.factorial 替代