启动文件

下载 lab01.zip。在存档中,您将找到本实验中问题的开始文件,以及 Ok 自动打分器的副本。

此外, 如果您在《实验 0:Python 的安装》或使用 Windows 自动安装程序时遇到任何问题,请填写此调查

为了快速生成 ok 命令,您现在可以使用 ok 命令生成器

快速回顾

使用 Python

运行 Python 文件时,您可以使用命令行的选项进一步检查代码。这里有一些会派上用场。如果您想了解其他 Python 命令行选项的更多信息,请查看文档

  • 不使用命令行选项将运行您提供的文件中的代码然后返回到命令行。例如,如果我们想以这种方式运行lab00.py ,我们可以在终端中输入:

    python3 lab00.py
  • -i:使用-i选项将运行您的 Python 脚本,然后打开一个交互式会话。在交互式会话中,您逐行运行 Python 代码并获得即时反馈,而不是一次运行整个文件。要退出的话,请在解释器提示符键入exit()。您还可以在 Linux/Mac 计算机上使用Ctrl-D或Windows上使用Ctrl-Z Enter等键盘快捷键。

    如果在交互运行时编辑 Python 文件,则需要退出并重新启动解释器以使这些更改生效。

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

    python3 -i lab00.py
  • -m doctest: 在特定文件中运行文档测试。文档测试被函数内的三重引号 (""")包围。

    文件中包含>>>的每个测试都跟随这一些 Python 代码和预期的输出(尽管>>>在文档测试命令的输出中看不到)。

    要运行`lab00.py的文档测试,我们可以运行:

    python3 -m doctest lab00.py

使用 OK

在 CS 61A 中,我们使用名为 Ok 的程序对实验、作业和项目进行自动评分。您在本实验开始时下载的启动文件中已经有了 Ok。有关使用 Ok 命令的更多信息,请在此处了解。

您可以在 ok-help 快速生成大多数 ok 命令 。

要使用 Ok 为指定的函数运行文档测试,请运行以下命令:

python3 ok -q <specified function>

默认情况下,只会显示未通过的测试。您可以使用-v 选项显示所有测试,包括您已通过的测试:

python3 ok -v

您还可以通过编写一下语句在 OK 中使用调试打印功能

print("DEBUG:", x)

最后,当您完成 lab01.py 中的所有问题后 ,您必须使用--submit选项提交作业 :

python3 ok --submit

结对编程

您可以将此实验用作尝试结对编程的一种方式。请查看 结对编程页面

主题

如果您需要复习本实验的材料,请参阅此部分。你可以直接跳到问题部分,如果你遇到困难,可以回来参考这里。

除法、整除和模

让我们比较一下 Python 3 中不同的除法相关的运算符:

真正的除法:(/ 十进制除法) 向下取整除法:(// 整除) 模:(% 求余数)
>> 1 / 5
0.2
>> 25 / 4
6.25
>>> 4 / 2
2.0
>>> 5 / 0
ZeroDivisionError
>>> 1 // 5
0
>>> 25 // 4
6
>>> 4 // 2
2
>>> 5 // 0
ZeroDivisionError
>>> 1 % 5
1
>>> 25 % 4
1
>>> 4 % 2
0
>>> 5 % 0
ZeroDivisionError

请注意,某些情况下 Python 会输出ZeroDivisionError。我们稍后将在本实验室的“错误信息”部分对此进行讨论。

一种关于%运算符的有用方法是检查一个数字x是否可以被另一个数字y整除:

x % y == 0

例如,为了检查x是否是偶数:

x % 2 == 0

函数

如果我们想一遍遍地执行一系列语句,我们可以将它们抽象成一个函数以避免重复写代码。

例如,假设我们想知道将数字 1 到 3 乘以 3 然后加上 2 的结果。这是一种方法:

>>> 1 * 3 + 2
5
>>> 2 * 3 + 2
8
>>> 3 * 3 + 2
11

如果我们想用更大的一组数字来做这件事,那将是大量重复的代码!让我们编写一个函数来捕获此操作,考虑到任何输入数字。

def foo(x):
    return x * 3 + 2

这个名为 foo 的函数接受一个参数,并将返回将该参数乘以 3 并加上 2 的结果。

现在我们可以在需要运算时调用此函数:

>>> foo(1)
5
>>> foo(2)
8
>>> foo(1000)
3002

将函数应用于某些参数是通过调用表达式完成的

调用表达式

调用表达式应用一个函数,该函数可能接收也可能不接收参数。调用表达式计算结果为函数的返回值。

函数调用的语法:

  add   (    2   ,    3   )
   |         |        |
operator  operand  operand

每个调用表达式都需要一组括号来限定其以逗号分隔的操作数。

要求值函数调用:

  1. 计算运算符,然后是操作数(从左到右)。
  2. 将运算符应用于操作数(操作数的值)。

如果操作数是嵌套调用表达式,则首先将这两个步骤应用于该内部操作数,以便评估外部操作数。

returnprint

您定义的大多数函数都将包含一个return语句。该return 语句将一些计算的结果返回给函数的调用者并退出当前函数。例如,下面的函数square接受一个数字x并返回它的平方。

def square(x):
    """
    >>> square(4)
    16
    """
    return x * x

当 Python 执行一条return语句时,函数立即终止。如果 Python 在没有执行return 语句的情况下到达函数体的末尾,它会自动返回None.

相反,print函数用于在终端中显示值。这可能会导致printreturn之间的一些混淆,因为在 Python 解释器中调用函数将打印出函数的返回值。

然而,不同于return声明,当 Python 计算一个print 表达式时,函数并不会立即终止。

def what_prints():
    print('Hello World!')
    return 'Exiting this function.'
    print('61A is awesome!')

>>> what_prints()
Hello World!
'Exiting this function.'

还要注意,print将显示没有引号的文本,但 return会保留引号。

控制

布尔运算符

Python 支持的三种布尔运算符:andornot

>>> a = 4
>>> a < 2 and a > 0
False
>>> a < 2 or a > 0
True
>>> not (a > 0)
False
  • and:只有当两个操作数计算结果都为Trueand的计算结果才为True。如果至少有一个操作数是False, 则and计算结果为False
  • or :如果至少一个操作数计算为True,则or计算结果为True。如果两个操作数都是False,则计算结果为False
  • not :如果其操作数计算为True,则结果为False。如果其操作数计算为False,则结果为True

您认为以下表达式的计算结果是什么?在 Python 解释器中尝试一下。

>>> True and not False or not True and False

很难阅读如上面的复杂的表达式,也很难理解程序的行为方式。使用括号可以使您的代码更容易理解。Python 以下列方式解释该表达式:

>>> (True and (not False)) or ((not True) and False)

这是因为布尔运算符和算术运算符一样,也有一个运算顺序:

  • not 具有最高优先级
  • and
  • or 具有最低优先级

真假值:事实证明andor不仅仅适用于布尔值 ( True, False)。诸如0, None, ''(空字符串)和[] (空列表)之类的 Python 值被视为假值。而所有其他值都被视为真值。

短路

如果我们在 Python 中输入以下内容,您认为会发生什么?

1 / 0

用 Python 试试吧!你应该看到一个ZeroDivisionError. 但是这个表达呢?

True or 1 / 0

它的结果为True,因为 Python andor运算符会短路。也就是说,它们不一定求值每个操作数。

运算符 检查是否: 从左到右求值直到: 例子
AND 所有值都为真 第一个假值 False and 1 / 0 求值为 False
OR 至少有一个值为真 第一个真值 True or 1 / 0 求值为 True

当运算符到达能够对表达式得到结果的操作数时,就会发生短路。例如,and一旦达到第一个假值就会短路,因为它知道并非所有值都为真。

如果andor不短路,它们就返回最后一个值;另一种记住这一点的方法是,无论是否短路andor始终返回求值的最后结果。请记住,使用比其它值时,当使用除了TrueFalse的其他值时,andor并非总是返回布尔值。

条件语句

您可以在《Composing Programs》的1.5.4节中查看if语句的语法。

提示:我们有时会看到如下所示的代码:

if x > 3:
 return True
else:
 return False

这可以更简洁地写成return x > 3. 如果你的代码看起来像上面的代码,看看你能不能更清晰地重写它!

While 循环

您可以在《Composing Programs》的1.5.5节中查看while循环的语法。

错误信息

到现在为止,您可能已经看到了一些错误信息。它们可能看起来令人生畏,但错误消息对于调试代码非常有帮助。以下是一些常见的错误类型:

错误类型 说明
SyntaxError 包含不正确的语法(例如,if语句后缺少冒号或忘记右括号/引号)
IndentationError 包含不正确的缩进(例如,函数体的缩进不一致)
TypeError 尝试对不兼容的类型进行操作(例如尝试对函数和数字使用加法)或使用错误数量的参数调用函数
ZeroDivisionError 试图除以零

使用这些错误消息的说明,您应该能够更好地了解代码出了什么问题。如果遇到错误信息,请在寻求帮助之前尝试确定问题。你可以经常谷歌不熟悉的错误信息,看看其他人是否也犯过类似的错误来帮助你调试。

例如:

>>> square(3, 3)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: square() takes 1 positional argument but 2 were given

笔记:

  • 错误消息的最后一行告诉我们错误的类型。在上面的例子中,我们有一个TypeError.
  • 错误消息告诉我们做错了什么——square当它只能接受 1 个参数时,我们给出了2 个参数。一般来说,最后一行是最有帮助的。
  • 错误消息的倒数第二行告诉我们错误发生在哪一行。这有助于我们追踪错误。在上面的例子中, TypeError发生在line 1

必答题

Python 会显示什么?

问题1:控制

使用 Ok 通过下面的“Python 会显示什么?”来测试您的知识。问题:

python3 ok -q control -u

提示:确保您的while循环条件最终求值为假,否则它们永远不会停止!键入Ctrl-C将停止解释器中的无限循环。

>>> def xk(c, d):
...     if c == 4:
...         return 6
...     elif d >= 4:
...         return 6 + 7 + c
...     else:
...         return 25
>>> xk(10, 10)
______
>>> xk(10, 6)
______
>>> xk(4, 6)
______
>>> xk(0, 0)
______
>>> def how_big(x):
...     if x > 10:
...         print('huge')
...     elif x > 5:
...         return 'big'
...     elif x > 0:
...         print('small')
...     else:
...         print("nothing")
>>> how_big(7)
______
>>> how_big(12)
______
>>> how_big(1)
______
>>> how_big(-1)
______
>>> n = 3
>>> while n >= 0:
...     n -= 1
...     print(n)
______

提示:确保您的while循环条件最终评估为假值,否则它们永远不会停止!键入Ctrl-C将停止解释器中的无限循环。

>>> positive = 28
>>> while positive:
...    print("positive?")
...    positive -= 3
______
>>> positive = -9
>>> negative = -12
>>> while negative:
...    if positive:
...        print(negative)
...    positive += 3
...    negative += 3
______

问题2:真值

使用 Ok 通过下面的“Python 会显示什么?”来测试您的知识。问题:

python3 ok -q short-circuit -u
>>> True and 13
______
>>> False or 0
______
>>> not 10
______
>>> not None
______
>>> True and 1 / 0 and False
______
>>> True or 1 / 0 or False
______
>>> True and 0
______
>>> False or 1
______
>>> 1 and 3 and 6 and 10 and 15
______
>>> -1 and 1 > 0
______
>>> 0 or False or 2 or 1 / 0
______
>>> not 0
______
>>> (1 + 1) and 1
______
>>> 1/0 or True
______
>>> (True or False) and False
______

问题3:调试测验

以下是有关不同调试技术的快速测验,将有助于您在本课程中使用。可以参考 调试 这篇文章回答问题。

使用 Ok 测试您的理解:

python3 ok -q debugging-quiz -u

编程练习

问题4:递降阶乘

让我们编写一个函数falling,它是一个“递降”阶乘,接受两个参数nk,并返回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:数字求和

编写一个函数,接收一个非负整数并将其各位数字相加。(这里使用整除和取模可能会有所帮助!)

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

提交

确保通过运行以下命令提交此作业:

python3 ok --submit

提醒:请填写 实验 0 安装调查(也包含在本作业的开头):此处

额外练习

这些问题是可选的,不会影响您在此作业中的分数。但是,它们是未来作业、项目和考试的绝佳练习。尝试这些问题有助于巩固您对课程概念的了解。

问题6:这会怎样?

使用 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)
______
>>> 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)
______
>>> bake(1, "mashed potatoes")
______

问题7:数字88

编写一个函数,接收一个数字并确定这些数字是否包含两个相邻的 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
最后修改日期: 2021年9月16日

留言

撰写回覆或留言

发布留言必须填写的电子邮件地址不会公开。