Skip to content
Snippets Groups Projects
Commit 93870b8d authored by LOUIS TYRRELL OLIPHANT's avatar LOUIS TYRRELL OLIPHANT
Browse files

Louis lecture 22 recursion

parent d67e3347
No related branches found
No related tags found
No related merge requests found
%% Cell type:code id: tags:
``` python
# Warmup 0: What is the difference between these two pieces of code?
# In the first example, we create a new grocery dictionary for each grocery
# In the second example, we only create a new grocery dictionary once
# (before the loop starts) and overwrite it on each iteration
```
%% Cell type:code id: tags:
``` python
groceries = ["apples", "bananas", "coconuts", "dragonfruit"]
groceries_dicts = []
for grocery in groceries:
grocery_dict = {}
grocery_dict['name'] = grocery
grocery_dict['size'] = len(grocery)
groceries_dicts.append(grocery_dict)
groceries_dicts
```
%% Output
[{'name': 'apples', 'size': 6},
{'name': 'bananas', 'size': 7},
{'name': 'coconuts', 'size': 8},
{'name': 'dragonfruit', 'size': 11}]
%% Cell type:code id: tags:
``` python
groceries = ["apples", "bananas", "coconuts", "dragonfruit"]
groceries_dicts = []
grocery_dict = {}
for grocery in groceries:
grocery_dict['name'] = grocery
grocery_dict['size'] = len(grocery)
groceries_dicts.append(grocery_dict)
groceries_dicts
```
%% Output
[{'name': 'dragonfruit', 'size': 11},
{'name': 'dragonfruit', 'size': 11},
{'name': 'dragonfruit', 'size': 11},
{'name': 'dragonfruit', 'size': 11}]
%% Cell type:code id: tags:
``` python
# Let's use PythonTutor to investigate!
```
%% Cell type:code id: tags:
``` python
# Warmup 1a: Use 'in' to determine if something is in my_list
my_list = ["meet", "me", "after", 84]
print("me" in my_list)
print(84 in my_list)
```
%% Output
True
True
%% Cell type:code id: tags:
``` python
# Warmup 1b: What about this list?
my_list = [11, "meet", ["me", "them", "us"], [84,19, 22], "school", 2.54]
print("meet" in my_list)
print(84 in my_list)
```
%% Output
True
False
%% Cell type:code id: tags:
``` python
# Warmup 2a: Write a function to find a thing in a list that may have lists in it
my_list = [11, "meet", ["me", "them", "us"], [84,19, 22], "school", 2.54]
def search_list_depth2(target, some_list):
''' returns True if thing in some_list, False otherwise'''
for list_item in some_list:
if target == list_item:
return True
elif type(list_item) == list and target in list_item:
return True
return False # after all possible searching....not found
print(search_list_depth2("school", my_list)) # in list
print(search_list_depth2(22, my_list)) # in nested list
print(search_list_depth2("house", my_list)) # not anywhere
```
%% Output
True
True
False
%% Cell type:code id: tags:
``` python
# Warmup 2b: Will our function work on this list? Guess:
list_3_deep = [22, [33, 44, [55, 66], 77 ], 88]
# let's try it with our previous function
print(search_list_depth2(22, list_3_deep)) # in list
print(search_list_depth2(99, list_3_deep)) # not in list
# Write other tests to be sure that it works
print(search_list_depth2(33, list_3_deep)) # in nested list
print(search_list_depth2(55, list_3_deep)) # in nested nested list
```
%% Output
True
False
True
False
%% Cell type:code id: tags:
``` python
# Warmup 2c: What about ANY depth list?
# That is the goal of today's lecture
list_3_deep = [22, [33, 44, [55, 66], 77 ], 88]
def search_list_depth_any(target, some_list):
''' returns True if thing in some_list, False otherwise'''
for list_item in some_list:
if target == list_item:
return True
elif type(list_item) == list:
is_in_next = search_list_depth_any(target, list_item)
if is_in_next:
return True
return False # after all possible searching....not found
search_list_depth_any(55, list_3_deep)
```
%% Output
True
%% Cell type:markdown id: tags:
### Lecture 22: Recursion
After today's Lecture you will be able to:
Define recursion and be able to identify
- the base case
- the recursive case
- infinite recursion
Explain why the following can be recursively defined
- lists
- dictionaries
Trace a recursive function
- involving numeric computation
- involving nested data structures
%% Cell type:markdown id: tags:
## What is Recursion?
Recursion is defined as the process of defining something in terms of itself.
%% Cell type:markdown id: tags:
![image.png](attachment:image.png)
%% Cell type:markdown id: tags:
### Define recursion and be able to identify
- the base case
- the recursive case
- infinite recursion
%% Cell type:code id: tags:
``` python
# In math, you can define the factorial of a number in terms of the number before it.
# Q: What is the value of 84!
# A: 84 * 83!
# What are we still missing?
# A: 0! = 1
```
%% Cell type:markdown id: tags:
### A recursive algorithm must have 2 parts:
- the base case....which stops the recursion
- the recursive case...which defines the same process in a smaller way
#### If there is no base case what happens in the above example?
- recursion never ends......infinite recursion
- infinite recursion can also happen if the recursive case does not move towards the base
%% Cell type:markdown id: tags:
### Writing Definitions Recursively
%% Cell type:code id: tags:
``` python
# Define the sequence 1, 3, 5, 7, 9, 11... recursively
# Base Case: seq_0 = 1
# Recursive Case: seq_n = seq_(n - 1) + 2
```
%% Cell type:code id: tags:
``` python
# Define whether a positive number is odd recursively
# Base Case: 1 is odd
# Recursive Case: True if (n - 2) is odd, False otherwise
```
%% Cell type:markdown id: tags:
### Writing Recursive Code
%% Cell type:code id: tags:
``` python
def factorial(n):
if n == 0:
return 1
else:
return n * factorial(n - 1)
print(factorial(0))
print(factorial(3))
print(factorial(6))
```
%% Output
1
6
720
%% Cell type:markdown id: tags:
### Write and try `is_odd` in PythonTutor
%% Cell type:code id: tags:
``` python
def is_odd(n):
if n == 1:
return True
elif n == 0:
return False
else:
if n < 0:
return is_odd(n + 2)
else:
return is_odd(n - 2)
is_odd(-3)
```
%% Output
True
%% Cell type:markdown id: tags:
### Can we write them iteratively instead?
%% Cell type:code id: tags:
``` python
def factorial_itr(n):
prod = 1
for i in range(1, n + 1):
prod *= i
return prod
print(factorial_itr(0))
print(factorial_itr(3))
print(factorial_itr(6))
```
%% Output
1
6
720
%% Cell type:markdown id: tags:
### Other Recursive Problems
Go back and complete Warmup 2.C
%% Cell type:code id: tags:
``` python
# The Collatz Conjecture problem
# Conjecture: Any positive integer n, put through the below equation
# will always converge to 1.
#
# https://en.wikipedia.org/wiki/Collatz_conjecture
# https://www.youtube.com/watch?v=5mFpVDpKX70
# US$500 for solving. And likely an honorary doctorate.
# Run this in Python Tutor on your own
def collatz(n):
print(n)
if n == 1:
return 1 # base case
elif n % 2 == 0:
return collatz(n//2)
else:
return collatz (3*n+1)
collatz(13) # try other numbers
```
%% Output
13
40
20
10
5
16
8
4
2
1
1
%% Cell type:markdown id: tags:
### Trace a recursive function involving nested data structures
%% Cell type:code id: tags:
``` python
# example 4
fav_stuff = [ "road bike",
["PB&J", "brownies", "spaghetti", "apples"] ,
("Brooks Ghost 13", "hoodie", "gloves"),
"macbook air",
[ "Johndee.com", "https://www.weather.gov/mkx/"],
["A", "K", ("S", "D", "K")]
]
print ("road bike" in fav_stuff)
print ("brownies" in fav_stuff) # Why is this False?
```
%% Output
True
False
%% Cell type:code id: tags:
``` python
# Write a recursive function to search *ANY* list of lists/tuples for a given word
# Modify your code from Warmup 2.C
def search_list_recursive(target, some_list):
''' returns True if thing in some_list, False otherwise'''
for list_item in some_list:
if target == list_item:
return True
elif type(list_item) == list or type(list_item) == tuple:
is_in_next = search_list_recursive(target, list_item)
if is_in_next:
return True
return False # after all possible searching....not found
print(search_list_recursive("apples", fav_stuff))
print(search_list_recursive("D", fav_stuff))
print(search_list_recursive("road bike", fav_stuff))
print(search_list_recursive("pizza", fav_stuff))
```
%% Output
True
True
True
False
%% Cell type:code id: tags:
``` python
# write a function that prints nested lists with indenting
#
def print_with_indenting(directory, indent_level):
for thing in directory:
if type(thing) == list or type(thing) == tuple:
print("\t" * indent_level + str(type(thing)))
print_with_indenting(thing, indent_level + 1)
else:
print("\t" * indent_level + str(thing))
print_with_indenting(fav_stuff, 0)
```
%% Output
road bike
<class 'list'>
PB&J
brownies
spaghetti
apples
<class 'tuple'>
Brooks Ghost 13
hoodie
gloves
macbook air
<class 'list'>
Johndee.com
https://www.weather.gov/mkx/
<class 'list'>
A
K
<class 'tuple'>
S
D
K
%% Cell type:markdown id: tags:
### Dictionaries can have a recursive structure
As can...
- lists
- dictionaries
- JSON objects
%% Cell type:code id: tags:
``` python
ancestry = {
"name": "Evan",
"age": 28,
"born": "Sheboygan",
"parent": {
"name": "Dean",
"age": 53,
"born": "Milwaukee",
"parent": {
"name": "Mike",
"age": 74,
"born": "Racine",
"parent": {
"name": "Bill",
"age": 96,
"born": "La Crosse"
}
}
}
}
```
%% Cell type:code id: tags:
``` python
# let's try to search through a deep dictionary.
def find_place_of_birth(target_name, ancestry_history):
if ancestry_history['name'] == target_name: # base case
return ancestry_history['born']
else:
if 'parent' in ancestry_history:
return find_place_of_birth(target_name, ancestry_history['parent'])
return "Unknown!"
find_place_of_birth("Evan", ancestry)
```
%% Output
'Sheboygan'
%% Cell type:code id: tags:
``` python
# Extra practice...can you predict the outcome?
# run this on your own in Python Tutor
def mystery(a, b):
# precondition: a > 0 and b > 0
if a < 0 or b < 0:
return None
if b == 1:
return a;
return a * mystery( a, b - 1 )
# make a function call here
mystery(7, 5)
```
%% Output
16807
%% Cell type:code id: tags:
``` python
```
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment