Port codebase from Python 2 to Python 3
Replace Python 2-only constructs throughout libs/: print statements, ConfigParser -> configparser, sets.Set -> builtin set, string.split -> str.split, xrange -> range, dict.has_key()/.iteritems() -> in/.items(), old-style raise Exception, "msg" syntax, and __cmp__ -> __eq__/__lt__ via functools.total_ordering (Python 3 dropped cmp()/__cmp__, which max()/.sort() rely on). Also cleaned up mixed tab/space indentation that Python 3's stricter tokenizer rejects. Fixed two latent bugs that only surfaced once end-to-end runs were possible under Python 3's stricter error handling: - HandleBestellung() compared G.Anzahl (a bound method) to an int instead of calling G.Anzahl() - silently "worked" under Python 2's permissive cross-type ordering, raises TypeError under Python 3. - LeuteAllein() raised KeyError for VIP-group members, who are never added to the regular Gruppen container; now skips people with no group entry instead of crashing. Verified end-to-end: bin/platz.sh --indir work/test1 and --indir work/test2 (VIP group included) both run to completion and produce correctly formatted output. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -10,11 +10,27 @@ sizes/neighbor relationships, and a penalty scheme. It reads an XML order/guest
|
||||
table layout, runs a small custom GA framework to search for a good seating, and writes the
|
||||
result to text/CSV output files.
|
||||
|
||||
**This is Python 2 code** (print statements, `ConfigParser`, `sets.Set`, `UserList`,
|
||||
`string.split`, old-style `raise Exception, "msg"`, `xrange`, `dict.has_key`,
|
||||
`dict.iteritems`). It will not run under Python 3 without a 2to3-style port. There is no
|
||||
build system, test suite, or linter configured in this repo. `requirements.txt` exists but
|
||||
is empty/commented — everything used is standard library — it's there only so
|
||||
**This is Python 3 code**, migrated from an original Python 2 implementation (the git
|
||||
history / old comments may still say "Python 2" — that's now stale). Notable migration
|
||||
artifacts to be aware of when touching this code:
|
||||
- `Gruppe`, `Loesung`, and `Sitzplatzverteilung` use `@functools.total_ordering` with
|
||||
`__eq__`/`__lt__` instead of the old Python 2 `__cmp__` (Python 3 dropped `__cmp__` and
|
||||
`cmp()` entirely; `max()`/`.sort()` need rich comparisons).
|
||||
- `sets.Set` → builtin `set`; `ConfigParser` → `configparser`; `string.split` →
|
||||
`str.split`; `xrange` → `range`; `dict.has_key(k)` → `k in dict`; `dict.iteritems()` →
|
||||
`dict.items()`; old-style `raise Exception, "msg"` → `raise Exception("msg")`.
|
||||
- `Strukturdaten.LeuteAllein()` was fixed to skip people with no entry in
|
||||
`self.Gruppen.GvonPid` (e.g. VIP-group members who were never added to the regular
|
||||
`Gruppen` container) instead of letting `GruppeVonPid` raise `KeyError` — this was a
|
||||
latent bug that only surfaced once VIP data (`work/test2`) was actually exercised
|
||||
end-to-end.
|
||||
- `HandleBestellung()` had a `G.Anzahl` comparison (`G.Anzahl > 0`) that used to silently
|
||||
compare a bound method to an int under Python 2's permissive cross-type ordering;
|
||||
Python 3 raises `TypeError` for that, which is what surfaced it. Fixed to call
|
||||
`G.Anzahl()`.
|
||||
|
||||
There is no build system, test suite, or linter configured in this repo. `requirements.txt`
|
||||
exists but is empty/commented — everything used is standard library — it's there only so
|
||||
`bin/install_py.*` has something to install into the `.venv`.
|
||||
|
||||
## Running the program
|
||||
@@ -39,8 +55,8 @@ Entry point is `libs/platz.py`, invoked via the scripts in `bin/` (each provided
|
||||
"$PLATZ_LIBS/platz.py"`. This is the actual program entry point (replaces the old
|
||||
`bin/run` / `bin/run.bat`, which hardcoded absolute paths and have been removed).
|
||||
|
||||
`libs/platz.py` requires a command-line switch `--indir <dir>` (parsed with `optparse`,
|
||||
since this is Python 2) pointing at a directory that holds the per-run input files and
|
||||
`libs/platz.py` requires a command-line switch `--indir <dir>` (parsed with `optparse`)
|
||||
pointing at a directory that holds the per-run input files and
|
||||
receives the output files — e.g. `work/test1/`, `work/test2/`, or any new folder following
|
||||
the same layout:
|
||||
- `tische.ini` — table definitions: id, `Nummer`, `Hof` (venue/court), `Plaetze` (seats),
|
||||
@@ -79,7 +95,7 @@ Domain-agnostic and reusable in principle:
|
||||
- `Farm` — owns the population (`Pool`/`PoolNeu`), and executes a `Zyklus` action-by-action
|
||||
against instances of a given solution class (passed as `Klasse` plus its constructor
|
||||
args/kwargs). `Bester()` returns the fittest (`max()`) solution found; solutions are ordered
|
||||
via `__cmp__` on `self.value`.
|
||||
via `__eq__`/`__lt__` (`@total_ordering`) on `self.value`.
|
||||
|
||||
### `Strukturdaten.py` — domain model for this specific seating problem
|
||||
- `Person`, `Gruppe` (group — a `Set` of people, splittable via `teilen()`), `Tisch` (table —
|
||||
|
||||
Reference in New Issue
Block a user