Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • HLI877/cs220-lecture-material
  • DANDAPANTULA/cs220-lecture-material
  • cdis/cs/courses/cs220/cs220-lecture-material
  • GIMOTEA/cs220-lecture-material
  • TWMILLER4/cs220-lecture-material
  • GU227/cs220-lecture-material
  • ABADAL/cs220-lecture-material
  • CMILTON3/cs220-lecture-material
  • BDONG39/cs220-lecture-material
  • JSANDOVAL6/cs220-lecture-material
  • JSABHARWAL2/cs220-lecture-material
  • GFREDERICKS/cs220-lecture-material
  • LMSUN/cs220-lecture-material
  • RBHALE/cs220-lecture-material
  • MILNARIK/cs220-lecture-material
  • SUTTI/cs220-lecture-material
  • NMISHRA4/cs220-lecture-material
  • HXIA36/cs220-lecture-material
  • DEPPELER/cs220-lecture-material
  • KIM2245/cs220-lecture-material
  • SKLEPFER/cs220-lecture-material
  • BANDIERA/cs220-lecture-material
  • JKILPS/cs220-lecture-material
  • SOERGEL/cs220-lecture-material
  • DBAUTISTA2/cs220-lecture-material
  • VLEFTWICH/cs220-lecture-material
  • MOU5/cs220-lecture-material
  • ALJACOBSON3/cs220-lecture-material
  • RCHOUDHARY5/cs220-lecture-material
  • MGERSCH/cs220-lecture-material
  • EKANDERSON8/cs220-lecture-material
  • ZHANG2752/cs220-lecture-material
  • VSANTAMARIA/cs220-lecture-material
  • VILBRANDT/cs220-lecture-material
  • ELADD2/cs220-lecture-material
  • YLIU2328/cs220-lecture-material
  • LMEASNER/cs220-lecture-material
  • ATANG28/cs220-lecture-material
  • AKSCHELLIN/cs220-lecture-material
  • OMBUSH/cs220-lecture-material
  • MJDAVID/cs220-lecture-material
  • AKHATRY/cs220-lecture-material
  • CZHUANG6/cs220-lecture-material
  • JPDEYOUNG/cs220-lecture-material
  • SDREES/cs220-lecture-material
  • CLCAMPBELL3/cs220-lecture-material
  • CJCAMPOS/cs220-lecture-material
  • AMARAN/cs220-lecture-material
  • rmflynn2/cs220-lecture-material
  • zhang2855/cs220-lecture-material
  • imanzoor/cs220-lecture-material
  • TOUSEEF/cs220-lecture-material
  • qchen445/cs220-lecture-material
  • nareed2/cs220-lecture-material
  • younkman/cs220-lecture-material
  • kli382/cs220-lecture-material
  • bsaulnier/cs220-lecture-material
  • isatrom/cs220-lecture-material
  • kgoodrum/cs220-lecture-material
  • mransom2/cs220-lecture-material
  • ahstevens/cs220-lecture-material
  • JRADUECHEL/cs220-lecture-material
  • mpcyr/cs220-lecture-material
  • wmeyrose/cs220-lecture-material
  • mmaltman/cs220-lecture-material
  • lsonntag/cs220-lecture-material
  • ghgallant/cs220-lecture-material
  • agkaiser2/cs220-lecture-material
  • rlgerhardt/cs220-lecture-material
  • chen2552/cs220-lecture-material
  • mickiewicz/cs220-lecture-material
  • cbarnish/cs220-lecture-material
  • alampson/cs220-lecture-material
  • mjwendt4/cs220-lecture-material
  • somsakhein/cs220-lecture-material
  • heppenibanez/cs220-lecture-material
  • szhang926/cs220-lecture-material
  • wewatson/cs220-lecture-material
  • jho34/cs220-lecture-material
  • lmedin/cs220-lecture-material
  • hjiang373/cs220-lecture-material
  • hfry2/cs220-lecture-material
  • ajroberts7/cs220-lecture-material
  • mcerhardt/cs220-lecture-material
  • njtomaszewsk/cs220-lecture-material
  • rwang728/cs220-lecture-material
  • jhansonflore/cs220-lecture-material
  • msajja/cs220-lecture-material
  • bjornson2/cs220-lecture-material
  • ccmclaren/cs220-lecture-material
  • armstrongbag/cs220-lecture-material
  • eloe2/cs220-lecture-material
