Download presentation
Presentation is loading. Please wait.
Published byMartina Jacobs Modified over 9 years ago
1
Cyriak: conceptually disruptive recursion… Baaa
2
Welcome to IST338… Be sure to watch your head!
4
We're computationally complete! IST338: now recursing… putting Python to work! Hw 2 – due Friday 2/20 ~ as usual pr1 lab – Turtle! pr2 – Monte Carlo simulation What's next? pr0 reading – Watson! Or re-cursing, depending on your feelings about recursion! pr3+4 – extra-credit probs! & adding building-blocks
5
Recursive design works… 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! … by solving a smaller version of the same problem!
6
mylen('cs5') Behind the curtain: how recursion works... def mylen(s): if s == '': return 0 else: return 1 + mylen(s[1:]) 1 + mylen('s5') 1 + 1 + mylen('5') 1 + 1 + 1 + mylen('') 1 + 1 + 1 + 0
7
mymax( [1,4,3,42,-100,7] ) def mymax(L): if len(L) == 1: return L[0] elif L[0] < L[1]: return mymax( L[1:] ) else: return mymax( L[0:1]+L[2:] ) mymax( [4,3,42,-100,7] ) mymax( [4,42,-100,7] ) mymax( [42,-100,7] ) mymax( [42,7] ) mymax( [42] ) 42 base case drop 1st drop 2nd
8
Picture it! power(2,5) -> 2*2 power(2,0) -> 1 2 0 == 12 5 2*2* 2 4 2 p 2*2* 2 4 power(2,p) -> 2*power(…,…) Do you see the call to power!? def power(b,p): """ returns b to the p power Use recursion, not ** Inputs: int b, int p: the base and the power """ What should this be? power(b,p) ->
9
Picture it! power(2,5) -> 2*2 power(2,0) -> 1 2 0 == 12 5 2*2* 2 4 2 p 2*2* 2 4 power(2,p) -> 2*power(…,…) Do you see the call to power!? Try it! def power(b,p): Handle negative p values w/elif. """ returns b to the p power Use recursion, not ** Inputs: int b, int p: the base and the power """ Want more power? E.g., power(5,-1) == 0.2 if : Base case test p == 0 return else: return Base case Recursive case What should this be? power(b,p) ->
10
power( 2, 5 ) 2* power( 2, 4 ) 2* 2* power( 2, 3 ) 2* 2* 2* power( 2, 2 ) 2* 2* 2* 2* power( 2, 1 ) 2* 2* 2* 2* 2* power( 2, 0 ) 2* 2* 2* 2* 2* 1 32
11
Picture it! sajak('') 0 NOT a space – this is no characters at all. This is the empty string – and it has 0 vowels! def sajak(s): """ returns the number of vowels in the input string, s """ '' sajak('okay') 1+sajak( ) 'okay' sajak('what') 0+sajak( ) 'what' starts with a vowel – count that vowel and delegate the rest to recursion starts with a consonant – so skip it and delegate the rest!
12
Picture it! sajak('') 0 NOT a space – this is no characters at all. This is the empty string – and it has 0 vowels! def sajak(s): What 7-letter English word w maximizes sajak(w) ? """ returns the number of vowels in the input string, s """ Want more Pat? if s == '' : elif else: return Base case test '' sajak('okay') 1+sajak( ) 'okay' sajak('what') 0+sajak( ) 'what' starts with a vowel – count that vowel and delegate the rest to recursion Try it! starts with a consonant – so skip it and delegate the rest!
13
sajak( 'eerier' ) 1+ sajak( 'erier' ) 1+ 1+ sajak( 'rier' ) 1+ 1+ 0+ sajak( 'ier' ) 1+ 1+ 0+ 1+ sajak( 'er' ) 1+ 1+ 0+ 1+ 1+ sajak( 'r' ) 1+ 1+ 0+ 1+ 1+ 0+ sajak( '' ) 1+ 1+ 0+ 1+ 1+ 0+ 0 4
14
def power(b,p): """ inputs: base b and power p (an int) implements: b**p """ if p == 0: return 1.0 elif p < 0: return ____________________ else: return b * power(b,p-1) Recursion is power!
15
# of vowels in s sajak(s): Base case? When there are no letters, there are ZERO vowels if s[0] is NOT a vowel, the answer is Rec. step? Look at the initial character. if s[0] is a vowel, the answer is DESIGNDESIGN sajak( s[1:] ) 1 + sajak( s[1:] )
16
def sajak(s): if s == '': return 0 elif s[0]=='a' or s[0]=='e' or… but how to check for vowels? Is s[0] a vowel?
17
Python is… in >>> 'i' in 'team' False >>> 'cs' in 'physics' True >>> 42 in [41,42,43] True >>> 42 in [[42], '42'] False I guess Python's the in thing >>> 'i' in 'alien' True >>> 3*'i' in 'alien' False
18
def sajak(s): if len(s) == 0: return 0 elif s[0] in 'aeiou': return 1 + sajak(s[1:]) else: return 0 + sajak(s[1:]) if s[0] is NOT a vowel, the answer is just the number of vowels in the rest of s if s[0] IS a vowel, the answer is 1 + the # of vowels in the rest of s Base Case Recursive Cases let's input 'eerier' for s
19
The key to understanding recursion is, first, to understand recursion. - a former student tutors @ LAC all week! Good luck with Homework #1 It's the eeriest!
20
Three random asides… import random choice( L ) choice(['cmc','scripps','pitzer','pomona']) chooses 1 element from the sequence L allows use of dir(random) and help(random) How could you get a random int from 0 to 99 inclusive? from random import * all random functions are now available! choice('mudd') uniform(low,hi) chooses a random float from low to hi floats have 16 places of precision Aargh – so close! range(1,5)[1,2,3,4]
21
A random function… print the guesses ? return the number of guesses ? from random import * def guess( hidden ): """ tries to guess our "hidden" # """ compguess = choice( range(100) ) if compguess == hidden: # at last! print 'I got it!' else: guess( hidden ) Suspicious? I am! slow down… investigate expected # of guesses?!?? Remember, this is [0,1,…,99]
22
Empirical Hypothesis Testing… a.k.a. How many guesses do we expect in order to find the correct number?
23
from random import * import time def guess( hidden ): """ guessing game """ compguess = choice( range(100) ) # print 'I choose', compguess # time.sleep(0.05) if compguess == hidden: # at last! # print 'I got it!' return 1 else: return 1 + guess( hidden ) Recursive guess-counting
24
A few random thoughts… choice( range(1,5)+[4,2,4,2] ) uniform( -20.5, 0.5 ) What are the chances this returns a 2 ? from random import * What're the chances of this being > 0? choice( '1,2,3,4' ) choice( ['1,2,3,4'] ) choice( '[1,2,3,4]' ) choice( [1,2,3,2] ) choice( range(5) ) What's the most likely return value here? Quiz Name(s): What's the most likely return value here? What are the chances of this returning a 4 ? Is this more likely to be even or odd (or same)? Careful! Extra! choice( 0,1,2,3,4 ) choice[ range(5) ] choice( [range(5)] ) Which two of these are syntax errors? What does the third, "correct" one do? and how likely are all these?
25
[ [0,1,2,3,4] ] choice( range(1,5)+[4,2,4,2] ) uniform( -20.5, 0.5 ) What are the chances this returns a 2 ? What're the chances of this being > 0? choice( '1,2,3,4' ) choice( ['1,2,3,4'] ) choice( '[1,2,3,4]' ) choice( [1,2,3,2] ) choice( range(5) ) What's the most likely return value here? What are the chances of this returning a 4 ? Is this more likely to be even or odd (or same)? 1/42 choice( 0,1,2,3,4 ) choice[ range(5) ] choice( [range(5)] ) and how likely are all these? 2/4 or 50% 3/8 ',' 3/7 '1,2,3,4' 1/1 ',' 3/9 even 3/5 [0,1,2,3,4] syntax error correct: always returns [0,1,2,3,4] syntax error 1/1 chance [1,2,3,4,4,2,4,2] Data is in black. Probabilities are in blue.
26
The two Monte Carlos Monte Carlo casino, Monaco Insights via random trials Monte Carlo methods, Math/CS and their denizens…
27
Insights via random trials Monte Carlo casino, Monaco Monte Carlo methods, Math/CS Stanislaw Ulam (Los Alamos badge) Bond, James Bond The two Monte Carlos and their denizens… Ulam, Stan Ulam
28
Monte Carlo in action def countDoubles( N ): """ input: the # of dice rolls to make output: the # of doubles seen """ if N == 0: return 0 # zero rolls, zero doubles… else: d1 = choice( [1,2,3,4,5,6] ) d2 = choice( range(1,7) ) if d1 != d2: return 0+countDoubles( N-1 ) # don't count it else: return 1+countDoubles( N-1 ) # COUNT IT! two dice from 1-6 inclusive where and how is the check for doubles? N is the total number of rolls How many doubles will you get in N rolls of 2 dice?
29
Empirical Hypothesis Testing… a.k.a. How many guesses do we expect in order to find the correct number?
30
Empirical Hypothesis Testing… a.k.a. Run it a zillion times! # this line runs guess(42) 1000 times! LC = [ guess(42) for x in range(1000) ] # Let's look at the first 10 of them: print LC[0:10] # Let's find the average: print "av. guesses:", sum(LC)*1.0/len(LC) Hah! Now I see why they told me I'd be making a zillion euros!
31
Empirical Hypothesis Testing… a.k.a. How likely are we to roll doubles on two six-sided dice? Hah! Now I see why they told me I'd be making a zillion euros!
32
Zillion-times testing! # this runs the doubles-counter 600 times… cd( 600 ) # Run _that_ 100 times (60,000 rolls total!) DBLS = [ cd(600) for x in range(100) ] # Look at the first 10 of these print DBLS[0:10] # Let's find the average: print "av. dbls/600:", sum(DBLS)*1.0/len(DBLS) needed a less continental name…
33
On balance? or maybe lighter is better?
34
Data Functions …together [8,9,10] sq( ) [64,81,100] [ sq(x) for x in [8,9,10] ]
35
List Comprehensions >>> [ 2*x for x in [0,1,2,3,4,5] ] What's the syntax saying here? List Comprehenion result [0, 2, 4, 6, 8, 10]
36
List Comprehensions >>> [ 2*x for x in [0,1,2,3,4,5] ] [0, 2, 4, 6, 8, 10] output input The same as map, only better! this "runner" variable can have any name... x takes on each value and 2*x is output for each one
37
List Comprehensions >>> [ 10*x for x in [0,1,2,3,4,5] if x%2==0] result >>> [ y*21 for y in range(0,3) ] LC result >>> [ s[1] for s in ["hi", "5Cs!"] ] result LC OK – got it. But what about that name?
38
List Comprehensions? >>> [ 2*x for x in [0,1,2,3,4,5] ] [0, 2, 4, 6, 8, 10] Is this really the best name Guido Van Rossum could think of?
39
List Comprehensions? >>> [ 2*x for x in [0,1,2,3,4,5] ] [0, 2, 4, 6, 8, 10] FunLists! Datafuncs? Google map s? A list comprehension by any other name would be as sweet…
40
[ n**2 for n in range(0,5) ] Quiz! [ a*(a-1) for a in range(8) if a%2==1 ] [ -7*b for b in range(-6,6) if abs(b)>4 ] [ s[1::2] for s in ['aces','451!'] ] [ 42 for z in [0,1,2] ] A range of list comprehensions... Write Python's result for each L.C.: [ z for z in [0,1,2] ] I wonder if these will be useful ?! Name(s): ___________________________
41
Syntax ?! a (frustrated!) rendering of an unfamiliar math problem >>> [ 2*x for x in [0,1,2,3,4,5] ] [0, 2, 4, 6, 8, 10] at first… a jumble of characters and random other stuff
42
Syntax ?! a (frustrated!) rendering of an unfamiliar math problem >>> [ 2*x for x in [0,1,2,3,4,5] ] [0, 2, 4, 6, 8, 10] at first… a jumble of characters and random other stuff
43
Syntax ~ is CS's key resource! a (frustrated!) rendering of an unfamiliar math problem which was likely similar to these… Where'd the change happen?
44
Syntax vs. Semantics Plus – you might consider coming to the Career Fair this Friday at HMC's LAC…
45
Another Monte Carlo Monty… ? inspiring the “Monty Hall paradox”
46
Let's make a deal… '63-'86 inspiring the Monty Hall paradox Monty
47
Let's make a deal: XKCD's take… … but what if you considered the goat the grand prize!? inspiring the Monty Hall paradox Monty
48
Monte Carlo Monty Hall Suppose you always switch to the other door... What are the chances that you will win the prize ? Run it (randomly) 300 times and see!
49
Monte Carlo Monty Hall def MCMH( init, sors, N ): """ plays the "Let's make a deal" game N times returns the number of times you win the *Spam!* """ if N == 0: return 0 # don't play, can't win przDoor = choice([1,2,3]) # where the spam (prize) is… if init == przDoor and sors == 'stay': result = 'Spam!' elif init == przDoor and sors == 'switch': result = 'pmfp.' elif init != przDoor and sors == 'switch': result = 'Spam!' else: result = 'pmfp.' print 'You get the', result if result == 'Spam!': return 1 + MCMH( init, sors, N-1 ) else: return 0 + MCMH( init, sors, N-1 ) Your initial choice! 'switch' or 'stay' number of times to play
50
CS for Insight! a.k.a. How often do we win if we SWITCH vs. STAY ? I hope the prize isn't in Euros!
51
Monte Carlo Monty Hall! # this runs the game once (staying…) MCMHonce1( 3, 'stay' ) # Run _that_ 3000 times PRIZES = [ MCMH1(3,'stay') for x in range(3000) ] # Look at the first 10 of these print PRIZES[0:10] # Let's find the total number of wins: how to do this… ?!
52
A B C D E F G H 0 1 2 34 5 6 7 8 9
53
A B C D E F G H 0 1 2 34 5 6 7 8 9
54
An example closer to home... 25262728502423220 An overworked CGU student (S) leaves Harg. after their "late-night" breakfast. Each moment, they randomly stumble toward class (W) or their Apartment (E) ACB Apt (S) (W) Harg. Write a program to model and analyze! this scenario... Once the student arrives at the dorm or classroom, the trip is complete. The program should then print the total number of steps taken. hw2pr2 rwpos(s,nsteps)rwsteps(s,low,hi) take nsteps random steps starting at s take random steps starting at s until you reach either low or hi S
55
An example closer to home... 25262728502423220 An overworked CGU student (S) leaves Harg. after their "late-night" breakfast. Each moment, they randomly stumble toward class (W) or their Apartment (E) ACB Apt (S) (W) Harg. Write a program to model and analyze! this scenario... Once the student arrives at the dorm or classroom, the trip is complete. The program should then print the total number of steps taken. hw2pr2 rwpos(s,nsteps)rwsteps(s,low,hi) take nsteps random steps starting at s take random steps starting at s until you reach either low or hi S How could we create this as an "ASCII" animation?
56
Nature prefers recursion, too! Recursion's challenge? You need to see BOTH the self-similar pieces AND the whole thing simultaneously!
58
Yes... and no.Are these rules for real?
59
Dragon's-blood Tree
60
There still has to be a base case…
61
or else!
62
Cyriak: conceptually disruptive recursion… is the branching, not the single-path variety. handfingers
63
Python's Etch-a-Sketch the turtle's canvas import time from turtle import * def draw(): shape('turtle') # pause time.sleep(2) # drawing… width(5) left(90) forward(50) right(90) backward(50) down() or up() color('darkgreen') tracer(1) or tracer(0) width(5) http://docs.python.org/library/turtle.html degrees! sets if the pen draws or not sets if the pen animates or not (0,0) window_height() window_width() (42,42) pixels!
64
Single-path recursion def tri(): """ a triangle! """ forward(100) left(120) forward(100) left(120) forward(100) left(120) Let's tri this with recursion: (1) How about any regular N-gon? (2) I don't know about tri, but there sure is NO return … ! def tri( n ): """ draws a triangle """ if n==0: return else: forward(100) # one side left(120) # turn 360/3 tri( n-1 ) # draw rest def poly(n, N): """ draws a triangle """ if n==0: return else: forward(100) # one side left(360.0/N) # turn 360/N poly(n-1, N) # draw rest
65
def chai(size): """ mystery! """ forward(size) left(90) forward(size/2.0) right(90) forward(size) left(90) forward(size/2.0) right(90) backward(size) What does chai(100) draw? (1) Be the turtle ! Finish rwalk so it draws a "stock-market" path: N steps of 10 pixels each. Use recursion. (2) from random import * def rwalk(N): """ make N 10-pixel steps, NE or SE """ if N == 0: return elif choice(['left','right']) == 'left': else: # this handles 'right' Extra! How could you make it a bull (or a bear) market? one possible result of rwalk(20) left(45) forward(10) What if you called chai(size/2) betw. the right(90) & left(90) calls? ? ? Extra!
66
def chai(size): """ mystery! """ if size<9: return forward(size) left(90) forward(size/2.0) right(90) forward(size) left(90) forward(size/2.0) right(90) backward(size) How could you add more to each T-tip?Why are there two identical commands in a row ~ twice!? (1) What does chai(100) do?
67
from random import * def rwalk(N): """ make N 10-px steps, NE or SE """ if N == 0: return elif choice(['left','right'])=='left': left(45) forward(10) right(45) rwalk( N-1 ) else: # 'right' right(45) forward(10) left(45) rwalk( N-1 ) What if we didn't turn back to face east each time? (2) rwalk is a random stock market walk... Extra: Creating a bull (or a bear) market?
68
hw2pr1 100 81 spiral( initLength, angle, multiplier ) spiral(100,90,0.9) 90 fractal art!
69
svtree( trunkLength, levels ) svtree( 100, 5 ) levels == 5 levels == 2 levels == 0 (no drawing) levels == 1 levels == 3 levels == 4
70
svtree( trunkLength, levels ) svtree( 100, 5 ) levels == 5 levels == 2 levels == 0 (no drawing) levels == 1 svtree( 75, 4 ) What steps does the turtle need to take before recursing? levels == 3 levels == 4
71
svtree( trunkLength, levels ) levels == 5 levels == 4 levels == 3 levels == 2 levels == 0 (no drawing) Be sure the turtle always returns to its starting position! levels == 1 svtree( 100, 5 ) step #1: go forward… step #2: turn a bit… step #3: draw a smaller svtree! step #4: turn to another heading step #5: draw another smaller svtree! step #6: get back to the start by turning and moving!
72
svtree( trunkLength, levels ) svtree( 100, 5 ) levels == 5 levels == 2 levels == 0 (no drawing) levels == 1 svtree( 75, 4 ) Be sure the turtle always returns to its starting position! that means it will finish the recursive call right here! levels == 3 levels == 4
73
The Koch curve snowflake(100, 0)snowflake(100, 1)snowflake(100, 2) snowflake(100, 3)snowflake(100, 4)snowflake(100, 5)
74
Recursive art? Create your own… hw2pr4 Happy turtling! What? Way too happy to be art… My recursive compositions burninate even Cyriak's brain! seven-cornered confetti
76
A B C D E F G H 0 1 2 34 5 6 7 8 9
77
Data Functions [13,14,15] sum( ) [3,4,5,6,7,8,9]
78
sum range def sum(L): """ input: L, a list of #s output: L's sum """ if len(L) == 0: return 0.0 else: return L[0] + sum(L[1:]) Base Case Recursive Case
79
def range(low,hi ): """ input: ints low and hi output: int list from low to hi """ if low >= hi: return [] else: return what's cookin' here? excluding hi sum range step?
80
>>> sum(range(1,101)) ? sum and range I'd bet you have a 50/50 chance on this one… - Ben. L '14 1784
81
>>> sum(range(1,101)) ? sum and range I'd bet you have a 50/50 chance on this one… - Ben. L '14 1784 and 100 more… http://www.americanscientist.org/template/AssetDetail/assetid/50686 Gauss's storied story…
82
sum and range Looks sort of scruffy for a 7-year old… ! and 100 more… http://www.americanscientist.org/template/AssetDetail/assetid/50686 1784 >>> sum(range(1,101)) 5050 Gauss's storied story…
83
Welcome to CS 5! Be sure to watch your head…
85
Designing with LCs >>> [ _______ for x in range(4) ] [0, 14, 28, 42] >>> [ _____________ for c in 'igetthis' ] [True, False, False, False, False, False, True, False] [ 1, 0, 0, 0, 0, 0, 1, 0 ] output input And what if we wanted these values in red…? [0,1,2,3]
86
LC = [1 for x in L] return sum( LC ) myst1(L): def [7,8,9] But one-liners are my specialty… Sweet! Using LCs LC = [letScore(c) for c in S] return sum( LC ) myst2(S): def 'twelve' lots of ifs… return score letScore(c): def
87
LC = [1 for x in L] return sum( LC ) len(L): def [7,8,9] But one-liners are my specialty… Sweet! Using LCs LC = [letScore(c) for c in S] return sum( LC ) scrabbleScore(S): def 'twelve' lots of ifs… return score letScore(c): def
88
stuff to get score… return score letScore(c): scrScore(s): LC = [ letScore(c) for c in s] return sum( LC ) def scrabble score! 'twelve' Using LCs
89
LC = [1 for x in L] return sum( LC ) len(L): def But in one-line … ? 'cs5' len(L): def return sum([1 for x in L]) Maybe too terse! Sweet! "One-line" LCs
90
count(e,L): LC = [ 1 for x in L if ] return sum( LC ) def sajak(s): LC = [ for c in s] return sum( LC ) # of vowels Remember True == 1 and False == 0 def 'sequoia' count(e,L): # of times e is in L LC = [ for x in L ] return sum( LC ) def [3,42,5,7,42] 42 using if instead…
91
Go! Write each of these functions using list comprehensions… def nodds(L): def lotto(Y,W): input: L, any list of #s output: the # of odd #s in L example: nodds( [3,4,5,7,42] ) == 3 inputs: Y and W, two lists of "lottery" numbers (ints) output: the # of matches between Y & W example: lotto( [5,7,42,47], [3,5,7,44,47] ) == 3 Y are your #sW are the winning #s def ndivs(N): input: N, an int >= 2 output: the # of positive divisors of N example: numdivs(12) == 6 (1,2,3,4,6,12) LC = [ for x in L ] return sum(LC) def primesUpTo(P): input: P, an int >= 2 output: the list of prime #s up to + incl. P example: primesUpTo(12) == [2,3,5,7,11] Extra! LC = [
92
output: the # of odd #s in L def nodds(L): inputs: L, any list of #s example: nodds( [3,4,5,7,42] ) == 3 LC = [ for x in L ] return sum(LC) def nodds(L): LC = [ 1 for x in L ] return sum(LC)
93
def lotto(Y,W): LC = [ for w in W ] return sum(LC) def lotto(Y,W): LC = [ 1 for w in W ] return sum(LC) inputs: Y and W, two lists of "lottery" numbers (ints) output: the # of matches between Y & W example: lotto( [5,7,42,47], [3,5,7,44,47] ) == 3 Y are your #sW are the winning #s … could adapt to "y in Y", too.
94
def ndivs(N): LC = [ for n in range(1,N+1)] return sum(LC) input: N, an int >= 2 output: the # of positive divisors of N example: numdivs(12) == 6 (1,2,3,4,6,12) def primesUpto( P ): Extra! A list of all primes up to P…
95
Turtle happiness? remember you can run done() after turtle drawing! This releases control of the turtle window to the computer (the operating system). To be honest, it seems that not every machine needs this…
96
We're computationally complete! CS 5: now recursing… putting Python to work! Hw 2 – due Sunday evening ~ usual time pr1 lab – Turtle! pr2, pr3 - Python probs… What's next? pr0 reading – Watson! Or re-cursing, depending on your feelings about recursion! pr4 – extra-credit turtle… ! & adding building-blocks
97
Recursive Art ~ hw2pr4 Submit things that work … … and even things that don't! septagonal confetti Cyriak's pet snake…
98
On-campus tutoring hours… ! CMC: Scripps: Pitzer! Pomona: Beckett Lounge, Mon 6-8 (Melody S) CSMath CR, Adams Hall, Sun 8-10 (Rachel L & Justin A) Edmunds, Sun 8-10 (Kim R) Scripps Student Union, Sun 6-8 (Kate F) Phillips Lounge, Sun 3-5 (Michael I) Beckett Lounge, Sat + Sun 1-3 (Melody S) Motley, Thu 8-10 (Kate F)
99
Picture it! Try it! def power(b,p): Handle negative values of p in an elif. """ returns b to the p power Use recursion, not ** Inputs: int b, int p: the base and the power """ Want more power? power(2,5) -> 2*2 For example, power(5,-1) == 0.2 if : Base case test p == 0 return else: return Base case Recursive case power(2,0) -> 1 2 0 == 12 5 2*2* 2 4 2 p 2*2* 2 4 power(2,p) -> 2*power(…) Do you see the call to power!?
100
Using a Euro, Yuan the deadline comes next time I'll try to make the Mark. I'm Pounding it into my brain, but I have to Peso much attention to other deadlines in the classes I Currency have - but if this keeps up, my grade will be demolished into Rubles. hw0 highlights and thoughts… Eric Nguyen Ashraf Mathkour Martha Parker ! 11:59 !?
101
Using a Euro, Yuan the deadline comes next time I'll try to make the Mark. I'm Pounding it into my brain, but I have to Peso much attention to other deadlines in the classes I Currency have - but if this keeps up, my grade will be demolished into Rubles. hw0 highlights and thoughts… Eric Nguyen Ashraf Mathkour Martha Parker ! 11:59 !? on-campus tutoring! (details Wed. …)
102
Run inside Sublime!? not required + not universal -- but you may want to try it… Python interpreter Python source instructions are at the start of this week's Lab…
103
Try it! def power(b,p): Handle negative values of p in an elif. """ returns b to the p power Use recursion, not ** Inputs: int b, int p: the base and the power """ Want more power? power(2,5) == 32.0 For example, power(5,-1) == 0.2 def sajak(s): sajak('wheel of fortune') == 6 What 7-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 : if s == '' : Base case test elif else: p == 0 return else: return Base case test elif in general:
104
Picture it! def mylen(s): """ returns the number of characters in s input: s, a string """ mylen('') 0 NOT a space – this is no characters at all. This is the empty string – and it has length of 0! s = '' mylen('hi') 1+mylen( ) mylen('recursion') 1+mylen( ) s = 'recursion' starts with a vowel – count that vowel and delegate the rest to recursion wow! s = 'hi' if : Base case test p == 0 return else: return Base case Recursive case
105
Design #2 def mymax(L): """ input: a NONEMPTY list, L output: L's maximum element """ if : elif : base case test! another case… len(L)==1 [1,4,3,42,-100,7] return else:
106
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?! Design #2
107
Computation's Dual Identity name: x type: int LOC: 300 41 memory location 300 ComputationData Storage name: y type: int LOC: 304 42 memory location 304 Last time variables ~ boxes But what does all this stuff look like ?
108
Giving names to data def flipside(s): """ flipside(s): swaps s's sides! input s: a string """ x = len(s)/2 return s[x:] + s[:x] This idea is the key to your happiness!
109
Hey - I'm happy about this, too! Why would computers "prefer" the top version, too? def flipside(s): x = len(s)/2 return s[x:] + s[:x] def flipside(s): return s[len(s)/2:] + s[:len(s)/2] Use variables! Avoid this approach…
110
control-b in Sublime Test! def flipside(s): """ flipside(s): swaps s's sides! input s: a string """ x = len(s)/2 return s[x:] + s[:x] # # Tests! # print "flipside('carpets') ~", flipside('carpets') (1) function definition (2) function tests We provide these tests (for now…) but don't test like this!
111
def convertFromSeconds(s): # total seconds """ convertFromSeconds(s): Converts an integer # of seconds into a list of [days, hours, minutes, seconds] input s: an int """ seconds = s % 60 # leftover seconds m = s / 60 # total minutes minutes = m % 60 # leftover minutes h = m / 60 # total hours hours = h % 24 # leftover hours days = h / 24 # total days return [days, hours, minutes, seconds] This program uses variables constantly! Using variables…
112
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 m = (s / 60) # total minutes minutes = m % 60 # leftover minutes h = m / 60 # total hours hours = h % 24 # leftover hours days = h / 24 # total days return [days, hours, minutes, seconds] How functions look… docstring comments – these are mostly optional in CS 5 code block return statement name input(s)
113
Computation's Dual Identity name: x type: int LOC: 300 41 memory location 300 ComputationData Storage name: y type: int LOC: 304 42 memory location 304 variables ~ boxes accessed through functions… Functions! It's no coincidence this starts with fun!
114
Functioning across disciplines def g(x): return x**100 g(x) = x 100 CS's googolizerMath's googolizer defined by what it does defined by what it is + how efficiently it works procedurestructure
115
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 might have a guess… Quiz First and last name(s): -4
116
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 Hey! This must be a stack-frame frame! stack frame
117
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… stack frame
118
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… These are distinct memory locations both holding x 's. stack frame
119
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… stack frame
120
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… done! stack frame
121
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 x = -4 return 11* 4 + g(-4/2) >>> demo(-4) ? How functions work… the "return value" stack frame
122
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… These are distinct memory locations both holding x 's – and now they also have different values!! stack frame
123
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 x = -4 return 11* 4 + 2 >>> demo(-4) ? How functions work… the "return value" stack frame
124
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 x = -4 return 11* 4 + 2 46 >>> demo(-4) ? How functions work… stack frame
125
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 + 46 42 >>> demo(-4) 42 How functions work… stack frame
126
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 (1) keeps separate variables for each function call… (2) remembers where to send results back to… "The stack" is a memory area that the stack stack frame
127
return > print >>> ans = dbl(21) def dbl(x): """ dbls x? """ return 2*x def dblPR(x): """ dbls x? """ print 2*x >>> ans = dblPR(21)
128
>>> ans = dbl(21) def dbl(x): """ dbls x? """ return 2*x def dblPR(x): """ dbls x? """ print 2*x >>> ans = dblPR(21) return yields the function call's value … print just prints stuff to the screen... … which the shell then prints! return > print
129
Function design
130
Thinking sequentially 5 ! = 5 * 4 * 3 * 2 * 1 N ! = N * (N-1) * (N-2) * … * 3 * 2 * 1 factorial 5 ! = 120
131
factorial 5 ! = 5 * 4 * 3 * 2 * 1 N ! = N * (N-1) * (N-2) * … * 3 * 2 * 1 5 ! = 120 March + beyond… Thinking sequentially
132
Recursion == self-reference! 5 ! = N ! = Thinking recursively 5 ! = 5 * 4 * 3 * 2 * 1 N ! = N * (N-1) * (N-2) * … * 3 * 2 * 1 factorial 5 ! = 120
133
Warning: this is legal! def fac(N): return N * fac(N-1) I wonder how this code will STACK up!?
134
def fac(N): return N * fac(N-1) The calls to fac will never stop: there's no BASE CASE! Make sure you have a base case, then worry about the recursion... legal != recommended
135
def fac(N): return fac(N) Roadsigns and recursion examples of self-fulfilling danger This runs ~ but does not help!
136
Recursion's advantage: It handles arbitrary structural depth – all at once! As a hat, I'm recursive, too!
137
The dizzying dangers of having no base case!
139
def fac(N): if N <= 1: return 1 Thinking recursively Base case
140
def fac(N): if N <= 1: return 1 Thinking recursively Base case "How could I use the factorial of anything smaller than N?" Then do! Ask yourself:
141
def fac(N): if N <= 1: return 1 else: return N*fac(N-1) Recursive case (shorter) Human: Base case and 1 stepComputer: Everything else Base case Thinking recursively
142
def fac(N): if N <= 1: return 1 else: rest = fac(N-1) return rest * N Recursive case (clearer, for some) Human: Base case and 1 stepComputer: Everything else Base case Thinking recursively
143
Behind the curtain… fac(5) def fac(N): if N <= 1: return 1 else: return N * fac(N-1)
144
fac(5) 5 * fac(4) Behind the curtain… def fac(N): if N <= 1: return 1 else: return N * fac(N-1)
145
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) 5 * Operation waiting …
146
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) 5 * 5 * 4 * More operations waiting…
147
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) 5 * 5 * 4 * 5 * 4 * 3 *
148
fac(5) 5 * fac(4) 4 * fac(3) 3 * fac(2) 2 * fac(1) 1 "The Stack" Stack frames hold all of the individual calls to fac Behind the curtain… def fac(N): if N <= 1: return 1 else: return N * fac(N-1) N=5 N=4 N=3 N=2 N=1 5 different N's are living in memory… 5 * 5 * 4 * 5 * 4 * 3 * 5 * 4 * 3 * 2 *
149
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) 5 * 5 * 4 * 5 * 4 * 3 *
150
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) 5 * 5 * 4 *
151
fac(5) 5 * fac(4) 4 * 6 Behind the curtain… def fac(N): if N <= 1: return 1 else: return N * fac(N-1) 5 *
152
fac(5) 5 * 24 Behind the curtain… def fac(N): if N <= 1: return 1 else: return N * fac(N-1)
153
fac(5) Result: 120 0 x*** -> N 0 0 N*** -> X 1 Look familiar? Recursive step Base case show facWPR … Behind the curtain… def fac(N): if N <= 1: return 1 else: return N * fac(N-1)
154
Thinking recursively… What will print when facWPR(5) is called?
155
def fac(N): if N <= 1: return 1 else: rest = fac(N-1) return rest * N You handle the base case – the easiest case! Recursion does almost all of the rest of the problem! You specify one step at the end Let recursion do the work for you. Exploit self-similarity Produce short, elegant code Less work !
156
But you do need to do one step yourself… def fac(N): if N <= 1: return 1 else: return fac(N) This will not work !
157
Nature prefers recursion, too! Recursion's challenge? You need to see BOTH the self-similar pieces AND the whole thing simultaneously!
159
Yes... and no.Are these rules for real?
160
Dragon's-blood Tree
161
There still has to be a base case…
162
or else!
163
Recursive design… (2) Find the self-similarity. (1) Program the base case. (3) Do one step! (4) Delegate the rest to recursion… fun! easy!? cool! Aha! indexing and slicing
164
One step? …is easy to do with Python s = 'aliens' How do we get at the initial character of s? L = [ 42, 21 ] How do we get at ALL THE REST of s? s[0] L[0] s[ ] L[ ] How do we get at the initial element of L? How do we get at ALL THE REST of L? 'liens' [ 21 ]
165
Recursive design #1 def mylen(s): """ input: any string, s output: the number of characters in s """ if : else: base case test! 'cs5' "How could I make use of the length of something smaller than s?" Then do! Ask yourself: return
166
… complete 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!
167
mylen('cs5') Behind the curtain: how recursion works... def mylen(s): if s == '': return 0 else: return 1 + mylen(s[1:]) 1 + mylen('s5') 1 + 1 + mylen('5') 1 + 1 + 1 + mylen('') 1 + 1 + 1 + 0
168
Looking behind the curtain… http://www.pythontutor.com/visualize.html
169
Design #2 def mymax(L): """ input: a NONEMPTY list, L output: L's maximum element """ if : elif : base case test! another case… len(L)==1 [1,4,3,42,-100,7] return else:
170
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?! Design #2
171
mymax( [1,4,3,42,-100,7] ) def mymax(L): if len(L) == 1: return L[0] elif L[0] < L[1]: return mymax( L[1:] ) else: return mymax( L[0:1]+L[2:] ) mymax( [4,3,42,-100,7] ) mymax( [4,42,-100,7] ) mymax( [42,-100,7] ) mymax( [42,7] ) mymax( [42] ) 42 base case drop 1st drop 2nd
172
Try it! def power(b,p): Handle negative values of p in an elif. """ returns b to the p power Use recursion, not ** Inputs: int b, int p: the base and the power """ Want more power? power(2,5) == 32.0 For example, power(5,-1) == 0.2 def sajak(s): sajak('wheel of fortune') == 6 What 7-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 : if s == '': Base case test elif else: p == 0 return else: return Base case test elif in general:
173
power( 2, 5 ) 2* power( 2, 4 ) 2* 2* power( 2, 3 ) 2* 2* 2* power( 2, 2 ) 2* 2* 2* 2* power( 2, 1 ) 2* 2* 2* 2* 2* power( 2, 0 ) 2* 2* 2* 2* 2* 1 32
174
sajak( 'eerier' ) 1+ sajak( 'erier' ) 1+ 1+ sajak( 'rier' ) 1+ 1+ 0+ sajak( 'ier' ) 1+ 1+ 0+ 1+ sajak( 'er' ) 1+ 1+ 0+ 1+ 1+ sajak( 'r' ) 1+ 1+ 0+ 1+ 1+ 0+ sajak( '' ) 1+ 1+ 0+ 1+ 1+ 0+ 0 4
175
def power(b,p): """ inputs: base b and power p (an int) implements: b**p """ if p == 0: return 1.0 elif p < 0: return ____________________ else: return b * power(b,p-1) Recursion is power!
176
# of vowels in s sajak(s): Base case? When there are no letters, there are ZERO vowels if s[0] is NOT a vowel, the answer is Rec. step? Look at the initial character. if s[0] is a vowel, the answer is DESIGNDESIGN sajak( s[1:] ) 1 + sajak( s[1:] )
177
def sajak(s): if s == '': return 0 elif s[0]=='a' or s[0]=='e' or… but how to check for vowels? Is s[0] a vowel?
178
Python is… in >>> 'i' in 'team' False >>> 'cs' in 'physics' True >>> 42 in [41,42,43] True >>> 42 in [[42], '42'] False I guess Python's the in thing >>> 'i' in 'alien' True >>> 3*'i' in 'alien' False
179
def sajak(s): if len(s) == 0: return 0 elif s[0] in 'aeiou': return 1 + sajak(s[1:]) else: return 0 + sajak(s[1:]) if s[0] is NOT a vowel, the answer is just the number of vowels in the rest of s if s[0] IS a vowel, the answer is 1 + the # of vowels in the rest of s Base Case Recursive Cases let's input 'eerier' for s
180
The key to understanding recursion is, first, to understand recursion. - a former CS 5 student tutors @ LAC W/Th/F/Sa/Su Good luck with Homework #1 It's the eeriest!
181
Nature prefers recursion, too! Recursion's challenge? You need to see BOTH the self-similar pieces AND the whole thing simultaneously!
183
Yes... and no.Are these rules for real?
184
Dragon's-blood Tree
185
There still has to be a base case…
186
or else!
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.