opt_tax_recur#

  • Series: lecture-python-advanced.myst

  • File: lectures/opt_tax_recur.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.4 / 10

  • Priority: LOW

Score breakdown#

Category

Score

One-line note

Writing

4.5/10

qe-writing-001 ×3; qe-writing-005 ×4; qe-writing-003 ×3, +3 more.

Math

5.5/10

qe-math-010 (proposed) ×3; qe-math-003 ×2; qe-math-009 ×4.

Code

8.5/10

qe-code-001 ×4.

JAX

out of scope

JAX rules target lecture-jax.

Figures

4.5/10

qe-fig-003 ×5; qe-fig-005 ×5; qe-fig-006 ×1, +2 more.

References

9/10

qe-ref-001 ×1.

Links

10/10

no mechanical violations detected.

Admonitions

10/10

no mechanical violations detected.

Issues#

Critical#

None found.

High severity#

  • [qe-fig-001] — Do not set figure size unless necessary. Count: 5. Lines: 1119, 1174, 1245, 1314, 1389. Example: figsize=.

  • [qe-fig-003] — No matplotlib embedded titles. Count: 5. Lines: 1127, 1175, 1250, 1316, 1395. Example: .set(title=.

  • [qe-fig-005] — Descriptive figure names for cross-referencing. Count: 5. Lines: 1101, 1173, 1233, 1302, 1368. Example: code-cell figure without mystnb figure metadata.

  • [qe-math-010 (proposed)] — Blackboard \mathbb{P}, \mathbb{E}, \mathbb{V} with braces. Count: 3. Lines: 484, 884, 1157. Example: non-blackboard {\rm Prob}.

  • [qe-writing-008] — Remove excessive whitespace between words. Count: 106. Lines: 35, 38, 40, 46, 47, 48, 49, 51, 55, 65, …. Example: 2 spaces.

Medium severity#

  • [qe-code-001] (reviewer) — Follow PEP8 unless closer to mathematical notation. Count: 4. Lines: 1174, 1245, 1315, 1393. Example: 1393-1396 indents a loop body to column 35, aligned under the arguments of the zip(...) call on the line above rather than one level past the for: for ax, title, sim_s, sim_b in zip(axes.flatten(), titles, sim_seq[:6], sim_rec[:6]): followed by three statements at 35 spaces - legal Python that reads as a continuation of the call, and directly at odds with the identically shaped loop at 1123-1129, which uses a four-space body. 1174 writes fix, ax = plt.subplots(figsize=(8, 5)), leaving an unused variable misspelled from fig while every other cell uses fig (1119, 1245, 1314, 1389). 1245 has figsize=(10,8) without the space after the comma that 1119, 1174, 1314 and 1389 all use. And 1307-1318 mismatches shapes against labels: τ_reset is allocated as np.empty((n, 2)) but filled at 1312 from simulate(..., 0, 1)[3], which returns a single period and broadcasts across both columns, so ax.plot(gov_debt, tax_policy[:, 1], gov_debt, τ_reset, lw=2) at 1315 creates three line artists - two of them identical - against the two legend entries supplied at 1318, leaving one line unlabelled and the mapping of $\tau_1^R$ to an artist implicit.

  • [qe-fig-008] — Use lw=2 for line charts. Count: 3. Lines: 1128, 1176, 1394. Example: plot() without lw=.

  • [qe-math-003] — Use square brackets for matrix notation. Count: 2. Lines: 1061, 1072. Example: matrix environment.

  • [qe-math-009] (reviewer) — Choose simplicity in mathematical notation. Count: 4. Lines: 84, 282, 810, 1061. Example: the state space is written three ways. 84 defines it with square brackets, ${\cal S} = [1, 2, \ldots, S]$, which is interval notation for a finite set; 480-481 restates it as $s\in [1, \ldots, S]$, again with brackets and without the calligraphic; and 810 sums over \sum_{s'\in S} with a plain \(S\) while the very next display at 820 sums over \sum_{s' \in {\cal S}} - so the two halves of the same Bellman-equation pair disagree about the symbol, and 826, 837, 848, 858 and 934 all use {\cal S} while 810 does not. Fractions are written two ways: \frac{}{} fourteen times, against the plain-TeX {a \over b} form at 282 and twice more at 286, in displays adjacent to a \frac at 270. And the two matrix displays at 1061 and 1072 use \left(\begin{matrix}...\end{matrix}\right), which is bmatrix written the long way and with the wrong delimiters (qe-math-003 flags both).

  • [qe-writing-001] — Use one sentence per paragraph. Count: 3. Lines: 55, 286, 654. Example: 3 sentences in one paragraph.

  • [qe-writing-002] (reviewer) — Keep writing clear, concise, and valuable. Count: 4. Lines: 640, 651, 1208, 1296. Example: 640-647 spends four one-line paragraphs establishing that two phrases are synonyms: “The means that a Ramsey plan is not time consistent.” (which also mis-types “This”), then “Another way to say the same thing is that a Ramsey plan is time inconsistent.”, then the reason, then “We shall discuss this more below.” The section “Time 0 manipulation of interest rate” (1208-1218) restates in three paragraphs what 1146-1168 has just said at greater length and with the formula for \(R_t\) attached, so the same mechanism is explained twice within sixty lines. 651-654 interrupts the specialisation with a bracketed aside about why the earlier utility function was used and that the lecture will revert to it. And two sentences carry duplicated words: “confronting this value for initial government debt government” (1296) and “the risk-free rate one-period interest rate” (1161).

  • [qe-writing-003] (reviewer) — Maintain logical flow. Count: 3. Lines: 1109, 1271, 1303. Example: the algebra and the code disagree about which state is the war state. 1053-1056 lists the six \((t,g)\) pairs as \((0,g_l),(1,g_l),(2,g_l),(3,g_l),(3,g_h),(t\geq4,g_l)\) mapped to \(s = 1,\ldots,6\), and the displayed expenditure vector at 1071-1073 is \(g = (0.1, 0.1, 0.1, 0.1, 0.2, 0.1)\) - so \(g_h\) sits in the fifth state. The code at 1109 writes g = np.array([0.1, 0.1, 0.1, 0.2, 0.1, 0.1]), putting \(g_h\) in the fourth, and 1114-1115 then simulate the war history through index 3 and the peace history through index 4, consistent with the code and not with the display. (The same discrepancy appears in amss.md at 794/815 against 846 and 891-892, which shares this construction, so the two files should be fixed together.) Second, 1271-1272 reverses the mechanism the surrounding paragraphs establish: “A side effect of lowering time \(t=0\) consumption is that it lowers the one-period interest rate at time \(t=0\) below that of subsequent periods” - but 1150-1154 and 1263-1266 both say the planner raises \(c_0\), and by the definition of \(R_t\) at 1156-1158, \(R_t = u_{c,t}/(\beta\mathbb E_t[u_{c,t+1}])\), lowering \(c_0\) raises \(u_{c,0}\) and therefore raises \(R_0\). Third, the cell at 1302-1322 rebuilds and re-solves what the cell at 1233-1257 has already computed - the same SequentialLS(CRRAutility(), g=np.array([0.15]), π=np.ones((1, 1))), the same gov_debt grid, the same 100-iteration tax_policy loop - so the slower of the lecture’s two solves runs twice.

  • [qe-writing-005] (reviewer) — Use bold for definitions, italic for emphasis. Count: 4. Lines: 40, 286, 290, 1135. Example: three terms are introduced in italic where the lecture’s own convention is bold: “Here a war means a more or less temporary surge in an exogenous government expenditure process” (40), “what finance economists call a stochastic discount factor process” (286), and “we derive the implementability condition” (290) - the last of which names the single constraint the rest of the lecture is built on, and which {eq}`TSs_cham1` labels. The bold convention is used correctly for Ramsey problem (300) and Ramsey plan, so the italics read as emphasis rather than definition. 1135 then uses bold as a section heading, **Tax smoothing**, standing alone above a bullet list, where a real #### heading would put it in the table of contents alongside “Government saving” (1181) and “Time 0 manipulation of interest rate” (1208), which are headings.

  • [qe-writing-007] (reviewer) — Use visual elements to enhance understanding. Count: 3. Lines: 1060, 1128, 1173. Example: every figure in the lecture distinguishes its series by a matplotlib format string and nothing else: '-ok' against '-or' at 1128 and 1176, '-ob' against '-xk' at 1394, and two unnamed columns at 1249 and 1315 - and only two of the five figures carry a legend (1253, 1398), each on one panel of a six-panel grid, so ten of the twelve panels leave the reader to recall from prose which colour is which. 1096-1099 has to state the convention in words (“black when \(g_3 = .1\), and red when \(g_3 = .2\)”) for a figure that could carry it. Second, the figure at 1173-1178 plots the gross interest rate against time with an embedded title and no axis labels at all - no set_xlabel, no set_ylabel - even though the point being made (that \(R_0\) is below its later values) is about a specific date on the horizontal axis. Third, the six-state \((t,g)\) construction at 1053-1067, with the war branch opening at \(t=3\) and both branches merging at \(t\geq4\), is presented only as a \(6\times6\) transition matrix, where a small transition diagram would make the device immediately legible - the same construction, and the same gap, as in amss.md.

Low severity#

  • [qe-fig-006] — Lowercase axis labels. Count: 1. Lines: 1254. Example: axis label Initial Government Debt.

  • [qe-ref-001] — Use correct citation style. Count: 1. Lines: 55. Example: {cite} in narrative flow: ‘of {cite}’.

Strengths#

  • The single constraint that carries the whole Ramsey problem is traceable to its source: the household’s Arrow-security budget constraints are consolidated into a present-value condition, the first-order conditions give {eq}`LSA_taxr` and {eq}`LS101`, {eq}`LS102` turns the latter into the Arrow-Debreu price system, and 289-298 then states exactly what was eliminated - taxes and prices - to arrive at the implementability condition {eq}`TSs_cham1`.

  • Each specialisation is fenced and dated: 476-490 says which assumptions are being added (finite Markov chain with transition matrix \(\Pi\), time-invariant \(g(s)\)) and that they hold “throughout the remainder of this lecture”; 649-677 says which of Lucas and Stokey’s assumptions are being replaced - leisure eliminated, \(\ell_t + n_t \leq 1\) dropped, \(n_t \in [0,+\infty]\) - and 654 explains why the original specification was presented first and will be reverted to.

  • The recursive representation is built in the two pieces the problem actually has, and the reader is told what comes out of each: {eq}`LSA_Bellman1` with the single implementability constraint {eq}`LSA_Bellman1cons` for \(t \geq 1\) (807-826), the separate time-0 problem for \(W(b_0, s_0)\) (848-858), and 829-840 naming the \(S+1\) time-invariant policy functions and the law of motion \(x_{t+1}(s_{t+1}) = h(s_{t+1}; x_t, s_t)\) that the value function delivers.

  • Time inconsistency is given a cause and then a sharp characterisation: 644-645 identifies it as the continuation planner taking \(u_{ct}b_t(s_t|s^{t-1})\) as given rather than \(b_t\) itself, and 1274-1290 finds the only two initial debt levels at which the Ramsey plan is time consistent - \(b_0 = 0\), where the \(t=0\) tax rate cannot move the value of the debt, and the first-best asset level, where \(\tau_t = 0\) - then 1298-1325 checks it by plotting the original planner’s \(\tau_1\) against a reborn planner’s \(\tau_1^R\).

  • The anticipated-war example is fully specified before anything runs: the six \((t,g)\) states listed (1053-1056), the \(6\times6\) transition matrix written out entry by entry (1060-1067), the expenditure vector (1071-1073), the utility function with \(\sigma = 2\), \(\gamma = 2\), \(\beta = 0.9\) (1077-1081), and \(b_0 = 1\) (1094) - so every number in the figure that follows is accounted for.

  • The war example’s economics is read off the figures date by date rather than in general terms: dissaving at \(t=0\) and why (1183-1186), saving at \(t=1\) and its motive (1188-1191), the two Arrow securities bought and sold at \(t=2\) named individually (1193-1197), the consequence that \(t=4\) debt is the same either way (1198-1202), and roll-over thereafter (1204-1206).

  • The tax-smoothing result is attributed and then deliberately broken: 1329-1345 uses \(U_{cc}c = -\sigma U_c\) and \(U_{nn}n = \gamma U_n\) to derive the CRRA relation that forces \(\tau\) to be constant, and 1349-1408 then swaps in \(u(c,n) = \log c + 0.69\log(1-n)\), computes the path both sequentially and recursively, plots the two together as a mutual check, and states the new outcome - the tax rate rises with \(g_t\) (1403-1408).