fix(m02-df): 36-2 변환 대조 96.7% — 표 찾기 위 끝 최소 · 값 칸 범위 갈림 · 로직.계 · 조건 찾기 원문번호
- convert(row, ctx={key, file, master}) — sub4 /api/m01/logic/flow 부르는 꼴 · master 는 ctx 것
- {입력} 요소 찾는 값 = 원문번호(「MO:경유:{지역}」 → "경유:"&지역 글 잇는 함수) · 호표 줄 그룹 = 키 앞 두 글자
- 로직(…).계 = 다른 로직 비목 셋 합
- 표 찾기: 여럿이면 범위 위 끝이 가장 작은 줄(옛 find) · 값 칸이 「·아래」 「·위」 로 갈리면 아래 = 위일 때 그 값(Rule · Compute 같음)
- 표 찾기 실패로 넣은 NA() 칸은 칸 계산 오류로 알리지 않음(Eval · Compute)
- 전수 대조는 서버 길 그대로(sub4 조건 찾기 · 표 식 글) · 입력은 옛 엔진처럼 수로 · 까닭 분류
- 시험입력 1,423/1,472(96.7%) · 기본 입력 1,434/1,472(97.4%)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VBToTCGk5dqDKeXCEP3vhk
This commit is contained in:
@@ -139,14 +139,15 @@ class _Flow:
|
||||
if len(texts) > 1:
|
||||
raise Unsupported(f"자리 표시가 여러 칸에 낀 요소 「{ref}」")
|
||||
((at, text),) = texts.items()
|
||||
holes = list(dict.fromkeys(_HOLE.findall(text)))
|
||||
if len(holes) == 1:
|
||||
src, hole = self.hole(holes[0]), holes[0]
|
||||
else: # 「레미콘 {a}-{b}-{c}」 — 함수 상자가 글을 이음
|
||||
src = self.func(f"{label} 찾는 말", ("@text", text))
|
||||
hole = src["name"]
|
||||
text = "{" + hole + "}"
|
||||
tpl = text if at is None else json.dumps(plain(ref | {at: text}), ensure_ascii=False)
|
||||
# 찾는 값 = 원문번호(「EQ:{기계}」 → 기계 · 「MO:경유:{지역}」 → "경유:"&지역)
|
||||
want = text.partition(":")[2] if at is None and ":" in text else text
|
||||
if _HOLE.fullmatch(want):
|
||||
src = self.hole(want[1:-1])
|
||||
else:
|
||||
src = self.func(f"{label} 찾는 말", ("@text", want))
|
||||
if at is not None:
|
||||
self.notes.append(f"재료 검색어에 입력이 낌 「{text}」 — 조건 찾기(키 같음)로 옮김")
|
||||
tpl = text if at is None else json.dumps(plain(ref), ensure_ascii=False)
|
||||
tpl += f"#{field}" if field else ""
|
||||
rule = {"field": "키", "op": "같음", "from": src}
|
||||
return ("@port", self.element(group, tpl, unit, f"{label} 자리", rule))
|
||||
@@ -295,6 +296,9 @@ class _Flow:
|
||||
group = GROUP_OF.get(base[1][:2], "기계")
|
||||
node2 = self.priced(group, base[1], "", f"{base[1]} {col}", col)
|
||||
return self.excel(node2, take, scope)
|
||||
if base[0] == "logic" and col == "계": # 다른 로직 출력은 비목 셋 — 계 = 그 합
|
||||
bid = self.logic(base)
|
||||
return self.excel(("@sum", [{"box": bid, "name": k} for k in COSTS]), take, scope)
|
||||
if base[0] == "logic":
|
||||
return take({"box": self.logic(base), "name": col}, f"{base[1]} {col}")
|
||||
if base[0] == "name" and base[1] == "줄" and f"줄.{col}" in scope:
|
||||
@@ -356,7 +360,9 @@ def _body(f: _Flow, row: dict) -> None:
|
||||
lines.setdefault(f"줄.{name}", []).append(part)
|
||||
continue
|
||||
unit = str(item.get("단위") or "")
|
||||
price = f.priced(str(item.get("종류")), item["요소"], unit, f"{name} 단가")
|
||||
ref = item["요소"] # 그룹 = 키 앞 두 글자(「MO:경유:{지역}」 = 유가전력) · 없으면 줄 종류
|
||||
group = GROUP_OF.get(ref[:2], str(item.get("종류"))) if isinstance(ref, str) else "재료"
|
||||
price = f.priced(group, ref, unit, f"{name} 단가")
|
||||
part = f.func(f"{name} 금액", ("bin", "*", qty, price))
|
||||
parts[item["비목"]].append(part)
|
||||
lines.setdefault(f"줄.{name}", []).append(part)
|
||||
|
||||
Reference in New Issue
Block a user