# Probability Distributions Reference Sheet: [Your course or data set]

> A reference sheet for the probability distributions that appear in introductory and intermediate statistics:
> Bernoulli, binomial, Poisson, geometric, negative binomial, hypergeometric, uniform, normal, exponential, gamma,
> beta, lognormal, Weibull, t, chi-square and F. For each one it gives the story behind it, the pmf or pdf in
> KaTeX, the support, the parameters, the mean and variance, and typical uses, followed by a map of how the
> distributions are related and a side-by-side table of R and Python (scipy.stats) functions with the
> parameterisation traps that cause most wrong answers. It is for students who need a single page to revise from,
> thesis writers choosing a model for their outcome, and analysts who switch between R and Python. It speeds up
> learning by attaching each formula to a concrete story, by showing the distributions as one connected family,
> and by making you practise lookups with fading worked examples and a "which distribution?" self-test. Every
> lookup value on this sheet was produced by running the code shown. The worked examples use fictional data;
> replace them with your own. Source basis: standard distribution theory, the NIST/SEMATECH e-Handbook of
> Statistical Methods (chapter 1.3.6), and the R `stats` and SciPy documentation.

<!--
Guidance: How to use this template
- Start with "Choosing a distribution": the decision diagram is the part you will use most in practice.
- For each distribution, learn the story (what process produces it) before the formula. If you can tell the
  story, you can rebuild the mean and often the variance.
- Use the R and Python table when coding. Before you trust any lookup, check the parameterisation row: scipy's
  scale is 1/rate, R's geometric counts failures, scipy's counts trials.
- Work through Example A, complete Example B, then solve Exercise C. Then do the "which distribution?" self-test
  without looking at the sheet.
- Add your own rows for distributions your course uses (for example multinomial, Cauchy, logistic) and delete
  rows you never need.
- Related templates: academic/stats-probability-basics, academic/stats-sampling-distributions,
  academic/stats-estimation-mle, academic/stats-count-regression, academic/stats-test-selector,
  academic/stats-formula-sheet, academic/stats-data-transformations, academic/stats-flashcards-spaced-review.
-->

## Document control

<!-- Guidance: Note your software versions: function names and default parameterisations have changed between library versions in the past, so a version note saves debugging time. -->

| Field | Value |
|---|---|
| Course or project | [STAT 201 Probability and Inference] |
| Learner or analyst | [Your name] |
| Data set | Fictional: Harbour City Library returns, Brightwell Bakery loaves, Lakemoor University exam scores |
| Software and versions | R 4.5.1 (stats); Python 3.14 with scipy 1.18.1 and numpy 2.5.4 |
| Date | YYYY-MM-DD |
| Version | [0.1] |

## The idea in one paragraph

<!-- Guidance: Restate this paragraph in your own words before reading on. The key idea is "a distribution is a model of a process", not "a formula to memorise". -->

A probability distribution is a model of how a random quantity behaves: which values it can take (its
**support**) and how likely each value or range is. **Discrete** distributions give a probability to each count
through a probability mass function (pmf); **continuous** distributions spread probability over an interval
through a probability density function (pdf), and probabilities are areas under the curve. Every named
distribution comes from a simple story: "count successes in a fixed number of independent tries" gives the
binomial, "count rare events in a fixed window" gives the Poisson, "add up many small independent effects"
gives the normal, "wait for the next event in a memoryless process" gives the exponential. Pick the distribution
whose story matches how your data were generated, check its support against your data, and then use software to
look up probabilities and quantiles. The four lookup questions are always the same: the probability of exactly a
value (d), the probability up to a value (p), the value with a given probability below it (q), and random draws
(r).

## Choosing a distribution

<!-- Guidance: Use the diagram on your own variable. Write the path you followed in the box below it; the path is your justification for the model choice in a methods section. -->

Structure aligned with the NIST/SEMATECH e-Handbook catalogue of distributions (chapter 1.3.6), reorganised by
the question a learner asks about their data; wording and examples are original.

```mermaid
flowchart TD
  A["What kind of values?"] --> B["Counts or yes/no (discrete)"]
  A --> C["Measurements (continuous)"]
  B --> D["One trial, success or failure?"]
  D -->|Yes| E["Bernoulli"]
  D -->|No| F["Fixed number of trials n?"]
  F -->|"Yes, with replacement or large population"| G["Binomial"]
  F -->|"Yes, without replacement from small population"| H["Hypergeometric"]
  F -->|"No, count trials until success"| I["Geometric or negative binomial"]
  F -->|"No, events in a window of time or space"| J["Poisson (variance about equal to mean)"]
  J -->|"Variance much bigger than mean"| K["Negative binomial"]
  C --> L["Bounded between 0 and 1?"]
  L -->|Yes| M["Beta"]
  L -->|No| N["Positive only and right-skewed?"]
  N -->|"Waiting time, constant rate"| O["Exponential"]
  N -->|"Sum of waits, flexible skew"| P["Gamma"]
  N -->|"Log of values looks normal"| Q["Lognormal"]
  N -->|"Lifetimes, rising or falling failure rate"| R["Weibull"]
  N -->|"No, symmetric, unbounded"| S["Normal"]
  C --> T["A test statistic?"]
  T --> U["t, chi-square or F"]
```

My path for [my variable]: [Measurements, positive, right-skewed, log looks normal: lognormal].

## Discrete distributions

<!-- Guidance: For each distribution, cover the formula and say the story aloud, then derive the mean from the story (for example, binomial mean = n trials times p per trial). -->

