lqramsey#

  • Series: lecture-python-advanced.myst

  • File: lectures/lqramsey.md

  • Audit date: 2026-08-26

  • Corpus snapshot: b83d6da399

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

  • Overall score: 7.5 / 10

  • Priority: HIGH

Score breakdown#

Category

Score

One-line note

Writing

4/10

qe-writing-005 ×5; qe-writing-003 ×5; qe-writing-002 ×5, +2 more.

Math

3/10

qe-math-010 (proposed) ×19; qe-math-002 ×10; qe-math-009 ×4.

Code

7.5/10

qe-code-001 ×7.

JAX

out of scope

JAX rules target lecture-jax.

Figures

8/10

qe-fig-006 ×3; qe-fig-001 ×2.

References

10/10

no mechanical violations detected.

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: 7. Lines: 589, 670, 716, 728, 740, 808, 826. Example: (1) 716 and 722 call sys.exit(0) from inside a library function to report a failure - it kills the notebook kernel rather than raising, and reports success while doing it; import sys at 78 exists only for those two lines, and a ValueError naming the failed condition is what the two neighbouring diagnostics at 711-721 are actually testing for. (2) 670 writes nx, nx = A.shape, binding one name twice and discarding the first value, and 676 then rebinds nx from C.shape. (3) 728 names the labour path l, the single letter PEP8 asks never to use, in a file that otherwise carries its mathematics in unicode (β, ν, τ, π, Π, ξ) - or ell would match both PEP8 and the \(\ell_t\) of the algebra; 896 likewise spells \(\mu_g\) as mg while \(\rho\) next to it is ρ. (4) 738 and 740 assign the identical expression to two names, H and temp (the second wrapped in a redundant extra pair of parentheses), and only temp is used at 741. (5) 826 and 827 are the same statement twice, bbox = (0., 1.02, 1., .102). (6) 808 calls axes[1, 1].plot(...) where the two lines above it in the same block use the local alias ax (806, 807). (7) Continuation indentation for the same construct takes three different forms: the namedtuple field lists are flat-indented to 20 and 16 spaces against parens at columns 28 and 24 (589-596, 599-613), Economy(...) continues at 16 against a paren at 18 (906-907, 955-956) but correctly at 18 at 1018-1019, and the array literals at 938-940 and 944-948 are indented to 12 where 1005-1009 aligns properly.

  • [qe-math-002] — Use \top for transpose notation. Count: 10. Lines: 387, 393, 401, 404, 408, 410, 411, 430. Example: apostrophe transpose )'.

  • [qe-math-010 (proposed)] — Blackboard \mathbb{P}, \mathbb{E}, \mathbb{V} with braces. Count: 19. Lines: 117, 128, 206, 262, 275, 331, 336, 359, 365, 401, …. Example: missing braces: \mathbb E.

  • [qe-writing-002] (reviewer) — Keep writing clear, concise, and valuable. Count: 5. Lines: 59, 536, 850, 858, 860. Example: 858-865 stops the lecture to teach the standard library: a 38-word sentence explaining what a namedtuple is, followed by a two-bullet list of its benefits (“Keeps content organized by meaning”, “Helps reduce the number of global variables”) and the concession at 867 that “Other than that, our code is long but relatively straightforward” - eight lines that say nothing about optimal taxation. 536 drops a symbol from the definition it is restating: the bullet writes \(R_t[B_t + g_t - \tau_t]\) where 524 has \(R_t[B_t - (\tau_t \ell_t - g_t)]\) and 542 gets it right (\(B_t + g_t - \tau_t \ell_t\)), so the \(\ell_t\) is missing in the middle version of three. 59 drops a conjunction from the sentence stating the lecture’s subject (“the dynamics of tax rates, tax revenues, government debt under a Ramsey plan”), 860 has “can then be references via dotted attribute notation”, and three more words are mistyped in load-bearing sentences: “identify covariance matrix” for identity (185), “the first-conditions” for first-order conditions (238), and the empty blockquote marker > left on line 539 in the middle of the martingale exposition.

  • [qe-writing-003] (reviewer) — Maintain logical flow. Count: 5. Lines: 611, 755, 756, 850, 1011. Example: the two objects the “A martingale” section exists for are computed differently from how they are defined, and documented as something else again. (i) 524 defines \(\pi_{t+1} := B_{t+1} - R_t[B_t - (\tau_t \ell_t - g_t)]\), so the revenue-and-spending term carries the factor \(R_t\); 755 computes π = B[1:] - R[:T-1] * B[:T-1] - rvn[:T-1] + g[:T-1], which is \(B_{t+1} - R_t B_t - \tau_t\ell_t + g_t\) - the \(R_t\) on that term is dropped, and the two agree only if \(R_t = 1\). (ii) 530 defines \(\Pi_t := \sum_{s=0}^t \pi_s\); 756 computes Π = cumsum(π * ξ), and \(\xi\) appears nowhere in the prose - it exists only as a namedtuple field (613), a docstring line (650), the quotients at 741 and 752-753, and the top panel of the second figure (833), so the figure plots an undefined object and the martingale result of 565-572 is asserted about a different sum than the one computed. (iii) 611-612 and 648-649 then label them wrongly in both the namedtuple and the docstring: π is annotated “One-period risk-free interest rate” (which is \(R\), already annotated at 610) and Π “Cumulative rate of return, adjusted”. Separately, the exercise at 984-990 asks for \(C_g = 0.7\sqrt{1-\rho^2}\) and the solution at 1011 sets C[0, 0] = np.sqrt(1 - ρ**2) * mg / 8, i.e. \(0.04375\sqrt{1-\rho^2}\) - a factor of 16 out - so the solution does not answer the exercise. And the orientation section at 848-867 misdirects on both counts: 850 attributes var_quadratic_sum to a module quadsums that is not imported anywhere (85 imports it from quantecon), and 853 says the namedtuples are “below the definition of the function” when 589-613 puts them above compute_paths at 616.

  • [qe-writing-005] (reviewer) — Use bold for definitions, italic for emphasis. Count: 5. Lines: 53, 197, 212, 218, 222. Example: the file contains no bold at all, and every term it defines is set in italic instead: Ramsey problem (53, and again at 218 where it is formally defined), feasible (197, defined by {eq}`lq_feasible` in the same sentence), equilibrium (212, followed by the two numbered conditions that constitute it) and Ramsey plan (222). The rule assigns italic to emphasis and bold to definitions, and here the whole vocabulary of the lecture takes the emphasis form, so italic carries no signal - there is no emphasis anywhere for it to be distinguished from. 576 adds a third treatment, inline code on an English phrase, for a term that is being introduced: “the excess payoff \(\{\Pi_t\}\)”.

  • [qe-writing-008] — Remove excessive whitespace between words. Count: 7. Lines: 53, 59, 382, 541, 572, 860. Example: 2 spaces.

