operations_research/CLAUDE.md
dschlueter 360912dbfa Aufgeraeumt: 33 PNG-Zweitfassungen, Bau-Ueberbleibsel, Ausgabepfade
Drei Aufraeumarbeiten - und zwei Funde, die dabei auffielen.

1. DIE PNG-ZWEITFASSUNGEN SIND WEG. Jedes Diagramm lag doppelt vor, als SVG
und als PNG, und kein einziges src=/href= in der Website zeigte je auf ein
PNG. Der Build kopierte sie trotzdem mit: 3,3 MB im Repository plus 3,3 MB,
die bei jeder Veroeffentlichung auf den Webserver gingen. Die 15 Generatoren
schreiben jetzt nur noch SVG, die Docstrings sind mitgezogen. Vor dem
Loeschen geprueft: Jedes PNG hatte sein gleichnamiges SVG, alle 33 waren
versioniert.

FUND 1: erzeuge_kap06_gantt.py folgte als einziger Generator nicht der
Konvention - weder svg.hashsalt noch metadata={"Date": None}. Sein SVG trug
einen echten Zeitstempel und bei jedem Lauf andere clip-path-IDs, war also
nie byteidentisch reproduzierbar, obwohl CLAUDE.md genau das fuer alle
Generatoren festhaelt. Aufgefallen nur, weil nach der PNG-Umstellung 32 von
33 SVGs bitgleich blieben und eines nicht. Jetzt byteidentisch ueber zwei
Laeufe.

FUND 2: spiegle_bilder() legte leere Verzeichnisse auf dem Webserver an. Der
Dateifilter arbeitete korrekt, aber os.walk durchlief auch __pycache__/, und
os.makedirs() erzeugte es am Ziel. Die Verzeichnisliste wird jetzt vorher
gefiltert. Gegengetestet.

2. BAU-UEBERBLEIBSEL entfernt (alle ignoriert und neu erzeugbar):
svg-inkscape/, build_v04.log, .pytest_cache/, Programme/output/, vier
__pycache__/ und die Excel-Mappen. Arbeitsbaum 36 -> 33 MB, danach null
ignorierte Ueberbleibsel.

3. Excel_Bruecke.py SCHREIBT NEBEN DAS SKRIPT statt ins
Arbeitsverzeichnis. Es benutzte blanke relative Namen; wer es aus der
Repository-Wurzel startete, verstreute dort produktionsmix.xlsx und
produktionsmix_ergebnis.xlsx. Jetzt wie die vier anderen schreibenden
Programme ueber os.path.dirname(os.path.abspath(__file__)). Nachgemessen:
Lauf aus der Wurzel legt dort null Dateien ab.

Ausserdem git gc: 653 lose Objekte gepackt, .git von 71 MB auf 28 MB -
reines Repacken, kein Inhalt beruehrt.

Geprueft: alle 33 im Buch referenzierten SVGs vorhanden, in Quelle und
Website; 16 Generatoren fehlerfrei; keine fehlenden Bilder im LaTeX-Lauf;
33 pytest-Tests; PDF unveraendert 760 Seiten.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-08 14:22:26 +02:00

8.6 KiB

CLAUDE.md

Kontext zum Repository Optimierte Entscheidungsfindung mit Python, Version 04.

Vor jeder Arbeit zuerst lesen

  • PLAN.md — das Ziel und der Weg dorthin: alle sechs Phasen, die Zielstruktur, der Kapitel-Baukasten, die dreizehn verbindlichen Regeln, die Verifikationsschritte. Ändert sich nur bei einem Kurswechsel.
  • PROGRESS.md — der erreichte Stand: eine Checkliste zur Wiederaufnahme, die Referenzwerte zum Gegenprüfen, was erledigt ist, welche Funde es unterwegs gab und was der konkret nächste Schritt ist. Wird nach jedem Arbeitsschritt fortgeschrieben.

Ohne diese beiden Dateien fehlt der Kontext, um sinnvoll weiterzuarbeiten — die Kapiteltexte allein verraten weder den Stand noch die Konventionen. Alle sechs Phasen sind abgeschlossen; PROGRESS.md Abschnitt 7 nennt, was bewusst offen geblieben ist und warum.


Struktur

Dieses Verzeichnis ist die Wurzel; alle Skripte leiten ihre Pfade daraus ab (BASIS = dirname(dirname(__file__)) bzw. dirname(HIER)).

