Sampling and Estimation
Confidence Interval for the Mean
Compute a 95% CI as mean ± t_crit × SE, where SE = s/√n (ddof=1) and
t_crit = scipy.stats.t.ppf(0.975, df=n−1) is hardcoded as a literal so
both halves use the identical critical value. Two loops for mean and sample
std; then CI = mean ± t_crit × SE. Library: scipy.stats.t.interval(0.95, df, loc=mean, scale=SE).
By hand
Sample [4,7,2,9,5,9], n=6. Mean=6.0, s=√8≈2.828427, SE≈1.154701, df=5. t_crit = 2.5705818356 (scipy.stats.t.ppf(0.975, 5)). Margin = t_crit × SE ≈ 2.9683. CI: (6.0−2.9683, 6.0+2.9683) = (3.0317, 8.9683).
import math
sample = [4, 7, 2, 9, 5, 9]
n = len(sample)
total = 0.0
for v in sample:
total = total + v
mean = total / n
sq_diff = 0.0
for v in sample:
sq_diff = sq_diff + (v - mean) ** 2
s = math.sqrt(sq_diff / (n - 1))
se = s / math.sqrt(n)
df = n - 1
t_crit = 2.570581835636314 # scipy.stats.t.ppf(0.975, df=5)
margin = t_crit * se
lower = mean - margin
upper = mean + margin
print('RESULT:', (round(lower, 4), round(upper, 4)))
import math
1import math2sample = [4, 7, 2, 9, 5, 9]sample ← [4, 7, 2, 9, 5, 9]
1import math2sample = [4, 7, 2, 9, 5, 9]3n = len(sample)values this step[4, 7, 2, 9, 5, 9]samplen ← 6
2sample = [4, 7, 2, 9, 5, 9]3n = len(sample)4total = 0.0values this step6ntotal ← 0.0
3n = len(sample)4total = 0.05for v in sample:values this step0.0totalv ← 4, total ← 4.0
pass 1 of 64total = 0.05for v in sample:6 total = total + v7mean = total / nvalues this step4v0.0 → 4.0totalAll 6 passes — pass 1 is the card above pass vtotal1 4 0.0 → 4.0 2 4 → 7 4.0 → 11.0 3 7 → 2 11.0 → 13.0 4 2 → 9 13.0 → 22.0 5 9 → 5 22.0 → 27.0 6 5 → 9 27.0 → 36.0 for v in sample:
4total = 0.05for v in sample:6 total = total + vmean ← 6.0
6 total = total + v7mean = total / n8sq_diff = 0.0values this step6.0meansq_diff ← 0.0
7mean = total / n8sq_diff = 0.09for v in sample:values this step0.0sq_diffv ← 4, sq_diff ← 4.0
pass 1 of 68sq_diff = 0.09for v in sample:10 sq_diff = sq_diff + (v - mean) ** 211s = math.sqrt(sq_diff / (n - 1))values this step9 → 4v0.0 → 4.0sq_diffAll 6 passes — pass 1 is the card above pass vsq_diff1 9 → 4 0.0 → 4.0 2 4 → 7 4.0 → 5.0 3 7 → 2 5.0 → 21.0 4 2 → 9 21.0 → 30.0 5 9 → 5 30.0 → 31.0 6 5 → 9 31.0 → 40.0 for v in sample:
8sq_diff = 0.09for v in sample:10 sq_diff = sq_diff + (v - mean) ** 2s ← 2.8284271247461903
10 sq_diff = sq_diff + (v - mean) ** 211s = math.sqrt(sq_diff / (n - 1))12se = s / math.sqrt(n)values this step2.8284271247461903sse ← 1.1547005383792517
11s = math.sqrt(sq_diff / (n - 1))12se = s / math.sqrt(n)13df = n - 1values this step1.1547005383792517sedf ← 5
12se = s / math.sqrt(n)13df = n - 114t_crit = 2.570581835636314 # scipy.stats.t.ppf(0.975, df=5)values this step5dft_crit ← 2.570581835636314
13df = n - 114t_crit = 2.570581835636314 # scipy.stats.t.ppf(0.975, df=5)15margin = t_crit * sevalues this step2.570581835636314t_critmargin ← 2.968252229557177
14t_crit = 2.570581835636314 # scipy.stats.t.ppf(0.975, df=5)15margin = t_crit * se16lower = mean - marginvalues this step2.968252229557177marginlower ← 3.031747770442823
15margin = t_crit * se16lower = mean - margin17upper = mean + marginvalues this step3.031747770442823lowerupper ← 8.968252229557176
16lower = mean - margin17upper = mean + margin18print('RESULT:', (round(lower, 4), round(upper, 4)))values this step8.968252229557176upperstdout ← RESULT: (3.0317, 8.9683)
17upper = mean + margin18print('RESULT:', (round(lower, 4), round(upper, 4)))values this stepRESULT: (3.0317, 8.9683)stdout
With the library
scipy.stats.t.interval(0.95, df, loc=mean, scale=SE) computes the same
interval using the same t critical value internally. The snapshot shows
t_crit explicitly so the match is verifiable.
import math
import numpy as np
from scipy.stats import t
from dalib.display import set_display
set_display()
sample = [4, 7, 2, 9, 5, 9]
n = len(sample)
mean = float(np.mean(sample))
s = float(np.std(sample, ddof=1))
se = s / math.sqrt(n)
df = n - 1
t_crit = float(t.ppf(0.975, df))
lo, hi = t.interval(0.95, df, loc=mean, scale=se)
print('mean:', mean, ' SE:', round(se, 6))
print('t_crit (df=5):', round(t_crit, 10))
print('RESULT:', (round(float(lo), 4), round(float(hi), 4)))
mean: 6.0 SE: 1.154701
t_crit (df=5): 2.5705818356
RESULT: (3.0317, 8.9683)
Honesty
This lesson shows the computation exactly, on a tiny pinned sample. The arithmetic is correct and reproducible, but with a sample this small the result is not a valid statistical finding — it demonstrates the mechanism, not evidence. Real inference needs an adequate sample size and assumption checks (e.g. independence and normality or large n for the CLT); the p-value / interval here should be read as "how the formula is computed," not as a conclusion about a population.
Implementation notes
- The t_crit literal
2.570581835636314equalsscipy.stats.t.ppf(0.975, 5)to full float64 precision — this is why parity holds. - Interpretation: "95% of intervals constructed this way will contain the true population mean." NOT "95% probability the true mean is in this specific interval."
- Width scales with 1/√n (via SE) and with df (wider for small samples due to higher t_crit). At large n, t_crit approaches the normal z=1.96.
- Cross-reference:
standard-error(this chapter) for the SE computation;z-scores(ch02) for the standardization concept underlying the t statistic.