Medium severity#

  • [qe-fig-001] — Do not set figure size unless necessary. Count: 2. Lines: 775, 824. Example: figsize=.

  • [qe-fig-006] — Lowercase axis labels. Count: 3. Lines: 780, 835, 842. Example: axis label Time.

  • [qe-math-009] (reviewer) — Choose simplicity in mathematical notation. Count: 4. Lines: 146, 274, 359, 497. Example: \(b_0\) means two different things inside one derivation. It is the time-0 value of the preference shock \(b_t\) where the household’s first-order conditions are normalised - “normalizing at \(\mu = b_0 - c_0\)” (245) and \(p_t^0 = (b_t - c_t)/(b_0 - c_0)\) in {eq}`lq_hfoc` - and then at 359 it is redefined as the expected discounted sum \(\mathbb E\{\sum \beta^t (b_t - \bar c_t)(g_t + s_t)\}\), which is what 374 solves for \(\nu\) with. Nothing marks the reuse. \(\pi\) carries two meanings the same way: the probability density of a history, \(\pi^0_t(x^t)\) at 145-146, and the excess payout \(\pi_{t+1}\) at 524 - and the code’s own comment at 611 reads it as a third thing, an interest rate. The expectation operator is written three ways: \(\mathbb E\) (117, 128, 206, 262, 275, 331, 336, 359, 365, 401, 426), \(\mathbb E_t\) (472, 481, 513) and a plain \(E_t\) (497, 505, 547, 562), with the plain form appearing in the middle of the martingale derivation alongside \(\tilde E_t\) (555, 568). And 274 uses \(\mathscr L\) for the Lagrangian, a script capital that appears exactly once in the file where a plain \(L\) was free.

  • [qe-writing-007] (reviewer) — Use visual elements to enhance understanding. Count: 3. Lines: 786, 833, 914. Example: gen_fig_1 draws four panels and plots the same two series in three of them: \(\tau_t\ell_t\) and \(g_t\) appear in panel (0,0) with \(c_t\) (787-789), in panel (0,1) with \(B_{t+1}\) (794-796), and in panel (1,1) with \(\pi_{t+1}\) (806-808), so six of the figure’s ten lines are two lines drawn three times, while \(R_t - 1\) gets a panel of its own. No panel has a title, no cell has a caption or name, and 914 substitutes for all of that with “The legends on the figures indicate the variables being tracked” - which is also the only thing distinguishing the continuous example’s figure (911) from the discrete one’s (960) and the exercise’s (1024), three visually identical four-panel plots. Second, the contrast the lecture ends on is explicit at 574-576 - Barro’s debt is a random walk, here \(\{B_t\}\) is not but \(\{\Pi_t\}\) is - and the two series are never put together: \(\Pi_t\) is plotted alone in the lower panel of gen_fig_2 (840) with no zero line and no comparison, while \(B_{t+1}\) is one of three lines in a panel of the other figure. Third, the upper panel of gen_fig_2 (833) plots \(\xi_t\), which the prose never defines.

