P3-M 4/25 Simulations
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
What are simulations by College Board definition?
- Simulations are simplifications that mimic more complex objects or phenomena from the real world
- Purposes include drawing inferences without the limites of the real world
- Simulations use varying sets of values to reflect the dynamic state of a real phenomenon
- Often, when developing a simulation, it is necessary to remove specific variables or simplify aspects
- Simulations can often contain bias based on which details or real-world elements were included/excluded
- Simulations allow the formulation of hypothesis 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: This code works by assigning the number of fish and original food amounts. These values are constant every time the program is run. However, as in simulations, the outcome is different. The simulation iterates through 5 days in the loop shown, each time having a reduction in food and adding to the variable daysStarving.
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, 1) #picks either 0 or 1 randomly
if randomflip == 0: #assigning 0 to be heads--> if 0 is chosen then it will print, "Heads"
print("Heads")
else:
if randomflip == 1: #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/HeadsOn.png")
image = Image.open(r"images/TailsOn.png")
i=random.randint(0,1)
if i == 1:
print("heads")
display(im)
else:
print("tails")
display(image)
# my images are not dragging/ dropping into here, which I cleared up with you guys during the lesson
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 = 300
blue = 0
red = 0
for i in range(n):
spin = random.randint(1,2)
if spin == 1: # head
blue = blue + 1
else: # tail
red = red + 1
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?
The simulation above does not account for bird wing or beak size is not taken into account. In a real natural disaster situation, the birds that survive in the aftermath likely have more in common than their height due to evolutionary principles that dictate survival-of-the-fittest. Therefore, this simulation is biased since there are many variables not taken into account.
- 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)
My hacks:
- During the lesson, I filled in the notes sections and played around with code. However, for the hacks that required images, I was unable to complete them fully since my vscode is not allowing me to drag and drop images, which I communicated to the presenters during class. I have completed them though to the best of my ability; they just won't run on my machine as intended but they may on yours.
-
Questions: A and B, A, A, D, B and C, C 1) Food preference and viewing type are not relevent to the wait time on rides 2) The grass amount may be necessary, but there is no need for a visual representation of the grass 3) The approximate length of time until the hole would be refilled could not be calculated due to the simulation only measuring data from the hole growth overtime, not prediction of refilling 4) all of the answers fall under the benefit of simulations; they are meant to test things that are hard to recreate in real life and do it fast 5) the purpose of such a large simulation would be to quickly perform an event hard to create in real life, and more control would be able to be implemented in a computer setting 6) the limit to simulations is that they are never able to recreate every single variable of real life, and are ultimately estimations
-
Biased coin (no visuals due to reason above) with a 9/10 chance of picking tails. Heads is only 1/10
- To make up for not being able to do the visuals on coin flip, for the spinner wheel hack, I did some research (and did consult chat gpt and google for the different chart/ pie chart options to be used in matplotlibrary) to incorporate a pie chart.
- My simulation is below with a description of its purpose. Although it is a little silly, I think the same logic of the simulation could be applied to a real life purpose of assessing possible impacts of a natural disaster on a house or building. My simulation doesn't really take into account variables like house income, price, location, or build, so it is biased in that it doesn't account for all variables that should dictate if a household is well enough to survive a disaster like a zombie apocalypse.
import random
def coinflip(): #def function
randomflip = random.randint(0, 9)
if randomflip == 0: #assigning 0 to be heads--> if 0 is chosen then it will print, "Heads"
print("Heads")
else:
print("Tails")
#Tossing the coin 5 times:
t1 = coinflip()
t2 = coinflip()
t3 = coinflip()
t4 = coinflip()
t5 = coinflip()
import random
import matplotlib.pyplot as plt
# Initialize counters
n = 300
blue = 0
red = 0
# Spin the wheel and count colors
for i in range(n):
spin = random.randint(1,2)
if spin == 1: # head
blue += 1
else: # tail
red += 1
# Create a pie chart
labels = ['Blue', 'Red']
sizes = [blue, red]
colors = ['lightblue', 'lightcoral']
explode = (0.1, 0) # "explode" the blue slice
fig, ax = plt.subplots()
ax.pie(sizes, explode=explode, labels=labels, colors=colors,
autopct='%1.1f%%', startangle=90)
ax.axis('equal') # Equal aspect ratio ensures that pie is drawn as a circle.
ax.set_title('Spin the Wheel')
plt.show()
#There is a zombie apocalypse. A household with 8 survivors is observed.
# Below is a simulation where we see how many of the people have been transformed into zombies.
# This involves three functions:
# 1: a function for randomizing decimal number 0-255.
# 2: a function for converting this to a 8-bit binary number (one bit per person).
# 3: a function to read the binary bits, and assign each person a label (zombie or naw) based on the position of 0s and 1s
# The amount of people who are zombies is randomly determined. Based on the placement of the 1s and 0s in the 8 bit number, each person is assigned as being a zombie or not
import random
import matplotlib.pyplot as plt
def randomnum(): # function for generating random int
n = random.randint(0,255)
print("The random decimal number generated is " + str(n))
return n
def converttobin(n):
if n == 0:
print("00000000")
return "00000000"
elif n == 1:
print("00000001")
return "00000001"
else:
binary = "" # define a string "" variable for storing binary digits; calculated below
# divide the number (n) by 2, until it becomes 0, and store the remainder in the above string variable
while int(n) > 0:
binary += str(int(n%2)) # retreive the remainder, and keep appending to the string
n = n / 2 # change the number to its quotient, then repeat
print(binary[::-1]) # now the binary string has all the desired digits, but in reverse order
# :: is how to reverse string
return binary
def survivors(binary):
zombie_count = 0
survivor_count = 0
survivorstatus = ["Jiya", "Shruthi", "Noor", "Ananya" , "Peter Parker", "Andrew Garfield", "Tom Holland", "Tobey Maguire"]
idx = 0
for bit in binary:
if (bit == "0"):
print(survivorstatus[idx] + " is a ZOMBIE!!!")
zombie_count += 1
else:
print(survivorstatus[idx] + " survived!!!")
survivor_count += 1
idx += 1 # advancing the index to the next position
plt.hist(['Zombies', 'Survivors'], weights=[zombie_count, survivor_count])
plt.title('Zombies vs. Survivors')
plt.xlabel('Status')
plt.ylabel('Count')
plt.show()
survivors(converttobin(randomnum())) # perform all the functions