fix(b09): 물탱크(살수차) 운전경비 되살림 — 8-4-8 셀 병합으로 줄째 버려지던 7204 다섯을 원문 값으로 · 살수차 조종원은 8-1-2 5호 화물차운전사(초류종자살포 ③)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BW6Jdsh18WPtYUR6THZJqn
This commit is contained in:
2026-09-15 04:11:25 +09:00
co-authored by Claude Opus 5
parent 3cfe3ef58a
commit 078af37d33
2 changed files with 80 additions and 1 deletions
@@ -43,11 +43,29 @@ _RE_FUEL_WITH_KIND = re.compile(r"^(휘발유|중유|경유)?(\d+(?:\.\d+)?)$")
#: 조종원 직종 — 품셈 표는 「인/일」 수만 주고 직종명을 안 준다.
#: TODO(미결 PLAN 9-6): 기종별 직종이 품셈 다른 장에 있다. 아래는 `aliases` 기반 **잠정**이며
#: 결과에 `operator_mapping_is_provisional: true` 로 드러난다.
_OPERATOR_TRUCK_WORDS = ("덤프트럭", "트럭", "트레일러", "화물")
#: 「살수차」 — 8-1-2 5호 화물차운전사 줄이 이름으로 적음(원문 또렷 · 물탱크(살수차) 7204 · 2026-09-15 ③).
_OPERATOR_TRUCK_WORDS = ("덤프트럭", "트럭", "트레일러", "화물", "살수차")
_OPERATOR_ALIAS_TRUCK = "labor_op_truck"
_OPERATOR_ALIAS_CONSTRUCTION = "labor_op_const"
#: ⚠ **셀 병합으로 줄째 버려지는 표에서 원문 값을 되살린다** (2026-09-15 초류종자살포 ③ 브레인).
#: 8-4-8 기타기계(원문 L3458)는 36기종이 한 칸에 뭉치고 자동세륜기 「-」 하나가 두 기종 몫이라 잡재료 35 ·
#: 조종원 34 개로 짝이 안 맞아 줄째 버려짐. 양끝 맞추기는 우연 일치로 틀린 값이 붙어 못 씀 → 공종이 쓰는
#: 물탱크(살수차) 다섯만 손으로(주연료 칸 · 잡재료 30 · 조종원 1 — 앞 기종 수가 칸마다 같아 자리가 또렷).
#: 버려진 줄 셋 81기종 중 공종이 쓰는 것은 이 다섯뿐(나머지는 막는 공종 0 이라 미룸).
#: 거창 실무 5,500ℓ 호표 「경유 9.3ℓ · 잡품 30% · 화물차운전사 1인」 일치. ⚠ 원천이 바로 실으면 이 표는 지운다.
MERGED_CELL_OPERATING_FIXES: dict[str, str] = {
"7204-0018": "8.2",
"7204-0038": "8.6",
"7204-0055": "9.3",
"7204-0065": "9.4",
"7204-0160": "12.9",
}
_WATER_TANK_MISC_PERCENT = Decimal(30)
_WATER_TANK_OPERATORS = Decimal(1)
class OperatingCostError(ValueError):
"""운전경비 표를 못 읽은 경우. 어긋난 채로 짝짓지 않는다."""
@@ -278,6 +296,20 @@ def load_operating_records(
aliases = _read_json(*_CATALOG_SUBPATH, labor_file)["variables"].get("aliases", {})
catalog = load_machine_catalog()
parsed = parse_operating_tables(pum, aliases, set(catalog.machines))
read = {record.machine_code for record in parsed.records}
for code, liters in MERGED_CELL_OPERATING_FIXES.items():
if code not in read:
parsed.records.append(
OperatingRecord(
machine_code=code,
machine_name="",
specification="",
fuel_liters_per_hour=Decimal(liters),
fuel_kind="경유",
misc_material_percent=_WATER_TANK_MISC_PERCENT,
operator_person_days=_WATER_TANK_OPERATORS,
)
)
return enrich_with_catalog(parsed, catalog, aliases)
@@ -0,0 +1,47 @@
"""물탱크(살수차) 운전경비 되살림 — 2026-09-15 브레인 ③ (초류종자살포 5-24 를 막던 넷 중 하나).
건설품셈 8-4-8 기타기계(원문 L3458)는 36기종이 한 칸에 뭉치고 자동세륜기 「-」 하나가 두 기종 몫(셀 병합)이라
잡재료 35 · 조종원 34 개로 짝이 안 맞아 **줄째 버려짐** → 물탱크 7204 다섯의 운전경비 레코드가 없어 기계 층이 안 섬.
양끝 맞추기는 우연 일치로 틀린 값이 붙어(자동세륜기 0010 조종원이 「1」 로 읽힘) 못 씀 → 원문 값을 손으로 되살림.
원문: 1,800 8.2 · 3,800 8.6 · 5,500 9.3 · 6,500 9.4 · 16,000 12.9 · 잡재료 30 · 조종원 1
조종원 직종 — 8-1-2 5호 「화물차운전사 … 살수차」(원문 또렷) · 거창 실무 5,500ℓ 호표도 화물차운전사 · 경유 9.3 · 잡품 30
"""
from __future__ import annotations
from decimal import Decimal
from B09_Estimation.B09_Estimation_MachineOperating import (
_CATALOG_SUBPATH,
_read_json,
load_operating_records,
)
from B09_Estimation.B09_Estimation_UnitPrice import cached_build
WATER_TANKS = {
"7204-0018": "8.2",
"7204-0038": "8.6",
"7204-0055": "9.3",
"7204-0065": "9.4",
"7204-0160": "12.9",
}
def test_물탱크_다섯은_원문_연료_잡재료_조종원으로_선다() -> None:
records = {r.machine_code: r for r in load_operating_records().records}
truck = _read_json(*_CATALOG_SUBPATH, "labor_const_2026-01-01.json")["variables"]["aliases"][
"labor_op_truck"
]
for code, liters in WATER_TANKS.items():
record = records[code]
assert record.fuel_liters_per_hour == Decimal(liters), record
assert record.fuel_kind == "경유"
assert record.misc_material_percent == Decimal(30)
assert record.operator_person_days == Decimal(1)
assert record.operator_occupation_code == truck, record # 8-1-2 5호 살수차
def test_살수차_기계_층이_서고_막힌_기계에서_빠짐() -> None:
build = cached_build()
assert "X-7204-0055" in build.book.titles
assert not any(m.startswith("7204-0055") for m in build.incomplete_machines)