Reference

Cheat sheet

Every test in the course on one printable page: its formula, when to use it, and the Python (scipy.stats and statsmodels) and Excel that run it on the course's own data. The core formulas are the tutorial's Appendix A. Every value is the lab's engine's, and the tests run every line against it, with each library's own conventions.

The Python lines assume these imports:

import numpy as np
from scipy import stats
from scipy.stats import norm, t, chi2, f
from statsmodels.stats.proportion import proportions_ztest, proportion_effectsize, confint_proportions_2indep
from statsmodels.stats.rates import test_poisson_2indep
from statsmodels.stats.contingency_tables import mcnemar
from statsmodels.stats.weightstats import ttost_ind
from statsmodels.stats.multitest import multipletests
from statsmodels.stats.power import TTestPower, TTestIndPower, NormalIndPower

The logic of a test

The one-sample z test (σ known)

Taught in chapter 3: The p-value

When to use it: When σ comes from a long record of the process, not from this sample. Reject H₀ when p ≤ α, or when z lies beyond the critical value.

Chapter 12's line A, 40 bottles (ml), in A2:A41.

line_a = np.array([506.9, 504.9, 492.6, 486.9, 516, 514.9, 500.2, 478.7, 520, 507.5, 503.4, 499.1, 496.2, 508, 487.7, 503.9, 498.8, 500.3, 498.5, 495.6, 509.9, 498.6, 491.4, 502.6, 505.9, 480.2, 500.6, 485.5, 510.3, 507.6, 497.7, 488.8, 494.5, 510.6, 504.1, 500, 504.5, 504.6, 509, 491.3])
What it computes Python Excel Value
z for the bottles: x̄ = 504, μ₀ = 500, σ = 10, n = 25 (504 - 500) / (10 / np.sqrt(25)) =(504-500)/(10/SQRT(25)) 2.00
Its two-tailed p-value 2 * norm.sf(abs((504 - 500) / (10 / np.sqrt(25)))) =2*(1-NORM.S.DIST(ABS((504-500)/(10/SQRT(25))), TRUE)) 0.0455
The two-tailed critical value at α = 0.05 norm.ppf(0.975) =NORM.S.INV(0.975) 1.9600
Line A against 500 ml with σ = 9 known: Excel's Z.TEST is the upper one-tailed p norm.sf((line_a.mean() - 500) / (9 / np.sqrt(40))) =Z.TEST(A2:A41, 500, 9) 0.3772

The confidence interval for a mean

Taught in chapter 5: Tests and confidence intervals

When to use it: To report the range of values for μ the data support. A two-sided test at α rejects exactly the values outside the 1 − α interval (for the z and t tests of a mean).

What it computes Python Excel Value
The bottles' 95 % t interval, σ estimated by s = 10 t.interval(0.95, 24, loc=504, scale=10 / np.sqrt(25)) =504-CONFIDENCE.T(0.05, 10, 25)=504+CONFIDENCE.T(0.05, 10, 25) (499.87, 508.13)
The same with σ = 10 known (z) norm.interval(0.95, loc=504, scale=10 / np.sqrt(25)) =504-CONFIDENCE.NORM(0.05, 10, 25)=504+CONFIDENCE.NORM(0.05, 10, 25) (500.08, 507.92)

Means

When to use it: One mean against a claimed value when σ is estimated from the sample, which is almost always. Check the shape for small samples; the Wilcoxon signed-rank test is the fallback.

Chapter 12's line A, 40 bottles (ml), in A2:A41.

