feat(791-1): 엔진 셈 의미 넓힘 — 금액번지 · 소계 단계 · 제외 · 줄 자리 · 블록 끝전 · 결과 조정 · 변수 표시

- 새 모듈 master_formula_sum.py — 덧줄 고리(master_formula.run 에서 옮김) · 번지 · 단계 · 합밖 · 조정 · 표시 · 검사
- master_cut.py — 줄 자리 {방법, 자리} · 블록 끝전(비목버림 | 큰나머지) · 결과 조정 · 답 단계 목록
- master_formula_check.py — 새 칸 검사(없는 번지 · 단계 순서 · 자리 범위 · 끝전 · 조정)
- _틀.md 7장 「셈 의미 넓힘」 · 8장 덧줄 이름
- 지킴 시험 test_791_1 — M01 로직 1,515 지문 전후 같음 · 새 의미 단위 · 실무 견본 넷(봉화 D00102 · 울진소광 D01489 · 동부청영월 D00003 · 북부청임도 18) = 엑셀
- master_formula.py 690 → 669 줄

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-11-05 17:03:36 +09:00
co-authored by Claude Opus 5.5
parent 17b6ee5460
commit c05139a971
7 changed files with 2352 additions and 38 deletions
@@ -570,7 +570,8 @@ def run(master: Master, ref: str, given: dict, depth: int = 0) -> dict:
env = _inputs(row, given, master)
for step in row.get("중간", []):
try:
env[step["이름"]] = evaluate(parse(step["식"]), env, master, depth)
value = evaluate(parse(step["식"]), env, master, depth)
env[step["이름"]] = ms.shown(step, value) # `표시` 자리 반올림(791-1)
except EmptyInput as e: # 못 구한 중간값 — 쓰는 줄만 비움
env[step["이름"]] = Blank(str(e))
if "결과" in row:
@@ -632,34 +633,11 @@ def run(master: Master, ref: str, given: dict, depth: int = 0) -> dict:
**(extra or {}),
}
)
# 덧줄이 호표 줄 금액 하나를 빼고 더할 수 있게 — `줄.'호표 줄 이름'`(빈 줄은 뺌)
env["줄"] = {x["이름"]: x["금액"] for x in lines if x["이름"] and x["금액"] is not None}
blank = {x["이름"]: x["까닭"] for x in lines if x.get("까닭")}
for extra in row.get("덧줄", []):
env.update(sums)
try: # 덧줄도 값 빈 품목·빈 줄을 부르면 그 줄만 비움
value, why = evaluate(parse(extra["식"]), env, master, depth), None
env[extra["이름"]] = value
except FormulaError as e:
gone = next((n for n in blank if n in extra["식"]), None)
value, why = None, f"「{gone}」 줄 비어 못 셈 — {blank[gone]}" if gone else str(e)
blank[extra["이름"]] = why
sums[extra["비목"]] += value or 0
lines.append(
{
"이름": extra["이름"],
"단위": "식",
"수량": Decimal(1),
"단가": value,
"금액": value,
"비목": {extra["비목"]: value},
**({"까닭": why} if why else {}),
}
)
sums = {k: cut(row, v, "계") for k, v in sums.items()} # 비목 합마다 끊고 계는 그 합
# 덧줄 · 비목 합 끊기 · 번지 · 단계 · 조정(791-1) = `master_formula_sum.extras`
sums, more = ms.extras(master, row, lines, env, sums, depth)
mb.tag(master, row, lines, env) # 줄마다 인력 · 재료 · 경비 · 하위 묶음(712-1)
mg.tag(master, row, lines, env) # 옵션으로 빠진 줄 `옵션꺼짐`(753-1)
return {"줄": lines, **sums, "계": sum(sums.values()), "중간": _shown(env)}
return {"줄": lines, **sums, "계": sum(sums.values()), "중간": _shown(env), **more}
# 품셈재료 단가 — 서로 부르는 모듈이라 끝에서 읽음
@@ -680,6 +658,7 @@ from master_material import ( # noqa: E402, F401
import master_pick as mp # noqa: E402 — 검색어 · 고름 · 단위
import master_bundle as mb # noqa: E402 — 인력 · 재료 · 경비 묶음
import master_gate as mg # noqa: E402 — 옵션으로 빠진 줄
import master_formula_sum as ms # noqa: E402 — 덧줄 · 번지 · 단계 · 조정 · 표시(791-1)
from master_formula_check import ( # noqa: E402, F401 — 검사는 나눈 파일 · 이름은 여기서 그대로
_check_cut,
_check_node,