Fixrunde 1 zu Task 11, zwei von der Koordination gefundene und am echten Netz nachgemessene
Fehler, beide durch die Senkung von MIN_CENTERLINE (15 m) auf MIN_EDGE (5 m) erst möglich:
1. cut_edges() hängte beide Enden eines Schnittstücks über attach() an - dessen 8-m-Umkreis fand
bei einem Reststück zwischen 5 und 8 m Länge für beide Enden denselben ursprünglichen Knoten
und machte aus dem geraden Stummel eine Schleife. section.py hält jeden Knoten ab Grad 3 für
eine Kreuzung; an einem Sackgassenende wären dort Kreuzungsfläche, Zebrastreifen und
Haltelinie entstanden. Die neue _cut_end() sucht nicht mehr im Umkreis, sondern nur noch nach
exakter Übereinstimmung mit einem der beiden ursprünglichen Kantenenden.
2. apply_street() hängte die Jefferson Avenue nur mit einem attach()-Paar an ihre beiden Enden.
Am echten Netz liegt ihr Nordende 23,2 m von jedem Knoten entfernt, aber die Straße kreuzt auf
dem Weg zu ihrem Südende (6,6 m von Knoten 561) die 11th Street mittendrin, ohne dass dort ein
Knoten entsteht - zwei Fahrbahnen hätten sich unverbunden überlagert. Die neue insert_edge()
bricht jede gekreuzte Kante am Kreuzungspunkt auf und teilt sich dort einen Knoten mit der
neuen Straße (mit attach() für die Knotenwahl, wie gehabt); apply_street() benutzt sie jetzt
statt des attach()-Paars.
Am echten Netz (1.537 Knoten, 1.790 Kanten vor Flamingo Park) bestätigt: Jefferson Avenue bricht
jetzt korrekt an der 11th Street auf (neuer Knoten, Grad 4) und hängt am Südende weiterhin an
Knoten 561 (Grad 3 -> 4); die Meldezeile und die Sperrflächen-Warnung blieben wörtlich. Die
Schleifenzahl im Gesamtnetz sank von 196 auf 193 (die Park-Anlage schneidet alte Schleifen im
Parkgebiet weg), keine der verbliebenen 193 entstand neu - jede hat ein Vor-Park-Gegenstück im
5-m-Umkreis. Keine Kante unter 1 m, weder vorher noch nachher.
Neue Tests: test_roads_cut.py (Schleifenregression), test_roads_insert.py (drei Szenarien:
Kreuzung in der Mitte, Anhängen an einen Grad-3-Knoten, Kreuzungspunkt nahe einem vorhandenen
Knoten), test_park_street.py (Knotengrad an beiden Kreuzungen der Park-Zufahrtsstraße).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
World.centerlines wird zu World.graph: apply_street() und apply_park() schneiden und
verlängern jetzt den Straßengraphen statt einer losen Liste von Mittellinien, mit den neuen
roads.cut_edges()/attach() als Gegenstück zum bestehenden Schneiden der Straßenflächen.
apply_park() schneidet dabei einmal am Parkviereck (nicht je Sperrfläche - das schneidet
tatsächlich nichts, was der Parkumriss nicht schon geschnitten hätte). check_corners() bleibt
unverändert gegen world.roads (den Korridor) messen, mit einem erklärenden Docstring-Absatz und
einer Regressionswache dafür in den Tests.
MIN_CENTERLINE (15 m) entfällt zugunsten von MIN_EDGE (5 m): Der alte Grund - Laternen wählten
ihre Straßenseite über den Listenindex - fällt weg, sobald eine spätere Aufgabe die Seite aus
der Geometrie bestimmt. test_park_street.py dokumentiert das jetzt: die beiden 11-m-Enden der
geschnittenen Gasse bleiben deshalb stehen, statt wie vorher zu verschwinden.
Beim Nachrechnen der Prüfkörper aus dem Auftrag fielen zwei echte Fehler auf: Der Reste-unter-
Mindestlänge-Test schnitt ursprünglich bis übers Streckenende hinaus, sodass der Rest schon
geometrisch verschwand und der MIN_EDGE-Filter nie geprüft wurde - jetzt schneidet er innerhalb
der Strecke, sodass tatsächlich ein zu kurzes Stück verworfen wird. Und die neue
Korridor-Regressionswache verglich (12-7)/2 > 2.5, was mit den echten Maßen immer falsch ist
(2.5 > 2.5); korrigiert auf >=, denn die Halbdifferenz trifft die Toleranz exakt.
Ausserdem musste eine Test-Fixture in test_park_apply.py von einem 5-m-Reststück (exakt an der
neuen MIN_EDGE-Grenze, hätte also entgegen der ursprünglichen Testabsicht überlebt) auf 3 m
verkürzt werden, damit der Test weiterhin prüft, dass echte Kurzreste wegfallen.
run.py bleibt unangetastet: Es ist bereits durch eine frühere Aufgabe gebrochen und wird von der
nächsten Aufgabe repariert.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>