Notation: $p$ is the success probability, $q = 1 - p$, $n$ the number of trials, $\lambda$ a rate or mean count,
and $\binom{n}{x}$ the number of combinations (see academic/stats-probability-basics).

| Distribution | Story | Support | Parameters | Mean | Variance | Typical uses |
|---|---|---|---|---|---|---|
| Bernoulli | One trial: success (1) or failure (0) | 0, 1 | $p$ | $p$ | $pq$ | A single yes/no outcome; building block of the others |
| Binomial | Successes in $n$ independent trials with the same $p$ | 0, 1, ..., $n$ | $n, p$ | $np$ | $npq$ | Pass counts, defect counts in a batch, survey yes counts |
| Poisson | Count of independent rare events in a fixed window | 0, 1, 2, ... | $\lambda > 0$ | $\lambda$ | $\lambda$ | Arrivals per hour, typos per page, library returns per day |
| Geometric | Trials until (and including) the first success | 1, 2, 3, ... | $p$ | $1/p$ | $q/p^2$ | Attempts until a pass, calls until a sale |
| Negative binomial | Failures before the $r$-th success; or an overdispersed count | 0, 1, 2, ... | $r, p$ (or mean $\mu$, size $k$) | $rq/p$ (or $\mu$) | $rq/p^2$ (or $\mu + \mu^2/k$) | Counts with variance above the mean (see academic/stats-count-regression) |
| Hypergeometric | Successes in $n$ draws without replacement from $N$ items with $K$ successes | max(0, n+K−N) to min(n, K) | $N, K, n$ | $nK/N$ | $n \frac{K}{N}\frac{N-K}{N}\frac{N-n}{N-1}$ | Audit samples, Fisher's exact test, quality inspection of a small lot |

**Probability mass functions**

$$
\text{Bernoulli: } P(X = x) = p^x (1-p)^{1-x}, \quad x \in \{0, 1\}
$$

$$
\text{Binomial: } P(X = x) = \binom{n}{x} p^x (1-p)^{n-x}
$$

$$
\text{Poisson: } P(X = x) = \frac{e^{-\lambda} \lambda^x}{x!}
$$

$$
\text{Geometric (trials): } P(X = x) = (1-p)^{x-1} p, \quad x = 1, 2, \dots
$$

$$
\text{Negative binomial (failures): } P(X = x) = \binom{x + r - 1}{x} p^r (1-p)^x, \quad x = 0, 1, \dots
$$

$$
\text{Hypergeometric: } P(X = x) = \frac{\binom{K}{x}\binom{N-K}{n-x}}{\binom{N}{n}}
$$

**Picture: the Poisson as a limit of the binomial.** The chart compares Binomial(30, 0.1) with Poisson(3), which
has the same mean of 3. With many trials and a small success probability, the two are nearly the same, which is
why rare-event counts are modelled as Poisson. The probabilities were computed with `dpois(0:10, 3)` and
`dbinom(0:10, 30, 0.1)` in R (identical to scipy to four decimals).

```vega-lite
{
  "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
  "description": "Binomial(30, 0.1) and Poisson(3) probabilities for x = 0 to 10",
  "width": 400,
  "height": 220,
  "data": {"values": [
    {"x": 0, "distribution": "Poisson(3)", "probability": 0.0498}, {"x": 0, "distribution": "Binomial(30, 0.1)", "probability": 0.0424},
    {"x": 1, "distribution": "Poisson(3)", "probability": 0.1494}, {"x": 1, "distribution": "Binomial(30, 0.1)", "probability": 0.1413},
    {"x": 2, "distribution": "Poisson(3)", "probability": 0.224}, {"x": 2, "distribution": "Binomial(30, 0.1)", "probability": 0.2277},
    {"x": 3, "distribution": "Poisson(3)", "probability": 0.224}, {"x": 3, "distribution": "Binomial(30, 0.1)", "probability": 0.2361},
    {"x": 4, "distribution": "Poisson(3)", "probability": 0.168}, {"x": 4, "distribution": "Binomial(30, 0.1)", "probability": 0.1771},
    {"x": 5, "distribution": "Poisson(3)", "probability": 0.1008}, {"x": 5, "distribution": "Binomial(30, 0.1)", "probability": 0.1023},
    {"x": 6, "distribution": "Poisson(3)", "probability": 0.0504}, {"x": 6, "distribution": "Binomial(30, 0.1)", "probability": 0.0474},
    {"x": 7, "distribution": "Poisson(3)", "probability": 0.0216}, {"x": 7, "distribution": "Binomial(30, 0.1)", "probability": 0.018},
    {"x": 8, "distribution": "Poisson(3)", "probability": 0.0081}, {"x": 8, "distribution": "Binomial(30, 0.1)", "probability": 0.0058},
    {"x": 9, "distribution": "Poisson(3)", "probability": 0.0027}, {"x": 9, "distribution": "Binomial(30, 0.1)", "probability": 0.0016},
    {"x": 10, "distribution": "Poisson(3)", "probability": 0.0008}, {"x": 10, "distribution": "Binomial(30, 0.1)", "probability": 0.0004}
  ]},
  "mark": "bar",
  "encoding": {
    "x": {"field": "x", "type": "ordinal", "title": "Count x", "axis": {"labelAngle": 0}},
    "xOffset": {"field": "distribution"},
    "y": {"field": "probability", "type": "quantitative", "title": "P(X = x)"},
    "color": {"field": "distribution", "type": "nominal", "title": "Distribution"},
    "tooltip": [{"field": "distribution"}, {"field": "x"}, {"field": "probability"}]
  }
}
```

