知识点
1.布尔值
Boolean Operations — and, or, not
运算符(Operation) | 计算结果(Result) | 优先级 |
---|---|---|
x or y | if x is false, then y, else x | (1) |
x and y | if x is false, then x, else y | (2) |
not x | if x is false, then True, else False | (3) |
逻辑运算符优先级,not 最高,and 第二, or 第三。
not 运算符优先级低于其它非逻辑运算符,not a == b
相当于 not (a == b)
,如果写成 a == not b
就会报语法错误。
逻辑短路,计算2个值和一个逻辑运算符组成的表达式。
x or y 只有当 bool(x) 为False时,才会计算后面的y,否则直接得出表达式的值。
下面的代码发生短路情况,0为除数不合法,但发生短路,3/0没有被计算。
>>> 1 or 3 / 0
1
x and y 只有当 bool(x) 为True时,才会计算后面的y。
下面的代码发生短路情况
>>> 0 and 3 / 0
0
下面这样的表达式为啥不发生短路。为啥结果不是0
,而是[]
>>> 0 and 3 / 0 or None and 1 or []
[]
逻辑短路,计算2个值和一个逻辑运算符组成的表达式,0 and 3 / 0 发生了短路,0 and 3 / 0计算结果为0,但整个表达式求值没有完。
没有not,所有计算优先级最高的and,一共有两部分
0 and 3 / 0 → 0
None and 1 → None
此时整理成
0 or None or []
此时优先级相同,继续按顺序计算
首先计算
0 or None → None
最后计算
None or [] → []
最后结果为[]
第二个纠结是:
>>> 3 and 4
4
文档上说了x and y if x is false, then x, else y。
2.代码习惯
lab01中Q3-Q5三个题写的像屎一样。
我发现我有一个啰嗦的习惯,就是把参数的值赋值给一个变量,而不是直接使用参数,
Lab 01
Q3: Repeated
Implement the repeated
function, which takes a one-argument function f
, a positive integer n
, and a parameter x
. It returns the result of composing, or applying, f
n
times on x
, i.e., f(f(...f(x)...))
.
def repeated(f, n, x):
"""Returns the result of composing f n times on x.
>>> def square(x):
... return x * x
...
>>> repeated(square, 2, 3) # square(square(3)), or 3 ** 4
81
>>> repeated(square, 1, 4) # square(4)
16
>>> repeated(square, 6, 2) # big number
18446744073709551616
>>> def opposite(b):
... return not b
...
>>> repeated(opposite, 4, True)
True
>>> repeated(opposite, 5, True)
False
>>> repeated(opposite, 631, 1)
False
>>> repeated(opposite, 3, 0)
True
"""
"*** YOUR CODE HERE ***"
我的答案
def repeated(f, n, x):
count = 1
answer = x
while count <= n:
count = count + 1
answer = f(answer)
return answer
更好的答案
def repeated(f, n, x):
while n > 0:
x = f(x)
n -= 1
return x
Q4: Sum Digits
def sum_digits(n):
"""Sum all the digits of n.
>>> sum_digits(10) # 1 + 0 = 1
1
>>> sum_digits(4224) # 4 + 2 + 2 + 4 = 12
12
>>> sum_digits(1234567890)
45
"""
"*** YOUR CODE HERE ***"
我的答案
def sum_digits(n):
yushu = 0
shengxia = n
sum = 0
while shengxia != 0:
yushu = shengxia % 10
sum = sum + yushu
shengxia = shengxia // 10
return sum
更好的答案
def sum_digits(n):
while n != 0:
remainder = n % 10
sum = remainder + sum
n = n // 10
return sum
Q5: Double Eights
Write a function that takes in a number and determines if the digits contain two adjacent 8s.
def double_eights(n):
"""Return true if n has two eights in a row.
>>> double_eights(8)
False
>>> double_eights(88)
True
>>> double_eights(2882)
True
>>> double_eights(880088)
True
>>> double_eights(12345)
False
>>> double_eights(80808080)
False
"""
"*** YOUR CODE HERE ***"
我的答案
def double_eights(n):
count = 0
remainder = 0
shengxia = n
while shengxia != 0:
remainder = shengxia % 10
if remainder == 8:
count = count + 1
else:
count = 0
if count == 2:
return True
shengxia = shengxia // 10
return False
更好的答案
def double_eights(n):
return '88' in str(n)
这个思路和上面的不太一样了
其实按照上面的思路,更简练的写法是 % 100。
Q6: WWPD: Truthiness
>>> 0 or True
True
>>> not '' or not 0 and False
True
>>> 13 and False
False
>>> False or 1
1
>>> '' or 1 and 1/0
False
>>> not 0 and 12 or 0
12
Q7: WWPD: What If?
>>> def xk(c, d):
... if c == 4:
... return 6
... elif d >= 4:
... return 6 + 7 + c
... else:
... return 25
>>> xk(10, 10)
23
>>> xk(10, 6)
23
>>> xk(4, 6)
6
>>> xk(0, 0)
25
>>> def how_big(x):
... if x > 10:
... print('huge')
... elif x > 5:
... return 'big'
... elif x > 0:
... print('small')
... else:
... print("nothin'")
>>> how_big(7)
big
>>> how_big(12)
huge
>>> how_big(1)
small
>>> how_big(-1)
nothin
>>> def so_big(x):
... if x > 10:
... print('huge')
... if x > 5:
... return 'big'
... if x > 0:
... print('small')
... print("nothin'")
>>> so_big(7)
big
>>> so_big(12)
huge
big
>>> so_big(1)
small
nothin
>>> def ab(c, d):
... if c > 5:
... print(c)
... elif c > 7:
... print(d)
... print('foo')
>>> ab(10, 20)
10
foo
>>> def bake(cake, make):
... if cake == 0:
... cake = cake + 1
... print(cake)
... if cake == 1:
... print(make)
... else:
... return cake
... return make
>>> bake(0, 29)
1
29
29
>>> bake(1, "mashed potatoes")
mashed potatoes
mashed potatoes
Q8: Fix the Bug
The following snippet of code doesn’t work! Figure out what is wrong and fix the bugs.
def both_positive(x, y):
"""Returns True if both x and y are positive.
>>> both_positive(-1, 1)
False
>>> both_positive(1, 1)
True
"""
return x and y > 0 # You can replace this line!
我的答案
def both_positive(x, y):
"""Returns True if both x and y are positive.
>>> both_positive(-1, 1)
False
>>> both_positive(1, 1)
True
"""
if x > 0 and y > 0:
return True
else:
return False
Q9: Falling Factorial
Let’s write a function falling, which is a “falling” factorial that takes two arguments, n
and k
, and returns the product of k
consecutive numbers, starting from n
and working downwards.
def falling(n, k):
"""Compute the falling factorial of n to depth k.
>>> falling(6, 3) # 6 * 5 * 4
120
>>> falling(4, 0)
1
>>> falling(4, 3) # 4 * 3 * 2
24
>>> falling(4, 1) # 4
4
"""
"*** YOUR CODE HERE ***"
我的答案
def falling(n, k):
if k == 0:
return 1
count = k - 1
product = n
while count > 0:
count = count - 1
n = n - 1
product = product * n
return product
Q10: Guess Linear
One weakness in the guess_random
strategy is that it can repeat (incorrect) guesses. Rather than guessing wildly, let’s guess numbers in increasing order.
def guess_linear():
"""Guess in increasing order and return the number of guesses."""
prompt_for_number(LOWER, UPPER)
num_guesses = 1
guess = LOWER
"*** YOUR CODE HERE ***"
return num_guesses
我的答案
def guess_linear():
"""Guess in increasing order and return the number of guesses."""
prompt_for_number(LOWER, UPPER)
num_guesses = 1
guess = LOWER
while not is_correct(guess):
guess = guess + 1
num_guesses = num_guesses + 1
return num_guesses
Q11: Guess Binary
Challenge question. The guess_linear
function can take a long time if your number is large. However, a strategy called binary search can find the correct number faster. The idea is to start in the middle of the range and after each incorrect guess ask if the guess is_too_high
or too low. Either way, you can eliminate half the remaining possible guesses.
def guess_binary():
"""Return the number of attempted guesses. Implement a faster search
algorithm that asks the user whether a guess is less than or greater than
the correct number.
Hint: If you know the guess is greater than the correct number, then your
algorithm doesn't need to try numbers that are greater than guess.
"""
prompt_for_number(LOWER, UPPER)
num_guesses = 1
lower, upper = LOWER, UPPER
guess = (lower + upper) // 2
"*** YOUR CODE HERE ***"
return num_guesses
我的答案
def guess_binary():
prompt_for_number(LOWER, UPPER)
num_guesses = 1
lower, upper = LOWER, UPPER
guess = (lower + upper) // 2
while not is_correct(guess):
ifbig = is_too_high(guess)
if ifbig is True:
upper = guess
else:
lower = guess
guess = (lower + upper) // 2
num_guesses = num_guesses + 1
return num_guesses