Operations_Research_mit_Python_Version_04/     Quelle: 36 Kapiteldateien + Build-Skripte
bilder_04/                                     Quelle: Diagramme + erzeuge_*.py-Generatoren
Operations_Research_mit_Python_Version_04.md   generiert: Gesamtdokument
Operations_Research_mit_Python_Version_04.pdf  generiert: PDF (xelatex)
OR_HTML_04/                                    generiert: Mehrseiten-Website
Operations_Research_mit_Python_Version_04_Programme/  generiert: Beispielprogramme
Notebooks_04/                                  generiert: ein .ipynb je Kapitel
Kritik_und_Verbesserungsvorschlaege/           Quelle: Rezension, Verbesserungsvorschläge,
                                               NEUER_TITEL.md (Vorlage des Titelblatts)
pyproject.toml                                 Quelle: Abhängigkeiten in Gruppen
Dockerfile, .dockerignore                      Quelle: Kurs-Image (nur Programme)
pandoc-defaults-basis.yaml, pandoc/, pandoc-defaults-buch.yaml   PDF-Konfiguration

Nur die als Quelle markierten Verzeichnisse werden von Hand bearbeitet.

Dieses Verzeichnis ist seit dem 08.09.2026 ein eigenes Git-Repository (main). Das übergeordnete OR_mit_Python/ ist nur noch das Archiv der Historie bis zur Trennung und verwaltet aktiv allein Version_03; es trägt Version_04/ in seiner .gitignore. Commits gehören ab jetzt hierher.

Build

cd Version_04
python3 Operations_Research_mit_Python_Version_04/build_version_04.py --check    # nur prüfen
python3 Operations_Research_mit_Python_Version_04/build_version_04.py --pdf --html
python3 Operations_Research_mit_Python_Version_04/extract_programme_04.py

--check prüft mehr als die Struktur: fehlende Codezäune, Links auf nicht existierende Dateien und harte Kapitel-/Abschnitts-/Aufgabennummern im Quelltext. Es meldet Datei und Zeile. Der Suchausdruck erlaubt beliebigen Zwischenraum — der letzte gefundene Fall war ein Handrechnung\n12.1 über zwei Zeilen, an dem jede zeilenweise Suche vorbeiläuft.

build_version_04.py fasst nicht notwendige harte Zeilenumbrüche innerhalb von Absätzen zusammen (reflow_markdown()) — viele Markdown-Renderer stellen einen einzelnen Umbruch sonst fälschlich als sichtbaren Umbruch dar.


Die wichtigsten Konventionen

