124
CS 301: Recursion The Art of Self Reference Tyler Caraza-Harter

CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

  • Upload
    others

  • View
    0

  • Download
    0

Embed Size (px)

Citation preview

Page 1: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

CS 301: Recursion The Art of Self Reference

Tyler Caraza-Harter

Page 2: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Hofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.”

(From Gödel, Escher, Bach)

https://en.wikipedia.org/wiki/Circular_definition

Goal: use self-reference is a meaningful way

good advice for CS 301 assignments!

Page 3: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Hofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.”

(From Gödel, Escher, Bach)

mountain: “a landmass that projects conspicuously above its surroundings and is higher than a hill”

hill: “a usually rounded natural elevation of land lower than a mountain”

(Example of unhelpful self reference from Merriam-Webster dictionary)

https://en.wikipedia.org/wiki/Circular_definition

Goal: use self-reference is a meaningful way

Page 4: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Overview: Learning ObjectivesRecursive information

• What is a recursive definition/structure? • Arbitrarily vs. infinitely

Recursive code • What is recursive code? • Why write recursive code? • Where do computers keep local variables for recursive calls? • What happens to programs with infinite recursion?

Read Think Python ✦ Ch 5: “Recursion” through “Infinite Recursion” ✦ Ch 6: “More Recursion” through end

Page 5: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Overview: Learning ObjectivesRecursive information

• What is a recursive definition/structure? • Arbitrarily vs. infinitely

Recursive code • What is recursive code? • Why write recursive code? • Where do computers keep local variables for recursive calls? • What happens to programs with infinite recursion?

Read Think Python ✦ Ch 5: “Recursion” through “Infinite Recursion” ✦ Ch 6: “More Recursion” through end

Page 6: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

What is Recursion?

Recursive definitions contain the term in the body • Dictionaries, mathematical definitions, etc

A number x is a positive even number if:

• x is 2

OR

• x equals another positive even number plus two

Page 7: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

What is Recursion?

Recursive definitions contain the term in the body • Dictionaries, mathematical definitions, etc

Recursive structures may refer to structures of the same type • data structures or real-world structures

rowsrows = [ [“A”,[1,2]], [“B”,[3,4,5]], [“C”,[6,7]]] “A” “B” “C”

1 2 3 4 6 75

Page 8: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Recursive structures are EVERYWHERE!

{“name”: “alice”,“grade”: “A”,“score”: 96,“exams”: { “midterm”: {“points”:94, “total”:100}, “final”: {“points”: 98, “total”: 100}}

}

filesdirectories

nature files formats

Page 9: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Example: Trees (Finite Recursion)

Term: branch

Def: wooden stick, with an end splitting into other branches, OR terminating with a leaf

?

Page 10: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Example: Trees (Finite Recursion)

Term: branch

Def: wooden stick, with an end splitting into other branches, OR terminating with a leaf

? ??

Page 11: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Example: Trees (Finite Recursion)

Term: branch

Def: wooden stick, with an end splitting into other branches, OR terminating with a leaf

? ?

Page 12: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Example: Trees (Finite Recursion)

Term: branch

Def: wooden stick, with an end splitting into other branches, OR terminating with a leaf

? ? ?? ?

Page 13: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Example: Trees (Finite Recursion)

Term: branch

Def: wooden stick, with an end splitting into other branches, OR terminating with a leaf

Page 14: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Example: Trees (Finite Recursion)

Term: branch

Def: wooden stick, with an end splitting into other branches, OR terminating with a leaf

trees are arbitrarily large: recursive case allows

indefinite growth

arbitrarily != infinitely

Page 15: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Example: Trees (Finite Recursion)

Term: branch

Def: wooden stick, with an end splitting into other branches, OR terminating with a leaf

trees are arbitrarily large: recursive case allows

indefinite growthtrees are finite:

eventual base caseallows completion

arbitrarily != infinitely

Page 16: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

base case (leaf)

recursive case (branch)

Page 17: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Example: Directories (aka folders)

Term: directory

Def: a collection of files and directories

recursive because def contains term

Page 18: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Example: Directories (aka folders)

file system tree

Term: directory

Def: a collection of files and directories

recursive because def contains term

Page 19: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Example: Directories (aka folders)

