Files
Aislo/resources/tester/test_b09_table_reading.py
T
eomsangdonandClaude Opus 5 6905cd1eb5 fix(axis): 표 읽기 2차 — 절 이름 밑수 · 조합 기종 앞머리 · 합판거푸집 막힘 사유
- 마스터 생성기: 밑수가 절 이름에만 있는 표를 이름 전체가 「수+단위+당」일 때만 읽음 —
  4-2-1 「100본당」·4-2-2 「1,000㎡당」 두 표만 바뀜(재생성 diff 2표 · basis_missing 140→138)
- 뭉친 줄 조합 기종: 앞머리를 공백 지우고 견줌 — 「굴착기+부착용집게」가 카탈로그 「부착용 집게」에 붙어
  단목베기 4-2-2 가 섬(X-0201-0020#조합 + 부착용 집게)
- 실무 대조: 단목베기 5m 미만 866원/㎡ ↔ 영월 설계내역 「잡관목제거 벌목(5m미만)」 882원/㎡(노임 연도 차 2%)
- 합판거푸집 12-4: 사용횟수별 비율 미구현이라 일부러 안 풂 — 막힌 사유를 그 까닭으로 갈아 끼움(판정)
- 일위대가 HEAD↔수정 대조: 바뀐 공종은 FP-04-02-02 하나 · 전체 시험 1522 통과

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BW6Jdsh18WPtYUR6THZJqn
2026-09-13 18:05:02 +09:00

108 lines
4.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""표 읽기 (2026-09-13 축 C 1장 · 브레인 차례 ②).
지키는 것
① 밑수가 **절 이름에만** 있는 표는 이름 전체가 「수+단위+당」일 때만 뽑는다(4-2-2 「1,000㎡당」)
② 뭉친 줄: 「굴 삭 기 (무한궤도)」 표기 맞추기 · 비고 줄 거름 · 「-」 칸은 그 갈래에 품 없음
③ 조합 기종 「굴착기+부착용집게」는 공백이 달라도 카탈로그 「부착용 집게」에 붙는다
④ 형식을 안 적은 「굴 삭 기」는 잠정 우선순위로 고르지 않는다(판정 Ⓒ)
⑤ 실무값 대조 — 단목베기 5m 미만이 영월 설계내역 「잡관목제거 벌목(5m미만)」 882원/㎡ 근처로 선다
"""
from __future__ import annotations
from decimal import Decimal
from B08_Quantity.B08_Quantity_Build_WorkItemMaster import basis_from_name
from B09_Estimation.B09_Estimation_ResourceAxis import (
AxisResult,
CatalogEntry,
ResourceCatalog,
match_table,
)
def test_절_이름_밑수는_이름_전체가_밑수일_때만():
assert basis_from_name("1,000㎡당") == (1000.0, "㎡")
assert basis_from_name("100본당") == (100.0, "본")
assert basis_from_name("나무주사(100본당)") == (None, None)
assert basis_from_name("자재의 1회당 표준 운반량") == (None, None)
def _packed(*rows: list[str]) -> dict:
return {
"pum_table_id": "T-시험",
"pum_form": "requirement",
"basis_quantity": 10.0,
"basis_unit": "㎡",
"raw_row": [list(row) for row in rows],
}
MACHINES = [
CatalogEntry("0201-0080", "굴착기(무한궤도)", "machine", "0.8"),
CatalogEntry("0211-0080", "굴착기(타이어)", "machine", "0.8"),
CatalogEntry("0201-0020", "굴착기(무한궤도)", "machine", "0.2"),
CatalogEntry("7206-0020", "부착용 집게", "machine", "0.2"),
CatalogEntry("7206-0100", "부착용 집게", "machine", "1.0"),
CatalogEntry("1002", "보통인부", "labor"),
CatalogEntry("1037", "벌목부", "labor"),
CatalogEntry("1003", "특별인부", "labor"),
]
def _codes(result: AxisResult, variant: str) -> dict[str, Decimal]:
return {r.resource_code: r.amount for r in result.rows if r.variant == variant}
def test_뭉친_줄_굴삭기_표기를_맞추고_비고는_거른다():
table = _packed(
["직경 40㎝이상 60㎝미만", "직경 60㎝이상 80㎝미만"],
["보통인부", "", "인", "1.04(1.17)", "1.08(1.22)"],
["굴 삭 기 (무한궤도)", "0.8㎥", "h", "3.84", "3.52"],
["비고", "- 본 품의 집재거리는 100m까지를 기준하며 매 100m 증가마다 30%씩 가산한다."],
)
result = AxisResult()
match_table({"work_item_code": "FP-13-06-01"}, table, ResourceCatalog(entries=MACHINES), result)
first = _codes(result, "직경 40㎝이상 60㎝미만")
assert first["0201-0080"] == Decimal("0.384") # 무한궤도 — 이름에 형식이 적혀 있음
assert "0211-0080" not in first
assert "FP-13-06-01" not in result.partial_items # 비고 줄로 막히지 않음
def test_조합_기종은_공백이_달라도_붙는다():
table = _packed(
["5m 미만", "5m이상~8m미만"],
["벌목부 보통인부", "", "인 인", "2.14 0.51", "2.80 0.66"],
["굴착기+부착용집게", "0.2㎥", "hr", "2.71", "3.54"],
)
result = AxisResult()
match_table({"work_item_code": "FP-04-02-02"}, table, ResourceCatalog(entries=MACHINES), result)
assert set(_codes(result, "5m 미만")) >= {"0201-0020", "7206-0020"}
assert "FP-04-02-02" not in result.partial_items
def test_형식_없는_굴삭기와_빈칸_표시():
table = _packed(
["식생매트설치", "복 토"],
["특 별 인 부", "", "인", "0.014", "-"],
["굴 삭 기", "0.6 ㎥", "시간", "-", "0.031"],
)
result = AxisResult()
match_table({"work_item_code": "FP-13-13-02"}, table, ResourceCatalog(entries=MACHINES), result)
# 「-」 — 복토 갈래에는 특별인부가 안 든다(자리만 지킴)
assert _codes(result, "식생매트설치") == {"1003": Decimal("0.0014")}
# 형식이 없는 굴삭기는 무한궤도·타이어 중 고르지 않는다 → 막고 사유를 남긴다
assert "굴 삭 기" in result.partial_items.get("FP-13-13-02", "")
def test_단목베기_5m_미만이_실무값_근처로_선다():
from B09_Estimation.B09_Estimation_UnitPrice import build_unit_prices
build = build_unit_prices()
assert "FP-04-02-02" not in build.partial_ratio
# 합판거푸집 — 일부러 안 푼 표는 **그 까닭**이 사유로 뜬다(사용횟수 비율 미구현)
assert "사용횟수" in (build.component_gaps.get("FP-12-04") or "")
total = build.book.resolve("B-FP-04-02-02#5m미만").total
# 영월 설계내역 1.9.2 「잡관목제거 벌목(5m미만)」 @882 — 노임 연도 차이로 ±5 % 안이면 같은 읽기
assert Decimal("838") <= total <= Decimal("926"), total