《Think Python》课后实现合集(更新至 练习4-5)

这篇博客详细记录了作者在学习《Think Python》过程中的课堂笔记和课后作业,包括第1至4章的练习题解答,涉及交互模式错误、解释器计算器、函数应用、接口设计等多个方面。作者分享了解题思路,探讨了Python中的一些常见错误和编程技巧,并提供了部分代码实现。
摘要由CSDN通过智能技术生成

这是什么?

你好!这里是九月初夏的 《Think Python》作业本 !在这里我将记录自己《Think Python》的章节练习和解题思路,希望能和你一起度过奇妙的编程初见之旅~ 为了便于寻找和我自己区分,我给每个习题都取了个名字。

- 这是《Think Python》哪个版本的作业?
《Think Python:如何像计算机科学家一样思考》第二版(基于Python 3),各大购书平台有售。当然便于写作业的时候“誊抄”题目,我找到了一本双语PDF(作者让这本书基于GNU自由文档许可协议“开源”了,但是该版本部分习题和纸书不同),来自哈尔滨工业大学 车万翔教授 ,渠道是中国大学MOOC。

- 可以当成《Think Python》参考答案吗?
参考答案建议还是以 绿茶出版社官方代码 为准。这里主要存放的还是我的个人答案和解题感悟,当然因为是编程初见,很有可能出现 无法求解 的情况,你有可能看到的是无法正确实现题目要求的代码。当然,如果发生这种情况我会再放一份官方代码研究,并 分析原因、总结规律 ,当然希望这种情况不要发生_(:зゝ∠)_ 还有就是一些没有官方答案的题目,我也不能保证100%正确_(:зゝ∠)_

课堂笔记&课后作业

第1章 程序之道

练习 1-1:在交互模式中故意犯错(1)

【习题 1.1.1】print 语句中,如果漏掉一个括号,或者两个都漏掉,会发生什么?
【求解】
情况1:漏掉左括号,或者都漏掉

>>> print 'Holle, World!')
  File "<stdin>", line 1
    print 'Holle, World!')
                        ^
SyntaxError: Missing parentheses in call to 'print'. Did you mean print('Holle, World!'))?
>>>print 'Holle, World!'
  File "<stdin>", line 1
    print 'Holle, World!')
                        ^
SyntaxError: Missing parentheses in call to 'print'. Did you mean print('Holle, World!'))?
序号 报错 含义
1 SyntaxError: Missing parentheses in call to ‘print’. 语法错误:调用时缺少括号

推测原因:Python 2 中 print 语句不需要括号,而Python 3 需要,所以这里特别说明缺少括号并给出了可能的建议

情况2:漏掉右括号

