Lec4 Functions Recursion PDF
Lec4 Functions Recursion PDF
ABSTRACTION,
FUNCTIONS
GOOD PROGRAMMING
more code not necessarily a good thing
measure good programmers by the amount of
functionality
introduce functions Functions help give you a way to encapsulate pieces of computation
EXAMPLE -- PROJECTOR
projecting large image for
Olympics decomposed into
separate tasks for separate
projectors
each projector takes input
and produces separate output
all projectors work together
to produce larger image
By Adenosine (Own work) [CC BY-SA 3.0
DECOMPOSITION IDEA: (http://creativecommons.org/licenses/by-sa/3.0) or
different devices work GFDL (http://www.gnu.org/copyleft/fdl.html)], via
Wikimedia Commons
together to achieve an end
goal
February 22, 2016 6.0001 LECTURE 6 5
APPLY THESE IDEAS TO
PROGRAMMING
DECOMPOSITION
• Break problem into different, self-contained, pieces
ABSTRACTION
• Suppress details of method to compute something from
use of that computation
def is_even( i ):
"""
"""
expressions you want to evaluate when you're ready to use it. Notice the
print("hi”) indentation
return i%2 == 0
is_even(3)
"""
"""
print("hi”) Return tells you that you're ready to stop the computation.
return i%2 == 0 Whatever the following expression is, that is the value it
will give back to the person who asked for it.
In this case, it could have just been your shell, but it could
also be somebody else that's going to use it as part of
another computation
VARIABLE SCOPE
formal parameter gets bound to the value of
actual parameter when function is called
new scope/frame/environment created when enter a function
scope is mapping of names to objects
return x x 3
x = 3
z = f( x ) call to f, before z
body evaluated
February 22, 2016 6.0001 LECTURE 6 15
Anytime you do a invocation of a function, you create a new frame and bind the formal parameter of that function
to the values of the expressions passed in
VARIABLE SCOPE
formal parameter gets bound to the value of
actual parameter when function is called
new scope/frame/environment created when enter a function
scope is mapping of names to objects
return x x 3
x = 3
z = f( x ) z
February 22, 2016 6.0001 LECTURE 6 16
VARIABLE SCOPE
formal parameter gets bound to the value of
actual parameter when function is called
new scope/frame/environment created when enter a function
scope is mapping of names to objects
return x x 3
x = 3
z = f( x ) z
February 22, 2016 6.0001 LECTURE 6 17
VARIABLE SCOPE
formal parameter gets bound to the value of
actual parameter when function is called
new scope/frame/environment created when enter a function
scope is mapping of names to objects
Global scope
def f( x ):
f Some
x = x + 1
code
print('in f(x): x =', x)
return x x 3
x = 3
"""
If no return statement, rather than returning i%2==0, Python will return
the value None because you did not give a return.
Input: i, a positive int
Represents the absence of value.
Does not return anything
Anytime you want a function to do something, you always want to have at
"""
least one return that gives a value back
i%2 == 0
inside func_a
def func_a(): takes no parameters None inside
func_b
print('inside func_a’) 7
inside func_c
def func_b(y): takes one parameter inside func_a
print('inside func_b’) None
return y
def func_c(z):
print('inside func_c’)
return z()
print(func_a())
print(5 + func_b(2))
in each case, evaluating body with respect to a
print(func_c(func_a)) frame
SCOPE EXAMPLE
inside a function, can access a variable defined outside
inside a function, cannot modify a variable defined
trying to look up the
even though X
outside For g, first you call g with the value of x,
which is 5, which means 5 is going to be
local variable x and
= 5 in "global" won't succeed.
used in place of y
scope, it is def f(y): def g(y): def h(y):
redefined
inside the x = 1 print(x) print 5 x = x + 1
"local" scope
x += 1 print(x + 1)
print 6
print(x) x = 5
print 2 <- global
x = 5 environment h(x)
x = 5 g(x)call g = 5 print(x)
f(x) print(x)
print(x) print 5
Print statement will print
out the value 5 because it
sees the value of x defined in
the global scope
Output: in g(x): x = 4
SCOPE DETAILS
def g(x): Global scope 1. g is bound to some code
2. h hasn't happened yet
def h(): 3. x is bound to 3
g Some
x = 'abc'
code
x = x + 1
return x
z
x = 3 3.
z = g(x)
z
x = 3
z = g(x)
z
x = 3
z = g(x)
z
x = 3
z = g(x)
SCOPE DETAILS
def g(x): Global scope g scope
def h():
g Some x
x = 'abc'
4
code
x = x + 1
None
z
x = 3
z = g(x)
return x
z 4
x = 3
z = g(x)
printName(‘Eric’, ‘Grimson’)
printName(‘Eric’, ‘Grimson’, True)
SPECIFICATIONS
a contract between the implementer of a function and
the clients who will use it
• Assumptions: conditions that must be met by clients of
the function; typically constraints on values of parameters
• Guarantees: conditions that must be met by function,
providing it has been called in manner consistent with
assumptions
If assumptions are met, here are the guarantees.
is_even(3)
WHAT IS RECURSION
a way to design solutions to problems by divide-and-
conquer or decrease-and-conquer
a programming technique where a function calls itself
in programming, goal is to NOT have infinite recursion
• must have 1 or more base cases that are easy to solve
• must solve the same problem on some other input with
the goal of simplifying the larger problem input
In recusion, as long as you don't set up an infinite loop, then you're fine.
As long as you have 1 or more base case that is easy to solve, you can
reduce the solution into a simpler version of the same problem until
you get into a simple base case.
Global scope fact scope fact scope fact scope fact scope
(call w/ n=4) (call w/ n=3) (call w/ n=2) (call w/ n=1)
fact Some n n n n
4 3 2 1
code
= 24 =6 =2
In iteration, you have a looping variable that will change so you know it will end. i.e. mult_iter decreases
by 1 each time which triggers the end clause
INDUCTIVE REASONING
How do we know that our def mult_iter(a, b):
recursive code will work? result = 0
mult_iter terminates while b > 0:
because b is initially positive, result += a
and decreases by 1 each time b -= 1
around loop; thus must
eventually become less than 1 return result
Mathematical Induction: If i want to prove a statement that is indexed on integers is true, for all values in a parameter n, we just have to
prove it's true when n has it's smallest value (n = 0 or n = 1).
- Then, prove that if it is true, on an arbitraty value of n, then we must show it's also true for n + 1
Then, you can deduce that it's true for all values that is n + 1
else:
return a + mult(a, b-1)
Base case, we can show that mult must return correct answer
For recursive case, we can assume that mult correctly returns an
answer for problems of size smaller than b, then by the addition step, it
must also return a correct answer for problem of size b
Thus by induction, code correctly returns answer
February 22, 2016 6.0001 LECTURE 6 51
February 22, 2016 6.0001 LECTURE 6 52
TOWERS OF HANOI
The story:
• 3 tall spikes
• Stack of 64 different sized discs – start on one spike
• Need to move stack to second spike (at which point
universe ends)
• Can only move one disc at a time, and a larger disc can
never cover up a small disc
By André Karwath aka Aka (Own work) [CC BY-SA 2.5 (http://creativecommons.org/licenses/by-sa/2.5)], via Wikimedia
Commons
February 22, 2016 6.0001 LECTURE 6 53
TOWERS OF HANOI
Having seen a set of examples of different sized stacks,
how would you write a program to print out the right
set of moves?
Think recursively!
• Solve a smaller problem move a stack of n-1 onto a spare disk
printMove(fr, to)
else: 3, P1, P3, P2
Towers(n-1, fr, spare, to) move a smaller stack from the From to Spare slot
1, P1, P2, P3
Towers(1, fr, to, spare)
Towers(n-1, spare, to, fr) 3, P3, P2, P1
Note: you can have multiple recursive calls inside of a function body.
Recursive case
• Females(n) = Females(n-1) + Females(n-2)
two invocations of this Females function.
One for n-1 and one for n-2
return 1
else:
return fib(x-1) + fib(x-2)
SOLVING RECURSIVELY?
First, convert the string to just characters, by stripping
out punctuation, and converting upper case to lower
case
Then
• Base case: a string of length 0 or 1 is a palindrome
• Recursive case:
◦ If first character matches last character, then is a palindrome if
middle section is a palindrome
If the string is empty, it's a palindrome.
However, with so many functions, we need to think about how to However, this is cumbersome when we've
handle them got large collections of code.
print(circle.area(3)) Inside circle module, get the function called area and call it on argument 3
print(circle.circumference(3))
results in the following being printed:
3
3.14159
28.27431
18.849539999999998
print(pi)
print(area(3))
this has the effect of creating bindings within the current
scope for all objects defined within circle
statements within a module are executed only the first
time a module is imported