stats_examples#
Series: lecture-python.myst
File:
lectures/stats_examples.mdAudit date: 2026-08-26
Corpus snapshot:
e25fdf2345Categories audited: writing, math, code, figures, links, admonitions (JAX out of scope)
Overall score: 6.9 / 10
Priority: HIGH
Score breakdown#
Category |
Score |
One-line note |
|---|---|---|
Writing |
3/10 |
|
Math |
4.5/10 |
|
Code |
7/10 |
|
JAX |
out of scope |
JAX rules target |
Figures |
7/10 |
|
References |
N/A |
no citations in this lecture. |
Links |
10/10 |
no mechanical violations detected. |
Admonitions |
10/10 |
no mechanical violations detected. |
Issues#
Critical#
None found.
High severity#
[qe-code-001] (reviewer) — Follow PEP8 unless closer to mathematical notation. Count: 6. Lines: 39, 77, 234, 302, 535, 540. Example: 77 creates the only generator in the lecture with
np.random.default_rng()and no seed, and every section then prints a sample moment next to a population moment for the reader to compare (89-93, 137-139, 228-229, 270-272, 309) - so all the printed numbers change on every build. 234-235 makes that worse by testing one-sidedly:print(μ-μ_hat < 1e-3)andprint(σ-σ_hat < 1e-3)pass automatically whenever the estimate exceeds the parameter, so the check labelled# comparecannot fail in half the cases;abs(...)is meant. 302 leaves a commented-out earlier version of the next line in the cell. 39 importsAxes3Dand never uses it - the file draws no 3-D figure, and modern matplotlib needs no such import forprojection='3d'. 535-541 are two orphan cells with no surrounding prose:rng.geometric(1-λ, n).max()andnp.log(0.4)/np.log(0.3), the second using two constants that appear nowhere else in the section, where \(\lambda = 0.8\) at 519. Smaller items: 303 rebuilds the boolean maskx > 0.95three times in one statement, 176 uses a list comprehension wherenp.log10(1 + 1/np.arange(1, 10))vectorises, 176 and 193 writerange(1,10)without the space after the comma, and 331-332 run operators together (0.95*17.5**2+0.0005/3*(...)).[qe-fig-005] — Descriptive figure names for cross-referencing. Count: 5. Lines: 191, 442, 459, 518, 543. Example: code-cell figure without mystnb figure metadata.
[qe-math-010 (proposed)] — Blackboard \mathbb{P}, \mathbb{E}, \mathbb{V} with braces. Count: 12. Lines: 61, 110, 153, 343, 346, 385, 393, 394, 395, 470, …. Example: non-blackboard
\textrm{Prob}.[qe-math-014 (proposed)] (reviewer) — Braces {…} for events, parentheses (…) for sets. Count: 7. Lines: 61, 110, 287, 291, 470, 471, 479. Example: the lecture writes events both ways in roughly equal measure. With braces, as the convention asks: \(\textrm{Prob}\{X=d\}\) (153), \(\textrm{Prob}\{\tilde{X}=i\}\) (343), \(\textrm{Prob}\{X=i\}\) (346), \(\textrm{Prob}\{X\le x\}\) (385) and \(\textrm{Prob}\left\{X\leq x\right\}\) three times in the derivation at 393-395. With parentheses, for events of exactly the same kind: \(\textrm{Prob}(X=k)\) (61), \(\textrm{Prob}(X=k;r,p)\) (110), \(\textrm{Prob}(X=i)\) (470, 471), \(\textrm{Prob}(X\le i)\) (479), and the bare \(P(X=0)\) and \(P(300\le X \le 400)\) at 287 and 291. The two styles appear within a single derivation: 385 uses braces for \(\textrm{Prob}\{X \le x\}\) and 479 uses parentheses for \(\textrm{Prob}(X \le i)\). Nothing in the file is a named set, so every one of these arguments is a logical condition and every one should be braced.
[qe-writing-003] (reviewer) — Maintain logical flow. Count: 6. Lines: 64, 121, 417, 428, 500, 528. Example: the displayed algebra and the code disagree repeatedly, and where they disagree the code is right. 121-122 gives the negative binomial moments as \(\mathbb{E}(X) = k(1-p)/p\) and \(\mathbb{V}(X) = k(1-p)/p^2\), using \(k\) - which is the realised number of failures, the argument of the mass function two lines above at 110 - where \(r\) is meant; the code at 138-139 correctly computes
r*(1-p)/pandr*(1-p)/p**2. 417 writes the exponential CDF as \(F(x)=\int_{0}^{\infty}\lambda e^{-\lambda x}=1-e^{-\lambda x}\): the upper limit must be \(x\) (with \(\infty\) the integral is 1, contradicting the stated answer) and the \(dx\) is missing. 428-431 derives the inverse transform with two errors - 429 reads \(-U = e^{-\lambda X}\), dropping the 1 from \(1-U\), and 431 concludes \(X = (1-U)/(-\lambda)\) with the logarithm dropped - while 430 in between and 435 after both have it right, as does the code at 449. 479 sums \(\lambda^i\) over \(j = 0, \ldots, i\) where the summand is \(\lambda^j\). 500 inverts its own relation: “However, \(\tilde{U}=F^{-1}(X)\) may not be an integer for any \(x\geq0\)” - it is \(X = F^{-1}(\tilde U)\), and it is \(X\), not \(\tilde U\), that need not be an integer. 64 says \(k\) is “the number of trials before the first success” where the mass function \((1-p)^{k-1}p\) on \(k = 1, 2, \ldots\) counts trials including the success. And 528 compares the wrong two samples:xfrom 525 has support \(\{0, 1, \ldots\}\), matching the parameterisation at 470, whilerng.geometric(1-λ, n)returns \(\{1, 2, \ldots\}\), so the two histograms the section exists to compare are offset by exactly one and the verification promised at 512 does not hold.[qe-writing-006] — Capitalize lecture titles properly. Count: 4. Lines: 45, 238, 275, 338. Example: H2 Title Case: ‘Some Discrete Probability Distributions’ (Discrete, Probability, Distributions).
[qe-writing-008] — Remove excessive whitespace between words. Count: 29. Lines: 48, 53, 58, 74, 114, 145, 275, 277, 280, 284, …. Example: 3 spaces.
Medium severity#
[qe-code-003] — Package installation at lecture top. Count: 1. Lines: 26. Example: non-Anaconda import with no install cell: [‘matplotlib_inline’].
[qe-fig-003] — No matplotlib embedded titles. Count: 1. Lines: 194. Example: plt.title.
[qe-math-009] (reviewer) — Choose simplicity in mathematical notation. Count: 4. Lines: 70, 110, 210, 435. Example: 70 writes the variance operator as
\mathbb{Var}(X), which typesets as three separate blackboard-bold letters \(\mathbb{V}\mathbb{a}\mathbb{r}\), while 122, 169 and 252 write\mathbb{V}for the same operator - one operator, two spellings, and the first is malformed. 110 uses a matrix environment for a binomial coefficient,\begin{bmatrix}k+r-1 \\ r-1 \end{bmatrix}, which renders as a two-row column vector in square brackets rather than as \(\binom{k+r-1}{r-1}\);\binomis the macro. 210 writes the normal density as \(f(x|u,\sigma^2)=\frac{1}{\sqrt{2\pi\sigma^2}}e^{[-\frac{1}{2\sigma^2}(x-u)^2]}\), using Latinufor the mean that 205 and 212 call \(\mu\), and wrapping the exponent in square brackets for no reason; it is also the only display in the file written on a single$$ ... $$line. 435 writeslograther than\loginside math, so it renders as the product \(l \cdot o \cdot g\), and 505 uses unsized\lceil ... \rceilaround a fraction that overflows them.[qe-writing-002] (reviewer) — Keep writing clear, concise, and valuable. Count: 4. Lines: 74, 282, 353, 379. Example: four sentences drop an auxiliary verb or a preposition: “Let’s use Python draw observations from the distribution” (74), “you know your salary will uniformly distributed in the interval 300~400 a day” (282), “It turns out that if we use draw uniform random numbers \(U\)” (379), and “Let \(X\) distributed geometrically” (466). 353-364 then states one idea three times: the three-bullet recipe at 353-357, the summary at 360 (“Thus, knowing the “inverse” CDF of a distribution is enough to simulate from this distribution”), and a
{note}at 362-364 repeating the caveat that the scare quotes around “inverse” have already flagged twice. 347 also carries a typo, “arbitary”.[qe-writing-005] (reviewer) — Use bold for definitions, italic for emphasis. Count: 3. Lines: 356, 404, 464. Example: 404 and 464 set whole-line headings in bold - Example: A continuous geometric (exponential) distribution and Geometric distribution - where the file’s other seven distributions each get a real
##heading (56, 97, 143, 200, 238, 275, 338), so these two sections are absent from the{contents}table and cannot be linked. 356 and 360 bold a scare-quoted word, “inverse”, and 438 bolds continuous geometric for emphasis. The file contains no italics at all, and its two genuine definitions are correctly bolded (Newcomb-Benford law 145, first digit 156), so the marker is doing headings, scare quotes and emphasis as well as definitions.[qe-writing-007] (reviewer) — Use visual elements to enhance understanding. Count: 3. Lines: 191, 275, 455. Example: the two places where the lecture says “# plot and compare” cannot compare anything: 454-461 and 530-545 each draw the transformed sample and the library sample as separate histograms in separate cells with separate
plt.show()calls, so they land as two figures with independently chosen axis limits - and thealpha=0.6on the second of each pair (460, 544) only makes sense for overlaid series, which is evidently what was intended. Twohistcalls in one cell would settle both verifications, and would also have exposed the off-by-one betweenxandx_gat 525-528. Second, the mixed discrete-continuous distribution (275-335) is the most interesting object in the lecture - a point mass of 0.95 at zero plus a uniform slab of total mass 0.05 on \([300,400]\) - and it has no figure at all, even thoughxis already simulated at 301-304 and a single histogram would show the atom and the slab together and make the variance of 332 (dominated by the \(0.95 \times 17.5^2\) term) intuitive. Third, the Benford figure at 191-195 plots nine probabilities as unconnected markers viaplt.plot(range(1,10), Benford_pmf, 'o')with a title and no axis labels; a bar chart is the natural form for a mass function, and the claim the section opens with - that in real data “the leading digit is more likely to be small than large” (145-146) - is never plotted against any data.
Low severity#
None found.
Strengths#
Every distribution follows the same three-step template stated up front at 50-54 - population moments from the distribution, a sample of \(N\) IID draws, then a comparison - and the code delivers all three for the geometric (76-94), Pascal (126-140), Gaussian (214-236), uniform (256-273) and mixed (300-335) cases, so a reader can read any one section without the others.
The case convention for densities and CDFs is right throughout: lowercase \(f\) for densities and mass functions (210, 243, 295, 411) and \(f_i\) for an arbitrary discrete distribution (346-347), against uppercase \(F\), \(F^{-1}\), \(F_X\) for cumulative distribution functions (351-395, 414-428, 475-505).
The Benford section verifies its own claim rather than quoting it: 161 states that the nine probabilities are nonnegative and sum to one, and 176-188 computes the sum, the mean and the variance and prints all three against the \(3.4402\) and \(6.0565\) asserted at 168-169.
The inverse-transform method is proved, not just used: 366-372 defines \(F^{-1}(u) = \inf\{x \in \mathbb{R} : F(x) \geq u\}\) and says why the infimum is needed (a CDF is non-decreasing and right-continuous), and 391-400 then shows \(F_X(x) = \textrm{Prob}\{F^{-1}(U) \le x\} = \textrm{Prob}\{U \le F(x)\} = F(x)\) with the reason for the last equality spelled out.
The method is then applied to both a continuous and a discrete target, and the discrete case is not glossed: 500-510 notices that the continuous inversion returns a non-integer, introduces the ceiling function, and says what the resulting \(x\) is - “the smallest integer such that the discrete geometric CDF is greater than or equal to \(\tilde{U}\)” - which is the right characterisation of the discrete inverse.
The mixed discrete-continuous example (275-335) is set up as a story with a reason to care, and both moments are derived by hand with the atom and the continuous part kept separate in the variance (324-326) before the same numbers are recomputed in code at 331-334.
514-516 places a
{note}saying that the exponential is the continuous analogue of the geometric exactly where the reader has just seen the two derivations side by side, which is the one place that observation pays off.Every simulation uses \(10^6\) draws (80, 128, 219, 261, 301, 443, 519), large enough that the printed sample moments agree with the population moments to the precision shown, which is what makes the template of 50-54 convincing rather than suggestive.
Recommended actions#
Fix the six places where the mathematics contradicts the code or itself: \(k\) for \(r\) in the negative binomial moments at 121-122; the \(\int_0^\infty\) and missing \(dx\) at 417; the dropped 1 at 429 and the dropped logarithm at 431; \(\lambda^i\) for \(\lambda^j\) at 479; the inverted relation at 500; and “before the first success” at 64, which describes \(k-1\) rather than \(k\).
Correct the comparison at 525-528:
np.ceil(np.log(1-u)/np.log(λ) - 1)has support \(\{0, 1, \ldots\}\) matching 470, whilerng.geometric(1-λ, n)has support \(\{1, 2, \ldots\}\), so the two samples differ by one and the claim at 512 that this verifies the transform does not hold as written.Seed the generator at 77 and make the Gaussian check two-sided -
print(μ-μ_hat < 1e-3)at 234 andprint(σ-σ_hat < 1e-3)at 235 pass automatically whenever the estimate overshoots, so they test nothing in half the cases.Put each pair of histograms in one cell on one set of axes (454-461, 530-545). Both cells say “# plot and compare” and both set
alpha=0.6on the second series, but the separateplt.show()calls make comparison impossible - and an overlay would have made the off-by-one above visible immediately.Brace the events: \(\textrm{Prob}(X=k)\) at 61, \(\textrm{Prob}(X=k;r,p)\) at 110, \(\textrm{Prob}(X=i)\) at 470-471, \(\textrm{Prob}(X\le i)\) at 479, and the bare \(P(\cdot)\) at 287 and 291 all describe logical conditions, and the same file already writes them with braces at 153, 343, 346, 385 and 393-395. In the same pass convert all 12
\textrm{Prob}to\mathbb{P}and the malformed\mathbb{Var}at 70 to\mathbb{V}.Replace the
bmatrixat 110 with\binom{k+r-1}{r-1}- it currently renders as a bracketed column vector, not a binomial coefficient - and fix the normal density at 210, which uses Latinufor \(\mu\) and brackets its own exponent.Promote the two bold pseudo-headings at 404 and 464 to
##headings so they appear in the contents alongside the other seven distributions, and add a histogram of the mixed discrete-continuous sample already computed at 301-304.Sweep the rest: the 29 double and triple spaces (48, 53, 58, 74, 114, 145, 275, 277, 280, 284 and 19 more), the five Title Case headings at 45, 143, 238, 275 and 338,
mystnbcaption and name metadata on the five figure cells (191, 442, 459, 518, 543) with theplt.titleat 194 moved into one, the unusedAxes3Dimport at 39, the commented-out line at 302, the two orphan cells at 535-541, and the missing verbs at 74, 282, 379 and 466.