· 판정표 공통 한 곳(_unread_rows) — 읽힌 줄 밖의 줄을 올림 · 넘치지 않게: 읽힌 줄 · 이미 못 맞춤 이름 · 다른 갈래가 쓴 기계 줄 · 자원 머리(첫 줄 머리 모양 · 횟수별) · 빈 줄은 뺌 · 분류 딱지 줄(자재·인력·기계)은 이름 칸으로 · 비고는 글 앞머리와 함께 · 손 사유와 안 겹치게: 공종 사유 한 줄에 이미 적힌 이름은 안 올림 · 오늘 손으로 단 날개벽·면벽·맨홀 줄 목록 사유는 걷고 [주] 30% 할증만 남김 · 새던 셋이 함께 닫힘 — 12-15 거푸집·철근·뚜껑·설치비 · 12-04 비고(수직고 7m 할증) · 12-34-1 레미콘 별도계상 판정표 9표 늘어난 줄: 9-19-1 0 · 12-04 +1 · 12-15 +4 · 12-12 +8 · 12-13 +6 · 12-16 +7 · 12-34-1 +1 · 제목 금액·막힘·일부만 그대로 · 잴 시험 넷 빨강→초록 · 끄기 넷 빨강 · 전체 시험 1702 + 362 통과 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BW6Jdsh18WPtYUR6THZJqn
84 lines
3.9 KiB
Python
84 lines
3.9 KiB
Python
"""봉상후렉시블 셋 + 12-34-1 — 2026-09-14 브레인(672 다음).
|
||
|
||
같은 「봉상후렉시블(45mm) Q=5.4㎥/hr」 줄 하나가 12-12 날개벽 · 12-13 면벽 · 12-16 맨홀을 막고 있었음.
|
||
세 표는 12-15 집수정과 같은 모양(㎥ 줄 비고 인력 + 다짐기 줄) — 판정표 한 벌에 더하고 엔진식 4611-0350 로 이음.
|
||
실무 영월 「콘크리트타설(임도품셈 5-5)」 호표가 같은 모양: 콘크리트공 0.15·보통인부 0.27 인/㎥ + 진동기 1/Q(5.4)
|
||
· 진동기 45φ(2.6㎾)엔진식플렉시블형 손료 252천원 × 0.5101 · 노무 0 — 엔진식·계수·조종원 없음이 실무 실증.
|
||
|
||
12-34-1 콘크리트 타설(철근 진동기 포함) — 실무 호표 없음 → 브레인 판정
|
||
① 「콘크리트 진동기(3.5HP) 대 2」 만 4611-0350 × 2대 · 「봉상후렉시블(45mm) 대 2」 는 같은 기계의 봉이라 안 셈
|
||
② 머리 「(단위: 개소당)」 ↔ 인력 0.17·0.29 가 12-16 맨홀 ㎥당과 같고 기계도 Q ㎥/hr ⇒ ㎥당으로 읽고 사유에 나란히
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
from decimal import Decimal
|
||
|
||
from B09_Estimation.B09_Estimation_UnitPrice import cached_build, detail_of
|
||
|
||
VIBRATOR = "X-4611-0350"
|
||
PER_Q = Decimal(1) / Decimal("5.4")
|
||
|
||
|
||
def _rows(build, code: str) -> dict[str, Decimal]:
|
||
return {
|
||
r["ref_code"]: Decimal(r["quantity"])
|
||
for r in detail_of(build, code)["rows"]
|
||
if r.get("ref_code")
|
||
}
|
||
|
||
|
||
def test_날개벽_면벽은_콘크리트_갈래가_진동기와_함께_섬() -> None:
|
||
build = cached_build()
|
||
for code in ("B-FP-12-12#콘크리트", "B-FP-12-13#콘크리트"):
|
||
rows = _rows(build, code)
|
||
assert rows[VIBRATOR] == PER_Q and rows["1013"] == Decimal("0.15"), (code, rows)
|
||
assert rows["1002"] == Decimal("0.27"), (code, rows)
|
||
assert build.book.titles[code].unit == "㎥"
|
||
assert (
|
||
"FP-12-12" not in build.basis_missing
|
||
) # 비고가 인/㎥ — 「개소당」 머리가 없어도 밑수는 ㎥
|
||
|
||
|
||
def test_맨홀은_비고가_끝_칸이_아니어도_구체_버림_갈래() -> None:
|
||
build = cached_build()
|
||
body = _rows(build, "B-FP-12-16#구체콘크리트")
|
||
assert (
|
||
body[VIBRATOR] == PER_Q
|
||
and body["1013"] == Decimal("0.17")
|
||
and body["1002"] == Decimal("0.29")
|
||
)
|
||
lean = _rows(build, "B-FP-12-16#버림콘크리트")
|
||
assert lean == {"1013": Decimal("0.15"), "1002": Decimal("0.27")}, lean
|
||
for code in ("FP-12-12", "FP-12-13", "FP-12-16"):
|
||
assert "봉상후렉시블" not in " ".join(build.unattached.get(code, [])), code
|
||
|
||
|
||
def test_12_34_1_진동기_두_대만_세고_봉은_두_번_안_셈() -> None:
|
||
build = cached_build()
|
||
rows = _rows(build, "B-FP-12-34-01")
|
||
assert rows[VIBRATOR] == 2 * PER_Q, rows
|
||
assert rows["1013"] == Decimal("0.17") and rows["1002"] == Decimal("0.29"), rows
|
||
from B09_Estimation.B09_Estimation_KnownGaps import known_gap_note
|
||
|
||
assert "봉상후렉시블" in known_gap_note("FP-12-34-01") and "두 번 안 셈" in known_gap_note(
|
||
"FP-12-34-01"
|
||
)
|
||
refs = [r.get("ref_code") for r in detail_of(build, "B-FP-12-34-01")["rows"]]
|
||
assert refs.count(VIBRATOR) == 1, refs # 봉 줄이 기계로 또 안 섬(한 줄 · 2대 몫)
|
||
|
||
|
||
def test_12_34_1_은_개소당_머리를_세제곱미터당으로_읽은_까닭을_보임() -> None:
|
||
from B09_Estimation.B09_Estimation_KnownGaps import known_gap_note
|
||
|
||
build = cached_build()
|
||
assert build.book.titles["B-FP-12-34-01"].unit == "㎥"
|
||
note = known_gap_note("FP-12-34-01")
|
||
assert "개소당" in note and "㎥당" in note and "12-16" in note, note
|
||
|
||
|
||
def test_표의_나머지_줄은_조용히_안_사라지고_사유에_원문_그대로() -> None:
|
||
"""손 사유로 달던 줄 목록은 판정표 자동 목록(`_unread_rows`)으로 옮김 — `test_b09_judged_unread_rows`."""
|
||
left = " ".join(cached_build().unattached.get("FP-12-16", []))
|
||
assert "원형거푸집" in left and "설치비" in left, left
|