feat(785-5): 만들기 · 길 — 확인한 고른 것 → SC · SK · 장부 · 새 M02_Hopyo_Router · 판정 · 검산 · 옮기기

- 새 M02_Hopyo_Router — 옛 hopyo 길 모두 M02_Labor_Router 에서 옮김(옛 화면 785-7 까지 돎) · 새 길 hopyo-judge 목록 · 호표 · 블록 · hopyo/{키}/check · hopyo/{키}/move · main 등록 · 시동 warm · Fit.ensure 걷음 · 올림 때 엑셀 사전(Row.lexicon) · 블록 풀이 뒤 셈 · 끝내기 때 저장본 지움
- 새 M02_Hopyo_Judge — 1차 줄 판(Row) + 단산 줄 2차 풀이(Clause → Solve) · 엑셀 칸(이름 · 규격 · 단위 · 단가) · 블록 금액 · 절 몫 · 블록 풀이 파생 저장본(HP 폴더 _derived · 입력 지문 · 지문 다를 때만) · judged(folder, key) · 검산(입력값 = 엔진이 쓴 칸 모두 · 지역 · 자재지역 · 조종원직종 비움 · 맡은 절 단위 줄 · 몫과 품 대조 · 금액 = 일위대가 로직 줄과 같은 셈)
- 새 M02_Hopyo_Make — 고른 것 → SC 줄(같은 별칭 · 줄 본뜬 {호표, 차례, 행} · 수량 = 엑셀 × 몫 × 배 · 같은 기초 둘째 = 한 줄 SC 사본 · 별도계상 자재 · 이음 · 율 · 고정 · 참조) · SK 더한줄(바탕 없음 · SkUnit.adds · Sangeun.Maker.write) · 하위 먼저 · 입력 필요 · 단위 환산 못 정함 = 그 줄(블록)만 막힘 · 장부 고른 것 꼴 짝 · 이미 옮긴 것 = 덮음 없으면 409(남의 SC 덮지 않음) · 확인한 줄 몸(Lines) = Build 에서 옮김
- Build 나눔 — 모두 고정 길 · Builder · _order · _origins · build_all 그대로(B09 빌림) · 확인한 줄 몸 → Make.Lines
- SkUnit · Sangeun — SkPatch · Fit · Basis 부름 걷음(기계경비 기초 차례 SkUnit 으로 · 근거 꼬리표 = Clause.basis · 맞춤 셈 409 없앰 · 재료 고름 MO 됨) · Kids 가 _same_mark 가짐
- 시험 새 test_642_5_make(판정 · 검산 · 옮기기 · 예시 1 · 2 · 3 · 덮음 409 · 막는 길) · test_m02_hopyo_excel 마당에 새 Router 더함 · HOPYO_MAX_BYTES 자리(길 옮긴 까닭)
- 낡은 시험 고침: test_718_1 · test_729 「맞춤 셈 전 409」 뺌(맞춤 뒤 셈 안 기다림) · test_628 맞춤셈 캐시 넣기 뺌(근거 = 조항 색인) · test_729 근거 없음 꼴 · 고정 이음 유가 칸(785-3 LINKS 늘어난 까닭)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-11-04 23:13:53 +09:00
co-authored by Claude Opus 5.5
parent b2c2bb7ad3
commit a22af84b62
14 changed files with 1630 additions and 556 deletions
+16 -73
View File
@@ -33,6 +33,8 @@
`{까닭, 남은줄}`(저장 안 함 · `save` 거짓 = 막지 않고 `남은줄` 만) · 미리 보기 = `unlinked`(쓰기 없음).
수량(742-1 · 요구 584-1) = 엑셀 수량을 줄 · 자재 저장 수량(`{손}`)으로 · 같은 값 `본뜬.실무수량 {줄: {차례: 수},
자재: {코드: 수}}`(출처 기록 · 엑셀 대조 `M02_Hopyo_Compare` — 하위 호표 것까지 `excel_given`).
785-5 — 확인한 줄 몸 = `M02_Hopyo_Make.Lines`(옛 대상 꼴 `put` · 새 고른 것 꼴 `picks` = 몸 `{차례: {고른}}`) ·
여기는 모두 고정 길 · 줄 차례 · 쓰기(`Builder` · `_order` · `_origins` · `build_all` = B09 빌림).
"""
from __future__ import annotations
@@ -234,82 +236,17 @@ class Builder:
self, checked: dict[int, dict[str, Any]], whole: list[dict[str, Any]], save: bool = True
) -> dict:
"""`save` 거짓 = 사전조합 안 씀 · `{문서, 빠진줄, 줄수}`(704-4 [구조물 조합으로])."""
from M02_MasterTemplete import M02_Hopyo_Make as hmake # 확인한 줄 몸(785-5)
stamp = utc_now_text()
hopyo, file = self.hopyo, self.doc.get("파일") or ""
lines, mats, missing, used, mat_lines = [], {}, [], set(), {}
nation: dict[tuple, dict[str, Any]] = {}
taken, linker, poomsem, kids, kid_n = set(), hfix.Linker(self.strict and save), [], set(), 0
left: list[dict[str, Any]] = []
where = {"파일": file, "호표": self.no}
rows = hopyo.get("줄") or []
def put(line: dict[str, Any], one: dict[str, Any], alias: str | None) -> None:
if "이음" in one:
others = [x for x in rows if x is not line]
lines.append(hfix.line_of(line, others, where, taken, linker, one["이음"]))
return
qty = Decimal(str(line.get("수량") or 0)) * Decimal(str(one["배"]))
memo = _memo(line, one)
if "전국" in one:
at = (one["이름"], one["규격"], one["단위"])
have = nation.get(at)
hand = qty + Decimal(str(have["수량"]["손"])) if have else qty
head = {"이름": at[0], "규격": at[1], "단위": at[2], "수량": {"손": _num(hand)}}
nation[at] = {**head, **(hmat.marks(line, at[0]) if not have else {
k: have[k] for k in labor.MARKS if k in have
})} # fmt: skip
missing.append(_missing(line, NATIONAL))
return
if "자재" in one:
have = mats.get(one["자재"])
hand = qty + Decimal(str(have["수량"]["손"])) if have else qty
name = self.mat_names.get(one["자재"], "")
mats[one["자재"]] = {
"코드": one["자재"],
"수량": {"손": _num(hand)},
**(
have
and {k: have[k] for k in labor.MARKS if k in have}
or hmat.marks(line, name)
),
}
if not have:
mat_lines[one["자재"]] = line
return
if "호표" in one:
kids.add(one["호표"])
ref = {
"층": refs.here()[0],
"주인": refs.here()[1],
"키": self.done.get(mark(self.key, one["호표"]), "SC-미리"),
}
lines.append({"참조": ref, "별칭": alias, "메모": memo, "수량": {"손": _num(qty)}})
return
row = {"로직": one["로직"], "입력값": one["입력값"], "메모": memo}
kept, why = sklink.kept(self, line, one, qty, alias, memo)
if why:
left.append(sklink.left(line, why))
if kept is not None:
lines.append(kept)
return
if one["로직"] not in used:
used.add(one["로직"])
lines.append({**row, "별칭": alias, "수량": {"손": _num(qty)}})
return
at = int(line.get("차례", 0))
wrap = { # 같은 로직 둘째 — 한 줄 사전조합으로 감쌈
"이름": f"{hopyo['이름']} — {line.get('이름')}",
"단위": line.get("단위") or None,
"구분": ORIGIN,
"상세구분": file,
"담은로직": [{**row, "별칭": alias, "수량": {"손": 1}}],
"자재": [],
"본뜬": self._origin(f"{mark(self.key, self.no, at)} {one['로직']}", stamp),
}
ref = (
{"키": "SC-미리"} if self.dry else hkids.save(wrap, self.same)[0]
) # 미리 보기 = 쓰기 없음
lines.append({"참조": ref, "별칭": alias, "메모": memo, "수량": {"손": _num(qty)}})
where = {"파일": file, "호표": self.no}
body = hmake.Lines(self, rows, where, stamp, hfix.Linker(self.strict and save))
lines, mats, missing, left = body.lines, body.mats, body.missing, body.left
taken, linker, kids, put = body.taken, body.linker, body.kids, body.put
nation, mat_lines = body.nation, body.mat_lines
poomsem, kid_n = [], 0
book: dict[str, dict[str, Any]] = {}
if whole:
@@ -318,6 +255,12 @@ class Builder:
book[ledger.hopyo_key(hopyo)] = self._row(hopyo, "짝", whole)
for at, line in enumerate(rows):
got = checked.get(at)
if got and "고른" in got: # 새 길 고른 것(785-5 · Make 가 검사 · 다시 셈)
poomsem.append(at)
body.picks(at, line, got["고른"])
pairs = [hmake.ledger_pick(p) for p in got["고른"]]
book[ledger.key(line)] = self._row(line, "짝", pairs)
continue
if whole:
missing.append(_missing(line, WHOLE))
continue