## Continuous distributions

<!-- Guidance: For continuous distributions, the pdf value is a density, not a probability. Always turn a question into an area: below a value (p function), above a value (1 minus p, or the upper-tail option), or between two values. -->

Notation: $\mu$ and $\sigma$ are a mean and standard deviation, $\lambda$ a rate, $\alpha$ a shape, $\beta$ a
rate (for the gamma) or a second shape (for the beta), $\nu$ or $k$ degrees of freedom df, and $\Gamma(\cdot)$ the
gamma function, with $\Gamma(m) = (m-1)!$ for whole numbers.

| Distribution | Story | Support | Parameters | Mean | Variance | Typical uses |
|---|---|---|---|---|---|---|
| Uniform | Every value in an interval equally likely | $[a, b]$ | $a < b$ | $(a+b)/2$ | $(b-a)^2/12$ | Rounding error, random start times, simulation input |
| Normal | Sum of many small independent effects | all real numbers | $\mu, \sigma > 0$ | $\mu$ | $\sigma^2$ | Measurement error, heights, sample means (via the CLT) |
| Exponential | Waiting time to the next event at a constant rate (memoryless) | $x \ge 0$ | rate $\lambda$ | $1/\lambda$ | $1/\lambda^2$ | Time between arrivals, service times |
| Gamma | Waiting time to the $\alpha$-th event; flexible positive skew | $x > 0$ | shape $\alpha$, rate $\beta$ | $\alpha/\beta$ | $\alpha/\beta^2$ | Rainfall, insurance claims, total service time |
| Beta | A probability or proportion that is itself uncertain | $[0, 1]$ | shapes $\alpha, \beta$ | $\frac{\alpha}{\alpha+\beta}$ | $\frac{\alpha\beta}{(\alpha+\beta)^2(\alpha+\beta+1)}$ | Proportions, Bayesian prior for $p$ |
| Lognormal | Product of many small positive effects; log is normal | $x > 0$ | $\mu, \sigma$ of the log | $e^{\mu + \sigma^2/2}$ | $(e^{\sigma^2}-1)e^{2\mu+\sigma^2}$ | Incomes, reaction times, concentrations |
| Weibull | Lifetime with a failure rate that rises, falls or stays flat | $x \ge 0$ | shape $k$, scale $\lambda$ | $\lambda\,\Gamma(1+1/k)$ | $\lambda^2[\Gamma(1+2/k) - \Gamma(1+1/k)^2]$ | Reliability, equipment lifetimes, wind speed |
| t | Standardised mean when $\sigma$ is estimated | all real numbers | df $\nu$ | 0 (for $\nu > 1$) | $\nu/(\nu-2)$ (for $\nu > 2$) | t-tests, CIs for means, regression coefficients |
| Chi-square | Sum of $k$ squared standard normals | $x \ge 0$ | df $k$ | $k$ | $2k$ | Variance tests, goodness of fit, contingency tables |
| F | Ratio of two independent chi-squares, each divided by its df | $x \ge 0$ | df $d_1, d_2$ | $\frac{d_2}{d_2-2}$ (for $d_2 > 2$) | $\frac{2d_2^2(d_1+d_2-2)}{d_1(d_2-2)^2(d_2-4)}$ (for $d_2 > 4$) | ANOVA, comparing variances, regression F-test |

**Probability density functions**

$$
\text{Uniform: } f(x) = \frac{1}{b-a}, \quad a \le x \le b
$$

$$
\text{Normal: } f(x) = \frac{1}{\sigma\sqrt{2\pi}} \exp\!\left(-\frac{(x-\mu)^2}{2\sigma^2}\right)
$$

$$
\text{Exponential: } f(x) = \lambda e^{-\lambda x}, \qquad P(X > x) = e^{-\lambda x}
$$

$$
\text{Gamma: } f(x) = \frac{\beta^{\alpha}}{\Gamma(\alpha)} x^{\alpha - 1} e^{-\beta x}
$$

$$
\text{Beta: } f(x) = \frac{x^{\alpha-1}(1-x)^{\beta-1}}{B(\alpha, \beta)}, \qquad B(\alpha, \beta) = \frac{\Gamma(\alpha)\Gamma(\beta)}{\Gamma(\alpha+\beta)}
$$

$$
\text{Lognormal: } f(x) = \frac{1}{x\sigma\sqrt{2\pi}} \exp\!\left(-\frac{(\ln x - \mu)^2}{2\sigma^2}\right)
$$

$$
\text{Weibull: } f(x) = \frac{k}{\lambda}\left(\frac{x}{\lambda}\right)^{k-1} e^{-(x/\lambda)^k}
$$

$$
\text{t: } f(t) = \frac{\Gamma\!\left(\frac{\nu+1}{2}\right)}{\sqrt{\nu\pi}\,\Gamma\!\left(\frac{\nu}{2}\right)} \left(1 + \frac{t^2}{\nu}\right)^{-\frac{\nu+1}{2}}
$$

$$
\text{Chi-square: } f(x) = \frac{x^{k/2 - 1} e^{-x/2}}{2^{k/2}\,\Gamma(k/2)}
$$

$$
\text{F: } f(x) = \frac{1}{B\!\left(\frac{d_1}{2}, \frac{d_2}{2}\right)} \left(\frac{d_1}{d_2}\right)^{d_1/2} x^{d_1/2 - 1} \left(1 + \frac{d_1}{d_2}x\right)^{-\frac{d_1+d_2}{2}}
$$

