Discussion1主要是围绕control语句(while和if)、environment diagrams进行一些问题的小组讨论和思考。
While and If
Q1: Race
传统的龟兔赛跑问题。设定兔子先按y feet/分的速度跑5分钟,然后再休息5分钟。乌龟一直按照x feet/分的速度跑。问多久后两者第一次相遇。
def race(x, y):
"""The tortoise always walks x feet per minute, while the hare repeatedly
runs y feet per minute for 5 minutes, then rests for 5 minutes. Return how
many minutes pass until the tortoise first catches up to the hare.
>>> race(5, 7) # After 7 minutes, both have gone 35 steps
7
>>> race(2, 4) # After 10 minutes, both have gone 20 steps
10
"""
assert y > x and y <= 2 * x, 'the hare must be fast but not too fast'
tortoise, hare, minutes = 0, 0, 0
while minutes == 0 or tortoise - hare:
tortoise += x
if minutes % 10 < 5:
hare += y
minutes += 1
return minutes
题目给的代码是有问题的。让我们讨论x和y怎样取值的时候,输出的结果是 wrong value 或runs forever的。在分析后发现,此处的minutes只取整数,忽略了小数的情况。当x=2,y=3时,第一次相遇的时间应该是7.5min,但是程序的结果是15min,return wrong value。
思考一个程序runs forever意味着什么。意味着得到的minutes有无数个。此处代码的逻辑是将“第一次追赶上”理解成了“相遇”,即tortoise - hare==0时打断循环。没有了“第一次”这个限定,在一定的x和y输入时就会有无数个结果。我们发现x=4,y=5时程序runs forever。
⚠️注意
- 0 is a false value and all other numbers are true values.也就是说bool(负数)的结果也是True。
Q2: Fizzbuzz
首先要理解什么是Fizz buzz game。“Fizz buzz is a group word game for children to teach them about division”。游戏者轮流递增计数,用 “fizz ”代替任何能被 3 整除的数字,用 “buzz ”代替任何能被 5 整除的数字,用 “fizzbuzz ”代替任何能被 3 和 5 整除的数字。例子如下:
1, 2, Fizz, 4, Buzz, Fizz, 7, 8, Fizz, Buzz, 11, Fizz, 13, 14, Fizz Buzz, 16, 17, Fizz, 19, Buzz, Fizz, 22, 23, Fizz, Buzz, 26, Fizz, 28, 29, Fizz Buzz, 31, 32, Fizz, 34, Buzz, Fizz, ...
def fizzbuzz(n):
"""
>>> result = fizzbuzz(16)
1
2
fizz
4
buzz
fizz
7
8
fizz
buzz
11
fizz
13
14
fizzbuzz
16
>>> print(result)意味着没有return只有print
None
"""
"*** YOUR CODE HERE ***"
m = 1
while m <= n:
if m % 3 ==0 and m % 5==0:
print('fizzbuzz')
elif m % 3== 0 and m % 5 != 0:
print("fizz")
elif m % 3!= 0 and m % 5 == 0:
print('buzz')
else:
print(m)
m = m + 1
总结:用if-elif-else成套可以用条件处理多种情况。非常清晰明了。其中result是None意味着函数没有return只有print。
Problem Solving
这个部分让我持续思考写代码的整个过程。如何将脑中的逻辑传递给计算机呢?数学是其中一个重要的桥梁。我很赞同此处伯克利老师写的解决过程。
A useful approach to implementing a function is to:
- Pick an example input and corresponding output. 选择一个简单案例
- Describe a process (in English) that computes the output from the input using simple steps. 描述大致的过程
- Figure out what additional names you'll need to carry out this process. 细化过程,看过程中哪些数需要存储,引入新name
- Implement the process in code using those additional names.明确name在过程中的作用
- Determine whether the implementation really works on your original example. 用案例结果证实
- Determine whether the implementation really works on other examples. (If not, you might need to revise step 2.) 再用一个例子论证
Q3: Is Prime?
def is_prime(n):
"""
>>> is_prime(10)
False
>>> is_prime(7)
True
>>> is_prime(1) # one is not a prime number!!
False
"""
"*** YOUR CODE HERE ***"#只有两个因子:1和他自己
i = 1
sum=0
while i <= n:
if n % i ==0:
sum=sum+1
else:
sum=sum+0
i=i+1
if sum ==2:
return True
else:
return False
以此题为例。任务:判断这个数是否是质数。可以转化为判断这个数是否只有1和其本身两个因子的数学问题。那么这一过程在程序中具体如何实现呢?对于一个数n,从1到n全部遍历一遍,然后计算n%i 为0的个数是否为2。如果是,则为质数;否则便不是。因为要遍历所以想着要用while。因为要用n%i==0来判断所以要有个数i表示从1到n的遍历。因为要看个数是否为2,所以需要有个name来计数,就是sum。新变量的选择与具体的实现细节分不开。在之前的编程中我可能更看重逻辑,对于name的选择并没有很重视。现在我的一个想法就是要重视对新变量的引入。要在解题的过程中有意识地思考哪些步骤中需要存什么数,这些数是全局的还是局部的,他是为了什么而存在的。
Q4: Unique Digits
def unique_digits(n):
"""Return the number of unique digits in positive integer n.
>>> unique_digits(8675309) # All are unique
7
>>> unique_digits(13173131) # 1, 3, and 7
3
>>> unique_digits(101) # 0 and 1
2
"""
"*** YOUR CODE HERE ***"
sum = 0
b = -1
while n > 0 : #问题:怎么记录上一个位数的数? 222
a = n % 10 #2 2 2
n = (n - a)//10#22 2 0
if b != a:
sum = sum +1# 1
b = a #2
return sum
def has_digit(n, k):#199
"""Returns whether k is a digit in n.
>>> has_digit(10, 1)
True
>>> has_digit(12, 7)
False
"""
assert k >= 0 and k < 10
"*** YOUR CODE HERE ***"
while n > 0 :
a = n % 10#个位数 9 9 1
n = (n - a)//10#19 1 0
if a == k:
return True
return False
解决问题的本质就是获得每一位的位数。要达到这个目的,需要先获得该数的个位数,再将小数点左移一位,再获得该数的个位数,以此类推。
Q5和Q6此处省略。