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>
|
|
@ -139,7 +139,9 @@ keinen Generator — dort kann nichts driften. Das Kriterium steht in `PROGRESS.
|
|||
Abschnitt 6c.
|
||||
|
||||
Konventionen der Generatoren: `plt.rcParams["svg.hashsalt"] = "or-mit-python-v04"` und
|
||||
`metadata={"Date": None}` für byteidentische Läufe; stammt die Instanz aus einem
|
||||
`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
|
||||
|
|
|
|||
|
|
@ -405,8 +405,13 @@
|
|||
"from or_kern import (lade_produktionsproblem, loese_mit_glop, pruefe_loesung,\n",
|
||||
" schreibe_ergebnis)\n",
|
||||
"\n",
|
||||
"EINGABE = \"produktionsmix.xlsx\"\n",
|
||||
"AUSGABE = \"produktionsmix_ergebnis.xlsx\"\n",
|
||||
"# Die Mappen liegen NEBEN diesem Programm, nicht im aktuellen\n",
|
||||
"# Arbeitsverzeichnis. Sonst haengt es davon ab, aus welchem Ordner man das\n",
|
||||
"# Skript startet, wo die Dateien landen - und wer es aus der\n",
|
||||
"# Repository-Wurzel aufruft, verstreut sie dort.\n",
|
||||
"HIER = os.path.dirname(os.path.abspath(__file__))\n",
|
||||
"EINGABE = os.path.join(HIER, \"produktionsmix.xlsx\")\n",
|
||||
"AUSGABE = os.path.join(HIER, \"produktionsmix_ergebnis.xlsx\")\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"def lege_beispieldatei_an(pfad: str) -> None:\n",
|
||||
|
|
|
|||
|
|
@ -405,8 +405,13 @@
|
|||
"from or_kern import (lade_produktionsproblem, loese_mit_glop, pruefe_loesung,\n",
|
||||
" schreibe_ergebnis)\n",
|
||||
"\n",
|
||||
"EINGABE = \"produktionsmix.xlsx\"\n",
|
||||
"AUSGABE = \"produktionsmix_ergebnis.xlsx\"\n",
|
||||
"# Die Mappen liegen NEBEN diesem Programm, nicht im aktuellen\n",
|
||||
"# Arbeitsverzeichnis. Sonst haengt es davon ab, aus welchem Ordner man das\n",
|
||||
"# Skript startet, wo die Dateien landen - und wer es aus der\n",
|
||||
"# Repository-Wurzel aufruft, verstreut sie dort.\n",
|
||||
"HIER = os.path.dirname(os.path.abspath(__file__))\n",
|
||||
"EINGABE = os.path.join(HIER, \"produktionsmix.xlsx\")\n",
|
||||
"AUSGABE = os.path.join(HIER, \"produktionsmix_ergebnis.xlsx\")\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"def lege_beispieldatei_an(pfad: str) -> None:\n",
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 63 KiB |
|
Before Width: | Height: | Size: 94 KiB |
|
Before Width: | Height: | Size: 88 KiB |
|
Before Width: | Height: | Size: 80 KiB |
|
Before Width: | Height: | Size: 88 KiB |
|
Before Width: | Height: | Size: 44 KiB |
|
|
@ -6,7 +6,6 @@
|
|||
<rdf:RDF xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
|
||||
<cc:Work>
|
||||
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
|
||||
<dc:date>2026-09-07T01:51:51.979555</dc:date>
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:creator>
|
||||
<cc:Agent>
|
||||
|
|
@ -43,7 +42,7 @@ L 326.435455 32.849091
|
|||
L 326.435455 64.809875
|
||||
L 174.248182 64.809875
|
||||
z
|
||||
" clip-path="url(#p448fd06892)" style="fill: #4338ca; stroke: #ffffff; stroke-width: 1.2; stroke-linejoin: miter"/>
|
||||
" clip-path="url(#pce73ba693e)" style="fill: #4338ca; stroke: #ffffff; stroke-width: 1.2; stroke-linejoin: miter"/>
|
||||
</g>
|
||||
<g id="patch_4">
|
||||
<path d="M 326.435455 90.959608
|
||||
|
|
@ -51,7 +50,7 @@ L 427.893636 90.959608
|
|||
L 427.893636 122.920392
|
||||
L 326.435455 122.920392
|
||||
z
|
||||
" clip-path="url(#p448fd06892)" style="fill: #4338ca; stroke: #ffffff; stroke-width: 1.2; stroke-linejoin: miter"/>
|
||||
" clip-path="url(#pce73ba693e)" style="fill: #4338ca; stroke: #ffffff; stroke-width: 1.2; stroke-linejoin: miter"/>
|
||||
</g>
|
||||
<g id="patch_5">
|
||||
<path d="M 427.893636 149.070125
|
||||
|
|
@ -59,7 +58,7 @@ L 529.351818 149.070125
|
|||
L 529.351818 181.030909
|
||||
L 427.893636 181.030909
|
||||
z
|
||||
" clip-path="url(#p448fd06892)" style="fill: #4338ca; stroke: #ffffff; stroke-width: 1.2; stroke-linejoin: miter"/>
|
||||
" clip-path="url(#pce73ba693e)" style="fill: #4338ca; stroke: #ffffff; stroke-width: 1.2; stroke-linejoin: miter"/>
|
||||
</g>
|
||||
<g id="patch_6">
|
||||
<path d="M 72.79 32.849091
|
||||
|
|
@ -67,7 +66,7 @@ L 174.248182 32.849091
|
|||
L 174.248182 64.809875
|
||||
L 72.79 64.809875
|
||||
z
|
||||
" clip-path="url(#p448fd06892)" style="fill: #0891b2; stroke: #ffffff; stroke-width: 1.2; stroke-linejoin: miter"/>
|
||||
" clip-path="url(#pce73ba693e)" style="fill: #0891b2; stroke: #ffffff; stroke-width: 1.2; stroke-linejoin: miter"/>
|
||||
</g>
|
||||
<g id="patch_7">
|
||||
<path d="M 174.248182 149.070125
|
||||
|
|
@ -75,7 +74,7 @@ L 224.977273 149.070125
|
|||
L 224.977273 181.030909
|
||||
L 174.248182 181.030909
|
||||
z
|
||||
" clip-path="url(#p448fd06892)" style="fill: #0891b2; stroke: #ffffff; stroke-width: 1.2; stroke-linejoin: miter"/>
|
||||
" clip-path="url(#pce73ba693e)" style="fill: #0891b2; stroke: #ffffff; stroke-width: 1.2; stroke-linejoin: miter"/>
|
||||
</g>
|
||||
<g id="patch_8">
|
||||
<path d="M 427.893636 90.959608
|
||||
|
|
@ -83,7 +82,7 @@ L 630.81 90.959608
|
|||
L 630.81 122.920392
|
||||
L 427.893636 122.920392
|
||||
z
|
||||
" clip-path="url(#p448fd06892)" style="fill: #0891b2; stroke: #ffffff; stroke-width: 1.2; stroke-linejoin: miter"/>
|
||||
" clip-path="url(#pce73ba693e)" style="fill: #0891b2; stroke: #ffffff; stroke-width: 1.2; stroke-linejoin: miter"/>
|
||||
</g>
|
||||
<g id="patch_9">
|
||||
<path d="M 72.79 90.959608
|
||||
|
|
@ -91,7 +90,7 @@ L 275.706364 90.959608
|
|||
L 275.706364 122.920392
|
||||
L 72.79 122.920392
|
||||
z
|
||||
" clip-path="url(#p448fd06892)" style="fill: #b45309; stroke: #ffffff; stroke-width: 1.2; stroke-linejoin: miter"/>
|
||||
" clip-path="url(#pce73ba693e)" style="fill: #b45309; stroke: #ffffff; stroke-width: 1.2; stroke-linejoin: miter"/>
|
||||
</g>
|
||||
<g id="patch_10">
|
||||
<path d="M 275.706364 149.070125
|
||||
|
|
@ -99,23 +98,23 @@ L 427.893636 149.070125
|
|||
L 427.893636 181.030909
|
||||
L 275.706364 181.030909
|
||||
z
|
||||
" clip-path="url(#p448fd06892)" style="fill: #b45309; stroke: #ffffff; stroke-width: 1.2; stroke-linejoin: miter"/>
|
||||
" clip-path="url(#pce73ba693e)" style="fill: #b45309; stroke: #ffffff; stroke-width: 1.2; stroke-linejoin: miter"/>
|
||||
</g>
|
||||
<g id="matplotlib.axis_1">
|
||||
<g id="xtick_1">
|
||||
<g id="line2d_1">
|
||||
<path d="M 72.79 188.44
|
||||
L 72.79 25.44
|
||||
" clip-path="url(#p448fd06892)" style="fill: none; stroke-dasharray: 0.8,1.32; stroke-dashoffset: 0; stroke: #b0b0b0; stroke-opacity: 0.5; stroke-width: 0.8"/>
|
||||
" clip-path="url(#pce73ba693e)" style="fill: none; stroke-dasharray: 0.8,1.32; stroke-dashoffset: 0; stroke: #b0b0b0; stroke-opacity: 0.5; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g id="line2d_2">
|
||||
<defs>
|
||||
<path id="mfeb5fcddc7" d="M 0 0
|
||||
<path id="mf0a04b41f8" d="M 0 0
|
||||
L 0 3.5
|
||||
" style="stroke: #000000; stroke-width: 0.8"/>
|
||||
</defs>
|
||||
<g>
|
||||
<use xlink:href="#mfeb5fcddc7" x="72.79" y="188.44" style="stroke: #000000; stroke-width: 0.8"/>
|
||||
<use xlink:href="#mf0a04b41f8" x="72.79" y="188.44" style="stroke: #000000; stroke-width: 0.8"/>
|
||||
</g>
|
||||
</g>
|
||||
<g id="text_1">
|
||||
|
|
@ -152,11 +151,11 @@ z
|
|||
<g id="line2d_3">
|
||||
<path d="M 123.519091 188.44
|
||||
L 123.519091 25.44
|
||||
" clip-path="url(#p448fd06892)" style="fill: none; stroke-dasharray: 0.8,1.32; stroke-dashoffset: 0; stroke: #b0b0b0; stroke-opacity: 0.5; stroke-width: 0.8"/>
|
||||
" clip-path="url(#pce73ba693e)" style="fill: none; stroke-dasharray: 0.8,1.32; stroke-dashoffset: 0; stroke: #b0b0b0; stroke-opacity: 0.5; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g id="line2d_4">
|
||||
<g>
|
||||
<use xlink:href="#mfeb5fcddc7" x="123.519091" y="188.44" style="stroke: #000000; stroke-width: 0.8"/>
|
||||
<use xlink:href="#mf0a04b41f8" x="123.519091" y="188.44" style="stroke: #000000; stroke-width: 0.8"/>
|
||||
</g>
|
||||
</g>
|
||||
<g id="text_2">
|
||||
|
|
@ -186,11 +185,11 @@ z
|
|||
<g id="line2d_5">
|
||||
<path d="M 174.248182 188.44
|
||||
L 174.248182 25.44
|
||||
" clip-path="url(#p448fd06892)" style="fill: none; stroke-dasharray: 0.8,1.32; stroke-dashoffset: 0; stroke: #b0b0b0; stroke-opacity: 0.5; stroke-width: 0.8"/>
|
||||
" clip-path="url(#pce73ba693e)" style="fill: none; stroke-dasharray: 0.8,1.32; stroke-dashoffset: 0; stroke: #b0b0b0; stroke-opacity: 0.5; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g id="line2d_6">
|
||||
<g>
|
||||
<use xlink:href="#mfeb5fcddc7" x="174.248182" y="188.44" style="stroke: #000000; stroke-width: 0.8"/>
|
||||
<use xlink:href="#mf0a04b41f8" x="174.248182" y="188.44" style="stroke: #000000; stroke-width: 0.8"/>
|
||||
</g>
|
||||
</g>
|
||||
<g id="text_3">
|
||||
|
|
@ -230,11 +229,11 @@ z
|
|||
<g id="line2d_7">
|
||||
<path d="M 224.977273 188.44
|
||||
L 224.977273 25.44
|
||||
" clip-path="url(#p448fd06892)" style="fill: none; stroke-dasharray: 0.8,1.32; stroke-dashoffset: 0; stroke: #b0b0b0; stroke-opacity: 0.5; stroke-width: 0.8"/>
|
||||
" clip-path="url(#pce73ba693e)" style="fill: none; stroke-dasharray: 0.8,1.32; stroke-dashoffset: 0; stroke: #b0b0b0; stroke-opacity: 0.5; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g id="line2d_8">
|
||||
<g>
|
||||
<use xlink:href="#mfeb5fcddc7" x="224.977273" y="188.44" style="stroke: #000000; stroke-width: 0.8"/>
|
||||
<use xlink:href="#mf0a04b41f8" x="224.977273" y="188.44" style="stroke: #000000; stroke-width: 0.8"/>
|
||||
</g>
|
||||
</g>
|
||||
<g id="text_4">
|
||||
|
|
@ -282,11 +281,11 @@ z
|
|||
<g id="line2d_9">
|
||||
<path d="M 275.706364 188.44
|
||||
L 275.706364 25.44
|
||||
" clip-path="url(#p448fd06892)" style="fill: none; stroke-dasharray: 0.8,1.32; stroke-dashoffset: 0; stroke: #b0b0b0; stroke-opacity: 0.5; stroke-width: 0.8"/>
|
||||
" clip-path="url(#pce73ba693e)" style="fill: none; stroke-dasharray: 0.8,1.32; stroke-dashoffset: 0; stroke: #b0b0b0; stroke-opacity: 0.5; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g id="line2d_10">
|
||||
<g>
|
||||
<use xlink:href="#mfeb5fcddc7" x="275.706364" y="188.44" style="stroke: #000000; stroke-width: 0.8"/>
|
||||
<use xlink:href="#mf0a04b41f8" x="275.706364" y="188.44" style="stroke: #000000; stroke-width: 0.8"/>
|
||||
</g>
|
||||
</g>
|
||||
<g id="text_5">
|
||||
|
|
@ -321,11 +320,11 @@ z
|
|||
<g id="line2d_11">
|
||||
<path d="M 326.435455 188.44
|
||||
L 326.435455 25.44
|
||||
" clip-path="url(#p448fd06892)" style="fill: none; stroke-dasharray: 0.8,1.32; stroke-dashoffset: 0; stroke: #b0b0b0; stroke-opacity: 0.5; stroke-width: 0.8"/>
|
||||
" clip-path="url(#pce73ba693e)" style="fill: none; stroke-dasharray: 0.8,1.32; stroke-dashoffset: 0; stroke: #b0b0b0; stroke-opacity: 0.5; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g id="line2d_12">
|
||||
<g>
|
||||
<use xlink:href="#mfeb5fcddc7" x="326.435455" y="188.44" style="stroke: #000000; stroke-width: 0.8"/>
|
||||
<use xlink:href="#mf0a04b41f8" x="326.435455" y="188.44" style="stroke: #000000; stroke-width: 0.8"/>
|
||||
</g>
|
||||
</g>
|
||||
<g id="text_6">
|
||||
|
|
@ -366,11 +365,11 @@ z
|
|||
<g id="line2d_13">
|
||||
<path d="M 377.164545 188.44
|
||||
L 377.164545 25.44
|
||||
" clip-path="url(#p448fd06892)" style="fill: none; stroke-dasharray: 0.8,1.32; stroke-dashoffset: 0; stroke: #b0b0b0; stroke-opacity: 0.5; stroke-width: 0.8"/>
|
||||
" clip-path="url(#pce73ba693e)" style="fill: none; stroke-dasharray: 0.8,1.32; stroke-dashoffset: 0; stroke: #b0b0b0; stroke-opacity: 0.5; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g id="line2d_14">
|
||||
<g>
|
||||
<use xlink:href="#mfeb5fcddc7" x="377.164545" y="188.44" style="stroke: #000000; stroke-width: 0.8"/>
|
||||
<use xlink:href="#mf0a04b41f8" x="377.164545" y="188.44" style="stroke: #000000; stroke-width: 0.8"/>
|
||||
</g>
|
||||
</g>
|
||||
<g id="text_7">
|
||||
|
|
@ -416,11 +415,11 @@ z
|
|||
<g id="line2d_15">
|
||||
<path d="M 427.893636 188.44
|
||||
L 427.893636 25.44
|
||||
" clip-path="url(#p448fd06892)" style="fill: none; stroke-dasharray: 0.8,1.32; stroke-dashoffset: 0; stroke: #b0b0b0; stroke-opacity: 0.5; stroke-width: 0.8"/>
|
||||
" clip-path="url(#pce73ba693e)" style="fill: none; stroke-dasharray: 0.8,1.32; stroke-dashoffset: 0; stroke: #b0b0b0; stroke-opacity: 0.5; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g id="line2d_16">
|
||||
<g>
|
||||
<use xlink:href="#mfeb5fcddc7" x="427.893636" y="188.44" style="stroke: #000000; stroke-width: 0.8"/>
|
||||
<use xlink:href="#mf0a04b41f8" x="427.893636" y="188.44" style="stroke: #000000; stroke-width: 0.8"/>
|
||||
</g>
|
||||
</g>
|
||||
<g id="text_8">
|
||||
|
|
@ -446,11 +445,11 @@ z
|
|||
<g id="line2d_17">
|
||||
<path d="M 478.622727 188.44
|
||||
L 478.622727 25.44
|
||||
" clip-path="url(#p448fd06892)" style="fill: none; stroke-dasharray: 0.8,1.32; stroke-dashoffset: 0; stroke: #b0b0b0; stroke-opacity: 0.5; stroke-width: 0.8"/>
|
||||
" clip-path="url(#pce73ba693e)" style="fill: none; stroke-dasharray: 0.8,1.32; stroke-dashoffset: 0; stroke: #b0b0b0; stroke-opacity: 0.5; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g id="line2d_18">
|
||||
<g>
|
||||
<use xlink:href="#mfeb5fcddc7" x="478.622727" y="188.44" style="stroke: #000000; stroke-width: 0.8"/>
|
||||
<use xlink:href="#mf0a04b41f8" x="478.622727" y="188.44" style="stroke: #000000; stroke-width: 0.8"/>
|
||||
</g>
|
||||
</g>
|
||||
<g id="text_9">
|
||||
|
|
@ -505,11 +504,11 @@ z
|
|||
<g id="line2d_19">
|
||||
<path d="M 529.351818 188.44
|
||||
L 529.351818 25.44
|
||||
" clip-path="url(#p448fd06892)" style="fill: none; stroke-dasharray: 0.8,1.32; stroke-dashoffset: 0; stroke: #b0b0b0; stroke-opacity: 0.5; stroke-width: 0.8"/>
|
||||
" clip-path="url(#pce73ba693e)" style="fill: none; stroke-dasharray: 0.8,1.32; stroke-dashoffset: 0; stroke: #b0b0b0; stroke-opacity: 0.5; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g id="line2d_20">
|
||||
<g>
|
||||
<use xlink:href="#mfeb5fcddc7" x="529.351818" y="188.44" style="stroke: #000000; stroke-width: 0.8"/>
|
||||
<use xlink:href="#mf0a04b41f8" x="529.351818" y="188.44" style="stroke: #000000; stroke-width: 0.8"/>
|
||||
</g>
|
||||
</g>
|
||||
<g id="text_10">
|
||||
|
|
@ -555,11 +554,11 @@ z
|
|||
<g id="line2d_21">
|
||||
<path d="M 580.080909 188.44
|
||||
L 580.080909 25.44
|
||||
" clip-path="url(#p448fd06892)" style="fill: none; stroke-dasharray: 0.8,1.32; stroke-dashoffset: 0; stroke: #b0b0b0; stroke-opacity: 0.5; stroke-width: 0.8"/>
|
||||
" clip-path="url(#pce73ba693e)" style="fill: none; stroke-dasharray: 0.8,1.32; stroke-dashoffset: 0; stroke: #b0b0b0; stroke-opacity: 0.5; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g id="line2d_22">
|
||||
<g>
|
||||
<use xlink:href="#mfeb5fcddc7" x="580.080909" y="188.44" style="stroke: #000000; stroke-width: 0.8"/>
|
||||
<use xlink:href="#mf0a04b41f8" x="580.080909" y="188.44" style="stroke: #000000; stroke-width: 0.8"/>
|
||||
</g>
|
||||
</g>
|
||||
<g id="text_11">
|
||||
|
|
@ -574,11 +573,11 @@ L 580.080909 25.44
|
|||
<g id="line2d_23">
|
||||
<path d="M 630.81 188.44
|
||||
L 630.81 25.44
|
||||
" clip-path="url(#p448fd06892)" style="fill: none; stroke-dasharray: 0.8,1.32; stroke-dashoffset: 0; stroke: #b0b0b0; stroke-opacity: 0.5; stroke-width: 0.8"/>
|
||||
" clip-path="url(#pce73ba693e)" style="fill: none; stroke-dasharray: 0.8,1.32; stroke-dashoffset: 0; stroke: #b0b0b0; stroke-opacity: 0.5; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g id="line2d_24">
|
||||
<g>
|
||||
<use xlink:href="#mfeb5fcddc7" x="630.81" y="188.44" style="stroke: #000000; stroke-width: 0.8"/>
|
||||
<use xlink:href="#mf0a04b41f8" x="630.81" y="188.44" style="stroke: #000000; stroke-width: 0.8"/>
|
||||
</g>
|
||||
</g>
|
||||
<g id="text_12">
|
||||
|
|
@ -724,12 +723,12 @@ z
|
|||
<g id="ytick_1">
|
||||
<g id="line2d_25">
|
||||
<defs>
|
||||
<path id="m2b8ef16b3a" d="M 0 0
|
||||
<path id="mc0b9ff744f" d="M 0 0
|
||||
L -3.5 0
|
||||
" style="stroke: #000000; stroke-width: 0.8"/>
|
||||
</defs>
|
||||
<g>
|
||||
<use xlink:href="#m2b8ef16b3a" x="72.79" y="48.829483" style="stroke: #000000; stroke-width: 0.8"/>
|
||||
<use xlink:href="#mc0b9ff744f" x="72.79" y="48.829483" style="stroke: #000000; stroke-width: 0.8"/>
|
||||
</g>
|
||||
</g>
|
||||
<g id="text_14">
|
||||
|
|
@ -843,7 +842,7 @@ z
|
|||
<g id="ytick_2">
|
||||
<g id="line2d_26">
|
||||
<g>
|
||||
<use xlink:href="#m2b8ef16b3a" x="72.79" y="106.94" style="stroke: #000000; stroke-width: 0.8"/>
|
||||
<use xlink:href="#mc0b9ff744f" x="72.79" y="106.94" style="stroke: #000000; stroke-width: 0.8"/>
|
||||
</g>
|
||||
</g>
|
||||
<g id="text_15">
|
||||
|
|
@ -884,7 +883,7 @@ z
|
|||
<g id="ytick_3">
|
||||
<g id="line2d_27">
|
||||
<g>
|
||||
<use xlink:href="#m2b8ef16b3a" x="72.79" y="165.050517" style="stroke: #000000; stroke-width: 0.8"/>
|
||||
<use xlink:href="#mc0b9ff744f" x="72.79" y="165.050517" style="stroke: #000000; stroke-width: 0.8"/>
|
||||
</g>
|
||||
</g>
|
||||
<g id="text_16">
|
||||
|
|
@ -1320,7 +1319,7 @@ z
|
|||
</g>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="p448fd06892">
|
||||
<clipPath id="pce73ba693e">
|
||||
<rect x="72.79" y="25.44" width="558.02" height="163"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 55 KiB |
|
Before Width: | Height: | Size: 42 KiB |
|
Before Width: | Height: | Size: 84 KiB |
|
Before Width: | Height: | Size: 86 KiB |
|
Before Width: | Height: | Size: 52 KiB |
|
Before Width: | Height: | Size: 158 KiB |
|
Before Width: | Height: | Size: 144 KiB |
|
Before Width: | Height: | Size: 84 KiB |
|
Before Width: | Height: | Size: 99 KiB |
|
Before Width: | Height: | Size: 132 KiB |
|
Before Width: | Height: | Size: 102 KiB |
|
Before Width: | Height: | Size: 54 KiB |
|
Before Width: | Height: | Size: 142 KiB |
|
Before Width: | Height: | Size: 101 KiB |
|
Before Width: | Height: | Size: 99 KiB |
|
Before Width: | Height: | Size: 94 KiB |
|
Before Width: | Height: | Size: 157 KiB |
|
Before Width: | Height: | Size: 138 KiB |
|
Before Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 68 KiB |
|
Before Width: | Height: | Size: 194 KiB |
|
Before Width: | Height: | Size: 101 KiB |
|
Before Width: | Height: | Size: 75 KiB |
|
Before Width: | Height: | Size: 104 KiB |
|
Before Width: | Height: | Size: 113 KiB |
|
Before Width: | Height: | Size: 230 KiB |
|
|
@ -1205,66 +1205,71 @@ Vorteil der Optimierung: 300.00 EUR pro Tag (15.0 %)
|
|||
<span id="cb9-34"><a href="#cb9-34" aria-hidden="true" tabindex="-1"></a><span class="im">from</span> or_kern <span class="im">import</span> (lade_produktionsproblem, loese_mit_glop, pruefe_loesung,</span>
|
||||
<span id="cb9-35"><a href="#cb9-35" aria-hidden="true" tabindex="-1"></a> schreibe_ergebnis)</span>
|
||||
<span id="cb9-36"><a href="#cb9-36" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb9-37"><a href="#cb9-37" aria-hidden="true" tabindex="-1"></a>EINGABE <span class="op">=</span> <span class="st">"produktionsmix.xlsx"</span></span>
|
||||
<span id="cb9-38"><a href="#cb9-38" aria-hidden="true" tabindex="-1"></a>AUSGABE <span class="op">=</span> <span class="st">"produktionsmix_ergebnis.xlsx"</span></span>
|
||||
<span id="cb9-39"><a href="#cb9-39" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb9-40"><a href="#cb9-40" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb9-41"><a href="#cb9-41" aria-hidden="true" tabindex="-1"></a><span class="kw">def</span> lege_beispieldatei_an(pfad: <span class="bu">str</span>) <span class="op">-></span> <span class="va">None</span>:</span>
|
||||
<span id="cb9-42"><a href="#cb9-42" aria-hidden="true" tabindex="-1"></a> <span class="co">"""Schreibt die Eingabemappe, wie sie auch aus dem Controlling kaeme."""</span></span>
|
||||
<span id="cb9-43"><a href="#cb9-43" aria-hidden="true" tabindex="-1"></a> produkte <span class="op">=</span> pd.DataFrame({</span>
|
||||
<span id="cb9-44"><a href="#cb9-44" aria-hidden="true" tabindex="-1"></a> <span class="st">"Produkt"</span>: [<span class="st">"Tisch"</span>, <span class="st">"Stuhl"</span>, <span class="st">"Regal"</span>],</span>
|
||||
<span id="cb9-45"><a href="#cb9-45" aria-hidden="true" tabindex="-1"></a> <span class="st">"Deckungsbeitrag"</span>: [<span class="fl">240.0</span>, <span class="fl">60.0</span>, <span class="fl">130.0</span>],</span>
|
||||
<span id="cb9-46"><a href="#cb9-46" aria-hidden="true" tabindex="-1"></a> <span class="st">"Montagestunden"</span>: [<span class="fl">3.0</span>, <span class="fl">1.0</span>, <span class="fl">2.0</span>],</span>
|
||||
<span id="cb9-47"><a href="#cb9-47" aria-hidden="true" tabindex="-1"></a> <span class="st">"Plattenmaterial"</span>: [<span class="fl">6.0</span>, <span class="fl">1.0</span>, <span class="fl">4.0</span>],</span>
|
||||
<span id="cb9-48"><a href="#cb9-48" aria-hidden="true" tabindex="-1"></a> })</span>
|
||||
<span id="cb9-49"><a href="#cb9-49" aria-hidden="true" tabindex="-1"></a> kapazitaeten <span class="op">=</span> pd.DataFrame({</span>
|
||||
<span id="cb9-50"><a href="#cb9-50" aria-hidden="true" tabindex="-1"></a> <span class="st">"Ressource"</span>: [<span class="st">"Montagestunden"</span>, <span class="st">"Plattenmaterial"</span>],</span>
|
||||
<span id="cb9-51"><a href="#cb9-51" aria-hidden="true" tabindex="-1"></a> <span class="st">"Verfuegbar"</span>: [<span class="fl">150.0</span>, <span class="fl">240.0</span>],</span>
|
||||
<span id="cb9-52"><a href="#cb9-52" aria-hidden="true" tabindex="-1"></a> })</span>
|
||||
<span id="cb9-53"><a href="#cb9-53" aria-hidden="true" tabindex="-1"></a> <span class="cf">with</span> pd.ExcelWriter(pfad, engine<span class="op">=</span><span class="st">"openpyxl"</span>) <span class="im">as</span> mappe:</span>
|
||||
<span id="cb9-54"><a href="#cb9-54" aria-hidden="true" tabindex="-1"></a> produkte.to_excel(mappe, sheet_name<span class="op">=</span><span class="st">"Produkte"</span>, index<span class="op">=</span><span class="va">False</span>)</span>
|
||||
<span id="cb9-55"><a href="#cb9-55" aria-hidden="true" tabindex="-1"></a> kapazitaeten.to_excel(mappe, sheet_name<span class="op">=</span><span class="st">"Kapazitaeten"</span>, index<span class="op">=</span><span class="va">False</span>)</span>
|
||||
<span id="cb9-56"><a href="#cb9-56" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb9-57"><a href="#cb9-57" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb9-58"><a href="#cb9-58" aria-hidden="true" tabindex="-1"></a><span class="cf">if</span> <span class="va">__name__</span> <span class="op">==</span> <span class="st">"__main__"</span>:</span>
|
||||
<span id="cb9-59"><a href="#cb9-59" aria-hidden="true" tabindex="-1"></a> <span class="cf">if</span> <span class="kw">not</span> os.path.exists(EINGABE):</span>
|
||||
<span id="cb9-60"><a href="#cb9-60" aria-hidden="true" tabindex="-1"></a> lege_beispieldatei_an(EINGABE)</span>
|
||||
<span id="cb9-61"><a href="#cb9-61" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="ss">f"Beispiel-Eingabedatei angelegt: </span><span class="sc">{</span>EINGABE<span class="sc">}</span><span class="ss">"</span>)</span>
|
||||
<span id="cb9-37"><a href="#cb9-37" aria-hidden="true" tabindex="-1"></a><span class="co"># Die Mappen liegen NEBEN diesem Programm, nicht im aktuellen</span></span>
|
||||
<span id="cb9-38"><a href="#cb9-38" aria-hidden="true" tabindex="-1"></a><span class="co"># Arbeitsverzeichnis. Sonst haengt es davon ab, aus welchem Ordner man das</span></span>
|
||||
<span id="cb9-39"><a href="#cb9-39" aria-hidden="true" tabindex="-1"></a><span class="co"># Skript startet, wo die Dateien landen - und wer es aus der</span></span>
|
||||
<span id="cb9-40"><a href="#cb9-40" aria-hidden="true" tabindex="-1"></a><span class="co"># Repository-Wurzel aufruft, verstreut sie dort.</span></span>
|
||||
<span id="cb9-41"><a href="#cb9-41" aria-hidden="true" tabindex="-1"></a>HIER <span class="op">=</span> os.path.dirname(os.path.abspath(<span class="va">__file__</span>))</span>
|
||||
<span id="cb9-42"><a href="#cb9-42" aria-hidden="true" tabindex="-1"></a>EINGABE <span class="op">=</span> os.path.join(HIER, <span class="st">"produktionsmix.xlsx"</span>)</span>
|
||||
<span id="cb9-43"><a href="#cb9-43" aria-hidden="true" tabindex="-1"></a>AUSGABE <span class="op">=</span> os.path.join(HIER, <span class="st">"produktionsmix_ergebnis.xlsx"</span>)</span>
|
||||
<span id="cb9-44"><a href="#cb9-44" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb9-45"><a href="#cb9-45" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb9-46"><a href="#cb9-46" aria-hidden="true" tabindex="-1"></a><span class="kw">def</span> lege_beispieldatei_an(pfad: <span class="bu">str</span>) <span class="op">-></span> <span class="va">None</span>:</span>
|
||||
<span id="cb9-47"><a href="#cb9-47" aria-hidden="true" tabindex="-1"></a> <span class="co">"""Schreibt die Eingabemappe, wie sie auch aus dem Controlling kaeme."""</span></span>
|
||||
<span id="cb9-48"><a href="#cb9-48" aria-hidden="true" tabindex="-1"></a> produkte <span class="op">=</span> pd.DataFrame({</span>
|
||||
<span id="cb9-49"><a href="#cb9-49" aria-hidden="true" tabindex="-1"></a> <span class="st">"Produkt"</span>: [<span class="st">"Tisch"</span>, <span class="st">"Stuhl"</span>, <span class="st">"Regal"</span>],</span>
|
||||
<span id="cb9-50"><a href="#cb9-50" aria-hidden="true" tabindex="-1"></a> <span class="st">"Deckungsbeitrag"</span>: [<span class="fl">240.0</span>, <span class="fl">60.0</span>, <span class="fl">130.0</span>],</span>
|
||||
<span id="cb9-51"><a href="#cb9-51" aria-hidden="true" tabindex="-1"></a> <span class="st">"Montagestunden"</span>: [<span class="fl">3.0</span>, <span class="fl">1.0</span>, <span class="fl">2.0</span>],</span>
|
||||
<span id="cb9-52"><a href="#cb9-52" aria-hidden="true" tabindex="-1"></a> <span class="st">"Plattenmaterial"</span>: [<span class="fl">6.0</span>, <span class="fl">1.0</span>, <span class="fl">4.0</span>],</span>
|
||||
<span id="cb9-53"><a href="#cb9-53" aria-hidden="true" tabindex="-1"></a> })</span>
|
||||
<span id="cb9-54"><a href="#cb9-54" aria-hidden="true" tabindex="-1"></a> kapazitaeten <span class="op">=</span> pd.DataFrame({</span>
|
||||
<span id="cb9-55"><a href="#cb9-55" aria-hidden="true" tabindex="-1"></a> <span class="st">"Ressource"</span>: [<span class="st">"Montagestunden"</span>, <span class="st">"Plattenmaterial"</span>],</span>
|
||||
<span id="cb9-56"><a href="#cb9-56" aria-hidden="true" tabindex="-1"></a> <span class="st">"Verfuegbar"</span>: [<span class="fl">150.0</span>, <span class="fl">240.0</span>],</span>
|
||||
<span id="cb9-57"><a href="#cb9-57" aria-hidden="true" tabindex="-1"></a> })</span>
|
||||
<span id="cb9-58"><a href="#cb9-58" aria-hidden="true" tabindex="-1"></a> <span class="cf">with</span> pd.ExcelWriter(pfad, engine<span class="op">=</span><span class="st">"openpyxl"</span>) <span class="im">as</span> mappe:</span>
|
||||
<span id="cb9-59"><a href="#cb9-59" aria-hidden="true" tabindex="-1"></a> produkte.to_excel(mappe, sheet_name<span class="op">=</span><span class="st">"Produkte"</span>, index<span class="op">=</span><span class="va">False</span>)</span>
|
||||
<span id="cb9-60"><a href="#cb9-60" aria-hidden="true" tabindex="-1"></a> kapazitaeten.to_excel(mappe, sheet_name<span class="op">=</span><span class="st">"Kapazitaeten"</span>, index<span class="op">=</span><span class="va">False</span>)</span>
|
||||
<span id="cb9-61"><a href="#cb9-61" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb9-62"><a href="#cb9-62" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb9-63"><a href="#cb9-63" aria-hidden="true" tabindex="-1"></a> <span class="co"># 1. Lesen und pruefen. Faellt hier etwas auf, ist der Fehler noch</span></span>
|
||||
<span id="cb9-64"><a href="#cb9-64" aria-hidden="true" tabindex="-1"></a> <span class="co"># zuzuordnen - spaeter waere er nur noch eine merkwuerdige Zahl.</span></span>
|
||||
<span id="cb9-65"><a href="#cb9-65" aria-hidden="true" tabindex="-1"></a> problem <span class="op">=</span> lade_produktionsproblem(EINGABE)</span>
|
||||
<span id="cb9-66"><a href="#cb9-66" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb9-67"><a href="#cb9-67" aria-hidden="true" tabindex="-1"></a> <span class="co"># 2. Loesen. Einzige solverabhaengige Zeile des ganzen Programms -</span></span>
|
||||
<span id="cb9-68"><a href="#cb9-68" aria-hidden="true" tabindex="-1"></a> <span class="co"># 'loese_mit_scipy' waere ein Einzeiler-Wechsel.</span></span>
|
||||
<span id="cb9-69"><a href="#cb9-69" aria-hidden="true" tabindex="-1"></a> loesung <span class="op">=</span> loese_mit_glop(problem)</span>
|
||||
<span id="cb9-70"><a href="#cb9-70" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb9-71"><a href="#cb9-71" aria-hidden="true" tabindex="-1"></a> <span class="co"># 3. Abnahmepruefung gegen die Anforderungen, ohne den Solver zu fragen.</span></span>
|
||||
<span id="cb9-72"><a href="#cb9-72" aria-hidden="true" tabindex="-1"></a> beanstandungen <span class="op">=</span> pruefe_loesung(problem, loesung)</span>
|
||||
<span id="cb9-73"><a href="#cb9-73" aria-hidden="true" tabindex="-1"></a> <span class="cf">if</span> beanstandungen:</span>
|
||||
<span id="cb9-74"><a href="#cb9-74" aria-hidden="true" tabindex="-1"></a> <span class="cf">raise</span> <span class="pp">SystemExit</span>(<span class="st">"Abnahmepruefung fehlgeschlagen:</span><span class="ch">\n</span><span class="st"> - "</span></span>
|
||||
<span id="cb9-75"><a href="#cb9-75" aria-hidden="true" tabindex="-1"></a> <span class="op">+</span> <span class="st">"</span><span class="ch">\n</span><span class="st"> - "</span>.join(beanstandungen))</span>
|
||||
<span id="cb9-76"><a href="#cb9-76" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb9-77"><a href="#cb9-77" aria-hidden="true" tabindex="-1"></a> <span class="co"># 4. Zurueckschreiben - im Format, das die Fachabteilung ohnehin benutzt.</span></span>
|
||||
<span id="cb9-78"><a href="#cb9-78" aria-hidden="true" tabindex="-1"></a> schreibe_ergebnis(AUSGABE, problem, loesung)</span>
|
||||
<span id="cb9-79"><a href="#cb9-79" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb9-80"><a href="#cb9-80" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="st">"="</span> <span class="op">*</span> <span class="dv">66</span>)</span>
|
||||
<span id="cb9-81"><a href="#cb9-81" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="st">" PRODUKTIONSPLAN AUS DER EXCEL-MAPPE"</span>)</span>
|
||||
<span id="cb9-82"><a href="#cb9-82" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="st">"="</span> <span class="op">*</span> <span class="dv">66</span>)</span>
|
||||
<span id="cb9-83"><a href="#cb9-83" aria-hidden="true" tabindex="-1"></a> <span class="cf">for</span> produkt <span class="kw">in</span> problem.produkte:</span>
|
||||
<span id="cb9-84"><a href="#cb9-84" aria-hidden="true" tabindex="-1"></a> menge <span class="op">=</span> loesung.werte[produkt.name]</span>
|
||||
<span id="cb9-85"><a href="#cb9-85" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="ss">f"</span><span class="sc">{</span>produkt<span class="sc">.</span>name<span class="sc">:<18}</span><span class="ss"> </span><span class="sc">{</span>menge<span class="sc">:8.1f}</span><span class="ss"> Stueck "</span></span>
|
||||
<span id="cb9-86"><a href="#cb9-86" aria-hidden="true" tabindex="-1"></a> <span class="ss">f"</span><span class="sc">{</span>menge <span class="op">*</span> produkt<span class="sc">.</span>deckungsbeitrag<span class="sc">:12,.2f}</span><span class="ss"> EUR"</span>)</span>
|
||||
<span id="cb9-87"><a href="#cb9-87" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="st">"-"</span> <span class="op">*</span> <span class="dv">66</span>)</span>
|
||||
<span id="cb9-88"><a href="#cb9-88" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(loesung.als_bericht())</span>
|
||||
<span id="cb9-89"><a href="#cb9-89" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="st">"Abnahmepruefung: bestanden</span><span class="ch">\n</span><span class="st">"</span>)</span>
|
||||
<span id="cb9-90"><a href="#cb9-90" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb9-91"><a href="#cb9-91" aria-hidden="true" tabindex="-1"></a> <span class="co"># Die Schattenpreise beantworten die Frage, die der Plan nicht stellt:</span></span>
|
||||
<span id="cb9-92"><a href="#cb9-92" aria-hidden="true" tabindex="-1"></a> <span class="co"># Was waere eine zusaetzliche Einheit dieser Ressource wert?</span></span>
|
||||
<span id="cb9-93"><a href="#cb9-93" aria-hidden="true" tabindex="-1"></a> <span class="cf">for</span> ressource, preis <span class="kw">in</span> loesung.schattenpreise.items():</span>
|
||||
<span id="cb9-94"><a href="#cb9-94" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="ss">f" eine Einheit </span><span class="sc">{</span>ressource<span class="sc">:<18}</span><span class="ss"> mehr waere wert: </span><span class="sc">{</span>preis<span class="sc">:7.2f}</span><span class="ss"> EUR"</span>)</span>
|
||||
<span id="cb9-95"><a href="#cb9-95" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="st">"="</span> <span class="op">*</span> <span class="dv">66</span>)</span>
|
||||
<span id="cb9-96"><a href="#cb9-96" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="ss">f"Ergebnis geschrieben nach: </span><span class="sc">{</span>AUSGABE<span class="sc">}</span><span class="ss">"</span>)</span></code></pre></div>
|
||||
<span id="cb9-63"><a href="#cb9-63" aria-hidden="true" tabindex="-1"></a><span class="cf">if</span> <span class="va">__name__</span> <span class="op">==</span> <span class="st">"__main__"</span>:</span>
|
||||
<span id="cb9-64"><a href="#cb9-64" aria-hidden="true" tabindex="-1"></a> <span class="cf">if</span> <span class="kw">not</span> os.path.exists(EINGABE):</span>
|
||||
<span id="cb9-65"><a href="#cb9-65" aria-hidden="true" tabindex="-1"></a> lege_beispieldatei_an(EINGABE)</span>
|
||||
<span id="cb9-66"><a href="#cb9-66" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="ss">f"Beispiel-Eingabedatei angelegt: </span><span class="sc">{</span>EINGABE<span class="sc">}</span><span class="ss">"</span>)</span>
|
||||
<span id="cb9-67"><a href="#cb9-67" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb9-68"><a href="#cb9-68" aria-hidden="true" tabindex="-1"></a> <span class="co"># 1. Lesen und pruefen. Faellt hier etwas auf, ist der Fehler noch</span></span>
|
||||
<span id="cb9-69"><a href="#cb9-69" aria-hidden="true" tabindex="-1"></a> <span class="co"># zuzuordnen - spaeter waere er nur noch eine merkwuerdige Zahl.</span></span>
|
||||
<span id="cb9-70"><a href="#cb9-70" aria-hidden="true" tabindex="-1"></a> problem <span class="op">=</span> lade_produktionsproblem(EINGABE)</span>
|
||||
<span id="cb9-71"><a href="#cb9-71" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb9-72"><a href="#cb9-72" aria-hidden="true" tabindex="-1"></a> <span class="co"># 2. Loesen. Einzige solverabhaengige Zeile des ganzen Programms -</span></span>
|
||||
<span id="cb9-73"><a href="#cb9-73" aria-hidden="true" tabindex="-1"></a> <span class="co"># 'loese_mit_scipy' waere ein Einzeiler-Wechsel.</span></span>
|
||||
<span id="cb9-74"><a href="#cb9-74" aria-hidden="true" tabindex="-1"></a> loesung <span class="op">=</span> loese_mit_glop(problem)</span>
|
||||
<span id="cb9-75"><a href="#cb9-75" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb9-76"><a href="#cb9-76" aria-hidden="true" tabindex="-1"></a> <span class="co"># 3. Abnahmepruefung gegen die Anforderungen, ohne den Solver zu fragen.</span></span>
|
||||
<span id="cb9-77"><a href="#cb9-77" aria-hidden="true" tabindex="-1"></a> beanstandungen <span class="op">=</span> pruefe_loesung(problem, loesung)</span>
|
||||
<span id="cb9-78"><a href="#cb9-78" aria-hidden="true" tabindex="-1"></a> <span class="cf">if</span> beanstandungen:</span>
|
||||
<span id="cb9-79"><a href="#cb9-79" aria-hidden="true" tabindex="-1"></a> <span class="cf">raise</span> <span class="pp">SystemExit</span>(<span class="st">"Abnahmepruefung fehlgeschlagen:</span><span class="ch">\n</span><span class="st"> - "</span></span>
|
||||
<span id="cb9-80"><a href="#cb9-80" aria-hidden="true" tabindex="-1"></a> <span class="op">+</span> <span class="st">"</span><span class="ch">\n</span><span class="st"> - "</span>.join(beanstandungen))</span>
|
||||
<span id="cb9-81"><a href="#cb9-81" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb9-82"><a href="#cb9-82" aria-hidden="true" tabindex="-1"></a> <span class="co"># 4. Zurueckschreiben - im Format, das die Fachabteilung ohnehin benutzt.</span></span>
|
||||
<span id="cb9-83"><a href="#cb9-83" aria-hidden="true" tabindex="-1"></a> schreibe_ergebnis(AUSGABE, problem, loesung)</span>
|
||||
<span id="cb9-84"><a href="#cb9-84" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb9-85"><a href="#cb9-85" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="st">"="</span> <span class="op">*</span> <span class="dv">66</span>)</span>
|
||||
<span id="cb9-86"><a href="#cb9-86" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="st">" PRODUKTIONSPLAN AUS DER EXCEL-MAPPE"</span>)</span>
|
||||
<span id="cb9-87"><a href="#cb9-87" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="st">"="</span> <span class="op">*</span> <span class="dv">66</span>)</span>
|
||||
<span id="cb9-88"><a href="#cb9-88" aria-hidden="true" tabindex="-1"></a> <span class="cf">for</span> produkt <span class="kw">in</span> problem.produkte:</span>
|
||||
<span id="cb9-89"><a href="#cb9-89" aria-hidden="true" tabindex="-1"></a> menge <span class="op">=</span> loesung.werte[produkt.name]</span>
|
||||
<span id="cb9-90"><a href="#cb9-90" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="ss">f"</span><span class="sc">{</span>produkt<span class="sc">.</span>name<span class="sc">:<18}</span><span class="ss"> </span><span class="sc">{</span>menge<span class="sc">:8.1f}</span><span class="ss"> Stueck "</span></span>
|
||||
<span id="cb9-91"><a href="#cb9-91" aria-hidden="true" tabindex="-1"></a> <span class="ss">f"</span><span class="sc">{</span>menge <span class="op">*</span> produkt<span class="sc">.</span>deckungsbeitrag<span class="sc">:12,.2f}</span><span class="ss"> EUR"</span>)</span>
|
||||
<span id="cb9-92"><a href="#cb9-92" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="st">"-"</span> <span class="op">*</span> <span class="dv">66</span>)</span>
|
||||
<span id="cb9-93"><a href="#cb9-93" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(loesung.als_bericht())</span>
|
||||
<span id="cb9-94"><a href="#cb9-94" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="st">"Abnahmepruefung: bestanden</span><span class="ch">\n</span><span class="st">"</span>)</span>
|
||||
<span id="cb9-95"><a href="#cb9-95" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb9-96"><a href="#cb9-96" aria-hidden="true" tabindex="-1"></a> <span class="co"># Die Schattenpreise beantworten die Frage, die der Plan nicht stellt:</span></span>
|
||||
<span id="cb9-97"><a href="#cb9-97" aria-hidden="true" tabindex="-1"></a> <span class="co"># Was waere eine zusaetzliche Einheit dieser Ressource wert?</span></span>
|
||||
<span id="cb9-98"><a href="#cb9-98" aria-hidden="true" tabindex="-1"></a> <span class="cf">for</span> ressource, preis <span class="kw">in</span> loesung.schattenpreise.items():</span>
|
||||
<span id="cb9-99"><a href="#cb9-99" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="ss">f" eine Einheit </span><span class="sc">{</span>ressource<span class="sc">:<18}</span><span class="ss"> mehr waere wert: </span><span class="sc">{</span>preis<span class="sc">:7.2f}</span><span class="ss"> EUR"</span>)</span>
|
||||
<span id="cb9-100"><a href="#cb9-100" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="st">"="</span> <span class="op">*</span> <span class="dv">66</span>)</span>
|
||||
<span id="cb9-101"><a href="#cb9-101" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="ss">f"Ergebnis geschrieben nach: </span><span class="sc">{</span>AUSGABE<span class="sc">}</span><span class="ss">"</span>)</span></code></pre></div>
|
||||
<p><strong>Erwartete Ausgabe:</strong></p>
|
||||
<pre><code>Beispiel-Eingabedatei angelegt: produktionsmix.xlsx
|
||||
==================================================================
|
||||
|
|
|
|||
|
|
@ -4198,66 +4198,71 @@ Vorteil der Optimierung: 300.00 EUR pro Tag (15.0 %)
|
|||
<span id="cb13-34"><a href="#cb13-34" aria-hidden="true" tabindex="-1"></a><span class="im">from</span> or_kern <span class="im">import</span> (lade_produktionsproblem, loese_mit_glop, pruefe_loesung,</span>
|
||||
<span id="cb13-35"><a href="#cb13-35" aria-hidden="true" tabindex="-1"></a> schreibe_ergebnis)</span>
|
||||
<span id="cb13-36"><a href="#cb13-36" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb13-37"><a href="#cb13-37" aria-hidden="true" tabindex="-1"></a>EINGABE <span class="op">=</span> <span class="st">"produktionsmix.xlsx"</span></span>
|
||||
<span id="cb13-38"><a href="#cb13-38" aria-hidden="true" tabindex="-1"></a>AUSGABE <span class="op">=</span> <span class="st">"produktionsmix_ergebnis.xlsx"</span></span>
|
||||
<span id="cb13-39"><a href="#cb13-39" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb13-40"><a href="#cb13-40" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb13-41"><a href="#cb13-41" aria-hidden="true" tabindex="-1"></a><span class="kw">def</span> lege_beispieldatei_an(pfad: <span class="bu">str</span>) <span class="op">-></span> <span class="va">None</span>:</span>
|
||||
<span id="cb13-42"><a href="#cb13-42" aria-hidden="true" tabindex="-1"></a> <span class="co">"""Schreibt die Eingabemappe, wie sie auch aus dem Controlling kaeme."""</span></span>
|
||||
<span id="cb13-43"><a href="#cb13-43" aria-hidden="true" tabindex="-1"></a> produkte <span class="op">=</span> pd.DataFrame({</span>
|
||||
<span id="cb13-44"><a href="#cb13-44" aria-hidden="true" tabindex="-1"></a> <span class="st">"Produkt"</span>: [<span class="st">"Tisch"</span>, <span class="st">"Stuhl"</span>, <span class="st">"Regal"</span>],</span>
|
||||
<span id="cb13-45"><a href="#cb13-45" aria-hidden="true" tabindex="-1"></a> <span class="st">"Deckungsbeitrag"</span>: [<span class="fl">240.0</span>, <span class="fl">60.0</span>, <span class="fl">130.0</span>],</span>
|
||||
<span id="cb13-46"><a href="#cb13-46" aria-hidden="true" tabindex="-1"></a> <span class="st">"Montagestunden"</span>: [<span class="fl">3.0</span>, <span class="fl">1.0</span>, <span class="fl">2.0</span>],</span>
|
||||
<span id="cb13-47"><a href="#cb13-47" aria-hidden="true" tabindex="-1"></a> <span class="st">"Plattenmaterial"</span>: [<span class="fl">6.0</span>, <span class="fl">1.0</span>, <span class="fl">4.0</span>],</span>
|
||||
<span id="cb13-48"><a href="#cb13-48" aria-hidden="true" tabindex="-1"></a> })</span>
|
||||
<span id="cb13-49"><a href="#cb13-49" aria-hidden="true" tabindex="-1"></a> kapazitaeten <span class="op">=</span> pd.DataFrame({</span>
|
||||
<span id="cb13-50"><a href="#cb13-50" aria-hidden="true" tabindex="-1"></a> <span class="st">"Ressource"</span>: [<span class="st">"Montagestunden"</span>, <span class="st">"Plattenmaterial"</span>],</span>
|
||||
<span id="cb13-51"><a href="#cb13-51" aria-hidden="true" tabindex="-1"></a> <span class="st">"Verfuegbar"</span>: [<span class="fl">150.0</span>, <span class="fl">240.0</span>],</span>
|
||||
<span id="cb13-52"><a href="#cb13-52" aria-hidden="true" tabindex="-1"></a> })</span>
|
||||
<span id="cb13-53"><a href="#cb13-53" aria-hidden="true" tabindex="-1"></a> <span class="cf">with</span> pd.ExcelWriter(pfad, engine<span class="op">=</span><span class="st">"openpyxl"</span>) <span class="im">as</span> mappe:</span>
|
||||
<span id="cb13-54"><a href="#cb13-54" aria-hidden="true" tabindex="-1"></a> produkte.to_excel(mappe, sheet_name<span class="op">=</span><span class="st">"Produkte"</span>, index<span class="op">=</span><span class="va">False</span>)</span>
|
||||
<span id="cb13-55"><a href="#cb13-55" aria-hidden="true" tabindex="-1"></a> kapazitaeten.to_excel(mappe, sheet_name<span class="op">=</span><span class="st">"Kapazitaeten"</span>, index<span class="op">=</span><span class="va">False</span>)</span>
|
||||
<span id="cb13-56"><a href="#cb13-56" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb13-57"><a href="#cb13-57" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb13-58"><a href="#cb13-58" aria-hidden="true" tabindex="-1"></a><span class="cf">if</span> <span class="va">__name__</span> <span class="op">==</span> <span class="st">"__main__"</span>:</span>
|
||||
<span id="cb13-59"><a href="#cb13-59" aria-hidden="true" tabindex="-1"></a> <span class="cf">if</span> <span class="kw">not</span> os.path.exists(EINGABE):</span>
|
||||
<span id="cb13-60"><a href="#cb13-60" aria-hidden="true" tabindex="-1"></a> lege_beispieldatei_an(EINGABE)</span>
|
||||
<span id="cb13-61"><a href="#cb13-61" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="ss">f"Beispiel-Eingabedatei angelegt: </span><span class="sc">{</span>EINGABE<span class="sc">}</span><span class="ss">"</span>)</span>
|
||||
<span id="cb13-37"><a href="#cb13-37" aria-hidden="true" tabindex="-1"></a><span class="co"># Die Mappen liegen NEBEN diesem Programm, nicht im aktuellen</span></span>
|
||||
<span id="cb13-38"><a href="#cb13-38" aria-hidden="true" tabindex="-1"></a><span class="co"># Arbeitsverzeichnis. Sonst haengt es davon ab, aus welchem Ordner man das</span></span>
|
||||
<span id="cb13-39"><a href="#cb13-39" aria-hidden="true" tabindex="-1"></a><span class="co"># Skript startet, wo die Dateien landen - und wer es aus der</span></span>
|
||||
<span id="cb13-40"><a href="#cb13-40" aria-hidden="true" tabindex="-1"></a><span class="co"># Repository-Wurzel aufruft, verstreut sie dort.</span></span>
|
||||
<span id="cb13-41"><a href="#cb13-41" aria-hidden="true" tabindex="-1"></a>HIER <span class="op">=</span> os.path.dirname(os.path.abspath(<span class="va">__file__</span>))</span>
|
||||
<span id="cb13-42"><a href="#cb13-42" aria-hidden="true" tabindex="-1"></a>EINGABE <span class="op">=</span> os.path.join(HIER, <span class="st">"produktionsmix.xlsx"</span>)</span>
|
||||
<span id="cb13-43"><a href="#cb13-43" aria-hidden="true" tabindex="-1"></a>AUSGABE <span class="op">=</span> os.path.join(HIER, <span class="st">"produktionsmix_ergebnis.xlsx"</span>)</span>
|
||||
<span id="cb13-44"><a href="#cb13-44" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb13-45"><a href="#cb13-45" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb13-46"><a href="#cb13-46" aria-hidden="true" tabindex="-1"></a><span class="kw">def</span> lege_beispieldatei_an(pfad: <span class="bu">str</span>) <span class="op">-></span> <span class="va">None</span>:</span>
|
||||
<span id="cb13-47"><a href="#cb13-47" aria-hidden="true" tabindex="-1"></a> <span class="co">"""Schreibt die Eingabemappe, wie sie auch aus dem Controlling kaeme."""</span></span>
|
||||
<span id="cb13-48"><a href="#cb13-48" aria-hidden="true" tabindex="-1"></a> produkte <span class="op">=</span> pd.DataFrame({</span>
|
||||
<span id="cb13-49"><a href="#cb13-49" aria-hidden="true" tabindex="-1"></a> <span class="st">"Produkt"</span>: [<span class="st">"Tisch"</span>, <span class="st">"Stuhl"</span>, <span class="st">"Regal"</span>],</span>
|
||||
<span id="cb13-50"><a href="#cb13-50" aria-hidden="true" tabindex="-1"></a> <span class="st">"Deckungsbeitrag"</span>: [<span class="fl">240.0</span>, <span class="fl">60.0</span>, <span class="fl">130.0</span>],</span>
|
||||
<span id="cb13-51"><a href="#cb13-51" aria-hidden="true" tabindex="-1"></a> <span class="st">"Montagestunden"</span>: [<span class="fl">3.0</span>, <span class="fl">1.0</span>, <span class="fl">2.0</span>],</span>
|
||||
<span id="cb13-52"><a href="#cb13-52" aria-hidden="true" tabindex="-1"></a> <span class="st">"Plattenmaterial"</span>: [<span class="fl">6.0</span>, <span class="fl">1.0</span>, <span class="fl">4.0</span>],</span>
|
||||
<span id="cb13-53"><a href="#cb13-53" aria-hidden="true" tabindex="-1"></a> })</span>
|
||||
<span id="cb13-54"><a href="#cb13-54" aria-hidden="true" tabindex="-1"></a> kapazitaeten <span class="op">=</span> pd.DataFrame({</span>
|
||||
<span id="cb13-55"><a href="#cb13-55" aria-hidden="true" tabindex="-1"></a> <span class="st">"Ressource"</span>: [<span class="st">"Montagestunden"</span>, <span class="st">"Plattenmaterial"</span>],</span>
|
||||
<span id="cb13-56"><a href="#cb13-56" aria-hidden="true" tabindex="-1"></a> <span class="st">"Verfuegbar"</span>: [<span class="fl">150.0</span>, <span class="fl">240.0</span>],</span>
|
||||
<span id="cb13-57"><a href="#cb13-57" aria-hidden="true" tabindex="-1"></a> })</span>
|
||||
<span id="cb13-58"><a href="#cb13-58" aria-hidden="true" tabindex="-1"></a> <span class="cf">with</span> pd.ExcelWriter(pfad, engine<span class="op">=</span><span class="st">"openpyxl"</span>) <span class="im">as</span> mappe:</span>
|
||||
<span id="cb13-59"><a href="#cb13-59" aria-hidden="true" tabindex="-1"></a> produkte.to_excel(mappe, sheet_name<span class="op">=</span><span class="st">"Produkte"</span>, index<span class="op">=</span><span class="va">False</span>)</span>
|
||||
<span id="cb13-60"><a href="#cb13-60" aria-hidden="true" tabindex="-1"></a> kapazitaeten.to_excel(mappe, sheet_name<span class="op">=</span><span class="st">"Kapazitaeten"</span>, index<span class="op">=</span><span class="va">False</span>)</span>
|
||||
<span id="cb13-61"><a href="#cb13-61" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb13-62"><a href="#cb13-62" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb13-63"><a href="#cb13-63" aria-hidden="true" tabindex="-1"></a> <span class="co"># 1. Lesen und pruefen. Faellt hier etwas auf, ist der Fehler noch</span></span>
|
||||
<span id="cb13-64"><a href="#cb13-64" aria-hidden="true" tabindex="-1"></a> <span class="co"># zuzuordnen - spaeter waere er nur noch eine merkwuerdige Zahl.</span></span>
|
||||
<span id="cb13-65"><a href="#cb13-65" aria-hidden="true" tabindex="-1"></a> problem <span class="op">=</span> lade_produktionsproblem(EINGABE)</span>
|
||||
<span id="cb13-66"><a href="#cb13-66" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb13-67"><a href="#cb13-67" aria-hidden="true" tabindex="-1"></a> <span class="co"># 2. Loesen. Einzige solverabhaengige Zeile des ganzen Programms -</span></span>
|
||||
<span id="cb13-68"><a href="#cb13-68" aria-hidden="true" tabindex="-1"></a> <span class="co"># 'loese_mit_scipy' waere ein Einzeiler-Wechsel.</span></span>
|
||||
<span id="cb13-69"><a href="#cb13-69" aria-hidden="true" tabindex="-1"></a> loesung <span class="op">=</span> loese_mit_glop(problem)</span>
|
||||
<span id="cb13-70"><a href="#cb13-70" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb13-71"><a href="#cb13-71" aria-hidden="true" tabindex="-1"></a> <span class="co"># 3. Abnahmepruefung gegen die Anforderungen, ohne den Solver zu fragen.</span></span>
|
||||
<span id="cb13-72"><a href="#cb13-72" aria-hidden="true" tabindex="-1"></a> beanstandungen <span class="op">=</span> pruefe_loesung(problem, loesung)</span>
|
||||
<span id="cb13-73"><a href="#cb13-73" aria-hidden="true" tabindex="-1"></a> <span class="cf">if</span> beanstandungen:</span>
|
||||
<span id="cb13-74"><a href="#cb13-74" aria-hidden="true" tabindex="-1"></a> <span class="cf">raise</span> <span class="pp">SystemExit</span>(<span class="st">"Abnahmepruefung fehlgeschlagen:</span><span class="ch">\n</span><span class="st"> - "</span></span>
|
||||
<span id="cb13-75"><a href="#cb13-75" aria-hidden="true" tabindex="-1"></a> <span class="op">+</span> <span class="st">"</span><span class="ch">\n</span><span class="st"> - "</span>.join(beanstandungen))</span>
|
||||
<span id="cb13-76"><a href="#cb13-76" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb13-77"><a href="#cb13-77" aria-hidden="true" tabindex="-1"></a> <span class="co"># 4. Zurueckschreiben - im Format, das die Fachabteilung ohnehin benutzt.</span></span>
|
||||
<span id="cb13-78"><a href="#cb13-78" aria-hidden="true" tabindex="-1"></a> schreibe_ergebnis(AUSGABE, problem, loesung)</span>
|
||||
<span id="cb13-79"><a href="#cb13-79" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb13-80"><a href="#cb13-80" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="st">"="</span> <span class="op">*</span> <span class="dv">66</span>)</span>
|
||||
<span id="cb13-81"><a href="#cb13-81" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="st">" PRODUKTIONSPLAN AUS DER EXCEL-MAPPE"</span>)</span>
|
||||
<span id="cb13-82"><a href="#cb13-82" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="st">"="</span> <span class="op">*</span> <span class="dv">66</span>)</span>
|
||||
<span id="cb13-83"><a href="#cb13-83" aria-hidden="true" tabindex="-1"></a> <span class="cf">for</span> produkt <span class="kw">in</span> problem.produkte:</span>
|
||||
<span id="cb13-84"><a href="#cb13-84" aria-hidden="true" tabindex="-1"></a> menge <span class="op">=</span> loesung.werte[produkt.name]</span>
|
||||
<span id="cb13-85"><a href="#cb13-85" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="ss">f"</span><span class="sc">{</span>produkt<span class="sc">.</span>name<span class="sc">:<18}</span><span class="ss"> </span><span class="sc">{</span>menge<span class="sc">:8.1f}</span><span class="ss"> Stueck "</span></span>
|
||||
<span id="cb13-86"><a href="#cb13-86" aria-hidden="true" tabindex="-1"></a> <span class="ss">f"</span><span class="sc">{</span>menge <span class="op">*</span> produkt<span class="sc">.</span>deckungsbeitrag<span class="sc">:12,.2f}</span><span class="ss"> EUR"</span>)</span>
|
||||
<span id="cb13-87"><a href="#cb13-87" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="st">"-"</span> <span class="op">*</span> <span class="dv">66</span>)</span>
|
||||
<span id="cb13-88"><a href="#cb13-88" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(loesung.als_bericht())</span>
|
||||
<span id="cb13-89"><a href="#cb13-89" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="st">"Abnahmepruefung: bestanden</span><span class="ch">\n</span><span class="st">"</span>)</span>
|
||||
<span id="cb13-90"><a href="#cb13-90" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb13-91"><a href="#cb13-91" aria-hidden="true" tabindex="-1"></a> <span class="co"># Die Schattenpreise beantworten die Frage, die der Plan nicht stellt:</span></span>
|
||||
<span id="cb13-92"><a href="#cb13-92" aria-hidden="true" tabindex="-1"></a> <span class="co"># Was waere eine zusaetzliche Einheit dieser Ressource wert?</span></span>
|
||||
<span id="cb13-93"><a href="#cb13-93" aria-hidden="true" tabindex="-1"></a> <span class="cf">for</span> ressource, preis <span class="kw">in</span> loesung.schattenpreise.items():</span>
|
||||
<span id="cb13-94"><a href="#cb13-94" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="ss">f" eine Einheit </span><span class="sc">{</span>ressource<span class="sc">:<18}</span><span class="ss"> mehr waere wert: </span><span class="sc">{</span>preis<span class="sc">:7.2f}</span><span class="ss"> EUR"</span>)</span>
|
||||
<span id="cb13-95"><a href="#cb13-95" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="st">"="</span> <span class="op">*</span> <span class="dv">66</span>)</span>
|
||||
<span id="cb13-96"><a href="#cb13-96" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="ss">f"Ergebnis geschrieben nach: </span><span class="sc">{</span>AUSGABE<span class="sc">}</span><span class="ss">"</span>)</span></code></pre></div>
|
||||
<span id="cb13-63"><a href="#cb13-63" aria-hidden="true" tabindex="-1"></a><span class="cf">if</span> <span class="va">__name__</span> <span class="op">==</span> <span class="st">"__main__"</span>:</span>
|
||||
<span id="cb13-64"><a href="#cb13-64" aria-hidden="true" tabindex="-1"></a> <span class="cf">if</span> <span class="kw">not</span> os.path.exists(EINGABE):</span>
|
||||
<span id="cb13-65"><a href="#cb13-65" aria-hidden="true" tabindex="-1"></a> lege_beispieldatei_an(EINGABE)</span>
|
||||
<span id="cb13-66"><a href="#cb13-66" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="ss">f"Beispiel-Eingabedatei angelegt: </span><span class="sc">{</span>EINGABE<span class="sc">}</span><span class="ss">"</span>)</span>
|
||||
<span id="cb13-67"><a href="#cb13-67" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb13-68"><a href="#cb13-68" aria-hidden="true" tabindex="-1"></a> <span class="co"># 1. Lesen und pruefen. Faellt hier etwas auf, ist der Fehler noch</span></span>
|
||||
<span id="cb13-69"><a href="#cb13-69" aria-hidden="true" tabindex="-1"></a> <span class="co"># zuzuordnen - spaeter waere er nur noch eine merkwuerdige Zahl.</span></span>
|
||||
<span id="cb13-70"><a href="#cb13-70" aria-hidden="true" tabindex="-1"></a> problem <span class="op">=</span> lade_produktionsproblem(EINGABE)</span>
|
||||
<span id="cb13-71"><a href="#cb13-71" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb13-72"><a href="#cb13-72" aria-hidden="true" tabindex="-1"></a> <span class="co"># 2. Loesen. Einzige solverabhaengige Zeile des ganzen Programms -</span></span>
|
||||
<span id="cb13-73"><a href="#cb13-73" aria-hidden="true" tabindex="-1"></a> <span class="co"># 'loese_mit_scipy' waere ein Einzeiler-Wechsel.</span></span>
|
||||
<span id="cb13-74"><a href="#cb13-74" aria-hidden="true" tabindex="-1"></a> loesung <span class="op">=</span> loese_mit_glop(problem)</span>
|
||||
<span id="cb13-75"><a href="#cb13-75" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb13-76"><a href="#cb13-76" aria-hidden="true" tabindex="-1"></a> <span class="co"># 3. Abnahmepruefung gegen die Anforderungen, ohne den Solver zu fragen.</span></span>
|
||||
<span id="cb13-77"><a href="#cb13-77" aria-hidden="true" tabindex="-1"></a> beanstandungen <span class="op">=</span> pruefe_loesung(problem, loesung)</span>
|
||||
<span id="cb13-78"><a href="#cb13-78" aria-hidden="true" tabindex="-1"></a> <span class="cf">if</span> beanstandungen:</span>
|
||||
<span id="cb13-79"><a href="#cb13-79" aria-hidden="true" tabindex="-1"></a> <span class="cf">raise</span> <span class="pp">SystemExit</span>(<span class="st">"Abnahmepruefung fehlgeschlagen:</span><span class="ch">\n</span><span class="st"> - "</span></span>
|
||||
<span id="cb13-80"><a href="#cb13-80" aria-hidden="true" tabindex="-1"></a> <span class="op">+</span> <span class="st">"</span><span class="ch">\n</span><span class="st"> - "</span>.join(beanstandungen))</span>
|
||||
<span id="cb13-81"><a href="#cb13-81" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb13-82"><a href="#cb13-82" aria-hidden="true" tabindex="-1"></a> <span class="co"># 4. Zurueckschreiben - im Format, das die Fachabteilung ohnehin benutzt.</span></span>
|
||||
<span id="cb13-83"><a href="#cb13-83" aria-hidden="true" tabindex="-1"></a> schreibe_ergebnis(AUSGABE, problem, loesung)</span>
|
||||
<span id="cb13-84"><a href="#cb13-84" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb13-85"><a href="#cb13-85" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="st">"="</span> <span class="op">*</span> <span class="dv">66</span>)</span>
|
||||
<span id="cb13-86"><a href="#cb13-86" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="st">" PRODUKTIONSPLAN AUS DER EXCEL-MAPPE"</span>)</span>
|
||||
<span id="cb13-87"><a href="#cb13-87" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="st">"="</span> <span class="op">*</span> <span class="dv">66</span>)</span>
|
||||
<span id="cb13-88"><a href="#cb13-88" aria-hidden="true" tabindex="-1"></a> <span class="cf">for</span> produkt <span class="kw">in</span> problem.produkte:</span>
|
||||
<span id="cb13-89"><a href="#cb13-89" aria-hidden="true" tabindex="-1"></a> menge <span class="op">=</span> loesung.werte[produkt.name]</span>
|
||||
<span id="cb13-90"><a href="#cb13-90" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="ss">f"</span><span class="sc">{</span>produkt<span class="sc">.</span>name<span class="sc">:<18}</span><span class="ss"> </span><span class="sc">{</span>menge<span class="sc">:8.1f}</span><span class="ss"> Stueck "</span></span>
|
||||
<span id="cb13-91"><a href="#cb13-91" aria-hidden="true" tabindex="-1"></a> <span class="ss">f"</span><span class="sc">{</span>menge <span class="op">*</span> produkt<span class="sc">.</span>deckungsbeitrag<span class="sc">:12,.2f}</span><span class="ss"> EUR"</span>)</span>
|
||||
<span id="cb13-92"><a href="#cb13-92" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="st">"-"</span> <span class="op">*</span> <span class="dv">66</span>)</span>
|
||||
<span id="cb13-93"><a href="#cb13-93" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(loesung.als_bericht())</span>
|
||||
<span id="cb13-94"><a href="#cb13-94" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="st">"Abnahmepruefung: bestanden</span><span class="ch">\n</span><span class="st">"</span>)</span>
|
||||
<span id="cb13-95"><a href="#cb13-95" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb13-96"><a href="#cb13-96" aria-hidden="true" tabindex="-1"></a> <span class="co"># Die Schattenpreise beantworten die Frage, die der Plan nicht stellt:</span></span>
|
||||
<span id="cb13-97"><a href="#cb13-97" aria-hidden="true" tabindex="-1"></a> <span class="co"># Was waere eine zusaetzliche Einheit dieser Ressource wert?</span></span>
|
||||
<span id="cb13-98"><a href="#cb13-98" aria-hidden="true" tabindex="-1"></a> <span class="cf">for</span> ressource, preis <span class="kw">in</span> loesung.schattenpreise.items():</span>
|
||||
<span id="cb13-99"><a href="#cb13-99" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="ss">f" eine Einheit </span><span class="sc">{</span>ressource<span class="sc">:<18}</span><span class="ss"> mehr waere wert: </span><span class="sc">{</span>preis<span class="sc">:7.2f}</span><span class="ss"> EUR"</span>)</span>
|
||||
<span id="cb13-100"><a href="#cb13-100" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="st">"="</span> <span class="op">*</span> <span class="dv">66</span>)</span>
|
||||
<span id="cb13-101"><a href="#cb13-101" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="ss">f"Ergebnis geschrieben nach: </span><span class="sc">{</span>AUSGABE<span class="sc">}</span><span class="ss">"</span>)</span></code></pre></div>
|
||||
<p><strong>Erwartete Ausgabe:</strong></p>
|
||||
<pre><code>Beispiel-Eingabedatei angelegt: produktionsmix.xlsx
|
||||
==================================================================
|
||||
|
|
|
|||
|
|
@ -34,8 +34,13 @@ import pandas as pd
|
|||
from or_kern import (lade_produktionsproblem, loese_mit_glop, pruefe_loesung,
|
||||
schreibe_ergebnis)
|
||||
|
||||
EINGABE = "produktionsmix.xlsx"
|
||||
AUSGABE = "produktionsmix_ergebnis.xlsx"
|
||||
# Die Mappen liegen NEBEN diesem Programm, nicht im aktuellen
|
||||
# Arbeitsverzeichnis. Sonst haengt es davon ab, aus welchem Ordner man das
|
||||
# Skript startet, wo die Dateien landen - und wer es aus der
|
||||
# Repository-Wurzel aufruft, verstreut sie dort.
|
||||
HIER = os.path.dirname(os.path.abspath(__file__))
|
||||
EINGABE = os.path.join(HIER, "produktionsmix.xlsx")
|
||||
AUSGABE = os.path.join(HIER, "produktionsmix_ergebnis.xlsx")
|
||||
|
||||
|
||||
def lege_beispieldatei_an(pfad: str) -> None:
|
||||
|
|
|
|||
|
|
@ -1539,8 +1539,13 @@ import pandas as pd
|
|||
from or_kern import (lade_produktionsproblem, loese_mit_glop, pruefe_loesung,
|
||||
schreibe_ergebnis)
|
||||
|
||||
EINGABE = "produktionsmix.xlsx"
|
||||
AUSGABE = "produktionsmix_ergebnis.xlsx"
|
||||
# Die Mappen liegen NEBEN diesem Programm, nicht im aktuellen
|
||||
# Arbeitsverzeichnis. Sonst haengt es davon ab, aus welchem Ordner man das
|
||||
# Skript startet, wo die Dateien landen - und wer es aus der
|
||||
# Repository-Wurzel aufruft, verstreut sie dort.
|
||||
HIER = os.path.dirname(os.path.abspath(__file__))
|
||||
EINGABE = os.path.join(HIER, "produktionsmix.xlsx")
|
||||
AUSGABE = os.path.join(HIER, "produktionsmix_ergebnis.xlsx")
|
||||
|
||||
|
||||
def lege_beispieldatei_an(pfad: str) -> None:
|
||||
|
|
|
|||
|
|
@ -966,8 +966,13 @@ import pandas as pd
|
|||
from or_kern import (lade_produktionsproblem, loese_mit_glop, pruefe_loesung,
|
||||
schreibe_ergebnis)
|
||||
|
||||
EINGABE = "produktionsmix.xlsx"
|
||||
AUSGABE = "produktionsmix_ergebnis.xlsx"
|
||||
# Die Mappen liegen NEBEN diesem Programm, nicht im aktuellen
|
||||
# Arbeitsverzeichnis. Sonst haengt es davon ab, aus welchem Ordner man das
|
||||
# Skript startet, wo die Dateien landen - und wer es aus der
|
||||
# Repository-Wurzel aufruft, verstreut sie dort.
|
||||
HIER = os.path.dirname(os.path.abspath(__file__))
|
||||
EINGABE = os.path.join(HIER, "produktionsmix.xlsx")
|
||||
AUSGABE = os.path.join(HIER, "produktionsmix_ergebnis.xlsx")
|
||||
|
||||
|
||||
def lege_beispieldatei_an(pfad: str) -> None:
|
||||
|
|
|
|||
|
|
@ -1447,7 +1447,13 @@ def spiegle_bilder(html_verz: str) -> None:
|
|||
return
|
||||
ziel_wurzel = os.path.join(html_verz, BILDER_NAME)
|
||||
kopiert = 0
|
||||
for wurzel, _verzeichnisse, dateien in os.walk(BILDER_VERZ):
|
||||
for wurzel, verzeichnisse, dateien in os.walk(BILDER_VERZ):
|
||||
# Unterverzeichnisse ohne Grafiken gar nicht erst betreten. os.walk
|
||||
# wuerde sie sonst durchlaufen, und os.makedirs() legte sie am Ziel an -
|
||||
# so stand ein leeres __pycache__/ auf dem Webserver, obwohl der
|
||||
# Dateifilter unten korrekt nichts daraus kopiert hat.
|
||||
verzeichnisse[:] = [v for v in verzeichnisse
|
||||
if v != "__pycache__" and not v.startswith(".")]
|
||||
rel = os.path.relpath(wurzel, BILDER_VERZ)
|
||||
ziel_verz = ziel_wurzel if rel == "." else os.path.join(ziel_wurzel, rel)
|
||||
os.makedirs(ziel_verz, exist_ok=True)
|
||||
|
|
|
|||
|
|
@ -34,8 +34,13 @@ import pandas as pd
|
|||
from or_kern import (lade_produktionsproblem, loese_mit_glop, pruefe_loesung,
|
||||
schreibe_ergebnis)
|
||||
|
||||
EINGABE = "produktionsmix.xlsx"
|
||||
AUSGABE = "produktionsmix_ergebnis.xlsx"
|
||||
# Die Mappen liegen NEBEN diesem Programm, nicht im aktuellen
|
||||
# Arbeitsverzeichnis. Sonst haengt es davon ab, aus welchem Ordner man das
|
||||
# Skript startet, wo die Dateien landen - und wer es aus der
|
||||
# Repository-Wurzel aufruft, verstreut sie dort.
|
||||
HIER = os.path.dirname(os.path.abspath(__file__))
|
||||
EINGABE = os.path.join(HIER, "produktionsmix.xlsx")
|
||||
AUSGABE = os.path.join(HIER, "produktionsmix_ergebnis.xlsx")
|
||||
|
||||
|
||||
def lege_beispieldatei_an(pfad: str) -> None:
|
||||
|
|
|
|||
36
PROGRESS.md
|
|
@ -77,9 +77,9 @@ sie unerwartet ab, ist etwas kaputtgegangen.
|
|||
| Kapiteldateien | 22 | **36** (31 + 5 Teil-Synthesen) |
|
||||
| Kapitel | 15 | **23** |
|
||||
| Anhänge | 4 | **5** |
|
||||
| Zeilen im Gesamtdokument | 11 082 | **28 565** |
|
||||
| Zeilen im Gesamtdokument | 11 082 | **28 570** |
|
||||
| Größe des Gesamtdokuments | 606 KB | **1 622 KB** |
|
||||
| Hauptüberschriften | 131 | **302** |
|
||||
| Hauptüberschriften | 131 | **306** |
|
||||
| registrierte Abschnitte | 122 | **296** |
|
||||
| aufgelöste Querverweise | 314 | **825** (0 unaufgelöst) |
|
||||
| Indexmarken | 295 | **328** |
|
||||
|
|
@ -87,7 +87,7 @@ sie unerwartet ab, ist etwas kaputtgegangen.
|
|||
| PDF-Seiten | — | **760** |
|
||||
| Notebooks | — | **25** |
|
||||
| Plotly-Figuren | — | **4** |
|
||||
| Diagramme (SVG) | 26 | **33**, davon **19** mit Generatorskript (16 Skripte) |
|
||||
| Diagramme (SVG) | 26 | **33**, davon **19** mit Generatorskript (16 Skripte); keine PNG-Zweitfassung mehr |
|
||||
|
||||
**Gegenprobe:** `build_version_03.py --check` läuft unverändert durch — Version 03 ist von
|
||||
allen Änderungen unberührt.
|
||||
|
|
@ -1909,6 +1909,36 @@ könnte die Hälfte der Beispiele nicht ausführen.
|
|||
|
||||
**Damit ist Phase 8 abgeschlossen und der Plan abgearbeitet.**
|
||||
|
||||
### ✅ Aufgeräumt — und dabei zwei Funde
|
||||
|
||||
**Die 33 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 Veröffentlichung auf den
|
||||
Webserver gingen, ohne dass sie jemand abrief. Die 15 Generatoren schreiben jetzt nur noch
|
||||
SVG; die Docstrings sind mitgezogen. Vor dem Löschen geprüft: Jedes PNG hatte sein
|
||||
gleichnamiges SVG, und alle 33 waren versioniert — rückholbar.
|
||||
|
||||
**Fund 1 dabei: `erzeuge_kap06_gantt.py` folgte als einziger Generator nicht der Konvention.**
|
||||
Weder `svg.hashsalt` noch `metadata={"Date": None}` waren gesetzt. Sein SVG trug deshalb
|
||||
einen echten Zeitstempel und bei jedem Lauf andere `clip-path`-IDs — es war **nie**
|
||||
byteidentisch reproduzierbar, obwohl `CLAUDE.md` genau das für alle Generatoren festhält.
|
||||
Aufgefallen ist es nur, weil nach der PNG-Umstellung 32 von 33 SVGs bitgleich blieben und
|
||||
eines nicht. Jetzt byteidentisch über zwei Läufe.
|
||||
|
||||
**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 — ein leerer Ordner in `OR_HTML_04/bilder_04/`. Die
|
||||
Verzeichnisliste wird jetzt vorher gefiltert. Gegengetestet.
|
||||
|
||||
**`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 über `os.path.dirname(os.path.abspath(__file__))`. Nachgemessen: Lauf
|
||||
aus der Wurzel legt dort **null** Dateien ab.
|
||||
|
||||
**Und `git gc`:** 653 lose Objekte gepackt, `.git` von 71 MB auf **28 MB** — reines
|
||||
Repacken, kein Inhalt berührt.
|
||||
|
||||
---
|
||||
|
||||
## 8. Commit-Historie des V04-Strangs
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@
|
|||
"""
|
||||
Erzeugt die beiden Architekturdiagramme fuer den Weg vom Skript zum Betrieb:
|
||||
|
||||
bilder_04/kap_praxisfallen_schichten.svg / .png Schichten von or_kern.py
|
||||
bilder_04/kap_testing_dienst.svg / .png der Dienst und sein Ablauf
|
||||
bilder_04/kap_praxisfallen_schichten.svg Schichten von or_kern.py
|
||||
bilder_04/kap_testing_dienst.svg der Dienst und sein Ablauf
|
||||
|
||||
Beide bilden ab, was in den Programmen tatsaechlich steht - nicht ein
|
||||
allgemeines Architekturschema:
|
||||
|
|
@ -62,7 +62,7 @@ def kasten(punkt: graphviz.Digraph, name: str, text: str, farbe: str,
|
|||
|
||||
def schreibe(punkt: graphviz.Digraph, name: str) -> None:
|
||||
os.makedirs(BILDER, exist_ok=True)
|
||||
for endung in ("svg", "png"):
|
||||
for endung in ("svg",):
|
||||
punkt.format = endung
|
||||
pfad = punkt.render(os.path.join(BILDER, name), cleanup=True)
|
||||
print(f"geschrieben: {pfad}")
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"""
|
||||
Erzeugt den Branch-and-Bound-Suchbaum zum MILP-Kapitel:
|
||||
|
||||
bilder_04/kap_milp_suchbaum.svg / .png
|
||||
bilder_04/kap_milp_suchbaum.svg
|
||||
|
||||
Gezeichnet wird der Baum der Handrechnung des Kapitels:
|
||||
|
||||
|
|
@ -172,7 +172,7 @@ def zeichne(knoten, kanten, bestes, zielwert, geloest) -> None:
|
|||
color="#94a3b8", fontsize="10", margin="0.18,0.12")
|
||||
|
||||
os.makedirs(BILDER, exist_ok=True)
|
||||
for endung in ("svg", "png"):
|
||||
for endung in ("svg",):
|
||||
punkt.format = endung
|
||||
pfad = punkt.render(os.path.join(BILDER, "kap_milp_suchbaum"), cleanup=True)
|
||||
print(f"geschrieben: {pfad}")
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@
|
|||
Erzeugt die Figur "Was die Hausregeln kosten" zum Kapitel Markowitz:
|
||||
|
||||
bilder_04/kap_markowitz_restriktionen.svg statisch, fuer das PDF
|
||||
bilder_04/kap_markowitz_restriktionen.png Rasterfassung
|
||||
bilder_04/plotly/kap_markowitz_restriktionen.html interaktiv, fuer die Website
|
||||
|
||||
Gezeigt werden zwei Effizienzlinien desselben Universums: einmal ohne
|
||||
|
|
@ -210,7 +209,7 @@ def zeichne_statisch(frei, gebunden, abstand, risiko_stelle) -> None:
|
|||
figur.tight_layout()
|
||||
|
||||
os.makedirs(BILDER, exist_ok=True)
|
||||
for endung in ("svg", "png"):
|
||||
for endung in ("svg",):
|
||||
pfad = os.path.join(BILDER, f"kap_markowitz_restriktionen.{endung}")
|
||||
figur.savefig(pfad, format=endung, dpi=160,
|
||||
metadata={"Date": None} if endung == "svg" else None)
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@
|
|||
Erzeugt das Gantt-Diagramm zum Job-Shop-Beispiel aus Kapitel 6 in zwei Fassungen:
|
||||
|
||||
bilder_04/kap06_jobshop_gantt.svg statisch, fuer das PDF
|
||||
bilder_04/kap06_jobshop_gantt.png statisch, Rasterfassung
|
||||
bilder_04/plotly/kap06_jobshop_gantt.html interaktiv, fuer die Website
|
||||
|
||||
Die Daten sind identisch mit JobShop_Intervalle.py; geloest wird hier erneut,
|
||||
|
|
@ -27,6 +26,11 @@ import matplotlib.pyplot as plt
|
|||
import plotly.graph_objects as go
|
||||
from ortools.sat.python import cp_model
|
||||
|
||||
# Reproduzierbare SVG-Ausgabe (siehe erzeuge_titelseite.py). Dieser Generator
|
||||
# war als einziger ohne beides - sein SVG trug deshalb einen echten
|
||||
# Zeitstempel und bei jedem Lauf andere clip-path-IDs.
|
||||
plt.rcParams["svg.hashsalt"] = "or-mit-python-v04"
|
||||
|
||||
# Identisch zu JobShop_Intervalle.py
|
||||
AUFTRAEGE = [
|
||||
[(0, 3), (1, 2), (2, 2)], # Auftrag 0
|
||||
|
|
@ -111,9 +115,10 @@ def zeichne_statisch(plan, makespan: int) -> None:
|
|||
figur.tight_layout()
|
||||
|
||||
os.makedirs(BILDER, exist_ok=True)
|
||||
for endung in ("svg", "png"):
|
||||
for endung in ("svg",):
|
||||
pfad = os.path.join(BILDER, f"kap06_jobshop_gantt.{endung}")
|
||||
figur.savefig(pfad, format=endung, dpi=160)
|
||||
figur.savefig(pfad, format=endung, dpi=160,
|
||||
metadata={"Date": None} if endung == "svg" else None)
|
||||
print(f"geschrieben: {pfad}")
|
||||
plt.close(figur)
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"""
|
||||
Erzeugt das KKT-Diagramm zum QP/NLP-Kapitel:
|
||||
|
||||
bilder_04/kap_qp_kkt.svg / .png
|
||||
bilder_04/kap_qp_kkt.svg
|
||||
|
||||
Zwei Bilder nebeneinander:
|
||||
|
||||
|
|
@ -216,7 +216,7 @@ if __name__ == "__main__":
|
|||
zeichne_2d(rechts, x_stern, lam)
|
||||
figur.tight_layout()
|
||||
os.makedirs(BILDER, exist_ok=True)
|
||||
for endung in ("svg", "png"):
|
||||
for endung in ("svg",):
|
||||
pfad = os.path.join(BILDER, f"kap_qp_kkt.{endung}")
|
||||
figur.savefig(pfad, format=endung, dpi=160,
|
||||
metadata={"Date": None} if endung == "svg" else None)
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@
|
|||
Erzeugt das Konditionszahl-Diagramm zum Kapitel Fundament:
|
||||
|
||||
bilder_04/kap_fundament_kondition.svg statisch, fuer das PDF
|
||||
bilder_04/kap_fundament_kondition.png Rasterfassung
|
||||
|
||||
Zwei Aussagen, beide gerechnet und nicht behauptet:
|
||||
|
||||
|
|
@ -185,7 +184,7 @@ def zeichne(kappas, mediane, maxima, kappa_vorher, kappa_nachher) -> None:
|
|||
|
||||
figur.tight_layout()
|
||||
os.makedirs(BILDER, exist_ok=True)
|
||||
for endung in ("svg", "png"):
|
||||
for endung in ("svg",):
|
||||
pfad = os.path.join(BILDER, f"kap_fundament_kondition.{endung}")
|
||||
figur.savefig(pfad, format=endung, dpi=160,
|
||||
metadata={"Date": None} if endung == "svg" else None)
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@
|
|||
Erzeugt das Suchverlauf-Diagramm zum Kapitel Metaheuristiken:
|
||||
|
||||
bilder_04/kap_metaheuristiken_landschaft.svg statisch, fuer das PDF
|
||||
bilder_04/kap_metaheuristiken_landschaft.png Rasterfassung
|
||||
bilder_04/plotly/kap_metaheuristiken_verlauf.html interaktiv, fuer die Website
|
||||
|
||||
Eine Suchlandschaft laesst sich bei 200 Auftraegen nicht zeichnen - der Raum
|
||||
|
|
@ -223,7 +222,7 @@ def zeichne(verlaeufe, start, temperaturreihe) -> None:
|
|||
|
||||
figur.tight_layout()
|
||||
os.makedirs(BILDER, exist_ok=True)
|
||||
for endung in ("svg", "png"):
|
||||
for endung in ("svg",):
|
||||
pfad = os.path.join(BILDER, f"kap_metaheuristiken_landschaft.{endung}")
|
||||
figur.savefig(pfad, format=endung, dpi=160,
|
||||
metadata={"Date": None} if endung == "svg" else None)
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"""
|
||||
Erzeugt das Flussdiagramm zum Graphen-Kapitel:
|
||||
|
||||
bilder_04/kap_graphen_min_cost_flow.svg / .png
|
||||
bilder_04/kap_graphen_min_cost_flow.svg
|
||||
|
||||
Das Vorgaengerbild zeigte die Instanz von Min_Cost_Flow.py korrekt - aber nur
|
||||
die Instanz. Kosten und Kapazitaeten standen an den Kanten, der FLUSS nicht.
|
||||
|
|
@ -128,7 +128,7 @@ def zeichne(gesamtkosten: float, fluss: np.ndarray, preise: np.ndarray) -> None:
|
|||
penwidth=f"{1.0 + 3.0 * menge / kapazitaet:.1f}")
|
||||
|
||||
os.makedirs(BILDER, exist_ok=True)
|
||||
for endung in ("svg", "png"):
|
||||
for endung in ("svg",):
|
||||
punkt.format = endung
|
||||
pfad = punkt.render(os.path.join(BILDER, "kap_graphen_min_cost_flow"),
|
||||
cleanup=True)
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@
|
|||
Erzeugt das Pareto-Front-Diagramm zum Mehrziel-Kapitel in zwei Fassungen:
|
||||
|
||||
bilder_04/kap_mehrziel_pareto.svg statisch, fuer das PDF
|
||||
bilder_04/kap_mehrziel_pareto.png statisch, Rasterfassung
|
||||
bilder_04/plotly/kap_mehrziel_pareto.html interaktiv, fuer die Website
|
||||
|
||||
Die Instanz ist identisch mit Mehrziel_Pareto.py, und gerechnet wird hier
|
||||
|
|
@ -140,7 +139,7 @@ def zeichne_statisch(front, huelle) -> None:
|
|||
figur.tight_layout()
|
||||
|
||||
os.makedirs(BILDER, exist_ok=True)
|
||||
for endung in ("svg", "png"):
|
||||
for endung in ("svg",):
|
||||
pfad = os.path.join(BILDER, f"kap_mehrziel_pareto.{endung}")
|
||||
figur.savefig(pfad, format=endung, dpi=160,
|
||||
metadata={"Date": None} if endung == "svg" else None)
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@
|
|||
"""
|
||||
Erzeugt die beiden Polyeder-Diagramme zum Fundament- und zum LP-Kapitel:
|
||||
|
||||
bilder_04/kap_fundament_polyeder.svg / .png der zulaessige Bereich
|
||||
bilder_04/kap_lp_simplex_ecken.svg / .png der Eckenlauf des Simplex
|
||||
bilder_04/kap_fundament_polyeder.svg der zulaessige Bereich
|
||||
bilder_04/kap_lp_simplex_ecken.svg der Eckenlauf des Simplex
|
||||
|
||||
Beide zeigen DASSELBE Modell - das Bot-Allokationsproblem, das sich durch die
|
||||
ersten Kapitel zieht:
|
||||
|
|
@ -165,7 +165,7 @@ def zeichne_rahmen(achse, ecken: np.ndarray) -> None:
|
|||
|
||||
def schreibe(figur, name: str) -> None:
|
||||
os.makedirs(BILDER, exist_ok=True)
|
||||
for endung in ("svg", "png"):
|
||||
for endung in ("svg",):
|
||||
pfad = os.path.join(BILDER, f"{name}.{endung}")
|
||||
figur.savefig(pfad, format=endung, dpi=160,
|
||||
metadata={"Date": None} if endung == "svg" else None)
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@
|
|||
Erzeugt das Diagramm "Warum Runden scheitert" zum MILP-Kapitel:
|
||||
|
||||
bilder_04/kap_milp_runden.svg statisch, fuer das PDF
|
||||
bilder_04/kap_milp_runden.png Rasterfassung
|
||||
|
||||
Zwei Bilder nebeneinander, beide aus dem Kapitel selbst:
|
||||
|
||||
|
|
@ -213,7 +212,7 @@ def zeichne(zeilen) -> None:
|
|||
figur.tight_layout()
|
||||
|
||||
os.makedirs(BILDER, exist_ok=True)
|
||||
for endung in ("svg", "png"):
|
||||
for endung in ("svg",):
|
||||
pfad = os.path.join(BILDER, f"kap_milp_runden.{endung}")
|
||||
figur.savefig(pfad, format=endung, dpi=160,
|
||||
metadata={"Date": None} if endung == "svg" else None)
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@
|
|||
Erzeugt die beiden Entscheidungs-Flussdiagramme "Welches Werkzeug passt zu
|
||||
meinem Problem?" fuer die Auftakte von Teil II und Teil III:
|
||||
|
||||
bilder_04/teil2_solverwahl.svg / .png deterministische Verfahren
|
||||
bilder_04/teil3_solverwahl.svg / .png Nichtlinearitaet und Unsicherheit
|
||||
bilder_04/teil2_solverwahl.svg deterministische Verfahren
|
||||
bilder_04/teil3_solverwahl.svg Nichtlinearitaet und Unsicherheit
|
||||
|
||||
Beide entstehen mit Graphviz. Die Farben folgen der Buchpalette
|
||||
(Indigo, Cyan, Violett, Gruen, Amber), die Kastenform codiert die Rolle:
|
||||
|
|
@ -57,7 +57,7 @@ def empfehlung(punkt: graphviz.Digraph, name: str, text: str, farbe: str) -> Non
|
|||
|
||||
def schreibe(punkt: graphviz.Digraph, name: str) -> None:
|
||||
os.makedirs(BILDER, exist_ok=True)
|
||||
for endung in ("svg", "png"):
|
||||
for endung in ("svg",):
|
||||
punkt.format = endung
|
||||
pfad = punkt.render(os.path.join(BILDER, name), cleanup=True)
|
||||
print(f"geschrieben: {pfad}")
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@
|
|||
Erzeugt das VaR/CVaR-Diagramm zum Kapitel CVaR:
|
||||
|
||||
bilder_04/kap_cvar_var_vergleich.svg statisch, fuer das PDF
|
||||
bilder_04/kap_cvar_var_vergleich.png Rasterfassung
|
||||
|
||||
Gezeigt wird die Verteilung simulierter Tagesrenditen mit beiden Kennzahlen:
|
||||
Der VaR ist die SCHWELLE, unter die nur 5 % der Tage fallen; der CVaR ist der
|
||||
|
|
@ -142,7 +141,7 @@ def zeichne(werte: np.ndarray, var: float, cvar: float) -> None:
|
|||
figur.tight_layout()
|
||||
|
||||
os.makedirs(BILDER, exist_ok=True)
|
||||
for endung in ("svg", "png"):
|
||||
for endung in ("svg",):
|
||||
pfad = os.path.join(BILDER, f"kap_cvar_var_vergleich.{endung}")
|
||||
figur.savefig(pfad, format=endung, dpi=160,
|
||||
metadata={"Date": None} if endung == "svg" else None)
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"""
|
||||
Erzeugt die Tourenkarte zum Graphen-Kapitel:
|
||||
|
||||
bilder_04/kap_graphen_vrp_touren.svg / .png
|
||||
bilder_04/kap_graphen_vrp_touren.svg
|
||||
|
||||
Das Vorgaengerbild war ein Schema: zwei Touren, vier Kunden, Zeitfenster in
|
||||
Uhrzeiten. Die Instanz des Kapitels hat 16 Kunden, vier Fahrzeuge und
|
||||
|
|
@ -170,7 +170,7 @@ def zeichne(koordinaten, touren) -> None:
|
|||
figur.tight_layout()
|
||||
|
||||
os.makedirs(BILDER, exist_ok=True)
|
||||
for endung in ("svg", "png"):
|
||||
for endung in ("svg",):
|
||||
pfad = os.path.join(BILDER, f"kap_graphen_vrp_touren.{endung}")
|
||||
figur.savefig(pfad, format=endung, dpi=160, bbox_inches="tight",
|
||||
metadata={"Date": None} if endung == "svg" else None)
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@
|
|||
Erzeugt das Wasserfalldiagramm zum Kapitel Supply-Chain und Energieeinsatz:
|
||||
|
||||
bilder_04/kap_supplychain_wirkung.svg statisch, fuer das PDF
|
||||
bilder_04/kap_supplychain_wirkung.png Rasterfassung
|
||||
|
||||
Die Frage, die es beantwortet, ist die des Managements: WOFUER genau kostet
|
||||
der Erwartungswert-Plan 149 % mehr? Die Tabelle im Kapitel nennt nur die
|
||||
|
|
@ -228,7 +227,7 @@ def zeichne(zwei: dict, erw: dict) -> None:
|
|||
|
||||
figur.tight_layout()
|
||||
os.makedirs(BILDER, exist_ok=True)
|
||||
for endung in ("svg", "png"):
|
||||
for endung in ("svg",):
|
||||
pfad = os.path.join(BILDER, f"kap_supplychain_wirkung.{endung}")
|
||||
figur.savefig(pfad, format=endung, dpi=160,
|
||||
metadata={"Date": None} if endung == "svg" else None)
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 63 KiB |
|
Before Width: | Height: | Size: 94 KiB |
|
Before Width: | Height: | Size: 88 KiB |
|
Before Width: | Height: | Size: 80 KiB |
|
Before Width: | Height: | Size: 88 KiB |
|
Before Width: | Height: | Size: 44 KiB |
|
|
@ -6,7 +6,6 @@
|
|||
<rdf:RDF xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
|
||||
<cc:Work>
|
||||
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
|
||||
<dc:date>2026-09-07T01:51:51.979555</dc:date>
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:creator>
|
||||
<cc:Agent>
|
||||
|
|
@ -43,7 +42,7 @@ L 326.435455 32.849091
|
|||
L 326.435455 64.809875
|
||||
L 174.248182 64.809875
|
||||
z
|
||||
" clip-path="url(#p448fd06892)" style="fill: #4338ca; stroke: #ffffff; stroke-width: 1.2; stroke-linejoin: miter"/>
|
||||
" clip-path="url(#pce73ba693e)" style="fill: #4338ca; stroke: #ffffff; stroke-width: 1.2; stroke-linejoin: miter"/>
|
||||
</g>
|
||||
<g id="patch_4">
|
||||
<path d="M 326.435455 90.959608
|
||||
|
|
@ -51,7 +50,7 @@ L 427.893636 90.959608
|
|||
L 427.893636 122.920392
|
||||
L 326.435455 122.920392
|
||||
z
|
||||
" clip-path="url(#p448fd06892)" style="fill: #4338ca; stroke: #ffffff; stroke-width: 1.2; stroke-linejoin: miter"/>
|
||||
" clip-path="url(#pce73ba693e)" style="fill: #4338ca; stroke: #ffffff; stroke-width: 1.2; stroke-linejoin: miter"/>
|
||||
</g>
|
||||
<g id="patch_5">
|
||||
<path d="M 427.893636 149.070125
|
||||
|
|
@ -59,7 +58,7 @@ L 529.351818 149.070125
|
|||
L 529.351818 181.030909
|
||||
L 427.893636 181.030909
|
||||
z
|
||||
" clip-path="url(#p448fd06892)" style="fill: #4338ca; stroke: #ffffff; stroke-width: 1.2; stroke-linejoin: miter"/>
|
||||
" clip-path="url(#pce73ba693e)" style="fill: #4338ca; stroke: #ffffff; stroke-width: 1.2; stroke-linejoin: miter"/>
|
||||
</g>
|
||||
<g id="patch_6">
|
||||
<path d="M 72.79 32.849091
|
||||
|
|
@ -67,7 +66,7 @@ L 174.248182 32.849091
|
|||
L 174.248182 64.809875
|
||||
L 72.79 64.809875
|
||||
z
|
||||
" clip-path="url(#p448fd06892)" style="fill: #0891b2; stroke: #ffffff; stroke-width: 1.2; stroke-linejoin: miter"/>
|
||||
" clip-path="url(#pce73ba693e)" style="fill: #0891b2; stroke: #ffffff; stroke-width: 1.2; stroke-linejoin: miter"/>
|
||||
</g>
|
||||
<g id="patch_7">
|
||||
<path d="M 174.248182 149.070125
|
||||
|
|
@ -75,7 +74,7 @@ L 224.977273 149.070125
|
|||
L 224.977273 181.030909
|
||||
L 174.248182 181.030909
|
||||
z
|
||||
" clip-path="url(#p448fd06892)" style="fill: #0891b2; stroke: #ffffff; stroke-width: 1.2; stroke-linejoin: miter"/>
|
||||
" clip-path="url(#pce73ba693e)" style="fill: #0891b2; stroke: #ffffff; stroke-width: 1.2; stroke-linejoin: miter"/>
|
||||
</g>
|
||||
<g id="patch_8">
|
||||
<path d="M 427.893636 90.959608
|
||||
|
|
@ -83,7 +82,7 @@ L 630.81 90.959608
|
|||
L 630.81 122.920392
|
||||
L 427.893636 122.920392
|
||||
z
|
||||
" clip-path="url(#p448fd06892)" style="fill: #0891b2; stroke: #ffffff; stroke-width: 1.2; stroke-linejoin: miter"/>
|
||||
" clip-path="url(#pce73ba693e)" style="fill: #0891b2; stroke: #ffffff; stroke-width: 1.2; stroke-linejoin: miter"/>
|
||||
</g>
|
||||
<g id="patch_9">
|
||||
<path d="M 72.79 90.959608
|
||||
|
|
@ -91,7 +90,7 @@ L 275.706364 90.959608
|
|||
L 275.706364 122.920392
|
||||
L 72.79 122.920392
|
||||
z
|
||||
" clip-path="url(#p448fd06892)" style="fill: #b45309; stroke: #ffffff; stroke-width: 1.2; stroke-linejoin: miter"/>
|
||||
" clip-path="url(#pce73ba693e)" style="fill: #b45309; stroke: #ffffff; stroke-width: 1.2; stroke-linejoin: miter"/>
|
||||
</g>
|
||||
<g id="patch_10">
|
||||
<path d="M 275.706364 149.070125
|
||||
|
|
@ -99,23 +98,23 @@ L 427.893636 149.070125
|
|||
L 427.893636 181.030909
|
||||
L 275.706364 181.030909
|
||||
z
|
||||
" clip-path="url(#p448fd06892)" style="fill: #b45309; stroke: #ffffff; stroke-width: 1.2; stroke-linejoin: miter"/>
|
||||
" clip-path="url(#pce73ba693e)" style="fill: #b45309; stroke: #ffffff; stroke-width: 1.2; stroke-linejoin: miter"/>
|
||||
</g>
|
||||
<g id="matplotlib.axis_1">
|
||||
<g id="xtick_1">
|
||||
<g id="line2d_1">
|
||||
<path d="M 72.79 188.44
|
||||
L 72.79 25.44
|
||||
" clip-path="url(#p448fd06892)" style="fill: none; stroke-dasharray: 0.8,1.32; stroke-dashoffset: 0; stroke: #b0b0b0; stroke-opacity: 0.5; stroke-width: 0.8"/>
|
||||
" clip-path="url(#pce73ba693e)" style="fill: none; stroke-dasharray: 0.8,1.32; stroke-dashoffset: 0; stroke: #b0b0b0; stroke-opacity: 0.5; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g id="line2d_2">
|
||||
<defs>
|
||||
<path id="mfeb5fcddc7" d="M 0 0
|
||||
<path id="mf0a04b41f8" d="M 0 0
|
||||
L 0 3.5
|
||||
" style="stroke: #000000; stroke-width: 0.8"/>
|
||||
</defs>
|
||||
<g>
|
||||
<use xlink:href="#mfeb5fcddc7" x="72.79" y="188.44" style="stroke: #000000; stroke-width: 0.8"/>
|
||||
<use xlink:href="#mf0a04b41f8" x="72.79" y="188.44" style="stroke: #000000; stroke-width: 0.8"/>
|
||||
</g>
|
||||
</g>
|
||||
<g id="text_1">
|
||||
|
|
@ -152,11 +151,11 @@ z
|
|||
<g id="line2d_3">
|
||||
<path d="M 123.519091 188.44
|
||||
L 123.519091 25.44
|
||||
" clip-path="url(#p448fd06892)" style="fill: none; stroke-dasharray: 0.8,1.32; stroke-dashoffset: 0; stroke: #b0b0b0; stroke-opacity: 0.5; stroke-width: 0.8"/>
|
||||
" clip-path="url(#pce73ba693e)" style="fill: none; stroke-dasharray: 0.8,1.32; stroke-dashoffset: 0; stroke: #b0b0b0; stroke-opacity: 0.5; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g id="line2d_4">
|
||||
<g>
|
||||
<use xlink:href="#mfeb5fcddc7" x="123.519091" y="188.44" style="stroke: #000000; stroke-width: 0.8"/>
|
||||
<use xlink:href="#mf0a04b41f8" x="123.519091" y="188.44" style="stroke: #000000; stroke-width: 0.8"/>
|
||||
</g>
|
||||
</g>
|
||||
<g id="text_2">
|
||||
|
|
@ -186,11 +185,11 @@ z
|
|||
<g id="line2d_5">
|
||||
<path d="M 174.248182 188.44
|
||||
L 174.248182 25.44
|
||||
" clip-path="url(#p448fd06892)" style="fill: none; stroke-dasharray: 0.8,1.32; stroke-dashoffset: 0; stroke: #b0b0b0; stroke-opacity: 0.5; stroke-width: 0.8"/>
|
||||
" clip-path="url(#pce73ba693e)" style="fill: none; stroke-dasharray: 0.8,1.32; stroke-dashoffset: 0; stroke: #b0b0b0; stroke-opacity: 0.5; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g id="line2d_6">
|
||||
<g>
|
||||
<use xlink:href="#mfeb5fcddc7" x="174.248182" y="188.44" style="stroke: #000000; stroke-width: 0.8"/>
|
||||
<use xlink:href="#mf0a04b41f8" x="174.248182" y="188.44" style="stroke: #000000; stroke-width: 0.8"/>
|
||||
</g>
|
||||
</g>
|
||||
<g id="text_3">
|
||||
|
|
@ -230,11 +229,11 @@ z
|
|||
<g id="line2d_7">
|
||||
<path d="M 224.977273 188.44
|
||||
L 224.977273 25.44
|
||||
" clip-path="url(#p448fd06892)" style="fill: none; stroke-dasharray: 0.8,1.32; stroke-dashoffset: 0; stroke: #b0b0b0; stroke-opacity: 0.5; stroke-width: 0.8"/>
|
||||
" clip-path="url(#pce73ba693e)" style="fill: none; stroke-dasharray: 0.8,1.32; stroke-dashoffset: 0; stroke: #b0b0b0; stroke-opacity: 0.5; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g id="line2d_8">
|
||||
<g>
|
||||
<use xlink:href="#mfeb5fcddc7" x="224.977273" y="188.44" style="stroke: #000000; stroke-width: 0.8"/>
|
||||
<use xlink:href="#mf0a04b41f8" x="224.977273" y="188.44" style="stroke: #000000; stroke-width: 0.8"/>
|
||||
</g>
|
||||
</g>
|
||||
<g id="text_4">
|
||||
|
|
@ -282,11 +281,11 @@ z
|
|||
<g id="line2d_9">
|
||||
<path d="M 275.706364 188.44
|
||||
L 275.706364 25.44
|
||||
" clip-path="url(#p448fd06892)" style="fill: none; stroke-dasharray: 0.8,1.32; stroke-dashoffset: 0; stroke: #b0b0b0; stroke-opacity: 0.5; stroke-width: 0.8"/>
|
||||
" clip-path="url(#pce73ba693e)" style="fill: none; stroke-dasharray: 0.8,1.32; stroke-dashoffset: 0; stroke: #b0b0b0; stroke-opacity: 0.5; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g id="line2d_10">
|
||||
<g>
|
||||
<use xlink:href="#mfeb5fcddc7" x="275.706364" y="188.44" style="stroke: #000000; stroke-width: 0.8"/>
|
||||
<use xlink:href="#mf0a04b41f8" x="275.706364" y="188.44" style="stroke: #000000; stroke-width: 0.8"/>
|
||||
</g>
|
||||
</g>
|
||||
<g id="text_5">
|
||||
|
|
@ -321,11 +320,11 @@ z
|
|||
<g id="line2d_11">
|
||||
<path d="M 326.435455 188.44
|
||||
L 326.435455 25.44
|
||||
" clip-path="url(#p448fd06892)" style="fill: none; stroke-dasharray: 0.8,1.32; stroke-dashoffset: 0; stroke: #b0b0b0; stroke-opacity: 0.5; stroke-width: 0.8"/>
|
||||
" clip-path="url(#pce73ba693e)" style="fill: none; stroke-dasharray: 0.8,1.32; stroke-dashoffset: 0; stroke: #b0b0b0; stroke-opacity: 0.5; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g id="line2d_12">
|
||||
<g>
|
||||
<use xlink:href="#mfeb5fcddc7" x="326.435455" y="188.44" style="stroke: #000000; stroke-width: 0.8"/>
|
||||
<use xlink:href="#mf0a04b41f8" x="326.435455" y="188.44" style="stroke: #000000; stroke-width: 0.8"/>
|
||||
</g>
|
||||
</g>
|
||||
<g id="text_6">
|
||||
|
|
@ -366,11 +365,11 @@ z
|
|||
<g id="line2d_13">
|
||||
<path d="M 377.164545 188.44
|
||||
L 377.164545 25.44
|
||||
" clip-path="url(#p448fd06892)" style="fill: none; stroke-dasharray: 0.8,1.32; stroke-dashoffset: 0; stroke: #b0b0b0; stroke-opacity: 0.5; stroke-width: 0.8"/>
|
||||
" clip-path="url(#pce73ba693e)" style="fill: none; stroke-dasharray: 0.8,1.32; stroke-dashoffset: 0; stroke: #b0b0b0; stroke-opacity: 0.5; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g id="line2d_14">
|
||||
<g>
|
||||
<use xlink:href="#mfeb5fcddc7" x="377.164545" y="188.44" style="stroke: #000000; stroke-width: 0.8"/>
|
||||
<use xlink:href="#mf0a04b41f8" x="377.164545" y="188.44" style="stroke: #000000; stroke-width: 0.8"/>
|
||||
</g>
|
||||
</g>
|
||||
<g id="text_7">
|
||||
|
|
@ -416,11 +415,11 @@ z
|
|||
<g id="line2d_15">
|
||||
<path d="M 427.893636 188.44
|
||||
L 427.893636 25.44
|
||||
" clip-path="url(#p448fd06892)" style="fill: none; stroke-dasharray: 0.8,1.32; stroke-dashoffset: 0; stroke: #b0b0b0; stroke-opacity: 0.5; stroke-width: 0.8"/>
|
||||
" clip-path="url(#pce73ba693e)" style="fill: none; stroke-dasharray: 0.8,1.32; stroke-dashoffset: 0; stroke: #b0b0b0; stroke-opacity: 0.5; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g id="line2d_16">
|
||||
<g>
|
||||
<use xlink:href="#mfeb5fcddc7" x="427.893636" y="188.44" style="stroke: #000000; stroke-width: 0.8"/>
|
||||
<use xlink:href="#mf0a04b41f8" x="427.893636" y="188.44" style="stroke: #000000; stroke-width: 0.8"/>
|
||||
</g>
|
||||
</g>
|
||||
<g id="text_8">
|
||||
|
|
@ -446,11 +445,11 @@ z
|
|||
<g id="line2d_17">
|
||||
<path d="M 478.622727 188.44
|
||||
L 478.622727 25.44
|
||||
" clip-path="url(#p448fd06892)" style="fill: none; stroke-dasharray: 0.8,1.32; stroke-dashoffset: 0; stroke: #b0b0b0; stroke-opacity: 0.5; stroke-width: 0.8"/>
|
||||
" clip-path="url(#pce73ba693e)" style="fill: none; stroke-dasharray: 0.8,1.32; stroke-dashoffset: 0; stroke: #b0b0b0; stroke-opacity: 0.5; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g id="line2d_18">
|
||||
<g>
|
||||
<use xlink:href="#mfeb5fcddc7" x="478.622727" y="188.44" style="stroke: #000000; stroke-width: 0.8"/>
|
||||
<use xlink:href="#mf0a04b41f8" x="478.622727" y="188.44" style="stroke: #000000; stroke-width: 0.8"/>
|
||||
</g>
|
||||
</g>
|
||||
<g id="text_9">
|
||||
|
|
@ -505,11 +504,11 @@ z
|
|||
<g id="line2d_19">
|
||||
<path d="M 529.351818 188.44
|
||||
L 529.351818 25.44
|
||||
" clip-path="url(#p448fd06892)" style="fill: none; stroke-dasharray: 0.8,1.32; stroke-dashoffset: 0; stroke: #b0b0b0; stroke-opacity: 0.5; stroke-width: 0.8"/>
|
||||
" clip-path="url(#pce73ba693e)" style="fill: none; stroke-dasharray: 0.8,1.32; stroke-dashoffset: 0; stroke: #b0b0b0; stroke-opacity: 0.5; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g id="line2d_20">
|
||||
<g>
|
||||
<use xlink:href="#mfeb5fcddc7" x="529.351818" y="188.44" style="stroke: #000000; stroke-width: 0.8"/>
|
||||
<use xlink:href="#mf0a04b41f8" x="529.351818" y="188.44" style="stroke: #000000; stroke-width: 0.8"/>
|
||||
</g>
|
||||
</g>
|
||||
<g id="text_10">
|
||||
|
|
@ -555,11 +554,11 @@ z
|
|||
<g id="line2d_21">
|
||||
<path d="M 580.080909 188.44
|
||||
L 580.080909 25.44
|
||||
" clip-path="url(#p448fd06892)" style="fill: none; stroke-dasharray: 0.8,1.32; stroke-dashoffset: 0; stroke: #b0b0b0; stroke-opacity: 0.5; stroke-width: 0.8"/>
|
||||
" clip-path="url(#pce73ba693e)" style="fill: none; stroke-dasharray: 0.8,1.32; stroke-dashoffset: 0; stroke: #b0b0b0; stroke-opacity: 0.5; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g id="line2d_22">
|
||||
<g>
|
||||
<use xlink:href="#mfeb5fcddc7" x="580.080909" y="188.44" style="stroke: #000000; stroke-width: 0.8"/>
|
||||
<use xlink:href="#mf0a04b41f8" x="580.080909" y="188.44" style="stroke: #000000; stroke-width: 0.8"/>
|
||||
</g>
|
||||
</g>
|
||||
<g id="text_11">
|
||||
|
|
@ -574,11 +573,11 @@ L 580.080909 25.44
|
|||
<g id="line2d_23">
|
||||
<path d="M 630.81 188.44
|
||||
L 630.81 25.44
|
||||
" clip-path="url(#p448fd06892)" style="fill: none; stroke-dasharray: 0.8,1.32; stroke-dashoffset: 0; stroke: #b0b0b0; stroke-opacity: 0.5; stroke-width: 0.8"/>
|
||||
" clip-path="url(#pce73ba693e)" style="fill: none; stroke-dasharray: 0.8,1.32; stroke-dashoffset: 0; stroke: #b0b0b0; stroke-opacity: 0.5; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g id="line2d_24">
|
||||
<g>
|
||||
<use xlink:href="#mfeb5fcddc7" x="630.81" y="188.44" style="stroke: #000000; stroke-width: 0.8"/>
|
||||
<use xlink:href="#mf0a04b41f8" x="630.81" y="188.44" style="stroke: #000000; stroke-width: 0.8"/>
|
||||
</g>
|
||||
</g>
|
||||
<g id="text_12">
|
||||
|
|
@ -724,12 +723,12 @@ z
|
|||
<g id="ytick_1">
|
||||
<g id="line2d_25">
|
||||
<defs>
|
||||
<path id="m2b8ef16b3a" d="M 0 0
|
||||
<path id="mc0b9ff744f" d="M 0 0
|
||||
L -3.5 0
|
||||
" style="stroke: #000000; stroke-width: 0.8"/>
|
||||
</defs>
|
||||
<g>
|
||||
<use xlink:href="#m2b8ef16b3a" x="72.79" y="48.829483" style="stroke: #000000; stroke-width: 0.8"/>
|
||||
<use xlink:href="#mc0b9ff744f" x="72.79" y="48.829483" style="stroke: #000000; stroke-width: 0.8"/>
|
||||
</g>
|
||||
</g>
|
||||
<g id="text_14">
|
||||
|
|
@ -843,7 +842,7 @@ z
|
|||
<g id="ytick_2">
|
||||
<g id="line2d_26">
|
||||
<g>
|
||||
<use xlink:href="#m2b8ef16b3a" x="72.79" y="106.94" style="stroke: #000000; stroke-width: 0.8"/>
|
||||
<use xlink:href="#mc0b9ff744f" x="72.79" y="106.94" style="stroke: #000000; stroke-width: 0.8"/>
|
||||
</g>
|
||||
</g>
|
||||
<g id="text_15">
|
||||
|
|
@ -884,7 +883,7 @@ z
|
|||
<g id="ytick_3">
|
||||
<g id="line2d_27">
|
||||
<g>
|
||||
<use xlink:href="#m2b8ef16b3a" x="72.79" y="165.050517" style="stroke: #000000; stroke-width: 0.8"/>
|
||||
<use xlink:href="#mc0b9ff744f" x="72.79" y="165.050517" style="stroke: #000000; stroke-width: 0.8"/>
|
||||
</g>
|
||||
</g>
|
||||
<g id="text_16">
|
||||
|
|
@ -1320,7 +1319,7 @@ z
|
|||
</g>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="p448fd06892">
|
||||
<clipPath id="pce73ba693e">
|
||||
<rect x="72.79" y="25.44" width="558.02" height="163"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 55 KiB |
|
Before Width: | Height: | Size: 42 KiB |
|
Before Width: | Height: | Size: 84 KiB |
|
Before Width: | Height: | Size: 86 KiB |
|
Before Width: | Height: | Size: 52 KiB |
|
Before Width: | Height: | Size: 158 KiB |
|
Before Width: | Height: | Size: 144 KiB |
|
Before Width: | Height: | Size: 84 KiB |
|
Before Width: | Height: | Size: 99 KiB |
|
Before Width: | Height: | Size: 132 KiB |
|
Before Width: | Height: | Size: 102 KiB |
|
Before Width: | Height: | Size: 54 KiB |
|
Before Width: | Height: | Size: 142 KiB |
|
Before Width: | Height: | Size: 101 KiB |
|
Before Width: | Height: | Size: 99 KiB |
|
Before Width: | Height: | Size: 94 KiB |
|
Before Width: | Height: | Size: 157 KiB |
|
Before Width: | Height: | Size: 138 KiB |
|
Before Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 68 KiB |
|
Before Width: | Height: | Size: 194 KiB |
|
Before Width: | Height: | Size: 101 KiB |
|
Before Width: | Height: | Size: 75 KiB |
|
Before Width: | Height: | Size: 104 KiB |
|
Before Width: | Height: | Size: 113 KiB |
|
Before Width: | Height: | Size: 230 KiB |