line_a = np.array([506.9, 504.9, 492.6, 486.9, 516, 514.9, 500.2, 478.7, 520, 507.5, 503.4, 499.1, 496.2, 508, 487.7, 503.9, 498.8, 500.3, 498.5, 495.6, 509.9, 498.6, 491.4, 502.6, 505.9, 480.2, 500.6, 485.5, 510.3, 507.6, 497.7, 488.8, 494.5, 510.6, 504.1, 500, 504.5, 504.6, 509, 491.3])
What it computes Python Excel Value
The bottles' two-tailed p-value, t = 2.00 on 24 degrees of freedom 2 * t.sf(2.0, 24) =T.DIST.2T(2, 24) 0.0569
The two-tailed critical value at α = 0.05 t.ppf(0.975, 24) =T.INV.2T(0.05, 24) 2.0639
Line A's mean against 500 ml, from the data stats.ttest_1samp(line_a, 500).pvalue =T.DIST.2T(ABS((AVERAGE(A2:A41)-500)/(STDEV.S(A2:A41)/SQRT(40))), 39) 0.7656
Cohen's d for the bottles (504 - 500) / 10 =(504-500)/10 0.40

Two independent means: Welch's t test

Taught in chapter 7: Two independent means

When to use it: Two separate groups of units. Use Welch's test by default: it does not assume equal variances and costs almost nothing when they are equal. scipy pools the variances unless you pass equal_var=False.

Chapter 14's settlement times in days: office A in A2:A16, office B in B2:B16.

a = np.array([6.6, 2.1, 26.4, 5.3, 3.7, 3.4, 11.8, 5, 20.5, 9.7, 3.2, 8.2, 7, 3.6, 3.4])
b = np.array([18.8, 9.4, 6.4, 78.2, 7.5, 6.8, 12, 6.9, 15.8, 18.8, 7.5, 29.8, 15.4, 8.6, 28.8])
What it computes Python Excel Value
Welch's t for the two offices' settlement times stats.ttest_ind(a, b, equal_var=False).statistic =(AVERAGE(A2:A16)-AVERAGE(B2:B16))/SQRT(VAR.S(A2:A16)/15+VAR.S(B2:B16)/15) -1.9891
Welch's two-tailed p-value stats.ttest_ind(a, b, equal_var=False).pvalue =T.TEST(A2:A16, B2:B16, 2, 3) 0.0622
The pooled (Student) test: what scipy runs when equal_var is left out stats.ttest_ind(a, b).pvalue =T.TEST(A2:A16, B2:B16, 2, 2) 0.0565

Paired samples: the paired t test

Taught in chapter 8: Paired samples

When to use it: The same units measured twice, or matched pairs. It is a one-sample t test on the differences; the design, not the p-value, decides that the data are paired.

Helion's first 12 agents, average daily calls before (A2:A13) and after (B2:B13).

pre = np.array([50.1, 40.6, 62.7, 69.6, 63.9, 68.6, 60.7, 54.2, 59.2, 53.3, 85.2, 64.5])
post = np.array([36.5, 38.2, 59.4, 63.3, 58, 63.7, 64.6, 41.8, 45, 50, 76.5, 67.6])
What it computes Python Excel Value
The first 12 agents, after against before stats.ttest_rel(post, pre).pvalue =T.TEST(B2:B13, A2:A13, 2, 1) 0.0067
The same data wrongly treated as two independent groups stats.ttest_ind(post, pre, equal_var=False).pvalue =T.TEST(B2:B13, A2:A13, 2, 3) 0.2618
Cohen's d_z, the mean difference in standard deviations of the differences (post - pre).mean() / (post - pre).std(ddof=1) =AVERAGE(B2:B13-A2:A13)/STDEV.S(B2:B13-A2:A13) -0.9621

Proportions and counts

One proportion: the z test and the exact binomial test

Taught in chapter 9: One proportion

When to use it: A yes/no outcome against a target rate. The z test needs n p₀ and n(1 − p₀) both at least 10; otherwise, or when in doubt, use the exact binomial test.

