- Q1 = 3600×0.7×K×f×E0/22초 · 토사 47.63 · 암절취 16.32 · 발파암 13.67 ㎥/hr - E0 는 운반 식 Es 와 다른 기호 — 토사 0.60(표 「임도」·10-12-3 [주]③) 채택 · 본문 0.75 버림(브레인 판정) - 거리 무관이라 늘 세움 · 내역은 인계 수단 표지 dump_loading 줄을 잎 #적재 로(B08 짝 줄은 다음 커밋) - 시험 1건 보탬 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BW6Jdsh18WPtYUR6THZJqn
127 lines
5.2 KiB
Python
127 lines
5.2 KiB
Python
"""덤프 운반(산림품셈 10-12 「2. 운반」) — 거리별 호표 · 원문 어긋남은 고른 값·버린 값을 사유에.
|
||
|
||
2026-09-14 축 C 1장 (브레인 판정 ①②④⑤):
|
||
① n 의 Qt = 계산값 T/γt×L (원문 표기 10 버림) ② 발파암 E 0.9 ④ Es = 운반 줄 값
|
||
⑤ 운반거리마다 갈래 · 거리 없으면 0 원 아니라 「운반거리 미입력」
|
||
손셈(토사 164.23 m): Qt 10.2632 · n 16.2907 · t1 6.3885 · t2 3.6131 · ㎝t 12.5016 · f 0.77
|
||
→ Q 34.135 → 34.14(사사오입)
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
import sys
|
||
from decimal import Decimal
|
||
from pathlib import Path
|
||
|
||
ROOT = Path(__file__).resolve().parents[2]
|
||
sys.path.insert(0, str(ROOT))
|
||
|
||
from B09_Estimation.B09_Estimation_MachineProductivity_Dump import ( # noqa: E402
|
||
DUMP_MATERIALS,
|
||
DumpHaul,
|
||
dump_child_for,
|
||
dump_distance_from_code,
|
||
dump_haul_distances,
|
||
dump_title_code,
|
||
)
|
||
from B09_Estimation.B09_Estimation_UnitPrice import cached_build # noqa: E402
|
||
|
||
DISTANCE = Decimal("164.23")
|
||
|
||
|
||
def test_토사_운반_식_손셈() -> None:
|
||
haul = DumpHaul(DUMP_MATERIALS["FP-10-12-01"], DISTANCE)
|
||
assert round(haul.truck_load_m3, 4) == Decimal("10.2632")
|
||
assert round(haul.loader_cycles, 4) == Decimal("16.2907")
|
||
assert round(haul.cycle_minutes, 4) == Decimal("12.5016")
|
||
assert (haul.volume_factor, haul.hourly_output) == (Decimal("0.77"), Decimal("34.14"))
|
||
|
||
|
||
def test_암절취는_계산값_Qt_와_운반줄_Es() -> None:
|
||
haul = DumpHaul(DUMP_MATERIALS["FP-10-12-02"], DISTANCE)
|
||
assert round(haul.truck_load_m3, 4) == Decimal("8.4375") # 원문 표기 10 이 아님
|
||
assert haul.hourly_output == Decimal("12.49")
|
||
assert any("원문 표기" in note for note in DUMP_MATERIALS["FP-10-12-02"].notes)
|
||
assert DUMP_MATERIALS["FP-10-12-03"].truck_efficiency == Decimal("0.9")
|
||
assert any("E 원문 누락" in note for note in DUMP_MATERIALS["FP-10-12-03"].notes)
|
||
|
||
|
||
def test_거리마다_호표가_서고_코드에서_거리를_되읽는다() -> None:
|
||
build = cached_build(dump_haul_m=(str(DISTANCE),))
|
||
code = dump_title_code("FP-10-12-01", DISTANCE)
|
||
assert code == "B-FP-10-12-01#L164.23m"
|
||
money = build.book.resolve(code)
|
||
assert money.total > 0
|
||
assert dump_distance_from_code(code) == ("164.23",)
|
||
assert code not in cached_build().book.titles # 거리 없는 조립엔 안 섬
|
||
|
||
|
||
def test_인계_거리와_갈래_잇기() -> None:
|
||
payload = {
|
||
"work_items": [
|
||
{
|
||
"work_item_code": "FP-10-12",
|
||
"haul_equipment": "dump_truck",
|
||
"haul_distance_m": 164.23,
|
||
},
|
||
{"work_item_code": "FP-10-12", "haul_equipment": "dump_truck", "haul_distance_m": None},
|
||
{"work_item_code": "FP-10-11", "haul_equipment": "dozer", "haul_distance_m": 32.09},
|
||
]
|
||
}
|
||
assert dump_haul_distances(payload) == ("164.23",)
|
||
assert dump_child_for("리핑암", "2026-01-01") == "FP-10-12-02" # 범위 별칭 리핑암 → 암절취
|
||
assert dump_child_for("토사", "2026-01-01") == "FP-10-12-01"
|
||
assert dump_child_for("모르는암", "2026-01-01") is None
|
||
|
||
|
||
def test_적재는_거리_무관_한_장이고_E0_는_0_60() -> None:
|
||
from B09_Estimation.B09_Estimation_MachineProductivity_Dump import (
|
||
loading_output,
|
||
loading_title_code,
|
||
)
|
||
|
||
# 토사 3600×0.7×0.9×0.77×0.60/22 = 47.628 → 47.63
|
||
# 암절취 3600×0.7×0.55×0.74×0.35/22 = 16.317 → 16.32
|
||
assert loading_output("FP-10-12-01") == Decimal("47.63")
|
||
assert loading_output("FP-10-12-02") == Decimal("16.32")
|
||
build = cached_build() # 거리 없어도 섬
|
||
code = loading_title_code("FP-10-12-01")
|
||
assert build.book.resolve(code).total > 0
|
||
basis = build.book.details[f"D-{code[2:]}"][0].note
|
||
assert "0.75 버림" in basis
|
||
|
||
|
||
def test_내역_줄_거리_없으면_운반거리_미입력() -> None:
|
||
from B09_Estimation.B09_Estimation_BillOfQuantities import build_bill
|
||
|
||
def payload(distance):
|
||
return {
|
||
"work_items": [
|
||
{
|
||
"work_item_code": "FP-10-12",
|
||
"name": "dump_truck 운반",
|
||
"spec": "토사",
|
||
"unit": "㎥",
|
||
"quantity": 40.0,
|
||
"haul_equipment": "dump_truck",
|
||
"haul_distance_m": distance,
|
||
"variant_axis": "ground_class",
|
||
"variant_value": "토사",
|
||
"in_bill": True,
|
||
"origin": "haul",
|
||
}
|
||
],
|
||
"materials": [],
|
||
}
|
||
|
||
blank = build_bill(payload(None), build=cached_build())
|
||
assert any("운반거리 미입력" in m["reason"] for m in blank.missing)
|
||
priced = build_bill(payload(164.23), build=cached_build(dump_haul_m=("164.23",)))
|
||
row = next(r for r in priced.rows if r.name == "dump_truck 운반")
|
||
assert row.price_code == "B-FP-10-12-01#L164.23m" and row.amount_krw > 0
|
||
loading = payload(None)
|
||
loading["work_items"][0].update(name="덤프 적재", haul_equipment="dump_loading")
|
||
loaded = build_bill(loading, build=cached_build())
|
||
row = next(r for r in loaded.rows if r.name == "덤프 적재")
|
||
assert row.price_code == "B-FP-10-12-01#적재" and row.amount_krw > 0
|