>>>print ('Holle, World!'
    
                          ^
SyntaxError: unexpected EOF while parsing
序号 报错 含义
2 SyntaxError: unexpected EOF while parsing 语法错误:解析时意外终止

推测原因:解释器从左往右读代码, print 语句没有终止符,后面又没有东西,就“意外终止”了

【习题 1.1.2】 如果正尝试打印一个字符串,那么漏掉一个货所有引号,会发生什么?
【求解】
情况1:漏掉左引号,或者都漏掉

>>>print (Holle, World!')
  File "<stdin>", line 1
    print (Holle, World!')
                       ^
SyntaxError: invalid syntax
>>>print (Holle, World!)
  File "<stdin>", line 1
    print (Holle, World!)
                       ^
SyntaxError: invalid syntax
序号 报错 含义
3 SyntaxError: invalid syntax 语法错误:无效语法

推测原因:没有引号,解释器将括号里的“Holle, World!”当成了一个变量名,但是逗号、空格、感叹号是非法字符,违背了变量命名的规则,去掉这些符号后,报错就变成了“命名错误:命名没有被定义”了

>>>print ('HolleWorld')
Traceback (most recent call last):
  File "<stdin>", line 1
    print (HolleWorld)
NameError: name 'HolleWorld' is not defined
序号 报错 含义
5 NameError: name ‘HolleWorld’ is not defined 命名错误:命名没有被定义

情况2:漏掉右引号

>>>print ('Holle, World!)
  File "<stdin>", line 1
    print ('Holle, World!)
                         ^
SyntaxError: EOL while scanning string literal
序号 报错 含义
4 SyntaxError: EOL while scanning string literal 语法错误:扫描字符串时行终止

推测原因:解释器从左往右读代码,字符串没有终止符,但是print语句却终止了,故“扫描字符串时行终止”

【习题 1.1.3】 可以使用一个负号来表示负数,如-2。如果在数字之前放一个正好,会发生什么?如果是2++2呢?
【求解】

>>> -2
-2
>>> 2++2
4

【习题 1.1.4】 在数学标记里,前置 0 是没有问题的,如 02。在 Python 中也这么做会发生什么?
【求解】

>>> 02
2

【习题 1.1.5】 如果在两个值之间不放任何操作符,会发生什么?
【求解】
情况1:两个值中间无空格:

>>> 24
24

情况2:两个值中间有空格:

>>> 2 4
  File "<stdin>", line 1
    2 4
      ^
SyntaxError: invalid syntax
序号 报错 含义
3 SyntaxError: invalid syntax 语法错误:无效语法

练习 1-2:解释器牌计算器(时间换算、距离换算、速度换算)

【习题 1.2.1】 在42分42秒钟,一共有多少秒?
【求解】

>>> 42*60+42
2562

【习题 1.2.2】 10千米相当于多少英里?提示:1英里相当于1.61千米。
【求解】

>>> 10/1.61
6.211180124223602

【习题 1.2.3】 如果你42分42秒跑完10千米,那么你的平均速度(跑1千米需要的分钟和秒数)是多少?平均速度是多少千米每小时?
【求解】
问题1:跑1千米需要的分钟和秒数:
分钟:

>>> (42*60+42)/10/60
4

秒数:

>>> (42*60+42)/10.0%60
16.19999999999999

问题2:平均速度是多少千米每小时:

>>> 10.0/(42*60+42)*60*60
14.051522248243561

第2章 变量、表达式和语句

练习 2-1:在交互模式中故意犯错(2)

【习题 2.1.1】 我们已经见过 n = 42 是合法的。那么 42 = n 呢?
【求解】

>>> 42 = n
  File "<stdin>", line 1
SyntaxError: can't assign to literal
序号 报错 含义
6 SyntaxError: can’t assign to literal 语法错误:不能给文字赋值

【习题 2.1.2】 那么 x = y = 1呢?
【求解】

>>> x = y = 1
>>> x
1
>>> y
1

【习题 2.1.3】 有些语言中,每个语句都需要以分好(;)结尾。如果你在 Python 语句的结尾放一个分好,会有什么情况?
【求解】

>> x = y = 1
>>> print(x);print(y)
1
1

【习题 2.1.4】 如果在语句结尾放的是句号呢?
【求解】

>>> print(x).
  File "<stdin>", line 1
    print(x).
            ^
SyntaxError: invalid syntax
序号 报错 含义
3 SyntaxError: invalid syntax 语法错误:无效语法

【习题 2.1.5】 在数学标记中,对于 x 乘以 y,可以这么表达:xy。在Python中这样尝试会有什么结果?
【求解】

>>> x = 2
>>> y = 4
>>> xy
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'xy' is not defined
序号 报错 含义
5 NameError: name ‘HolleWorld’ is not defined 命名错误:命名没有被定义

练习 2-2:解释器牌计算器(球体积、书总价、晨练到家时间)

【习题 2.2.1】 半径为 r r r 的球体的体积是 ( 4 / 3 ) π r 3 (4/3)πr^{3} (4/3)πr3。半径为 5 5 5 的球体体积是多少?
【求解】

>>> (4.0/3)*3.14*5**3
523.3333333333334

【习题 2.2.2】 假设一本书的定价是24.95美元,但是书店打了40%的折扣(6折)。运费是一本3美元,每加一本加75美分。60本书的总价是多少?
【求解】

>>> 24.95*(1-0.4)*60+3+0.75*(60-1)
945.4499999999999

【习题 2.2.3】 如果我 06:52 时离开家,并以慢速(6分10秒/千米)跑1.6千米,接下来以4分30秒/千米的速度跑4.8千米,再以慢速跑1.6千米。请问我回家吃早餐时什么时候?
【求解】
时:

>> 6+1
7

分:

>>> (52+((6*60+10)*1.6*2+(4*60+30)*4.8-((6*60+10)*1.6*2+(4*60+30)*4.8)%60)/60)%60
33.0

秒:

>>> 0+((6*60+10)*1.6*2+(4*60+30)*4.8)%60
20.0

第3章 函数

练习 3-1:输入长度<70的任意字符串,让其最后一个字母在第70列上

【习题 3.1.1】 编写一个函数 right_justify,接收一个字符串形参 s,并打印出足够的前导空白,以达到最后一个字符显示在第70列上。

>>> right_justify('monty')
                                                                 monty

提示:可以利用字符串的拼接和重复特性。另外,Python提供了一个内置名为 len 的函数,返回一个字符串的长度,所以 len(‘allen’) 的值是5。
【求解】
先计算s的长度l,前导空白=空格*(70-l):

>>> def right_justify(s):
...     l = len(s)
...     print(' '*(70-l)+s)
... 
>>> right_justify('monty')
                                                                 monty

将len(s)带入l,还能更剪短点:

>>> def right_justify(s):
...     print(' '*(70-len(s))+s)
... 
>>> right_justify('monty')
                                                                 monty

练习 3-2:在函数中调用另一个函数

函数对象是一个值,可以将它赋值给变量,或者作为实参传递。例如,do_twice 是一个函数,接收一个函数对象作为实参,并调用它两次:

def do_twice(f):
    f()
    f()

下面是一个使用 do_twice 来调用一个 print_spam 函数两次的示例:

def print_spam():
    print('spam')
    
do_twice(print_spam)

【习题 3.2.1】 将这个示例存入脚本并测试它。
【求解】
代码:

def do_twice(f):
    f()
    f()
	
def print_spam():
    print('spam')
    
do_twice(print_spam)

运行结果:

spam
spam

【习题 3.2.2】 修改 do_twice,让他接收两个实参,一个是函数对象,另一个是一个值,它会调用函数对象两次,并传入那个值作为实参。
【求解】 这让我想起了代数 y=g(f(x),x)
代码:

def do_twice(f,x):
    f(x)
    f(x)
	
def print_spam(x):
    print(x)
    
do_twice(print_spam,'spam')

运行结果:

spam
spam

【习题 3.2.3】 将本章前面介绍的函数 print_twice 的定义复制到你的脚本中。
【求解】

def print_twice(bruce):
	print(bruce)
	print(bruce)

【习题 3.2.4】 使用修改版的 do_twice 来调用 print_twice 两次,并传入实参 ‘spam’。
【求解】
代码:

def do_twice(f,x):
    f(x)
    f(x)
	
def print_twice(bruce):
	print(bruce)
	print(bruce)
    
do_twice(print_twice,'spam')

运行结果:

spam
spam
spam
spam

【习题 3.2.4】 定义一个新的函数 do_four,接收一个函数对象与一个值,使用这个值作为实参调用函数4次。这个函数的函数体应该只有2条语句,而不是4条。
【求解】 在 do_four 里调用 do_twice 两次,从而实现调用实参函数4次(2×2)
代码:

#执行函数f(x)两次
def do_twice(f,x):
    f(x)
    f(x)

#通过执行do_twice(f,x)两次,实现执行f(x)四次
def do_four(f,x):
	do_twice(f,x)
	do_twice(f,x)
	
#定义最终被调用的函数	
def print_spam(x):
    print(x)

#执行将'spam'打印四次
do_four(print_spam,'spam')

执行结果:

spam
spam
spam
spam

练习 3-3:用函数画表格

注意:这个练习应该仅使用当前我们学过的语句和特性来实现。
【习题 3.3.1】 编写一个函数,绘制如下表格:
在这里插入图片描述
提示:要在同一行打印出个值,可以使用逗号分隔不同的值:

print ('+', '-')

如果一个序列以逗号结尾,Python会认为这一行没有结束, 于是下一个打印出的值会
出现在同一行。

print ('+', end=' ')
print ('-')

这两条语句的输出结果是’+ -’。
一条单独的print语句会结束当前行,开始下一行。
【分析】
第一步:先分析表格下表格在这里插入图片描述
第二布:确认下方案
首先,题目给出的 print 语句的用法肯定是有用的

print ('+', end=' ')
print ('-')

其次,【习题 3.2.4】 的 do_twice 和 do_four 也是有用的

#执行函数f(x)两次
def do_twice(f,x):
    f(x)
    f(x)

#通过执行do_twice(f,x)两次,实现执行f(x)四次
def do_four(f,x):
	do_twice(f,x)
	do_twice(f,x)

所以我打算用 do_twice 画边界和空白的每一条,再用 do_four 画4条空白的行高
【求解】

#执行函数f(x)两次
def do_twice(f,x,y):
    f(x,y)
    f(x,y)

#通过执行do_twice(f,x)两次,实现执行f(x)四次
def do_four(f,x,y):
	do_twice(f,x,y)
	do_twice(f,x,y)
	
#画出表格的每条,边界、空白可用
def do(x,y):
	print (x, end=' ')
	print (x, end=' ')
	print (y)

#画出表格的“一行”:1条上边+4条行高
def line():
	do('+ - - - -','+')
	do_four(do,'|        ','|')
	
#画出表格:2行+1底边
def list():
	line()
	line()
	do('+ - - - -','+')
	
list()

【再解】 瞄了一眼,下面 【习题 3.3.1】 要求变成 4 × 4 的表格,我想能不能把变量尽量提出来,改变表格的时候改个数字就好了?最后发现列很容易做到(用《Think Python》13页《2.6 字符串操作》中的 ‘Spam’*3),行还是要靠 print 语句一行一行打印。
当然此方法中的“+ - - - - ”和“| ”要比 【求解】 中多1个空格

#变量:表格列数
n = 2

#n列表格的1条:n个循环体+1个终止符,边界、空白均可使用
def cell(x,y,n):
	print(x*n+y)

#行高:4条空白(直接4条,懒得再定义do_twice和do_four了)
def line_height_4(n):
	cell('|         ','|',n)
	cell('|         ','|',n)
	cell('|         ','|',n)
	cell('|         ','|',n)

#行:一条边界+行高
def line(n):
	cell('+ - - - - ','+',n)
	line_height_4(n)

#表格:2行+1底
def list(n):
	line(n)
	line(n)
	cell('+ - - - - ','+',n)
	
#执行表格函数,打印出表格
list(n)

【习题 3.3.2】 编写一个函数绘制类似的表格,单有4行4列。
【求解】 基于 【习题 3.3.1】 中的 【求解】,用了 do_twice 和 do_four,没有被拿出来的变量。
代码变动:需要在画“每条”时多打印“列” print (x, end=’ ') 2次,画表格的时候多打印“行” line() 2次

#执行函数f(x)两次
def do_twice(f,x,y):
    f(x,y)
    f(x,y)

#通过执行do_twice(f,x)两次,实现执行f(x)四次
def do_four(f,x,y):
	do_twice(f,x,y)
	do_twice(f,x,y)
	
#画出表格的每条,边界、空白可用
def do(x,y):
	print (x, end=' ')
	print (x, end=' ')
	print (x, end=' ')
	print (x, end=' ')
	print (y)

#画出表格的“一行”:1条上边+4条行高
def line():
	do('+ - - - -','+')
	do_four(do,'|        ','|')
	
#画出表格:2行+1底边
def list():
	line()
	line()
	line()
	line()
	do('+ - - - -','+')
	
list()

【再解】 基于 【习题 3.3.1】 中的

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值