- 등록부 box_culvert: 연장(기본값 없음) · 측벽 0.3 · 상·저판 0.25 · 헌치 0.2 · 버림 0.1 — 제안값 = 산림과임업기술(임도) 5장 수량산출 예제 · KDS 44 90 00 300㎜ 병기(판 0.25 는 못 미침을 나란히) - B06 BOX 세트(파이썬·TS 짝)가 두께 칸을 읽음 — 종전 「세월교 값 승계」(벽 0.2·판 0.3) 걷음 · 그림 따라감 - B08 전개식 `_UnitQuantity_Box`: 콘크리트 · 버림 · 유로폼(외벽·내벽·상판 밑·귀면) · 버림 옆 합판 · 동바리 · 비계(시종점 두 면은 개소당 한 번) · 철근은 울진 2×2 관측(D13 179·D16 157kg/m)만, 나머지 크기는 「크기별 식 없음」 - 울진 기번3 「암거수량집계표(2×2)」 m당과 맞음: 레미콘 2.84 · 버림 0.28 · 유로폼 11.131 · 합판 0.2 · 동바리 3.92 · 비계 벽체 5.2 - 치수 칸을 안 적은 BOX 는 제안값으로 서되 미확정(금액 밖) · 연장이 비면 안 섬 - 묶음 조각 12-01-01·12-38·12-04(6회)·12-03·12-20·12-19·12-25 · 동바리 대상 표시 · 세월교 「수량 근거 없음」 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016VBGFXB9AbJBwXP19z75Qq
126 lines
5.9 KiB
Python
126 lines
5.9 KiB
Python
"""BOX암거 전개식 — **m당 × 연장** (2026-09-15 브레인 12장 D 판정 ①~⑤).
|
||
|
||
근거 둘 — 구조가 같다
|
||
① 산림과임업기술(임도) 5장 「나) 구조물도에 의한 수량산출(예)」 · 그림 5-2-70
|
||
Box(2.0×1.5×2련×6.03m) — 구체 = (외곽 − 유수구 + 헌치) × L · 기초 = 폭 × 0.1 × L ·
|
||
거푸집 = 외벽·유수구·받침판·귀면 · 동바리 = 유수구 단면 × L · 철근 「상세도에서」(값 없음)
|
||
② 실무 울진 기번3 `5. 구조도(기번3).xlsx` 「암거수량집계표(2×2)」 m당 — 레미콘 2.84 ·
|
||
버림 0.28 · 유로폼 11.132 · 합판6회 0.2 · 철근 SD40 H13 0.179 + H16 0.157t · 동바리 3.92 ·
|
||
비계 18.72
|
||
두께 제안값은 등록부 칸(예제 벽 0.3 · 판 0.25 · 헌치 0.2 · 버림 0.1 · KDS 300㎜ 병기).
|
||
⚠ 1련만 — 등록부에 련수 칸이 없음(예제 식은 련수로 늘어나나 그림·칸이 1련).
|
||
⚠ 철근은 **크기별 식이 없다** — 울진 2×2 관측값만 선다(판정 ②).
|
||
⚠ 비계 시종점 두 면은 **개소당 한 번** — 원문은 m당 칸에 넣어 연장을 곱하면 부풀어 오름.
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
import math
|
||
from typing import Any
|
||
|
||
from B08_Quantity.B08_Quantity_Engine_UnitQuantity_Base import Component, _num, routed
|
||
|
||
#: 버림 폭 여유(m, 한쪽) — 예제 5.1 = 외곽 4.9 + 0.1×2 · 울진 2.8 = 외곽 2.6 + 0.1×2 (둘이 같음).
|
||
BLINDING_EXTRA_M = 0.1
|
||
#: 철근 관측값(kg/m) — 울진 기번3 「암거수량집계표(2×2)」 SD40 · 내공 2.0×2.0 · 벽·판 0.3.
|
||
REBAR_OBSERVED_2X2 = (("D13", 179.0), ("D16", 157.0))
|
||
REBAR_SIZE_ONLY = (
|
||
"철근 — 크기별 식 없음 · 관측값은 2×2 뿐(울진 기번3 구조도 SD40 H13 0.179 + H16 0.157t/m ·"
|
||
" 벽·판 0.3) — 이 크기는 철근이 안 섬(2026-09-15 브레인 판정 ②)"
|
||
)
|
||
SOURCES = (
|
||
"산식 = 산림과임업기술(임도) 5장 수량산출 예제(그림 5-2-70) · 실무 울진 기번3 구조도"
|
||
" 「암거수량집계표(2×2)」"
|
||
)
|
||
NOTE_FORMWORK = (
|
||
"거푸집 — 본체 유로폼(외벽 · 내벽 헌치 뺀 높이 · 상판 밑면 · 귀면 넷) · 버림 옆면 합판"
|
||
" (울진 2×2 모양 · 예제는 합판 3회)"
|
||
)
|
||
NOTE_SHORING_SCAFFOLD = (
|
||
"동바리(유수구 단면 − 헌치)·비계(외벽 양면 + 시종점 두 면)는 **실무 관측 모양**"
|
||
"(울진 2×2 「강재 3개월」) — 품셈 12-20 강관동바리 · 12-19 강관비계로 이음 ·"
|
||
" 시종점 두 면은 개소당 한 번(원문은 m당 칸)"
|
||
)
|
||
NOTE_WING_EARTH = (
|
||
"날개벽 수량 근거 없음(교본·실무 모두 · 판정 ⑤) — 날개벽 줄 안 섬"
|
||
" · 구체 터파기·되메우기는 아직 안 셈"
|
||
)
|
||
|
||
|
||
def box_culvert(options: dict[str, Any]) -> tuple[list[Component], list[str]]:
|
||
"""BOX암거 한 개소 — (성분, 사유). 연장이 없으면 성분 없이 사유만."""
|
||
length = _num(options.get("length_m"))
|
||
if length <= 0:
|
||
return [], ["BOX암거 연장(계류 방향)이 없어 수량이 안 섬 — 연장 칸을 적을 것(기본값 없음)"]
|
||
width, height = _num(options.get("body_width_m")), _num(options.get("body_height_m"))
|
||
wall, slab = _num(options.get("wall_thickness_m")), _num(options.get("slab_thickness_m"))
|
||
haunch, blinding = _num(options.get("haunch_m")), _num(options.get("blinding_thickness_m"))
|
||
if min(width, height, wall, slab) <= 0:
|
||
return [], ["BOX암거 본체 폭·높이·두께 중 빈 칸이 있어 수량이 안 섬"]
|
||
|
||
outer_w, outer_h = width + 2 * wall, height + 2 * slab
|
||
chamfer = math.sqrt(2) * haunch
|
||
per_m: list[tuple[str, str, float, str, str]] = [
|
||
(
|
||
"콘크리트",
|
||
"㎥",
|
||
outer_w * outer_h - width * height + haunch**2 / 2 * 4,
|
||
f"{outer_w:g}×{outer_h:g} − {width:g}×{height:g} + {haunch:g}²÷2×4",
|
||
"",
|
||
),
|
||
(
|
||
"버림콘크리트",
|
||
"㎥",
|
||
(outer_w + 2 * BLINDING_EXTRA_M) * blinding,
|
||
f"({outer_w:g} + {BLINDING_EXTRA_M:g}×2) × {blinding:g}",
|
||
"",
|
||
),
|
||
(
|
||
"유로폼",
|
||
"㎡",
|
||
2 * outer_h + 2 * (height - 2 * haunch) + (width - 2 * haunch) + 4 * chamfer,
|
||
f"외벽 {outer_h:g}×2 + 내벽 ({height:g} − {haunch:g}×2)×2"
|
||
f" + 상판 밑 ({width:g} − {haunch:g}×2) + 귀면 √({haunch:g}²+{haunch:g}²)×4",
|
||
"",
|
||
),
|
||
("합판거푸집", "㎡", 2 * blinding, f"버림 옆면 {blinding:g}×2", ""),
|
||
(
|
||
"동바리",
|
||
"㎥",
|
||
width * height - 2 * haunch**2,
|
||
f"{width:g}×{height:g} − {haunch:g}²÷2×4",
|
||
"",
|
||
),
|
||
("비계", "㎡", 2 * outer_h, f"외벽 양면 {outer_h:g}×2", ""),
|
||
]
|
||
notes: list[str] = [SOURCES, NOTE_FORMWORK, NOTE_SHORING_SCAFFOLD, NOTE_WING_EARTH]
|
||
if math.isclose(width, 2.0) and math.isclose(height, 2.0):
|
||
per_m += [
|
||
("이형철근", "kg", kg, "울진 기번3 구조도 2×2 관측(SD40)", size)
|
||
for size, kg in REBAR_OBSERVED_2X2
|
||
]
|
||
notes.append("철근은 관측값(울진 2×2 · 벽·판 0.3) — 두께를 바꿔도 따라 안 바뀜")
|
||
else:
|
||
notes.append(REBAR_SIZE_ONLY)
|
||
|
||
components = [
|
||
Component(
|
||
name,
|
||
unit,
|
||
amount * length,
|
||
destination,
|
||
f"{basis} = m당 {amount:.4g} × 연장 {length:g}m",
|
||
spec=spec,
|
||
)
|
||
for name, unit, amount, basis, spec in per_m
|
||
if (destination := routed(name, notes))
|
||
]
|
||
ends = 2 * outer_w * outer_h
|
||
for component in components:
|
||
if component.name == "비계":
|
||
component.amount += ends
|
||
component.basis += (
|
||
f" + 시종점 두 면 {outer_w:g}×{outer_h:g}×2 = {ends:.4g}(개소당 한 번)"
|
||
)
|
||
return components, notes
|