Topic 3.16: Simulations | AP CSP Big Idea 3 | APCSExamPrep.com
Simulations
After this lesson, you will be able to:
- Explain what a simulation is and how it abstracts a real-world phenomenon using assumptions
- Give concrete reasons a simulation is used instead of a real experiment, such as cost, safety, speed, and repeatability
- Describe how randomness and iteration let a simulation run many trials and tally outcomes
- Explain why more trials generally give a more reliable estimate while results stay approximate
- Identify the limitations of a simulation, including its dependence on the model and its assumptions
- Read and trace simulation code that seeds randomness, loops over trials, and reports a summary
How would you find the chance of rolling a 6? You could roll a real die thousands of times, or you could write ten lines of code that rolls a virtual die a million times in a second, counts the sixes, and reports the fraction. That is a simulation: a safe, fast, repeatable model of the real world. The catch is that a model is only a model, and this lesson is about trusting it exactly as far as its assumptions allow.
What a Simulation Is
A simulation is a program that imitates a real-world process so you can study it on a computer instead of in the real world. It is a kind of abstraction: it keeps the details that matter for the question you are asking and leaves out everything else. A flight simulator does not recreate every molecule of air; it keeps just enough physics to practice flying. Because a simulation is built on assumptions and hypotheses about how the real thing behaves, it is a simplified stand-in, not a perfect copy.
Many simulations include randomness, because the real process being modeled has chance in it: a coin flip, a dice roll, whether it rains, which customer arrives next. The simulation uses a random number generator to mimic that uncertainty, and it uses a loop to run the scenario many times so it can see the range of things that could happen.
import random random.seed(1) heads = 0 for i in range(100): if random.randint(0, 1) == 1: heads = heads + 1 print(heads)
heads <- 0 REPEAT 100 TIMES { flip <- RANDOM(0, 1) IF (flip = 1) { heads <- heads + 1 } } DISPLAY(heads)
The code above models flipping a coin 100 times and counts the heads. The random.seed(1) line fixes the random sequence so the run is reproducible: everyone who runs it gets the same tally. Notice the AP pseudocode on the right expresses the same idea with RANDOM(0, 1) and REPEAT 100 TIMES. The two are just different spellings of one simulation.
The CED (AAP-3.F) says a simulation is "an abstraction of a real-world phenomenon" that uses "hypotheses" and often randomness. The exam will not ask you to write a full simulation. It asks you to reason about one: why it is used, what randomness and loops are doing, and what its results can and cannot tell you.
wins = 3 games = 4 print(wins * 100 // games)
Why We Simulate
If you can flip a real coin, why write a program to flip a fake one? Because for most interesting questions the real experiment is expensive, slow, dangerous, or impossible to repeat. A simulation removes those obstacles:
- Cheaper and safer: crash-test a bridge design or a rocket engine on a computer before spending money or risking harm.
- Faster: a program can play out a hundred years of climate or a million dice games in seconds.
- Repeatable and adjustable: you can run the exact same scenario again, or change one parameter (the rain chance, the number of trials) and immediately see the effect.
- Observable: you can model things that are hard to watch directly, like the spread of a disease or the motion of galaxies.
import random random.seed(2) sixes = 0 trials = 600 for i in range(trials): if random.randint(1, 6) == 6: sixes = sixes + 1 print(sixes * 100 // trials)
sixes <- 0 trials <- 600 REPEAT trials TIMES { roll <- RANDOM(1, 6) IF (roll = 6) { sixes <- sixes + 1 } } DISPLAY(sixes * 100 / trials)
Here the loop runs 600 trials of rolling a die and counts how often a 6 appears, then reports that count as a percent of the trials. That percent is an estimate of the true probability of rolling a 6. This is the core pattern of a probability simulation: run many trials, tally an outcome, report the fraction.
The more independent trials you run, the closer the estimate tends to land to the true probability. Six hundred rolls gives a steadier estimate than six rolls. A favorite exam idea: increasing the number of trials improves the reliability of the estimate but never makes it exact.
Randomness, Seeds, and Reproducibility
Randomness is what makes a simulation feel like the real, unpredictable world, and it is also why two runs can give slightly different answers. To make a run reproducible for testing or grading, you set a seed. Seeding fixes the random sequence, so the same seed always produces the same outcomes. That is useful, but the seed has to be set in the right place.
# BUG: seed is inside the loop for i in range(4): random.seed(1) print(random.randint(1, 6))
# FIX: seed once, before the loop random.seed(1) REPEAT 4 TIMES { DISPLAY(RANDOM(1, 6)) }
On the left the seed is placed inside the loop, so every iteration resets the generator to the same starting point and every roll comes out identical. That is not a simulation of four different rolls, it is the same roll printed four times. The fix on the right seeds once, before the loop, so the four rolls vary as intended while the whole run stays reproducible.
Because a simulation uses randomness, two runs with different seeds can produce different tallies and different estimates. That variation is not a bug. It is a property of the model. It also means a single run is weak evidence: you judge a simulation by many trials, not one lucky result.
import random random.seed(1) c = 0 for i in range(5): if random.randint(1, 6) == 6: c = c + 1 print(c)
Limitations: A Model Is Only as Good as Its Assumptions
A simulation is powerful precisely because it simplifies, and that simplification is also its weakness. Every simulation leaves things out, and its results are only as trustworthy as the assumptions built into it. If the model assumes a fair coin but the real coin is weighted, the simulation will confidently produce wrong conclusions. The output is an approximation of reality that depends entirely on the quality of the model.
The parameterized weather model below assumes a fixed 40 percent chance of rain every single day, independent of the day before. Real weather does not work that way, so this simulation is a rough abstraction. It is still useful for exploring "what if the chance were higher," but its numbers should never be mistaken for a real forecast.
import random random.seed(4) rainy = 0 chance = 40 for day in range(30): if random.randint(1, 100) <= chance: rainy = rainy + 1 print(rainy)
rainy <- 0 chance <- 40 REPEAT 30 TIMES { IF (RANDOM(1, 100) <= chance) { rainy <- rainy + 1 } } DISPLAY(rainy)
When you evaluate a simulation, ask two questions: are the assumptions reasonable for the question being asked, and were enough trials run to make the estimate stable? A well-built simulation with sound assumptions and many trials gives a useful approximation. A simulation with bad assumptions gives precise-looking numbers that are simply wrong.
heads = 120 total = 200 print(heads * 100 // total)
Key Vocabulary
| Term | Definition | Example |
|---|---|---|
| Simulation | A program that imitates a real-world process to study it safely and cheaply | a flight simulator |
| Abstraction | Keeping the details that matter and removing the rest | ignoring air molecules |
| Assumption | A simplifying belief the model is built on, which limits its accuracy | "rain chance is 40% daily" |
| Trial | One run of the scenario inside the simulation loop | one dice roll |
| Estimate | An approximate result computed from tallying many trials | sixes / trials |
| Seed | A fixed starting point that makes a random run reproducible | random.seed(1) |
A simulation is a strong choice for the Create Performance Task because it naturally uses a list, a loop, randomness, and a procedure that returns a result, which is exactly the machinery the rubric rewards. The key is to describe it honestly as a model with assumptions, not as reality.
A point-earning example
Imagine a program that estimates the chance of rolling a 6 by simulating many dice rolls and reporting the percentage:
In your written response, name the phenomenon, the randomness, and the role of iteration:
- "My program simulates rolling a fair die, using
RANDOM(1, 6)to model one roll." - "The loop runs 1000 independent trials and tallies how many are a 6, so the output estimates the probability rather than computing it exactly."
- "Because the estimate depends on randomness, running more trials makes it more reliable, but it remains an approximation based on the assumption that the die is fair."
The trap to avoid
Do not claim your simulation produces the true, exact answer. A simulation reports an approximation that depends on its assumptions and the number of trials. Saying "this proves the probability is exactly 16 percent" loses the abstraction point. See the full Create Task module →
Get a free AP CSP question every day
Join 3,000+ students. Daily practice, study tips, and exam strategies.
n successes out of t trials and reports the result as a whole-number percent. What is displayed?data equal 1. It prints the wrong total. Where is the bug?- I. A simulation uses simplifying assumptions, so its results are approximations of the real world.
- II. Running more independent trials generally makes the estimate more reliable.
- III. A simulation that uses randomness produces the exact same output on every run, no matter the seed.
-
headsis the count of heads -
totalis the number of flips
results is a list where 1 means success and 0 means failure. Loop through it, count the 1s, and print the count. Target output: 4
random.randint(1, 6)) 10 times, count how many are a 6, and print the count. Target output: 4
chance of rain each day. Simulate 30 days: each day, if random.randint(1, 100) is at most chance, it rained. Count and print the rainy days.-
chanceis 40 (a 40 percent daily chance)
random.randint(0, 1), where 1 is heads) 50 times. Print three lines:- line 1: the number of heads
- line 2: the number of tails
- line 3: the whole-number percent that were heads
Frequently Asked Questions
randomness. Each run draws different random values, so the tallies differ. To make a run reproducible, set a seed; the same seed always produces the same sequence. Different seeds, or no seed, give runs that vary.🔗 Continue studying
The Superpack includes an editable Topic 3.16 slide deck with animated trial-and-tally traces, a benefits-versus-limitations discussion bank, seed-placement bug examples, a print-ready simulation worksheet, and a unit quiz. View what's included →
Get in Touch
Whether you're a student, parent, or teacher — I'd love to hear from you.
Just want free AP CS resources?
Enter your email below and check the subscribe box — no message needed. Students get daily practice questions and study tips. Teachers get curriculum resources and teaching strategies.
Message Sent!
Thanks for reaching out. I'll get back to you within 24 hours.
Prefer email? Reach me directly at [email protected]