mobility#

  • Series: lecture-python-intro

  • File: lectures/mobility.md

  • Audit date: 2026-08-26

  • Corpus snapshot: a12d17c0ef

  • Categories audited: writing, math, code, figures, references, links, admonitions (JAX out of scope)

  • Overall score: 7.6 / 10

  • Priority: LOW

Score breakdown#

Category

Score

One-line note

Writing

4.5/10

qe-writing-004 ×2; qe-writing-005 ×3; qe-writing-003 ×3, +2 more.

Math

6/10

qe-math-010 (proposed) ×8; qe-math-009 ×2.

Code

8.5/10

qe-code-001 ×4.

JAX

out of scope

JAX rules target lecture-jax.

Figures

7.5/10

qe-fig-003 ×1; qe-fig-005 ×1; qe-fig-004 ×1, +1 more.

References

7/10

qe-ref-001 ×19.

Links

10/10

no mechanical violations detected.

Admonitions

10/10

no mechanical violations detected.

Issues#

Critical#

None found.

High severity#

  • [qe-math-010 (proposed)] — Blackboard \mathbb{P}, \mathbb{E}, \mathbb{V} with braces. Count: 8. Lines: 92, 880, 899, 904, 905, 912, 920. Example: missing braces: \mathbb P.

  • [qe-ref-001] — Use correct citation style. Count: 19. Lines: 248, 286, 298, 360, 504, 590, 597, 771, 804, 984, …. Example: {cite} in narrative flow: ‘of {cite}’.

Medium severity#

  • [qe-code-001] (reviewer) — Follow PEP8 unless closer to mathematical notation. Count: 4. Lines: 515, 516, 729, 788. Example: the code is otherwise clean - no line over 79 characters, no trailing whitespace anywhere in the file, and Unicode Greek used exactly as intended (ψ_star, λ, α, β, Δ_B, Δ_T). Four items remain. 515 and 523 use single-quoted one-line docstrings ("Return the four mobility measures for stochastic matrix M.") where PEP 257 asks for triple quotes even on one-liners - and the file’s other three docstrings (442-448, 1145 region) are correctly triple-quoted, so it disagrees with itself. 516-519 and 788-791 pad after the dict colon to align the values ('μ_S':   shorrocks(M),), which is the “more than one space around an operator to align it with another” that PEP8 lists under Pet Peeves. And 729-734 and 736-741 indent the continuation to a flat 28 spaces under long_horizon['1989-2009'] = normalize_rows(, whose opening delimiter sits at column 42 - neither a visual indent nor a 4-space hanging one.

  • [qe-fig-003] — No matplotlib embedded titles. Count: 1. Lines: 669. Example: .set_title.

  • [qe-math-009] (reviewer) — Choose simplicity in mathematical notation. Count: 2. Lines: 473, 483. Example: the same three letters are typeset two ways four lines apart: 473 and 478 write the mean first passage functional as \text{MFP}(M), upright, while 483 writes the normalized measure as \mu_{MFP}(M), so MFP is italic there and upright above it - and \(\mu_{MFP}\) is then the form carried through 501, 716, 944, 1048 and the code label 'μ_MFP'. The same slip affects \(\mu_{2E}\) (357 onward) and \(\mu_{NB}\) (326 onward), whose multi-character subscripts are set in maths italic and so read as products of variables. One \mathrm{...} convention across all four subscripts, matching the \mathrm{trace}, \mathrm{corr}, \mathrm{cov} and \mathrm{var} the lecture already uses correctly (253, 880, 912, 920), would settle it.

  • [qe-writing-002] (reviewer) — Keep writing clear, concise, and valuable. Count: 4. Lines: 652, 802, 1118, 1224. Example: 652 packs a two-part answer into one 44-word sentence directly after announcing it as two: 650 says “Two things push them off”, and then a single sentence delivers both causes joined by “and” with an em-dash aside inside the second. 802 - “Also, unobserved features are at work.” - is filler between the substantive 800 and the concrete example at 804 that actually names the unobserved features. 1116-1120 restates 1112-1114 in different words five lines later: 1114 already said Bartholomew’s measure “counts only distance travelled”, and 1118 says it again as “counts distance travelled and so favours a matrix that shifts mass towards the corners”. And 1224 is a 60-word sentence containing an embedded four-item list of Shorrocks’ axioms between em-dashes, in a lecture whose house style is one short sentence per paragraph; the four axioms are exactly the material a bulleted list carries better.

  • [qe-writing-003] (reviewer) — Maintain logical flow. Count: 3. Lines: 426, 947, 1237. Example: 426-431 reuses \(t\) for a second meaning. The lecture fixes \(t\) as the horizon at 80 (“two dates, \(s\) and \(s + t\)”), carries that through the definition of \(m_{ij}\) at 92-93 and states at 106 that “the time unit of the chain is the horizon \(t\)”; then 426 writes “\(t\) for the vector of these unknowns” and 429-431 display \(t = \mathbb 1 + M_{-j} \, t\), so the same letter is the length of a period and a vector of expected waiting times measured in those periods. 947 drops a closed form into the mob_ex2 solution with no derivation and no sentence naming it - mfp_measure(M2), 8 * α * β / ((1 + α + β) * + β)) - so the reader sees two numbers agreeing and has to reverse-engineer what the second expression is; every other claim in this lecture is either derived or explicitly deferred to a citation. And the {note} at 1236-1240 inverts its own reason: “This section describes the shape of Shorrocks’ impossibility result rather than stating it formally, since the precise axiom list matters” - if the precise axiom list matters, that is an argument for stating it, not for paraphrasing it.

  • [qe-writing-004] — Avoid unnecessary capitalization in narrative text. Count: 2. Lines: 597. Example: mid-sentence ‘Income’.

  • [qe-writing-005] (reviewer) — Use bold for definitions, italic for emphasis. Count: 3. Lines: 1244, 1246, 1248. Example: the body is exemplary - ten definitions, all bold, all at first mention - and then the Further reading section defines three more terms and bolds none of them. 1244 defines a term with a colon and a gloss in italic: “This lecture has studied intragenerational mobility: the movement of a given family through the distribution over its own lifetime”; 1246 does the same with “meaning”: “studies intergenerational mobility, meaning the relationship between the economic position of parents and that of their children”. 1248 defines the intergenerational elasticity - “the coefficient from regressing a child’s log earnings on the parent’s” - with no emphasis at all, three lines before Great Gatsby curve at 1250 is correctly bolded. Two lesser instances of the same drift: the three toy economies are named in italic at 558, 560 and 562 (ladder, jumper, sticky), and those names are what the rest of the section refers to them by.

  • [qe-writing-007] (reviewer) — Use visual elements to enhance understanding. Count: 3. Lines: 461, 564, 787. Example: the lecture visualises the empirical matrices well (five figures, four of them named and captioned) and then leaves its three most argument-carrying objects as raw numeric output. 545-567 is the pedagogical core - three hand-built 3x3 matrices constructed so that each measure is provably blind to something - and the reader only ever sees them as a mobility_table(...) DataFrame at 564-567; the matrices themselves are never drawn, even though the file already has the exact idiom for it at 666-675, a 1x3 imshow row of the same shape. 461 prints the 5x5 mean-first-passage matrix with np.round(..., 1) and then 464 asks the reader to read “the top right entry” out of it, which is the one place in the lecture where a heatmap or an annotated table would do real work. And 787-793 tests whether the quintile chain is Markov by tabulating \(M\), \(M^2\) and \(M^4\) against the data; the claim at 796-798 is about a gap (“\(\mu_S\) is 0.87 under the Markov prediction against 0.74 in the data”), which is a comparison a two-line bar chart shows and a four-row table does not.

