Fuenfte harte Nummer gefunden: eine Tabellenzelle - und die Pruefung dagegen

31_Unsicherheit.md trug in der Uebersicht "Die drei Ansaetze im Ueberblick"
noch die Zeile

    | Kapitel | 9.2 | 9.3 | 9.4 |

Die Abschnitte heissen in Version 04 aber 12.4 bis 12.6 - stehengebliebene
Version-03-Nummern, im PDF abgedruckt. Damit ist die Regel "keine
abgeleiteten Zahlen im Quelltext" zum fuenften Mal verletzt gefunden worden.

--check lief daran vorbei, weil der bestehende Ausdruck das Wort unmittelbar
vor der Zahl verlangt ((Kapitel|Abschnitt|...)\s+\d+). Hier steht "Kapitel"
als Zeilenkopf, durch " | " von der Zahl getrennt - \s+ matcht keinen
senkrechten Strich.

pruefe_dateien() bekommt daher eine zweite Pruefung: eine Tabellenzelle, die
nur aus einer Nummer der Form N.N besteht. Sie ueberspringt Codezaeune, weil
abgedruckte Programmausgaben ihre Spalten ebenfalls mit "|" setzen
(40_Finanzdaten.md Zeilen 381-385 waeren sonst fuenf Fehlalarme).

Gegengetestet: die wieder eingebaute Zeile wird mit allen drei Zellen
einzeln gemeldet, nach dem Rueckbau ist der Lauf sauber.

Die Zeile heisst jetzt "Nachzulesen in" und traegt drei {ref:sec:...};
Querverweise 703 -> 706. Referenzwerte in PROGRESS.md auf die gemessenen
Werte nachgezogen (27.015 Zeilen, 1512 KB) - sie lagen zwei Zeilen zurueck.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
dschlueter 2026-09-08 01:23:33 +02:00
commit 62952ba066
3 changed files with 60 additions and 4 deletions

View file

@ -267,7 +267,7 @@ Erwartungswert der Kosten ist größer als die Kosten des Erwartungswerts.
| Typische Frage | „Wie riskant ist dieser Plan?“ | „Was ist im Mittel am besten?“ | „Was hält auch im schlimmsten Fall?“ | | Typische Frage | „Wie riskant ist dieser Plan?“ | „Was ist im Mittel am besten?“ | „Was hält auch im schlimmsten Fall?“ |
| Stärke | beliebige Kennzahlen, sehr flexibel | nutzt Wahrscheinlichkeiten voll aus | keine Verteilungsannahme nötig | | Stärke | beliebige Kennzahlen, sehr flexibel | nutzt Wahrscheinlichkeiten voll aus | keine Verteilungsannahme nötig |
| Schwäche | keine Optimierung | Wahrscheinlichkeiten müssen stimmen | oft übervorsichtig, kostet Ertrag | | Schwäche | keine Optimierung | Wahrscheinlichkeiten müssen stimmen | oft übervorsichtig, kostet Ertrag |
| Kapitel | 9.2 | 9.3 | 9.4 | | Nachzulesen in | {ref:sec:unsicherheit-monte-carlo-simulation} | {ref:sec:unsicherheit-zweistufige-stochastische-programmierung} | {ref:sec:unsicherheit-robuste-optimierung-gegen-den-worst-case} |
--- ---

View file

@ -227,6 +227,32 @@ def pruefe_dateien() -> list[str]:
f"{{ref:...}}-Verweis oder ein Name.") f"{{ref:...}}-Verweis oder ein Name.")
fehlend.append(name) fehlend.append(name)
# Dieselbe Zahl, aber in einer Tabellenzelle - dort steht das Wort
# 'Kapitel' als Zeilenkopf und ist durch ' | ' von der Nummer getrennt, an
# dem \s+ oben vorbeilaeuft. Genau so ueberlebte '| Kapitel | 9.2 | 9.3 |
# 9.4 |' in 31_Unsicherheit.md den Umbau auf Version 04, wo dieselben
# Abschnitte 12.4 bis 12.6 heissen.
#
# Codezaeune werden uebersprungen: Abgedruckte Programmausgaben setzen
# Spalten ebenfalls mit '|' und enthalten legitime Zahlen wie '| 12.6 |'.
zelle_re = re.compile(r"^\d{1,2}\.\d{1,2}([ ,]+\d{1,2}\.\d{1,2})*$")
for name in DATEIEN:
with open(os.path.join(HIER, name), encoding="utf-8") as f:
inhalt = f.read()
im_codeblock = False
for nr, zeile in enumerate(inhalt.split("\n"), start=1):
if zeile.lstrip().startswith("```"):
im_codeblock = not im_codeblock
continue
if im_codeblock or not zeile.lstrip().startswith("|"):
continue
for zelle in zeile.strip().strip("|").split("|"):
if zelle_re.match(zelle.strip()):
print(f"FEHLER: {name}:{nr} hat die Tabellenzelle "
f"'{zelle.strip()}' - eine nackte Abschnittsnummer. "
f"Dorthin gehoert ein {{ref:...}}-Verweis.")
fehlend.append(name)
return fehlend return fehlend

