Dokumentation nachgezogen - und dabei den neunten Fund gemacht
Der Leser-Wegweiser Operations_Research_mit_Python_Version_04/README.md, die Datei, die Leser als erstes oeffnen, beschrieb noch die Struktur der Version 03: * 12 der 15 Kapitelnummern falsch. "20_Lineare_Programmierung.md | 4" - es ist Kapitel 5. Bei den Finanzkapiteln lag die Abweichung bei sieben: README 11, tatsaechlich 18. * 8 der 23 Kapitel fehlten ganz (Metaheuristiken, Spaltengenerierung, Mehrziel, Predict-then-Optimize, Testing und drei weitere). * 93_Anhang_Spickzettel.md fehlte in der Anhangtabelle; der Bauabschnitt nannte dreimal build_version_03.py statt _04 und beschrieb --html als "Single-Page-HTML", obwohl es laengst eine mehrseitige Website erzeugt. Dieselbe Regel wie acht Mal zuvor, dieselbe Behandlung: Die Tabelle wird erzeugt, nicht korrigiert. schreibe_kapiteltabelle() ersetzt den Block zwischen den KAPITELTABELLE-Marken aus der Struktur, die baue_seiten_registry() ohnehin ermittelt - derselben Quelle, aus der die Nummern im Buch stammen. --check meldet einen veralteten Block und bricht ab. Gegenprobe: alle 37 Dateien aus DATEIEN stehen in der Uebersicht. Weiter nachgezogen: * CLAUDE.md kannte veroeffentliche_04.py nicht und nannte .env.beispiel nicht. Der Abschnitt "Veroeffentlichung" beschrieb noch das Kopieren von Hand samt curl-Kontrolle - das erledigt jetzt das Skript. * Fundzahl der Nummern-Regel: CLAUDE.md sagte sieben, README acht, PROGRESS dokumentiert einen "Achter Fund". Jetzt ueberall neun. * Diagrammzahl: CLAUDE.md zaehlt 32 Kapiteldiagramme, README 33 - der Unterschied ist titelseite.svg. Das steht jetzt dabei. Nebenbei am Upload-Skript: rsync bekommt --checksum. Der Bau schreibt alle 42 Seiten bei jedem Lauf neu, auch ohne inhaltliche Aenderung; nach Zeitstempel und Groesse waeren das jedes Mal rund 19 MB sinnlose Uebertragung. Gemessen nach einem Neubau ohne Aenderung: 0 statt 151 Dateien. Website unveraendert - kein Upload noetig, der Probelauf meldet 0 zu uebertragen und 0 zu loeschen. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
e3ff5846f6
commit
3d85488d7c
6 changed files with 212 additions and 42 deletions
|
|
@ -29,63 +29,81 @@ arbeiten, üben und eigene Anwendungen bauen können.**
|
|||
Der Text ist auf mehrere Dateien verteilt, damit er handhabbar bleibt. Die Nummern-Präfixe
|
||||
legen die Lesereihenfolge fest.
|
||||
|
||||
<!-- KAPITELTABELLE:ANFANG - erzeugt von build_version_04.py -->
|
||||
|
||||
### Vorspann
|
||||
|
||||
| Datei | Inhalt |
|
||||
| --- | --- |
|
||||
| [`00_Vorwort_und_Lesehilfe.md`](00_Vorwort_und_Lesehilfe.md) | Vorwort, Lernpfade, Verzeichnis der Beispielprogramme, Setup, wie die Lernelemente funktionieren |
|
||||
| [`01_Notation_und_Abkuerzungen.md`](01_Notation_und_Abkuerzungen.md) | Alle Symbole und Abkürzungen, ausgeschrieben und erklärt |
|
||||
| [`00_Vorwort_und_Lesehilfe.md`](00_Vorwort_und_Lesehilfe.md) | Vorwort & Lesehilfe |
|
||||
| [`01_Notation_und_Abkuerzungen.md`](01_Notation_und_Abkuerzungen.md) | Notation & Abkürzungen |
|
||||
|
||||
### Teil I — Grundlagen
|
||||
### Teil I: Grundlagen des Operations Research
|
||||
|
||||
| Datei | Kapitel |
|
||||
| --- | --- |
|
||||
| [`10_Einfuehrung_OR.md`](10_Einfuehrung_OR.md) | 1 — Einführung in Operations Research |
|
||||
| [`11_Mathematisches_Fundament.md`](11_Mathematisches_Fundament.md) | 2 — Vektoren, Matrizen, Konvexität |
|
||||
| [`12_Python_Oekosystem.md`](12_Python_Oekosystem.md) | 3 — Das Python-Ökosystem für OR |
|
||||
| [`10_Einfuehrung_OR.md`](10_Einfuehrung_OR.md) | Kapitel 1 — Einführung in Operations Research — Vom Ursprung zur mathematischen Entscheidungsfindung |
|
||||
| [`11_Mathematisches_Fundament.md`](11_Mathematisches_Fundament.md) | Kapitel 2 — Das mathematische Fundament — Vektoren, Matrizen, Konvexität |
|
||||
| [`12_Python_Oekosystem.md`](12_Python_Oekosystem.md) | Kapitel 3 — Das Python-Ökosystem für OR — Solver, Bindings und Modellierungsschichten |
|
||||
| [`13_Vom_Wunsch_zum_Modell.md`](13_Vom_Wunsch_zum_Modell.md) | Kapitel 4 — Vom Management-Wunsch zum Modell |
|
||||
| [`19_Synthese_Grundlagen.md`](19_Synthese_Grundlagen.md) | Synthese Teil I |
|
||||
|
||||
### Teil II — Deterministische Kernverfahren
|
||||
### Teil II: Die Kernverfahren der deterministischen Optimierung
|
||||
|
||||
| Datei | Kapitel |
|
||||
| --- | --- |
|
||||
| [`20_Lineare_Programmierung.md`](20_Lineare_Programmierung.md) | 4 — Lineare Programmierung, Simplex, Dualität |
|
||||
| [`21_MILP.md`](21_MILP.md) | 5 — Gemischt-ganzzahlige Optimierung |
|
||||
| [`22_CP_SAT.md`](22_CP_SAT.md) | 6 — Constraint Programming mit CP-SAT |
|
||||
| [`23_Graphen_Fluesse_Touren.md`](23_Graphen_Fluesse_Touren.md) | 7 — Graphen, Flüsse, Tourenplanung |
|
||||
| [`20_Lineare_Programmierung.md`](20_Lineare_Programmierung.md) | Kapitel 5 — Lineare Programmierung — Simplex, Dualität und Schattenpreise |
|
||||
| [`21_MILP.md`](21_MILP.md) | Kapitel 6 — Gemischt-ganzzahlige Optimierung — Diskrete Entscheidungen und Branch-and-Bound |
|
||||
| [`22_CP_SAT.md`](22_CP_SAT.md) | Kapitel 7 — Constraint Programming mit CP-SAT — Logik, Scheduling und Zuweisung |
|
||||
| [`23_Graphen_Fluesse_Touren.md`](23_Graphen_Fluesse_Touren.md) | Kapitel 8 — Graphen, Flüsse und Touren — Min-Cost-Flow, Matching und VRP |
|
||||
| [`24_Metaheuristiken.md`](24_Metaheuristiken.md) | Kapitel 9 — Metaheuristiken — wenn der exakte Solver aussteigt |
|
||||
| [`25_Spaltengenerierung.md`](25_Spaltengenerierung.md) | Kapitel 10 — Spaltengenerierung — das Modell umbauen statt die Lösung raten |
|
||||
| [`29_Synthese_Kernverfahren.md`](29_Synthese_Kernverfahren.md) | Synthese Teil II |
|
||||
|
||||
### Teil III — Nichtlinearität, Unsicherheit, Dynamik
|
||||
### Teil III: Nichtlinearität, Unsicherheit und mehrperiodige Dynamik
|
||||
|
||||
| Datei | Kapitel |
|
||||
| --- | --- |
|
||||
| [`30_QP_und_NLP.md`](30_QP_und_NLP.md) | 8 — Quadratische und nichtlineare Optimierung, KKT |
|
||||
| [`31_Unsicherheit.md`](31_Unsicherheit.md) | 9 — Monte-Carlo, stochastische und robuste Optimierung |
|
||||
| [`32_Dynamische_Programmierung.md`](32_Dynamische_Programmierung.md) | 10 — Dynamische Programmierung, Bellman |
|
||||
| [`30_QP_und_NLP.md`](30_QP_und_NLP.md) | Kapitel 11 — Quadratische und nichtlineare Optimierung — KKT, Lagrange, Konvexität |
|
||||
| [`31_Unsicherheit.md`](31_Unsicherheit.md) | Kapitel 12 — Optimierung unter Unsicherheit — Monte-Carlo, Stochastik, Robustheit |
|
||||
| [`32_Dynamische_Programmierung.md`](32_Dynamische_Programmierung.md) | Kapitel 13 — Dynamische Programmierung — Die Bellman-Gleichung und Order-Execution |
|
||||
| [`33_Mehrziel_und_Pareto.md`](33_Mehrziel_und_Pareto.md) | Kapitel 14 — Mehrere Ziele — Pareto-Fronten statt Gewichte |
|
||||
| [`34_Predict_then_Optimize.md`](34_Predict_then_Optimize.md) | Kapitel 15 — Predict-then-Optimize — die bessere Prognose, die schlechtere Entscheidung |
|
||||
| [`39_Synthese_Nichtlinear.md`](39_Synthese_Nichtlinear.md) | Synthese Teil III |
|
||||
|
||||
### Teil IV — Operations Research an den Finanzmärkten
|
||||
### Teil IV: Anwendungen — Energiewirtschaft und Finanzmärkte
|
||||
|
||||
| Datei | Kapitel |
|
||||
| --- | --- |
|
||||
| [`40_Finanzdaten.md`](40_Finanzdaten.md) | 11 — Finanzdaten, Kovarianz, Shrinkage |
|
||||
| [`41_Markowitz.md`](41_Markowitz.md) | 12 — Markowitz-Portfoliotheorie |
|
||||
| [`42_CVaR.md`](42_CVaR.md) | 13 — Tail-Risiko, CVaR, Transaktionskosten |
|
||||
| [`43_Handelsmaschine.md`](43_Handelsmaschine.md) | 14 — Die vollständige Handelsmaschine |
|
||||
| [`35_Strukturbruecke.md`](35_Strukturbruecke.md) | Kapitel 16 — Die Strukturbrücke — dieselbe Mathematik, zwei Welten |
|
||||
| [`36_Supply_Chain_Energie.md`](36_Supply_Chain_Energie.md) | Kapitel 17 — Supply-Chain und Energieeinsatz unter Unsicherheit |
|
||||
| [`40_Finanzdaten.md`](40_Finanzdaten.md) | Kapitel 18 — Finanzdaten-Modellierung — Renditen, Kovarianz und Shrinkage |
|
||||
| [`41_Markowitz.md`](41_Markowitz.md) | Kapitel 19 — Die moderne Portfoliotheorie nach Markowitz |
|
||||
| [`42_CVaR.md`](42_CVaR.md) | Kapitel 20 — Tail-Risiko, CVaR und Transaktionskosten |
|
||||
| [`43_Handelsmaschine.md`](43_Handelsmaschine.md) | Kapitel 21 — Die vollständige quantitative Handelsmaschine |
|
||||
| [`49_Synthese_Anwendungen.md`](49_Synthese_Anwendungen.md) | Synthese Teil IV |
|
||||
|
||||
### Teil V — Praxis
|
||||
### Teil V: Praxis
|
||||
|
||||
| Datei | Kapitel |
|
||||
| --- | --- |
|
||||
| [`50_Praxis.md`](50_Praxis.md) | 15 — Praxisfallen und produktiver Einsatz |
|
||||
| [`59_Projektwerkstatt.md`](59_Projektwerkstatt.md) | Projektwerkstatt: 8 eigene Anwendungen |
|
||||
| [`50_Praxis.md`](50_Praxis.md) | Kapitel 22 — Praxisfallen und der Weg zum produktiven Einsatz |
|
||||
| [`51_Testing_und_Deployment.md`](51_Testing_und_Deployment.md) | Kapitel 23 — Testen, Messen, Ausliefern |
|
||||
| [`52_Synthese_Praxis.md`](52_Synthese_Praxis.md) | Synthese Teil V |
|
||||
| [`59_Projektwerkstatt.md`](59_Projektwerkstatt.md) | Projektwerkstatt |
|
||||
|
||||
### Anhang
|
||||
|
||||
| Datei | Inhalt |
|
||||
| --- | --- |
|
||||
| [`90_Anhang_Loesungen.md`](90_Anhang_Loesungen.md) | Lösungen zu **allen** Übungsaufgaben und Selbsttests |
|
||||
| [`91_Anhang_Modellierungsmuster.md`](91_Anhang_Modellierungsmuster.md) | Musterkatalog: 24 wiederkehrende Modellierungstricks |
|
||||
| [`92_Anhang_Fehlerdiagnose.md`](92_Anhang_Fehlerdiagnose.md) | Diagnose-Handbuch für Solver-Probleme |
|
||||
| [`94_Anhang_Glossar.md`](94_Anhang_Glossar.md) | Glossar der Fachbegriffe |
|
||||
| [`95_Anhang_Literatur.md`](95_Anhang_Literatur.md) | Literaturverzeichnis |
|
||||
| [`90_Anhang_Loesungen.md`](90_Anhang_Loesungen.md) | Anhang A — Lösungen zu allen Übungsaufgaben |
|
||||
| [`91_Anhang_Modellierungsmuster.md`](91_Anhang_Modellierungsmuster.md) | Anhang B — Katalog der Modellierungsmuster |
|
||||
| [`92_Anhang_Fehlerdiagnose.md`](92_Anhang_Fehlerdiagnose.md) | Anhang C — Fehlerdiagnose-Handbuch |
|
||||
| [`93_Anhang_Spickzettel.md`](93_Anhang_Spickzettel.md) | Anhang D — Spickzettel der Solver |
|
||||
| [`94_Anhang_Glossar.md`](94_Anhang_Glossar.md) | Anhang E — Glossar |
|
||||
| [`95_Anhang_Literatur.md`](95_Anhang_Literatur.md) | Anhang F — Literaturverzeichnis |
|
||||
|
||||
<!-- KAPITELTABELLE:ENDE -->
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -95,7 +113,7 @@ Wer lieber ein einziges Dokument möchte (z. B. zum Drucken oder für die PDF-Er
|
|||
baut es aus den Einzeldateien:
|
||||
|
||||
```bash
|
||||
cd OR_mit_Python/Version_04 # Wurzel der Version 04
|
||||
cd Version_04 # das Wurzelverzeichnis des Repositorys
|
||||
python3 Operations_Research_mit_Python_Version_04/build_version_04.py
|
||||
```
|
||||
|
||||
|
|
@ -105,11 +123,15 @@ Inhaltsverzeichnis-Platzhalter und entfernten unnötigen Zeilenumbrüchen innerh
|
|||
Absätzen. Optionen:
|
||||
|
||||
```bash
|
||||
python3 .../build_version_03.py --pdf # zusätzlich PDF über pandoc + xelatex
|
||||
python3 .../build_version_03.py --html # zusätzlich Single-Page-HTML
|
||||
python3 .../build_version_03.py --check # nur Konsistenzprüfung, schreibt nichts
|
||||
python3 .../build_version_04.py --pdf # zusätzlich PDF über pandoc + xelatex
|
||||
python3 .../build_version_04.py --html # zusätzlich die Website OR_HTML_04/
|
||||
python3 .../build_version_04.py --check # nur Konsistenzprüfung, schreibt nichts
|
||||
```
|
||||
|
||||
`--html` erzeugt die **mehrseitige** Website mit Suche, Stichwortverzeichnis und
|
||||
Notebook-Downloads; das Gesamtdokument auf einer Seite liegt darin als
|
||||
`gesamtdokument.html`.
|
||||
|
||||
---
|
||||
|
||||
## Empfohlene Reihenfolge für Kursteilnehmer
|
||||
|
|
|
|||
|
|
@ -2443,6 +2443,86 @@ def baue_stichwortverzeichnis(html_verz: str, struktur: list[dict],
|
|||
print(f"Stichwortverzeichnis erzeugt: {len(namen)} Hauptbegriffe.")
|
||||
|
||||
|
||||
# Der Leser-Wegweiser Operations_Research_mit_Python_Version_04/README.md fuehrt
|
||||
# alle Quelldateien mit ihrer Kapitelnummer auf. Diese Tabelle stand von Hand
|
||||
# darin - und war der NEUNTE Fall der Regel "keine abgeleiteten Zahlen im
|
||||
# Quelltext": 12 der 15 Nummern zeigten noch die Zaehlung der Version 03, und
|
||||
# 8 der 23 Kapitel fehlten ganz. Jetzt erzeugt der Bau den Block zwischen den
|
||||
# beiden Marken; --check meldet, wenn er veraltet ist.
|
||||
README_MARKE_ANFANG = "<!-- KAPITELTABELLE:ANFANG - erzeugt von build_version_04.py -->"
|
||||
README_MARKE_ENDE = "<!-- KAPITELTABELLE:ENDE -->"
|
||||
|
||||
LESER_README = os.path.join(HIER, "README.md")
|
||||
|
||||
|
||||
def baue_kapiteltabelle(struktur: list[dict]) -> str:
|
||||
"""Baut die Dateiuebersicht des Leser-Wegweisers aus der Struktur, die
|
||||
baue_seiten_registry() ohnehin ermittelt - dieselbe Quelle, aus der auch
|
||||
die Nummern im Buch stammen. Damit koennen die beiden nicht auseinander-
|
||||
laufen."""
|
||||
zeilen = [README_MARKE_ANFANG, ""]
|
||||
|
||||
def tabelle(eintraege: list[dict], spalte: str) -> None:
|
||||
zeilen.append(f"| Datei | {spalte} |")
|
||||
zeilen.append("| --- | --- |")
|
||||
for e in eintraege:
|
||||
was = f'{e["nummer"]} — {e["titel"]}' if e["nummer"] else e["titel"]
|
||||
zeilen.append(f'| [`{e["datei"]}`]({e["datei"]}) | {was} |')
|
||||
zeilen.append("")
|
||||
|
||||
vorspann = [e for e in struktur if e["teil"] is None and e["typ"] == "sonder"]
|
||||
if vorspann:
|
||||
zeilen.append("### Vorspann")
|
||||
zeilen.append("")
|
||||
tabelle(vorspann, "Inhalt")
|
||||
|
||||
gesehen: list[str] = []
|
||||
for e in struktur:
|
||||
if e["teil"] and e["teil"] not in gesehen:
|
||||
gesehen.append(e["teil"])
|
||||
for teil in gesehen:
|
||||
zeilen.append(f"### {teil}")
|
||||
zeilen.append("")
|
||||
tabelle([e for e in struktur if e["teil"] == teil], "Kapitel")
|
||||
|
||||
anhaenge = [e for e in struktur if e["typ"] == "anhang"]
|
||||
if anhaenge:
|
||||
zeilen.append("### Anhang")
|
||||
zeilen.append("")
|
||||
tabelle(anhaenge, "Inhalt")
|
||||
|
||||
zeilen.append(README_MARKE_ENDE)
|
||||
return "\n".join(zeilen)
|
||||
|
||||
|
||||
def schreibe_kapiteltabelle(struktur: list[dict], nur_pruefen: bool) -> list[str]:
|
||||
"""Ersetzt den markierten Block im Leser-Wegweiser. Liefert bei --check
|
||||
eine nicht leere Liste, wenn er veraltet ist."""
|
||||
if not os.path.exists(LESER_README):
|
||||
return []
|
||||
with open(LESER_README, encoding="utf-8") as f:
|
||||
inhalt = f.read()
|
||||
if README_MARKE_ANFANG not in inhalt or README_MARKE_ENDE not in inhalt:
|
||||
print(f"FEHLER: {os.path.basename(LESER_README)} hat keine "
|
||||
f"KAPITELTABELLE-Marken - die Dateiuebersicht kann nicht "
|
||||
f"erzeugt werden.")
|
||||
return ["README-Marken"]
|
||||
vorher, rest = inhalt.split(README_MARKE_ANFANG, 1)
|
||||
_, nachher = rest.split(README_MARKE_ENDE, 1)
|
||||
neu = vorher + baue_kapiteltabelle(struktur) + nachher
|
||||
if neu == inhalt:
|
||||
return []
|
||||
if nur_pruefen:
|
||||
print(f"FEHLER: Die Dateiuebersicht in "
|
||||
f"{os.path.basename(LESER_README)} ist veraltet - ein Lauf ohne "
|
||||
f"--check zieht sie nach.")
|
||||
return ["README-Kapiteltabelle"]
|
||||
with open(LESER_README, "w", encoding="utf-8") as f:
|
||||
f.write(neu)
|
||||
print(f"Dateiuebersicht im Leser-Wegweiser nachgezogen.")
|
||||
return []
|
||||
|
||||
|
||||
def erzeuge_suchindex(html_verz: str, suchindex: list[dict]) -> None:
|
||||
# .js mit globaler Variable statt .json + fetch() - siehe Kommentar in
|
||||
# baue_programme_seite() (fetch() auf lokale Dateien scheitert unter
|
||||
|
|
@ -2511,6 +2591,13 @@ def main() -> int:
|
|||
print(f"Geprueft: {len(DATEIEN)} Dateien, {zeilen:,} Zeilen, "
|
||||
f"{zeichen/1024:.0f} KB, {kapitel} Hauptueberschriften.")
|
||||
|
||||
# Die Dateiuebersicht des Leser-Wegweisers stammt aus derselben Struktur
|
||||
# wie die Nummern im Buch. Bei --check wird nur gemeldet, dass sie veraltet
|
||||
# ist; geschrieben wird sie im normalen Lauf.
|
||||
_, _, _, struktur_fuer_readme, _ = baue_seiten_registry()
|
||||
if schreibe_kapiteltabelle(struktur_fuer_readme, nur_pruefen=argumente.check):
|
||||
return 1
|
||||
|
||||
if argumente.check:
|
||||
print("Nur Pruefung - es wurde nichts geschrieben.")
|
||||
return 0
|
||||
|
|
|
|||
|
|
@ -192,7 +192,13 @@ def rsync_befehl(env: dict[str, str], probelauf: bool) -> list[str]:
|
|||
# ohnehin nicht setzen, -a erzeugte dafuer nur Warnungen. --chmod sorgt
|
||||
# dafuer, dass der Webserver alles lesen kann, unabhaengig von der lokalen
|
||||
# umask.
|
||||
befehl = ["rsync", "-rltz", "--delete", "--chmod=D755,F644",
|
||||
# --checksum: vergleiche INHALTE, nicht Groesse und Zeitstempel. Der Bau
|
||||
# schreibt alle 42 Seiten bei jedem Lauf neu, auch wenn sich nichts
|
||||
# geaendert hat - nach der Vorgabe waeren das jedes Mal rund 19 MB
|
||||
# sinnlose Uebertragung. Mit --checksum meldet der Probelauf genau die
|
||||
# Dateien, deren Inhalt sich wirklich unterscheidet. Das Lesen der 23 MB
|
||||
# auf beiden Seiten faellt dagegen nicht ins Gewicht.
|
||||
befehl = ["rsync", "-rltz", "--checksum", "--delete", "--chmod=D755,F644",
|
||||
"--skip-compress=pdf/zip/woff2/png/jpg/svg",
|
||||
"--itemize-changes",
|
||||
"-e", ssh_optionen(env)]
|
||||
|
|
|
|||
Loading…
Reference in a new issue