Low severity#

  • [qe-fig-001] — Do not set figure size unless necessary. Count: 1. Lines: 666. Example: figsize=.

  • [qe-fig-004] — Caption formatting conventions. Count: 1. Lines: 658. Example: caption of 7 words.

  • [qe-fig-005] — Descriptive figure names for cross-referencing. Count: 1. Lines: 1013. Example: code-cell figure without mystnb figure metadata.

Strengths#

  • The two benchmarks are argued for, not assumed. 192 raises the objection a careful reader would raise - “You might object that \(M^*\) is not the only matrix with this property” - then 198-207 derives double stochasticity from the fact that quantiles hold equal numbers of households at both dates, and 209-213 shows that within that setting the uniform matrix is the unique origin-independent one. That is the whole justification for calibrating four measures to 0 and 1, and it is done in fifteen lines.

  • Every forward reference is honoured, and honoured in a way that closes a loop rather than just pointing: 112 promises the data section and 592-605 delivers it; 108 promises to return to the choice of horizon and 684-716 does, with the sharpest sentence in the lecture at 714; 374 sends the reader to mob_ex2 for the two-state autocorrelation claim and 878-920 proves it; and 654 predicts that the column-sum deviation “will resurface in {ref}`the final exercise <mob_ex6>`”, which 1207-1211 then traces back to the same two causes named at 652.

  • First-step analysis is derived, then checked on the smallest case that has an answer already known, then generalised: 397-404 annotates each term of the recursion with an \underbrace saying what it is, 416-422 specialises it to the two-state unemployment chain and recovers \(T_{ij} = 1/\alpha\) with the geometric-waiting-time cross-check, and only then does 424-434 recast it as the linear solve the code implements at 452-456.

  • “What the measures miss” (536-590) is constructed rather than asserted: three 3x3 matrices are built so that two of them share a diagonal, two share a Bartholomew score and two share a second eigenvalue, and 582-588 then shows the measures reversing each other’s ranking and states the conclusion plainly - “there is, in short, no complete ordering of mobility matrices, and any single index imposes one by fiat”. Exercise mob_ex5 (1041-1120) turns that into a search problem and finds a fresh disagreement by random draw.

  • Both proposed math conventions are satisfied without exception. Events are written with braces (\mathbb P \{ \text{household $h$ is in quantile } j \mid \ldots \} at 92-93, \mathbb P\{X_t = 1, X_{t+1} = 1\} at 905) per qe-math-014 (proposed), and the case convention of qe-math-015 (proposed) holds throughout - lowercase for distributions and probabilities (\(\psi\), \(\psi^*\), \(m_{ij}\), \(p\)), uppercase for the matrices that hold them (\(M\), \(T\), \(I\)).

  • The two {note} blocks pre-empt the two objections a reader actually raises, at the point they arise: 225-235 explains why a measure exceeding 1 is meaningful rather than a bug, four sections before any matrix could produce such a value, and mob_ex1 part 4 (823) then asks the reader to explain it back. 503-507 says the source paper’s closed form for \(T\) is equivalent to the first-step derivation used here, which is exactly the discrepancy a reader checking against {cite}`carroll2026mobility` would trip over.

  • The simulation exercise does not stop at agreement: 1176-1182 names the specific bias in the estimator it just validated - paths shorter than the rarest transition truncate the hitting time downwards - and hands the reader the reproduction (Try rerunning with path_length=30); and 1164 explains why the code searches X[1:] rather than X, which is the one line of that function a reader would otherwise misread.