Keine abgeleiteten Zahlen im Quelltext. Das ist die Regel, an der dieses Projekt am häufigsten gescheitert ist — sieben Mal an verschiedenen Stellen verletzt gefunden (Anhang A, 66 Programm-Docstrings, die Übersichtstabellen der Anhänge, CLAUDE.md selbst, eine Tabellenzelle, die 98 Lösungsmarken des Anhangs, neun Denkfehler-Verweise). Seit dem letzten Fund trägt keine Marke mehr eine handgeschriebene Nummer, und --check bewacht jede Familie. Konkret:

  • Überschriften: # Kapitel: <Titel> {#kap:<label>}, ## Titel {#sec:<label>} — die Nummer vergibt der Build (resolve_numbering(), nummeriere_abschnitte()).
  • Aufgaben, Handrechnungen, Abbildungen, Micro-Quiz: **Aufgabe ⭐ — Titel.**, > **✏️ Handrechnung: Titel**, ![Bildunterschrift](bilder_04/…), > **❓ Micro-Quiz: Titel** — Nummern von nummeriere_marken().
  • Lösungen in Anhang A: **{loesung} — Titel.** Der Präfix kommt nicht aus # Anhang A:, sondern aus dem Kapitel des umgebenden {#sec:loesungen-<X>}-Abschnitts — die Zuordnung sec:loesungen-<X>kap:<X> gilt für alle 23. --check zählt zusätzlich ab, dass es je Kapitel so viele Lösungen wie Aufgaben gibt.
  • Der Denkfehler bekommt bewusst gar keine Nummer. Es gibt je Kapitel genau einen, unter einer bereits nummerierten Überschrift. Verwiesen wird auf {ref:sec:<kapitel>-denkfehler}.
  • Im Fließtext {ref:<label>}, nie eine Literalzahl.
  • In Code-Kommentaren und Docstrings der Kapitelname („Kapitel Metaheuristiken:"), nie die Nummer. Auch nicht im Dateinamen.

Querverweise für die Website laufen über baue_seiten_registry() / resolve_numbering_seite(), nicht über resolve_numbering() — nur dort entsteht aus einem seitenübergreifenden Verweis andere-seite.html#anker.

Stichwortregister: {idx:Begriff} bzw. {idx:Oberbegriff!Unterbegriff}. Vor einem neuen Begriff prüfen, ob er schon existiert: grep -ohE '\{idx:[^}]+\}' Operations_Research_mit_Python_Version_04/*.md | sort -u — sonst entstehen zwei Registereinträge für dasselbe Konzept. texindy sortiert mit dem deutschen din5007-Modul (Umlaute wie im Telefonbuch); das generische -L german bricht ab.

Programme sind ein Artefakt, keine zweite Quelle. Änderungen gehören in den Kapitel-Codeblock, danach extract_programme_04.py. Ein Codeblock gilt als vollständiges Programm, wenn er mit #!/usr/bin/env python3, einer Leerzeile und # Name.py beginnt. Auch das README.md im Programme-Verzeichnis wird erzeugt — aus der Vorlage README_Programme.md; requirements.txt ist die einzige dort von Hand gepflegte Datei.

or_kern.py ist der gemeinsame Unterbau aller Programme (Domänenmodell, SolverStatus, Loesung-DTO, Abnahmeprüfung). Abgedruckt im Kapitel Praxisfallen.

ortools und highspy lassen sich nicht im selben Prozess importieren (beide bringen eine eigene HiGHS-Kopie mit). Deshalb lädt or_kern.py Solverbibliotheken erst in der aufrufenden Funktion, und Programme, die beide brauchen, starten getrennte Prozesse (Muster: Ein_System_Vier_Ansaetze.py, Solverwechsel_CPSAT_HiGHS.py). cvxpy zieht ein installiertes highspy bei der Solver-Erkennung selbst mit hinein — der Konflikt entsteht also auch indirekt.

Neue Kapiteldatei ⇒ in die DATEIEN-Liste in build_version_04.py. Neues Programm ⇒ drei Stellen: Kapitelkopf („Programme:"), Vorwort („Verzeichnis der Beispielprogramme"), bei neuer Abhängigkeit requirements.txt und pyproject.toml (dort in die passende Gruppe, nicht pauschal in die Grundausstattung).

Die vollständigen dreizehn Regeln stehen in PLAN.md Abschnitt 9 — darunter, dass jede abgedruckte Ausgabe aus einem echten Lauf stammt und dass PROGRESS.md in denselben Commit gehört wie die Arbeit, die sie beschreibt.


Diagramme

bilder_04/erzeuge_*.py erzeugen 18 der 32 SVGs, jeweils aus derselben Instanz wie das zugehörige Buchprogramm. Das ist kein Selbstzweck: Von zehn nachgebauten Bildern förderten sieben einen Fehler zutage — dreimal ein Modell, das im Buch gar nicht vorkommt, einmal widersprüchliche Zahlen zwischen Bild und Text, einmal ein gekipptes Vorzeichen. Wer ein Diagramm anfasst, vergleicht es zuerst mit dem Modell des Kapitels.

Die übrigen 14 sind schematisch (Kästen, Pfeile, beschriftete Formeln) und bekommen bewusst keinen Generator — dort kann nichts driften. Das Kriterium steht in PROGRESS.md Abschnitt 6c.

Konventionen der Generatoren: plt.rcParams["svg.hashsalt"] = "or-mit-python-v04" und metadata={"Date": None} für byteidentische Läufe — beides, sonst trägt das SVG einen Zeitstempel und wechselnde clip-path-IDs. Geschrieben wird nur SVG; PNG-Zweitfassungen gab es einmal, sie wurden nirgends referenziert; stammt die Instanz aus einem Zufallsstrom, wird die Ziehungsreihenfolge des Buchprogramms nachgespielt.

Plotly-Figuren

{plotly:name} bindet bilder_04/plotly/<name>.html in die Kapitelseite ein. Das Fragment wird als Rohblock ```{=html} ausgegeben — nicht als blankes HTML: Plotlys Fragment ist eine einzige lange Zeile mit eingebetteten Leerzeichenketten, aus der Pandoc sonst einen Codeblock macht. Genau daran waren alle vier Figuren kaputt, bis es die Schlussabnahme fand. Im PDF steht stattdessen ein Hinweis auf die Website.


Sprache

Kommentare, Ausgaben und Fließtext sind durchgängig Deutsch — diesen Stil beibehalten.