You rarely compute these densities by hand. What matters is recognising the shape (symmetric or skewed, bounded
or not), knowing the mean and variance, and asking software for areas.

## Relationships between distributions

<!-- Guidance: Pick any arrow and explain it in one sentence of your own; this is elaboration, one of the strongest study techniques. Arrows marked "limit" are approximations that improve as a parameter grows. -->

The distributions are one family, not a list. Knowing the links lets you rebuild a forgotten formula and explains
why tests use the t, chi-square and F distributions at all.

```mermaid
flowchart TD
  BE["Bernoulli(p)"] -->|"sum of n"| BI["Binomial(n, p)"]
  HY["Hypergeometric"] -->|"population large"| BI
  BI -->|"n large, p small, np = lambda"| PO["Poisson(lambda)"]
  BI -->|"n large (limit)"| NO["Normal"]
  PO -->|"lambda large (limit)"| NO
  BE -->|"trials until first success"| GE["Geometric(p)"]
  GE -->|"sum of r"| NB["Negative binomial"]
  PO -->|"gaps between events"| EX["Exponential(rate)"]
  EX -->|"sum of alpha"| GA["Gamma(alpha, rate)"]
  GA -->|"shape k/2, rate 1/2"| CH["Chi-square(k)"]
  NO -->|"square of a standard normal"| CH
  NO -->|"Z over root of chi-square/df"| TT["t(df)"]
  CH -->|"ratio of two, each over df"| FF["F(d1, d2)"]
  TT -->|"t squared"| FF
  TT -->|"df large (limit)"| NO
  NO -->|"exponentiate"| LN["Lognormal"]
  WE["Weibull"] -->|"shape 1"| EX
  BT["Beta(1, 1)"] -->|"equals"| UN["Uniform(0, 1)"]
```

The most useful links in practice:

- **Binomial to Poisson**: when $n$ is large and $p$ small, $\text{Binomial}(n, p) \approx \text{Poisson}(np)$ (see
  the chart above).
- **Binomial and Poisson to normal**: a common rule of thumb (not a theorem) is that with $np \ge 10$ and
  $n(1-p) \ge 10$, or $\lambda \ge 10$ or so, a normal curve with the same mean and variance is a reasonable
  approximation (some textbooks use 5 instead of 10; the closer $p$ is to 0 or 1, the larger $n$ must be); this is the basis of the z-test for
  proportions (see academic/stats-proportion-tests).
- **Normal to t, chi-square and F**: the t distribution appears when $\sigma$ is replaced by the sample SD, the
  chi-square when squared standardised values are summed, and the F as a ratio of two variance estimates. This is
  why t-tests, chi-square tests and ANOVA use them (see academic/stats-sampling-distributions).
- **Exponential and Poisson**: if events arrive as a Poisson process with rate $\lambda$, the waiting time between
  events is exponential with the same rate. Counts and waits are two views of one process.

## R and Python functions

<!-- Guidance: Before running any lookup, read the "Parameterisation trap" column for that row. Most wrong answers in assignments come from that column, not from the statistics. -->

R uses a prefix system: `d` density or mass, `p` cumulative probability $P(X \le x)$, `q` quantile, `r` random
draws. scipy.stats uses methods on a distribution object: `.pmf` or `.pdf`, `.cdf`, `.ppf` (quantile), `.sf`
(survival function $P(X > x) = 1 -$ cdf), `.isf` (inverse survival) and `.rvs` (draws; prefer
`numpy.random.default_rng(seed)` for reproducible simulation).

| Distribution | R (d, p, q, r stem) | scipy.stats | Parameterisation trap |
|---|---|---|---|
| Bernoulli | `dbinom(x, 1, p)` | `bernoulli(p)` | None |
| Binomial | `dbinom(x, size, prob)` | `binom(n, p)` | None |
| Poisson | `dpois(x, lambda)` | `poisson(mu)` | scipy calls the mean `mu` |
| Geometric | `dgeom(x, prob)` | `geom(p)` | R counts **failures** before the first success (starts at 0); scipy counts **trials** (starts at 1). `dgeom(2, p)` equals `geom.pmf(3, p)`. |
| Negative binomial | `dnbinom(x, size, prob)` or `dnbinom(x, size, mu = m)` | `nbinom(n, p)` | Both count failures. R allows the mean form `size, mu`; scipy needs `n = size` and `p = size / (size + mu)`. |
| Hypergeometric | `dhyper(x, m, n, k)`: m successes, n failures, k draws | `hypergeom(M, n, N)`: M total, n successes, N draws | The letters mean different things. R's `n` is the number of failures; scipy's `n` is the number of successes. |
| Uniform | `dunif(x, min, max)` | `uniform(loc, scale)` | scipy: `loc = a`, `scale = b - a` (not `b`) |
| Normal | `dnorm(x, mean, sd)` | `norm(loc, scale)` | Both use the SD, not the variance |
| Exponential | `dexp(x, rate)` | `expon(scale)` | scipy `scale = 1 / rate` |
| Gamma | `dgamma(x, shape, rate)` (or `scale =`) | `gamma(a, scale)` | scipy `scale = 1 / rate`; R's third positional argument is the rate |
| Beta | `dbeta(x, shape1, shape2)` | `beta(a, b)` | None |
| Lognormal | `dlnorm(x, meanlog, sdlog)` | `lognorm(s, scale)` | scipy `s = sdlog`, `scale = exp(meanlog)` |
| Weibull | `dweibull(x, shape, scale)` | `weibull_min(c, scale)` | scipy calls the shape `c` |
| t | `dt(x, df)` | `t(df)` | None |
| Chi-square | `dchisq(x, df)` | `chi2(df)` | None |
| F | `df(x, df1, df2)` | `f(dfn, dfd)` | In R, `df` is also a common variable name; `df()` is the F density |

