介绍
下载 hw01.zip。
提交:完成后,提交python3 ok --submit
。您可以在截止日期前提交多次;只有最终提交的作品才会被评分。检查您是否已在okpy.org上成功提交代码。有关提交作业的更多说明,请参阅实验 0。
使用 Ok:如果您对使用 Ok 有任何疑问,请参阅本指南。
阅读材料:您可能会发现以下参考资料很有用:
重要提示: 8 月 30 日星期一的讲座将涉及阅读材料 1.3-1.5部分,其中包含问题 4、5 和 6 所需的知识。
评分:作业根据正确性进行评分。每道错题都会使总分减少一分。教学大纲中规定了家庭作业补救政策。 这个作业满分2分。
必答题
问题1:欢迎表单
请填写课程大纲测验(基于我们在课程大纲中的政策) 以及可选的 欢迎调查。
问题2:A 加 B 的绝对值
在下面的函数中填空实现a
加b
的绝对值,不可以调用abs
函数。除了两个空格之外,您不得修改任何提供的代码。
def a_plus_abs_b(a, b):
"""Return a+abs(b), but without calling abs.
>>> a_plus_abs_b(2, 3)
5
>>> a_plus_abs_b(2, -3)
5
"""
if b < 0:
f = _____
else:
f = _____
return f(a, b)
使用 Ok 测试您的代码:
python3 ok -q a_plus_abs_b
问题3:三选二
编写一个函数,将三个正数作为参数,并返回两个最小数的平方和。要求函数主体只使用一行代码。
def two_of_three(x, y, z):
"""Return a*a + b*b, where a and b are the two smallest members of the
positive numbers x, y, and z.
>>> two_of_three(1, 2, 3)
5
>>> two_of_three(5, 3, 1)
10
>>> two_of_three(10, 2, 8)
68
>>> two_of_three(5, 5, 5)
50
"""
return _____
提示:考虑使用
max
ormin
函数:>>> max(1, 2, 3) 3 >>> min(-1, -2, -3) -3
使用 Ok 测试您的代码:
python3 ok -q two_of_three
问题4:最大因子
编写一个函数,接收一个大于 1 的整数参数n
并返回小于n
的最大因子。
def largest_factor(n):
"""Return the largest factor of n that is smaller than n.
>>> largest_factor(15) # factors are 1, 3, 5
5
>>> largest_factor(80) # factors are 1, 2, 4, 5, 8, 10, 16, 20, 40
40
>>> largest_factor(13) # factor is 1 since 13 is prime
1
"""
"*** YOUR CODE HERE ***"
提示:要检查是否
b
整除a
,则可以使用表达式a % b == 0
,这可以理解为,“a
除以b
的余数为0。”
使用 Ok 测试您的代码:
python3 ok -q largest_factor
问题5:If 函数重构
这里有两个具有相似结构的函数。在两者中,if
防止当x
为 0 时出现ZeroDivisionError
错误。
def invert(x, limit):
"""Return 1/x, but with a limit.
>>> x = 0.2
>>> 1/x
5.0
>>> invert(x, 100)
5.0
>>> invert(x, 2) # 2 is smaller than 5
2
>>> x = 0
>>> invert(x, 100) # No error, even though 1/x divides by 0!
100
"""
if x != 0:
return min(1/x, limit)
else:
return limit
def change(x, y, limit):
"""Return abs(y - x) as a fraction of x, but with a limit.
>>> x, y = 2, 5
>>> abs(y - x) / x
1.5
>>> change(x, y, 100)
1.5
>>> change(x, y, 1) # 1 is smaller than 1.5
1
>>> x = 0
>>> change(x, y, 100) # No error, even though abs(y - x) / x divides by 0!
100
"""
if x != 0:
return min(abs(y - x) / x, limit)
else:
return limit
“重构”程序意味着重写它,使其具有相同的行为,但对设计进行一些更改。下面是尝试通过定义一个包含这两个函数公共结构的新函数limited
来重构它们以具有简短的单行定义。
def limited(x, z, limit):
"""Logic that is common to invert and change."""
if x != 0:
return min(z, limit)
else:
return limit
def invert_short(x, limit):
"""Return 1/x, but with a limit.
>>> x = 0.2
>>> 1/x
5.0
>>> invert_short(x, 100)
5.0
>>> invert_short(x, 2) # 2 is smaller than 5
2
>>> x = 0
>>> invert_short(x, 100) # No error, even though 1/x divides by 0!
100
"""
return limited(x, 1/x, limit)
def change_short(x, y, limit):
"""Return abs(y - x) as a fraction of x, but with a limit.
>>> x, y = 2, 5
>>> abs(y - x) / x
1.5
>>> change_short(x, y, 100)
1.5
>>> change_short(x, y, 1) # 1 is smaller than 1.5
1
>>> x = 0
>>> change_short(x, y, 100) # No error, even though abs(y - x) / x divides by 0!
100
"""
return limited(x, abs(y - x) / x, limit)
这个重构的代码有问题!试试看invert_short(0, 100)
。它导致ZeroDivisionError
错误但是invert(0, 100)
没有。
你的首要任务是了解行为改变的原因。在invert
中,除以x
仅在x
不为 0 时发生,但在x
为 0 时invert_short
会发生除以 0 的情况。阅读 If 语句的求值规则 和 调用表达式以了解原因。
你的第二项工作是编辑invert_short
,change_short
使它们具有与invert
和change
相同的行为但仍然只有一行。您还需要编辑limited
. 您在invert
里不需要使用and
、or
或 if
;需要注意除法发生的位置。
使用 Ok 测试您的代码:
python3 ok -q invert_short
python3 ok -q change_short
问题6:冰雹序列
道格拉斯·霍夫斯塔特 (Douglas Hofstadter) 的普利策奖获奖著作《哥德尔、埃舍尔、巴赫》提出了以下数学难题。
- 选择一个正整数
n
作为开始。 - 如果
n
是偶数,则除以 2。 - 如果
n
是奇数,则乘以 3 并加 1。 - 继续这个过程直到
n
是 1。
该数字n
会上下浮动,但最终以 1 结束(至少对于曾经尝试过的所有数字 – 没有人曾证明该序列会终止)。类似地,冰雹在最终降落在地面之前也在大气中上下移动。
n
的值组成的序列通常称为冰雹序列。编写一个函数,它接收一个形式参数名为n
的参数,打印出从n
开始的冰雹序列,并返回序列中的步数:
def hailstone(n):
"""Print the hailstone sequence starting at n and return its
length.
>>> a = hailstone(10)
10
5
16
8
4
2
1
>>> a
7
"""
"*** YOUR CODE HERE ***"
冰雹序列可能会很长!试一试 27. 你能找到的最长的是多少?
使用 Ok 测试您的代码:
python3 ok -q hailstone
对冰雹或冰雹序列感到好奇吗?看看这些文章:
有意思的题
这个问题超出了 61A 的范围。如果你想要一个额外的挑战,你可以尝试一下,但这只是一个没有实际价值的题,不强求也不推荐。几乎所有的学生都会跳过它,这很好。
问题7:自产生程序
编写一个打印自身的单行程序,仅使用 Python 语言的以下特性:
- 数字常量
- 赋值语句
- 可以使用单引号或双引号表示的字符串
- 算术运算符
+
,-
,*
, 和/
- 内置的
print
函数 - 内置的
eval
函数,将字符串计算为 Python 表达式 - 内置的
repr
函数,它返回一个计算其参数的表达式
您可以通过+
将两个字符串相加来连接两个字符串,并通过将其乘以一个整数来重复一个字符串。分号可用于分隔同一行上的多个语句。例如,
>>> c='c';print('a');print('b' + c * 2)
a
bcc
提示:探索应用于字符串的单引号、双引号和
repr
函数之间的关系 。
打印自身的程序称为 Quine。将您的解答放在名为quine
的多行字符串中。
使用 Ok 测试您的代码:
python3 ok -q quine_test
留言