Chapter 77 · Solutions
t-Tests — Worked Solutions ✅
Five challenges, each verified in code.
⚙️ Setup¶
In [1]:
import numpy as np, pandas as pd
from scipy import stats
BASE="https://raw.githubusercontent.com/johnfisher-ai/Statistics-Data-Science-AI-Visual-Book/main/data/"
rng=np.random.default_rng(770)
CHALLENGE 1
One-sample t-test
For a sample of 30 from N(48,10), test H0: mu = 50 (two-sided).
In [2]:
x=rng.normal(48,10,30); r=stats.ttest_1samp(x,50)
print(f"mean={x.mean():.2f}, t={r.statistic:.2f}, p={r.pvalue:.4f}")
mean=48.15, t=-0.96, p=0.3466
CHALLENGE 2
Welch two-sample t-test
Compare N(50,8,n=40) and N(54,14,n=45) with Welch's test.
In [3]:
a=rng.normal(50,8,40); b=rng.normal(54,14,45); r=stats.ttest_ind(a,b,equal_var=False)
print(f"meanA={a.mean():.2f}, meanB={b.mean():.2f}, t={r.statistic:.2f}, p={r.pvalue:.4f}")
meanA=49.38, meanB=52.33, t=-1.36, p=0.1771
CHALLENGE 3
Paired vs unpaired
Make before ~ N(100,15,n=30) and after = before - N(4,6). Compare paired and unpaired p-values.
In [4]:
before=rng.normal(100,15,30); after=before-rng.normal(4,6,30)
print(f"paired p={stats.ttest_rel(after,before).pvalue:.4f}")
print(f"unpaired p={stats.ttest_ind(after,before,equal_var=False).pvalue:.4f} (less powerful here)")
paired p=0.0713 unpaired p=0.6231 (less powerful here)
CHALLENGE 4
One-sided two-sample
For groups above, test H1: muB > muA (one-sided). Halve the two-sided p only if the direction matches.
In [5]:
a=rng.normal(50,8,40); b=rng.normal(54,10,45); r=stats.ttest_ind(b,a,equal_var=False)
p_one = r.pvalue/2 if r.statistic>0 else 1-r.pvalue/2
print(f"t={r.statistic:.2f}, one-sided p (muB>muA) = {p_one:.4f}")
t=0.59, one-sided p (muB>muA) = 0.2774
CHALLENGE 5
Real data: three class tests
Load t-tests--class_scores.xlsx; run the paired (post vs pre), two-sample (flipped vs traditional), and one-sample (gain vs 5) tests.
In [6]:
try: sc = pd.read_excel("../../data/t-tests--class_scores.xlsx", sheet_name="Scores")
except FileNotFoundError: sc = pd.read_excel(BASE+"t-tests--class_scores.xlsx", sheet_name="Scores")
gain=sc.posttest-sc.pretest
print(f"paired p={stats.ttest_rel(sc.posttest,sc.pretest).pvalue:.2e}")
fl=sc[sc.method=="flipped"].posttest; tr=sc[sc.method=="traditional"].posttest
print(f"two-sample p={stats.ttest_ind(fl,tr,equal_var=False).pvalue:.2e}")
print(f"one-sample gain vs 5 p={stats.ttest_1samp(gain,5).pvalue:.2e}")
paired p=6.00e-31 two-sample p=2.33e-05 one-sample gain vs 5 p=2.71e-08
Statistics, Data Science and AI: A Visual Handbook · © 2026 John Fisher