What it computes Python Excel Value
470 of 500 on time against 95 %, z with the null standard error proportions_ztest(470, 500, value=0.95, prop_var=0.95)[1] =2*NORM.S.DIST(-ABS((470/500-0.95)/SQRT(0.95*0.05/500)), TRUE) 0.3049
statsmodels' default uses the sample proportion instead proportions_ztest(470, 500, value=0.95)[1] =2*NORM.S.DIST(-ABS((470/500-0.95)/SQRT(0.94*0.06/500)), TRUE) 0.3464
The exact binomial test, two-sided stats.binomtest(470, 500, 0.95).pvalue Excel has no two-sided exact test: BINOM.DIST gives each tail, and the two-sided p adds every outcome no more likely than the one observed. 0.3037
The exact test, one-sided: fewer on time than promised stats.binomtest(470, 500, 0.95, alternative='less').pvalue =BINOM.DIST(470, 500, 0.95, TRUE) 0.1765
Meridian's large losses, 171 of 4,663: the exact (Clopper–Pearson) 95 % interval stats.binomtest(171, 4663).proportion_ci(method='exact') =BETA.INV(0.025, 171, 4663-171+1)=BETA.INV(0.975, 171+1, 4663-171) (0.0315, 0.0425)

Two proportions: the z test

Taught in chapter 10: Two proportions

When to use it: Two groups' rates, the workhorse of A/B testing. The test uses the pooled rate p̂, because H₀ says the rates are equal; the interval for the gap uses each group's own rate.

What it computes Python Excel Value
Helion's H1: 2,290 of 6,031 against 2,052 of 5,969 proportions_ztest([2290, 2052], [6031, 5969])[0] =(2290/6031-2052/5969)/SQRT(4342/12000*(1-4342/12000)*(1/6031+1/5969)) 4.0952
The small pilot: 138 against 110 of 1,000 proportions_ztest([138, 110], [1000, 1000])[1] =2*NORM.S.DIST(-ABS((0.138-0.11)/SQRT(0.124*0.876*2/1000)), TRUE) 0.0575
The 95 % Wald interval for H1's gap confint_proportions_2indep(2290, 6031, 2052, 5969, method='wald') =2290/6031-2052/5969-NORM.S.INV(0.975)*SQRT(2290/6031*(1-2290/6031)/6031+2052/5969*(1-2052/5969)/5969)=2290/6031-2052/5969+NORM.S.INV(0.975)*SQRT(2290/6031*(1-2290/6031)/6031+2052/5969*(1-2052/5969)/5969) (0.0187, 0.0531)
Cohen's h for H1 proportion_effectsize(2290 / 6031, 2052 / 5969) =2*ASIN(SQRT(2290/6031))-2*ASIN(SQRT(2052/5969)) 0.0748

Small counts: Fisher's exact test

Taught in chapter 10: Two proportions

When to use it: A 2 × 2 table with fewer than 10 successes or failures in a group. Given the table's totals, it adds the exact probabilities of every table at least as extreme as the observed one.

What it computes Python Excel Value
The tiny trial: 6 sales of 15 calls against 1 of 15, two-sided stats.fisher_exact([[6, 9], [1, 14]]).pvalue Excel has no two-sided Fisher test: HYPGEOM.DIST gives one table at a time (the one-sided line below adds them). 0.0801
One-sided: the new script sells more stats.fisher_exact([[6, 9], [1, 14]], alternative='greater').pvalue =1-HYPGEOM.DIST(5, 15, 7, 30, TRUE) 0.0400

When to use it: Counts in categories against a mix fixed in advance: a forecast, a 50/50 split (the sample ratio mismatch check). Counts, never percentages; every expected count at least 5.

Helion's contacts by channel in A2:A5, and the forecast's expected counts (the shares times 1,600) in B2:B5.

observed = np.array([742, 388, 271, 199])
expected = np.array([736, 384, 288, 192])
What it computes Python Excel Value
Helion's channel mix: χ² stats.chisquare(observed, expected).statistic =SUM((A2:A5-B2:B5)^2/B2:B5) 1.3493
Its p-value stats.chisquare(observed, expected).pvalue =CHISQ.TEST(A2:A5, B2:B5) 0.7175
The sample ratio mismatch check: 5,969 against 6,031 for 50/50 stats.chisquare([5969, 6031]).pvalue =CHISQ.DIST.RT((5969-6000)^2/6000+(6031-6000)^2/6000, 1) 0.5714

