Session 10 Coin Toss Simulator
Introduction
A coin toss simulator is a simple way to introduce randomness in programming. In computational thinking, simulation means defining a random process, repeating it many times, and collecting the outcomes to study a pattern.
This exercise fits well after guessing games and prime number programs because it still uses variables, loops, and conditionals, but it introduces a new idea: the same program can produce different valid results on different runs because chance is involved.
Nature of Probability
To understand probability, we must distinguish between what is possible and what is likely
Equal Likelihood: In a fair coin toss, the probability of heads or tails is 50% (1/2). However, this does not mean that if you toss a coin 10 times, you will get exactly five heads and five tails.
Likelihood of Outcomes: While getting 10 heads in a row is possible, it is extremely unlikely. Probability tells us that a 5/5 or 6/4 distribution is the more likely outcome, whereas 9/1 is much less likely.
Independent Events: Each coin toss is independent. Previous results do not influence the next toss; even if you have already tossed eight heads, the probability for the next toss remains exactly 50%.
The Law of Large Numbers: As the number of tosses increases (e.g., to 100 or 1,000), the distribution of heads and tails will become roughly equal
Learning goals
By the end of this lesson, students should be able to:
- identify the inputs, outputs, and variables needed for a simulation program;
- write the logic of a repeated random experiment in simple steps;
- convert that logic into pseudocode;
- implement the pseudocode in Python;
- discuss why results vary from run to run and why large numbers of trials often produce stable patterns.
Problem statement
Write a program to simulate tossing a fair coin (N) times. The program must count how many times the result is Heads and how many times it is Tails.
After all tosses are completed, the program should also calculate the fraction of tosses that are Heads and the fraction of tosses that are Tails. These fractions are examples of an empirical distribution, meaning a distribution based on observed outcomes from data or simulation.
Input
- A positive integer (N), representing the number of coin tosses.
Output
- Number of Heads.
- Number of Tails.
- Fraction of Heads.
- Fraction of Tails.
Example
If (N = 10), one run of the program might produce 6 Heads and 4 Tails, while another run with the same (N) might produce 3 Heads and 7 Tails because the outcomes are random.
What is needed
Before writing code, clearly identify what the program needs.
| Item | Purpose |
|---|---|
N |
Number of tosses to simulate. |
heads_count |
Stores how many Heads have occurred. |
tails_count |
Stores how many Tails have occurred. |
| Random coin toss | Produces one outcome for each trial, such as 0/1 or H/T. |
| Loop | Repeats the toss process exactly (N) times. |
This stage is important because students learn that a program becomes easier to write once the data to be tracked is clearly identified.
Logic in words
The logic can be written in simple English before pseudocode.
- Read the value of (N).
- Set the Heads counter to 0.
- Set the Tails counter to 0.
- Repeat the following steps (N) times:
- simulate one coin toss;
- if the toss is Heads, increase the Heads counter by 1;
- otherwise, increase the Tails counter by 1.
- After the loop ends, calculate the fraction of Heads and the fraction of Tails.
- Print all results.
This structure follows the standard simulation pattern of defining one random event, repeating it many times, and collecting summary results.
Pseudocode
START
INPUT N
SET heads_count = 0
SET tails_count = 0
REPEAT N TIMES
GENERATE a random result: 0 or 1
IF result == 1 THEN
heads_count = heads_count + 1
ELSE
tails_count = tails_count + 1
END IF
END REPEAT
SET heads_fraction = heads_count / N
SET tails_fraction = tails_count / N
PRINT "Heads =", heads_count
PRINT "Tails =", tails_count
PRINT "Heads fraction =", heads_fraction
PRINT "Tails fraction =", tails_fraction
END
The pseudocode is intentionally close to the final Python program so that students can see how a plan becomes code.
Python code
import random
n = int(input("Enter number of coin tosses: "))
heads_count = 0
tails_count = 0
for i in range(n):
toss = random.randint(0, 1) # 0 = Tails, 1 = Heads
if toss == 1:
heads_count = heads_count + 1
else:
tails_count = tails_count + 1
heads_fraction = heads_count / n
tails_fraction = tails_count / n
print("Heads =", heads_count)
print("Tails =", tails_count)
print("Heads fraction =", heads_fraction)
print("Tails fraction =", tails_fraction)This solution uses a for loop for repetition, counters to store totals, and an if statement to update the correct counter after each toss.
Sample run
Enter number of coin tosses: 10
Heads = 6
Tails = 4
Heads fraction = 0.6
Tails fraction = 0.4
A second run may produce different values even for the same input because the simulation depends on random outcomes.
Detailed discussion
Why do results change every run?
A simulation of a fair coin toss uses randomness, so the exact sequence of Heads and Tails is different each time the program is executed. This is what makes simulation useful for studying chance processes.
Why do the fractions move toward 0.5?
For a fair coin, the long-run proportion of Heads is expected to be close to 0.5, and simulations with larger numbers of tosses tend to produce empirical proportions closer to that value. Small samples can vary a lot, but larger samples are usually more stable.
Which programming ideas are revised here?
This program reinforces several core ideas:
- variables and assignment;
- counters;
- loops;
- conditional statements;
- input and output;
- basic numerical calculation.
What edge cases should be discussed?
If the user enters 0, the program attempts to divide by zero while calculating fractions, so the class should either require (N > 0) or add validation before continuing. This is a useful moment to discuss why programs must handle invalid input carefully.
Classroom extensions
Once the basic version works, students can try small modifications.
- Print each toss as
HorTbefore printing the final totals. - Check whether Heads occurred more often, Tails occurred more often, or both were equal.
- Run the experiment for (N = 10), (100), and (1000), and compare the results.
- Repeat the whole experiment 5 times and compare the fractions from each run.
- Count how many times two Heads occur in a row, which leads naturally to pattern-based simulations.
Questions for discussion
- Why is it possible for two students to use the same code and input but get different answers?
- Why does the program need two counters?
- What happens if (N) is very small, such as 1 or 2?
- What happens if (N) is 0?
- Why do larger values of (N) usually produce more balanced fractions?
Python Implementation & Tools
VS Code and AI: Students are encouraged to use GitHub Copilot or AI chat within VS Code to convert their pseudo-code into functional Python
Loops: While a while loop requires manual decrementing of the control variable, a for in range(tosses) loop handles the iterations automatically
Verification: Using a computer to simulate a coin toss is “validating mathematics with mathematics” because the program relies on a mathematical random function rather than a physical toss
Learning Strategy: The “Human-First” Approach
It is vital to understand the logic before using AI. If you provide a problem directly to an AI, it will implement its own logic, which you may not understand
The recommended process is:
- Write top-level conceptual logic
- Write line-by-line programmatic logic
- Use AI to convert that logic to Python
- Ask the AI to explain any lines you do not understand
Homework Assignments
The Million-Toss Challenge: Run the coin toss program for 1,000, 10,000, and up to 1,000,000 tosses. Record how the percentages of heads and tails change as the sample size grows
Single Dice Simulation: Write a program for a single dice toss. Track how many times each number (1–6) appears and calculate their percentages over powers of six (e.g., 6, 36, 216 tosses)
Two Dice Summation: Create a program that tosses two dice and calculates the sum of the results (ranging from 2 to 12). Track the percentage distribution of these sums to see which totals occur most frequently
Summary
The coin toss simulator is a compact example of computational thinking. It shows how to describe a process clearly, translate it into logic and pseudocode, implement it in code, and then interpret the output using ideas from randomness and empirical distributions.