Upper tails: in R add `lower.tail = FALSE` to a `p` or `q` function; in scipy use `.sf` or `.isf`. For a
discrete variable, "at least 6" is "more than 5", so the upper-tail call uses 5, not 6.

## Worked example A (fully solved): late returns at Harbour City Library

<!-- Guidance: Follow every step, then cover the solution and redo the lookup in both languages from memory. Note the off-by-one step: it is the most common error with discrete upper tails. -->

**Question.** Harbour City Library (fictional) receives late book returns at an average of 3 per hour, and
returns arrive independently. What is the probability of 6 or more late returns in a given hour?

**Step 1: choose the distribution.** Counts of independent events in a fixed window with a known average rate:
Poisson with $\lambda = 3$. Check: the support (0, 1, 2, ...) matches a count, and there is no fixed upper limit.

**Step 2: write the event.** $P(X \ge 6) = 1 - P(X \le 5)$.

**Step 3: by hand (optional check).**

$$
P(X \le 5) = e^{-3}\left(1 + 3 + \frac{9}{2} + \frac{27}{6} + \frac{81}{24} + \frac{243}{120}\right) = 0.04979 \times 18.4 \approx 0.9161
$$

so $P(X \ge 6) \approx 0.0839$.

**Step 4: software.** R `ppois(5, 3, lower.tail = FALSE)` and scipy `poisson.sf(5, 3)` both give 0.0839 (see the
verification output below). Both use 5, because $X \ge 6$ is the same event as $X > 5$.

**Step 5: interpret.** About 8% of hours, or roughly one hour in twelve, will see 6 or more late returns. If the
library adds a second person to the returns desk only to cope with hours of 6 or more late returns, it should
expect to need that help in about one hour in twelve, assuming the rate really is constant across the day (it often is not: check the
assumption against hourly data).

## Worked example B (half solved): underbaked loaves at Brightwell Bakery

<!-- Guidance: Complete each [ ] before checking the Answer key. Reuse the five steps from Example A. -->

**Question.** At Brightwell Bakery (fictional), each loaf is underbaked with probability 0.05, independently. A
quality check takes 10 loaves. Find (a) the probability that exactly 1 is underbaked and (b) the probability that
2 or more are underbaked.

**Step 1: choose the distribution.** A fixed number of independent trials with the same success probability:
[ ] with $n = [\ ]$ and $p = [\ ]$.

**Step 2: write the events.** (a) $P(X = 1)$. (b) $P(X \ge 2) = 1 - P(X \le [\ ])$.

**Step 3: by hand for (a).**

$$
P(X = 1) = \binom{10}{1}(0.05)^1(0.95)^{9} = 10 \times 0.05 \times [\ \ ] \approx [\ \ ]
$$

**Step 4: software.** R: `dbinom(1, 10, 0.05)` gives 0.3151 and `pbinom(1, 10, 0.05)` gives 0.9139. So
(b) is [ ]. The scipy equivalents are `binom.pmf([ ], 10, 0.05)` and `binom.sf([ ], 10, 0.05)`.

**Step 5: interpret.** If the bakery's process is in control, a batch of 10 with 2 or more underbaked loaves will
occur in about [ ] of checks, so seeing it [ ].

## Exercise C (unsolved): exam scores and waiting times

<!-- Guidance: Solve without looking at the examples. For each part, write the distribution, the event, the R call and the scipy call before computing. -->

1. Scores on a Lakemoor University (fictional) statistics exam are approximately normal with mean 65 and SD 10.
   What proportion of students score above 80? What score marks the 90th percentile?
2. Waiting time in the Brightwell Bakery queue is exponential with a mean of 4 minutes. What is the probability
   a customer waits more than 6 minutes? Write the scipy call carefully.
3. A cart at Harbour City Library holds 20 returned books, 5 of them damaged. A volunteer picks 4 at random
   without replacement. What is the probability that exactly 1 is damaged? Write both the R and scipy calls.

## Lookup verification code

<!-- Guidance: Run both scripts. Every number quoted on this sheet comes from this output. If a value differs on your machine, compare the parameterisation first. -->

**R (base R only)**

