Objectives

  1. Understand how computers can be used to represent real-world phenomena or outcomes
  2. Compare simulations with real-world contexts.
  3. Implement code to mimic real world situations, problems, or phenomena.

What are simulations by College Board definition?

  • Simulations are abstractions that mimic more complex objects or phenomena from the real world
    • Purposes include drawing inferences without the constraints of the real world
  • Simulations use varying sets of values to reflect the changing state of a real phenomenon
  • Often, when developing a simulation, it is necessary to remove specific complexities or simplify aspects
    • Simulations can often contain biases based on which details or real-world elements were included/excluded
  • Simulations allow the formulation of hypotheses or predictions under consideration
  • Variability and randomness of the world is considered using random number generators
  • Examples: rolling dice, spinners, molecular models, analyzing 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

Functions we often need (python)

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.

Functions we often need (js)

// Math.random(); returns a random number
// Math.floor(Math.random() * 10); // Returns a random integer from 0 to 9:

College Board Question 1

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:

Examples

Card Flip

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))
King of Hearts

Coin Flip

import random

def coinflip():         #def function 
    randomflip = random.randint(1, 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()
Tails
Tails
Tails
Tails
Tails

Your turn: Change the code to make it simulate the flipping of a weighted coin.

Adding images (in Python)

  • 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/tails.png")

i=random.randint(0,1)

if i == 1:
    print("heads")
    display(im)

else:
    print("tails")
    display(image)
heads

In order to display an image in python, we can use the PIL package we previously learned about.

Spin the Wheel

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)
Spin the wheel!
----------------------------------
Number of blue: 155
Number of red: 145

Your turn: Add a visual to the simulation!

Population Growth and Plots

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()
Matplotlib is building the font cache; this may take a moment.

If we create quantative data, we can plot it using the Matplotlib library.

Example on how simplification can cause bias

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") 
When a hurricane hit medium birds died

How does this simulation have bias? It only picks from the height catagory.

JS examples

Hacks

  • Answer all questions and prompts in the notes (0.2)
  • Create a simulation
    1. 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?
  • 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)
import random
import matplotlib.pyplot as plt

# initialize variables
num_dice = 2
num_rolls = 1000
rolls = []

# roll the dice and collect data
for i in range(num_rolls):
    roll = 0
    for j in range(num_dice):
        roll += random.randint(1, 6)
    rolls.append(roll)

# display data using a histogram
plt.hist(rolls, bins=range(num_dice, num_dice*6+2), align='left', rwidth=0.8)
plt.xlabel('Roll')
plt.ylabel('Frequency')
plt.show()
import random
import matplotlib.pyplot as plt

In this section, we are importing the random and matplotlib.pyplot libraries. The random library is used to generate random integers, which we will use to simulate the roll of the dice. The matplotlib.pyplot library is used to plot the histogram of the data.

num_dice = 2
num_rolls = 1000
rolls = []

In this section, we are initializing three variables: num_dice, which represents the number of dice we will be rolling; num_rolls, which represents the number of times we will repeat the rolling process; and rolls, which will be a list that we will use to store the data from each roll.

for i in range(num_rolls):
    roll = 0
    for j in range(num_dice):
        roll += random.randint(1, 6)
    rolls.append(roll)

In this section, we are using a nested loop to simulate the rolling of the dice. We start by iterating num_rolls times using a for loop, and on each iteration, we reset the value of roll to 0. We then use another for loop to simulate rolling num_dice dice, and on each iteration, we add a random integer between 1 and 6 (inclusive) to roll. Finally, we append the total value of the roll to the rolls list.

plt.hist(rolls, bins=range(num_dice, num_dice*6+2), align='left', rwidth=0.8)
plt.xlabel('Roll')
plt.ylabel('Frequency')
plt.show()

Real World Problem In this section, we use the plt.hist() function from the Matplotlib library to plot the histogram of the data. The rolls list is passed as the first argument, and we set the bins parameter to a list of integers ranging from num_dice to num_dice*6+1, which specifies the range of values that can be rolled. We also set the align parameter to 'left', which shifts the bins to the left, so that each bin corresponds to a specific roll value (e.g., 2, 3, 4, etc.). Finally, we set the rwidth parameter to 0.8, which sets the width of each bin to 80% of its total width. We also set the labels for the x and y axes, and then use the plt.show() function to display the histogram.

BiasPseudo-random number generation: The random library in Python uses a pseudorandom number generator to simulate rolling dice. While this generator produces numbers that are statistically random, they are not truly random and can be predicted if the seed value is known. This means that the results of the simulation may not perfectly mimic the results of rolling real dice, which are truly random.

import sqlite3

database = 'instance/example.db' # If no file exists, this will create a new file "example.db" in the instance folder


def create_table():
    conn = sqlite3.connect(database)
    cursor = conn.cursor()

    cursor.execute("""
        CREATE TABLE students (
            id INTEGER PRIMARY KEY,
            name TEXT,
            grade INTEGER
        )
    """)

    conn.commit()
    conn.close()

create_table()