http://inst.eecs.berkeley.edu/~cs61a/sp18/
CS 61A LECTURE 4
The Fibonacci Sequence
0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, …
def fib(n):
"""Compute the nth Fibonacci number, for N >= 1."""
pred, curr = 0, 1 #0th and 1st Fibonacci number
k = 1 #curr is the kth Fibonacci number
while k < n:
pred, curr = curr, pred + curr #The next Fibonacci number is the sum of the
k = k + 1 # current one and its predecessor
return curr
def fibo(n):
"""Compute the nth Fibonacci number?"""
pred, curr = 1, 0
k = 0
while k < n:
pred, curr = curr, pred + curr
k = k + 1
return curr
Designing Functions
Characteristics of Functions
def fib(n):
“”“Compute the nth Fibonacci number, for N >= 1.”""
n is an integer greater than or equal to 1
returns a Fibonacci number
return value is the nth Fibonacci number
A Guide to Designing Function
-
Give each function exactly one job.
-
Don’t repeat yourself (DRY). Implement a process just once, but execute it many times.
-
Define functions generally.
Generalizing Patterns with Arguments
"""Generalization"""
from math import pi, sqrt
def area_square(r):
return r * r
def area_circle(r):
return r * r * pi
def area_hexagon(r):
return r * r * 3 * sqrt(3) / 2
$ python -i gen.py >>> area_circle(10)
314.1592653589793
>>> area_hexagon(10)
259.8076211353316
assert
>>> assert 3 > 2, 'Math is broken'
>>> assert 2 > 3, 'That is false'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AssertionError: That is false
from math import pi, sqrt
def area(r, shape_constant):
assert r > 0, 'A length must be positive'
return r * r * shape_constant
def area_square(r):
return area(r, 1)
def area_circle(r):
return area(r, pi)
def area_hexagon(r):
return area(r, 3 * sqrt(3) / 2)
Do not repeat yourself
>>> area_hexagon(10)
259.8076211353316
>>> area_hexagon(-10)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "gen.py", line 16, in area_hexagon
return area(r, 3 * sqrt(3) / 2)
File "gen.py", line 6, in area
assert r > 0, 'A length must be positive'
AssertionError: A length must be positive
Generalizing Over Computational Process
The common structure among functions may be a computational process, rather than a number.
Summation Example
"""Generalization."""
def sum_naturals(n):
"""Sum the first N natural numbers.
>>> sum_naturals(5)
15
"""
total, k = 0, 1
while k <= n:
total, k = total + k, k + 1
return total
def sum_cubes(n):
"""Sum the first N cubes of naturals numbers.
>>> sum_cubes(5)
225
"""
total, k = 0, 1
while k <= n:
total, k = total + pow(k,3), k + 1
return total
Do not repeat then we get
"""Generalization."""
def identity(k):
return k
def cube(k):
return pow(k, 3)
def summation(n, term):
"""Sum the first N terms of a sequence.
>>> summation(5, cube)
225
"""
total, k = 0, 1
while k <= n:
total, k = total + term(k), k + 1
return total
def sum_naturals(n):
"""Sum the first N natural numbers.
>>> sum_naturals(5)
15
"""
return summation(n, identity)
def sum_cubes(n):
"""Sum the first N cubes of naturals numbers.
>>> sum_cubes(5)
225
"""
return summation(n,cube)
$ python -m doctest -v ex.py
Trying:
sum_cubes(5)
Expecting:
225
ok
Trying:
sum_naturals(5)
Expecting:
15
ok
Trying:
summation(5, cube)
Expecting:
225
ok
3 items had no tests:
ex
ex.cube
ex.identity
3 items passed all tests:
1 tests in ex.sum_cubes
1 tests in ex.sum_naturals
1 tests in ex.summation
3 tests in 6 items.
3 passed and 0 failed.
Test passed.
$ python -i ex.py
>>> from operator import mul
>>> def pi_term(k):
... return 8 / mul(4 * k - 3, 4 * k -1)
...
>>> summation(1000000, pi_term)
3.141592153589902
Functions as Return Values
Functions defined within other function bodies are bound to names in a local frame
"""Generalization."""
def make_adder(n):
"""Return a function that takes one argument K
and return K + N.
>>> add_three = make_adder(3)
>>> add_three(4)
7
"""
def adder(k):
return k + n
return adder
amazing!
Call Expressions as Operator Expressions
$ python -i ex.py
>>> make_adder(1)(20)
21
>>> f = make_adder(2000)
>>> f
<function make_adder.<locals>.adder at 0x000002094D885378>
>>> f(13)
2013
The Purpose of Higher-Order Function
Functions are first-class: Functions can be manipulated as values in our programing language.
Higher-order function: A function that takes a function as an argument value or returns a function as a return value.
Higher-order functions:
- Express general methods of computation
- Remove repetition from programs
- Separate concerns among functions
Lambda Expressions
>>> x = 10
>>> square = x * x
>>> x
10
>>> square
100
>>> square = lambda x : x * x
>>> square
<function <lambda> at 0x0000024BED34C1E0>
>>> square(10)
100
>>> (lambda x: x * x)(3)
9
Lambda expressions are not common in Python, but important in general, In some programming languages, they’re totally fundamental.
In other programming languages that didn’t have them for a long time they’re starting to appear because people have realized just how wonderful a lambda expression is !
Lambda expressions in Python cannot contain statements at all!
Lambda Expression Versus Def Statements
- Both create a function with the same domain, range, and behavior.
- Both functions have as their parent the frame in which they were defined.
- Both bind that function to the name square.
- Only the def statement gives the function an intrinsic name.
>>> square = lambda x : x * x
>>> square
<function <lambda> at 0x0000024BED34C1E0>
>>> def square(x):
... return x * x
...
>>> square
<function square at 0x0000024BED685378>