```r
# Worked lookups (fictional settings)
# 1 Binomial: 10 loaves, P(defect) = 0.05; P(X = 1), P(X <= 1)
cat(sprintf("dbinom(1, 10, 0.05) = %.4f\n", dbinom(1, 10, 0.05)))
cat(sprintf("pbinom(1, 10, 0.05) = %.4f\n", pbinom(1, 10, 0.05)))
# 2 Poisson: library late returns, mean 3 per hour; P(X >= 6)
cat(sprintf("1 - ppois(5, 3) = %.4f\n", 1 - ppois(5, 3)))
cat(sprintf("ppois(5, 3, lower.tail = FALSE) = %.4f\n", ppois(5, 3, lower.tail = FALSE)))
# 3 Normal: exam scores N(65, 10^2); P(X > 80) and 90th percentile
cat(sprintf("pnorm(80, 65, 10, lower.tail = FALSE) = %.4f\n", pnorm(80, 65, 10, lower.tail = FALSE)))
cat(sprintf("qnorm(0.90, 65, 10) = %.4f\n", qnorm(0.90, 65, 10)))
cat(sprintf("qnorm(0.975) = %.4f\n", qnorm(0.975)))
# 4 Exponential: waiting time, rate 0.25 per minute (mean 4); P(T > 6)
cat(sprintf("pexp(6, rate = 0.25, lower.tail = FALSE) = %.4f\n", pexp(6, rate = 0.25, lower.tail = FALSE)))
# 5 t, chi-square, F critical values
cat(sprintf("qt(0.975, df = 9) = %.4f\n", qt(0.975, df = 9)))
cat(sprintf("qchisq(0.95, df = 3) = %.4f\n", qchisq(0.95, df = 3)))
cat(sprintf("qf(0.95, df1 = 2, df2 = 27) = %.4f\n", qf(0.95, 2, 27)))
# 6 Geometric: P(first success on trial 3), p = 0.2 (R counts failures)
cat(sprintf("dgeom(2, 0.2) = %.4f\n", dgeom(2, 0.2)))
# 7 Negative binomial: mean 4, size 2 (overdispersed counts); P(X = 0)
cat(sprintf("dnbinom(0, size = 2, mu = 4) = %.4f\n", dnbinom(0, size = 2, mu = 4)))
# 8 Hypergeometric: 20 books, 5 damaged, draw 4; P(exactly 1 damaged)
cat(sprintf("dhyper(1, m = 5, n = 15, k = 4) = %.4f\n", dhyper(1, 5, 15, 4)))
# 9 Gamma shape 2 rate 0.5; Beta(2, 5); Lognormal meanlog 1 sdlog 0.5
cat(sprintf("pgamma(6, shape = 2, rate = 0.5) = %.4f\n", pgamma(6, shape = 2, rate = 0.5)))
cat(sprintf("pbeta(0.3, 2, 5) = %.4f\n", pbeta(0.3, 2, 5)))
cat(sprintf("plnorm(4, meanlog = 1, sdlog = 0.5) = %.4f\n", plnorm(4, 1, 0.5)))
cat(sprintf("punif(0.3, 0, 2) = %.4f\n", punif(0.3, 0, 2)))
cat(sprintf("pweibull(3, shape = 1.5, scale = 4) = %.4f\n", pweibull(3, 1.5, 4)))
set.seed(2026); x <- rpois(5, 3); cat("rpois(5, 3) with seed 2026:", x, "\n")
```

```text
dbinom(1, 10, 0.05) = 0.3151
pbinom(1, 10, 0.05) = 0.9139
1 - ppois(5, 3) = 0.0839
ppois(5, 3, lower.tail = FALSE) = 0.0839
pnorm(80, 65, 10, lower.tail = FALSE) = 0.0668
qnorm(0.90, 65, 10) = 77.8155
qnorm(0.975) = 1.9600
pexp(6, rate = 0.25, lower.tail = FALSE) = 0.2231
qt(0.975, df = 9) = 2.2622
qchisq(0.95, df = 3) = 7.8147
qf(0.95, df1 = 2, df2 = 27) = 3.3541
dgeom(2, 0.2) = 0.1280
dnbinom(0, size = 2, mu = 4) = 0.1111
dhyper(1, m = 5, n = 15, k = 4) = 0.4696
pgamma(6, shape = 2, rate = 0.5) = 0.8009
pbeta(0.3, 2, 5) = 0.5798
plnorm(4, meanlog = 1, sdlog = 0.5) = 0.7801
punif(0.3, 0, 2) = 0.1500
pweibull(3, shape = 1.5, scale = 4) = 0.4777
rpois(5, 3) with seed 2026: 4 3 1 2 3
```

**Python (scipy.stats)**

```python
from scipy import stats
import numpy as np
print(f"binom.pmf(1, 10, 0.05) = {stats.binom.pmf(1, 10, 0.05):.4f}")
print(f"binom.cdf(1, 10, 0.05) = {stats.binom.cdf(1, 10, 0.05):.4f}")
print(f"poisson.sf(5, 3) = {stats.poisson.sf(5, 3):.4f}")
print(f"norm.sf(80, 65, 10) = {stats.norm.sf(80, loc=65, scale=10):.4f}")
print(f"norm.ppf(0.90, 65, 10) = {stats.norm.ppf(0.90, loc=65, scale=10):.4f}")
print(f"norm.ppf(0.975) = {stats.norm.ppf(0.975):.4f}")
print(f"expon.sf(6, scale=4) = {stats.expon.sf(6, scale=1/0.25):.4f}")
print(f"t.ppf(0.975, 9) = {stats.t.ppf(0.975, 9):.4f}")
print(f"chi2.ppf(0.95, 3) = {stats.chi2.ppf(0.95, 3):.4f}")
print(f"f.ppf(0.95, 2, 27) = {stats.f.ppf(0.95, 2, 27):.4f}")
print(f"geom.pmf(3, 0.2) = {stats.geom.pmf(3, 0.2):.4f}")
size, mu = 2, 4
p = size / (size + mu)
print(f"nbinom.pmf(0, n=2, p={p:.4f}) = {stats.nbinom.pmf(0, size, p):.4f}")
print(f"hypergeom.pmf(1, M=20, n=5, N=4) = {stats.hypergeom.pmf(1, 20, 5, 4):.4f}")
print(f"gamma.cdf(6, a=2, scale=2) = {stats.gamma.cdf(6, a=2, scale=1/0.5):.4f}")
print(f"beta.cdf(0.3, 2, 5) = {stats.beta.cdf(0.3, 2, 5):.4f}")
print(f"lognorm.cdf(4, s=0.5, scale=e^1) = {stats.lognorm.cdf(4, s=0.5, scale=np.exp(1)):.4f}")
print(f"uniform.cdf(0.3, loc=0, scale=2) = {stats.uniform.cdf(0.3, loc=0, scale=2):.4f}")
print(f"weibull_min.cdf(3, c=1.5, scale=4) = {stats.weibull_min.cdf(3, 1.5, scale=4):.4f}")
rng = np.random.default_rng(2026); print("rng.poisson(3, 5) with seed 2026:", rng.poisson(3, 5))
```

