这是一个在线活页练习题,您可以在讨论时做。你的作业没有评分,也不需要提交任何东西。

控制结构

控制结构使用逻辑语句引导程序流。例如,条件 ( if-elif-else) 允许程序跳过代码段,而迭代 ( while) 允许程序重复一段代码。

条件语句

条件语句让程序根据特定条件执行不同的代码行。让我们回顾一下if-elif-else语法:

  • elifelse从句是可选的,你可以有任意数量的 elif从句。
  • 条件表达式是一个表达式,计算结果要不为真值(True,一个非零整数等)或一个假值(False0None""[],等等)。
  • 只有在第一个条件表达式计算为真值的if/elif语句下缩进的程序组才会被执行。
  • 如果没有一个条件表达式计算为真值,则执行else程序组。条件语句中只能有一个else从句。

这是一般形式:

if <conditional expression>:
    <suite of statements>
elif <conditional expression>:
    <suite of statements>
else:
    <suite of statements>

布尔运算符

Python 也包括布尔运算符 andornot。这些运算符用于组合和操作布尔值。

  • not返回与后面表达式相反的布尔值,并且始终返回TrueFalse
  • and按顺序计算表达式并在达到第一个假值时停止计算(短路),然后返回它。如果所有值都计算为真值,则返回最后一个值。
  • or按顺序计算表达式并在第一个真值处短路并返回它。如果所有值的计算结果都为假值,则返回最后一个值。

例如:

>>> not None
True
>>> not True
False
>>> -1 and 0 and 1
0
>>> False or 9999 or 1/0
9999

问题1:夹克与天气?

阿方索只有在低于 60 度或下雨的情况下才会在外面穿夹克。

编写一个函数,接收当前温度和一个说明是否正在下雨的布尔值。如果阿方索穿夹克,则此函数应返回True,否则应返回False

首先,尝试使用if语句解决此问题。

def wears_jacket_with_if(temp, raining):
    """
    >>> wears_jacket_with_if(90, False)
    False
    >>> wears_jacket_with_if(40, False)
    True
    >>> wears_jacket_with_if(100, True)
    True
    """
    "*** YOUR CODE HERE ***"

请注意,我们将基于单个条件返回TrueFalse,其真实的值也将为TrueFalse。知道了这一点,试着用一行来写这个函数。

def wears_jacket(temp, raining):
    "*** YOUR CODE HERE ***"

问题2:案例难题

在这个问题里,我们将探讨ifelif的区别。

以下代码求值的结果是什么?

def special_case():
    x = 10
    if x > 0:
        x += 2
    elif x < 13:
        x += 3
    elif x % 2 == 1:
        x += 4
    return x

special_case()

这段代码求值的结果是什么?

def just_in_case():
    x = 10
    if x > 0:
        x += 2
    if x < 13:
        x += 3
    if x % 2 == 1:
        x += 4
    return x

just_in_case()

这段代码呢?

def case_in_point():
    x = 10
    if x > 0:
        return x + 2
    if x < 13:
        return x + 3
    if x % 2 == 1:
        return x + 4
    return x

case_in_point()

哪些代码片段会产生相同的输出,为什么?根据您的发现,您认为何时使用一系列if语句与同时使用ifelif具有相同的效果?

问题3:If 函数 vs 语句

现在我们已经了解了if语句是如何工作的,让我们看看我们是否可以编写一个行为与if语句相同的函数。

def if_function(condition, true_result, false_result):
    """Return true_result if condition is a true value, and
    false_result otherwise.

    >>> if_function(True, 2, 3)
    2
    >>> if_function(False, 2, 3)
    3
    >>> if_function(3==2, 'equal', 'not equal')
    'not equal'
    >>> if_function(3>2, 'bigger', 'smaller')
    'bigger'
    """
    if condition:
        return true_result
    else:
        return false_result

尽管有上面的文档测试,这个函数实际上并没有在所有情况下做与if语句相同的事情。

为了证明这一点,我们想找到一种情况,该函数的行为与if语句不同。要在此问题中做到这样,实现以下内容,

  • cond:这应该作为“if”的“条件”。
  • true_func:这应该代表在“条件”为真的情况下我们希望“if”的结果。
  • false_func:这应该代表在“条件”为假的情况下我们希望“if”的结果。

来让with_if_functionwith_if_statement的行为不一样,也就是在它们的文档测试中指定的那样:

  • with_if_statement被调用时,我们打印出来61A
  • with_if_function被调用时,我们在分开的行中打印出Welcome to61A

实现以下的condtrue_func、 和false_func

提示:如果您在确定with_if_statement 以及with_if_function将如何在行为上有所不同感到困难,考虑if语句的求值规则调用表达式

def with_if_statement():
    """
    >>> result = with_if_statement()
    61A
    >>> print(result)
    None
    """
    if cond():
        return true_func()
    else:
        return false_func()

def with_if_function():
    """
    >>> result = with_if_function()
    Welcome to
    61A
    >>> print(result)
    None
    """
    return if_function(cond(), true_func(), false_func())

def cond():
    "*** YOUR CODE HERE ***"

