实验 1:函数、控制

截止时间:6月25日(周四)23:59。

Starter 文件

下载 lab01.zip

出勤

除了出勤外,你还需要提交实验题目才能获得实验分数。

如果你因正当理由(如生病或时间冲突)缺席实验,或因某种原因未能签到,请在一周内发邮件至 cs61a@berkeley.edu 以获得出勤分数。

必做题

复习

重要提示:如果 python3 命令不可用,请尝试使用 pythonpy

以下是最常用的在文件上运行 Python 的方式。
  1. 不使用命令行选项将运行你提供的文件中的代码,然后返回到命令行。如果你的文件只包含函数定义,除非有语法错误,否则你不会看到任何输出。

    python3 lab00.py
  2. -i-i 选项运行你提供的文件中的代码,然后打开一个交互式会话(带有 >>> 提示符)。然后你可以评估表达式,例如调用你定义的函数。要退出,输入 exit()。你也可以在 Linux/Mac 上使用快捷键 Ctrl-D,或在 Windows 上使用 Ctrl-Z Enter

    如果在交互式运行时编辑了 Python 文件,你需要退出并重启解释器才能使更改生效。

    以下是我们如何交互式运行 lab00.py

    python3 -i lab00.py
  3. -m doctest:运行文件中的 doctest,即函数文档字符串中的示例。

    文件中的每个测试由 >>> 后跟一些 Python 代码和预期输出组成。

    以下是我们如何运行 lab00.py 中的 doctest:

     python3 -m doctest lab00.py

    当我们的代码通过所有 doctest 时,不会显示任何输出。否则,将显示关于失败测试的信息。


在 CS 61A 中,我们使用一个名为 Ok 的程序来自动评分实验、作业和项目。

要使用 OK 测试函数,请运行以下命令(将 FUNCTION 替换为函数名):

python3 ok -q FUNCTION

如果你的函数包含以 "DEBUG:" 开头的 print 调用,则该行将被 OK 忽略。(否则,包含额外的 print 调用可能会因额外的输出导致测试失败。)

print("DEBUG:", x)

更多功能请参阅使用 OK 页面你可以在 ok-help 快速生成大多数 ok 命令。


以下是 Python 3 中除法相关运算符的示例:

真除法:/
(小数除法)
向下取整除法://
(整数除法)
取模:%
(余数)
>>> 1 / 5
0.2

>>> 25 / 4
6.25

>>> 4 / 2
2.0

>>> 5 / 0
ZeroDivisionError
>>> 1 // 5 # truncate result of true division
0

>>> 25 // 4
6

>>> 4 // 2
2

>>> 5 // 0
ZeroDivisionError
>>> 1 % 5
1

>>> 25 % 4
1

>>> 4 % 2
0

>>> 5 % 0
ZeroDivisionError

当除以 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.'

还要注意 print 显示的文本不带引号,但 return 会保留引号。

Python 会输出什么?(WWPD)

Q1:Return and Print

使用 Ok 测试你对以下"Python 会输出什么?"问题的理解:

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

Q2:WWPD:What If?

使用 Ok 测试你对以下"Python 会输出什么?"问题的理解:

python3 ok -q if-statements -u

提示print(与 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'

编写代码

Q3:Debugging Quiz

以下是一个关于不同调试技巧的快速测验,这些技巧在本课程中会对你有所帮助。你可以参考调试文章来回答这些问题。

使用 Ok 测试你的理解:

python3 ok -q debugging-quiz -u

Q4:Falling Factorial

让我们写一个函数 falling,它是一个"下降"阶乘,接受两个参数 nk,返回从 n 开始向下递减的 k 个连续数字的乘积。当 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

Q5:Divisible By k

编写一个函数 divisible_by_k,接受正整数 nk。它打印所有小于或等于 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

Q6:Double Eights

编写一个函数,接受一个数字并判断其数字中是否包含两个相邻的 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

课程大纲测验

Q7:Syllabus Quiz

请填写课程大纲测验,确认你已理解课程大纲页面上的政策。

本地检查你的分数

你可以通过运行以下命令在本地检查本作业每道题的分数:

python3 ok --score

这不会提交作业!当你对分数满意后,将作业提交到 Gradescope 以获得分数。

提交作业

通过上传你编辑过的文件到相应的 Gradescope 作业来提交本作业。实验 00有详细说明。

正确完成所有题目得一分。 离开前请确保你的助教已记录你的出勤。

选做题

这些题目是选做的。如果你不完成它们,仍然可以获得本作业的分数。但它们是很好的练习,所以还是建议你做一做!

Q8:Pick a Digit

实现 digit,它接受正整数 nk,函数体只有一条 return 语句。它返回 n 中距离最右边数字(个位数字)k 个位置的数字。如果 k 为 0,返回最右边的数字。如果 n 中没有距离最右边数字 k 个位置的数字,返回 0。

提示:使用 //% 以及内置 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

Q9:Middle Number

实现 middle,写一条 return 表达式,其值为三个不同整数 abc 中既不是最大也不是最小的那个值。

提示:尝试将所有数字相加,然后使用内置的 minmax 函数去掉你不想返回的数字。

>>> 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

Q10:Sum Digits

编写一个函数,接受一个非负整数并对其各位数字求和。(使用向下取整除法和取模可能会有帮助!)

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