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

Louis 20 Objects and Tuples

parent 1550758f
No related branches found
No related tags found
No related merge requests found
%% 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
```
{
"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
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