When to use it: Two categorical variables on the same units: is one associated with the other? scipy applies Yates' correction to a 2 × 2 table by default; Excel's CHISQ.TEST never does.

H1's counts in A2:B3 (Portal v2 first; paperless, then not), and the expected counts built from the margins in D2:E3.

table = np.array([[2290, 3741], [2052, 3917]])
expected = np.array([[2182.2168333333334, 3848.7831666666666], [2159.7831666666666, 3809.2168333333334]])
What it computes Python Excel Value
H1 as a 2 × 2 table, with scipy's default Yates correction stats.chi2_contingency(table)[1] Excel's CHISQ.TEST has no Yates correction: the next line is what it computes. 4.6e-05
Without the correction, as Excel computes it stats.chi2_contingency(table, correction=False)[1] =CHISQ.TEST(A2:B3, D2:E3) 4.2e-05
Uncorrected χ², which is z² of the two-proportion test stats.chi2_contingency(table, correction=False)[0] =((2290/6031-2052/5969)/SQRT(4342/12000*(1-4342/12000)*(1/6031+1/5969)))^2 16.7706
Cramér's V stats.contingency.association(table, method='cramer') Excel has no function for Cramér's V: use the formula above. 0.0374

Spread, several groups, and correlation

When to use it: One group's spread against a specification. Valid only for normal data, and very sensitive to anything else.

Chapter 12's line B, 40 bottles (ml), in B2:B41.

line_b = np.array([514.1, 478.4, 496.2, 503.6, 483.4, 507.7, 482.1, 513.5, 502, 496.4, 516.5, 518.6, 490.6, 496.9, 501.4, 498.5, 497.4, 535.8, 470.9, 519.9, 514.9, 498.5, 483.9, 516.6, 510.2, 497.2, 510.3, 502, 493.3, 521.2, 506.1, 502.4, 512.1, 497.5, 488, 499.3, 489.2, 499.9, 499.6, 500.1])
What it computes Python Excel Value
Is line B more erratic than σ = 10 ml allows? Upper tail chi2.sf(39 * np.var(line_b, ddof=1) / 10**2, 39) =CHISQ.DIST.RT(39*VAR.S(B2:B41)/10^2, 39) 0.0042

Two variances: the F test, Levene and Fligner–Killeen

Taught in chapter 12: Variances: χ², F and Levene

When to use it: Are two groups equally consistent? The F test is exact only for normal data; Levene's test (centred on the median) is the practical tool, and Fligner–Killeen a rank-based second opinion.

Chapter 12's two filling lines, 40 bottles each (ml): line A in A2:A41, line B in B2:B41.

line_a = np.array([506.9, 504.9, 492.6, 486.9, 516, 514.9, 500.2, 478.7, 520, 507.5, 503.4, 499.1, 496.2, 508, 487.7, 503.9, 498.8, 500.3, 498.5, 495.6, 509.9, 498.6, 491.4, 502.6, 505.9, 480.2, 500.6, 485.5, 510.3, 507.6, 497.7, 488.8, 494.5, 510.6, 504.1, 500, 504.5, 504.6, 509, 491.3])
line_b = np.array([514.1, 478.4, 496.2, 503.6, 483.4, 507.7, 482.1, 513.5, 502, 496.4, 516.5, 518.6, 490.6, 496.9, 501.4, 498.5, 497.4, 535.8, 470.9, 519.9, 514.9, 498.5, 483.9, 516.6, 510.2, 497.2, 510.3, 502, 493.3, 521.2, 506.1, 502.4, 512.1, 497.5, 488, 499.3, 489.2, 499.9, 499.6, 500.1])
What it computes Python Excel Value
F for line B against line A, two-sided 2 * min(f.sf(np.var(line_b, ddof=1) / np.var(line_a, ddof=1), 39, 39), f.cdf(np.var(line_b, ddof=1) / np.var(line_a, ddof=1), 39, 39)) =F.TEST(B2:B41, A2:A41) 0.0430
The upper critical value at α = 0.05, two-sided f.ppf(0.975, 39, 39) =F.INV.RT(0.025, 39, 39) 1.8907
Levene's test, median-centred (scipy's default) stats.levene(line_a, line_b).pvalue Excel has no function for this test. 0.1339
Fligner–Killeen stats.fligner(line_a, line_b).pvalue Excel has no function for this test. 0.1856