92 results
Show changes
Showing
with 4689 additions and 0 deletions
{
"msg": "Successfully got the latest messages!",
"page": 1,
"messages": [
{
"id": 393,
"poster": "q",
"title": "test2",
"content": "hello!",
"chatroom": "Bascom Hill Chatters",
"created": "2023-10-20T00:52:09.000Z"
},
{
"id": 391,
"poster": "q",
"title": "test1",
"content": "hello!",
"chatroom": "Bascom Hill Chatters",
"created": "2023-10-20T00:48:19.000Z"
},
{
"id": 375,
"poster": "newAnkit",
"title": "test",
"content": "test",
"chatroom": "Bascom Hill Chatters",
"created": "2023-10-19T22:19:52.000Z"
},
{
"id": 357,
"poster": "car",
"title": "Test",
"content": "vroom",
"chatroom": "Bascom Hill Chatters",
"created": "2023-10-19T21:32:50.000Z"
},
{
"id": 354,
"poster": "user",
"title": "test",
"content": "test",
"chatroom": "Bascom Hill Chatters",
"created": "2023-10-19T21:31:17.000Z"
},
{
"id": 350,
"poster": "user",
"title": "Test",
"content": "Test",
"chatroom": "Bascom Hill Chatters",
"created": "2023-10-19T21:17:04.000Z"
},
{
"id": 349,
"poster": "testaccmc1234",
"title": "Testing Testing 7 8 9",
"content": "Even MORE generic content",
"chatroom": "Bascom Hill Chatters",
"created": "2023-10-19T21:11:48.000Z"
},
{
"id": 348,
"poster": "testaccmc1234",
"title": "Testing Testing 4 5 6",
"content": "More generic posting content",
"chatroom": "Bascom Hill Chatters",
"created": "2023-10-19T21:08:56.000Z"
},
{
"id": 345,
"poster": "user",
"title": "I need this to be a generic title",
"content": "I need this to be generic content",
"chatroom": "Bascom Hill Chatters",
"created": "2023-10-19T20:19:33.000Z"
},
{
"id": 323,
"poster": "testtesttest1",
"title": "testtets",
"content": "tttt",
"chatroom": "Bascom Hill Chatters",
"created": "2023-10-19T18:17:04.000Z"
},
{
"id": 320,
"poster": "chase",
"title": "UI is cool",
"content": "i <3 react",
"chatroom": "Bascom Hill Chatters",
"created": "2023-10-19T18:04:36.000Z"
},
{
"id": 314,
"poster": "k.dot",
"title": "poem",
"content": "so I went running for answers",
"chatroom": "Bascom Hill Chatters",
"created": "2023-10-19T17:24:32.000Z"
},
{
"id": 313,
"poster": "k.dot",
"title": "poem",
"content": "The evils of lucy was all around me",
"chatroom": "Bascom Hill Chatters",
"created": "2023-10-19T17:24:22.000Z"
},
{
"id": 312,
"poster": "k.dot",
"title": "poem",
"content": "I didn't want to self destruct",
"chatroom": "Bascom Hill Chatters",
"created": "2023-10-19T17:24:03.000Z"
},
{
"id": 311,
"poster": "k.dot",
"title": "poem",
"content": "found myself screaming in a hotel room",
"chatroom": "Bascom Hill Chatters",
"created": "2023-10-19T17:23:51.000Z"
},
{
"id": 310,
"poster": "k.dot",
"title": "poem",
"content": "resentment that turned into a great depressions",
"chatroom": "Bascom Hill Chatters",
"created": "2023-10-19T17:22:17.000Z"
},
{
"id": 309,
"poster": "k.dot",
"title": "poem",
"content": "abusing my power full of resentment",
"chatroom": "Bascom Hill Chatters",
"created": "2023-10-19T17:22:01.000Z"
},
{
"id": 308,
"poster": "k.dot",
"title": "poem",
"content": "sometimes I did the same",
"chatroom": "Bascom Hill Chatters",
"created": "2023-10-19T17:21:43.000Z"
},
{
"id": 307,
"poster": "k.dot",
"title": "poem",
"content": "I remember you was conflicted misusing your influence",
"chatroom": "Bascom Hill Chatters",
"created": "2023-10-19T17:21:14.000Z"
},
{
"id": 302,
"poster": "g",
"title": "test",
"content": "r",
"chatroom": "Bascom Hill Chatters",
"created": "2023-10-19T17:11:47.000Z"
},
{
"id": 297,
"poster": "b",
"title": "Test",
"content": "Hello",
"chatroom": "Bascom Hill Chatters",
"created": "2023-10-19T16:10:44.000Z"
},
{
"id": 295,
"poster": "w",
"title": "hello",
"content": "hello",
"chatroom": "Bascom Hill Chatters",
"created": "2023-10-19T16:09:42.000Z"
},
{
"id": 271,
"poster": "krirk1",
"title": "Good luck everyone",
"content": "You got this!",
"chatroom": "Bascom Hill Chatters",
"created": "2023-10-19T07:09:12.000Z"
},
{
"id": 262,
"poster": "robert",
"title": "test again",
"content": "test again",
"chatroom": "Bascom Hill Chatters",
"created": "2023-10-19T06:32:45.000Z"
},
{
"id": 261,
"poster": "robert",
"title": "test",
"content": "test",
"chatroom": "Bascom Hill Chatters",
"created": "2023-10-19T06:31:59.000Z"
}
]
}
\ No newline at end of file
{
"data": {
"lend": {
"loans": {
"values": [
{
"name": "Polikseni",
"description": "Polikseni is 70 years old and married. She and her husband are both retired and their main income is a retirement pension of $106 a month for Polikseni and disability income for her husband of $289 a month. <br /><br />Polikseni's husband, even though disabled, works in a very small shop as a watchmaker on short hours, just to provide additional income for his family and to feel useful. Polikseni's husband needs constant medical treatment due to his health problems. She requested another loan, which she will use to continue paying for the therapy her husband needs. With a part of the loan, she is going to pay the remainder of the previous loan.",
"loanAmount": "1325.00",
"geocode": {
"city": "Korce",
"country": {
"name": "Albania",
"region": "Eastern Europe",
"fundsLentInCountry": 9051250
}
}
},
{
"name": "Safarmo",
"description": "Safarmo is 47 years old. She lives with her husband and her children in Khuroson district. <br /><br />Safarmo is a seamstress. She has been engaged in sewing for 10 years. She learned this activity with help of her mother and elder sister. <br /><br />Safarmo's sewing machine is old and she cannot work well. Her difficulty is lack of money. That’s why she applied for a loan to buy a new modern sewing machine. <br /><br />Safarmo needs your support.",
"loanAmount": "1075.00",
"geocode": {
"city": "Khuroson",
"country": {
"name": "Tajikistan",
"region": "Asia",
"fundsLentInCountry": 64243075
}
}
},
{
"name": "Elizabeth",
"description": "Elizabeth is a mom blessed with five lovely children, who are her greatest motivation in life. She lives in the Natuu area of Kenya. Elizabeth is one of the most hardworking women in sub-Saharan Africa. Being a mother and living in a poor country has never been an excuse for Elizabeth, who has practiced mixed farming for the past few years.<br /><br />The cultural expectations in her area contribute to the notion that men should support their families. However, Elizabeth works independently for the success of her children. She perseveres because she wants to provide a better future for them.<br /><br />Elizabeth has always loved farming. She is a very proud farmer and enjoys milking her dairy cows. Elizabeth keeps poultry and grows crops, but she has not been making a good profit because of poor farming inputs. <br /><br />Elizabeth will use this loan to buy farm inputs and purchase high-quality seeds and good fertilizer to improve her crop production. Modern farming requires the use of modern techniques, and, therefore, using high-quality seeds will assure her of a bumper harvest and increased profit levels.<br /><br />Elizabeth is very visionary. Her goal for the season is to boost her crop production over the previous year.",
"loanAmount": "800.00",
"geocode": {
"city": "Matuu",
"country": {
"name": "Kenya",
"region": "Africa",
"fundsLentInCountry": 120841775
}
}
},
{
"name": "Ester",
"description": "Ester believes that this year is her year of prosperity. Ester is a hardworking, progressive and honest farmer from a very remote village in the Kitale area of Kenya. This area is very fertile, with favorable weather patterns that support farming activities. Ester is happily married and the proud mother of lovely children. Together, they live on a small piece of land that she really treasures. Her primary sources of income are eggs and milk.<br /><br />Although this humble and industrious mother makes a profit, she faces the challenge of not being able to produce enough to meet the readily available market. Therefore, she is seeking funds from Kiva lenders to buy farm inputs such as good fertilizer and good-quality seeds. Through this loan, Ester should double her production, and this will translate into increased income. She then intends to save more money in the future so that she can develop her farming.<br /><br />One objective that Juhudi Kilimo aims at fulfilling is increasing the ease of accessing farm inputs and income-generating assets for farmers. Through the intervention of Juhudi Kilimo and Kiva, inputs such as fertilizers and pesticides have become more accessible to its members than buying a bottle of water. Ester is very optimistic and believes this loan will change her life completely.",
"loanAmount": "275.00",
"geocode": {
"city": "Kitale",
"country": {
"name": "Kenya",
"region": "Africa",
"fundsLentInCountry": 120841775
}
}
},
{
"name": "Cherifa",
"description": "Cherifa is married, 57 years old with two children. She caters and also sells the local drink. She asks for credit to buy the necessities, in particular bags of anchovies, bags of maize and bundles of firewood. She wants to have enough income to run the house well.",
"loanAmount": "875.00",
"geocode": {
"city": "Agoe",
"country": {
"name": "Togo",
"region": "Africa",
"fundsLentInCountry": 13719125
}
}
}
]
}
}
}
}
\ No newline at end of file
{
"bob": [
20.0,
10.0
],
"alice": [
30.0,
20.0
],
"meena": [
100.0,
10.0
]
}
\ No newline at end of file
%% Cell type:markdown id: tags:
## Warmups
%% Cell type:code id: tags:
``` python
# Warmup 0: Recall how to read in and use json data
import json
# we are going to learn about this today !
from collections import namedtuple
# Deserialize
def read_json(path):
with open(path, encoding="utf-8") as f: # f is a variable
return json.load(f) # f represents a reference the JSON file
# Serialize
def write_json(path, data):
with open(path, 'w', encoding="utf-8") as f:
json.dump(data, f, indent=2)
kiva_dict = read_json('kiva.json')
loan_list = kiva_dict['data']['lend']['loans']['values'] # this gives us a list of dicts
loan_list[0].keys()
```
%% Output
dict_keys(['name', 'description', 'loanAmount', 'geocode'])
%% Cell type:code id: tags:
``` python
# Warmup 1a: What is the total amount needed to fund all of the loans?
tot_loan_amount = 0.0
for loan_dict in loan_list:
tot_loan_amount += float(loan_dict['loanAmount'])
tot_loan_amount
```
%% Output
4350.0
%% Cell type:code id: tags:
``` python
# Warmup 1b: What are the unique countries of origin in alphabetical order?
countries = []
for loan_dict in loan_list:
countries.append(loan_dict['geocode']['country']['name'])
uniq_countries = sorted(list(set(countries)))
uniq_countries
```
%% Output
['Albania', 'Kenya', 'Tajikistan', 'Togo']
%% Cell type:code id: tags:
``` python
# Warmup 2: Explain what the code below does
x = 1
```
%% Cell type:code id: tags:
``` python
# In Plain English: It assigns the value of 1 to x.
```
%% Cell type:markdown id: tags:
# CS220: Lecture 20
## Learning Objectives
After this lecture you will be able to...
- Explain the difference between objects vs references, and stack vs heap.
- Determine the side effects that occur when modifying parameters.
- Use tuples to store immutable sequences of values.
- Use namedtuple (immutable) to store user-defined data objects.
%% Cell type:markdown id: tags:
### Objects vs References & Stack vs Heap
- Check out the slides!
- Try some of the code in PythonTutor
%% Cell type:code id: tags:
``` python
# Warmup 2: Explain what the code below does
x = 1
```
%% Cell type:code id: tags:
``` python
# In Plain English: It assigns the value of 1 to x.
```
%% Cell type:code id: tags:
``` python
# More Precisely: It creates a reference variable, x, which refers to the object 1.
# Why? In Python, every variable is just a reference to an object.
# The variable only holds the memory address of the object it is referring to.
# The object is the actual data (e.g. an int, string, list, etc.)
#
# Think about it like a class roster.
# Each name on the roster refers to a student in the class.
# In this example, each name represents a variable, and each student represents an object.
```
%% Cell type:code id: tags:
``` python
# MOST Precisely: It creates a reference variable, x, stored on the stack
# which refers to the object 1, stored on the heap.
# Why? The heap is the collection of ALL objects. Think about it like a supermarket.
# The stack is the "stack" of frames we studied earlier in the semester.
# It is the ordered collection of function frames and their variables.
#
# Tip: Use PythonTutor to visualize this!
#
# Typically, the stack is much smaller in size than the heap.
#
```
%% Cell type:code id: tags:
``` python
# Warmup 2b: Explain what the code below does
shelf = ["sugar", "coffee"]
```
%% Cell type:code id: tags:
``` python
# In Plain English: It assigns a list of coffee and sugar to shelf.
```
%% Cell type:code id: tags:
``` python
# More Precisely: It creates a reference variable, shelf, stored on the stack which
# refers to a list of sugar and coffee on the heap.
```
%% Cell type:code id: tags:
``` python
# MOST Precisely: It creates a reference variable, shelf, stored on the stack which
# refers to a list object on the heap. This list object contains a
# reference to a string object "sugar" on the heap, followed by a
# reference to a string object "coffee" on the heap.
```
%% Cell type:markdown id: tags:
### Determine the side effects that occur when modifying parameters.
%% Cell type:markdown id: tags:
Example 1a [PythonTutor Link](https://pythontutor.com/visualize.html#code=def%20f%28x%29%3A%0A%20%20%20%20x%20*%3D%203%0A%20%20%20%20print%28%22f%3A%22,%20x%29%0A%0Anum%20%3D%2010%0Aprint%28%22before%3A%22,%20num%29%0Af%28num%29%0Aprint%28%22after%3A%22,%20num%29&cumulative=false&curInstr=0&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=3&rawInputLstJSON=%5B%5D&textReferences=false)
%% Cell type:code id: tags:
``` python
def f(x):
x *= 3
print("f:", x)
num = 10
print("before:", num)
f(num)
print("after:", num)
# Takeaway: What happens when a parameter is reassigned in a function?
# The original value does not change!
```
%% Output
before: 10
f: 30
after: 10
%% Cell type:markdown id: tags:
Example 1b, [PythonTutor Link](https://pythontutor.com/visualize.html#code=def%20f%28items%29%3A%0A%20%20%20%20items.append%28%22donuts%22%29%0A%20%20%20%20print%28%22f%3A%22,%20items%29%0A%0Awords%20%3D%20%5B'sugar',%20'coffee'%5D%0Aprint%28%22before%3A%22,%20words%29%0Af%28words%29%0Aprint%28%22after%3A%22,%20words%29&cumulative=false&curInstr=0&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=3&rawInputLstJSON=%5B%5D&textReferences=false)
%% Cell type:code id: tags:
``` python
def f(items):
items.append("donuts")
print("f:", items)
words = ['sugar', 'coffee']
print("before:", words)
f(words)
print("after:", words)
# Takeaway: What happens when a list parameter is mutated in a function?
# The list is changed! This is true for any mutable object.
```
%% Output
before: ['sugar', 'coffee']
f: ['sugar', 'coffee', 'donuts']
after: ['sugar', 'coffee', 'donuts']
%% Cell type:markdown id: tags:
Example 1c [PythonTutor Link](https://pythontutor.com/visualize.html#code=def%20f%28items%29%3A%0A%20%20%20%20items%20%3D%20items%20%2B%20%5B%22donuts%22%5D%0A%20%20%20%20print%28%22f%3A%22,%20items%29%0A%0Awords%20%3D%20%5B'sugar',%20'coffee'%5D%0Aprint%28%22before%3A%22,%20words%29%0Af%28words%29%0Aprint%28%22after%3A%22,%20words%29&cumulative=false&curInstr=0&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=3&rawInputLstJSON=%5B%5D&textReferences=false)
%% Cell type:code id: tags:
``` python
def f(items):
items = items + ["donuts"]
print("f:", items)
words = ['sugar', 'coffee']
print("before:", words)
f(words)
print("after:", words)
# Takeaway: What happens when a list parameter is reassigned?
# The original list is not changed.
```
%% Output
before: ['sugar', 'coffee']
f: ['sugar', 'coffee', 'donuts']
after: ['sugar', 'coffee']
%% Cell type:markdown id: tags:
Example 1d [PythonTutor Link](https://pythontutor.com/visualize.html#code=def%20first%28items%29%3A%0A%20%20%20%20return%20items%5B0%5D%0A%0Adef%20smallest%28items%29%3A%0A%20%20%20%20items.sort%28%29%0A%20%20%20%20return%20items%5B0%5D%0A%0Anumbers%20%3D%20%5B4,5,3,2,1%5D%0Aprint%28%22first%3A%22,%20first%28numbers%29%29%0Aprint%28%22smallest%3A%22,%20smallest%28numbers%29%29%0Aprint%28%22first%3A%22,%20first%28numbers%29%29&cumulative=false&curInstr=0&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=3&rawInputLstJSON=%5B%5D&textReferences=false)
%% Cell type:code id: tags:
``` python
def first(items):
return items[0]
def smallest(items):
items.sort()
return items[0]
numbers = [4,5,3,2,1]
print("first:", first(numbers))
print("smallest:", smallest(numbers))
print("first:", first(numbers))
# Takeaway: What happens when a list parameter is sorted "in place" using .sort() ?
# The original list is changed!
```
%% Output
first: 4
smallest: 1
first: 1
%% Cell type:markdown id: tags:
Example 1e [PythonTutor Link](https://pythontutor.com/visualize.html#code=def%20first%28items%29%3A%0A%20%20%20%20return%20items%5B0%5D%0A%0Adef%20smallest%28items%29%3A%0A%20%20%20%20items%20%3D%20sorted%28items%29%0A%20%20%20%20return%20items%5B0%5D%0A%0Anumbers%20%3D%20%5B4,5,3,2,1%5D%0Aprint%28%22first%3A%22,%20first%28numbers%29%29%0Aprint%28%22smallest%3A%22,%20smallest%28numbers%29%29%0Aprint%28%22first%3A%22,%20first%28numbers%29%29&cumulative=false&curInstr=0&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=3&rawInputLstJSON=%5B%5D&textReferences=false)
%% Cell type:code id: tags:
``` python
def first(items):
return items[0]
def smallest(items):
items = sorted(items)
return items[0]
numbers = [4,5,3,2,1]
print("first:", first(numbers))
print("smallest:", smallest(numbers))
print("first:", first(numbers))
# Takeaway: What happens when a list parameter is sorted using sorted()?
# The original list does not change.
```
%% Output
first: 4
smallest: 1
first: 4
%% Cell type:code id: tags:
``` python
# What can we say about the last two examples?
# sort() mutates the list; sorted does not mutate the list, it returns a new list.
```
%% Cell type:code id: tags:
``` python
# Write one good thing about lists being mutable:
# We can change (mutate) them in functions!
```
%% Cell type:code id: tags:
``` python
# Write one bad thing about lists being mutable:
# We can change (mutate) them in functions!
```
%% Cell type:markdown id: tags:
## Your Turn!
%% Cell type:markdown id: tags:
Explain how the below code works.
%% Cell type:code id: tags:
``` python
def add_vacation_plan(itinerary, location, plan):
# Itinerary is a dictionary of locations, where each location has a list of plans.
# We know that dictionaries and lists are mutable, so we can change them within this function.
#
# We first check if they have plans for the location, and if not start an empty list.
# Then, we add our plan onto the list of plans for that location.
if location not in itinerary:
itinerary[location] = []
itinerary[location].append(plan)
def get_vacation_plans(itinerary, location):
if location not in itinerary:
return []
return itinerary[location]
alices_vacay = {}
bobs_vacay = {}
add_vacation_plan(alices_vacay, "Malibu", "Swimming")
add_vacation_plan(alices_vacay, "San Diego", "Touring")
add_vacation_plan(alices_vacay, "San Diego", "Shopping")
add_vacation_plan(bobs_vacay, "Madison", "Studying")
add_vacation_plan(bobs_vacay, "HWY 151", "Driving")
add_vacation_plan(bobs_vacay, "Devils Lake", "Swimming")
add_vacation_plan(bobs_vacay, "Devils Lake", "Kayaking")
add_vacation_plan(bobs_vacay, "Devils Lake", "Hiking")
print(alices_vacay)
print(bobs_vacay)
print(get_vacation_plans(alices_vacay, 'San Diego'))
print(get_vacation_plans(bobs_vacay, 'Seattle'))
```
%% Output
{'Malibu': ['Swimming'], 'San Diego': ['Touring', 'Shopping']}
{'Madison': ['Studying'], 'HWY 151': ['Driving'], 'Devils Lake': ['Swimming', 'Kayaking', 'Hiking']}
['Touring', 'Shopping']
[]
%% Cell type:markdown id: tags:
### Use tuples to store immutable sequences of values.
Check out the slides about tuples
%% Cell type:code id: tags:
``` python
# Tuples are like lists BUT are IMMUTABLE
# practice with tuples
scores = [32, 55, 72, 91] # a list is mutable
coordinates = (-3, 4, 7) # a tuple is not mutable
```
%% Cell type:code id: tags:
``` python
# show that scores is mutable
scores[-1] = 100
print(scores)
# show that tuples are immutable
#coordinates[-1] = 100. #tuple not mutable
#print(coordinates)
```
%% Output
[32, 55, 72, 100]
%% Cell type:code id: tags:
``` python
coordinates = (5, 77, -3) # However, re-assignment is OK
print(coordinates)
```
%% Output
(5, 77, -3)
%% Cell type:code id: tags:
``` python
scores_tuple = tuple(scores) # you can convert a list into a tuple
print(scores_tuple)
```
%% Output
(32, 55, 72, 100)
%% Cell type:code id: tags:
``` python
# Question: Can tuples be sorted?
# Discuss with your neighbor
# coordinates.sort() # tuples are immutable
new_tuple = sorted(coordinates) # sorted makes a new object
```
%% Cell type:code id: tags:
``` python
# reference: https://www.w3schools.com/python/python_tuples.asp
```
%% Cell type:code id: tags:
``` python
# Why use tuples?
# keys in dictionaries must be immutable types
# some data never changes : GPS coordinates
# Fails with TypeError
buildings = {
[0,0]: "Comp Sci",
[0,2]: "Psychology",
[4,0]: "Noland",
[1,8]: "Van Vleck" }
```
%% Output
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Cell In[29], line 6
1 # Why use tuples?
2 # keys in dictionaries must be immutable types
3 # some data never changes : GPS coordinates
4
5 # Fails with TypeError
----> 6 buildings = {
7 [0,0]: "Comp Sci",
8 [0,2]: "Psychology",
9 [4,0]: "Noland",
10 [1,8]: "Van Vleck" }
TypeError: unhashable type: 'list'
%% Cell type:code id: tags:
``` python
# Works with tuple as keys
buildings = {
(0,0): "Comp Sci",
(0,2): "Psychology",
(4,0): "Noland",
(1,8): "Van Vleck" }
# find the name of the building at coordinate (4,0)
buildings[(4,0)]
```
%% Output
'Noland'
%% Cell type:markdown id: tags:
### 21.3 Use namedtuple (immutable) to store user-defined data objects.
- namedtuple is useful for creating well-defined objects
- namedtuple is like a mix of tuples and dictionaries
- let's look at the slides
%% Cell type:code id: tags:
``` python
people = []
# A namedtuple is like its own kind of type!
# its a Python convention to use a Capital letter when naming a namedtuple
# define a namedtuple called Person
Person = namedtuple("Person", ["fname", "lname", "age"])
# make a single person....please don't name it person !!
p1 = Person("Bucky", "Badger", 124)
print(p1.age)
# Add another Person by using keyword arguments
person2 = Person(age=25, lname="Star", fname = "Patrick")
```
%% Output
124
%% Cell type:code id: tags:
``` python
# make a list of Persons
people=[
Person("Alice", "Anderson", 30), # positional arguments
Person("Bob", "Baker", 31),
# add two more Persons to people
Person("Celia", "Answer", 21),
Person("Marcus", "Carlson", 33)
]
# Print the first person's name.
person0 = people[0]
print("Hello " + person0.fname + " " + person0.lname)
```
%% Output
Hello Alice Anderson
%% Cell type:code id: tags:
``` python
# Print out everyone's name!
print(people)
for p in people:
print("Hello " + p.fname + " " + p.lname)
```
%% Output
[Person(fname='Alice', lname='Anderson', age=30), Person(fname='Bob', lname='Baker', age=31), Person(fname='Celia', lname='Answer', age=21), Person(fname='Marcus', lname='Carlson', age=33)]
Hello Alice Anderson
Hello Bob Baker
Hello Celia Answer
Hello Marcus Carlson
%% Cell type:markdown id: tags:
Namedtuples have a deeper significance....the namedtuples we create are their own type
%% Cell type:markdown id: tags:
![namedtuple.png](attachment:namedtuple.png)
%% Cell type:code id: tags:
``` python
# Write a function to find the average age of the Persons in people
def avg_age(p_list):
# assume p_list is a list of Persons
sum_ages = 0
for person in p_list:
sum_ages += person.age
return sum_ages / len(p_list)
avg_age(people)
```
%% Output
28.75
%% Cell type:code id: tags:
``` python
```
%% Cell type:markdown id: tags:
## Warmups
%% Cell type:code id: tags:
``` python
# Warmup 0: Recall how to read in and use json data
import json
# we are going to learn about this today !
from collections import namedtuple
# Deserialize
def read_json(path):
with open(path, encoding="utf-8") as f: # f is a variable
return json.load(f) # f represents a reference the JSON file
# Serialize
def write_json(path, data):
with open(path, 'w', encoding="utf-8") as f:
json.dump(data, f, indent=2)
kiva_dict = read_json('kiva.json')
loan_list = kiva_dict['data']['lend']['loans']['values'] # this gives us a list of dicts
loan_list[0].keys()
```
%% Cell type:code id: tags:
``` python
# Warmup 1a: What is the total amount needed to fund all of the loans?
```
%% Cell type:code id: tags:
``` python
# Warmup 1b: What are the unique countries of origin in alphabetical order?
```
%% Cell type:code id: tags:
``` python
# Warmup 2: Explain what the code below does
x = 1
```
%% Cell type:markdown id: tags:
# CS220: Lecture 20
## Learning Objectives
After this lecture you will be able to...
- Explain the difference between objects vs references, and stack vs heap.
- Determine the side effects that occur when modifying parameters.
- Use tuples to store immutable sequences of values.
- Use namedtuple (immutable) to store user-defined data objects.
%% Cell type:markdown id: tags:
### Objects vs References & Stack vs Heap
- Check out the slides!
- Try some of the code in PythonTutor
%% Cell type:code id: tags:
``` python
# Warmup 2: Explain what the code below does
x = 1
```
%% Cell type:code id: tags:
``` python
# Warmup 2b: Explain what the code below does
shelf = ["sugar", "coffee"]
```
%% Cell type:markdown id: tags:
### Determine the side effects that occur when modifying parameters.
%% Cell type:markdown id: tags:
Example 1a [PythonTutor Link](https://pythontutor.com/visualize.html#code=def%20f%28x%29%3A%0A%20%20%20%20x%20*%3D%203%0A%20%20%20%20print%28%22f%3A%22,%20x%29%0A%0Anum%20%3D%2010%0Aprint%28%22before%3A%22,%20num%29%0Af%28num%29%0Aprint%28%22after%3A%22,%20num%29&cumulative=false&curInstr=0&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=3&rawInputLstJSON=%5B%5D&textReferences=false)
%% Cell type:code id: tags:
``` python
def f(x):
x *= 3
print("f:", x)
num = 10
print("before:", num)
f(num)
print("after:", num)
# Takeaway: What happens when a parameter is reassigned in a function?
```
%% Output
before: 10
f: 30
after: 10
%% Cell type:markdown id: tags:
Example 1b, [PythonTutor Link](https://pythontutor.com/visualize.html#code=def%20f%28items%29%3A%0A%20%20%20%20items.append%28%22donuts%22%29%0A%20%20%20%20print%28%22f%3A%22,%20items%29%0A%0Awords%20%3D%20%5B'sugar',%20'coffee'%5D%0Aprint%28%22before%3A%22,%20words%29%0Af%28words%29%0Aprint%28%22after%3A%22,%20words%29&cumulative=false&curInstr=0&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=3&rawInputLstJSON=%5B%5D&textReferences=false)
%% Cell type:code id: tags:
``` python
def f(items):
items.append("donuts")
print("f:", items)
words = ['sugar', 'coffee']
print("before:", words)
f(words)
print("after:", words)
# Takeaway: What happens when a list parameter is mutated in a function?
```
%% Output
before: ['sugar', 'coffee']
f: ['sugar', 'coffee', 'donuts']
after: ['sugar', 'coffee', 'donuts']
%% Cell type:markdown id: tags:
Example 1c [PythonTutor Link](https://pythontutor.com/visualize.html#code=def%20f%28items%29%3A%0A%20%20%20%20items%20%3D%20items%20%2B%20%5B%22donuts%22%5D%0A%20%20%20%20print%28%22f%3A%22,%20items%29%0A%0Awords%20%3D%20%5B'sugar',%20'coffee'%5D%0Aprint%28%22before%3A%22,%20words%29%0Af%28words%29%0Aprint%28%22after%3A%22,%20words%29&cumulative=false&curInstr=0&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=3&rawInputLstJSON=%5B%5D&textReferences=false)
%% Cell type:code id: tags:
``` python
def f(items):
items = items + ["donuts"]
print("f:", items)
words = ['sugar', 'coffee']
print("before:", words)
f(words)
print("after:", words)
# Takeaway: What happens when a list parameter is reassigned?
```
%% Output
before: ['sugar', 'coffee']
f: ['sugar', 'coffee', 'donuts']
after: ['sugar', 'coffee']
%% Cell type:markdown id: tags:
Example 1d [PythonTutor Link](https://pythontutor.com/visualize.html#code=def%20first%28items%29%3A%0A%20%20%20%20return%20items%5B0%5D%0A%0Adef%20smallest%28items%29%3A%0A%20%20%20%20items.sort%28%29%0A%20%20%20%20return%20items%5B0%5D%0A%0Anumbers%20%3D%20%5B4,5,3,2,1%5D%0Aprint%28%22first%3A%22,%20first%28numbers%29%29%0Aprint%28%22smallest%3A%22,%20smallest%28numbers%29%29%0Aprint%28%22first%3A%22,%20first%28numbers%29%29&cumulative=false&curInstr=0&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=3&rawInputLstJSON=%5B%5D&textReferences=false)
%% Cell type:code id: tags:
``` python
def first(items):
return items[0]
def smallest(items):
items.sort()
return items[0]
numbers = [4,5,3,2,1]
print("first:", first(numbers))
print("smallest:", smallest(numbers))
print("first:", first(numbers))
# Takeaway: What happens when a list parameter is sorted "in place" using .sort() ?
```
%% Output
first: 4
smallest: 1
first: 1
%% Cell type:markdown id: tags:
Example 1e [PythonTutor Link](https://pythontutor.com/visualize.html#code=def%20first%28items%29%3A%0A%20%20%20%20return%20items%5B0%5D%0A%0Adef%20smallest%28items%29%3A%0A%20%20%20%20items%20%3D%20sorted%28items%29%0A%20%20%20%20return%20items%5B0%5D%0A%0Anumbers%20%3D%20%5B4,5,3,2,1%5D%0Aprint%28%22first%3A%22,%20first%28numbers%29%29%0Aprint%28%22smallest%3A%22,%20smallest%28numbers%29%29%0Aprint%28%22first%3A%22,%20first%28numbers%29%29&cumulative=false&curInstr=0&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=3&rawInputLstJSON=%5B%5D&textReferences=false)
%% Cell type:code id: tags:
``` python
def first(items):
return items[0]
def smallest(items):
items = sorted(items)
return items[0]
numbers = [4,5,3,2,1]
print("first:", first(numbers))
print("smallest:", smallest(numbers))
print("first:", first(numbers))
# Takeaway: What happens when a list parameter is sorted using sorted()?
```
%% Output
first: 4
smallest: 1
first: 4
%% Cell type:code id: tags:
``` python
# What can we say about the last two examples?
```
%% Cell type:code id: tags:
``` python
# Write one good thing about lists being mutable:
```
%% Cell type:code id: tags:
``` python
# Write one bad thing about lists being mutable:
```
%% Cell type:markdown id: tags:
## Your Turn!
%% Cell type:markdown id: tags:
Explain how the below code works.
%% Cell type:code id: tags:
``` python
def add_vacation_plan(itinerary, location, plan):
if location not in itinerary:
itinerary[location] = []
itinerary[location].append(plan)
def get_vacation_plans(itinerary, location):
if location not in itinerary:
return []
return itinerary[location]
alices_vacay = {}
bobs_vacay = {}
add_vacation_plan(alices_vacay, "Malibu", "Swimming")
add_vacation_plan(alices_vacay, "San Diego", "Touring")
add_vacation_plan(alices_vacay, "San Diego", "Shopping")
add_vacation_plan(bobs_vacay, "Madison", "Studying")
add_vacation_plan(bobs_vacay, "HWY 151", "Driving")
add_vacation_plan(bobs_vacay, "Devils Lake", "Swimming")
add_vacation_plan(bobs_vacay, "Devils Lake", "Kayaking")
add_vacation_plan(bobs_vacay, "Devils Lake", "Hiking")
print(alices_vacay)
print(bobs_vacay)
print(get_vacation_plans(alices_vacay, 'San Diego'))
print(get_vacation_plans(bobs_vacay, 'Seattle'))
```
%% Output
{'Malibu': ['Swimming'], 'San Diego': ['Touring', 'Shopping']}
{'Madison': ['Studying'], 'HWY 151': ['Driving'], 'Devils Lake': ['Swimming', 'Kayaking', 'Hiking']}
['Touring', 'Shopping']
[]
%% Cell type:markdown id: tags:
### Use tuples to store immutable sequences of values.
Check out the slides about tuples
%% Cell type:code id: tags:
``` python
# Tuples are like lists BUT are IMMUTABLE
# practice with tuples
scores = [32, 55, 72, 91] # a list is mutable
coordinates = (-3, 4, 7) # a tuple is not mutable
```
%% Cell type:code id: tags:
``` python
# show that scores is mutable
scores[-1] = 100
print(scores)
# show that tuples are immutable
#coordinates[-1] = 100. #tuple not mutable
#print(coordinates)
```
%% Output
[32, 55, 72, 100]
%% Cell type:code id: tags:
``` python
coordinates = (5, 77, -3) # However, re-assignment is OK
print(coordinates)
```
%% Output
(5, 77, -3)
%% Cell type:code id: tags:
``` python
scores_tuple = tuple(scores) # you can convert a list into a tuple
print(scores_tuple)
```
%% Output
(32, 55, 72, 100)
%% Cell type:code id: tags:
``` python
# Question: Can tuples be sorted?
# Discuss with your neighbor
```
%% Cell type:code id: tags:
``` python
# reference: https://www.w3schools.com/python/python_tuples.asp
```
%% Cell type:code id: tags:
``` python
# Why use tuples?
# keys in dictionaries must be immutable types
# some data never changes : GPS coordinates
# Fails with TypeError
buildings = {
[0,0]: "Comp Sci",
[0,2]: "Psychology",
[4,0]: "Noland",
[1,8]: "Van Vleck" }
```
%% Output
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
C:\Users\COLENE~1\AppData\Local\Temp/ipykernel_18196/3672081683.py in <module>
4
5 # Fails with TypeError
----> 6 buildings = {
7 [0,0]: "Comp Sci",
8 [0,2]: "Psychology",
TypeError: unhashable type: 'list'
%% Cell type:code id: tags:
``` python
# Works with tuple as keys
buildings = {
(0,0): "Comp Sci",
(0,2): "Psychology",
(4,0): "Noland",
(1,8): "Van Vleck" }
# find the name of the building at coordinate (4,0)
```
%% Output
'Noland'
%% Cell type:markdown id: tags:
### 21.3 Use namedtuple (immutable) to store user-defined data objects.
- namedtuple is useful for creating well-defined objects
- namedtuple is like a mix of tuples and dictionaries
- let's look at the slides
%% Cell type:code id: tags:
``` python
people = []
# A namedtuple is like its own kind of type!
# its a Python convention to use a Capital letter when naming a namedtuple
# define a namedtuple called Person
Person = namedtuple("Person", ["fname", "lname", "age"])
# make a single person....please don't name it person !!
# Add another Person by using keyword arguments
```
%% Output
124
%% Cell type:code id: tags:
``` python
# make a list of Persons
people=[
Person("Alice", "Anderson", 30), # positional arguments
Person("Bob", "Baker", 31),
# add two more Persons to people
Person("Celia", "Answer", 21),
Person("Marcus", "Carlson", 33)
]
# Print the first person's name.
```
%% Output
Hello Alice Anderson
%% Cell type:code id: tags:
``` python
# Print out everyone's name!
```
%% Output
[Person(fname='Alice', lname='Anderson', age=30), Person(fname='Bob', lname='Baker', age=31), Person(fname='Celia', lname='Answer', age=21), Person(fname='Marcus', lname='Carlson', age=33)]
Hello Alice Anderson
Hello Bob Baker
Hello Celia Answer
Hello Marcus Carlson
%% Cell type:markdown id: tags:
Namedtuples have a deeper significance....the namedtuples we create are their own type
%% Cell type:markdown id: tags:
![namedtuple.png](attachment:namedtuple.png)
%% Cell type:code id: tags:
``` python
# Write a function to find the average age of the Persons in people
def avg_age(p_list):
# assume p_list is a list of Persons
pass
avg_age(people)
```
%% Output
28.75
{
"data": {
"lend": {
"loans": {
"values": [
{
"name": "Polikseni",
"description": "Polikseni is 70 years old and married. She and her husband are both retired and their main income is a retirement pension of $106 a month for Polikseni and disability income for her husband of $289 a month. <br /><br />Polikseni's husband, even though disabled, works in a very small shop as a watchmaker on short hours, just to provide additional income for his family and to feel useful. Polikseni's husband needs constant medical treatment due to his health problems. She requested another loan, which she will use to continue paying for the therapy her husband needs. With a part of the loan, she is going to pay the remainder of the previous loan.",
"loanAmount": "1325.00",
"geocode": {
"city": "Korce",
"country": {
"name": "Albania",
"region": "Eastern Europe",
"fundsLentInCountry": 9051250
}
}
},
{
"name": "Safarmo",
"description": "Safarmo is 47 years old. She lives with her husband and her children in Khuroson district. <br /><br />Safarmo is a seamstress. She has been engaged in sewing for 10 years. She learned this activity with help of her mother and elder sister. <br /><br />Safarmo's sewing machine is old and she cannot work well. Her difficulty is lack of money. That’s why she applied for a loan to buy a new modern sewing machine. <br /><br />Safarmo needs your support.",
"loanAmount": "1075.00",
"geocode": {
"city": "Khuroson",
"country": {
"name": "Tajikistan",
"region": "Asia",
"fundsLentInCountry": 64243075
}
}
},
{
"name": "Elizabeth",
"description": "Elizabeth is a mom blessed with five lovely children, who are her greatest motivation in life. She lives in the Natuu area of Kenya. Elizabeth is one of the most hardworking women in sub-Saharan Africa. Being a mother and living in a poor country has never been an excuse for Elizabeth, who has practiced mixed farming for the past few years.<br /><br />The cultural expectations in her area contribute to the notion that men should support their families. However, Elizabeth works independently for the success of her children. She perseveres because she wants to provide a better future for them.<br /><br />Elizabeth has always loved farming. She is a very proud farmer and enjoys milking her dairy cows. Elizabeth keeps poultry and grows crops, but she has not been making a good profit because of poor farming inputs. <br /><br />Elizabeth will use this loan to buy farm inputs and purchase high-quality seeds and good fertilizer to improve her crop production. Modern farming requires the use of modern techniques, and, therefore, using high-quality seeds will assure her of a bumper harvest and increased profit levels.<br /><br />Elizabeth is very visionary. Her goal for the season is to boost her crop production over the previous year.",
"loanAmount": "800.00",
"geocode": {
"city": "Matuu",
"country": {
"name": "Kenya",
"region": "Africa",
"fundsLentInCountry": 120841775
}
}
},
{
"name": "Ester",
"description": "Ester believes that this year is her year of prosperity. Ester is a hardworking, progressive and honest farmer from a very remote village in the Kitale area of Kenya. This area is very fertile, with favorable weather patterns that support farming activities. Ester is happily married and the proud mother of lovely children. Together, they live on a small piece of land that she really treasures. Her primary sources of income are eggs and milk.<br /><br />Although this humble and industrious mother makes a profit, she faces the challenge of not being able to produce enough to meet the readily available market. Therefore, she is seeking funds from Kiva lenders to buy farm inputs such as good fertilizer and good-quality seeds. Through this loan, Ester should double her production, and this will translate into increased income. She then intends to save more money in the future so that she can develop her farming.<br /><br />One objective that Juhudi Kilimo aims at fulfilling is increasing the ease of accessing farm inputs and income-generating assets for farmers. Through the intervention of Juhudi Kilimo and Kiva, inputs such as fertilizers and pesticides have become more accessible to its members than buying a bottle of water. Ester is very optimistic and believes this loan will change her life completely.",
"loanAmount": "275.00",
"geocode": {
"city": "Kitale",
"country": {
"name": "Kenya",
"region": "Africa",
"fundsLentInCountry": 120841775
}
}
},
{
"name": "Cherifa",
"description": "Cherifa is married, 57 years old with two children. She caters and also sells the local drink. She asks for credit to buy the necessities, in particular bags of anchovies, bags of maize and bundles of firewood. She wants to have enough income to run the house well.",
"loanAmount": "875.00",
"geocode": {
"city": "Agoe",
"country": {
"name": "Togo",
"region": "Africa",
"fundsLentInCountry": 13719125
}
}
}
]
}
}
}
}
\ No newline at end of file
Source diff could not be displayed: it is too large. Options to address this: view the blob.
Source diff could not be displayed: it is too large. Options to address this: view the blob.
%% Cell type:markdown id:193622e7 tags:
**Q2:** [PythonTutor Link](https://pythontutor.com/visualize.html#code=x%20%3D%20%5B1,%202,%203%5D%0Ay%20%3D%20%5B1,%202,%203%5D%0Az%20%3D%20x%0Az.append%284%29&cumulative=false&curInstr=0&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=3&rawInputLstJSON=%5B%5D&textReferences=false)
%% Cell type:code id:131b9746 tags:
``` python
x = [1, 2, 3]
y = [1, 2, 3]
z = x
z.append(4)
```
%% Cell type:markdown id:f578b492 tags:
**Q3:** [PythonTutor Link](https://pythontutor.com/visualize.html#code=nums1%20%3D%20%5B1,2%5D%0Anums2%20%3D%20nums1%0Ax%20%3D%20nums2.pop%281%29&cumulative=false&curInstr=0&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=3&rawInputLstJSON=%5B%5D&textReferences=false)
%% Cell type:code id:6d6a052b tags:
``` python
nums1 = [1,2]
nums2 = nums1
x = nums2.pop(1)
```
%% Cell type:markdown id:0abc64c0 tags:
**Q4:** [PythonTutor Link](https://pythontutor.com/visualize.html#code=x%20%3D%20%5B1,%202%5D%0Ay%20%3D%20%5B3%5D%0Az%20%3D%20x%20%2B%20y%0Ay.append%284%29&cumulative=false&curInstr=0&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=3&rawInputLstJSON=%5B%5D&textReferences=false)
%% Cell type:code id:373369b9 tags:
``` python
x = [1, 2]
y = [3]
z = x + y
y.append(4)
```
%% Cell type:markdown id:a3eb791e tags:
**Q5:** [PythonTutor Link](https://pythontutor.com/visualize.html#code=people%20%3D%20%7B%22alice%22%3A30,%20%22bob%22%3A25%7D%0Ax%20%3D%20people%0Ay%20%3D%20people%5B%22bob%22%5D%0Ax%5B%22alice%22%5D%20%3D%2031%0Ay%20%3D%2026&cumulative=false&curInstr=0&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=3&rawInputLstJSON=%5B%5D&textReferences=false)
%% Cell type:code id:ab703ab8 tags:
``` python
people = {"alice":30, "bob":25}
x = people
y = people["bob"]
x["alice"] = 31
y = 26
```
%% Cell type:markdown id:6dd6f676 tags:
**Q6:** [PythonTutor Link](https://pythontutor.com/visualize.html#code=def%20f%28items%29%3A%0A%20%20%20%20return%20items.pop%280%29%0Anums%20%3D%20%5B1,2,3%5D%0Anums.append%28f%28nums%29%29&cumulative=false&curInstr=0&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=3&rawInputLstJSON=%5B%5D&textReferences=false)
%% Cell type:code id:81a7d6d6 tags:
``` python
def f(items):
return items.pop(0)
nums = [1,2,3]
nums.append(f(nums))
```
%% Cell type:markdown id:5cea38e0 tags:
**Q7 (As Written):** [PythonTutor Link](https://pythontutor.com/visualize.html#code=import%20copy%0Ax%20%3D%20%5B2,1%5D%0Ay%20%3D%20copy.copy%28y%29%0Ay.sort%28%29&cumulative=false&curInstr=0&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=3&rawInputLstJSON=%5B%5D&textReferences=false)
%% Cell type:code id:ed06d8b5 tags:
``` python
import copy
x = [2,1]
y = copy.copy(y)
y.sort()
```
%% Cell type:markdown id:1499a535 tags:
**Q7 (As Fixed):** [PythonTutor Link](https://pythontutor.com/visualize.html#code=import%20copy%0Ax%20%3D%20%5B2,1%5D%0Ay%20%3D%20copy.copy%28x%29%0Ay.sort%28%29&cumulative=false&curInstr=0&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=3&rawInputLstJSON=%5B%5D&textReferences=false)
%% Cell type:code id:25a014f1 tags:
``` python
import copy
x = [2,1]
y = copy.copy(x)
y.sort()
```
%% Cell type:markdown id:88899380 tags:
**Q8:** [PythonTutor Link](https://pythontutor.com/visualize.html#code=import%20copy%0Adef%20biggest%28items%29%3A%0A%20%20%20%20items%20%3D%20copy.copy%28items%29%0A%20%20%20%20items.sort%28%29%0A%20%20%20%20return%20items%5B-1%5D%0Anums%20%3D%20%5B3,9,6%5D%0Ax%20%3D%20biggest%28nums%29&cumulative=false&curInstr=0&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=3&rawInputLstJSON=%5B%5D&textReferences=false)
%% Cell type:code id:a03f0f27 tags:
``` python
import copy
def biggest(items):
items = copy.copy(items)
items.sort()
return items[-1]
nums = [3,9,6]
x = biggest(nums)
```
%% Cell type:markdown id:60f15a79 tags:
**Q9:** [PythonTutor Link](https://pythontutor.com/visualize.html#code=import%20copy%0Ateam1%20%3D%20%5B%0A%20%20%7B%22name%22%3A%22A%22,%20%22age%22%3A7%7D%0A%5D%0Ateam2%20%3D%20copy.copy%28team1%29%0Ateam2.append%28%0A%20%20%7B%22name%22%3A%22B%22,%20%22age%22%3A9%7D%0A%29%0Ateam2%5B0%5D%5B%22age%22%5D%20%3D%208%0Ax%20%3D%20team1%5B0%5D%5B%22age%22%5D&cumulative=false&curInstr=0&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=3&rawInputLstJSON=%5B%5D&textReferences=false)
%% Cell type:code id:ba913d5b tags:
``` python
import copy
team1 = [
{"name":"A", "age":7}
]
team2 = copy.copy(team1)
team2.append(
{"name":"B", "age":9}
)
team2[0]["age"] = 8
x = team1[0]["age"]
```
%% Cell type:markdown id:9e3d7dd3 tags:
**Q10:** [PythonTutor Link](https://pythontutor.com/visualize.html#code=import%20copy%0Ateam1%20%3D%20%5B%0A%20%20%7B%22name%22%3A%22A%22,%20%22age%22%3A7%7D%0A%5D%0Ateam2%20%3D%20copy.deepcopy%28team1%29%0Ateam2.append%28%0A%20%20%7B%22name%22%3A%22B%22,%20%22age%22%3A9%7D%0A%29%0Ateam2%5B0%5D%5B%22age%22%5D%20%3D%208%0Ax%20%3D%20team1%5B0%5D%5B%22age%22%5D&cumulative=false&curInstr=0&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=3&rawInputLstJSON=%5B%5D&textReferences=false)
%% Cell type:code id:1c49cbcb tags:
``` python
import copy
team1 = [
{"name":"A", "age":7}
]
team2 = copy.deepcopy(team1)
team2.append(
{"name":"B", "age":9}
)
team2[0]["age"] = 8
x = team1[0]["age"]
```
%% Cell type:markdown id:30953821 tags:
**Q11:** [PythonTutor Link](https://pythontutor.com/visualize.html#code=import%20copy%0Aorig%20%3D%20%5B1,%5B2,%5B3,4%5D%5D%5D%0Ax%20%3D%20orig%0Ay%20%3D%20copy.copy%28orig%29%0Az%20%3D%20copy.deepcopy%28orig%29&cumulative=false&curInstr=0&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=3&rawInputLstJSON=%5B%5D&textReferences=false)
%% Cell type:code id:e67ede97 tags:
``` python
import copy
orig = [1,[2,[3,4]]]
x = orig
y = copy.copy(orig)
z = copy.deepcopy(orig)
```
%% 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
```
%% Cell type:code id: tags:
``` python
# Warmup 0: What is the difference between these two pieces of code?
```
%% 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
```
%% 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
```
%% Cell type:code id: tags:
``` python
# Warmup 1a: Use 'in' to determine if something is in my_list
my_list = ["meet", "me", "after", 84]
```
%% 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]
```
%% 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):
pass
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
```
%% 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
```
%% 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):
pass
search_list_depth_any(55, list_3_deep)
```
%% 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:
# What are we still missing?
# A:
```
%% 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:
# Recursive Case:
```
%% Cell type:code id: tags:
``` python
# Define whether a positive number is odd recursively
# Base Case:
# Recursive Case:
```
%% Cell type:markdown id: tags:
### Writing Recursive Code
%% Cell type:code id: tags:
``` python
def factorial(n):
pass
print(factorial(0))
# print(factorial(3))
# print(factorial(6))
```
%% Cell type:markdown id: tags:
### Write and try `is_odd` in PythonTutor
%% Cell type:code id: tags:
``` python
def is_odd(n):
pass
is_odd(7)
```
%% Cell type:markdown id: tags:
### Can we write them iteratively instead?
%% Cell type:code id: tags:
``` python
def factorial_itr(n):
pass
print(factorial_itr(0))
# print(factorial_itr(3))
# print(factorial_itr(6))
```
%% Cell type:markdown id: tags:
### Other Recursive Problems
%% Cell type:code id: tags:
``` python
# 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
```
%% Cell type:markdown id: tags:
### Trace a recursive function involving nested data structures
%% Cell type:code id: tags:
``` python
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?
```
%% 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):
pass
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))
```
%% 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)
```
%% 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 ???
return "Unknown!"
find_place_of_birth("Evan", ancestry)
```
%% 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)
```
%% Cell type:code id: tags:
``` python
# Warmup 1: Complete the recursive function.
# Write a function that prints nested lists with indenting
#
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")]
]
def print_with_indenting(directory, indent_level):
for subitem in directory:
if type(subitem) == list or type(subitem) == tuple:
print("\t" * indent_level + str(type(subitem)))
# TODO make recursive call
print_with_indenting(subitem, indent_level + 1)
else:
print("\t" * indent_level + str(subitem))
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:
[PythonTutor Link](https://pythontutor.com/visualize.html#code=def%20mystery%28a,%20b%29%3A%20%0A%23%20precondition%3A%20assume%20a%20%3E%200%20and%20b%20%3E%200%0A%20%20%20%20if%20b%20%3D%3D%201%3A%20%0A%20%20%20%20%20%20%20%20return%20a%3B%0A%20%20%20%20return%20a%20*%20mystery%28%20a,%20b%20-%201%20%29%0A%0A%23%20make%20a%20function%20call%20here%0Amystery%287,%205%29&cumulative=false&curInstr=0&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=3&rawInputLstJSON=%5B%5D&textReferences=false)
%% Cell type:code id: tags:
``` python
# Warmup 2: Trace Recursion by hand .... possible exam question
def mystery(a, b):
# precondition: assume a > 0 and b > 0
if b == 1:
return a;
return a * mystery( a, b - 1 )
# make a function call here
mystery(7, 5)
#Q: What would be the result if we call
#. mystery(-3, -1) ??
# If b starts at -1, and we subtract 1 each time we call a mystery, it will never == 1
```
%% Output
16807
%% Cell type:markdown id: tags:
## Lecture 23: Functions are Objects!
As we have learned previously, all variables in Python are stored as objects.
This is also true for functions, and it gives us more power as programmers.
**Learning Objectives:**
- Define a function reference and trace code that uses function references.
- Explain the default use of sorted() on lists of tuples, and dictionaries.
- Sort a list of tuples, a list of dictionaries, or a dictionary using a function as a key.
- Use a lambda expression when sorting.
%% Cell type:code id: tags:
``` python
# function references
# try this in Python Tutor
x = [1,2,3]
y = x
def f(some_list): # what is f? its a function but also an object
return some_list[-1]
z = f(y) # z stores the result of a call to f
g = f # what is g? it is a reference to an object that is a function
# TODO: similar to line 10, store the result of a call to g
w = g(x) # calls the same function
w
```
%% Output
3
%% Cell type:markdown id: tags:
### Define a function reference and trace code that uses function references.
%% Cell type:markdown id: tags:
![function%20reference.png](attachment:function%20reference.png)
%% Cell type:markdown id: tags:
[PythonTutor Link](https://pythontutor.com/visualize.html#code=def%20hammer%28%29%3A%0A%20%20%20%20print%28%22tap%20tap%20tap%22%29%0A%20%20%20%20%0Adef%20call_n_times%28f,%20n%29%3A%0A%20%20%20%20for%20i%20in%20range%28n%29%3A%0A%20%20%20%20%20%20%20%20f%28%29%0A%0Acall_n_times%28hammer,%203%29&cumulative=false&curInstr=0&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=3&rawInputLstJSON=%5B%5D&textReferences=false)
%% Cell type:code id: tags:
``` python
# function references can be passed as arguments ...Wow!
# first: try this in Python Tutor
def hammer():
print("tap tap tap")
# then on your own: define a function called screwdriver
def screwdriver():
print("churn churn churn")
def call_n_times(f, n):
for i in range(n):
f()
call_n_times(hammer, 3)
# then on your own: invoke call_n_times with screwdriver and 5 as arguments
call_n_times(screwdriver, 5)
```
%% Output
tap tap tap
tap tap tap
tap tap tap
churn churn churn
churn churn churn
churn churn churn
churn churn churn
churn churn churn
%% Cell type:markdown id: tags:
## Your turn!
Calculate the distance between two points using either the manhattan or euclidean distance.
%% Cell type:markdown id: tags:
![image.png](attachment:image.png)
Source: https://www.researchgate.net/figure/Example-of-Euclidean-and-Manhattan-distances-between-two-points-A-and-B-The-Euclidean_fig8_333430988
%% Cell type:markdown id: tags:
### Review: NamedTuples
We create a namedtuple `Point` with named attributes `x` and `y`. We then create lists of points we want to calculate distances between
%% Cell type:code id: tags:
``` python
from collections import namedtuple
Point = namedtuple("Point", ["x", "y"])
left_points = [
Point(0, 0),
Point(3, 3),
Point(2, 2)
]
right_points = [
Point(5, 5),
Point(0, 3),
Point(2, 2)
]
```
%% Cell type:markdown id: tags:
### Complete the function `calculate_distances`
%% Cell type:markdown id: tags:
We already did the math behind `manhattan_distance` and `euclidean_distance` for you!
**Hint:** `distance_algo` should be a reference to a function that calculates distance between two points.
Then, call calculate_distances measuring first in manhattan_distance, then euclidean_distance.
%% Cell type:code id: tags:
``` python
import math
def manhattan_distance(point1, point2):
dist_x = abs(point1.x - point2.x)
dist_y = abs(point1.y - point2.y)
return dist_x + dist_y
def euclidean_distance(point1, point2):
dist_x = (point1.x - point2.x) ** 2
dist_y = (point1.y - point2.y) ** 2
return math.sqrt(dist_x + dist_y)
def calculate_distances(distance_algo):
for i in range(len(left_points)):
left_point = left_points[i]
right_point = right_points[i]
print(distance_algo(left_point, right_point))
calculate_distances(manhattan_distance)
calculate_distances(euclidean_distance)
```
%% Output
10
3
0
7.0710678118654755
3.0
0.0
%% Cell type:markdown id: tags:
### Explain the default use of sorted() on lists of tuples, and on dictionaries.
%% Cell type:code id: tags:
``` python
# first... did you know that sort/sorted takes a 2nd argument called reverse?
populations = [55, 77, 33, 99, 22]
# TODO: sort populations in reverse
sorted(populations, reverse=True)
```
%% Output
[99, 77, 55, 33, 22]
%% Cell type:code id: tags:
``` python
# Sorting part 1....how are lists of tuples sorted?
# olympic womens hockey badgers...first, last, age
owhockey_badgers = [ ("Hillary", "Knight", 32 ),
("Brianna", "Decker", 30),
("Amanda", "Kessel", 30),
("Alex", "Cavalenni", 30),
("Caroline", "Harvey", 19),
("Abbey", "Roque", 24)
]
# call sorted on this list of tuples
sorted(owhockey_badgers)
# what did this make? How was it sorted?
```
%% Output
[('Abbey', 'Roque', 24),
('Alex', 'Cavalenni', 30),
('Amanda', 'Kessel', 30),
('Brianna', 'Decker', 30),
('Caroline', 'Harvey', 19),
('Hillary', 'Knight', 32)]
%% Cell type:code id: tags:
``` python
# sorting part 2: define a function that returns a value from a tuple
def select0(some_tuple): # function must have exactly one parameter
return some_tuple[0]
def select1(some_tuple):
return some_tuple[1]
def select2(some_tuple):
return some_tuple[2]
# Test these functions on the tuple ("Mike", "Gurmail", "Cole")
my_tuple = ("Mike", "Gurmail", "Cole")
select1(my_tuple)
```
%% Output
'Gurmail'
%% Cell type:code id: tags:
``` python
# call sorted using the 'key' argument
# sort and sorted can take a parameter named key
# key is a reference to a function!
sorted(owhockey_badgers, key=select2)
```
%% Output
[('Caroline', 'Harvey', 19),
('Abbey', 'Roque', 24),
('Brianna', 'Decker', 30),
('Amanda', 'Kessel', 30),
('Alex', 'Cavalenni', 30),
('Hillary', 'Knight', 32)]
%% Cell type:code id: tags:
``` python
# sort the list of tuples based on the last name
sorted(owhockey_badgers, key=select1)
```
%% Output
[('Alex', 'Cavalenni', 30),
('Brianna', 'Decker', 30),
('Caroline', 'Harvey', 19),
('Amanda', 'Kessel', 30),
('Hillary', 'Knight', 32),
('Abbey', 'Roque', 24)]
%% Cell type:code id: tags:
``` python
# sort the list of tuples based on the age
sorted(owhockey_badgers, key=select2)
```
%% Output
[('Caroline', 'Harvey', 19),
('Abbey', 'Roque', 24),
('Brianna', 'Decker', 30),
('Amanda', 'Kessel', 30),
('Alex', 'Cavalenni', 30),
('Hillary', 'Knight', 32)]
%% Cell type:markdown id: tags:
### Using `lambda`
- `lambda` functions are a way to abstract a function reference
- lambdas are simple functions with:
- multiple possible parameters
- single expression line as the function body
- lambdas are useful abstractions for:
- mathematical functions
- lookup operations
- lambdas are often associated with a collection of values within a list
- Syntax:
```python
lambda parameters: expression
```
%% Cell type:code id: tags:
``` python
# sorting part 3....using lambdas
'''
def no_name(each_tuple):
return each_tuple[-1]
'''
sorted(owhockey_badgers, key = lambda each_tuple : each_tuple[-1])
# read the lambda as: my no-name function has each_tuple as a parameter
# and returns each_tuple[-1] (the last element)
# the variable 'each_tuple' is like a function parameter
```
%% Output
[('Caroline', 'Harvey', 19),
('Abbey', 'Roque', 24),
('Brianna', 'Decker', 30),
('Amanda', 'Kessel', 30),
('Alex', 'Cavalenni', 30),
('Hillary', 'Knight', 32)]
%% Cell type:code id: tags:
``` python
# TODO: sort the list by the length of the first name
'''
def no_name(x):
return len(x[0])
'''
sorted(owhockey_badgers, key = lambda x : len(x[0]))
```
%% Output
[('Alex', 'Cavalenni', 30),
('Abbey', 'Roque', 24),
('Amanda', 'Kessel', 30),
('Hillary', 'Knight', 32),
('Brianna', 'Decker', 30),
('Caroline', 'Harvey', 19)]
%% Cell type:code id: tags:
``` python
# TODO: Sort the list by the length of their full name
'''
def no_name(player):
return len(player[0]) + len(player[1])
'''
sorted(owhockey_badgers, key = lambda player : len(player[0]) + len(player[1]))
```
%% Output
[('Abbey', 'Roque', 24),
('Amanda', 'Kessel', 30),
('Hillary', 'Knight', 32),
('Brianna', 'Decker', 30),
('Alex', 'Cavalenni', 30),
('Caroline', 'Harvey', 19)]
%% Cell type:markdown id: tags:
### OK, I can sort a list of tuples....what about a list of dictionaries?
%% Cell type:code id: tags:
``` python
hurricanes = [
{"name": "Calvin", "year": 2000},
{"name": "Alexandria", "year": 1980, "speed": 100},
{"name": "Blanc", "year": 1990, "speed": 250},
]
# call sorted on hurricanes and use a lambda expression to grab the year
sorted(hurricanes, key = lambda d : d["year"], reverse=True)
```
%% Output
[{'name': 'Calvin', 'year': 2000},
{'name': 'Blanc', 'year': 1990, 'speed': 250},
{'name': 'Alexandria', 'year': 1980, 'speed': 100}]
%% Cell type:code id: tags:
``` python
# sort hurricanes alphabetically by name
# for you to do on your own...see the above example
sorted(hurricanes, key = lambda d : d["name"])
```
%% Output
[{'name': 'Alexandria', 'year': 1980, 'speed': 100},
{'name': 'Blanc', 'year': 1990, 'speed': 250},
{'name': 'Calvin', 'year': 2000}]
%% Cell type:code id: tags:
``` python
# on your own, sort hurricanes by speed.....
sorted(hurricanes, key = lambda d : d.get("speed", 0))
```
%% Output
[{'name': 'Calvin', 'year': 2000},
{'name': 'Alexandria', 'year': 1980, 'speed': 100},
{'name': 'Blanc', 'year': 1990, 'speed': 250}]
%% Cell type:markdown id: tags:
### This is all great, but what I'd really like to do is to sort dictionaries!
%% Cell type:code id: tags:
``` python
menu = { 'pie': 3.95,
'ala mode':1.50,
'donut': 1.25,
'cookie': 0.79,
'milk':1.65,
'loaf': 5.99,
'hot dog': 4.99}
# sorted (dict) returns a list of the keys sorted
sorted(menu)
```
%% Output
['ala mode', 'cookie', 'donut', 'hot dog', 'loaf', 'milk', 'pie']
%% Cell type:code id: tags:
``` python
# but we can make progress on this by using the .items() method
menu.items()
```
%% Output
dict_items([('pie', 3.95), ('ala mode', 1.5), ('donut', 1.25), ('cookie', 0.79), ('milk', 1.65), ('loaf', 5.99), ('hot dog', 4.99)])
%% Cell type:code id: tags:
``` python
# that looks like a list of tuples!
# let's sort menu.items() the same way we sorted a list of tuples
sorted(menu.items(), key = lambda t : t[0] ) # set the sorting key to a lambda expressoin
```
%% Output
[('ala mode', 1.5),
('cookie', 0.79),
('donut', 1.25),
('hot dog', 4.99),
('loaf', 5.99),
('milk', 1.65),
('pie', 3.95)]
%% Cell type:code id: tags:
``` python
# now let's turn this list of tuples into a dict
dict(sorted(menu.items(), key=lambda thing: thing[0]))
```
%% Output
{'ala mode': 1.5,
'cookie': 0.79,
'donut': 1.25,
'hot dog': 4.99,
'loaf': 5.99,
'milk': 1.65,
'pie': 3.95}
%% Cell type:code id: tags:
``` python
# can you change the previous code to sort by price?
dict(sorted(menu.items(), key=lambda thing: thing[1]))
```
%% Output
{'cookie': 0.79,
'donut': 1.25,
'ala mode': 1.5,
'milk': 1.65,
'pie': 3.95,
'hot dog': 4.99,
'loaf': 5.99}
%% Cell type:code id: tags:
``` python
# can you sort the dictionary by the length of the name?
dict(sorted(menu.items(), key=lambda thing: len(thing[0])))
```
%% Output
{'pie': 3.95,
'milk': 1.65,
'loaf': 5.99,
'donut': 1.25,
'cookie': 0.79,
'hot dog': 4.99,
'ala mode': 1.5}
%% Cell type:markdown id: tags:
## After Lecture
%% Cell type:code id: tags:
``` python
# Practice sorting a list of tuples
# Practice sorting a list of dictionaries
# Practice sorting a dictionary by keys
# Practice sorting a dictionary by values
```
%% Cell type:code id: tags:
``` python
# Warmup 1: Complete the recursive function.
# Write a function that prints nested lists with indenting
#
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")]
]
def print_with_indenting(directory, indent_level):
for subitem in directory:
if type(subitem) == list or type(subitem) == tuple:
print("\t" * indent_level + str(type(subitem)))
# TODO make recursive call
else:
print("\t" * indent_level + str(subitem))
print_with_indenting(fav_stuff, 0)
```
%% Cell type:markdown id: tags:
[PythonTutor Link](https://pythontutor.com/visualize.html#code=def%20mystery%28a,%20b%29%3A%20%0A%23%20precondition%3A%20assume%20a%20%3E%200%20and%20b%20%3E%200%0A%20%20%20%20if%20b%20%3D%3D%201%3A%20%0A%20%20%20%20%20%20%20%20return%20a%3B%0A%20%20%20%20return%20a%20*%20mystery%28%20a,%20b%20-%201%20%29%0A%0A%23%20make%20a%20function%20call%20here%0Amystery%287,%205%29&cumulative=false&curInstr=0&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=3&rawInputLstJSON=%5B%5D&textReferences=false)
%% Cell type:code id: tags:
``` python
# Warmup 2: Trace Recursion by hand .... possible exam question
def mystery(a, b):
# precondition: assume a > 0 and b > 0
if b == 1:
return a;
return a * mystery( a, b - 1 )
# make a function call here
mystery(7, 5)
#Q: What would be the result if we call
#. mystery(-3, -1) ??
```
%% Output
16807
%% Cell type:markdown id: tags:
## Lecture 23: Functions are Objects!
As we have learned previously, all variables in Python are stored as objects.
This is also true for functions, and it gives us more power as programmers.
**Learning Objectives:**
- Define a function reference and trace code that uses function references.
- Explain the default use of sorted() on lists of tuples, and dictionaries.
- Sort a list of tuples, a list of dictionaries, or a dictionary using a function as a key.
- Use a lambda expression when sorting.
%% Cell type:code id: tags:
``` python
# function references
# try this in Python Tutor
x = [1,2,3]
y = x
def f(some_list): # what is f?
return some_list[-1]
z = f(y) # z stores the result of a call to f
g = f # what is g?
# TODO: similar to line 10, store the result of a call to g
```
%% Cell type:markdown id: tags:
### Define a function reference and trace code that uses function references.
%% Cell type:markdown id: tags:
![function%20reference.png](attachment:function%20reference.png)
%% Cell type:markdown id: tags:
[PythonTutor Link](https://pythontutor.com/visualize.html#code=def%20hammer%28%29%3A%0A%20%20%20%20print%28%22tap%20tap%20tap%22%29%0A%20%20%20%20%0Adef%20call_n_times%28f,%20n%29%3A%0A%20%20%20%20for%20i%20in%20range%28n%29%3A%0A%20%20%20%20%20%20%20%20f%28%29%0A%0Acall_n_times%28hammer,%203%29&cumulative=false&curInstr=0&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=3&rawInputLstJSON=%5B%5D&textReferences=false)
%% Cell type:code id: tags:
``` python
# function references can be passed as arguments ...Wow!
# first: try this in Python Tutor
def hammer():
print("tap tap tap")
# then on your own: define a function called screwdriver
def screwdriver():
pass
def call_n_times(f, n):
for i in range(n):
f()
call_n_times(hammer, 3)
# then on your own: invoke call_n_times with screwdriver and 5 as arguments
```
%% Output
tap tap tap
tap tap tap
tap tap tap
%% Cell type:markdown id: tags:
## Your turn!
Calculate the distance between two points using either the manhattan or euclidean distance.
%% Cell type:markdown id: tags:
![image.png](attachment:image.png)
Source: https://www.researchgate.net/figure/Example-of-Euclidean-and-Manhattan-distances-between-two-points-A-and-B-The-Euclidean_fig8_333430988
%% Cell type:markdown id: tags:
### Review: NamedTuples
We create a namedtuple `Point` with named attributes `x` and `y`. We then create lists of points we want to calculate distances between
%% Cell type:code id: tags:
``` python
from collections import namedtuple
Point = namedtuple("Point", ["x", "y"])
left_points = [
Point(0, 0),
Point(3, 3),
Point(2, 2),
# TODO: Add another point!
]
right_points = [
Point(5, 5),
Point(0, 3),
Point(2, 2),
# TODO: Add another point!
]
```
%% Cell type:markdown id: tags:
### Complete the function `calculate_distances`
%% Cell type:markdown id: tags:
We already did the math behind `manhattan_distance` and `euclidean_distance` for you!
**Hint:** `distance_algo` should be a reference to a function that calculates distance between two points.
Then, call calculate_distances measuring first in manhattan_distance, then euclidean_distance.
%% Cell type:code id: tags:
``` python
import math
def manhattan_distance(point1, point2):
dist_x = abs(point1.x - point2.x)
dist_y = abs(point1.y - point2.y)
return dist_x + dist_y
def euclidean_distance(point1, point2):
dist_x = (point1.x - point2.x) ** 2
dist_y = (point1.y - point2.y) ** 2
return math.sqrt(dist_x + dist_y)
# TODO: Complete this function!
def calculate_distances(distance_algo):
pass
# TODO: Calculate the distance between the points using manhattan distance
# TODO: Calculate the distance between the points using euclidean distance
```
%% Cell type:markdown id: tags:
### Explain the default use of sorted() on lists of tuples, and on dictionaries.
%% Cell type:code id: tags:
``` python
# first... did you know that sort/sorted takes a 2nd argument called reverse?
populations = [55, 77, 33, 99, 22]
# TODO: sort populations in reverse
```
%% Cell type:code id: tags:
``` python
# Sorting part 1....how are lists of tuples sorted?
# olympic womens hockey badgers...first, last, age
owhockey_badgers = [ ("Hillary", "Knight", 32 ),
("Brianna", "Decker", 30),
("Amanda", "Kessel", 30),
("Alex", "Cavalenni", 30),
("Caroline", "Harvey", 19),
("Abbey", "Roque", 24)
]
# call sorted on this list of tuples
sorted(owhockey_badgers)
# what did this make? How was it sorted?
```
%% Output
[('Abbey', 'Roque', 24),
('Alex', 'Cavalenni', 30),
('Amanda', 'Kessel', 30),
('Brianna', 'Decker', 30),
('Caroline', 'Harvey', 19),
('Hillary', 'Knight', 32)]
%% Cell type:code id: tags:
``` python
# sorting part 2: define a function that returns a value from a tuple
def select0(some_tuple): # function must have exactly one parameter
return some_tuple[0]
def select1(some_tuple):
return some_tuple[1]
def select2(some_tuple):
return some_tuple[2]
# Test these functions on the tuple ("Mike", "Gurmail", "Cole")
```
%% Cell type:code id: tags:
``` python
# call sorted using the 'key' argument
# sort and sorted can take a parameter named key
# key is a reference to a function!
sorted(owhockey_badgers, key=select2)
```
%% Cell type:code id: tags:
``` python
# sort the list of tuples based on the last name
```
%% Cell type:code id: tags:
``` python
# sort the list of tuples based on the age
```
%% Cell type:markdown id: tags:
### Using `lambda`
- `lambda` functions are a way to abstract a function reference
- lambdas are simple functions with:
- multiple possible parameters
- single expression line as the function body
- lambdas are useful abstractions for:
- mathematical functions
- lookup operations
- lambdas are often associated with a collection of values within a list
- Syntax:
```python
lambda parameters: expression
```
%% Cell type:code id: tags:
``` python
# sorting part 3....using lambdas
'''
def no_name(each_tuple):
return each_tuple[-1]
'''
sorted(owhockey_badgers, key = lambda each_tuple : each_tuple[-1])
# read the lambda as: my no-name function has each_tuple as a parameter
# and returns each_tuple[-1] (the last element)
# the variable 'each_tuple' is like a function parameter
```
%% Cell type:code id: tags:
``` python
# TODO: sort the list by the length of the first name
'''
def no_name(x):
return len(x[0])
'''
```
%% Cell type:code id: tags:
``` python
# TODO: Sort the list by the length of their full name
```
%% Cell type:markdown id: tags:
### OK, I can sort a list of tuples....what about a list of dictionaries?
%% Cell type:code id: tags:
``` python
hurricanes = [
{"name": "Calvin", "year": 2000},
{"name": "Alexandria", "year": 1980, "speed": 100},
{"name": "Blanc", "year": 1990, "speed": 250},
]
# call sorted on hurricanes and use a lambda expression to grab the year
sorted(hurricanes, key = lambda d : d["year"], reverse=True)
```
%% Output
[{'name': 'Calvin', 'year': 2000},
{'name': 'Blanc', 'year': 1990, 'speed': 250},
{'name': 'Alexandria', 'year': 1980, 'speed': 100}]
%% Cell type:code id: tags:
``` python
# sort hurricanes alphabetically by name
# for you to do on your own...see the above example
```
%% Cell type:code id: tags:
``` python
# on your own, sort hurricanes by speed.....
```
%% Cell type:markdown id: tags:
### This is all great, but what I'd really like to do is to sort dictionaries!
%% Cell type:code id: tags:
``` python
menu = { 'pie': 3.95,
'ala mode':1.50,
'donut': 1.25,
'cookie': 0.79,
'milk':1.65,
'loaf': 5.99,
'hot dog': 4.99}
# sorted (dict) returns a list of the keys sorted
sorted(menu)
```
%% Cell type:code id: tags:
``` python
# but we can make progress on this by using the .items() method
menu.items()
```
%% Cell type:code id: tags:
``` python
# that looks like a list of tuples!
# let's sort menu.items() the same way we sorted a list of tuples
sorted(menu.items(), key = lambda t : t[0] ) # set the sorting key to a lambda expressoin
```
%% Cell type:code id: tags:
``` python
# now let's turn this list of tuples into a dict
```
%% Cell type:code id: tags:
``` python
# can you change the previous code to sort by price?
```
%% Cell type:code id: tags:
``` python
# can you sort the dictionary by the length of the name?
```
%% Cell type:markdown id: tags:
## After Lecture
%% Cell type:code id: tags:
``` python
# Practice sorting a list of tuples
# Practice sorting a list of dictionaries
# Practice sorting a dictionary by keys
# Practice sorting a dictionary by values
```