问题2

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 = sub
    else:
        f = add
    return f(a, b)

如果b是正数,我们将数字相加。如果b是负数,我们减去数字。因此,我们基于b的符号选择运算符addsub

问题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 min(x*x+y*y, x*x+z*z, y*y+z*z)
    # Alternate solution
def two_of_three_alternate(x, y, z):
    return x**2 + y**2 + z**2 - max(x, y, z)**2

我们使用的事实是,如果x>yy>0,则square(x)>square(y)。所以,我们可以用min取所有对的平方和的最小值。min函数可以接受任意数量的参数。

或者,我们可以计算所有数字的平方和。然后我们挑出最大的数字,然后减去它的平方。

问题4

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
    """
    factor = n - 1
    while factor > 0:
        if n % factor == 0:
            return factor
        factor -= 1

n-1到 1 进行迭代,我们返回第一个整除n的整数。这能保证是n的最大因数。

问题5

def limited(x, z, limit):
    """Logic that is common to invert and change."""
    if x != 0:
        return min(z / x, 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, 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), limit)

在最初的invert_shortchange_short中,我们将首先求值limited函数调用的参数,它在limited被调用之前产生了ZeroDivisionError错误。

因此,我们希望推迟对除法的求值,使其发生在limitedif语句中,观察除以xinvert_shortchange_short之间的另一个共同逻辑。

我们现在可以更新invert_shortchange_short使它们只传入表达式的分子,因为分母是公共表达式 x,现在抽象进limited。没有ZeroDivisionError了!

问题6

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
    """
    length = 1
    while n != 1:
        print(n)
        if n % 2 == 0:
            n = n // 2      # Integer division prevents "1.0" output
        else:
            n = 3 * n + 1
        length = length + 1
    print(n)                # n is now 1
    return length

我们保持跟踪冰雹序列的当前长度和当前值。从那里,我们循环直到到达序列的末尾,每一步更新序列的长度。

注意:我们需要做向下取整除法//来去除小数部分。

问题7

q='q=%r;print (q%%q)';print (q%q)

参考

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

留言

撰写回覆或留言

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