One-way ANOVA and Tukey's HSD

Taught in chapter 13: One-way ANOVA and after

When to use it: Three or more groups' means at once, instead of many t tests. A significant F says some means differ; Tukey's HSD (the Tukey–Kramer form) says which.

A made-up example: delivery days at three depots, five parcels each, in A2:A6, B2:B6 and C2:C6.

d1 = np.array([2.9, 3.4, 3.1, 3.8, 3.3])
d2 = np.array([3.9, 4.4, 3.6, 4.1, 4.5])
d3 = np.array([3.2, 3, 3.7, 3.5, 2.8])
What it computes Python Excel Value
F for the three depots stats.f_oneway(d1, d2, d3).statistic =(5*((AVERAGE(A2:A6)-AVERAGE(A2:A6, B2:B6, C2:C6))^2+(AVERAGE(B2:B6)-AVERAGE(A2:A6, B2:B6, C2:C6))^2+(AVERAGE(C2:C6)-AVERAGE(A2:A6, B2:B6, C2:C6))^2)/2)/((DEVSQ(A2:A6)+DEVSQ(B2:B6)+DEVSQ(C2:C6))/12) 9.0287
Its p-value stats.f_oneway(d1, d2, d3).pvalue =F.DIST.RT((5*((AVERAGE(A2:A6)-AVERAGE(A2:A6, B2:B6, C2:C6))^2+(AVERAGE(B2:B6)-AVERAGE(A2:A6, B2:B6, C2:C6))^2+(AVERAGE(C2:C6)-AVERAGE(A2:A6, B2:B6, C2:C6))^2)/2)/((DEVSQ(A2:A6)+DEVSQ(B2:B6)+DEVSQ(C2:C6))/12), 2, 12) 0.0040
Tukey's HSD: depot 1 against depot 2 stats.tukey_hsd(d1, d2, d3).pvalue[0, 1] Excel has no Tukey test and no studentized range distribution. 0.0105
η², the share of the variation between depots stats.f_oneway(d1, d2, d3).statistic * 2 / (stats.f_oneway(d1, d2, d3).statistic * 2 + 12) In Excel, divide the between sum of squares by the total: DEVSQ of all the values is the total. 0.6008

Rank tests: Mann–Whitney, Wilcoxon and Kruskal–Wallis

Taught in chapter 14: When the assumptions fail: ranks and permutations

When to use it: When the data are skewed or ordinal and n is small. Each asks whether one group tends to give larger values, not whether the means differ.

The offices' settlement times (a, b), the 12 agents' calls (pre, post) and the three depots (d1, d2, d3), as in the entries above.

a = np.array([6.6, 2.1, 26.4, 5.3, 3.7, 3.4, 11.8, 5, 20.5, 9.7, 3.2, 8.2, 7, 3.6, 3.4])
b = np.array([18.8, 9.4, 6.4, 78.2, 7.5, 6.8, 12, 6.9, 15.8, 18.8, 7.5, 29.8, 15.4, 8.6, 28.8])
pre = np.array([50.1, 40.6, 62.7, 69.6, 63.9, 68.6, 60.7, 54.2, 59.2, 53.3, 85.2, 64.5])
post = np.array([36.5, 38.2, 59.4, 63.3, 58, 63.7, 64.6, 41.8, 45, 50, 76.5, 67.6])
d1 = np.array([2.9, 3.4, 3.1, 3.8, 3.3])
d2 = np.array([3.9, 4.4, 3.6, 4.1, 4.5])
d3 = np.array([3.2, 3, 3.7, 3.5, 2.8])
What it computes Python Excel Value
Mann–Whitney for the two offices stats.mannwhitneyu(a, b).pvalue Excel has no function for this test. 0.0070
Wilcoxon signed-rank for the 12 agents stats.wilcoxon(post, pre).pvalue Excel has no function for this test. 0.0093
Kruskal–Wallis for the three depots stats.kruskal(d1, d2, d3).pvalue Excel has no function for this test. 0.0185