file system tree

Term: directory

Def: a collection of files and directories

recursive because def contains term

Page 20: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Example: Directories (aka folders)

file system tree

Term: directory

Def: a collection of files and directories

recursive because def contains term

Page 21: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Example: Directories (aka folders)

file system tree

Term: directory

Def: a collection of files and directories

recursive because def contains term

Page 22: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Example: Directories (aka folders)

file system tree

Term: directory

Def: a collection of files and directories

recursive because def contains term

Page 23: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Example: Directories (aka folders)

file system tree

Term: directory

Def: a collection of files and directories

recursive because def contains term

Page 24: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Example: Directories (aka folders)

file system tree

Term: directory

Def: a collection of files and directories

recursive because def contains term

Page 25: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Example: Directories (aka folders)

file system tree

Term: directory

Def: a collection of files and directories

recursive because def contains term

Page 26: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Example: Directories (aka folders)

Term: directory

Def: a collection of files and directories

recursive because def contains term

file system tree

Page 27: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Example: (simplified) JSON Format

Example JSON Dictionary:

{“name”: “alice”,“grade”: “A”,“score”: 96

}

Page 28: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Example: (simplified) JSON Format

Example JSON Dictionary:

{“name”: “alice”,“grade”: “A”,“score”: 96

}

Term: json-dict Def: a set of json-mapping's

Page 29: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Example: (simplified) JSON Format

Example JSON Dictionary:

{“name”: “alice”,“grade”: “A”,“score”: 96

}

Term: json-dict Def: a set of json-mapping's

Page 30: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Example: (simplified) JSON Format

Example JSON Dictionary:

{“name”: “alice”,“grade”: “A”,“score”: 96

}

Term: json-dict Def: a set of json-mapping's

Term: json-mapping Def: a json-string (KEY) paired with a json-string OR json-number OR json-dict (VALUE)

keys values

Page 31: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Example: (simplified) JSON Format

Example JSON Dictionary:

{“name”: “alice”,“grade”: “A”,“score”: 96

}

Term: json-dict Def: a set of json-mapping's

Term: json-mapping Def: a json-string (KEY) paired with a json-string OR json-number OR json-dict (VALUE)

recursive self reference isn’t always direct!

Page 32: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Example: (simplified) JSON Format

Example JSON Dictionary:

{“name”: “alice”,“grade”: “A”,“score”: 96,“exams”: { “midterm”: 94, “final”: 98}

}

Term: json-dict Def: a set of json-mapping's

Term: json-mapping Def: a json-string (KEY) paired with a json-string OR json-number OR json-dict (VALUE)

Page 33: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Example: (simplified) JSON Format

Example JSON Dictionary:

{“name”: “alice”,“grade”: “A”,“score”: 96,“exams”: { “midterm”: {“points”:94, “total”:100}, “final”: {“points”: 98, “total”: 100}}

}

Term: json-dict Def: a set of json-mapping's

Term: json-mapping Def: a json-string (KEY) paired with a json-string OR json-number OR json-dict (VALUE)

Page 34: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Example: (simplified) JSON Format

Example JSON Dictionary:

{“name”: “alice”,“grade”: “A”,“score”: 96,“exams”: { “midterm”: {“points”:94, “total”:100}, “final”: {“points”: 98, “total”: 100}}

}

Term: json-dict Def: a set of json-mapping's

Term: json-mapping Def: a json-string (KEY) paired with a json-string OR json-number OR json-dict (VALUE)

Page 35: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Overview: Learning ObjectivesRecursive information

• What is a recursive definition/structure? • Arbitrarily vs. infinitely

Recursive code • What is recursive code? • Why write recursive code? • Where do computers keep local variables for recursive calls? • What happens to programs with infinite recursion?

Page 36: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Recursive Code

What is it? • A function that calls itself (possible indirectly)

f g h

call

callcall

Page 37: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Recursive Code

What is it? • A function that calls itself (possible indirectly)

g h

call

call

def f(): # other code f() # other code

Page 38: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Recursive Code

What is it? • A function that calls itself (possible indirectly)

def f(): # other code f() # other code

def g(): # other code h() # other code

def h(): # other code g() # other code

Page 39: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Recursive Code

What is it? • A function that calls itself (possible indirectly)

