Web-M1-Ausbau: JSON-Gaesteliste, GA-Verlauf, Python-Serversteuerung, tische.ini-Upload
- bestellung.xml -> bestellung.json: neuer JSONConfig (loest XMLConfig ab), alle work-Beispiele konvertiert, Doku (CLAUDE/README/dateiformate) umgestellt - ga.py: Beobachtungsobjekt Entwicklung zeichnet den Loesungsverlauf auf, neuer Schalter --show-development erzeugt Entwicklung.svg (beste/mittlere/ schlechteste Wertigkeit ueber die Zyklus-Aktionen) - web/main.py: neuer Endpunkt /tische-datei (tische.ini-Upload, ast.literal_eval), Frontend kann jetzt eine tische.ini laden - libs/webserver.py: plattformunabhaengige start/stop/status-Steuerung der Web-Testinstanz (ersetzt run_web_helper.ps1), raeumt auch verwaiste --reload-Prozessbaeume zuverlaessig auf - Sicherheit/Modernisierung: eval() -> ast.literal_eval in Tische/Strafliste, sicherer Mini-Auswerter fuer die String-Ausdruecke in zyklus.cfg, defaultdict(set) in Plaetze - SVG: Tischnummer fett zentriert im Tischkreis statt "Tisch x" darueber - Tests: JSONConfig, Entwicklung und der Zyklus-Auswerter abgedeckt (9 Tests) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@@ -4,7 +4,7 @@ Referenz fuer die Eingabe- und Ausgabedateien eines `platz`-Laufs, mit Beispiele
|
||||
`work/test1/` und `work/test2/`.
|
||||
|
||||
Alle vier Dateien liegen unter dem mit `--indir <dir>` angegebenen Verzeichnis (z.B.
|
||||
`work/test1/` oder `work/test2/`) unter festen Namen: `tische.ini`, `bestellung.xml` als
|
||||
`work/test1/` oder `work/test2/`) unter festen Namen: `tische.ini`, `bestellung.json` als
|
||||
Eingabe, `TischePersonen.txt` und `PersonenTische.csv` als Ausgabe. Beispielaufruf:
|
||||
|
||||
```bash
|
||||
@@ -67,108 +67,90 @@ Werte wie `Nachbarliste` und `Koordinaten` werden mit `eval()` geladen (siehe
|
||||
`Tische.laden()` in `libs/Strukturdaten.py`) — es steht also echter Python-Ausdruckscode im
|
||||
File, keine reine INI-Syntax.
|
||||
|
||||
## Gaesteliste: `bestellung.xml`
|
||||
## Gaesteliste: `bestellung.json`
|
||||
|
||||
Ein `<Bestellung>` mit mehreren `<Gruppe>`-Bloecken. Jede Gruppe enthaelt:
|
||||
Ein JSON-Objekt mit dem Schluessel `"gruppen"`, einer Liste von Gruppen-Objekten. Jede
|
||||
Gruppe enthaelt:
|
||||
|
||||
- ein oder mehrere `<Person>`-Elemente mit `<Vorname>`, `<Nachname>` und optionalem
|
||||
`<Titel>`
|
||||
- optional `<Anzahl>N</Anzahl>`, um die zuletzt beschriebene Person zu einer Sammelbuchung
|
||||
von `N` (anonymen/gleichnamigen) Personen zu vervielfaeltigen
|
||||
- optional `<Tisch>Id</Tisch>`, um die Gruppe als VIP-Gruppe fest an den angegebenen Tisch
|
||||
zu binden (sie wird dann **nicht** vom GA platziert)
|
||||
- `"personen"`: Liste von Personen-Objekten mit `"vorname"`, `"nachname"` und optionalem
|
||||
`"titel"` (Pflicht: Vor- und Nachname)
|
||||
- optional `"name"`: Anzeigename der Gruppe (z.B. `"Familie Huber"`); nur fuer Ausgabe und
|
||||
Web-Anzeige, nicht fuer die Optimierung relevant
|
||||
- optional `"anzahl"`: N, um **jede** Person der Gruppe zu einer Sammelbuchung von N
|
||||
(gleichnamigen) Buchungen zu vervielfaeltigen — praktisch fuer anonyme Kontingente
|
||||
- optional `"tisch"`: Tisch-Id, um die Gruppe als VIP-Gruppe fest an diesen Tisch zu binden
|
||||
(sie wird dann **nicht** vom GA platziert)
|
||||
|
||||
XML-Kommentare (`<!-- ... -->`) sind erlaubt und werden beim Parsen ignoriert.
|
||||
Geladen wird das File von `JSONConfig` in `libs/Strukturdaten.py` (Nachfolger des frueheren
|
||||
`XMLConfig`; das alte `bestellung.xml`-Format wurde vollstaendig durch JSON abgeloest).
|
||||
Die Datei sollte UTF-8 sein; ein evtl. vorhandenes BOM (Excel) wird geschluckt.
|
||||
|
||||
Minimalbeispiel mit Sammelbuchungen, aus `work/test1/bestellung.xml`:
|
||||
Minimalbeispiel mit Sammelbuchungen, aus `work/test1/bestellung.json`:
|
||||
|
||||
```xml
|
||||
<Bestellung>
|
||||
|
||||
<Gruppe>
|
||||
<Person>
|
||||
<Vorname>A</Vorname>
|
||||
<Nachname>AA</Nachname>
|
||||
<Titel>Dipl. Ing.</Titel>
|
||||
</Person>
|
||||
<Anzahl>10</Anzahl>
|
||||
</Gruppe>
|
||||
|
||||
<Gruppe>
|
||||
<Person>
|
||||
<Vorname>B</Vorname>
|
||||
<Nachname>BB</Nachname>
|
||||
<Titel>Prof.</Titel>
|
||||
</Person>
|
||||
<Anzahl>4</Anzahl>
|
||||
</Gruppe>
|
||||
|
||||
<Gruppe>
|
||||
<Person>
|
||||
<Vorname>C</Vorname>
|
||||
<Nachname>CC</Nachname>
|
||||
<Titel>Dr.</Titel>
|
||||
</Person>
|
||||
<Anzahl>5</Anzahl>
|
||||
</Gruppe>
|
||||
|
||||
</Bestellung>
|
||||
```json
|
||||
{
|
||||
"gruppen": [
|
||||
{
|
||||
"anzahl": 10,
|
||||
"personen": [
|
||||
{ "vorname": "A", "nachname": "AA", "titel": "Dipl. Ing." }
|
||||
]
|
||||
},
|
||||
{
|
||||
"anzahl": 4,
|
||||
"personen": [
|
||||
{ "vorname": "B", "nachname": "BB", "titel": "Prof." }
|
||||
]
|
||||
},
|
||||
{
|
||||
"anzahl": 5,
|
||||
"personen": [
|
||||
{ "vorname": "C", "nachname": "CC", "titel": "Dr." }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Umfangreicheres Beispiel mit benannten Personen und einer VIP-Gruppe, aus
|
||||
`work/test2/bestellung.xml`:
|
||||
Umfangreicheres Beispiel mit benannten Gruppen und einer VIP-Gruppe, aus
|
||||
`work/test2/bestellung.json`:
|
||||
|
||||
```xml
|
||||
<Bestellung>
|
||||
|
||||
<!-- einfache Gruppe aus drei Personen
|
||||
mit festem Wunsch fuer einen Tisch-->
|
||||
<Gruppe>
|
||||
<Person>
|
||||
<Vorname>Michael</Vorname>
|
||||
<Nachname>Stangl</Nachname>
|
||||
<Titel>Dipl. Ing.</Titel>
|
||||
</Person>
|
||||
<Person>
|
||||
<Vorname>Magnus</Vorname>
|
||||
<Nachname>Mueller</Nachname>
|
||||
<Titel>Professor</Titel>
|
||||
</Person>
|
||||
<Person>
|
||||
<Vorname>Bernd Robert</Vorname>
|
||||
<Nachname>Hoehn</Nachname>
|
||||
<Titel>Professor</Titel>
|
||||
</Person>
|
||||
<Tisch>1</Tisch>
|
||||
</Gruppe>
|
||||
|
||||
<!-- einfache Gruppe aus zwei Personen -->
|
||||
<Gruppe>
|
||||
<Person>
|
||||
<Vorname>Heinz</Vorname>
|
||||
<Nachname>Bruegge</Nachname>
|
||||
</Person>
|
||||
<Person>
|
||||
<Vorname>Hubert</Vorname>
|
||||
<Nachname>K</Nachname>
|
||||
</Person>
|
||||
</Gruppe>
|
||||
|
||||
<!--Gruppe aus drei anonymen Personen-->
|
||||
<Gruppe>
|
||||
<Person>
|
||||
<Vorname>Bestelli</Vorname>
|
||||
<Nachname>Bloedkopf</Nachname>
|
||||
</Person>
|
||||
<Anzahl>3</Anzahl>
|
||||
</Gruppe>
|
||||
|
||||
</Bestellung>
|
||||
```json
|
||||
{
|
||||
"gruppen": [
|
||||
{
|
||||
"name": "einfache Gruppe aus drei Personen mit festem Wunsch fuer einen Tisch",
|
||||
"tisch": 1,
|
||||
"personen": [
|
||||
{ "vorname": "Michael", "nachname": "Stangl", "titel": "Dipl. Ing." },
|
||||
{ "vorname": "Magnus", "nachname": "Mueller", "titel": "Professor" },
|
||||
{ "vorname": "Bernd Robert", "nachname": "Hoehn", "titel": "Professor" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "einfache Gruppe aus zwei Personen",
|
||||
"personen": [
|
||||
{ "vorname": "Heinz", "nachname": "Bruegge" },
|
||||
{ "vorname": "Hubert", "nachname": "K" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Gruppe aus drei anonymen Personen",
|
||||
"anzahl": 3,
|
||||
"personen": [
|
||||
{ "vorname": "Bestelli", "nachname": "Bloedkopf" }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Die erste Gruppe hier ist per `<Tisch>1</Tisch>` fest an Tisch 1 gebunden (VIP-Gruppe); die
|
||||
letzte Gruppe erzeugt ueber `<Anzahl>3</Anzahl>` drei gleichnamige "Bestelli Bloedkopf"
|
||||
Buchungen.
|
||||
Die erste Gruppe hier ist per `"tisch": 1` fest an Tisch 1 gebunden (VIP-Gruppe); die letzte
|
||||
Gruppe erzeugt ueber `"anzahl": 3` drei gleichnamige "Bestelli Bloedkopf" Buchungen.
|
||||
|
||||
> Fuer den Web-Weg (Meilenstein 1) gibt es zusaetzlich einen CSV-Import (`libs/CSVConfig.py`,
|
||||
> Spalten `Vorname;Nachname;Titel;Gruppe;Tisch;Anzahl`) — inhaltlich aequivalent, nur
|
||||
> flach statt verschachtelt.
|
||||
|
||||
## Ausgabe: `TischePersonen.txt`
|
||||
|
||||
|
||||
@@ -2,15 +2,18 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="251.2" height="90.4" viewBox="0 0 251.2 90.4">
|
||||
<rect width="100%" height="100%" fill="white"/>
|
||||
<circle cx="45.2" cy="45.2" r="35.2" fill="white" stroke="black" stroke-width="1.5"/>
|
||||
<text x="45.2" y="8" text-anchor="middle" font-size="10" fill="black">Tisch 1</text>
|
||||
<circle cx="45.2" cy="32" r="12" fill="#e6194b" stroke="black" stroke-width="1"/>
|
||||
<circle cx="45.2" cy="58.4" r="12" fill="#e6194b" stroke="black" stroke-width="1"/>
|
||||
<circle cx="45.2" cy="45.2" r="12" fill="white" fill-opacity="0.75"/>
|
||||
<text x="45.2" y="45.2" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">0</text>
|
||||
<circle cx="125.6" cy="45.2" r="35.2" fill="white" stroke="black" stroke-width="1.5"/>
|
||||
<text x="125.6" y="8" text-anchor="middle" font-size="10" fill="black">Tisch 2</text>
|
||||
<circle cx="125.6" cy="32" r="12" fill="#3cb44b" stroke="black" stroke-width="1"/>
|
||||
<circle cx="125.6" cy="58.4" r="12" fill="#3cb44b" stroke="black" stroke-width="1"/>
|
||||
<circle cx="125.6" cy="45.2" r="12" fill="white" fill-opacity="0.75"/>
|
||||
<text x="125.6" y="45.2" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">0</text>
|
||||
<circle cx="206" cy="45.2" r="35.2" fill="white" stroke="black" stroke-width="1.5"/>
|
||||
<text x="206" y="8" text-anchor="middle" font-size="10" fill="black">Tisch 3</text>
|
||||
<circle cx="206" cy="32" r="12" fill="#4363d8" stroke="black" stroke-width="1"/>
|
||||
<circle cx="206" cy="58.4" r="12" fill="#4363d8" stroke="black" stroke-width="1"/>
|
||||
<circle cx="206" cy="45.2" r="12" fill="white" fill-opacity="0.75"/>
|
||||
<text x="206" y="45.2" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">0</text>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.5 KiB |
@@ -2,27 +2,33 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="251.2" height="412" viewBox="0 0 251.2 412">
|
||||
<rect width="100%" height="100%" fill="white"/>
|
||||
<circle cx="125.6" cy="366.8" r="35.2" fill="white" stroke="black" stroke-width="1.5"/>
|
||||
<text x="125.6" y="329.6" text-anchor="middle" font-size="10" fill="black">Tisch 1</text>
|
||||
<circle cx="125.6" cy="353.6" r="12" fill="#e6194b" stroke="black" stroke-width="1"/>
|
||||
<circle cx="125.6" cy="380" r="12" fill="#3cb44b" stroke="black" stroke-width="1"/>
|
||||
<circle cx="125.6" cy="366.8" r="12" fill="white" fill-opacity="0.75"/>
|
||||
<text x="125.6" y="366.8" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">0</text>
|
||||
<circle cx="206" cy="286.4" r="35.2" fill="white" stroke="black" stroke-width="1.5"/>
|
||||
<text x="206" y="249.2" text-anchor="middle" font-size="10" fill="black">Tisch 2</text>
|
||||
<circle cx="206" cy="273.2" r="12" fill="#e6194b" stroke="black" stroke-width="1"/>
|
||||
<circle cx="206" cy="299.6" r="12" fill="#e6194b" stroke="black" stroke-width="1"/>
|
||||
<circle cx="206" cy="286.4" r="12" fill="white" fill-opacity="0.75"/>
|
||||
<text x="206" y="286.4" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">0</text>
|
||||
<circle cx="206" cy="125.6" r="35.2" fill="white" stroke="black" stroke-width="1.5"/>
|
||||
<text x="206" y="88.4" text-anchor="middle" font-size="10" fill="black">Tisch 3</text>
|
||||
<circle cx="206" cy="112.4" r="12" fill="#4363d8" stroke="black" stroke-width="1"/>
|
||||
<circle cx="206" cy="138.8" r="12" fill="#4363d8" stroke="black" stroke-width="1"/>
|
||||
<circle cx="206" cy="125.6" r="12" fill="white" fill-opacity="0.75"/>
|
||||
<text x="206" y="125.6" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">0</text>
|
||||
<circle cx="125.6" cy="45.2" r="35.2" fill="white" stroke="black" stroke-width="1.5"/>
|
||||
<text x="125.6" y="8" text-anchor="middle" font-size="10" fill="black">Tisch 4</text>
|
||||
<circle cx="125.6" cy="32" r="12" fill="#f58231" stroke="black" stroke-width="1"/>
|
||||
<circle cx="125.6" cy="58.4" r="12" fill="#4363d8" stroke="black" stroke-width="1"/>
|
||||
<circle cx="125.6" cy="32" r="12" fill="#4363d8" stroke="black" stroke-width="1"/>
|
||||
<circle cx="125.6" cy="58.4" r="12" fill="#f58231" stroke="black" stroke-width="1"/>
|
||||
<circle cx="125.6" cy="45.2" r="12" fill="white" fill-opacity="0.75"/>
|
||||
<text x="125.6" y="45.2" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">0</text>
|
||||
<circle cx="45.2" cy="125.6" r="35.2" fill="white" stroke="black" stroke-width="1.5"/>
|
||||
<text x="45.2" y="88.4" text-anchor="middle" font-size="10" fill="black">Tisch 5</text>
|
||||
<circle cx="45.2" cy="112.4" r="12" fill="#f58231" stroke="black" stroke-width="1"/>
|
||||
<circle cx="45.2" cy="138.8" r="12" fill="#f58231" stroke="black" stroke-width="1"/>
|
||||
<circle cx="45.2" cy="125.6" r="12" fill="white" fill-opacity="0.75"/>
|
||||
<text x="45.2" y="125.6" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">0</text>
|
||||
<circle cx="45.2" cy="286.4" r="35.2" fill="white" stroke="black" stroke-width="1.5"/>
|
||||
<text x="45.2" y="249.2" text-anchor="middle" font-size="10" fill="black">Tisch 6</text>
|
||||
<circle cx="45.2" cy="273.2" r="12" fill="#3cb44b" stroke="black" stroke-width="1"/>
|
||||
<circle cx="45.2" cy="299.6" r="12" fill="#3cb44b" stroke="black" stroke-width="1"/>
|
||||
<circle cx="45.2" cy="286.4" r="12" fill="white" fill-opacity="0.75"/>
|
||||
<text x="45.2" y="286.4" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">0</text>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.9 KiB |
@@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="900" height="500" viewBox="0 0 900 500" font-family="sans-serif">
|
||||
<rect width="100%" height="100%" fill="white"/>
|
||||
<text x="450" y="30" text-anchor="middle" font-size="16" fill="#333">Entwicklung der Loesungsfindung</text>
|
||||
<line x1="60" y1="60" x2="60" y2="440" stroke="#333" stroke-width="1.5"/>
|
||||
<line x1="60" y1="440" x2="840" y2="440" stroke="#333" stroke-width="1.5"/>
|
||||
<line x1="60" y1="440.0" x2="840" y2="440.0" stroke="#eee" stroke-width="1"/>
|
||||
<text x="52" y="444.0" text-anchor="end" font-size="11" fill="#666">-200</text>
|
||||
<line x1="60" y1="364.0" x2="840" y2="364.0" stroke="#eee" stroke-width="1"/>
|
||||
<text x="52" y="368.0" text-anchor="end" font-size="11" fill="#666">-168</text>
|
||||
<line x1="60" y1="288.0" x2="840" y2="288.0" stroke="#eee" stroke-width="1"/>
|
||||
<text x="52" y="292.0" text-anchor="end" font-size="11" fill="#666">-136</text>
|
||||
<line x1="60" y1="212.0" x2="840" y2="212.0" stroke="#eee" stroke-width="1"/>
|
||||
<text x="52" y="216.0" text-anchor="end" font-size="11" fill="#666">-104</text>
|
||||
<line x1="60" y1="136.0" x2="840" y2="136.0" stroke="#eee" stroke-width="1"/>
|
||||
<text x="52" y="140.0" text-anchor="end" font-size="11" fill="#666">-72</text>
|
||||
<line x1="60" y1="60.0" x2="840" y2="60.0" stroke="#eee" stroke-width="1"/>
|
||||
<text x="52" y="64.0" text-anchor="end" font-size="11" fill="#666">-40</text>
|
||||
<text x="18" y="250" text-anchor="middle" font-size="12" fill="#333" transform="rotate(-90 18 250)">Wertigkeit (hoeher = besser)</text>
|
||||
<text x="450" y="482" text-anchor="middle" font-size="12" fill="#333">Zyklus-Aktion (Zeit)</text>
|
||||
<text x="60.0" y="456" text-anchor="middle" font-size="10" fill="#999">e</text>
|
||||
<text x="450.0" y="456" text-anchor="middle" font-size="10" fill="#999">s</text>
|
||||
<text x="840.0" y="456" text-anchor="middle" font-size="10" fill="#999">m</text>
|
||||
<polyline points="60.0,178.8 450.0,131.2 840.0,60.0" fill="none" stroke="#2f6f4f" stroke-width="2"/>
|
||||
<polyline points="60.0,313.3 450.0,155.0 840.0,95.6" fill="none" stroke="#c08a2d" stroke-width="2"/>
|
||||
<polyline points="60.0,440.0 450.0,178.8 840.0,131.2" fill="none" stroke="#a03030" stroke-width="2"/>
|
||||
<line x1="680" y1="70" x2="704" y2="70" stroke="#2f6f4f" stroke-width="2"/>
|
||||
<text x="710" y="74" font-size="11" fill="#333">beste Loesung</text>
|
||||
<line x1="680" y1="88" x2="704" y2="88" stroke="#c08a2d" stroke-width="2"/>
|
||||
<text x="710" y="92" font-size="11" fill="#333">Durchschnitt</text>
|
||||
<line x1="680" y1="106" x2="704" y2="106" stroke="#a03030" stroke-width="2"/>
|
||||
<text x="710" y="110" font-size="11" fill="#333">schlechteste Loesung</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.6 KiB |
@@ -2,19 +2,23 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="331.6" height="90.4" viewBox="0 0 331.6 90.4">
|
||||
<rect width="100%" height="100%" fill="white"/>
|
||||
<circle cx="45.2" cy="45.2" r="35.2" fill="white" stroke="black" stroke-width="1.5"/>
|
||||
<text x="45.2" y="8" text-anchor="middle" font-size="10" fill="black">Tisch 1</text>
|
||||
<circle cx="45.2" cy="32" r="12" fill="#e6194b" stroke="black" stroke-width="1"/>
|
||||
<circle cx="45.2" cy="58.4" r="12" fill="#e6194b" stroke="black" stroke-width="1"/>
|
||||
<circle cx="45.2" cy="45.2" r="12" fill="white" fill-opacity="0.75"/>
|
||||
<text x="45.2" y="45.2" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">0</text>
|
||||
<circle cx="125.6" cy="45.2" r="35.2" fill="white" stroke="black" stroke-width="1.5"/>
|
||||
<text x="125.6" y="8" text-anchor="middle" font-size="10" fill="black">Tisch 2</text>
|
||||
<circle cx="125.6" cy="32" r="12" fill="#e6194b" stroke="black" stroke-width="1"/>
|
||||
<circle cx="125.6" cy="58.4" r="12" fill="#e6194b" stroke="black" stroke-width="1"/>
|
||||
<circle cx="125.6" cy="45.2" r="12" fill="white" fill-opacity="0.75"/>
|
||||
<text x="125.6" y="45.2" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">0</text>
|
||||
<circle cx="206" cy="45.2" r="35.2" fill="white" stroke="black" stroke-width="1.5"/>
|
||||
<text x="206" y="8" text-anchor="middle" font-size="10" fill="black">Tisch 3</text>
|
||||
<circle cx="206" cy="32" r="12" fill="#3cb44b" stroke="black" stroke-width="1"/>
|
||||
<circle cx="206" cy="58.4" r="12" fill="#3cb44b" stroke="black" stroke-width="1"/>
|
||||
<circle cx="206" cy="45.2" r="12" fill="white" fill-opacity="0.75"/>
|
||||
<text x="206" y="45.2" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">0</text>
|
||||
<circle cx="286.4" cy="45.2" r="35.2" fill="white" stroke="black" stroke-width="1.5"/>
|
||||
<text x="286.4" y="8" text-anchor="middle" font-size="10" fill="black">Tisch 4</text>
|
||||
<circle cx="286.4" cy="32" r="12" fill="#3cb44b" stroke="black" stroke-width="1"/>
|
||||
<circle cx="286.4" cy="58.4" r="12" fill="#3cb44b" stroke="black" stroke-width="1"/>
|
||||
<circle cx="286.4" cy="45.2" r="12" fill="white" fill-opacity="0.75"/>
|
||||
<text x="286.4" y="45.2" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">0</text>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 2.0 KiB |
@@ -235,6 +235,17 @@ verarbeitet werden (was bei jedem Webserver der Fall ist).
|
||||
- [ ] Optional: Hintergrund-Job-Queue (z.B. Celery/RQ), falls Berechnung >5s dauert,
|
||||
damit der Webserver nicht blockiert
|
||||
|
||||
**Tech-Debt / Modernisierung (Code-Review 2026-07-11):** Beim Umbau bereits erledigt sind
|
||||
`eval()` → `ast.literal_eval` (bzw. ein sicherer Mini-Auswerter für die String-Ausdrücke
|
||||
in `zyklus.cfg`) und `defaultdict(set)` in `Plaetze`. Bewusst *nicht* umgesetzt, für M2 zu
|
||||
prüfen: **GA-Kern auf [DEAP](https://deap.readthedocs.io/) umstellen** (fertige
|
||||
Population/Selektion/Statistik — würde das eigene `Farm`/`Entwicklung`-Gerüst ablösen und
|
||||
`TopN` sowie die Diversitäts-Seeds quasi geschenkt liefern); **SVG-Erzeugung** in
|
||||
`Sitzplatzverteilung.alsSVG`/`Entwicklung.alsSVG` von String-Konkatenation auf `svgwrite`
|
||||
oder Jinja2-Templates; **Container-/Datenklassen** (`Person`, `Gruppe`, …) als
|
||||
`@dataclass`. `Sitzplatzverteilung.TopX` bleibt bewusst handgeschrieben (die monoton
|
||||
sinkende Schwelle prägt das Mutationsverhalten, siehe Kommentar im Code).
|
||||
|
||||
**Aufwand:** ~3–4 Wochen, aufbauend auf Meilenstein 1.
|
||||
|
||||
---
|
||||
|
||||