feat(B09): 노체다짐(9-16-2) 단가가 서게 함 — 다짐 공식은 굴착·운반과 식이 다름

Q = 1000 × V × W × E × D × f / N 로 서는 첫 공종. 계수 여섯은 표에 다 있고 기종만
[주]에 있어 마스터가 못 싣던 자리.

- 롤러만 듦 — [주]③ 의 「굴착기와 진동롤러 조합」은 포설(9-16-1)과 다짐을 함께 쓰라는
  뜻으로 읽음. 이 줄에 굴착기를 또 넣으면 포설에서 센 굴착기를 두 번 셈.
- 계수가 하나라도 없으면 안 섬 — 채워 넣지 않음.
- 조건([주]⑤ 대규모 성토지 층다짐)과 기종 근거를 줄에 남김.
- ⚠ 인계에 그 줄이 없어 금액은 아직 안 섬 — 층다짐을 셀지는 설계 판단(사용자 확정 대기).
  넣으면 13,150.2㎥ × 527.40 = 6,935,414원.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-09 22:57:01 +09:00
co-authored by Claude Opus 5
parent 9f2de109dd
commit 87c710a27b
3 changed files with 210 additions and 1 deletions
+82
View File
@@ -0,0 +1,82 @@
"""노체다짐(9-16-2) — 다짐 공식으로 서는 공종 (2026-09-09 밤).
굴착·운반과 **식이 다르다** — 사이클(㎝)이 아니라 롤러가 지나간 넓이로 센다.
Q = 1000 × V × W × E × D × f / N (㎥/시간)
⚠ 겨누는 것 넷
① 계수 여섯을 표에서 그대로 읽는다 — 하나라도 없으면 **채워 넣지 않고 안 선다**
② Q 가 원문 값과 같다 (1000×4×1.9×0.6×0.3×1.0÷6 = 228 ㎥/hr)
③ **롤러만** 든다 — [주]③ 의 「굴착기와 롤러 조합」은 포설(9-16-1)과 다짐을 함께 쓰라는
뜻이라, 이 줄에 굴착기를 또 넣으면 **포설에서 센 굴착기를 두 번 센다**
④ 조건([주]⑤ 대규모 성토지 층다짐)과 기종 근거가 줄에 남는다
"""
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_Compaction import ( # noqa: E402
capacity_per_hour,
compaction_factors,
compaction_rows,
)
from B09_Estimation.B09_Estimation_UnitPrice import ( # noqa: E402
cached_build,
load_work_item_master,
)
def _node(code: str) -> dict:
master = load_work_item_master()
return next(w for w in master["work_items"] if w["work_item_code"] == code)
def test_계수_여섯을_표에서_그대로_읽는다() -> None:
factors = compaction_factors(_node("FP-09-16-02")["tables"][0])
assert factors == {
"V": Decimal("4"),
"W": Decimal("1.9"),
"E": Decimal("0.6"),
"D": Decimal("0.3"),
"f": Decimal("1.0"),
"N": Decimal("6"),
}
def test_하나라도_없으면_안_선다() -> None:
"""① 채워 넣으면 조용히 틀린 작업량이 선다."""
assert compaction_factors({"raw_row": [["V(다짐속도,km/hr)", "4", ""]]}) is None
def test_작업량이_원문_식과_같다() -> None:
factors = compaction_factors(_node("FP-09-16-02")["tables"][0])
assert factors is not None
assert capacity_per_hour(factors) == Decimal(228)
def test_롤러만_든다() -> None:
"""③ 굴착기를 또 넣으면 포설에서 센 것을 두 번 센다."""
rows = compaction_rows(_node("FP-09-16-02"))
assert [row["machine_code"] for row in rows] == ["1306-0100"] # 진동롤러(자주식) 10ton
def test_근거와_조건이_줄에_남는다() -> None:
rows = compaction_rows(_node("FP-09-16-02"))
text = rows[0]["source_text"]
assert "9-16-2 [주]①" in text and "층다짐" in text and "두 번" in text
def test_단가가_선다() -> None:
build = cached_build()
title = build.book.titles.get("B-FP-09-16-02")
assert title is not None and title.unit == ""
money = build.book.resolve("B-FP-09-16-02")
assert money.total > 0
# 포설(굴착기)보다 싸야 한다 — 롤러 한 대가 228㎥/hr 로 도는 줄이다.
assert money.total < build.book.resolve("B-FP-09-16-01").total