The last CS 5 lecture you’ll ever need! Inducing labor for the machine! == Reducing labor for humans! On Warner Brothers' insistence, we affirm that this 'C' does not stand for 'Chamber' and 'S' does not stand for 'Secrets.' * Caution: do not take this statement too literally or it is possible find yourself in twice as many CS 5 lectures as you need! Aye! Aye! Aye! mateys… HMC's legal counsel requires us to include these footnotes… Hw #1 due this Sunday, 9/13, at 11:59 pm CS? This is just like magic! did somebody say induction? * Tutoring hours: afternoons & evenings (LAC)
hw1 if you attended lab (see website…) - you receive credit for the lab portion of the HW (#1a, #1b) else: : - you should complete the two lab problems (#1a, #1b) regardless, you should complete the other problems (#2) Extra Credit: Files!Problem #2: Functions Is this Python??
Computation's Dual Identity name: x type: int LOC: "variables as containers" memory location 300 ComputationData Storage name: y type: int LOC: memory location 304
Naming help s! def convertFromSeconds(s): # total seconds """ convertFromSectons(s): Converts an integer # of seconds into a list of [days, hours, minutes, seconds] input s: an int """ seconds = s % 60 # leftover seconds s = (s / 60) # total minutes minutes = s % 60 # leftover minutes s = s / 60 # total hours hours = s % 24 # leftover hours days = s / 24 # total days return [days, hours, minutes, seconds]
Computation's Dual Identity name: x type: int LOC: "variables as containers" memory location 300 ComputationData Storage name: y type: int LOC: memory location 304 accessed through functions…
Comparing disciplines… def g(x): return x**100 g(x) = x 100 CS googlizerMathematical googlizer defined by what it does defined by what it is and how efficiently it does it proceduralstructural
def convertFromSeconds(s): # total seconds """ convertFromSectons(s): Converts an integer # of seconds into a list of [days, hours, minutes, seconds] input s: an int """ seconds = s % 60 # leftover seconds s = (s / 60) # total minutes minutes = s % 60 # leftover minutes s = s / 60 # total hours hours = s % 24 # leftover hours days = s / 24 # total days return [days, hours, minutes, seconds] How functions look… docstring comments code block return statement name input(s)
How functions work… def f(x): return 11*g(x) + g(x/2) What is >>> demo(-4) ? def demo(x): return x + f(x) def g(x): return -1 * x I have a guess… Three functions: Quiz Name(s): The graders have asked - very politely - that names be reasonably legible… Thank you!
How functions work… def f(x): return 11*g(x) + g(x/2) >>> demo(-4) ? def demo(x): return x + f(x) demo x = -4 return -4 + f(-4) def g(x): return -1 * x
How functions work… def f(x): return 11*g(x) + g(x/2) def demo(x): return x + f(x) demo x = -4 return -4 + f(-4) f x = -4 return 11*g(x) + g(x/2) def g(x): return -1 * x >>> demo(-4) ?
How functions work… def f(x): return 11*g(x) + g(x/2) def demo(x): return x + f(x) demo x = -4 return -4 + f(-4) f x = -4 return 11*g(x) + g(x/2) def g(x): return -1 * x These are different x 's ! >>> demo(-4) ?
How functions work… def f(x): return 11*g(x) + g(x/2) def demo(x): return x + f(x) demo x = -4 return -4 + f(-4) f g x = -4 return 11*g(-4) + g(-4/2) x = -4 return -1.0 * x def g(x): return -1 * x >>> demo(-4) ?
How functions work… def f(x): return 11*g(x) + g(x/2) def g(x): return -1 * x def demo(x): return x + f(x) demo x = -4 return -4 + f(-4) f g x = -4 return 11* 4 + g(-4/2) x = -4 return -1 * -4 4 >>> demo(-4) ?
How functions work… def f(x): return 11*g(x) + g(x/2) def g(x): return -1.0 * x def demo(x): return x + f(x) demo x = -4 return -4 + f(-4) f x = -4 return 11* 4 + g(-4/2) >>> demo(-4) ?
How functions work… def f(x): return 11*g(x) + g(x/2) def g(x): return -1 * x def demo(x): return x + f(x) demo x = -4 return -4 + f(-4) f g x = -4 return 11* 4 + g(-4/2) x = -2 return -1 * -2 2 >>> demo(-4) ?
How functions work… def f(x): return 11*g(x) + g(x/2) def g(x): return -1.0 * x def demo(x): return x + f(x) demo x = -4 return -4 + f(-4) f x = -4 return 11* >>> demo(-4) ?
How functions work… def f(x): return 11*g(x) + g(x/2) def g(x): return -1.0 * x def demo(x): return x + f(x) demo x = -4 return -4 + f(-4) f x = -4 return 11* >>> demo(-4) ?
How functions work… def f(x): return 11*g(x) + g(x/2) def g(x): return -1.0 * x def demo(x): return x + f(x) demo x = -4 return >>> demo(-4) 42
Douglas Adams's 42 puzzle answer: 42 question: unknown
Function stacking def f(x): return 11*g(x) + g(x/2) def g(x): return -1 * x def demo(x): return x + f(x) demo x = -4 return -4 + f(-4) f g x = -4 return 11* 4 + g(-4/2) x = -2 return -1 * -2 2 "The stack" (1) remembers separate functions' values for variables… (2) remembers where to send results back to… >>> demo(-4) 42
Function design
Thinking sequentially 5! = 5 * 4 * 3 * 2 * 1 N! = N * (N-1) * (N-2) * … * 3 * 2 * 1 factorial 5! = 120
Recursion == self-reference! Thinking recursively 5! = 5 * 4 * 3 * 2 * 1 N! = N * (N-1) * (N-2) * … * 3 * 2 * 1 factorial 5! = 120 5! = N! =
Warning def fac(N): return N * fac(N-1) This is legal code! I wonder how this code will STACK up!?
def fac(N): return N * fac(N-1) No base case -- the calls to fac will never stop! Make sure you have a base case, then worry about the recursive step... Warning
def fac(N): return fac(N) Roadsigns and recursion examples of self-fulfilling danger
def fac(N): if N <= 1: return 1 Thinking recursively ! Base Case
def fac(N): if N <= 1: return 1 else: return N * fac(N-1) Base Case Recursive Step Thinking recursively ! Human: Base case and 1 stepComputer: Everything else
Behind the curtain… def fac(N): if N <= 1: return 1 else: return N * fac(N-1) >>> fac(1) Result: 1 The base case is No Problem!
Behind the curtain… def fac(N): if N <= 1: return 1 else: return N * fac(N-1) fac(5)
def fac(N): if N <= 1: return 1 else: return N * fac(N-1) fac(5) 5 * fac(4) Behind the curtain…
def fac(N): if N <= 1: return 1 else: return N * fac(N-1) fac(5) 5 * fac(4) 4 * fac(3) Behind the curtain…
def fac(N): if N <= 1: return 1 else: return N * fac(N-1) fac(5) 5 * fac(4) 4 * fac(3) 3 * fac(2) Behind the curtain…
def fac(N): if N <= 1: return 1 else: return N * fac(N-1) fac(5) 5 * fac(4) 4 * fac(3) 3 * fac(2) 2 * fac(1) Behind the curtain…
def fac(N): if N <= 1: return 1 else: return N * fac(N-1) fac(5) 5 * fac(4) 4 * fac(3) 3 * fac(2) 2 * fac(1) 1 "The Stack" Remembers all of the individual calls to fac Behind the curtain…
def fac(N): if N <= 1: return 1 else: return N * fac(N-1) fac(5) 5 * fac(4) 4 * fac(3) 3 * fac(2) 2 * 1 Behind the curtain…
def fac(N): if N <= 1: return 1 else: return N * fac(N-1) fac(5) 5 * fac(4) 4 * fac(3) 3 * 2 Behind the curtain…
def fac(N): if N <= 1: return 1 else: return N * fac(N-1) fac(5) 5 * fac(4) 4 * 6 Behind the curtain…
def fac(N): if N <= 1: return 1 else: return N * fac(N-1) fac(5) 5 * 24 Behind the curtain…
def fac(N): if N <= 1: return 1 else: return N * fac(N-1) fac(5) Result: N*** -> X 1 0 x*** -> N 0 Look familiar? Base Case Recursive Step Behind the curtain…
Let recursion do the work for you.
def fac(N): if N <= 1: return 1 else: return N * fac(N-1) You handle the base case – the easiest possible case to think of! Recursion does almost all of the rest of the problem! Exploit self-similarity Produce short, elegant code Less work ! Let recursion do the work for you.
But you do need to do one step yourself… def fac(N): if N <= 1: return 1 else: return fac(N) You handle the base case – the easiest possible case to think of! This will not work
Breaking Up… …is easy to do with Python s = "This has 2 T's" How do we get at the initial character of s? L = [ 42, 21, 7 ] How do we get at the initial element of L? How do we get at ALL THE REST of s? How do we get at ALL the REST of L?
Recursion Examples def mylen(s): """ input: any string, s output: the number of characters in s """ if : else: base case test!
Recursion Examples def mylen(s): """ input: any string, s output: the number of characters in s """ if s == '': return 0 else: rest = s[1:] len_of_rest = mylen( rest ) total_len = 1 + len_of_rest return total_len
Recursion Examples def mylen(s): """ input: any string, s output: the number of characters in s """ if s == '': return 0 else: rest = s[1:] len_of_rest = mylen( rest ) return 1 + len_of_rest
Recursion Examples def mylen(s): """ input: any string, s output: the number of characters in s """ if s == '': return 0 else: rest = s[1:] return 1 + mylen( rest )
Recursion Examples def mylen(s): """ input: any string, s output: the number of characters in s """ if s == '': return 0 else: return 1 + mylen(s[1:]) There's not much len left here!
mylen('cs5') Behind the curtain…
Recursion Examples def mymax(L): """ input: a NONEMPTY list, L output: L's maximum element """ if : elif : else: base case test! another case…
Recursion Examples def mymax(L): """ input: a NONEMPTY list, L output: L's maximum element """ if len(L) == 1: return L[0] elif L[0] < L[1]: return mymax( L[1:] ) else: return mymax( L[0:1] + L[2:] ) Hey - do I get a slice?!
mymax( [1,7,3,42,5] ) Behind the curtain…
Recursion: not just numbers Relationships Self-similarity elsewhere... Natural phenomena Names / Acronyms What is an “ancestor” ? how much here is leaf vs. stem? GNU == "GNU’s Not Unix"
Recursion: not just numbers Relationships Self-similarity elsewhere... Natural phenomena Names / Acronyms What is an “ancestor” ? GNU all stem! An ancestor is a parent OR an ancestor of a parent… == GNU’s Not Unix
Try it! def power(b,p): Do not hand this one in… Handle negative values of p, as well. """ returns b to the p power using recursion, not ** inputs: int b, int p output: a float """ Want more power ? power(5,2) == 25.0 For example, power(5,-1) == 0.2 (or so) def sajak(s): sajak('wheel of fortune') == 6 What seven-letter English word w maximizes sajak( w ) ? What about y ? You decide… """ returns the number of vowels in the input string, s """ Want more Pat? if : Base case test elif else: Base case test
def power(b,p): """ inputs: base b and power p (an int) implements: b**p """ if p == 0: return elif p > 0: return else: # p < 0 return Recursion is power!
behind the curtain power(2,3)
def sajak(s): Base case? when there are no letters, there are ZERO vowels if it is NOT a vowel, the answer is Rec. step? Look at the initial character. if it IS a vowel, the answer is
def sajak(s): Base case? when there are no letters, there are ZERO vowels if it is NOT a vowel, the answer is just the number of vowels in the rest of s Rec. step? Look at the initial character. if it IS a vowel, the answer is 1 + the number of vowels in the rest of s
def sajak(s): if s == '': return 0 elif s[0]=='a' or s[0]=='e' or… Checking for a vowel: Try #1 Base Case
in >>> 'i' in 'team' False >>> 'cs' in 'physics' True >>> 42 in [41,42,43] True >>> 42 in [ [42], '42' ] ?? I guess Python's the in thing >>> 'i' in 'alien' ?? >>> 3*'i' in 'alien' ?? Perceptive!
def sajak(s): if len(s) == 0: return 0 elif s[0] in 'aeiou': return 1 + sajak(s[1:]) else: return sajak(s[1:]) if it is NOT a vowel, the answer is just the number of vowels in the rest of s if it IS a vowel, the answer is 1 + the number of vowels in the rest of s Base Case Rec. Steps
sajak('eerier') behind the curtain
return != print >>> answer = dbl(21) def dbl(x): """ doubles x """ return 2*x def dblPR(x): """ doubles x """ print 2*x >>> answer = dbl(21) return provides the function call's value … print just prints
Good luck with Homework #1 The key to understanding recursion is to first understand recursion… - advice from a CS 5 student LAC F/Sa/Su office hrs. Friday aft.: CS Labs
Recursion is the root of all computation since it trades description for time. - Alan Perlis Recursion is the secret to all happiness in writing short, powerful functional programs!
while we're here… import random comp = random.choice( range(0,100) ) while True: user = input('Your choice: ') print user, '?' if user == comp: print 'Yes!' break else: print 'No...'
"Quiz" on recursion def power(b,p):def sajak(s): sajak('wheel of fortune') == 6 What five-letter English word w maximizes sajak( w ) ? Names: What about y ? You decide… Handle negative values of p, as well. """ returns the number of vowels in the input string, s """ """ returns b to the p power using recursion and not ** inputs: b and p are ints output: should be a float """ Want more Pat? Want more power ? power(5,2) == 25.0 For example, power(5,-1) == 0.2 (or so)
def sajak(s): if s == '': return 0 else: Checking for a vowel: Try #1 and or not same as in English! but each side has to be a complete boolean value! Base Case
def sajak(s): if len(s) == 0: return 0 else: Checking for a vowel: Try #1 and or not same as in English! but each side has to be a complete boolean value! if s[0] == 'a' or s[0] == 'e' or… Base Case
in Checking for a vowel: Try #2 def sajak(s): if len(s) == 0: return 0 else: Base Case