Low severity#

None found.

Strengths#

  • The solution is announced as three steps at 224-232 and then executed in exactly that order under its own headings: household first-order conditions at 238-254, substitution into the government budget constraint at 256-264, and the constrained maximisation at 266-281 - so a reader always knows which of the three they are in.

  • The two hard expectations are reduced to a single reusable object and both branches are then supplied: 384-402 shows that both terms of {eq}`lq_gc3` are special cases of \(q(x_0) = \mathbb E \sum \beta^t x_t' H x_t\), 406-414 gives the Lyapunov solution for the VAR case, and 416-449 gives the \((I - \beta P)^{-1} h\) solution for the Markov case - which is precisely the branch structure of compute_paths at 692-703.

  • The martingale result is derived rather than quoted: 544-548 substitutes {eq}`lq_cb22` and {eq}`lq_rfr` into the definition of \(\pi_{t+1}\), 552-563 identifies the change of measure through the likelihood ratio \(m^t_{t+1} = p^t_{t+1}/E_t p^t_{t+1}\), and 567-572 shows \(\tilde E_t \pi_{t+1} = 0\) in one line - and 574-576 says what it is worth by contrasting it with Barro’s random-walk debt.

  • The scaled Arrow-Debreu price is not left as a convention: 143-154 gives the unscaled price \(\beta^t p^0_t / \pi^0_t(x^t)\) explicitly and states in a sentence what the scaling multiplies and divides by, which is what makes {eq}`lq_hc` and {eq}`lq_gc` readable.

  • The existence condition for the Ramsey plan is stated where it belongs and then actually tested in code: 379-380 requires \(4 b_0 < a_0\) for a unique \(\nu \in (0, 1/2)\), and 705-722 checks the discriminant and then the sign of \(\nu(0.5 - \nu)\), reporting which of the two failed.

  • The two exogenous-process specifications are labelled once at 183-185 and then referred to by {ref}above <lq_twospec>`` from all four places that need them (406, 418, 851, 876), so the reader is never asked to remember which case is which.

  • The whole model is stated in six primitive selector matrices (168-179) and the two worked examples set exactly those, with the discrete case documenting its own state layout in the cell (# Each column is a state of the world. The rows are [g d b s 1], 942-943) so x_vals at 944-948 can be read against Sg-Ss at 950-953.