def true_func():
    "*** YOUR CODE HERE ***"

def false_func():
    "*** YOUR CODE HERE ***"

While 循环

要在程序中多次重复相同的语句,我们可以使用迭代。在 Python 中,我们可以使用 while 循环做到这一点。

while <conditional clause>:
    <statements body>

只要<conditional clause>求值为真, <statements body>就会继续执行。每次主体执行完成时都会求值条件从句。

问题4:平方太慢了

以下代码求值的结果是什么?

def square(x):
    print("here!")
    return x * x

def so_slow(num):
    x = num
    while x > 0:
        x=x+1
    return x / 0

square(so_slow(5))

提示:随着时间的推移x会发生什么?

问题5:是质数吗?

编写一个函数,如果正整数n是质数则返回True,否则返回False

质数 n 是不能被 1 和 n 本身以外任何数整除的数。例如,13 是质数,因为它只能被 1 和 13 整除,但 14 不是,因为它可以被 1、2、7 和 14 整除。

提示:使用%运算符:x % y返回x除以y时的余数。

def is_prime(n):
    """
    >>> is_prime(10)
    False
    >>> is_prime(7)
    True
    """
    "*** YOUR CODE HERE ***"

问题6:Fizzbuzz

实现 fizzbuzz 序列,它为从 1 到 n 的每个数字打印一条语句。对于一个数i

  • 如果i只能被 3 整除,那么我们打印“fizz”。
  • 如果i只能被 5 整除,那么我们打印“buzz”。
  • 如果i可以被 3 和 5 整除,那么我们打印“fizzbuzz”。
  • 否则,我们打印数字i本身。

在这里实现fizzbuzz(n)

def fizzbuzz(n):
    """
    >>> result = fizzbuzz(16)
    1
    2
    fizz
    4
    buzz
    fizz
    7
    8
    fizz
    buzz
    11
    fizz
    13
    14
    fizzbuzz
    16
    >>> result == None
    True
    """
    "*** YOUR CODE HERE ***"

环境图

环境图是一个我们用来追踪所有已定义的变量和它们绑定的值的模型。我们将在整个课程中使用这个工具来理解涉及多个不同赋值和函数调用的复杂程序。

这是一个简短的程序及其对应的图表:

请记住,程序主要是一组语句或指令—因此绘制表示这些程序的图表还涉及以下指令集!让我们深入···

赋值语句

赋值语句,例如x = 3,是在程序中定义变量的。在环境图中执行,会记录变量名和值:

  1. 求值=符号右侧的表达式。
  2. 在当前帧中写入变量名和表达式的值。

问题7:赋值图

使用这些规则为下面的赋值语句绘制环境图:

x = 11 % 4
y = x
x **= 2

image-20210928002709958

def 语句

def语句创建(“定义”)一个函数对象并将其绑定到一个名称。要用图解法表示def语句,请记录函数名并将函数对象绑定到该名称。编写函数的父帧也很重要,这是定义函数的地方。

一个非常重要的注意事项:def语句的赋值使用指向函数的指针,它可以具有与原语赋值(例如绑定到数字的变量)不同的行为。

  1. 将函数对象绘制到帧的右侧,表示函数的内在名称、参数和父帧(例如 func square(x) [parent = Global].
  2. 在当前帧中写入函数名并绘制从名称到函数对象的箭头。

问题8:定义图

使用这些定义函数的规则和赋值语句的规则为下面的代码绘制图表。

def double(x):
    return x * 2

def triple(x):
    return x * 3

hat = double
double = triple

image-20210928003014914

调用表达式

调用表达式,例如square(2),将函数应用于参数。在执行调用表达式时,我们在图表中创建一个新帧来跟踪局部变量:

  1. 求值运算符,它应该计算为一个函数。
  2. 从左到右计算操作数。
  3. 绘制一个新帧,并使用以下内容对其进行标记:
    • 唯一索引 ( f1, f2, f3, …)。
    • 函数的内在名称,这是函数对象本身的名字。例如,如果函数对象是 func square(x) [parent=Global],则内在名称是square
    • 父帧 ([ parent=Global])。
  4. 将形式参数绑定到步骤 2 中获得的参数值(例如绑定x到 3)。
  5. 在这个新帧中求值函数体,直到获得返回值。写下帧中的返回值。

如果函数没有返回值,则隐式返回None。在这种情况下,“返回值”框应包含None.

注意: 由于我们不知道内置函数min(...)或导入函数add(...)是如何实现的,我们在调用它们时不会绘制新的帧,因为我们无法准确填写它。

问题9:调用图

让我们把它们放在一起!为以下代码绘制环境图。您可能不必使用提供给您的所有空白。

def double(x):
    return x * 2

hmmm = double
wow = double(3)
hmmm(wow)

image-20210928003106462

问题10:嵌套调用图

绘制执行以下代码所产生的环境图。您可能不需要使用提供给您的所有帧和空白。

def f(x):
    return x

def g(x, y):
    if x(y):
        return not y
    return y

x = 3
x = g(f, x)
f = g(f, 0)

image-20210928003248472

最后修改日期: 2021年9月28日

留言

撰写回覆或留言

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