[CHANGE] JSON-Testdaten-Feldnamen aus dxf_anlage_export.py in lib/testdata_schema.py zentralisiert
dxf_anlage_export.py und dxf_scan_components.py fuehrten dieselben Feldnamen (abstand, deltaL_mm, as_seite, ...) aus doc/json-input-lisp.md unabhaengig als lose String-Literale - ein Tippfehler oder eine Schema-Aenderung in nur einer Datei waere nicht aufgefallen. Neues Modul lib/testdata_schema.py buendelt die Feldnamen/festen Werte der dokumentierten Schemas (Kreisel, Einzelblock, VF Standard/Etage, Gefaellestrecke Modus 1) als benannte Konstanten; dxf_anlage_export.py nutzt sie jetzt durchgaengig. dxf_scan_components.py bewusst NICHT mitumgebaut: deutlich grösser/komplexer, mit zusaetzlichen Sonderfaellen (z.B. "startpunkt"/"gerade"-Form), ein vollstaendiger Umbau haette den Rahmen dieser Aenderung gesprengt und mehr Risiko als Nutzen gehabt. Verhaltensgleich: alle 9 Tests in tests/test_dxf_anlage_export.py laufen weiterhin gruen. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -10,6 +10,14 @@ Die zugehoerigen LISP-Routinen mit Signaturen stehen in
|
|||||||
`tests/testdata/object_data.md` (geloescht in Commit `e147b89`, auf das Code-
|
`tests/testdata/object_data.md` (geloescht in Commit `e147b89`, auf das Code-
|
||||||
Kommentare teilweise noch verweisen).
|
Kommentare teilweise noch verweisen).
|
||||||
|
|
||||||
|
**Feldnamen als Python-Konstanten**: `lib/testdata_schema.py` buendelt die
|
||||||
|
Feldnamen/festen Werte der Abschnitte 1 (Kreisel), 2 (Einzelbloecke), 3 (VF
|
||||||
|
Standard/Etage) und 4.1 (Gefaellestrecke Modus 1) als benannte Konstanten
|
||||||
|
(`sch.F_ABSTAND`, `sch.SEITE_LINKS`, ...), genutzt von `lib/dxf_anlage_export.py`
|
||||||
|
(eigene, mit unseren Makros gebaute Zeichnungen). `lib/dxf_scan_components.py`
|
||||||
|
(fremde Zeichnungen) hat dieselben Feldnamen weiterhin als eigene String-
|
||||||
|
Literale - gleiches Schema, noch nicht auf das gemeinsame Modul umgestellt.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 0. Uebersicht
|
## 0. Uebersicht
|
||||||
|
|||||||
+44
-43
@@ -63,6 +63,7 @@ import sys
|
|||||||
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
||||||
from vf_journal_export import TRENNER, gruppen # noqa: E402
|
from vf_journal_export import TRENNER, gruppen # noqa: E402
|
||||||
from dxf_scan_components import arrays_einzeilig, kreisel_anschluss # noqa: E402
|
from dxf_scan_components import arrays_einzeilig, kreisel_anschluss # noqa: E402
|
||||||
|
import testdata_schema as sch # noqa: E402
|
||||||
|
|
||||||
PREFIX = "[dxf_anlage_export]"
|
PREFIX = "[dxf_anlage_export]"
|
||||||
RUND = 2
|
RUND = 2
|
||||||
@@ -204,17 +205,17 @@ def kreisel_eintrag(e, block_inhalt, projekt):
|
|||||||
quelle = "Blockdefinition (AN8 -> SP8)"
|
quelle = "Blockdefinition (AN8 -> SP8)"
|
||||||
nr = int(_float(a.get("NUMMER"))) or _nummer(e["name"])
|
nr = int(_float(a.get("NUMMER"))) or _nummer(e["name"])
|
||||||
return collections.OrderedDict([
|
return collections.OrderedDict([
|
||||||
("id", "Kreisel_%s_%02d" % (projekt, nr)),
|
(sch.F_ID, "Kreisel_%s_%02d" % (projekt, nr)),
|
||||||
("function", "insert"),
|
(sch.F_FUNCTION, sch.FUNC_INSERT),
|
||||||
("x", _r(e["p"][0])), ("y", _r(e["p"][1])), ("z", _r(e["p"][2])),
|
(sch.F_X, _r(e["p"][0])), (sch.F_Y, _r(e["p"][1])), (sch.F_Z, _r(e["p"][2])),
|
||||||
("abstand", _r(abstand)),
|
(sch.F_ABSTAND, _r(abstand)),
|
||||||
("rotation", _r(e["rot"])),
|
(sch.F_ROTATION, _r(e["rot"])),
|
||||||
("typ", a.get("KREISELART") or "STANDARD"),
|
(sch.F_TYP, a.get("KREISELART") or sch.TYP_STANDARD),
|
||||||
# Umlaufsinn: bestimmt die Reihenfolge im Kreisel-Umlauf und damit den
|
# Umlaufsinn: bestimmt die Reihenfolge im Kreisel-Umlauf und damit den
|
||||||
# TRO-Fluss - ohne ihn kam jeder Nachbau als UZS heraus (Dematic 1/4:
|
# TRO-Fluss - ohne ihn kam jeder Nachbau als UZS heraus (Dematic 1/4:
|
||||||
# GUZ). hundm05:bau-kreisel reicht ihn an kreisel-insert-script weiter.
|
# GUZ). hundm05:bau-kreisel reicht ihn an kreisel-insert-script weiter.
|
||||||
("drehrichtung", a.get("DREHRICHTUNG") or "UZS"),
|
(sch.F_DREHRICHTUNG, a.get("DREHRICHTUNG") or sch.DREHRICHTUNG_UZS),
|
||||||
("comment", "aus Zeichnung: %s (ID %s), abstand aus %s"
|
(sch.F_COMMENT, "aus Zeichnung: %s (ID %s), abstand aus %s"
|
||||||
% (e["name"], a.get("ID", "?"), quelle)),
|
% (e["name"], a.get("ID", "?"), quelle)),
|
||||||
])
|
])
|
||||||
|
|
||||||
@@ -251,15 +252,15 @@ def gf_eintrag(e, geo, projekt, hinweise):
|
|||||||
r = _richtung(hz)
|
r = _richtung(hz)
|
||||||
ende = (start[0] + deltaL * r[0], start[1] + deltaL * r[1])
|
ende = (start[0] + deltaL * r[0], start[1] + deltaL * r[1])
|
||||||
eintrag = collections.OrderedDict([
|
eintrag = collections.OrderedDict([
|
||||||
("test_id", "GF_%s_%02d" % (projekt, _nummer(e["name"]))),
|
(sch.F_TEST_ID, "GF_%s_%02d" % (projekt, _nummer(e["name"]))),
|
||||||
("modus", 1),
|
(sch.F_MODUS, sch.GF_MODUS_WERTEINGABE),
|
||||||
("deltaL_mm", _r(deltaL)),
|
(sch.F_DELTAL_MM, _r(deltaL)),
|
||||||
("hz_grad", _r(hz)),
|
(sch.F_HZ_GRAD, _r(hz)),
|
||||||
("start_mm", [_r(start[0]), _r(start[1]), _r(z_start)]),
|
(sch.F_START_MM, [_r(start[0]), _r(start[1]), _r(z_start)]),
|
||||||
("as_seite", a.get("SEITE_AS") or "links"),
|
(sch.F_AS_SEITE, a.get("SEITE_AS") or sch.SEITE_LINKS),
|
||||||
("es_seite", a.get("SEITE_ES") or "links"),
|
(sch.F_ES_SEITE, a.get("SEITE_ES") or sch.SEITE_LINKS),
|
||||||
("as_winkel", xd[2] or "90"),
|
(sch.F_AS_WINKEL, xd[2] or sch.SCHLEUS_WINKEL_90),
|
||||||
("es_winkel", xd[3] or "90"),
|
(sch.F_ES_WINKEL, xd[3] or sch.SCHLEUS_WINKEL_90),
|
||||||
])
|
])
|
||||||
k_start = kreisel_an_punkt(start, r, geo)
|
k_start = kreisel_an_punkt(start, r, geo)
|
||||||
k_ende = kreisel_an_punkt(ende, (-r[0], -r[1]), geo)
|
k_ende = kreisel_an_punkt(ende, (-r[0], -r[1]), geo)
|
||||||
@@ -275,7 +276,7 @@ def gf_eintrag(e, geo, projekt, hinweise):
|
|||||||
else:
|
else:
|
||||||
eintrag["winkel_grad"] = round(winkel, 4)
|
eintrag["winkel_grad"] = round(winkel, 4)
|
||||||
kommentar = "kein Kreisel am Ende - gebauter Winkel uebernommen"
|
kommentar = "kein Kreisel am Ende - gebauter Winkel uebernommen"
|
||||||
eintrag["comment"] = "aus Zeichnung: %s (ID %s); %s" % (
|
eintrag[sch.F_COMMENT] = "aus Zeichnung: %s (ID %s); %s" % (
|
||||||
e["name"], a.get("ID", "?"), kommentar)
|
e["name"], a.get("ID", "?"), kommentar)
|
||||||
return eintrag
|
return eintrag
|
||||||
|
|
||||||
@@ -286,18 +287,18 @@ def vf_standard_eintrag(e, projekt, typ):
|
|||||||
xd = e["xdata"].get("SSG_VF_EDIT") or []
|
xd = e["xdata"].get("SSG_VF_EDIT") or []
|
||||||
l_gf = [t for t in (a.get("L_GF_m") or "").split(",") if t.strip()]
|
l_gf = [t for t in (a.get("L_GF_m") or "").split(",") if t.strip()]
|
||||||
eintrag = collections.OrderedDict([
|
eintrag = collections.OrderedDict([
|
||||||
("test_id", "VF_%s_%02d" % (projekt, _nummer(e["name"]))),
|
(sch.F_TEST_ID, "VF_%s_%02d" % (projekt, _nummer(e["name"]))),
|
||||||
("typ", typ),
|
(sch.F_VF_TYP, typ),
|
||||||
("richtung", a.get("ANTRIEBFAHRTRICHTUNG") or "Auf"),
|
(sch.F_RICHTUNG, a.get("ANTRIEBFAHRTRICHTUNG") or sch.RICHTUNG_AUF),
|
||||||
("deltaL", _r(_float(a.get("DELTA_L_mm")))),
|
(sch.F_DELTA_L, _r(_float(a.get("DELTA_L_mm")))),
|
||||||
("deltaH", _r(_float(a.get("DELTA_H_mm")))),
|
(sch.F_DELTA_H, _r(_float(a.get("DELTA_H_mm")))),
|
||||||
("winkel", int(_float(a.get("VF_WINKEL")))),
|
(sch.F_WINKEL, int(_float(a.get("VF_WINKEL")))),
|
||||||
("L_GF1", _r(1000.0 * _float(l_gf[0])) if l_gf else 0.0),
|
(sch.F_L_GF1, _r(1000.0 * _float(l_gf[0])) if l_gf else 0.0),
|
||||||
("seite", a.get("SEITE_AS") or "rechts"),
|
(sch.F_SEITE, a.get("SEITE_AS") or sch.SEITE_RECHTS),
|
||||||
("motorseite", (a.get("MOTORSEITE") or "rechts").split(",")[0]),
|
(sch.F_MOTORSEITE, (a.get("MOTORSEITE") or sch.SEITE_RECHTS).split(",")[0]),
|
||||||
("hz", _r(_float(xd[1]) if len(xd) > 1 else 0.0)),
|
(sch.F_HZ, _r(_float(xd[1]) if len(xd) > 1 else 0.0)),
|
||||||
("x", _r(e["p"][0])), ("y", _r(e["p"][1])), ("z", _r(e["p"][2])),
|
(sch.F_X, _r(e["p"][0])), (sch.F_Y, _r(e["p"][1])), (sch.F_Z, _r(e["p"][2])),
|
||||||
("comment", "aus Zeichnung: %s (ID %s), Hoehe %s -> %s; deltaL/"
|
(sch.F_COMMENT, "aus Zeichnung: %s (ID %s), Hoehe %s -> %s; deltaL/"
|
||||||
"deltaH aus den (ganzzahligen) Attributen"
|
"deltaH aus den (ganzzahligen) Attributen"
|
||||||
% (e["name"], a.get("ID", "?"), a.get("HOEHE_VON_mm", "?"),
|
% (e["name"], a.get("ID", "?"), a.get("HOEHE_VON_mm", "?"),
|
||||||
a.get("HOEHE_BIS_mm", "?"))),
|
a.get("HOEHE_BIS_mm", "?"))),
|
||||||
@@ -311,10 +312,10 @@ def vf_journal_eintrag(e, projekt, nr):
|
|||||||
roh = "".join(e["xdata"]["SSG_VF_EDIT"][1:])
|
roh = "".join(e["xdata"]["SSG_VF_EDIT"][1:])
|
||||||
tokens = [t for t in roh.split(TRENNER) if t]
|
tokens = [t for t in roh.split(TRENNER) if t]
|
||||||
return collections.OrderedDict([
|
return collections.OrderedDict([
|
||||||
("test_id", "VF_%s_LZ_%02d" % (projekt, nr)),
|
(sch.F_TEST_ID, "VF_%s_LZ_%02d" % (projekt, nr)),
|
||||||
("typ", "linienzug_journal"),
|
(sch.F_VF_TYP, "linienzug_journal"),
|
||||||
("journal", tokens),
|
("journal", tokens),
|
||||||
("comment", "aus Zeichnung: %s (ID %s), %d Eingaben, Hoehe %s -> %s; "
|
(sch.F_COMMENT, "aus Zeichnung: %s (ID %s), %d Eingaben, Hoehe %s -> %s; "
|
||||||
"wird 1:1 abgespielt (vsp-bau-journal)"
|
"wird 1:1 abgespielt (vsp-bau-journal)"
|
||||||
% (e["name"], a.get("ID", "?"), len(tokens),
|
% (e["name"], a.get("ID", "?"), len(tokens),
|
||||||
a.get("HOEHE_VON_mm", "?"), a.get("HOEHE_BIS_mm", "?"))),
|
a.get("HOEHE_VON_mm", "?"), a.get("HOEHE_BIS_mm", "?"))),
|
||||||
@@ -326,11 +327,11 @@ def einzel_eintrag(e):
|
|||||||
info = ", ".join("%s %s" % (k, a[k]) for k in ("ID", "ZUORDNUNG", "ARTINR")
|
info = ", ".join("%s %s" % (k, a[k]) for k in ("ID", "ZUORDNUNG", "ARTINR")
|
||||||
if a.get(k))
|
if a.get(k))
|
||||||
return collections.OrderedDict([
|
return collections.OrderedDict([
|
||||||
("function", "insert"),
|
(sch.F_FUNCTION, sch.FUNC_INSERT),
|
||||||
("block", DIM_SUFFIX.sub("", e["name"])),
|
(sch.F_BLOCK, DIM_SUFFIX.sub("", e["name"])),
|
||||||
("x", _r(e["p"][0])), ("y", _r(e["p"][1])), ("z", _r(e["p"][2])),
|
(sch.F_X, _r(e["p"][0])), (sch.F_Y, _r(e["p"][1])), (sch.F_Z, _r(e["p"][2])),
|
||||||
("rotation", _r(e["rot"])),
|
(sch.F_ROTATION, _r(e["rot"])),
|
||||||
("comment", "aus Zeichnung: %s%s" % (e["name"],
|
(sch.F_COMMENT, "aus Zeichnung: %s%s" % (e["name"],
|
||||||
(" (%s)" % info) if info else "")),
|
(" (%s)" % info) if info else "")),
|
||||||
])
|
])
|
||||||
|
|
||||||
@@ -390,11 +391,11 @@ def main():
|
|||||||
eintraege, hinweise = baue_eintraege(inserts, block_inhalt, projekt)
|
eintraege, hinweise = baue_eintraege(inserts, block_inhalt, projekt)
|
||||||
|
|
||||||
zaehler = collections.Counter(
|
zaehler = collections.Counter(
|
||||||
"Kreisel" if "abstand" in e else
|
"Kreisel" if sch.F_ABSTAND in e else
|
||||||
"GF" if "modus" in e else
|
"GF" if sch.F_MODUS in e else
|
||||||
"VF Linienzug" if e.get("typ") == "linienzug_journal" else
|
"VF Linienzug" if e.get(sch.F_VF_TYP) == "linienzug_journal" else
|
||||||
"VF %s" % e["typ"] if "typ" in e and "test_id" in e else
|
"VF %s" % e[sch.F_VF_TYP] if sch.F_VF_TYP in e and sch.F_TEST_ID in e else
|
||||||
e.get("block", "?") for e in eintraege)
|
e.get(sch.F_BLOCK, "?") for e in eintraege)
|
||||||
for k, v in sorted(zaehler.items()):
|
for k, v in sorted(zaehler.items()):
|
||||||
print("%s %-22s %d" % (PREFIX, k, v))
|
print("%s %-22s %d" % (PREFIX, k, v))
|
||||||
for h in hinweise:
|
for h in hinweise:
|
||||||
|
|||||||
@@ -0,0 +1,79 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
testdata_schema.py - Feldnamen und feste Werte der JSON-Testdaten-Schemas aus
|
||||||
|
doc/json-input-lisp.md, als einzige Quelle fuer alle Erzeuger.
|
||||||
|
|
||||||
|
Bisher standen dieselben Feldnamen ("function", "abstand", "deltaL_mm",
|
||||||
|
"as_seite", ...) als lose String-Literale unabhaengig in dxf_scan_components.py
|
||||||
|
(fremde Zeichnungen) UND dxf_anlage_export.py (eigene, mit unseren Makros
|
||||||
|
gebaute Zeichnungen) - ein Tippfehler oder eine Schema-Aenderung in nur einer
|
||||||
|
der beiden Dateien waere nicht aufgefallen. Dieses Modul buendelt sie an
|
||||||
|
einer Stelle; die LISP-Treiber (tests/test_*.lsp) lesen die JSON-Keys direkt
|
||||||
|
als Strings und sind davon nicht betroffen.
|
||||||
|
|
||||||
|
Nur Feldnamen/feste Werte, KEINE Validierung oder Default-Logik - die bleibt
|
||||||
|
bewusst in den jeweiligen Erzeugern, deren Kontext (fremde vs. eigene
|
||||||
|
Zeichnung) unterschiedliche Fallbacks braucht.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# --- Gemeinsame Felder ---
|
||||||
|
F_FUNCTION = "function"
|
||||||
|
F_ID = "id"
|
||||||
|
F_TEST_ID = "test_id"
|
||||||
|
F_BLOCK = "block"
|
||||||
|
F_X = "x"
|
||||||
|
F_Y = "y"
|
||||||
|
F_Z = "z"
|
||||||
|
F_ROTATION = "rotation"
|
||||||
|
F_COMMENT = "comment"
|
||||||
|
|
||||||
|
FUNC_INSERT = "insert"
|
||||||
|
FUNC_CONNECT = "connect"
|
||||||
|
|
||||||
|
# --- Abschnitt 1 (json-input-lisp.md): Kreisel ---
|
||||||
|
F_ABSTAND = "abstand"
|
||||||
|
F_TYP = "typ"
|
||||||
|
F_DREHRICHTUNG = "drehrichtung"
|
||||||
|
|
||||||
|
TYP_STANDARD = "STANDARD"
|
||||||
|
TYP_PIN = "PIN"
|
||||||
|
DREHRICHTUNG_UZS = "UZS"
|
||||||
|
DREHRICHTUNG_GUZ = "GUZ"
|
||||||
|
|
||||||
|
# --- Abschnitt 3: VarioFoerderer Standard und Etage ---
|
||||||
|
F_VF_TYP = "typ"
|
||||||
|
F_RICHTUNG = "richtung"
|
||||||
|
F_DELTA_L = "deltaL"
|
||||||
|
F_DELTA_H = "deltaH"
|
||||||
|
F_WINKEL = "winkel"
|
||||||
|
F_L_GF1 = "L_GF1"
|
||||||
|
F_GF_VERTEILUNG = "gf_verteilung"
|
||||||
|
F_SEITE = "seite"
|
||||||
|
F_MOTORSEITE = "motorseite"
|
||||||
|
F_HZ = "hz"
|
||||||
|
|
||||||
|
VF_TYP_STANDARD = "standard"
|
||||||
|
VF_TYP_ETAGE = "etage"
|
||||||
|
RICHTUNG_AUF = "Auf"
|
||||||
|
RICHTUNG_AB = "Ab"
|
||||||
|
SEITE_LINKS = "links"
|
||||||
|
SEITE_RECHTS = "rechts"
|
||||||
|
|
||||||
|
# --- Abschnitt 4.1: Gefaellestrecke Modus 1 ---
|
||||||
|
F_MODUS = "modus"
|
||||||
|
F_DELTAL_MM = "deltaL_mm"
|
||||||
|
F_WINKEL_GRAD = "winkel_grad"
|
||||||
|
F_HZ_GRAD = "hz_grad"
|
||||||
|
F_START_MM = "start_mm"
|
||||||
|
F_AS_SEITE = "as_seite"
|
||||||
|
F_ES_SEITE = "es_seite"
|
||||||
|
F_AS_WINKEL = "as_winkel"
|
||||||
|
F_ES_WINKEL = "es_winkel"
|
||||||
|
|
||||||
|
GF_MODUS_WERTEINGABE = 1
|
||||||
|
GF_MODUS_RICHTUNG_AUS_PUNKTEN = 2
|
||||||
|
GF_MODUS_LINIENZUG = 3
|
||||||
|
|
||||||
|
SCHLEUS_WINKEL_90 = "90"
|
||||||
|
SCHLEUS_WINKEL_30 = "30"
|
||||||
Reference in New Issue
Block a user