knowledge(마스터): 나라장터 빼기 — 로직 호표를 자재품목으로 갈아 끼우고 MN 폐기
- 로직이 가리키던 나라장터 자리 121(정적 키 18 · 고르기 13벌)을 자재품목(MT) 줄로 갈아 끼움 — 이름·규격·단위가 맞는 줄 · 지역이 갈리는 품목은 서울 줄. - 자재품목에 맞는 줄이 없는 넷은 품셈재료 미연결로 돌림 — 시너(MP000266) · 동 및 동합금용 용접봉 BCUP3 · 폴리에틸렌필름 0.04㎜ · 아스팔트싱글(새 줄 셋). - 엔진이 자재품목 키를 바로 받으면 값 열 다섯 가운데 낮은 값(시험 계산용) · 출처는 「키.열」. - 재료_나라장터자재.json 과 그 빌더를 old 로 옮기고 키 대장에 MN 폐기 · check_master · 키 대장 · M01 서버·화면 · _틀.md · compare_estx 의 나라장터 자리 정리. - 끝 검사: check_master 틀 0 · 로직 0 · 일괄 시험 계산 통과 988 · 멈춤 363(앞 989 · 362 — 아스팔트싱글 한 줄) · pytest 67 통과 · typecheck 깨끗. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JgUhN55Z3BCYhUJTjwTNfj
This commit is contained in:
@@ -172,61 +172,23 @@ def bare_spec(name, spec) -> str:
|
||||
return "".join(ch for ch in s if ch not in "-()[]")
|
||||
|
||||
|
||||
def spec_match(nara_spec: str, estx_spec: str) -> bool:
|
||||
"""규격 같음 — 같거나, ESTX 규격(3자 이상)이 나라장터 규격 끝과 같음(앞 수식어 「아연도」 등)."""
|
||||
return nara_spec == estx_spec or (len(estx_spec) >= 3 and nara_spec.endswith(estx_spec))
|
||||
def spec_match(one: str, estx_spec: str) -> bool:
|
||||
"""규격 같음 — 같거나, ESTX 규격(3자 이상)이 상대 규격 끝과 같음(앞 수식어 「아연도」 등)."""
|
||||
return one == estx_spec or (len(estx_spec) >= 3 and one.endswith(estx_spec))
|
||||
|
||||
|
||||
def material_pairs(estx: Estx, nara: list[dict]):
|
||||
by_name = {}
|
||||
def estx_names(estx: Estx) -> dict[str, list[dict]]:
|
||||
by_name: dict[str, list[dict]] = {}
|
||||
for r in estx.table("StuffcDat"):
|
||||
if r.get("Name") and r.get("TC"):
|
||||
by_name.setdefault(base_name(r["Name"]), []).append(r)
|
||||
pairs = []
|
||||
for n in nara:
|
||||
cands = by_name.get(base_name(n["이름"])) if n.get("값") else None
|
||||
if not cands:
|
||||
continue
|
||||
s = bare_spec(n["이름"], n["규격"])
|
||||
hit = next((e for e in cands if spec_match(s, bare_spec(e["Name"], e.get("Size")))), None)
|
||||
if hit:
|
||||
pairs.append((n, hit))
|
||||
return by_name, pairs
|
||||
return by_name
|
||||
|
||||
|
||||
def material(estx: Estx, files: dict):
|
||||
nara = files["재료_나라장터자재.json"]["줄"]
|
||||
by_name, pairs = material_pairs(estx, nara)
|
||||
by_name = estx_names(estx)
|
||||
rows = sum(by_name.values(), [])
|
||||
names = {base_name(n["이름"]) for n in nara}
|
||||
print(
|
||||
f"## 자재 — 나라장터 {len(nara)}(품명 {len(names)}) · ESTX {len(rows)} · 품명 같음 {len(names & set(by_name))} · 품명·규격 짝 {len(pairs)}"
|
||||
)
|
||||
print(" TC 대 나라장터:", spread([rate(n["값"], e["TC"]) for n, e in pairs]))
|
||||
for i, slot in enumerate(SLOTS, 1):
|
||||
got = [rate(n["값"], e[f"Cost{i}"]) for n, e in pairs if e.get(f"Cost{i}")]
|
||||
print(f" 슬롯{i} {slot}:", spread(got))
|
||||
closest = {}
|
||||
for n, e in pairs:
|
||||
got = {
|
||||
s: abs(rate(n["값"], e[f"Cost{i}"]))
|
||||
for i, s in enumerate(SLOTS, 1)
|
||||
if e.get(f"Cost{i}")
|
||||
}
|
||||
best = min(got, key=got.get)
|
||||
closest[best] = closest.get(best, 0) + 1
|
||||
print(" 가장 가까운 슬롯:", closest)
|
||||
for n, e in pairs[:8]:
|
||||
print(
|
||||
" 예",
|
||||
n["이름"],
|
||||
"|",
|
||||
n["규격"],
|
||||
n["값"],
|
||||
"→",
|
||||
e.get("TC"),
|
||||
{s: e.get(f"Cost{i}") for i, s in enumerate(SLOTS, 1) if e.get(f"Cost{i}")},
|
||||
)
|
||||
print(f"## 자재 — ESTX 품목 {len(rows)}(품명 {len(by_name)}) · 품셈재료 미연결 후보")
|
||||
have, near, none = [], [], []
|
||||
for r in files["재료_품셈재료.json"]["줄"]:
|
||||
if r.get("연결"):
|
||||
|
||||
Reference in New Issue
Block a user