实验 1:函数与控制
截止时间:6 月 25 日(星期四)晚上 11:59。
起始文件
下载 lab01.zip.
出勤要求
要获得实验课学分,除了到场参加实验课外,你还需要提交实验题目。
如果你因合理原因(例如生病或时间冲突)缺席实验课,或者由于某种原因未能完成签到,请在一周内发送邮件至 cs61a@berkeley.edu ,以补记出勤学分。
必做题
知识回顾
Important: 如果
python3命令无法运行,请尝试使用python或py.
不带任何命令行选项时,Python 会运行指定文件中的代码,然后返回命令行。如果文件只包含函数定义,除非存在语法错误,否则不会看到任何输出。
python3 lab00.py-i:-i选项会先运行指定文件中的代码,再打开一个交互式会话(显示>>>提示符)。随后你可以对表达式求值,例如调用自己定义的函数。要退出,请输入exit()。也可以使用键盘快捷键Ctrl-D(Linux/Mac)或Ctrl-Z Enter(Windows)。如果在交互式运行期间修改了 Python 文件,需要退出并重新启动解释器,修改才会生效。
下面演示如何以交互方式运行
lab00.py:python3 -i lab00.py-m doctest:运行文件中的 doctest,也就是函数文档字符串里的示例。文件中的每个测试都由
>>>开头,后面跟着一段 Python 代码和预期输出。下面演示如何运行文件中的 doctest:
lab00.py:python3 -m doctest lab00.py如果代码通过所有 doctest,终端不会显示任何输出;否则会显示未通过测试的详细信息。
要用 Ok 测试某个函数,请运行以下命令(把 FUNCTION 替换为函数名):
python3 ok -q FUNCTION
如果函数中调用了 print ,并且输出内容以 "DEBUG:"开头,Ok 会忽略这一行。(否则,多余的 print 调用会产生额外输出,从而导致测试失败。)
print("DEBUG:", x)
真除法: / (小数除法) |
整除: // (向下取整除法) |
取模: % (余数) |
|---|---|---|
|
|
|
除以 0 时会发生 ZeroDivisionError 。
取模运算符有一个很实用的用途:检查一个数 % 是否能被另一个数 x 整除。 y:
x % y == 0
例如,要检查 x 是否为偶数,可以这样写: x % 2 == 0
return 语句,用来提供函数调用表达式的值。
当 Python 执行 return 语句时,函数调用会立即结束。如果 Python 运行到函数体末尾仍未执行 return 语句,函数将返回 None.
相比之下, print 函数用于显示值。与 return 语句不同,Python 对 print调用求值时,函数 不会 立即结束。
def what_prints():
print('Hello World!')
return 'Exiting this function.'
print('This course is awesome!')
>>> what_prints()
Hello World!
'Exiting this function.'
还要注意,
return会保留引号。
Python 会显示什么?(WWPD)
问题 1:Return 与 Print
使用 Ok 完成下面的“Python 会显示什么?”(WWPD)题,检查你对知识的掌握情况:
python3 ok -q return-and-print -u
>>> def welcome():
... print('Go')
... return 'hello'
...
>>> def cal():
... print('Bears')
... return 'world'
...
>>> welcome()
______Go
'hello'
>>> print(welcome(), cal())
______Go
Bears
hello world
问题 2:WWPD——如果这样呢?
使用 Ok 完成下面的“Python 会显示什么?”(WWPD)题,检查你对知识的掌握情况:
python3 ok -q if-statements -u
提示:
return),它会 不会 使函数退出。
>>> def ab(c, d):
... if c > 5:
... print(c)
... elif c > 7:
... print(d)
... print('foo')
>>> ab(10, 20)
______10
foo
>>> def bake(cake, make):
... if cake == 0:
... cake = cake + 1
... print(cake)
... if cake == 1:
... print(make)
... else:
... return cake
... return make
>>> bake(0, 29)
______1
29
29
>>> bake(1, "mashed potatoes")
______mashed potatoes
'mashed potatoes'
编写代码
问题 3:调试小测
下面是一份关于不同调试技巧的小测,这些技巧会在本课程中派上用场。答题时可以参考 调试指南 。
使用 Ok 检查你的理解:
python3 ok -q debugging-quiz -u
问题 4:下降阶乘
请编写函数 falling,它计算“下降阶乘”,接收两个参数 n 和 k,并返回从 k
开始向下连续 n 个整数的乘积。当 k 为 0 时,函数应返回 1。
def falling(n, k):
"""Compute the falling factorial of n to depth k.
>>> falling(6, 3) # 6 * 5 * 4
120
>>> falling(4, 3) # 4 * 3 * 2
24
>>> falling(4, 1) # 4
4
>>> falling(4, 0)
1
"""
"*** YOUR CODE HERE ***"
使用 Ok 测试你的代码:
python3 ok -q falling
问题 5:能被 k 整除
请编写函数 divisible_by_k ,它接收正整数 n 和 k。该函数按从小到大的顺序,打印所有不大于 n 且能被 k 整除的正整数,最后返回所打印数字的数量。
def divisible_by_k(n, k):
"""
>>> a = divisible_by_k(10, 2) # 2, 4, 6, 8, and 10 are divisible by 2
2
4
6
8
10
>>> a
5
>>> b = divisible_by_k(3, 1) # 1, 2, and 3 are divisible by 1
1
2
3
>>> b
3
>>> c = divisible_by_k(6, 7) # There are no integers up to 6 that are divisible by 7
>>> c
0
"""
"*** YOUR CODE HERE ***"
使用 Ok 测试你的代码:
python3 ok -q divisible_by_k
问题 6:连续两个 8
请编写一个接收数字的函数,判断它的十进制数位中是否包含两个相邻的 8。
def double_eights(n):
"""Return true if n has two eights in a row.
>>> double_eights(8)
False
>>> double_eights(88)
True
>>> double_eights(2882)
True
>>> double_eights(880088)
True
>>> double_eights(12345)
False
>>> double_eights(80808080)
False
"""
"*** YOUR CODE HERE ***"
使用 Ok 测试你的代码:
python3 ok -q double_eights
课程大纲小测
问题 7:课程大纲小测
请填写 课程大纲小测,以确认你已经理解课程大纲页面中的各项规定。
在本地检查得分
你可以运行以下命令,在本地检查本次作业每道题的得分:
python3 ok --score
这不会提交作业! 确认得分符合预期后,请将作业提交到 Gradescope,以获得作业学分。
提交作业
请上传所有你修改过的文件,将本次作业提交到 对应的 Gradescope 作业入口。 Lab 00 中提供了详细说明。
正确完成所有题目可得 1 分。 Please ensure your TA has taken your attendance before leaving.
可选题
以下题目为选做题。即使不完成,你仍能获得本次作业的学分;不过它们很适合用来练习,建议还是做一做!
问题 8:选取一个数位
请实现 digit,它接收正整数 n 和 k ,且函数体只能包含一条 return 语句。它应返回 n 中位于最右侧数位(个位)左边第 k
位的数字。如果 k 为 0,则返回最右侧数位;如果不存在位于其左边第 n 中位于最右侧数位(个位)左边第 k 位的数字,则返回 0。
Hint: 可以使用 // 和 % 以及内置 pow 函数来取出 n.
def digit(n, k):
"""Return the k-th digit from the right of n for positive integers n and k.
>>> digit(3579, 2)
5
>>> digit(3579, 0)
9
>>> digit(3579, 10)
0
"""
return ____
使用 Ok 测试你的代码:
python3 ok -q digit
问题 9:中间大小的数
请实现 middle :只写一个 return 表达式,返回三个互不相同的整数中既不是最大值、也不是最小值的那个数
a、 b和 c.
Hint: 可以先把所有数合在一起,再利用内置
min和max函数减去不需要返回的数。>>> max(1, 2, 3) 3 >>> min(-1, -2, -3) -3
def middle(a, b, c):
"""Return the number among a, b, and c that is not the smallest or largest.
Assume a, b, and c are all different numbers.
>>> middle(3, 5, 4)
4
>>> middle(30, 5, 4)
5
>>> middle(3, 5, 40)
5
>>> middle(3, 5, 40)
5
>>> middle(30, 5, 40)
30
"""
return ____
使用 Ok 测试你的代码:
python3 ok -q middle
问题 10:数位求和
请编写一个函数,接收非负整数并返回其各个数位之和。(整除和取模运算在这里可能很有帮助!)
def sum_digits(y):
"""Sum all the digits of y.
>>> sum_digits(10) # 1 + 0 = 1
1
>>> sum_digits(4224) # 4 + 2 + 2 + 4 = 12
12
>>> sum_digits(1234567890)
45
>>> a = sum_digits(123) # make sure that you are using return rather than print
>>> a
6
"""
"*** YOUR CODE HERE ***"
使用 Ok 测试你的代码:
python3 ok -q sum_digits