View file

@ -77,11 +77,11 @@ sie unerwartet ab, ist etwas kaputtgegangen.
| Kapiteldateien | 22 | **31** | | Kapiteldateien | 22 | **31** |
| Kapitel | 15 | **23** | | Kapitel | 15 | **23** |
| Anhänge | 4 | **5** | | Anhänge | 4 | **5** |
| Zeilen im Gesamtdokument | 11 082 | **27 013** | | Zeilen im Gesamtdokument | 11 082 | **27 015** |
| Größe des Gesamtdokuments | 606 KB | **1 511 KB** | | Größe des Gesamtdokuments | 606 KB | **1 512 KB** |
| Hauptüberschriften | 131 | **276** | | Hauptüberschriften | 131 | **276** |
| registrierte Abschnitte | 122 | **292** | | registrierte Abschnitte | 122 | **292** |
| aufgelöste Querverweise | 314 | **703** (0 unaufgelöst) | | aufgelöste Querverweise | 314 | **706** (0 unaufgelöst) |
| Indexmarken | 295 | **325** | | Indexmarken | 295 | **325** |
| Beispielprogramme | 41 | **73** (alle lauffähig) | | Beispielprogramme | 41 | **73** (alle lauffähig) |
| PDF-Seiten | — | **715** | | PDF-Seiten | — | **715** |
@ -937,6 +937,36 @@ Datei, Zeile und Fund. Damit ist die Gegenprobe nicht mehr etwas, woran man denk
sondern Teil von `--check`. Gegengetestet: Eine künstlich eingefügte zweizeilige sondern Teil von `--check`. Gegengetestet: Eine künstlich eingefügte zweizeilige
`Aufgabe\n4.3` wird gefunden. `Aufgabe\n4.3` wird gefunden.
### Die fünfte harte Nummer: eine Tabellenzelle — gefunden in Phase 6 ✅
Beim Lesen von `31_Unsicherheit.md` für den Chance-Constraints-Abschnitt stand in der
Übersichtstabelle „Die drei Ansätze im Überblick“ die Zeile
```
| Kapitel | 9.2 | 9.3 | 9.4 |
```
Die Abschnitte heißen in Version 04 aber **12.4 bis 12.6** — es waren stehengebliebene
Version-03-Nummern, im PDF abgedruckt. Damit ist die Regel „keine abgeleiteten Zahlen im
Quelltext“ zum **fünften** Mal verletzt gefunden worden.
**Warum `--check` daran vorbeilief:** Der Ausdruck von damals verlangt das Wort unmittelbar
vor der Zahl (`(Kapitel|Abschnitt|…)\s+\d+`). Hier steht „Kapitel“ als *Zeilenkopf* und ist
durch ` | ` von der Zahl getrennt — `\s+` matcht keinen senkrechten Strich. Die Verschärfung
der vorigen Runde (Zwischenraum statt Leerzeichen) war also richtig und trotzdem nicht genug.
`pruefe_dateien()` hat jetzt eine **zweite** Prüfung: eine Tabellenzelle, die nur aus einer
Nummer der Form `N.N` besteht. Sie überspringt Codezäune — abgedruckte Programmausgaben
setzen ihre Spalten ebenfalls mit `|` und enthalten legitime Zahlen (`40_Finanzdaten.md`
Zeilen 381385 wären sonst fünf Fehlalarme). Gegengetestet: Die wieder eingebaute Zeile wird
mit allen drei Zellen einzeln gemeldet, nach dem Rückbau ist der Lauf sauber.
Die Zeile heißt jetzt „Nachzulesen in“ und trägt drei `{ref:sec:…}` — Querverweise 703 → 706.
**Die Lehre:** Die vier früheren Fälle steckten alle im Fließtext oder in Docstrings. Dieser
saß in einer Tabelle, also in genau der Struktur, die man beim Korrekturlesen überfliegt.
Beide Prüfungen zusammen decken Fließtext, Docstrings und Tabellen ab.
### VaR/CVaR-Diagramm — und ein Widerspruch, den es aufgedeckt hat ✅ ### VaR/CVaR-Diagramm — und ein Widerspruch, den es aufgedeckt hat ✅
Beim Nachbau des ersten Finanzdiagramms stellte sich heraus, dass **Bild und Text Beim Nachbau des ersten Finanzdiagramms stellte sich heraus, dass **Bild und Text