Patrick Power PRO
Economics PhD @ Boston University
Focus on understanding the Ideas. Your understanding of the Syntax will develop with time & practice
Do not worry about understanding what this code does for the moment!
Still don't worry about understanding what this code does for the moment!
Takeaways
(1) We can use Python to Solve Problems
(2) Via Python, we can use other peoples' work to solve our problems
(3) Via Python, we can solve a problem by
Creating Variables
first_name = 'Lebron'
last_name = 'James'
print(first_name + ' ' + last_name)
a = 5
b = 10
print(a + b)
Integers
String (text!)
Creating Variables
a = 5
b = 10
a = 25
print(a + b)
Integers
first_name = 'Lebron'
last_name = 'James'
first_name = 'Bronny'
print(first_name + ' ' + last_name)
String (text!)
What happens when we do the following?
a = 5
import sys
a = 10
memory_location = id(a)
size_in_bytes = sys.getsizeof(a)
print(f"Memory location of a: {memory_location}")
print(f"Size of a: {size_in_bytes} bytes")
a
Memory
What happens when we do the following?
a = 5
b = 5
a = 5
b = 5
print(f"Memory location of a: {id(a)}")
print(f"Memory location of b: {id(b)}")
print(a is b)
print(a == b)
a
Memory
b
What happens when we do the following?
a = 257
b = 257
a = 257
b = 257
print(f"Memory location of a: {id(a)}")
print(f"Memory location of b: {id(b)}")
print(a is b)
print(a==b)
a
Memory
b
What happens when we do the following?
a = 257
b = a
a = 10
a
Memory
a = 257
a = 257
b = a
a
Memory
a
Memory
b
a = 257
b = a
a = 257
b = a
a = 10
a
Memory
b
a
Memory
b
Defining/Creating a Function
def f(x):
return x**2
(1) The `def' keyword tells us that we are defining a function
(2) `f' is the name of the function
(3) `x' is a placeholder for the input to the function
(4) The `:' indicates the beginning of a code block (in this context)
(5) The `return' keyword indicates what the function will return
def f(x):
return x**2
Working With Functions
def f(x):
return x**2
x = 2
f(x)
>> 4
What Do Mathematical Functions Do?
Domain
Codomain
Functions on the Computer
Domain
Codomain
Example # 1
def greeting(name):
print("Hello " + name)
a = greeting('Bob')
print(a)
Example # 2
def random_wage(avg_wage):
return avg_wage * (1 + np.random.normal(0, 0.1))
a = random_wage(10)
b = random_wage(10)
print(a)
print(b)
Example # 3
a = 10
def greeting(name):
global a
a = 20
print("Hello " + name)
print(a)
greeting("Bob")
print(a)
Let's Say We Have the Following Code
my_list = [0, 1, 2, 3, 4, 5]
def f(x):
return x**2
Task:
Print the square of each element in this list
Naive Approach
my_list = [0, 1, 2, 3, 4, 5]
def f(x):
return x**2
print(f(my_list[0]))
print(f(my_list[1]))
print(f(my_list[2]))
print(f(my_list[3]))
print(f(my_list[4]))
print(f(my_list[5]))
Redundant!
Indexing
For Loop #1
def f(x):
return x**2
my_list = [0, 1, 2, 3, 4, 5]
for i in my_list:
print(f(i))
"Easier" to write & read!
i = 0
print(f(i))
>> 0
i = 1
print(f(i))
>> 1
i = 2
print(f(i))
>> 4
i = 3
print(f(i))
>> 9
i = 4
print(f(i))
>> 16
i = 5
print(f(i))
>> 25
Python
For Loop #2
def f(x):
return x**2
my_list = [0, 1, 2, 3, 4, 5]
my_list_squared = []
for i in my_list:
my_list_squared.append(f(i))
Create empty list
For each element of `my_list`, apply `f` to the element and then include the result as the last element of `my_list_squared`
For Loop #3
In Class Exercise: Given a list, print the square of only the even numbers
my_list = [0, 1, 2, 3, 4, 5]
def f(x):
return x**2
for i in my_list:
if i % 2 == 0:
print(f(i))
For Loop #4
In Class Exercise: Given a list, print the square of the even numbers and the cube of the odd numbers
my_list = [0, 1, 2, 3, 4, 5]
def f(x):
return x**2
def g(x):
return x**3
for i in my_list:
if i % 2 == 0:
print(f(i))
else:
print(g(i))
For Loop #5
In Class Exercise: Given a list (could be a list of integers and/or strings), if it is an even number: print the square, if it is an odd number: print the cube, and if it is a string: print '!'
def f(x):
return x**2
def g(x):
return x**3
my_list = ["a", 1, 0, "b", 27, 9]
for x in my_list:
if type(x) == str:
print("!")
elif x % 2 == 0:
print(f(x))
elif x % 2 == 1:
print(g(x))
For Loop #6
In Class Exercise: Given a list of strings find the first element which begins with the letter 'a'
my_list = ['car', 'boat', 'airplane', 'truck']
for i in my_list:
if i[0] == 'a':
print(i)
break
In Class Exercise: The following code doesn't work. Explain why
def f(x):
return x**2
def g(x):
return x**3
my_list = ["a", 1, 0, "b", 27, 9]
for x in my_list:
if x % 2 == 0:
print(f(x))
elif x % 2 == 1:
print(g(x))
else:
print("!")
Original Code
def f(x):
return x**2
def g(x):
return x**3
my_list = ["a", 1, 0, "b", 27, 9]
for x in my_list:
if type(x) == str:
print("!")
elif x % 2 == 0:
print(f(x))
elif x % 2 == 1:
print(g(x))
Adjusted Code
Data Types
Integer (Int)
a = 1
b = 10
c = -8
String
a = 'Lebron'
b = 'Bronny'
c = 'James'
Float
a = 1.0
b = 10.2
c = -8.7
Boolean (Bool)
a = True
b = False
Function
Same Function, Different Types
Data Types
1 + 2
Int
1.4 + 2.7
Float
True + False
>> 1
Bool
'Lebron ' + 'James'
String
Data Types
Int
Float
Bool
String
def add_one(x):
return x + 1
In Class Exercise: Write a function that adds one to the input
Errors
Data Types
Int
Float
Bool
String
def add_one(x : int) -> int:
return x + 1
We can use Type Hints to inform the user (our future selves) of the type of inputs that our function takes and the type of output it produces
Input Type
Output Type
Data Types
Int
Float
Bool
String
In Class Exercise: Using type hints, write a function that takes an integer and a string as inputs and prints the string the number of times that the integer specifies. Include spaces!
def repeat_string(x : int, y : str) -> None:
print((y + ' ')*x)
Type Casting
Int
Float
int(2.0)
Int
Float
float(25)
import jax
def f(x):
return x**2
jax.grad(f)(1)
Type Error
import jax
def f(x):
return x**2
jax.grad(f)(float(1))
Type Casting
Type Casting
Int
Bool
int(True)
String
Float
float('25')
Infix Functions
'Lebron ' > 'Bronny'
(-1 < 2) & (2 >= 3)
(-1 < 2) | (2 >= 3)
(-1 < 2) or ('String'/2)
(-1 < 2) and (2 >= 3)
Conditionals
Examples
Conditionals
print("You won the lottery!")
print("Try again!")
Check if their ticket matches the drawn number
def lottery(ticket, drawn_numbers):
Let's say we want to create a function that captures the following idea
Match
Didn't Match
Example
The New Part
We can express this in Python
if condition:
print("You won the lottery!")
else:
print("Try again!")
We can express this in Python
What should the condition be?
ticket == drawn_number
Evaluates to either True or False
Check if their ticket matches the drawn number
Putting it All Together
print("You won the lottery!")
print("Try again!")
Check if their ticket matches the drawn number
def(ticket, drawn_numbers):
Match
Didn't Match
def lottery(ticket, drawn_number):
if ticket == drawn_number:
print("You won the lottery")
else:
print("Try again!")
my_ticket = 4
wed_draw = 4
lottery(my_ticket, wed_draw)
print("You won the lottery!")
if 4 == 4:
lottery(4, 4)
Walk Through
my_ticket = 8
wed_draw = 3
lottery(my_ticket, wed_draw)
print("Try again!")
if 8 == 3:
lottery(8, 3)
else:
Walk Through
Let's say though that given the score in soccer, we want to report which team won
Motivation
home_score > away_score
home_score == away_score
print("The Home team won!")
Compare the home_score to the away_score
def game(home_score, away_score):
print("Tie!")
print("The Away team won!")
home_score < away_score
If Condition
elif Condition
else Condition
def game(home_score, away_score):
if home_score > away_score:
print("The Home Team Won!")
elif home_score < away_score:
print("The Away Team Won")
else:
print("A Tie!")
Putting it All Together
h_score = 3
a_score = 4
game(h_score, a_score)
print("The Home Team Won!")
if 4 > 3:
game(4, 3)
Walk Through
h_score = 1
a_score = 2
game(h_score, a_score)
print("The Away Team Won!")
if 1 > 2:
game(1, 2)
Walk Through
elif 1 < 2:
h_score = 2
a_score = 2
game(h_score, a_score)
print("The Away Team Won!")
if 2 > 2:
game(2, 2)
Walk Through
elif 2 < 2:
else:
Analyst
Associate
Vice President
Managing Director
Partner
Global Head of Cardboard Packaging Investment Banking
Titles
Americas Head of Exotic Volatility Trading in Stocks Starting with ‘P’
Global head of "whatever the weird trad was"
Head of Macro
if other_person == 'colleague':
print("This is James, a Research Analyst")
else:
print("This is James, Head of Macro")
Head of Macro
(1) `if' keyword signifies that the following is a conditional
(2) `==' is an infix function that returns True or False
(3) `:' denotes that the following will be an indented line code block
(4) `else:' says run this code block if the first condition was False
Options
if (option == 'call') & (strike_price < stock_price):
profit = stock_price - strike_price - payment
elif (option == 'put') & (strike_price > stock_price):
profit = strike_price - stock_price - payment
else:
profit = - payment
Lists
companies = ["Microsoft", "GE", "Intel"]
Append
companies.append("Uber")
print(companies) # Output: ["Microsoft", "GE", "Intel", "Uber"]
Consider
What happens if you were to execute this code multiple times in a row?
Index
a = companies[2]
print(a) # Output: 'Intel'
print(companies[0]) # Output: 'Microsoft'
Index
companies = ["Microsoft", "GE", "Intel","Uber"]
print(companies[-3]) # Output: 'GE'
Slicing
print(companies[1:3]) # Output: ['GE', 'Intel']
Slicing
print(companies[:2]) # Output: ['Microsoft', GE']
print(companies[0:2]) # Output: ['Microsoft', GE']
print(companies[-3:]) # Output: ['GE', 'Intel', 'Uber']
print(companies[-3:len(companies)]) # Output: ['GE', 'Intel', 'Uber']
Check Your Understanding
#2 Create the same slice of the list using only negative integers
companies[:2]
#1 Create the same slice of the list using only positive integers
companies[-3:]
Lists of Lists
companies = ['Apple', 'Microsoft', 'Google', 'Amazon', 'Facebook', 'Tesla', 'IBM', 'Netflix', 'Samsung', 'Intel']
current_thoughts = [companies[:3], [companies[4], companies[7]], companies[8:]]
Wouldn't it be great to have labels associated with each inner list?
Check Your Understanding
True/False
companies[0] == companies[:1]
Extending
m_2000.extend(['BP', 'Royal Dutch Shell', 'IBM'])
Remove by Value
m_2000.remove('BP')
Remove by Index
m_2000.pop(2)
>> cisco
Checking Membership
'uber' in m_2000
>> False
Lists
m_2000.sort()
Sorting
Length
len(m_2000)
>> 7
Comparing Lists
[3, 4, 3] < [3, 4, 4]
>> True
Dictionaries
current_thoughts = {'prioritize' :companies[:3],
'wait_to_apply': [companies[4], companies[7]],
'ignore': companies[8:]}
Adding Elements to a Dictionary
current_thoughts['research_more'] = companies[1:4]
Consider
What happens if you were to execute this code multiple times in a row?
People Learn Differently
Want to learn about each function associated with Lists in Python before using them!
Will learn the relevant functions associated with Lists as they arise in real world coding problems
Our Approach
Understanding
Worked Example
Note some of the quotes and exercises are adopted from
Which is not a book about Python
By Patrick Power