```text
binom.pmf(1, 10, 0.05) = 0.3151
binom.cdf(1, 10, 0.05) = 0.9139
poisson.sf(5, 3) = 0.0839
norm.sf(80, 65, 10) = 0.0668
norm.ppf(0.90, 65, 10) = 77.8155
norm.ppf(0.975) = 1.9600
expon.sf(6, scale=4) = 0.2231
t.ppf(0.975, 9) = 2.2622
chi2.ppf(0.95, 3) = 7.8147
f.ppf(0.95, 2, 27) = 3.3541
geom.pmf(3, 0.2) = 0.1280
nbinom.pmf(0, n=2, p=0.3333) = 0.1111
hypergeom.pmf(1, M=20, n=5, N=4) = 0.4696
gamma.cdf(6, a=2, scale=2) = 0.8009
beta.cdf(0.3, 2, 5) = 0.5798
lognorm.cdf(4, s=0.5, scale=e^1) = 0.7801
uniform.cdf(0.3, loc=0, scale=2) = 0.1500
weibull_min.cdf(3, c=1.5, scale=4) = 0.4777
rng.poisson(3, 5) with seed 2026: [3 3 6 3 3]
```

**What the output teaches.**

- Every exact lookup agrees to four decimals between R and Python once the parameterisation is translated:
  `pexp(6, rate = 0.25)` matches `expon.sf(6, scale=4)`, `dgeom(2, 0.2)` matches `geom.pmf(3, 0.2)`, and
  `dnbinom(0, size = 2, mu = 4)` matches `nbinom.pmf(0, 2, 1/3)`.
- The random draws differ (4 3 1 2 3 in R, 3 3 6 3 3 in Python) even with the same seed, because R and numpy use
  different generators. Seeds make each language reproducible, not the two languages identical.
- The critical values you will meet in tests are here too: 1.96 for a two-sided 95% z interval, 2.2622 for a t
  interval with df = 9, 7.8147 for a chi-square test with df = 3, and 3.3541 for an F-test with df = 2 and 27.

## Common mistakes and misconceptions

<!-- Guidance: Cover the right-hand column and explain why each left-hand statement is wrong. Copy any you have made into academic/stats-error-log. -->

| Wrong statement | Correct statement |
|---|---|
| "The normal pdf at 80 is 0.0130, so the probability of scoring exactly 80 is 0.0130." | A density is not a probability. For a continuous variable, $P(X = 80) = 0$; ask for an area such as $P(79.5 < X < 80.5)$. |
| "P(X ≥ 6) for a Poisson is `1 - ppois(6, 3)`." | That gives $P(X > 6) = P(X \ge 7)$. For discrete variables use `1 - ppois(5, 3)` or `ppois(5, 3, lower.tail = FALSE)`. |
| "`expon(6)` in scipy is the exponential with rate 6." | After any shape parameters, the next positional argument of a scipy distribution is `loc`; `expon` has no shape parameter, so `expon(6)` shifts the start to 6 (its mean becomes 7). Use `expon(scale=1/6)` for rate 6. |
| "R's `dgeom` and scipy's `geom.pmf` give the same answer for the same x." | R counts failures (from 0), scipy counts trials (from 1). Shift x by one. |
| "The normal is the default for any data." | Choose by the data-generating story and the support. Counts, proportions, waiting times and incomes usually need another distribution or a transformation. |
| "Poisson data must have variance equal to the mean." | That is the model's assumption, not a guarantee. Real counts are often overdispersed; then a negative binomial fits better. |
| "The t distribution is for small samples, the normal for large ones." | The t arises whenever $\sigma$ is estimated from the data, whatever the sample size. It approaches the normal as df grows, so the choice matters less for large n. |
| "`rnorm(10, 5, 4)` draws from a normal with variance 4." | R's third argument is the SD, so the variance is 16. The same holds for scipy's `scale`. |

## Self-test: which distribution?

<!-- Guidance: This is interleaved practice: the scenarios are deliberately mixed. For each, name the distribution and its parameters before checking. Repeat the set after a few days without looking at your previous answers. -->

1. Each of 25 students passes a quiz independently with probability 0.8. X = number who pass. Name the
   distribution, and give its mean and variance.
2. X = number of help-desk emails the library receives in one hour, averaging 2 per hour. Name the distribution
   and give the R and scipy calls for $P(X \ge 4)$, with the value.
3. X = time in minutes until the next customer walks into the bakery, arrivals at a constant average rate.
4. A cart holds 30 books, 8 of them overdue. Six books are picked without replacement. X = number overdue.
5. A student retakes a driving test until passing, with a 0.6 chance of passing each attempt. X = number of
   attempts. Which R function would you use, and what value of x do you pass for "passes on the 2nd attempt"?
6. A test statistic is the ratio of two independent variance estimates from normal samples. Which distribution
   does it follow under the null hypothesis?