Motivation: don’t know how big the data is before execution • Need either iteration or recursion • In theory, these techniques are equally powerful

Page 40: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Recursive Code

What is it? • A function that calls itself (possible indirectly)

Motivation: don’t know how big the data is before execution • Need either iteration or recursion • In theory, these techniques are equally powerful

Why recurse? (instead of always iterating) • in practice, often easier • recursive code corresponds to recursive data • reduce a big problem into a smaller problem

https://texastreesurgeons.com/services/tree-removal/

Page 41: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Recursive Students

Example from https://courses.cs.washington.edu/courses/cse143/17au/

eager CS 301 students in the front row

wise and benevolent teacher wearing a top hat

Page 42: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Recursive StudentsImagine:

A teacher wants to know how many students are in a column. What should each student askthe person behind them?

Constraints: • It is dark, you can’t see the back • You can’t get up to count • You may talk to adjacent students • Mic is broken (students in back

can't hear from front)

How many students are in this column?

Example from https://courses.cs.washington.edu/courses/cse143/17au/

Page 43: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Recursive StudentsStrategy: reframe question as “how many students are behind you?”

Example from https://courses.cs.washington.edu/courses/cse143/17au/

how many are behind you?

Page 44: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Recursive StudentsStrategy: reframe question as “how many students are behind you?”

Example from https://courses.cs.washington.edu/courses/cse143/17au/

how many are behind you?

Reframing is the hardest part

Page 45: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Recursive StudentsStrategy: reframe question as “how many students are behind you?”

Process: if nobody is behind you: say 0 else: ask them, say their answer+1

Example from https://courses.cs.washington.edu/courses/cse143/17au/

how many are behind you?

Page 46: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Recursive Students

Example from https://courses.cs.washington.edu/courses/cse143/17au/

how many are behind you?

how many are behind you?

Strategy: reframe question as “how many students are behind you?”

Process: if nobody is behind you: say 0 else: ask them, say their answer+1

Page 47: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Recursive Students

Example from https://courses.cs.washington.edu/courses/cse143/17au/

how many are behind you?

how many are behind you?

how many are behind you?

how many are behind you?

how many are behind you?

Strategy: reframe question as “how many students are behind you?”

Process: if nobody is behind you: say 0 else: ask them, say their answer+1

Page 48: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Recursive Students

Example from https://courses.cs.washington.edu/courses/cse143/17au/

how many are behind you?

how many are behind you?

how many are behind you?

20

how many are behind you?

Strategy: reframe question as “how many students are behind you?”

Process: if nobody is behind you: say 0 else: ask them, say their answer+1

Page 49: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Recursive Students

Example from https://courses.cs.washington.edu/courses/cse143/17au/

how many are behind you?

how many are behind you?

21

20

how many are behind you?

Strategy: reframe question as “how many students are behind you?”

Process: if nobody is behind you: say 0 else: ask them, say their answer+1

Page 50: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Recursive Students

Example from https://courses.cs.washington.edu/courses/cse143/17au/

23

22

21

20

24

Strategy: reframe question as “how many students are behind you?”

Process: if nobody is behind you: say 0 else: ask them, say their answer+1

Page 51: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Recursive Students

Example from https://courses.cs.washington.edu/courses/cse143/17au/

23

22

21

20

24

Strategy: reframe question as “how many students are behind you?”

Process: if nobody is behind you: say 0 else: ask them, say their answer+1

Aha! Clearly there must be 25 students

in this column

Page 52: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Recursive Students

Example from https://courses.cs.washington.edu/courses/cse143/17au/

23

22

21

20

24

Strategy: reframe question as “how many students are behind you?”

Process: if nobody is behind you: say 0 else: ask them, say their answer+1

Observations: • Each student runs the same “code” • Each student has their own “state”

Aha! Clearly there must be 25 students

in this column

Page 53: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Practice: Reframing Factorials

N! = 1 x 2 x 3 x … x (N-2) x (N-1) x N

Page 54: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Example: Factorials3. Recursive Definition:1. Examples:

4. Python Code:

2. Self Reference:

1! = 12! = 1*2 = 23! = 1*2*3 = 64! = 1*2*3*4 = 245! = 1*2*3*4*5 = 120

Goal: work from examples to get to recursive code

def fact(n): pass # TODO

Page 55: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Example: Factorials3. Recursive Definition:1. Examples:

4. Python Code:

2. Self Reference:

1! = 12! = 1*2 = 23! = 1*2*3 = 64! = 1*2*3*4 = 245! = 1*2*3*4*5 = 120

look for patterns that allow rewrites with self reference

def fact(n): pass # TODO

Page 56: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Example: Factorials3. Recursive Definition:1. Examples:

4. Python Code:

2. Self Reference:

1! = 12! = 1*2 = 23! = 1*2*3 = 64! = 1*2*3*4 = 245! = 1*2*3*4*5 = 120

look for patterns that allow rewrites with self reference

def fact(n): pass # TODO

Page 57: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Example: Factorials3. Recursive Definition:1. Examples:

4. Python Code:

2. Self Reference:

1! = 12! = 1*2 = 23! = 1*2*3 = 64! = 1*2*3*4 = 245! = 1*2*3*4*5 = 120

1! =2! =3! =4! =5! = 4! * 5

def fact(n): pass # TODO

Page 58: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Example: Factorials3. Recursive Definition:1. Examples:

4. Python Code:

2. Self Reference:

1! = 12! = 1*2 = 23! = 1*2*3 = 64! = 1*2*3*4 = 245! = 1*2*3*4*5 = 120

1! =2! =3! =4! =5! = 4! * 5

def fact(n): pass # TODO

Page 59: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Example: Factorials3. Recursive Definition:1. Examples:

4. Python Code:

2. Self Reference:

1! = 12! = 1*2 = 23! = 1*2*3 = 64! = 1*2*3*4 = 245! = 1*2*3*4*5 = 120

1! =2! =3! =4! = 3! * 45! = 4! * 5

def fact(n): pass # TODO

Page 60: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Example: Factorials3. Recursive Definition:1. Examples:

4. Python Code:

2. Self Reference:1! =2! = 1! * 23! = 2! * 34! = 3! * 45! = 4! * 5

1! = 12! = 1*2 = 23! = 1*2*3 = 64! = 1*2*3*4 = 245! = 1*2*3*4*5 = 120 def fact(n):

pass # TODO

Page 61: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Example: Factorials3. Recursive Definition:1. Examples:

4. Python Code:

2. Self Reference:1! = 12! = 1! * 23! = 2! * 34! = 3! * 45! = 4! * 5

1! = 12! = 1*2 = 23! = 1*2*3 = 64! = 1*2*3*4 = 245! = 1*2*3*4*5 = 120

don’t need a pattern at the start

def fact(n): pass # TODO

Page 62: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Example: Factorials3. Recursive Definition:1. Examples:

4. Python Code:

2. Self Reference:1! = 12! = 1! * 23! = 2! * 34! = 3! * 45! = 4! * 5

1! = 12! = 1*2 = 23! = 1*2*3 = 64! = 1*2*3*4 = 245! = 1*2*3*4*5 = 120

convert self-referring examples to a recursive definition

def fact(n): pass # TODO

Page 63: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Example: Factorials3. Recursive Definition:1. Examples:

4. Python Code:

2. Self Reference:1! = 12! = 1! * 23! = 2! * 34! = 3! * 45! = 4! * 5

1! = 12! = 1*2 = 23! = 1*2*3 = 64! = 1*2*3*4 = 245! = 1*2*3*4*5 = 120

1! is 1

def fact(n): pass # TODO

Page 64: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Example: Factorials3. Recursive Definition:1. Examples:

4. Python Code:

2. Self Reference:1! = 12! = 1! * 23! = 2! * 34! = 3! * 45! = 4! * 5

1! = 12! = 1*2 = 23! = 1*2*3 = 64! = 1*2*3*4 = 245! = 1*2*3*4*5 = 120

1! is 1 N! is ???? for N>1

def fact(n): pass # TODO

Page 65: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Example: Factorials3. Recursive Definition:1. Examples:

def fact(n): pass # TODO

4. Python Code:

2. Self Reference:1! = 12! = 1! * 23! = 2! * 34! = 3! * 45! = 4! * 5

1! = 12! = 1*2 = 23! = 1*2*3 = 64! = 1*2*3*4 = 245! = 1*2*3*4*5 = 120

1! is 1 N! is (N-1)! * N for N>1

Page 66: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Example: Factorials3. Recursive Definition:1. Examples:

def fact(n): pass # TODO

4. Python Code:

2. Self Reference:1! = 12! = 1! * 23! = 2! * 34! = 3! * 45! = 4! * 5

1! = 12! = 1*2 = 23! = 1*2*3 = 64! = 1*2*3*4 = 245! = 1*2*3*4*5 = 120

1! is 1 N! is (N-1)! * N for N>1

Page 67: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Example: Factorials3. Recursive Definition:1. Examples:

def fact(n): if n == 1: return 1

4. Python Code:

2. Self Reference:1! = 12! = 1! * 23! = 2! * 34! = 3! * 45! = 4! * 5

1! = 12! = 1*2 = 23! = 1*2*3 = 64! = 1*2*3*4 = 245! = 1*2*3*4*5 = 120

1! is 1 N! is (N-1)! * N for N>1

Page 68: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Example: Factorials3. Recursive Definition:1. Examples:

def fact(n): if n == 1: return 1 p = fact(n-1) return n * p

4. Python Code:

2. Self Reference:1! = 12! = 1! * 23! = 2! * 34! = 3! * 45! = 4! * 5

1! = 12! = 1*2 = 23! = 1*2*3 = 64! = 1*2*3*4 = 245! = 1*2*3*4*5 = 120

1! is 1 N! is (N-1)! * N for N>1

Page 69: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Example: Factorials3. Recursive Definition:1. Examples:

def fact(n): if n == 1: return 1 p = fact(n-1) return n * p

4. Python Code:

2. Self Reference:1! = 12! = 1! * 23! = 2! * 34! = 3! * 45! = 4! * 5

1! = 12! = 1*2 = 23! = 1*2*3 = 64! = 1*2*3*4 = 245! = 1*2*3*4*5 = 120

1! is 1 N! is (N-1)! * N for N>1

Let’s “run” it!

Page 70: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

fact(n=4)Tracing Factorial

def fact(n): if n == 1: return 1 p = fact(n-1) return n * p

Note, this is not a stack frame! We're tracing code line-by-line.

Boxes represent which invocation.

somebody called fact(4)

Page 71: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

fact(n=4)if n == 1: Tracing Factorial

def fact(n): if n == 1: return 1 p = fact(n-1) return n * p

Page 72: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

fact(n=4)if n == 1: Tracing Factorial

def fact(n): if n == 1: return 1 p = fact(n-1) return n * p

Page 73: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

fact(n=4)if n == 1: Tracing Factorial

def fact(n): if n == 1: return 1 p = fact(n-1) return n * p

fact(n=3)

Page 74: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

fact(n=4)if n == 1: Tracing Factorial

def fact(n): if n == 1: return 1 p = fact(n-1) return n * p

fact(n=3)if n == 1:

Page 75: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

fact(n=4)if n == 1: Tracing Factorial

def fact(n): if n == 1: return 1 p = fact(n-1) return n * p

fact(n=3)if n == 1:

Page 76: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

fact(n=4)if n == 1: Tracing Factorial

def fact(n): if n == 1: return 1 p = fact(n-1) return n * p

fact(n=3)if n == 1: fact(n=2)

Page 77: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

fact(n=4)if n == 1: Tracing Factorial

def fact(n): if n == 1: return 1 p = fact(n-1) return n * p

fact(n=3)if n == 1: fact(n=2)

if n == 1:

Page 78: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

fact(n=4)if n == 1: Tracing Factorial

def fact(n): if n == 1: return 1 p = fact(n-1) return n * p

fact(n=3)if n == 1: fact(n=2)

if n == 1:

Page 79: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

fact(n=4)if n == 1: Tracing Factorial

def fact(n): if n == 1: return 1 p = fact(n-1) return n * p

fact(n=3)if n == 1: fact(n=2)

if n == 1:

fact(n=1)

Page 80: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

fact(n=4)if n == 1: Tracing Factorial

def fact(n): if n == 1: return 1 p = fact(n-1) return n * p

fact(n=3)if n == 1: fact(n=2)

if n == 1:

fact(n=1)if n == 1:

Page 81: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

fact(n=4)if n == 1: Tracing Factorial

def fact(n): if n == 1: return 1 p = fact(n-1) return n * p

fact(n=3)if n == 1: fact(n=2)

if n == 1:

fact(n=1)if n == 1:

return 1

Page 82: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

fact(n=4)if n == 1: Tracing Factorial

def fact(n): if n == 1: return 1 p = fact(n-1) return n * p

fact(n=3)if n == 1: fact(n=2)

if n == 1:

p = 1

fact(n=1)if n == 1:

return 1

Page 83: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

fact(n=4)if n == 1: Tracing Factorial

def fact(n): if n == 1: return 1 p = fact(n-1) return n * p

fact(n=3)if n == 1: fact(n=2)

if n == 1:

p = 1 return 2

fact(n=1)if n == 1:

return 1

Page 84: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

fact(n=4)if n == 1: Tracing Factorial

def fact(n): if n == 1: return 1 p = fact(n-1) return n * p

fact(n=3)if n == 1:

p = 2

fact(n=2)if n == 1:

p = 1 return 2

fact(n=1)if n == 1:

return 1

Page 85: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

fact(n=4)if n == 1: Tracing Factorial

def fact(n): if n == 1: return 1 p = fact(n-1) return n * p

fact(n=3)if n == 1:

p = 2 return 6

fact(n=2)if n == 1:

p = 1 return 2

fact(n=1)if n == 1:

return 1

Page 86: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

fact(n=4)if n == 1:

p = 6

Tracing Factorial

def fact(n): if n == 1: return 1 p = fact(n-1) return n * p

fact(n=3)if n == 1:

p = 2 return 6

fact(n=2)if n == 1:

p = 1 return 2

fact(n=1)if n == 1:

return 1

Page 87: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

fact(n=4)if n == 1:

p = 6 return 24

Tracing Factorial

def fact(n): if n == 1: return 1 p = fact(n-1) return n * p

fact(n=3)if n == 1:

p = 2 return 6

fact(n=2)if n == 1:

p = 1 return 2

fact(n=1)if n == 1:

return 1

Page 88: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

fact(n=4)if n == 1:

p = 6 return 24

Tracing Factorial

def fact(n): if n == 1: return 1 p = fact(n-1) return n * p

fact(n=3)if n == 1:

p = 2 return 6

fact(n=2)if n == 1:

p = 1 return 2

fact(n=1)if n == 1:

return 1

Page 89: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

fact(n=4)if n == 1:

p = 6 return 24

Tracing Factorial

def fact(n): if n == 1: return 1 p = fact(n-1) return n * p

fact(n=3)if n == 1:

p = 2 return 6

fact(n=2)if n == 1:

p = 1 return 2

fact(n=1)if n == 1:

return 1

How does Python keep all the variables separate?

Page 90: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Tracing Factorial

def fact(n): if n == 1: return 1 p = fact(n-1) return n * p

frames to the rescue!

fact(n=4)if n == 1:

p = 6 return 24

fact(n=3)if n == 1:

p = 2 return 6

fact(n=2)if n == 1:

p = 1 return 2

fact(n=1)if n == 1:

return 1

How does Python keep all the variables separate?

Page 91: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Deep Dive: Invocation StateIn recursion, each function invocation has its own state, but multiple invocations share code.

Page 92: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Deep Dive: Invocation StateIn recursion, each function invocation has its own state, but multiple invocations share code.

Variables for an invocation exist in a frame

frame: variables

Page 93: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Deep Dive: Invocation StateIn recursion, each function invocation has its own state, but multiple invocations share code.

Variables for an invocation exist in a frame • the frames are stored in the stack

frame: stack: activevariables

Page 94: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Deep Dive: Invocation StateIn recursion, each function invocation has its own state, but multiple invocations share code.

Variables for an invocation exist in a frame • the frames are stored in the stack • one invocation is active at a time: its frame is on the top of stack

frame: stack: active

pop!

variables

Page 95: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Deep Dive: Invocation StateIn recursion, each function invocation has its own state, but multiple invocations share code.

Variables for an invocation exist in a frame • the frames are stored in the stack • one invocation is active at a time: its frame is on the top of stack • if a function calls itself, there will be multiple frames at the same

time for the multiple invocations of the same function

frame: stack:fact

variables factfactfactglobal

Page 96: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

global

time0 1 2 3 4 5 6

Current Runtime Stack

Deep Dive: Runtime Stack

def fact(n): if n == 1: return 1 p = fact(n-1) return n * p

Page 97: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

global

time0 1 2 3 4 5 6

Current Runtime Stack

call fact(3)

Deep Dive: Runtime Stack

def fact(n): if n == 1: return 1 p = fact(n-1) return n * p

Page 98: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

global global

factn=3

time0 1 2 3 4 5 6

new, active frame

Current Runtime Stack

Deep Dive: Runtime Stack

def fact(n): if n == 1: return 1 p = fact(n-1) return n * p

Page 99: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

global global

factn=3 p=

def fact(n): if n == 1: return 1 p = fact(n-1) return n * p

time0 1 2 3 4 5 6

Deep Dive: Runtime Stack

Page 100: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

global global

factn=3 p=

global

factn=3 p=

factn=2

time0 1 2 3 4 5 6

Deep Dive: Runtime Stack

def fact(n): if n == 1: return 1 p = fact(n-1) return n * p

Page 101: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

global global

factn=3 p=

global

factn=3 p=

factn=2 p=

def fact(n): if n == 1: return 1 p = fact(n-1) return n * p

time0 1 2 3 4 5 6

Deep Dive: Runtime Stack

Page 102: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

global global

factn=3 p=

global

factn=3 p=

factn=2 p=

global

factn=3 p=

factn=2 p=

factn=1

time0 1 2 3 4 5 6

Deep Dive: Runtime Stack

def fact(n): if n == 1: return 1 p = fact(n-1) return n * p

Page 103: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

global global

factn=3 p=

global

factn=3 p=

factn=2 p=

global

factn=3 p=

factn=2 p=

factn=1 return 1 (base case)

def fact(n): if n == 1: return 1 p = fact(n-1) return n * p

time0 1 2 3 4 5 6

Deep Dive: Runtime Stack

Page 104: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Deep Dive: Runtime Stack

global global

factn=3 p=

global

factn=3 p=

factn=2 p=

global

factn=3 p=

factn=2 p=

factn=1

global

factn=3 p=

factn=2 p=

return 1 (base case)

def fact(n): if n == 1: return 1 p = fact(n-1) return n * p

time0 1 2 3 4 5 6

Page 105: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Deep Dive: Runtime Stack

global global

factn=3 p=

global

factn=3 p=

factn=2 p=

global

factn=3 p=

factn=2 p=

factn=1

global

factn=3 p=

factn=2 p=1

return 1 (base case)

def fact(n): if n == 1: return 1 p = fact(n-1) return n * p

time0 1 2 3 4 5 6

Page 106: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

global global

factn=3 p=

global

factn=3 p=

factn=2 p=

global

factn=3 p=

factn=2 p=

factn=1

global

factn=3 p=

factn=2 p=1

return 1 (base case)

return 2 (n*p)

def fact(n): if n == 1: return 1 p = fact(n-1) return n * p

time0 1 2 3 4 5 6

Deep Dive: Runtime Stack

Page 107: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

global global

factn=3 p=

global

factn=3 p=

factn=2 p=

global

factn=3 p=

factn=2 p=

factn=1

global

factn=3 p=

factn=2 p=1

global

factn=3 p=

return 1 (base case)

return 2 (n*p)

def fact(n): if n == 1: return 1 p = fact(n-1) return n * p

time0 1 2 3 4 5 6

Deep Dive: Runtime Stack

Page 108: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

global global

factn=3 p=

global

factn=3 p=

factn=2 p=

global

factn=3 p=

factn=2 p=

factn=1

global

factn=3 p=

factn=2 p=1

global

factn=3 p=2

return 1 (base case)

return 2 (n*p)

def fact(n): if n == 1: return 1 p = fact(n-1) return n * p

time0 1 2 3 4 5 6

Deep Dive: Runtime Stack

Page 109: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

global global

factn=3 p=

global

factn=3 p=

factn=2 p=

global

factn=3 p=

factn=2 p=

factn=1

global

factn=3 p=

factn=2 p=1

global

factn=3 p=2

return 1 (base case)

return 2 (n*p)

def fact(n): if n == 1: return 1 p = fact(n-1) return n * p

return 6 (n*p)

time0 1 2 3 4 5 6

Deep Dive: Runtime Stack

Page 110: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

global global

factn=3 p=

global

factn=3 p=

factn=2 p=

global

factn=3 p=

factn=2 p=

factn=1

global

factn=3 p=

factn=2 p=1

global

factn=3 p=2

global

return 1 (base case)

return 2 (n*p)

def fact(n): if n == 1: return 1 p = fact(n-1) return n * p

return 6 (n*p)

time0 1 2 3 4 5 6

Deep Dive: Runtime Stack

Page 111: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

“Infinite” Recursion Bugs

What happens if: • •

def fact(n): if n == 1: return 1 p = fact(n-1) return n * p

Page 112: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

“Infinite” Recursion Bugs

What happens if: • we forgot the “n == 1” check? •

def fact(n): if n == 1: return 1 p = fact(n-1) return n * p

Page 113: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

“Infinite” Recursion Bugs

What happens if: • we forgot the “n == 1” check? • factorial is called with a negative number?

def fact(n): if n == 1: return 1 p = fact(n-1) return n * p

-1

Page 114: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

def fact(n): if n == 1: return 1 p = fact(n-1) return n * p

“Infinite” Recursion Bugs

What happens if: • we forgot the “n == 1” check? • factorial is called with a negative number?

never terminates

-1 fact

p = fact

Page 115: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

“Infinite” Recursion Bugs

What happens if: • we forgot the “n == 1” check? • factorial is called with a negative number?

global

factn=3

factn=2

def fact(n): if n == 1: return 1 p = fact(n-1) return n * p

never terminates

-1 fact

p = fact

Page 116: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

“Infinite” Recursion Bugs

What happens if: • we forgot the “n == 1” check? • factorial is called with a negative number?

global

factn=3

factn=2

factn=1

factn=0

factn=-1

def fact(n): if n == 1: return 1 p = fact(n-1) return n * p

never terminates

-1 fact

p = fact

Page 117: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

“Infinite” Recursion Bugs

What happens if: • we forgot the “n == 1” check? • factorial is called with a negative number?

global

factn=3

factn=2

factn=1

factn=0

factn=-1

factn=-2

…StackOverflowError

def fact(n): if n == 1: return 1 p = fact(n-1) return n * p

never terminates

-1 fact

p = fact

Page 118: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Coding Demos

Page 119: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Demo 1: Pretty PrintGoal: format nested lists of bullet pointsInput:• The recursive lists

Output:• Appropriately-tabbed items

Example:

>>> pretty_print([“A”, [“1”, “2”, “3”,], “B”, [“4”, [“i”, “ii”]]]) *A *1 *2 *3 *B *4 *i *ii

Page 120: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Demo 2: Recursive List Search

Goal: does a given number exist in a recursive structure?

Input:• A number• A list of numbers and lists (which contain other numbers and lists)

Output:• True if there’s a list containing the number, else False

Example:>>> contains(3, [1,2,[4,[[3],[8,9]],5,6]]) True >>> contains(12, [1,2,[4,[[3],[8,9]],5,6]]) False

Page 121: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Conclusion: Review Learning Objectives

Page 122: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Learning Objectives: Recursive InformationWhat is a recursive definition/structure?

• Definition contains term • Structure refers to others of same type • Example: a dictionary contains dictionaries (which may contain...)

recursive case

base case

Page 123: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

Learning Objectives: Recursive CodeWhat is recursive code?

• Function that sometimes itself (maybe indirectly)

Why write recursive code?• Real-world data/structures are recursive; intuitive for code to reflect data

Where do computers keep local variables for recursive calls?• In a section of memory called a “frame” • Only one function is active at a time, so keep frames in a stack

What happens to programs with infinite recursion?• Calls keep pushing more frames • Exhaust memory, throw StackOverflowError

Page 124: CS 301: RecursionHofstadter's Law: “It always takes longer than you expect, even when you take into account Hofstadter's Law.” (From Gödel, Escher, Bach) mountain: “a landmass

https://xkcd.com/244/

Questions?