fix(axis): 표 읽기 1차 — 뭉친 줄 표기 맞추기·비고 거름·「-」 칸 · 지장목제거를 품셈에 이음
- 뭉친 줄 해석기: 「굴 삭 기 (무한궤도)」를 굴착기(무한궤도)로 맞춰 큰돌쌓기 메쌓기(13-6-1)· 13-7-2 장비 몫이 붙음(형식을 적은 이름만 · 형식 없는 굴삭기는 판정 Ⓒ대로 규격 미정) - 비고·합계 줄을 자원으로 안 읽음(단목베기 4-2-2 가짜 막힘 제거) · 「-」 칸은 그 갈래에 품 없음 (산림복원용 흙막이 13-13-2 가 특별인부·굴삭기 빠진 채 조용히 서던 것을 사유와 함께 막음) - 지장목제거(판정 Ⓑ): 잡관목제거 → FP-04-02-02 #5m미만 · 뿌리뽑기 → FP-09-21 + 임목축적 등급 갈래 · 준비공 「제근·뿌리다듬기」는 같은 면적이라 참조로만(이중계상 막이) · 미결 목록에서 뺌 - 기계 이름 별칭(백호·굴삭기→굴착기)은 별칭표 대상이 아닌 카탈로그 이름 정규화로 주석 정리 - 일위대가 전후 대조(HEAD↔수정): 새로 선 공종 13-6-1·13-7-2 · 새로 막힌 공종 13-13-2(사유 있음) · 내역 금액: 단목베기·제근은 밑수 미확보로 계속 막혀 변화 없음 · 전체 시험 1513 통과 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BW6Jdsh18WPtYUR6THZJqn
This commit is contained in:
@@ -29,7 +29,10 @@ from B09_Estimation.B09_Estimation_ResourceAxis import (
|
||||
ResourceCatalog,
|
||||
ResourceRow,
|
||||
UnmatchedRow,
|
||||
_tidy_resource_name,
|
||||
is_non_resource_label,
|
||||
parse_amount,
|
||||
parse_machine_cell,
|
||||
split_name_and_spec,
|
||||
)
|
||||
|
||||
@@ -210,6 +213,8 @@ _RE_PACKED_NUMBER = re.compile(r"\d+(?:\.\d+)?")
|
||||
#: 「1.04(1.17)」의 괄호 값 — **조건 시공 시 대안값**이라 기본 수에 안 센다
|
||||
#: (품셈 13-6-1 [주]②). 안 떼면 값이 하나 더 있는 것으로 보여 표가 통째로 버려진다.
|
||||
_RE_ALTERNATIVE_TAIL = re.compile(r"(?<=\d)\s*[((]\s*\d+(?:\.\d+)?\s*[))]")
|
||||
#: 「그 갈래엔 없음」 표시 칸.
|
||||
_ABSENT_MARKS = frozenset({"-", "–", "·", "ㆍ", "-"})
|
||||
|
||||
|
||||
def _packed_numbers(cell: str) -> list:
|
||||
@@ -235,11 +240,26 @@ def _resolve_packed(catalog: ResourceCatalog, name: str, specs: list[str] | None
|
||||
parts = [part.strip() for part in str(name).split("+") if part.strip()]
|
||||
found = []
|
||||
for part in parts:
|
||||
# ⚠ 행 읽기 길과 **같은 표기 맞추기**를 먼저 한다 — 이 길만 「굴 삭 기 (무한궤도)」를
|
||||
# 「굴착기(무한궤도)」로 못 바꿔 큰돌쌓기 메쌓기(13-6-1) 장비 몫이 막혀 있었다(09-13).
|
||||
# ⚠ **기종 이름이 실제로 바뀌고 형식(괄호)을 적었을 때만** 쓴다 — 공백만 지우면
|
||||
# 「부착용 집게」가 카탈로그 앞머리 비교에서 빠져 돌쌓기(장비) 넷이 막혔고(같은 날 대조로
|
||||
# 잡음), 형식 없는 「굴 삭 기」까지 바꾸면 무한궤도 **잠정** 우선순위로 새 단가가 선다
|
||||
# (판정 Ⓒ 「형식이 둘이면 규격 미정」과 어긋남).
|
||||
tidied = _tidy_resource_name(part)
|
||||
if _normalize_label(tidied) != _normalize_label(part) and "(" in tidied:
|
||||
part = tidied
|
||||
base, spec = split_name_and_spec(part)
|
||||
entry = catalog.resolve(base, spec)
|
||||
if entry is None and not spec:
|
||||
candidates = catalog.by_name(base)
|
||||
entry = candidates[0] if len(candidates) == 1 else None
|
||||
if entry is None:
|
||||
# 갈래를 이름에 품은 기종(「굴착기(무한궤도)」)은 **그 이름째** 옆 칸 규격으로 먼저 —
|
||||
# 앞머리 「굴착기」로만 보면 무한궤도·타이어가 둘 다 걸려 잠정 우선순위에 기댄다.
|
||||
machine_name, _ = parse_machine_cell(part)
|
||||
if machine_name != base:
|
||||
entry = _resolve_with_side_spec(catalog, machine_name, specs or [])
|
||||
if entry is None:
|
||||
entry = _resolve_with_side_spec(catalog, base, specs or [])
|
||||
if entry is None:
|
||||
@@ -370,6 +390,10 @@ def match_packed_rows(
|
||||
break
|
||||
continue
|
||||
|
||||
# 비고·합계 줄은 자원이 아니다 — 문장 속 수(「100m」·「30%」)를 값으로 보고 「못 풀었다」며
|
||||
# 공종을 막고 있었다(단목베기 4-2-2 「비고」, 2026-09-13). 행 읽기 길과 같은 거름을 쓴다.
|
||||
if is_non_resource_label(cells[0]):
|
||||
continue
|
||||
# 규격은 **옆 칸**에 있을 수 있다 — 「굴착기+부착용 집게 | 0.6㎥ | 시간 | …」.
|
||||
side_specs = [cell for cell in cells[1:3] if cell]
|
||||
# ⚠ **칸 전체를 한 이름으로 먼저 본다** — 「굴착기 (무한궤도)」처럼 이름 안에
|
||||
@@ -395,7 +419,12 @@ def match_packed_rows(
|
||||
)
|
||||
continue
|
||||
|
||||
groups = [_packed_numbers(cell) for cell in cells[1:]]
|
||||
# ⚠ 「-」·「·」 칸은 **그 갈래에 품이 없다**는 표시다 — 빈칸처럼 버리면 갈래 수가 모자라
|
||||
# 표째 버려진다(산림복원용 흙막이 13-13-2 「특별인부 0.014 | -」). 자리만 지키고 안 셈.
|
||||
groups = [
|
||||
_packed_numbers(cell) or ([None] * len(names) if cell in _ABSENT_MARKS else [])
|
||||
for cell in cells[1:]
|
||||
]
|
||||
groups = [group for group in groups if group]
|
||||
# 앞쪽에 규격·단위 칸이 낄 수 있다 — 「0.6㎥ | 시간 | 0.31 | 0.30 | 0.28」.
|
||||
# 갈래 수만큼 **뒤에서** 잘라 쓴다.
|
||||
@@ -417,6 +446,8 @@ def match_packed_rows(
|
||||
|
||||
for label, group in zip(labels, groups):
|
||||
for entries, amount in zip(resolved, group):
|
||||
if amount is None:
|
||||
continue # 「-」 — 그 갈래에는 이 자원이 안 든다
|
||||
value = amount
|
||||
if basis_quantity not in (None, 0, Decimal(1)):
|
||||
value = value / basis_quantity
|
||||
|
||||
Reference in New Issue
Block a user