When to use it: Two numbers measured on the same units: do they move together? Pearson for a straight line; Spearman (Pearson on ranks) when the relationship is curved but one-directional, or there are outliers.

Helion's first 12 agents, average daily calls before (A2:A13) and after (B2:B13).

pre = np.array([50.1, 40.6, 62.7, 69.6, 63.9, 68.6, 60.7, 54.2, 59.2, 53.3, 85.2, 64.5])
post = np.array([36.5, 38.2, 59.4, 63.3, 58, 63.7, 64.6, 41.8, 45, 50, 76.5, 67.6])
What it computes Python Excel Value
Pearson's r for the 12 agents, before and after stats.pearsonr(pre, post).statistic =CORREL(A2:A13, B2:B13) 0.8883
Its two-tailed p-value stats.pearsonr(pre, post).pvalue =T.DIST.2T(ABS(CORREL(A2:A13, B2:B13))*SQRT(10)/SQRT(1-CORREL(A2:A13, B2:B13)^2), 10) 0.00011
Its 95 % interval (Fisher's z) stats.pearsonr(pre, post).confidence_interval(0.95) Excel has no function for it: FISHER, FISHERINV and NORM.S.INV build it. (0.6414, 0.9685)
Spearman's ρ: Pearson on the ranks stats.spearmanr(pre, post).statistic =CORREL(RANK.AVG(A2:A13, A2:A13, 1), RANK.AVG(B2:B13, B2:B13, 1)) 0.8531

Using tests well

When to use it: Before the test, for the smallest effect worth acting on; always round the sample size up. Never after it at the observed effect: that is a restatement of the p-value.

What it computes Python Excel Value
Bottles for 80 % power against d = 0.4 (round up: 52) TTestPower().solve_power(effect_size=0.4, alpha=0.05, power=0.8) Excel has no non-central t: the normal approximation below is close, and slightly low. 51.0094
The normal approximation ((norm.ppf(0.975) + norm.ppf(0.8)) / 0.4) ** 2 =((NORM.S.INV(0.975)+NORM.S.INV(0.8))/0.4)^2 49.0555
The power of 25 bottles against d = 0.4 TTestPower().power(effect_size=0.4, nobs=25, alpha=0.05) Excel has no non-central t. 0.4840
Customers per arm for a 3-point lift from 34 % NormalIndPower().solve_power(effect_size=proportion_effectsize(0.37, 0.34), alpha=0.05, power=0.8) In Excel: ((NORM.S.INV(0.975)+NORM.S.INV(0.8))/h)^2 × 2, which leaves out the far tail and is a hair lower. 3,992.1
The smallest d that 5,969 per arm detect 80 % of the time TTestIndPower().solve_power(nobs1=5969, alpha=0.05, power=0.8) Excel has no non-central t. 0.0513

Multiple testing: Bonferroni, Holm and Benjamini–Hochberg

Taught in chapter 18: Multiple testing, pre-registration and p-hacking

When to use it: Several tests on one experiment. Bonferroni and Holm control the chance of any false win (the family-wise error rate); Benjamini–Hochberg controls the false discovery rate. Pre-register which.

Four p-values from one experiment, sorted, in B2:B5.

p = np.array([0.001, 0.012, 0.03, 0.2])
What it computes Python Excel Value
The chance of at least one false win in 20 tests 1 - (1 - 0.05) ** 20 =1-(1-0.05)^20 0.6415
Bonferroni: the second smallest p-value, adjusted multipletests(p, method='bonferroni')[1][1] =MIN(1, 4*B3) 0.048
Holm: the same p-value, adjusted multipletests(p, method='holm')[1][1] =MAX(MIN(1, 4*B2), MIN(1, 3*B3)) 0.036
Benjamini–Hochberg: the third, adjusted multipletests(p, method='fdr_bh')[1][2] =MIN(B4*4/3, B5*4/4) 0.040

The risk review's tests

When to use it: Counts of events over unequal time in service (claims per vehicle-year, incidents per machine-hour): compare the rates, not the share of units that had an event.

What it computes Python Excel Value
Meridian's claim frequency, telematics against standard: the rate ratio (2062 / 23671.791) / (2601 / 23560.917) =(2062/23671.791)/(2601/23560.917) 0.7891
The score test's z test_poisson_2indep(2062, 23671.791, 2601, 23560.917, method='score', compare='ratio').statistic =(2062-2601*(23671.791/23560.917))/SQRT(4663*23671.791/23560.917) -8.0536
Its two-sided p-value test_poisson_2indep(2062, 23671.791, 2601, 23560.917, method='score', compare='ratio').pvalue =2*NORM.S.DIST(-ABS((2062-2601*(23671.791/23560.917))/SQRT(4663*23671.791/23560.917)), TRUE) 8.0e-16

When to use it: Two models or raters scored on the same cases. Only the disagreements count: under H₀ each goes either way with probability ½. statsmodels' mcnemar is exact unless you pass exact=False.

What it computes Python Excel Value
Meridian's fraud models: 5 against 54 disagreements, continuity-corrected χ² mcnemar([[87, 54], [5, 954]], exact=False).statistic =(ABS(54-5)-1)^2/(54+5) 39.0508
Its p-value mcnemar([[87, 54], [5, 954]], exact=False).pvalue =CHISQ.DIST.RT((ABS(54-5)-1)^2/(54+5), 1) 4.1e-10
The exact form, statsmodels' default mcnemar([[87, 54], [5, 954]]).pvalue =MIN(1, 2*BINOM.DIST(5, 59, 0.5, TRUE)) 1.9e-11

When to use it: To show that a difference is small enough to ignore, within a margin fixed before the data and on the scale the decision uses. Not significant is not the same as equivalent.

Chapter 12's two filling lines, 40 bottles each (ml): line A in A2:A41, line B in B2:B41.

line_a = np.array([506.9, 504.9, 492.6, 486.9, 516, 514.9, 500.2, 478.7, 520, 507.5, 503.4, 499.1, 496.2, 508, 487.7, 503.9, 498.8, 500.3, 498.5, 495.6, 509.9, 498.6, 491.4, 502.6, 505.9, 480.2, 500.6, 485.5, 510.3, 507.6, 497.7, 488.8, 494.5, 510.6, 504.1, 500, 504.5, 504.6, 509, 491.3])
line_b = np.array([514.1, 478.4, 496.2, 503.6, 483.4, 507.7, 482.1, 513.5, 502, 496.4, 516.5, 518.6, 490.6, 496.9, 501.4, 498.5, 497.4, 535.8, 470.9, 519.9, 514.9, 498.5, 483.9, 516.6, 510.2, 497.2, 510.3, 502, 493.3, 521.2, 506.1, 502.4, 512.1, 497.5, 488, 499.3, 489.2, 499.9, 499.6, 500.1])
What it computes Python Excel Value
Do lines A and B fill the same within ±3 ml? The TOST p-value (pooled) ttost_ind(line_a, line_b, -3, 3)[0] =MAX(T.DIST.RT((AVERAGE(A2:A41)-AVERAGE(B2:B41)+3)/SQRT((VAR.S(A2:A41)+VAR.S(B2:B41))/40), 78), T.DIST((AVERAGE(A2:A41)-AVERAGE(B2:B41)-3)/SQRT((VAR.S(A2:A41)+VAR.S(B2:B41))/40), 78, TRUE)) 0.2414
An unhandled error has occurred. Reload ๐Ÿ—™

Reconnecting…

Your connection to Hypothesis Testing Lab dropped, probably a Wi-Fi blip. Hold on while it reconnects.

The connection could not be restored. The page will reload in a few seconds.