Full findings & remediation plan#
The complete cross-series breakdown behind the front-page triage. Start with the front page to decide where to focus; come here for the full numbers, every recurring rule, every HIGH-priority lecture, and the ordered remediation plan.
Every table on this page is generated from
lectures/data/*.csv
by tools/qestyle_report.py, so it cannot disagree with the per-lecture reports.
What was audited#
One commit per series, pinned at audit time. Re-running the pipeline against these commits reproduces every number on this page exactly.
Series |
Lectures |
Snapshot commit |
Snapshot date |
|---|---|---|---|
|
56 |
|
2026-08-23 |
|
27 |
|
2026-08-21 |
|
145 |
|
2026-08-24 |
|
68 |
|
2026-08-19 |
|
52 |
|
2026-08-07 |
Full scoreboard#
Average score per category, per series (0–10). Bold marks each series’ weakest category.
# |
Series |
Lectures |
Writing |
Math |
Code |
Figures |
References |
Links |
Admon |
Overall |
HIGH |
MEDIUM |
LOW |
NONE |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 |
68 |
4.6 |
5.8 |
7.3 |
6.3 |
9.2 |
9.2 |
10.0 |
7.4 |
43 |
0 |
20 |
5 |
|
2 |
145 |
4.5 |
7.0 |
7.6 |
6.5 |
9.5 |
9.8 |
10.0 |
7.7 |
81 |
1 |
46 |
17 |
|
3 |
52 |
4.7 |
6.6 |
7.7 |
6.4 |
9.3 |
9.5 |
10.0 |
7.7 |
34 |
0 |
9 |
9 |
|
4 |
27 |
4.1 |
9.0 |
8.4 |
7.3 |
N/A |
9.8 |
9.9 |
8.0 |
20 |
0 |
5 |
2 |
|
5 |
56 |
5.2 |
8.6 |
7.3 |
6.5 |
9.3 |
9.7 |
10.0 |
8.1 |
19 |
0 |
28 |
9 |
|
TOTAL / corpus average |
348 |
4.6 |
7.0 |
7.5 |
6.5 |
9.4 |
9.6 |
10.0 |
7.7 |
197 |
1 |
108 |
42 |
See the charts for the visual version.
Every recurring rule#
All rules with at least one violation in the corpus, ranked by how many lectures they
reach. Rules tagged (proposed) are documented in the style guide but not yet in the
action-style-guide registry.
1. qe-fig-005 — Descriptive figure names for cross-referencing (273 / 348 lectures, 1115 occurrences)#
lecture-python.myst110 / 145 ·lecture-python-advanced.myst54 / 68 ·lecture-python-intro46 / 56 ·lecture-dp42 / 52 ·lecture-python-programming21 / 27
2. qe-writing-008 — Remove excessive whitespace between words (237 / 348 lectures, 7122 occurrences)#
lecture-python.myst89 / 145 ·lecture-python-advanced.myst53 / 68 ·lecture-dp40 / 52 ·lecture-python-intro39 / 56 ·lecture-python-programming16 / 27
3. qe-fig-001 — Do not set figure size unless necessary (224 / 348 lectures, 892 occurrences)#
lecture-python.myst107 / 145 ·lecture-python-advanced.myst47 / 68 ·lecture-dp31 / 52 ·lecture-python-intro30 / 56 ·lecture-python-programming9 / 27
4. qe-fig-008 — Use lw=2 for line charts (196 / 348 lectures, 1194 occurrences)#
lecture-python.myst69 / 145 ·lecture-python-advanced.myst40 / 68 ·lecture-dp38 / 52 ·lecture-python-intro35 / 56 ·lecture-python-programming14 / 27
5. qe-writing-001 — Use one sentence per paragraph (175 / 348 lectures, 448 occurrences)#
lecture-python.myst65 / 145 ·lecture-python-advanced.myst42 / 68 ·lecture-python-intro30 / 56 ·lecture-dp23 / 52 ·lecture-python-programming15 / 27
6. qe-fig-003 — No matplotlib embedded titles (165 / 348 lectures, 630 occurrences)#
lecture-python.myst79 / 145 ·lecture-python-advanced.myst36 / 68 ·lecture-dp30 / 52 ·lecture-python-intro15 / 56 ·lecture-python-programming5 / 27
7. qe-writing-006 — Capitalize lecture titles properly (132 / 348 lectures, 768 occurrences)#
lecture-python.myst71 / 145 ·lecture-python-programming23 / 27 ·lecture-dp22 / 52 ·lecture-python-intro13 / 56 ·lecture-python-advanced.myst3 / 68
8. qe-math-010 (proposed) — Blackboard \mathbb{P}, \mathbb{E}, \mathbb{V} with braces (124 / 348 lectures, 1608 occurrences)#
lecture-python.myst60 / 145 ·lecture-python-advanced.myst33 / 68 ·lecture-dp20 / 52 ·lecture-python-intro8 / 56 ·lecture-python-programming3 / 27
9. qe-ref-001 — Use correct citation style (106 / 348 lectures, 291 occurrences)#
lecture-python.myst36 / 145 ·lecture-python-advanced.myst35 / 68 ·lecture-dp20 / 52 ·lecture-python-intro15 / 56
10. qe-writing-004 — Avoid unnecessary capitalization in narrative text (105 / 348 lectures, 339 occurrences)#
lecture-python.myst43 / 145 ·lecture-python-advanced.myst24 / 68 ·lecture-python-intro18 / 56 ·lecture-dp14 / 52 ·lecture-python-programming6 / 27
11. qe-link-002 — Use doc links for cross-series references (73 / 348 lectures, 205 occurrences)#
lecture-python-advanced.myst26 / 68 ·lecture-python.myst20 / 145 ·lecture-dp15 / 52 ·lecture-python-intro9 / 56 ·lecture-python-programming3 / 27
12. qe-code-002 — Use Unicode symbols for Greek letters in code (66 / 348 lectures, 798 occurrences)#
lecture-python.myst32 / 145 ·lecture-python-advanced.myst17 / 68 ·lecture-python-intro10 / 56 ·lecture-dp7 / 52
13. qe-math-002 — Use \top for transpose notation (63 / 348 lectures, 1597 occurrences)#
lecture-python.myst24 / 145 ·lecture-python-advanced.myst20 / 68 ·lecture-dp14 / 52 ·lecture-python-intro4 / 56 ·lecture-python-programming1 / 27
14. qe-fig-006 — Lowercase axis labels (60 / 348 lectures, 298 occurrences)#
lecture-python.myst21 / 145 ·lecture-python-advanced.myst15 / 68 ·lecture-dp12 / 52 ·lecture-python-intro11 / 56 ·lecture-python-programming1 / 27
15. qe-fig-004 — Caption formatting conventions (60 / 348 lectures, 189 occurrences)#
lecture-python.myst34 / 145 ·lecture-python-intro17 / 56 ·lecture-python-advanced.myst9 / 68
16. qe-math-003 — Use square brackets for matrix notation (46 / 348 lectures, 363 occurrences)#
lecture-python.myst21 / 145 ·lecture-python-advanced.myst15 / 68 ·lecture-dp6 / 52 ·lecture-python-intro4 / 56
17. qe-fig-002 — Prefer code-generated figures (38 / 348 lectures, 104 occurrences)#
lecture-python-advanced.myst12 / 68 ·lecture-python.myst10 / 145 ·lecture-python-intro6 / 56 ·lecture-dp5 / 52 ·lecture-python-programming5 / 27
18. qe-math-011 (proposed) — Distribution names in plain letters, not \mathcal / \mathbb (34 / 348 lectures, 134 occurrences)#
lecture-python-advanced.myst18 / 68 ·lecture-python.myst10 / 145 ·lecture-dp5 / 52 ·lecture-python-intro1 / 56
19. qe-math-004 — Do not use bold face for matrices or vectors (33 / 348 lectures, 584 occurrences)#
lecture-python.myst18 / 145 ·lecture-python-advanced.myst6 / 68 ·lecture-dp5 / 52 ·lecture-python-intro4 / 56
20. qe-code-004 — Use quantecon Timer context manager (31 / 348 lectures, 144 occurrences)#
lecture-python.myst15 / 145 ·lecture-dp8 / 52 ·lecture-python-advanced.myst4 / 68 ·lecture-python-intro3 / 56 ·lecture-python-programming1 / 27
21. qe-writing-009 (proposed) — Write “IID” — not “i.i.d.” or “iid” (30 / 348 lectures, 61 occurrences)#
lecture-python.myst15 / 145 ·lecture-python-advanced.myst10 / 68 ·lecture-dp4 / 52 ·lecture-python-intro1 / 56
22. qe-code-003 — Package installation at lecture top (25 / 348 lectures, 32 occurrences)#
lecture-python.myst8 / 145 ·lecture-dp6 / 52 ·lecture-python-advanced.myst6 / 68 ·lecture-python-programming3 / 27 ·lecture-python-intro2 / 56
23. qe-math-001 — Prefer UTF-8 unicode for simple parameter mentions, be consistent (15 / 348 lectures, 28 occurrences)#
lecture-python.myst9 / 145 ·lecture-dp3 / 52 ·lecture-python-advanced.myst1 / 68 ·lecture-python-intro1 / 56 ·lecture-python-programming1 / 27
24. qe-fig-007 — Keep figure box and spines (13 / 348 lectures, 71 occurrences)#
lecture-python-intro6 / 56 ·lecture-python.myst4 / 145 ·lecture-python-advanced.myst2 / 68 ·lecture-python-programming1 / 27
25. qe-link-001 — Use markdown style links for lectures in same lecture series (12 / 348 lectures, 21 occurrences)#
lecture-python.myst7 / 145 ·lecture-python-advanced.myst3 / 68 ·lecture-python-intro2 / 56
26. qe-math-005 — Use curly brackets for sequences (7 / 348 lectures, 14 occurrences)#
lecture-python.myst3 / 145 ·lecture-dp2 / 52 ·lecture-python-advanced.myst1 / 68 ·lecture-python-intro1 / 56
27. qe-code-005 — Use quantecon timeit for benchmarking (7 / 348 lectures, 13 occurrences)#
lecture-dp3 / 52 ·lecture-python.myst3 / 145 ·lecture-python-advanced.myst1 / 68
28. qe-math-013 (proposed) — Reference equations via {eq}`label` (6 / 348 lectures, 6 occurrences)#
lecture-dp3 / 52 ·lecture-python-advanced.myst2 / 68 ·lecture-python.myst1 / 145
29. qe-math-006 — Use aligned environment correctly for PDF compatibility (5 / 348 lectures, 14 occurrences)#
lecture-python.myst3 / 145 ·lecture-dp1 / 52 ·lecture-python-advanced.myst1 / 68
30. qe-math-012 (proposed) — Multiplication via \cdot or juxtaposition, never * (4 / 348 lectures, 6 occurrences)#
lecture-python-intro2 / 56 ·lecture-python-programming1 / 27 ·lecture-python.myst1 / 145
31. qe-fig-010 — Plotly figures require latex directive (4 / 348 lectures, 4 occurrences)#
lecture-python-advanced.myst3 / 68 ·lecture-python.myst1 / 145
32. qe-math-008 — Explain special notation (vectors/matrices) (3 / 348 lectures, 3 occurrences)#
lecture-dp1 / 52 ·lecture-python-advanced.myst1 / 68 ·lecture-python.myst1 / 145
34. qe-admon-003 — Use tick count management for nested directives (1 / 348 lectures, 2 occurrences)#
lecture-python-programming1 / 27
35. qe-admon-002 — Use dropdown class for solutions (1 / 348 lectures, 1 occurrences)#
lecture-python-intro1 / 56
All HIGH-priority lectures#
HIGH = overall ≤ 5.0 or any single in-scope category ≤ 4 (spec §4). In this pass every HIGH lecture was triggered by the category floor; none has an overall at or below 5.0. The Floor column is the weakest category’s score — the thing to fix.
Series |
Lecture |
Writing |
Math |
Code |
Figures |
References |
Links |
Admon |
Overall |
Floor |
|---|---|---|---|---|---|---|---|---|---|---|
python.myst |
3.5 |
3.0 |
— |
— |
— |
10.0 |
— |
5.5 |
3.0 |
|
advanced |
3.0 |
3.0 |
— |
— |
8.5 |
8.0 |
— |
5.6 |
3.0 |
|
dp |
4.0 |
3.0 |
— |
— |
— |
10.0 |
— |
5.7 |
3.0 |
|
python.myst |
3.0 |
3.0 |
7.5 |
— |
— |
10.0 |
— |
5.9 |
3.0 |
|
dp |
3.0 |
3.0 |
7.5 |
5.0 |
10.0 |
7.5 |
— |
6.0 |
3.0 |
|
advanced |
3.0 |
3.0 |
— |
7.0 |
8.5 |
8.5 |
— |
6.0 |
3.0 |
|
advanced |
3.0 |
3.0 |
7.5 |
5.0 |
10.0 |
7.5 |
— |
6.0 |
3.0 |
|
python.myst |
3.0 |
6.5 |
7.5 |
3.0 |
— |
10.0 |
— |
6.0 |
3.0 |
|
python.myst |
3.0 |
4.5 |
6.5 |
3.0 |
10.0 |
9.0 |
— |
6.0 |
3.0 |
|
advanced |
3.0 |
3.0 |
6.0 |
9.0 |
7.5 |
8.0 |
— |
6.1 |
3.0 |
|
advanced |
3.0 |
9.5 |
4.5 |
3.0 |
8.5 |
8.0 |
— |
6.1 |
3.0 |
|
python.myst |
4.5 |
3.5 |
7.5 |
5.0 |
— |
10.0 |
— |
6.1 |
3.5 |
|
python.myst |
3.0 |
3.0 |
5.5 |
5.0 |
— |
10.0 |
10.0 |
6.1 |
3.0 |
|
advanced |
3.0 |
6.0 |
7.0 |
4.0 |
7.0 |
10.0 |
— |
6.2 |
3.0 |
|
python.myst |
5.5 |
3.0 |
6.0 |
3.0 |
10.0 |
10.0 |
— |
6.2 |
3.0 |
|
dp |
4.5 |
4.0 |
7.0 |
6.0 |
7.5 |
9.0 |
— |
6.3 |
4.0 |
|
advanced |
5.0 |
3.0 |
7.0 |
5.5 |
8.5 |
9.0 |
— |
6.3 |
3.0 |
|
advanced |
4.0 |
4.5 |
7.0 |
6.0 |
7.5 |
9.0 |
— |
6.3 |
4.0 |
|
dp |
5.0 |
3.0 |
7.5 |
5.5 |
8.5 |
9.0 |
— |
6.4 |
3.0 |
|
advanced |
3.0 |
3.0 |
5.5 |
7.5 |
8.5 |
7.5 |
10.0 |
6.4 |
3.0 |
|
advanced |
3.5 |
4.0 |
6.5 |
8.0 |
9.0 |
7.5 |
— |
6.4 |
3.5 |
|
advanced |
5.0 |
3.5 |
7.5 |
4.0 |
8.5 |
10.0 |
— |
6.4 |
3.5 |
|
python.myst |
3.0 |
6.5 |
7.5 |
5.0 |
— |
10.0 |
— |
6.4 |
3.0 |
|
dp |
3.0 |
4.0 |
7.5 |
5.5 |
10.0 |
9.0 |
— |
6.5 |
3.0 |
|
dp |
3.0 |
6.0 |
8.5 |
5.0 |
— |
10.0 |
— |
6.5 |
3.0 |
|
dp |
5.5 |
3.5 |
7.5 |
4.0 |
8.5 |
10.0 |
— |
6.5 |
3.5 |
|
advanced |
3.0 |
3.0 |
7.0 |
4.0 |
10.0 |
8.5 |
10.0 |
6.5 |
3.0 |
|
python.myst |
3.0 |
3.0 |
6.0 |
8.0 |
— |
9.0 |
10.0 |
6.5 |
3.0 |
|
python.myst |
3.0 |
3.0 |
7.5 |
5.5 |
— |
10.0 |
10.0 |
6.5 |
3.0 |
|
python.myst |
3.0 |
4.0 |
7.5 |
5.5 |
10.0 |
9.0 |
— |
6.5 |
3.0 |
|
dp |
3.0 |
4.5 |
8.5 |
6.0 |
10.0 |
7.5 |
— |
6.6 |
3.0 |
|
dp |
3.0 |
3.0 |
7.5 |
4.5 |
10.0 |
8.0 |
10.0 |
6.6 |
3.0 |
|
advanced |
5.5 |
3.5 |
7.0 |
3.5 |
9.0 |
7.5 |
10.0 |
6.6 |
3.5 |
|
advanced |
3.0 |
4.5 |
8.5 |
6.0 |
10.0 |
7.5 |
— |
6.6 |
3.0 |
|
python.myst |
3.0 |
3.0 |
7.0 |
3.5 |
10.0 |
10.0 |
10.0 |
6.6 |
3.0 |
|
dp |
3.0 |
3.0 |
7.0 |
— |
10.0 |
7.5 |
10.0 |
6.8 |
3.0 |
|
advanced |
3.5 |
5.5 |
7.5 |
6.0 |
8.5 |
10.0 |
— |
6.8 |
3.5 |
|
advanced |
3.5 |
4.0 |
7.5 |
5.0 |
10.0 |
7.5 |
10.0 |
6.8 |
3.5 |
|
advanced |
3.0 |
3.0 |
7.5 |
6.5 |
10.0 |
7.5 |
10.0 |
6.8 |
3.0 |
|
python.myst |
3.0 |
3.0 |
7.0 |
— |
10.0 |
7.5 |
10.0 |
6.8 |
3.0 |
|
python.myst |
3.0 |
7.5 |
6.0 |
4.5 |
— |
10.0 |
10.0 |
6.8 |
3.0 |
|
dp |
3.0 |
3.0 |
6.5 |
7.0 |
8.5 |
10.0 |
10.0 |
6.9 |
3.0 |
|
advanced |
5.5 |
3.0 |
6.0 |
5.5 |
8.5 |
10.0 |
10.0 |
6.9 |
3.0 |
|
python.myst |
3.0 |
3.0 |
7.0 |
7.0 |
8.5 |
10.0 |
10.0 |
6.9 |
3.0 |
|
python.myst |
3.0 |
4.5 |
7.5 |
5.5 |
10.0 |
7.5 |
10.0 |
6.9 |
3.0 |
|
python.myst |
3.0 |
4.5 |
7.5 |
6.5 |
8.5 |
8.0 |
10.0 |
6.9 |
3.0 |
|
python.myst |
3.0 |
3.0 |
5.5 |
6.5 |
10.0 |
10.0 |
10.0 |
6.9 |
3.0 |
|
python.myst |
3.5 |
6.5 |
7.5 |
7.0 |
— |
10.0 |
— |
6.9 |
3.5 |
|
python.myst |
3.5 |
— |
7.5 |
4.5 |
— |
9.0 |
10.0 |
6.9 |
3.5 |
|
python.myst |
3.0 |
4.5 |
7.0 |
7.0 |
— |
10.0 |
10.0 |
6.9 |
3.0 |
|
dp |
3.5 |
5.5 |
8.5 |
6.0 |
8.5 |
10.0 |
— |
7.0 |
3.5 |
|
dp |
3.0 |
4.0 |
7.5 |
6.0 |
8.5 |
10.0 |
10.0 |
7.0 |
3.0 |
|
advanced |
4.0 |
6.0 |
7.0 |
5.5 |
9.0 |
7.5 |
10.0 |
7.0 |
4.0 |
|
advanced |
3.0 |
3.0 |
7.0 |
7.0 |
9.0 |
10.0 |
10.0 |
7.0 |
3.0 |
|
python.myst |
3.0 |
7.0 |
7.5 |
5.0 |
7.5 |
9.0 |
10.0 |
7.0 |
3.0 |
|
python.myst |
3.0 |
4.0 |
7.5 |
6.0 |
8.5 |
10.0 |
10.0 |
7.0 |
3.0 |
|
python.myst |
3.5 |
6.0 |
7.5 |
4.5 |
7.5 |
10.0 |
10.0 |
7.0 |
3.5 |
|
python.myst |
3.0 |
6.0 |
7.5 |
5.0 |
9.0 |
8.5 |
10.0 |
7.0 |
3.0 |
|
dp |
4.0 |
7.0 |
6.5 |
6.0 |
9.0 |
7.0 |
10.0 |
7.1 |
4.0 |
|
dp |
4.0 |
5.0 |
8.5 |
5.0 |
10.0 |
7.5 |
10.0 |
7.1 |
4.0 |
|
dp |
3.5 |
6.0 |
7.5 |
4.0 |
10.0 |
9.0 |
10.0 |
7.1 |
3.5 |
|
advanced |
3.0 |
7.5 |
7.5 |
4.5 |
10.0 |
10.0 |
— |
7.1 |
3.0 |
|
advanced |
3.5 |
5.5 |
7.5 |
5.5 |
7.5 |
10.0 |
10.0 |
7.1 |
3.5 |
|
advanced |
3.0 |
5.5 |
7.5 |
7.0 |
8.5 |
8.0 |
10.0 |
7.1 |
3.0 |
|
advanced |
4.0 |
5.5 |
7.5 |
4.0 |
10.0 |
9.0 |
10.0 |
7.1 |
4.0 |
|
programming |
3.0 |
— |
10.0 |
7.5 |
— |
8.0 |
— |
7.1 |
3.0 |
|
python.myst |
3.0 |
3.5 |
8.0 |
6.5 |
10.0 |
9.0 |
10.0 |
7.1 |
3.0 |
|
python.myst |
3.5 |
3.0 |
6.5 |
7.0 |
10.0 |
10.0 |
10.0 |
7.1 |
3.0 |
|
dp |
3.5 |
5.5 |
8.5 |
5.5 |
7.5 |
10.0 |
10.0 |
7.2 |
3.5 |
|
dp |
3.0 |
5.5 |
8.5 |
7.0 |
8.5 |
8.0 |
10.0 |
7.2 |
3.0 |
|
dp |
4.0 |
5.5 |
7.5 |
6.0 |
10.0 |
10.0 |
— |
7.2 |
4.0 |
|
dp |
3.0 |
7.0 |
6.5 |
6.0 |
10.0 |
8.0 |
10.0 |
7.2 |
3.0 |
|
advanced |
3.5 |
3.0 |
6.0 |
8.0 |
10.0 |
10.0 |
10.0 |
7.2 |
3.0 |
|
advanced |
5.5 |
4.0 |
8.5 |
7.0 |
8.5 |
10.0 |
— |
7.2 |
4.0 |
|
advanced |
4.0 |
7.5 |
7.5 |
8.0 |
8.5 |
8.0 |
— |
7.2 |
4.0 |
|
advanced |
5.0 |
3.0 |
9.0 |
3.5 |
10.0 |
10.0 |
10.0 |
7.2 |
3.0 |
|
intro |
3.0 |
8.5 |
7.5 |
4.0 |
— |
10.0 |
10.0 |
7.2 |
3.0 |
|
intro |
4.0 |
6.0 |
7.0 |
5.0 |
8.5 |
10.0 |
10.0 |
7.2 |
4.0 |
|
programming |
3.0 |
9.0 |
7.5 |
6.5 |
— |
10.0 |
7.5 |
7.2 |
3.0 |
|
python.myst |
3.0 |
3.0 |
7.5 |
7.0 |
10.0 |
10.0 |
10.0 |
7.2 |
3.0 |
|
python.myst |
3.0 |
7.5 |
6.0 |
6.0 |
10.0 |
8.0 |
10.0 |
7.2 |
3.0 |
|
python.myst |
4.5 |
3.0 |
7.5 |
5.5 |
10.0 |
10.0 |
10.0 |
7.2 |
3.0 |
|
python.myst |
6.5 |
5.5 |
4.5 |
4.0 |
10.0 |
10.0 |
10.0 |
7.2 |
4.0 |
|
dp |
3.5 |
3.5 |
8.0 |
6.0 |
10.0 |
10.0 |
10.0 |
7.3 |
3.5 |
|
dp |
4.0 |
5.0 |
8.5 |
4.5 |
9.0 |
10.0 |
10.0 |
7.3 |
4.0 |
|
advanced |
4.0 |
4.0 |
7.0 |
6.0 |
10.0 |
10.0 |
10.0 |
7.3 |
4.0 |
|
advanced |
3.0 |
8.0 |
5.0 |
5.0 |
10.0 |
10.0 |
10.0 |
7.3 |
3.0 |
|
advanced |
3.0 |
7.5 |
7.5 |
7.0 |
9.0 |
10.0 |
— |
7.3 |
3.0 |
|
intro |
3.0 |
10.0 |
7.5 |
3.0 |
7.5 |
10.0 |
10.0 |
7.3 |
3.0 |
|
programming |
3.0 |
— |
7.0 |
6.5 |
— |
10.0 |
10.0 |
7.3 |
3.0 |
|
programming |
3.5 |
— |
8.5 |
4.5 |
— |
10.0 |
10.0 |
7.3 |
3.5 |
|
python.myst |
3.0 |
3.0 |
7.5 |
7.5 |
10.0 |
10.0 |
10.0 |
7.3 |
3.0 |
|
python.myst |
3.0 |
3.0 |
7.0 |
8.0 |
10.0 |
10.0 |
10.0 |
7.3 |
3.0 |
|
python.myst |
4.0 |
4.0 |
7.5 |
9.5 |
9.0 |
10.0 |
— |
7.3 |
4.0 |
|
python.myst |
3.0 |
5.0 |
7.5 |
7.0 |
8.5 |
10.0 |
10.0 |
7.3 |
3.0 |
|
dp |
4.0 |
3.0 |
6.5 |
8.0 |
10.0 |
10.0 |
10.0 |
7.4 |
3.0 |
|
dp |
4.0 |
3.0 |
7.5 |
7.0 |
10.0 |
10.0 |
10.0 |
7.4 |
3.0 |
|
dp |
3.0 |
9.0 |
7.5 |
5.0 |
9.0 |
8.0 |
10.0 |
7.4 |
3.0 |
|
advanced |
3.0 |
7.5 |
7.0 |
6.0 |
10.0 |
8.0 |
10.0 |
7.4 |
3.0 |
|
advanced |
4.5 |
3.5 |
10.0 |
— |
8.5 |
8.0 |
10.0 |
7.4 |
3.5 |
|
advanced |
4.0 |
3.0 |
7.0 |
9.0 |
9.0 |
10.0 |
10.0 |
7.4 |
3.0 |
|
advanced |
4.0 |
3.0 |
10.0 |
7.0 |
10.0 |
8.0 |
10.0 |
7.4 |
3.0 |
|
intro |
3.5 |
10.0 |
7.5 |
3.5 |
— |
10.0 |
10.0 |
7.4 |
3.5 |
|
intro |
3.0 |
10.0 |
6.0 |
4.5 |
8.5 |
10.0 |
10.0 |
7.4 |
3.0 |
|
intro |
6.0 |
3.0 |
7.0 |
7.5 |
9.0 |
9.0 |
10.0 |
7.4 |
3.0 |
|
intro |
3.0 |
6.0 |
7.5 |
7.0 |
10.0 |
8.0 |
10.0 |
7.4 |
3.0 |
|
python.myst |
4.5 |
4.0 |
8.5 |
5.5 |
9.0 |
10.0 |
10.0 |
7.4 |
4.0 |
|
python.myst |
3.5 |
3.0 |
8.5 |
7.5 |
9.0 |
10.0 |
10.0 |
7.4 |
3.0 |
|
python.myst |
4.5 |
4.0 |
10.0 |
8.5 |
— |
10.0 |
— |
7.4 |
4.0 |
|
python.myst |
3.0 |
9.5 |
7.5 |
4.0 |
7.5 |
10.0 |
10.0 |
7.4 |
3.0 |
|
python.myst |
4.0 |
5.0 |
7.0 |
6.0 |
10.0 |
10.0 |
10.0 |
7.4 |
4.0 |
|
python.myst |
3.0 |
9.0 |
7.5 |
5.0 |
9.0 |
8.5 |
10.0 |
7.4 |
3.0 |
|
python.myst |
3.5 |
5.5 |
6.5 |
6.0 |
10.0 |
10.0 |
10.0 |
7.4 |
3.5 |
|
python.myst |
3.0 |
5.5 |
7.5 |
6.5 |
9.0 |
10.0 |
10.0 |
7.4 |
3.0 |
|
advanced |
3.0 |
9.0 |
8.5 |
6.0 |
8.5 |
10.0 |
— |
7.5 |
3.0 |
|
advanced |
4.0 |
4.0 |
5.0 |
9.5 |
10.0 |
10.0 |
10.0 |
7.5 |
4.0 |
|
advanced |
3.0 |
8.5 |
7.5 |
7.0 |
9.0 |
10.0 |
— |
7.5 |
3.0 |
|
advanced |
4.0 |
3.0 |
7.5 |
8.0 |
10.0 |
10.0 |
10.0 |
7.5 |
3.0 |
|
programming |
3.0 |
— |
7.5 |
7.0 |
— |
10.0 |
10.0 |
7.5 |
3.0 |
|
programming |
3.0 |
8.0 |
7.0 |
7.0 |
— |
10.0 |
10.0 |
7.5 |
3.0 |
|
python.myst |
3.0 |
6.0 |
10.0 |
6.0 |
10.0 |
10.0 |
— |
7.5 |
3.0 |
|
python.myst |
3.0 |
4.0 |
6.0 |
9.5 |
10.0 |
10.0 |
10.0 |
7.5 |
3.0 |
|
python.myst |
3.0 |
8.5 |
7.5 |
4.5 |
10.0 |
9.0 |
10.0 |
7.5 |
3.0 |
|
dp |
3.0 |
9.5 |
7.0 |
7.0 |
9.0 |
10.0 |
— |
7.6 |
3.0 |
|
programming |
4.0 |
10.0 |
7.0 |
4.5 |
— |
10.0 |
10.0 |
7.6 |
4.0 |
|
programming |
3.0 |
7.5 |
8.5 |
7.5 |
— |
9.0 |
10.0 |
7.6 |
3.0 |
|
python.myst |
5.0 |
10.0 |
8.0 |
4.0 |
8.5 |
10.0 |
— |
7.6 |
4.0 |
|
python.myst |
3.0 |
9.0 |
7.5 |
4.0 |
10.0 |
10.0 |
10.0 |
7.6 |
3.0 |
|
python.myst |
6.0 |
3.0 |
7.0 |
9.5 |
10.0 |
10.0 |
— |
7.6 |
3.0 |
|
python.myst |
3.5 |
7.5 |
6.5 |
6.0 |
10.0 |
10.0 |
10.0 |
7.6 |
3.5 |
|
python.myst |
3.0 |
7.0 |
7.5 |
7.5 |
10.0 |
8.0 |
10.0 |
7.6 |
3.0 |
|
dp |
3.0 |
10.0 |
8.5 |
6.0 |
8.5 |
10.0 |
— |
7.7 |
3.0 |
|
dp |
3.0 |
7.5 |
8.0 |
7.5 |
10.0 |
8.0 |
10.0 |
7.7 |
3.0 |
|
intro |
4.0 |
7.5 |
7.0 |
6.5 |
9.0 |
10.0 |
10.0 |
7.7 |
4.0 |
|
programming |
3.0 |
— |
8.5 |
7.0 |
— |
10.0 |
10.0 |
7.7 |
3.0 |
|
python.myst |
3.0 |
7.5 |
8.5 |
8.0 |
9.0 |
10.0 |
— |
7.7 |
3.0 |
|
python.myst |
3.0 |
9.5 |
8.5 |
6.0 |
10.0 |
7.0 |
10.0 |
7.7 |
3.0 |
|
python.myst |
3.0 |
7.0 |
7.5 |
6.5 |
10.0 |
10.0 |
10.0 |
7.7 |
3.0 |
|
python.myst |
3.0 |
10.0 |
8.5 |
5.0 |
7.5 |
10.0 |
10.0 |
7.7 |
3.0 |
|
advanced |
4.0 |
8.5 |
6.5 |
9.0 |
8.5 |
10.0 |
— |
7.8 |
4.0 |
|
advanced |
3.0 |
6.5 |
8.5 |
8.5 |
10.0 |
8.0 |
10.0 |
7.8 |
3.0 |
|
intro |
4.0 |
9.0 |
6.5 |
5.0 |
10.0 |
10.0 |
10.0 |
7.8 |
4.0 |
|
intro |
4.0 |
8.0 |
7.0 |
8.0 |
— |
10.0 |
10.0 |
7.8 |
4.0 |
|
intro |
3.0 |
9.5 |
6.0 |
6.0 |
10.0 |
10.0 |
10.0 |
7.8 |
3.0 |
|
programming |
3.0 |
7.5 |
8.5 |
8.0 |
— |
10.0 |
10.0 |
7.8 |
3.0 |
|
programming |
3.0 |
9.5 |
7.0 |
7.5 |
— |
10.0 |
10.0 |
7.8 |
3.0 |
|
python.myst |
3.0 |
7.5 |
7.5 |
9.0 |
— |
10.0 |
10.0 |
7.8 |
3.0 |
|
python.myst |
5.5 |
4.0 |
7.5 |
7.5 |
10.0 |
10.0 |
10.0 |
7.8 |
4.0 |
|
python.myst |
4.0 |
9.5 |
7.0 |
7.0 |
9.0 |
10.0 |
— |
7.8 |
4.0 |
|
python.myst |
4.0 |
9.5 |
7.0 |
6.0 |
— |
10.0 |
10.0 |
7.8 |
4.0 |
|
python.myst |
3.0 |
8.5 |
7.0 |
6.0 |
10.0 |
10.0 |
10.0 |
7.8 |
3.0 |
|
python.myst |
3.0 |
9.5 |
7.5 |
6.5 |
— |
10.0 |
10.0 |
7.8 |
3.0 |
|
python.myst |
3.0 |
9.5 |
— |
— |
7.5 |
9.0 |
10.0 |
7.8 |
3.0 |
|
dp |
3.5 |
9.5 |
7.5 |
5.5 |
9.0 |
10.0 |
10.0 |
7.9 |
3.5 |
|
dp |
6.5 |
3.0 |
7.5 |
8.0 |
10.0 |
10.0 |
10.0 |
7.9 |
3.0 |
|
advanced |
4.0 |
6.0 |
7.0 |
8.5 |
10.0 |
10.0 |
10.0 |
7.9 |
4.0 |
|
intro |
3.0 |
9.5 |
7.0 |
5.5 |
10.0 |
10.0 |
10.0 |
7.9 |
3.0 |
|
intro |
4.0 |
10.0 |
7.0 |
6.0 |
8.5 |
10.0 |
10.0 |
7.9 |
4.0 |
|
intro |
3.0 |
9.5 |
6.5 |
6.5 |
10.0 |
10.0 |
10.0 |
7.9 |
3.0 |
|
intro |
3.5 |
8.0 |
7.5 |
6.0 |
10.0 |
10.0 |
10.0 |
7.9 |
3.5 |
|
python.myst |
3.0 |
7.5 |
10.0 |
7.0 |
— |
10.0 |
10.0 |
7.9 |
3.0 |
|
python.myst |
3.5 |
7.0 |
7.5 |
7.5 |
10.0 |
10.0 |
10.0 |
7.9 |
3.5 |
|
python.myst |
4.0 |
5.5 |
8.5 |
7.5 |
10.0 |
10.0 |
10.0 |
7.9 |
4.0 |
|
python.myst |
3.5 |
9.5 |
8.0 |
4.5 |
10.0 |
10.0 |
10.0 |
7.9 |
3.5 |
|
python.myst |
3.5 |
5.0 |
7.5 |
10.0 |
9.0 |
10.0 |
10.0 |
7.9 |
3.5 |
|
python.myst |
3.5 |
9.0 |
6.5 |
6.0 |
10.0 |
10.0 |
10.0 |
7.9 |
3.5 |
|
dp |
4.0 |
9.0 |
7.5 |
9.0 |
8.5 |
10.0 |
— |
8.0 |
4.0 |
|
dp |
3.0 |
9.0 |
7.5 |
6.5 |
10.0 |
10.0 |
10.0 |
8.0 |
3.0 |
|
dp |
3.5 |
9.5 |
7.5 |
6.5 |
9.0 |
10.0 |
10.0 |
8.0 |
3.5 |
|
intro |
3.5 |
6.5 |
7.5 |
8.5 |
10.0 |
10.0 |
10.0 |
8.0 |
3.5 |
|
intro |
3.5 |
10.0 |
6.0 |
6.5 |
10.0 |
10.0 |
10.0 |
8.0 |
3.5 |
|
programming |
3.0 |
— |
10.0 |
7.0 |
— |
10.0 |
10.0 |
8.0 |
3.0 |
|
python.myst |
3.0 |
8.5 |
10.0 |
5.5 |
9.0 |
10.0 |
10.0 |
8.0 |
3.0 |
|
python.myst |
3.0 |
9.5 |
8.5 |
6.0 |
10.0 |
9.0 |
10.0 |
8.0 |
3.0 |
|
python.myst |
4.0 |
10.0 |
7.5 |
5.5 |
9.0 |
10.0 |
10.0 |
8.0 |
4.0 |
|
python.myst |
3.0 |
10.0 |
7.5 |
6.5 |
9.0 |
10.0 |
10.0 |
8.0 |
3.0 |
|
python.myst |
4.0 |
9.5 |
6.5 |
7.5 |
8.5 |
10.0 |
10.0 |
8.0 |
4.0 |
|
programming |
3.0 |
10.0 |
7.5 |
8.0 |
— |
10.0 |
10.0 |
8.1 |
3.0 |
|
programming |
4.0 |
8.0 |
8.5 |
10.0 |
— |
8.0 |
10.0 |
8.1 |
4.0 |
|
python.myst |
3.5 |
10.0 |
8.5 |
5.0 |
10.0 |
10.0 |
10.0 |
8.1 |
3.5 |
|
python.myst |
4.0 |
10.0 |
7.5 |
5.5 |
10.0 |
10.0 |
10.0 |
8.1 |
4.0 |
|
python.myst |
3.0 |
9.5 |
7.5 |
6.5 |
10.0 |
10.0 |
10.0 |
8.1 |
3.0 |
|
python.myst |
3.5 |
9.5 |
7.5 |
— |
10.0 |
10.0 |
— |
8.1 |
3.5 |
|
python.myst |
3.0 |
9.5 |
8.0 |
6.5 |
10.0 |
10.0 |
10.0 |
8.1 |
3.0 |
|
programming |
3.0 |
10.0 |
8.5 |
7.5 |
— |
10.0 |
10.0 |
8.2 |
3.0 |
|
programming |
4.0 |
— |
9.0 |
— |
— |
10.0 |
10.0 |
8.2 |
4.0 |
|
programming |
3.0 |
— |
10.0 |
8.5 |
— |
10.0 |
10.0 |
8.3 |
3.0 |
|
programming |
3.0 |
10.0 |
8.5 |
8.5 |
— |
10.0 |
10.0 |
8.3 |
3.0 |
|
programming |
3.0 |
10.0 |
8.5 |
— |
— |
10.0 |
10.0 |
8.3 |
3.0 |
|
python.myst |
3.0 |
10.0 |
7.0 |
— |
10.0 |
10.0 |
10.0 |
8.3 |
3.0 |
|
intro |
4.0 |
10.0 |
7.5 |
7.0 |
10.0 |
10.0 |
10.0 |
8.4 |
4.0 |
|
dp |
3.0 |
10.0 |
8.5 |
9.5 |
10.0 |
10.0 |
— |
8.5 |
3.0 |
|
advanced |
3.0 |
10.0 |
8.5 |
9.5 |
10.0 |
10.0 |
— |
8.5 |
3.0 |
|
intro |
4.0 |
10.0 |
8.5 |
7.0 |
10.0 |
10.0 |
10.0 |
8.5 |
4.0 |
|
python.myst |
3.0 |
9.5 |
8.5 |
10.0 |
8.5 |
10.0 |
10.0 |
8.5 |
3.0 |
|
python.myst |
4.0 |
9.5 |
7.0 |
9.0 |
10.0 |
10.0 |
10.0 |
8.5 |
4.0 |
|
programming |
3.5 |
10.0 |
10.0 |
9.0 |
— |
10.0 |
10.0 |
8.8 |
3.5 |
Remediation plan#
Ordered by return on effort. The first block is mechanical and can be scripted; the second needs a reading pass; the third is small and structural.
1. Scriptable sweeps — do these first#
Figure names (
qe-fig-005) — addmystnb.figure.namemetadata to every figure-producing code cell and:name:to every{figure}/{image}directive. Reaches the largest share of the corpus of any single rule and unlocks{numref}cross-referencing.Greek letters in code (
qe-code-002) —alpha→αand friends, in code cells only.lecture-python-programmingis already fully compliant and is the model.Line widths (
qe-fig-008) — addlw=2to line plots.Figure sizes (
qe-fig-001) — dropfigsize=overrides and let the series_config.ymldefaults apply; keep only where a plot genuinely needs a different aspect.Excess whitespace (
qe-writing-008) — collapse runs of spaces between words. The single largest raw count in the corpus, and entirely safe to automate.Heading capitalisation (
qe-writing-006) — H2 and below to sentence case. Needs a proper-noun allowlist;tools/qestyle_rules.pyalready carries one curated from this corpus.Transpose and expectation notation (
qe-math-002,qe-math-010(proposed)) —'and^T→^\top; bareE[·]→\mathbb{E}[·]. Concentrated in the older LQ and filtering lectures oflecture-python-advanced.mystandlecture-dp, so it is best done as one careful pass over that cluster rather than corpus-wide.Cross-series links (
qe-link-002) — raw*.quantecon.orgURLs →{doc}with the intersphinx prefix.
2. Needs a reading pass#
Plot titles → captions (
qe-fig-003) —ax.set_title(...)moved into the figure caption. Mechanical to find, but each caption has to be written. Titles insideexercise/solutionregions are exempt and are already excluded from the counts.Caption conventions (
qe-fig-004) — sentence case, six words or fewer. The only rule that got materially worse since the previous pass.Narrative citations (
qe-ref-001) —{cite}→{cite:t}where the author name is part of the sentence. Needs judgment on each site.One sentence per paragraph (
qe-writing-001) — splitting a paragraph changes its rhythm, so this is an editorial pass, not a sweep.
3. Structural — small and worth doing now#
The four findings on the front page: two unclosed
{exercise-start}fences, two malformed{eq}` `references, and a raw\label{}inside$$.Shared lectures between
lecture-dpandlecture-python.myst. 31 filenames appear in both series, but only 6 are byte-identical at this snapshot:cross_product_trick,ifp_discrete,ifp_opi,lq_inventories,mccall_model_with_separation,os_numerical. Those 6 account for 217 of the corpus’s 18,587 findings — 1.2 % genuinely counted twice, which is the honest size of the double-count. The other 25 share an origin and have diverged, so their findings are about different files even where the defect is the same. For the identical 6, fix upstream and both clear; for the diverged 25, each copy needs its own fix. Worth a decision on whether the corpus totals should de-duplicate the 6 — #3.
Corrections to the previous pass#
This pass re-measured the corpus with a program rather than by reading, which surfaced several defects in the previous report. They are listed here rather than quietly dropped, because they say something about how a pass should be run.
What the previous pass said |
What re-measurement found |
|---|---|
|
There is no |
299 lectures audited |
299 reports were written, but one of them ( |
Per-lecture overall scores |
94 of 299 headers did not equal the mean of their own in-scope categories, which is how spec §4 defines the overall score. Discrepancies ran up to 1.2 points. |
Per-lecture priority buckets |
35 of 299 did not follow spec §4 from their own scores — mostly lectures with a category at 4 that were filed MEDIUM rather than HIGH. |
|
The same series was reported as having |
|
|
None of these are surprising for a pass done by reading 299 files. They are the reason the
mechanical layer now exists, and the reason tools/qestyle_check.py runs as a gate: every
row above corresponds to a check that now fails loudly.
Coverage and its limits#
41 of 49 rules are measured by program (36 of the 42 in-scope registry rules plus 5 of the 7 proposed); the 8 judgment-only rules (spec §9) are reviewed by reading. A category scoring 10 means no mechanical violation was measured, not that every rule in it was verified by a human.
Review coverage is complete in this pass and was absent in the previous one, and scores depend on it. A lecture assessed against more rules scores lower. Every 2026-08 lecture folds in a judgment overlay, so the scoreboard above is comparable across series; the 2026-05 rows of
history.csvfold in none (itsreviewedcolumn), so score levels are not comparable across the two periods, and the front page says so with the like-for-like figures fromhistory_mechanical.csv— the evidence layer alone, on which the corpus improved. The rule-reach tables are unaffected, because those are measured over every lecture by the same code.Three checks are heuristic and say so where they fire:
qe-writing-004andqe-writing-006depend on curated proper-noun and common-noun lists, andqe-math-002has to distinguish a transpose apostrophe from a derivative and a^Ttranspose from a terminal date. They will need extending as the corpus grows.JAX is out of scope, not
N/A— the 7qe-jax-*rules targetlecture-jax, which is not part of this corpus.Counts are absolute, not per-line. A 2,000-line lecture and a 200-line lecture with the same number of violations of a rule score the same for it, which follows the spec’s severity definitions (§5) rather than any notion of density.