CS 61A: Structure and Interpretation of Computer Programs 课程官网
Homework 1: Control 作业链接 参考答案
**
//
;略
Fill in the blanks in the following function for adding
a
to the absolute value ofb
, without callingabs
. You may not modify any of the provided code other than the two blanks.
from operator import add, sub
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 = _____
else:
f = _____
return f(a, b)
我的解答(同参考答案):
if b < 0:
f = sub
else:
f = add
return f(a, b)
在Python中,函数作为对象,可以有多个名称。赋值语句f = sub
使名称f
连接到sub()
函数上。调用f(a, b)
与sub(a, b)
等价。f = add
同理。
Write a function that takes three positive numbers and returns the sum of the squares of the two largest numbers. Use only a single line for the body of the function.
def two_of_three(a, b, c):
"""Return x*x + y*y, where x and y are the two largest members of the
positive numbers a, b, and c.
>>> two_of_three(1, 2, 3)
13
>>> two_of_three(5, 3, 1)
34
>>> two_of_three(10, 2, 8)
164
>>> two_of_three(5, 5, 5)
50
"""
return _____
我的解答:
return a * a + b * b + c * c - pow(min(a, b, c), 2)
参考答案:
return max(a*a+b*b, a*a+c*c, b*b+c*c)
# Alternate solution
return a**2 + b**2 + c**2 - min(a, b, c)**2
两种思路:
a**2 == pow(a, 2) == a*a
Write a function that takes an integer
n
that is greater than 1 and returns the largest integer that is smaller thann
and evenly dividesn
.
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 ***"
我的解答:
i = 2
while i <= n ** 0.5:
if n % i:
i += 1
else:
return int(n / i)
return 1
参考答案:
factor = n - 1
while factor > 0:
if n % factor == 0:
return factor
factor -= 1
注意到
>>> largest_factor(15)
5 # 3 * 5 = 15
>>> largest_factor(80)
40 # 2 * 40 = 80
>>> largest_factor(13)
1 # 1 * 13 = 13
因此对于质数以外的输入,从2开始向上遍历可以以较少的迭代次数得到结果。此外,循环的终止条件为i ** 2 > n
,因为因子总是成对出现的。使用上述特性,可以减少循环次数,这是我的解答的思路。
相比之下,参考答案更为直观、简洁,只用了1个return
。
在n % i == 0
的条件下执行return int(n / i)
,此时int(n / i)
可用n // i
代替。参考:
>>> 6 / 2
3.0 # float
>>> 6 // 2
3 # int
>>> 6.0 // 2
3.0
>>> 6.5 / 2
3.25
>>> 6.5 // 2
3.0
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, 3+2, 3-2)
1
>>> if_function(3>2, 3+2, 3-2)
5
"""
if condition:
return true_result
else:
return false_result
def with_if_statement():
"""
>>> result = with_if_statement()
2
>>> print(result)
None
"""
if c():
return t()
else:
return f()
def with_if_function():
"""
>>> result = with_if_function()
1
2
>>> print(result)
None
"""
return if_function(c(), t(), f())
def c():
"*** YOUR CODE HERE ***"
def t():
"*** YOUR CODE HERE ***"
def f():
"*** YOUR CODE HERE ***"
我的解答(同参考答案):
def c():
return False
def t():
print(1)
def f():
print(2)
这道题的重点是,在执行return if_function(c(), t(), f())
时,解释器会首先计算3个函数,并将函数返回值作为参数传入if_function
,c()
的返回值不会影响t()
和f()
的执行。
如果修改代码:
def if_function(condition, true_result, false_result):
if condition:
return true_result()
else:
return false_result()
def with_if_statement():
if c():
return t()
else:
return f()
def with_if_function():
return if_function(c(), t, f)
将函数名作为参数传入if_function()
,在函数内计算。此时with_if_statement()
与with_if_function()
的结果一致。因此在编码时要注意函数参数传递的是函数名还是函数。
这道题的另一个关键点在于,print()
是一个非纯函数(non-pure function),导致t()
和f()
也是非纯函数。与之对应的概念是纯函数(pure function),例如max()
pow()
abs()
等。
Pure functions are restricted in that they cannot have side effects or change behavior over time. Imposing these restrictions yields substantial benefits. First, pure functions can be composed more reliably into compound call expressions. We can see in the non-pure function example above that print does not return a useful result when used in an operand expression. On the other hand, we have seen that functions such as max, pow and sqrt can be used effectively in nested expressions.
CS 61A Textbook Ch. 1.2
非纯函数会带来副作用(side effect),对于print()
而言,它会在标准输出上打印文字。因此,对于嵌套表达式,例如if_function(c(), t(), f())
,使用纯函数作为操作数(operand)会更好。如果这样修改代码:
def t():
return 1
def f():
return 2
with_if_statement()
与with_if_function()
的结果一致,因为此时t()
和f()
是纯函数。
This sequence of values of
n
is often called a Hailstone sequence. Write a function that takes a single argument with formal parameter namen
, prints out the hailstone sequence starting atn
, and returns the number of steps in the sequence:
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 ***"
我的解答:
count = 0
while n > 1:
print(int(n))
count += 1
if n % 2: # odd
n = n * 3 + 1
else: # even
n /= 2
print(int(n))
count += 1
return count
参考答案:
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