fix(m01): 빈 줄 값 조각 None · 만약 갈래 괄호 · 로직 조각 이름 (PLAN 6장 둘째 줄)

- 덧줄이 부른 빈 호표 줄 값 조각 글 None → 그 줄 이름
- 만약() 이 고른 갈래가 덧셈이면 곱셈 안에서 괄호로 묶음(× (1 + 60 %))
- 식 안 로직 부르기 조각 글 = 그 로직 이름(별칭 아님)
- GF000185 · GC000376 · GC000111 자동값 + 고르기 후보 66번 점검: 날글 · 산수 어긋남 0

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V1MKKZKpUHTPKb513FneU8
This commit is contained in:
2026-09-24 14:53:20 +09:00
co-authored by Claude Sonnet 5
parent 5e9df81cbd
commit 760c5233b6
2 changed files with 41 additions and 0 deletions
@@ -172,8 +172,20 @@ def _bin(show, real, env: dict, master, depth: int, draw) -> str:
)
def _shown(show, real, env: dict, master, depth: int):
"""만약() 은 걸린 갈래만 글이 됨 — 괄호를 정할 때는 그 갈래의 마디로 봄(못 가리면 그대로)."""
while show[0] == "call" and show[1] == "만약":
try:
at = 1 if mf.evaluate(real[2][0], env, master, depth) else 2
except _CALC_ERRORS:
break
show, real = show[2][at], real[2][at]
return show
def _side(show, real, parent, env: dict, master, depth: int, draw, right: bool) -> str:
text = draw(show, real, env, master, depth)
show = _shown(show, real, env, master, depth)
if show[0] != "bin":
return text
mine, up = _PREC[show[1]], _PREC[parent[1]]
@@ -248,6 +260,7 @@ def _alias_piece(mark: dict, env: dict, master, column: str | None) -> dict:
at = next(i for i, one in enumerate(table["줄"]) if one is row) # find 가 고른 줄
piece["참조"] = {"테이블": ref[:2], "키": ref, "행": conds, "열": column, "줄": at}
else:
piece["글"] = str(master.logic(ref).get("이름") or ref) # 요소조각처럼 로직 이름
piece["참조"] = {"테이블": ref[:2], "키": ref}
except _CALC_ERRORS:
pass # 다시 못 찾음 — 별칭 이름만 남김(값 자리 비움)
@@ -340,8 +353,12 @@ def _pieces(show, real, env: dict, master, alias_by_name: dict, ifdepth: int = 0
if kind == "name" and show[1] in alias_by_name:
return [_alias_piece(alias_by_name[show[1]], env, master, None)]
piece = _p_val(show[1] if kind == "name" else "") # 중간 값은 글에 그 이름
if kind == "field" and show[1] == ("name", "줄"): # 덧줄이 부른 호표 줄 — 비면 그 줄 이름
piece["글"] = show[2]
try:
value = _value(real, env, master, 0)
if value == "None": # 값이 빈 줄 — 「None」 을 글로 안 찍음
raise mf.FormulaError("값 없음")
piece.update({"값": value} if kind == "name" else {"글": value})
except _CALC_ERRORS:
pass # 값 계산 자체가 막힘 — 이름만(그 밖은 빈 글) 남겨 줄이 안 죽게
+24
View File
@@ -485,3 +485,27 @@ def test_값_식_작은_수는_유효숫자로_보인_수끼리_곱해도_금액
assert first == "273,308 * 0.001667 = 456"
assert mt.fmt(Decimal("0.00166667")) == "0.001667" and mt.fmt(Decimal("12.34567")) == "12.3457"
assert mt.fmt_price(Decimal("3.5")) == "3.5" and mt.fmt_price(Decimal("3500.4")) == "3,500"
def _text_of(key: str, **given) -> list[dict]:
auto = {k: v for k, v in (store.auto(key).get("값") or {}).items() if v is not None}
return _all_lines(store.text(key, {**auto, **given}))
def test_빈_줄을_부른_덧줄_값_조각은_None_대신_그_줄_이름() -> None:
line = next(x for x in _text_of("GF000185") if x["이름"] == "콘크리트다짐")
texts = [p["글"] for p in line["조각"]]
assert "None" not in texts and "구체콘크리트(철근) 레미콘" in texts
def test_만약이_고른_갈래가_덧셈이면_곱셈_안에서_괄호로_묶임() -> None:
line = next(x for x in _text_of("GC000376", 면="BOX 형상 내면") if x["이름"] == "도장공")
assert line["글"] == "263,017 * 0.031 * (1 + 60 %) = 13,046"
outer = next(x for x in _text_of("GC000376", 면="외면") if x["이름"] == "도장공")
assert "(" not in outer["글"]
def test_수량_식_안_로직_조각은_그_로직_이름() -> None:
line = next(x for x in _text_of("GC000111") if x["이름"] == "리퍼 기계경비")
pill = next(p for p in line["조각"] if p["kind"] == "로직")
assert pill["글"] == "굴착기(무한궤도) 시간당 기계경비" and pill["참조"]["키"] == "GC000267"