CS61A Homework 1: Variables & Functions, Control

271 阅读3分钟

今天是第一次作业,第一次接触Python,导致很多地方不太适应。第一题卡了我半个小时。没想到f可以代表方法名,真是一门灵活的语言。

第一题 :两数之和

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
    >>> # a check that you didn't change the return statement!
    >>> import inspect, re
    >>> re.findall(r'^\s*(return .*)', inspect.getsource(a_plus_abs_b), re.M)
    ['return f(a, b)']
    """
    if b < 0:
        f = _____
    else:
        f = _____
    return f(a, b)

这一题的目标就是不使用abs函数的情况下,获取a + |b|值;但是特别注意的是,return返回的是f(a,b),所以我们这个f只能是方法名,如果我们写了具体实现,则返回值就有问题;

❌ 错误写法

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
    >>> # a check that you didn't change the return statement!
    >>> import inspect, re
    >>> re.findall(r'^\s*(return .*)', inspect.getsource(a_plus_abs_b), re.M)
    ['return f(a, b)']
    """
    
    if b < 0:
        f = a - b # 这种方法f就代表一个具体值,但是我们需要考虑return的情况,所以不能写具体实现。
    else:
        f = a + b
    return f(a, b)

☑️ 正确写法

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
    >>> # a check that you didn't change the return statement!
    >>> import inspect, re
    >>> re.findall(r'^\s*(return .*)', inspect.getsource(a_plus_abs_b), re.M)
    ['return f(a, b)']
    """
    if b < 0:
        f = sub
    else:
        f = add
    return f(a, b)

第二题 三数中最小的两个数的平方和;

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
    >>> # check that your code consists of nothing but an expression (this docstring)
    >>> # a return statement
    >>> import inspect, ast
    >>> [type(x).__name__ for x in ast.parse(inspect.getsource(two_of_three)).body[0].body]
    ['Expr', 'Return']
    """
    return _____

这题需要考虑的就是如何取得最大值,然后将最大值剔除就行,这个远比最小值要简单,因为最小值需要考虑的是负数的情况,需要穷举法才行;

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
    >>> # check that your code consists of nothing but an expression (this docstring)
    >>> # a return statement
    >>> import inspect, ast
    >>> [type(x).__name__ for x in ast.parse(inspect.getsource(two_of_three)).body[0].body]
    ['Expr', 'Return']
    """
    return x * x + y * y + z * z - max(x, y, z) * max(x, y, z)

第三题 最大因子

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
    """
    "*** YOUR CODE HERE ***"

最大因子这一题,就是需要求出除本数之外的最大因子,我一开始考虑的是穷举法,然后遍历取最大值,但是后面一想,a* b = n 当n是最大因子的时候,也就意味着b是除1之外的最小因子,所以我们只需要从1开始递增,找到最小因子,然后相除就可以得到最大因子的数了;

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
    """
    "*** YOUR CODE HERE ***"
    fa = 2
    while (n % fa != 0):
        if fa < n:
            fa = fa + 1
​
    if fa == n:
        return 1
    else:
        return int(n / fa)

第四题 带条件的方法

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
​
​
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 ***"

这一题,需要我们知道方法调用的两种方式,with_if_statement这种调用方法,只会触发cond(),true_func(),false_func() 这里面的两个结果,因为code的结果只能是真/假,所以必然有一个不能执行.我们分下面两种情况讨论;

  • code为True,当code为True的时候,**result = with_if_statement() **出现 61A的结果,那么true_func() 应该就是print('61a');但是我们从后面的题目中可以得知,还需要答应一个 Welcome to到终端,所以,code()必定为false;
  • code为False的情况,那么,false_func()就必须打印'61a',那么true_func()打印的就是' Welcome to',这样顺序执行的时候,才不会导致61A出现在 Welcome to之前;

我们第二种调用方式,就是通过调用参数方法而不是直接调用参数,return if_function(cond(), true_func(), false_func()) 这就是这种情况,这种调用方式,首先会加载形参.而加载形参首先就需要对形参进行初始化,所以,cond(), true_func(), false_func()三个都会首先被加载一遍;

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
    """
    "*** YOUR CODE HERE ***"
    """ time = 1
    while (n != 1):
        print(n)
​
        if n % 2 == 0:
            n = int(n / 2)
        else:
            n = n * 3 + 1
​
        time += 1
​
    print(n)
​
    return time """
    step = 1
    while True:
        print(n)
        if n == 1:
            break
        if n % 2 == 0:
            n = n // 2 # 这里还学到一点,就是我们可以通过//语法向下取整,而避免了int方法转换的操作.
        else:
            n = n * 3 + 1
        step += 1
​
    return step

最后,附上通过截图.第一次作业提交完毕

image.png