Week 3¶
约 824 个字 142 行代码 1 张图片 预计阅读时间 5 分钟
Summary¶
大概需要2.5小时,Lab质量相当高,可以很好的弥补理解上的一些问题
Videos(1h)¶
Functional Abstraction¶
Lambda Function Environments¶
This is main case:
a = 1
def f(g):
a = 2
return lambda y: a * g(y)
f(lambda y: a + y)(a)
# we can get 4(2 * (1 + 1))
Return¶
def search(f):
"""找出能够返回Ture的最小非负整数"""
x = 0
while True:
if f(x):
return x
x += 1
# 下面是一个改进版本
while not f(x):
x += 1
return x
def inverse(f):
"""Return g(y) such that g(f(x)) -> x."""
# 找出使f(x)=y成立的最小x
return lambda y: search(lambda x: f(x) == y)
# 找反函数
sqrt = inverse(square)
Abstraction¶
Choose a name for valued function or parameters.
Some name guideline.
Errors & Tracebacks¶
Teach you check some errors and read tracebacks
Function Examples¶
Midterm 1 Review¶
- WWPP
def delay(arg):
print('delayed')
def g():
return arg
return g
delay(delay)()(6)()
# 分析
# delay(delay) -> 返回g 传入参数为delay函数 print也被调用
# delay(delay)() -> 调用g 返回delay
# delay(delay)()(6) -> 调用delay 传入参数为6 相当于delay(6)=g print也被调用
# delay(delay)()(6)() -> 调用g() 上一步知道传入参数为6 返回6
print(delay(print)()(4))
# 同理分析即可
Last example but a litttle difficult
def horse(mask):
horse = mask
def mask(horse):
return horse
return horse(mask)
mask = lambda horse: horse(2)
horse(mask)
有一种当年玩指针的美感(只要正确的指向就可以明白,这里的环境图确实是加进理解的一种手段)
Implementing Functions¶
Strategy:
- Read the description
- Verify the example & pick a simple one
- If the template is helpful, use it
- Write cide to compute the result
A case
def remove(n, digit):
kept, digits = 0, 0
while n > 0:
n, last = n // 10, n % 10
if last != digit:
kept = kept + last * 10 ** digits
digits += 1
return kept
Decoraters¶
def trace1(fn):
"""Return a version of fn"""
def traced(x):
print('Calling', fn, 'on argument', x)
return fn(x)
return traced
@trace1 # square = trace1(square)
def square(x):
return x * x
@trace1
def sum_squares_ up_to(n):
k = 1
total = 0
while k <= n:
total, k = total + square(k), k + 1
return total
Lab 02(1h)¶
前面是一些基础的Review部分,算是强行带你复习吗?感觉还是不错的,给出了Short-circuiting这个概念详细的解释
这里需要注意lambda表达式和def表达式的一些细微区别
# A lambda expression by itself does not alter
# the environment
lambda x: x * x
# We can assign lambda functions to a name
# with an assignment statement
square = lambda x: x * x
square(3)
# Lambda expressions can be used as an operator
# or operand
negate = lambda f, x: -f(x)
negate(lambda x: x * x, 3)
Note: As we saw in the
lambda
expression section above,lambda
functions have no intrinsic name. When drawinglambda
functions in environment diagrams, they are labeled with the namelambda
or with the lowercase Greek letter λ. This can get confusing when there are multiple lambda functions in an environment diagram, so you can distinguish them by numbering them or by writing the line number on which they were defined.
WWPD¶
Q1: WWPD: The Truth Will Prevail¶
If
and
andor
do not short-circuit, they just return the last value; another way to remember this is thatand
andor
always return the last thing they evaluate, whether they short circuit or not. Keep in mind thatand
andor
don't always return booleans when using values other thanTrue
andFalse
.
Used above info.
只要做完就会对短路求值这件事彻底理解
Q2: WWPD: Higher-Order Functions¶
这个也有点搞,需要稍微仔细一点去想返回的是函数还是调用函数
Q3: WWPD: Lambda¶
注:这个lab真是大开眼界了
Coding Practice¶
Q4: Composite Identity Function¶
Q5: Count Cond¶
这些代码并不难,答案也没有什么很优雅的做法
Environment Diagram Practice¶
Q6: HOF Diagram Practice¶
Optional Questions¶
Q7: Multiple¶
实际上应该是找最小公倍数的问题,有很多优化算法,偷懒打个简单的
可能答案想打个遍历吧,但是显然这样复杂度对于大数来说不划算
Q8: I Heard You Liked Functions...¶
这个题目也是够套娃的...但是也还好逻辑比较简单
Define a function cycle
that takes in three functions f1
, f2
, and f3
, as arguments. cycle
will return another function g
that should take in an integer argument n
and return another function h
. That final function h
should take in an argument x
and cycle through applying f1
, f2
, and f3
to x
, depending on what n
was. Here's what the final function h
should do to x
for a few values of n
:
n = 0
, returnx
n = 1
, applyf1
tox
, or returnf1(x)
n = 2
, applyf1
tox
and thenf2
to the result of that, or returnf2(f1(x))
n = 3
, applyf1
tox
,f2
to the result of applyingf1
, and thenf3
to the result of applyingf2
, orf3(f2(f1(x)))
n = 4
, start the cycle again applyingf1
, thenf2
, thenf3
, thenf1
again, orf1(f3(f2(f1(x))))
- And so forth.
Hint: most of the work goes inside the most nested function.
保险起见写了一个特别简单的版本,可以参考答案的做法
def classifier(n):
def inner_loop(x):
i = 1
while i <= n:
if (i % 3) == 1:
x = f1(x)
elif (i % 3) == 2:
x = f2(x)
elif (i % 3) == 0:
x = f3(x)
i += 1
return x
return inner_loop
return classifier
优雅的递归解法
def g(n):
def h(x):
if n == 0:
return x
return cycle(f2, f3, f1)(n - 1)(f1(x))
return h
return g
Disc 02(30min)¶
相应的测试代码在CS61A的仓库内
Q1: Warm Up¶
trivial
Q2:Make Keeper¶
也是很简单的
Q3: Digit Finder¶
答案使用的是lambda匿名封装(效果可能差不多但是有点帅,想学)
Q4: Match Maker¶
也比较简单,因为已给出了一个框架
def check(x):
while x // (10 ** k) > 0:
if (x % 10) != (x // (10 ** k)) % 10:
return False
x //= 10
return True
return check
总的来说Disc还是比较简单的