"""S02 template recommendation test (2026-10-15), no Rhino / no DWG converter: for every pier in data/ that has indexed drawing texts, estimate the fit answers from the texts and compare with the answers of the pier's own params.json (leave-in: the pier's own template is among the candidates). Prints the ranking; PASS when the estimates equal the pier's own profile and the top-ranked template set contains a template with the same profile.""" import json import sys from pathlib import Path APP = Path(__file__).resolve().parents[1] sys.path.insert(0, str(APP)) from engine import reader, recommend # noqa: E402 DATA = APP / "data" TPL = {d.name: json.loads((d / "params.json").read_text(encoding="utf-8")) for d in sorted((DATA / "_템플릿").iterdir()) if (d / "params.json").exists()} profiles = {n: recommend.profile(p) for n, p in TPL.items()} ok = True KNOWN_MISMATCH = set() # Ulsan P2 was one (stale P1 copy without piles) until its 2026-10-15 modelling (OPEN #31 resolved) def check(name, cond, detail=""): global ok ok &= bool(cond) print("PASS" if cond else "FAIL", name, str(detail)[:400], flush=True) for n, pr in profiles.items(): print("template", n, pr) for d in sorted(DATA.iterdir()): f = d / "drawings" / "texts.json" if not (d / "params.json").exists() or not f.exists(): continue texts = json.loads(f.read_text(encoding="utf-8")) rows = next((t["rows"] for t in reader.table_candidates(texts) if t["key"] == "elevation"), []) est = recommend.estimate(texts, rows) own = recommend.profile(json.loads((d / "params.json").read_text(encoding="utf-8"))) got = {q: est[q][0] for q, _ in recommend.QUESTIONS} if d.name in KNOWN_MISMATCH: print("WARN", d.name, "known mismatch drawing vs model (OPEN #31)", f"est={got} own={own}") continue check(f"{d.name}: estimate == own profile", got == own, f"est={got} own={own}") rk = recommend.rank(est, profiles) best = [r["name"] for r in rk if r["matched"] == rk[0]["matched"]] same = [n for n, pr in profiles.items() if pr == own] if same: check(f"{d.name}: top-ranked templates {best} contain a same-profile template {same}", set(best) & set(same) and rk[0]["matched"] == rk[0]["asked"]) else: # a form no protected template has (Ulsan P2: piles + straight soffit + 4 bearings) -> "판단 불가" check(f"{d.name}: no template has this profile -> no full match ({rk[0]['matched']}/{rk[0]['asked']}, closest {best})", rk[0]["matched"] < rk[0]["asked"]) print("RESULT", "PASS" if ok else "FAIL") sys.exit(0 if ok else 1)