P3-M 4/25 Simulations Lesson-Alan
Creating simulations using pandas and python libraries
- Objectives
- What are simulations by College Board definition?
- Analyzing an Example: Air-Traffic Simulator
- Functions we often need (python)
- Functions we often need (js)
- College Board Question 1
- Examples
- Adding images (in Python)
- Population Growth and Plots
- Example on how simplification can cause bias
- JS examples
- Hacks submission
What are simulations by College Board definition?
- Simulations are models that mimic more complex objects or phenomena from the real world
- Purposes include drawing inferences without the costs or risks of the real world
- Simulations use varying sets of values to reflect the current state of a real phenomenon
- Often, when developing a simulation, it is necessary to remove specific variables or simplify aspects
- Simulations can often contain biases based on which details or real-world elements were included/excluded
- Simulations allow the formulation of properties under consideration
- Variability and randomness of the world is considered using random number generators
- Examples: rolling dice, spinners, molecular models, analyze chemicals/reactions...
Analyzing an Example: Air-Traffic Simulator
- Say we want to find out what the optimal number of aircrafts that can be in the air in one area is.
- A simulation allows us to explore this question without real world contraints of money, time, safety
- Unfortunately we can't just fly 67 planes all at once and see what happens
- Since the simulation won't be able to take all variables into control, it may have a bias towards one answer
- Will not always have the same result
import random # a module that defines a series of functions for generating or manipulating random integers
random.choice() #returns a randomly selected element from the specified sequence
random.choice(mylist) # returns random value from list
random.randint(0,10) #randomly selects an integer from given range; range in this case is from 0 to 10
random.random() #will generate a random float between 0.0 to 1.
// Math.random(); returns a random number
// Math.floor(Math.random() * 10); // Returns a random integer from 0 to 9:
Question: The following code simulates the feeding of 4 fish in an aquarium while the owner is on a 5-day trip:
numFish ← 4
foodPerDay ← 20
foodLeft ← 160
daysStarving ← 0
REPEAT 5 TIMES {
foodConsumed ← numFish * foodPerDay
foodLeft ← foodLeft - foodConsumed
IF (foodLeft < 0) {
daysStarving ← daysStarving + 1
}
}
- This simulation simplifies a real-world scenario into something that can be modeled in code and executed on a computer.
- Summarize how the code works:
- The variables are first declared. numFish is 4, foodPerDay is 20, foodLeft is 160, and daysStarving is 0. There is a loop that repeats the code inside of it 5 times. Inside the loop, the variable foodConsumed is equal to numFish times foodPerDay. Then, foodLeft is subtracted by foodConsumed. An if statement checks to see if foodLeft is less than 0, and if it is, then daysStarving increases by one. Again, this code is all in the loop that repeats 5 times.
import random
cards = ["Ace", "2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King"]
suits = ["Diamonds", "Hearts", "Spades", "Clubs"]
print(random.choice(cards) + " of " + random.choice(suits))
import random
def coinflip(): #def function
randomflip = random.randint(0, 2) #picks either 0 or 1 randomly
if randomflip == 0 or randomflip == 1: #assigning 0 to be heads--> if 0 is chosen then it will print, "Heads"
print("Heads")
else:
if randomflip == 2: #assigning 1 to be tails--> if 1 is chosen then it will print, "Tails"
print("Tails")
#Tossing the coin 5 times:
t1 = coinflip()
t2 = coinflip()
t3 = coinflip()
t4 = coinflip()
t5 = coinflip()
Your turn: Change the code to make it simulate the flipping of a weighted coin.
- Add a heads and tails images into your images directory with the correct names and run the code below
import random
# importing Image class from PIL package
from PIL import Image
# creating a object
im = Image.open(r"images/coin_heads.png")
image = Image.open(r"images/coin_tails.png")
i=random.randint(0,1)
if i == 1:
print("heads")
display(im)
else:
print("tails")
display(image)
In order to display an image in python, we can use the PIL package we previously learned about.
import random
print("Spin the wheel!")
print("----------------------------------")
n = 10
blue = 0
red = 0
blueImg = Image.open(r"images/blue_color.png")
redImg = Image.open(r"images/red_color.png")
for i in range(n):
spin = random.randint(1,2)
if spin == 1: # head
blue = blue + 1
display(blueImg)
else: # tail
red = red + 1
display(redImg)
print('Number of blue:', blue)
print('Number of red:', red)
Your turn: Add a visual to the simulation!
import random
totalPopulation = 50
growthFactor = 1.00005
dayCount = 0 #Every 2 months the population is reported
while totalPopulation < 1000000:
totalPopulation *= growthFactor
#Every 56th day, population is reported
dayCount += 1
if dayCount == 56:
dayCount = 0
print(totalPopulation)
Here we initialize the total population to be 50, then set the growth factor as 1.00005 (.005 percent change). It will print the population every 56th day until it reaches one million. It multiplies the current population by the growth factor in each iteration, and increments the day count. When the day count reaches 56, it prints the current population and resets the day count to 0.
Note! This simulation assumes that the growth factor remains constant as time progresses, which may not be a realistic assumption in real-world scenarios.
import matplotlib.pyplot as plt
# Define the initial population and growth rate
population = 100
growth_rate = 0.05
# Define the number of years to simulate
num_years = 50
# Create lists to store the population and year values
populations = [population]
years = [0]
# Simulate population growth for the specified number of years
for year in range(1, num_years+1):
# Calculate the new population size
new_population = population + (growth_rate * population)
# Update the population and year lists
populations.append(new_population)
years.append(year)
# Set the new population as the current population for the next iteration
population = new_population
# Plot the population growth over time
plt.plot(years, populations)
plt.xlabel('Year')
plt.ylabel('Population')
plt.title('Population Growth Simulation')
plt.show()
If we create quantative data, we can plot it using the Matplotlib library.
import random
beak = ["small-beak", "long-beak", "medium-beak"],
wing = ["small-wings", "large-wings", "medium-wings"],
height = ["short", "tall","medium"]
naturaldisaster = ["flood", "drought", "fire", "hurricane", "dustbowl"]
print("When a" , random.choice(naturaldisaster) , "hit", random.choice(height), "birds died")
How does this simulation have bias?
It doesn't consider the exact cause for the death of birds. Only the height of the bird is shown which gives inadequate information. The death of birds and their physical traits only show an association, not causation.
- Answer all questions and prompts in the notes (0.2)
- Create a simulation
- Create a simulation that uses iteration and some form of data collection (list, dictionary...) (0.4)
- try creating quantative data and using the Matplotlib library to display said data
- Comment and describe function of each parts
- How does your simulation help solve/mimic a real world problem?
- Is there any bias in your simulation? Meaning, are there any discrepancies between your program and the real event?
- Create a simulation that uses iteration and some form of data collection (list, dictionary...) (0.4)
- Answer these simulation questions (0.3)
-
Bonus: take a real world event and make a pseudocode representation or pseudocode on a flowchart of how you would make a simulation for it (up to +0.1 bonus)
-
Due Thursday Night
Hacks submission
- My simulation mimics a real world problem by providing a sample chemistry experiment where the chemical reaction is 0th order(concentration vs time is linear). It predicts the outcomes of a 0th order experiment and allows students to analyze graphs by identifying the reaction orders.
- There are some biases in my simulation. My code assumes that a reaction will not be 1st or 2nd order, which fails to account for lots of different types of chemical reactions. It also assumes that concentration will always start out at 5 M and that time will end at 5 seconds. Chemical reactions don't always end at 5 seconds, and not all reactions will start out perfectly at a specific concentration.
import matplotlib.pyplot as plt
import math
# Create lists for time, concentration(0th order), ln(concentration)(1st order), and 1/(concentration)(2nd order)
concList = []
timeList = []
firstOList = []
secondOList = []
i = 0
# Use a while loop to automatically input experimental data
while i<5:
# Decreases concentration by 1 M each time
concentration = 5 - i
# Time is assumed to proceed from 1 to 5 seconds, it's the same as i value
time = i
# Adds concentration and time to their lists
concList.append(concentration)
timeList.append(time)
i = i + 1
# Takes the natural log of all the concentrations entered for ln[A] vs time plot
for concData in concList:
firstOrder = math.log(concData)
# Add the modified concentration in a separate list
firstOList.append(firstOrder)
# Takes the 1/concentration of all concentrations enter for 1/[A] vs time plot
for concData in concList:
secondOrder = 1/concData
# Add the modified concentration in a separate list
secondOList.append(secondOrder)
# Plot [A] vs time graph
plt.plot(timeList, concList)
plt.xlabel('time(sec)')
plt.ylabel('concentration [A]')
plt.title('[A] vs time plot')
plt.show()
# Plot ln[A] vs time graph
plt.plot(timeList, firstOList)
plt.xlabel('time(sec)')
plt.ylabel('concentration ln([A])')
plt.title('ln([A]) vs time plot')
plt.show()
# Plot 1/[A] vs time graph
plt.plot(timeList, secondOList)
plt.xlabel('time(sec)')
plt.ylabel('concentration 1/[A]')
plt.title('1/[A] vs time plot')
plt.show()
Simulation Question Answers:
- Answer is A and B because they are able to track which ride is the most popular.
- Answer is A because rabbit population growth already takes into account grass, and it can be assumed that there is a certain constant amount of grass.
- Answer is B because the hole isn't going to be refilled if processes occur as usual. Also, the depth of the hole is not being tracked in this simulation.
- Answer is D because a simulation is flexible and less time-consuming.
- Answer is B and C because it can provide data very efficiently and can also take into account many different specific variables.
- Answer is C. Simulations aren't real-world things so assumptions have to be made in order to make the simulation possible.