## My notes and next steps

<!-- Guidance: Rate each family honestly; anything at 1 or 2 deserves another pass through its row and one lookup in both languages. -->

| Topic | Confidence 1-5 | What still confuses me | Next action and date |
|---|---|---|---|
| *Example:* Discrete upper tails | 2 | Which number to pass for "at least" | Redo Example A in both languages, YYYY-MM-DD |
| Choosing a distribution from a story | [ ] | [ ] | [ ] |
| Continuous distributions and areas | [ ] | [ ] | [ ] |
| t, chi-square, F and their df | [ ] | [ ] | [ ] |
| R vs scipy parameterisation | [ ] | [ ] | [ ] |

Distributions my course uses that are not on this sheet: [List them and add rows above].

Mistakes to copy into my error log (academic/stats-error-log): [Mistake, why it happened, the fix].

## Sources and further reading

<!-- Guidance: Formulas for named distributions are standard mathematical facts; the wording, examples and tables on this sheet are original. Textbooks below are further reading by name only. -->

Based on standard distribution theory and the NIST/SEMATECH e-Handbook, with function names and
parameterisations checked against the R and SciPy documentation and by running the code above.

- NIST/SEMATECH e-Handbook of Statistical Methods, section 1.3.6 Probability Distributions,
  https://www.itl.nist.gov/div898/handbook/ (accessed 2026-10-25). Public domain.
- R Core Team (2025). *R: A Language and Environment for Statistical Computing*, version 4.5.1, package `stats` (help
  pages for `Distributions`, `NegBinomial`, `Geometric`, `Hypergeometric`).
- Virtanen, P., et al. (2020). SciPy 1.0: fundamental algorithms for scientific computing in Python. *Nature Methods*,
  17(3), 261–272. (Documentation for `scipy.stats` consulted for version 1.18.1.)
- Student (1908). The probable error of a mean. *Biometrika*, 6(1), 1–25. (Origin of the t distribution; Student was
  W. S. Gosset.)
- Weibull, W. (1951). A statistical distribution function of wide applicability. *Journal of Applied Mechanics*,
  18(3), 293–297.
- Dunlosky, J., Rawson, K. A., Marsh, E. J., Nathan, M. J., and Willingham, D. T. (2013). Improving students' learning
  with effective learning techniques. *Psychological Science in the Public Interest*, 14(1), 4–58. (Interleaved
  practice in the self-test.)
- Further reading (by name only): de Smith, M. J. (2024). *Statistical Analysis Handbook* (2024 edition, StatsRef);
  Diez, D. M., Çetinkaya-Rundel, M., and Barr, C. D., *OpenIntro Statistics* (CC BY-SA).

## Answer key

<!-- Guidance: Check only after a full attempt. For each error, note whether it was the model choice, the event (off-by-one), or the parameterisation. -->

**Example B (gaps).** Binomial with $n = 10$, $p = 0.05$. (b) $P(X \ge 2) = 1 - P(X \le 1)$. By hand:
$(0.95)^9 \approx 0.6302$, so $P(X = 1) = 10 \times 0.05 \times 0.6302 \approx 0.3151$. (b) is
$1 - 0.9139 = 0.0861$. scipy: `binom.pmf(1, 10, 0.05)` and `binom.sf(1, 10, 0.05)`. About 9% of checks would show
2 or more underbaked loaves even when the process is in control, so one such batch is not strong evidence of a
problem; a run of them would be.

**Exercise C.**

1. Normal(65, 10): $P(X > 80) = 0.0668$ (`pnorm(80, 65, 10, lower.tail = FALSE)`, `norm.sf(80, 65, 10)`), so
   about 6.7% of students. 90th percentile: 77.8 (`qnorm(0.90, 65, 10)` gives 77.8155).
2. Exponential with mean 4, so rate 0.25: $P(T > 6) = e^{-0.25 \times 6} = e^{-1.5} \approx 0.2231$. scipy:
   `expon.sf(6, scale=4)`. Writing `expon.sf(6, 0.25)` would set `loc = 0.25`, a different distribution.
3. Hypergeometric: $\binom{5}{1}\binom{15}{3}/\binom{20}{4} = 5 \times 455 / 4845 \approx 0.4696$. R
   `dhyper(1, 5, 15, 4)`; scipy `hypergeom.pmf(1, 20, 5, 4)`.

**Self-test.**

1. Binomial(25, 0.8): mean $25 \times 0.8 = 20$, variance $25 \times 0.8 \times 0.2 = 4$.
2. Poisson(2). R `ppois(3, 2, lower.tail = FALSE)`, scipy `poisson.sf(3, 2)`; both give 0.1429 (checked by
   running both).
3. Exponential (a constant rate of arrivals means memoryless waiting times).
4. Hypergeometric with $N = 30$, $K = 8$, $n = 6$ (without replacement from a small population).
5. Geometric with $p = 0.6$. R counts failures, so "passes on the 2nd attempt" is one failure: `dgeom(1, 0.6)`
   $= 0.4 \times 0.6 = 0.24$. In scipy it would be `geom.pmf(2, 0.6)`.
6. F distribution with df equal to the two variance estimates' df.

## Revision history

<!-- Guidance: Add a row when you add a distribution, fix a parameterisation note, or update software versions. -->

| Version | Date | Author | Change |
|---|---|---|---|
| 0.1 | YYYY-MM-DD | [Your name] | First version from template |
| [0.2] | YYYY-MM-DD | [Your name] | [Added distributions used in my course] |
