Chapter 64 · Solutions
Determining Sample Size — Worked Solutions ✅
Five challenges, each verified in code.
⚙️ Setup¶
In [1]:
import numpy as np
from scipy import stats
rng = np.random.default_rng(640)
z95 = stats.norm.ppf(0.975); z99 = stats.norm.ppf(0.995)
print(f"z(95%)={z95:.4f} z(99%)={z99:.4f}")
z(95%)=1.9600 z(99%)=2.5758
CHALLENGE 1
Sample size for a mean
With sigma=20 and a target margin of +/-3 at 95% confidence, find n and verify by simulation.
In [2]:
sigma, E = 20, 3
n = int(np.ceil((z95*sigma/E)**2))
print(f"n = (z*sigma/E)^2 = {(z95*sigma/E)**2:.1f} -> {n}")
w = np.mean([z95*rng.normal(50,sigma,n).std(ddof=1)/np.sqrt(n) for _ in range(4000)])
print(f"simulated margin at n={n}: +/- {w:.2f} (target {E})")
n = (z*sigma/E)^2 = 170.7 -> 171 simulated margin at n=171: +/- 3.00 (target 3)
CHALLENGE 2
Sample size for a proportion (known p)
A pilot suggests p=0.2. For a +/-4% margin at 95%, find n.
In [3]:
p, E = 0.2, 0.04
n = int(np.ceil(z95**2 * p*(1-p) / E**2))
print(f"n = z^2 p(1-p)/E^2 = {z95**2*p*(1-p)/E**2:.1f} -> {n}")
n = z^2 p(1-p)/E^2 = 384.1 -> 385
CHALLENGE 3
The worst case is p=0.5
Show p=0.5 maximizes the required sample size, and compute the safe n for +/-4%.
In [4]:
E=0.04
for p in [0.1,0.3,0.5,0.7,0.9]:
print(f"p={p}: n = {z95**2*p*(1-p)/E**2:.0f}")
print(f"\nworst case p=0.5: n = {z95**2*0.25/E**2:.0f} (use this when p is unknown)")
p=0.1: n = 216 p=0.3: n = 504 p=0.5: n = 600 p=0.7: n = 504 p=0.9: n = 216 worst case p=0.5: n = 600 (use this when p is unknown)
CHALLENGE 4
Halve the margin, quadruple the sample
Confirm that cutting the target margin in half multiplies the required sample size by four.
In [5]:
for E in [0.05, 0.025]:
print(f"E=+/-{E*100:.1f}%: n = {z95**2*0.25/E**2:.0f}")
print(f"ratio = {(z95**2*0.25/0.025**2)/(z95**2*0.25/0.05**2):.0f}x (because n ~ 1/E^2)")
E=+/-5.0%: n = 384 E=+/-2.5%: n = 1537 ratio = 4x (because n ~ 1/E^2)
CHALLENGE 5
Higher confidence costs more
Compare the sample size for 95% vs 99% confidence at the same +/-3% margin.
In [6]:
E=0.03
n95 = z95**2*0.25/E**2; n99 = z99**2*0.25/E**2
print(f"95% confidence: n = {n95:.0f}")
print(f"99% confidence: n = {n99:.0f}")
print(f"the extra confidence costs {(n99/n95-1)*100:.0f}% more data (ratio of z^2)")
95% confidence: n = 1067 99% confidence: n = 1843 the extra confidence costs 73% more data (ratio of z^2)
Statistics, Data Science and AI: A Visual Handbook · © 2026 John Fisher