Files
Aislo/B08_Quantity/B08_Quantity_Engine_UnitQuantity_Box.py
T
eomsangdonandClaude Opus 5 a314ac12fd feat(b05·b06·b08): BOX암거 수량식 — 등록부 두께·연장 칸 + m당 × 연장 전개식 · 세월교·날개벽은 근거 없음 사유로 닫음(12장 D · 브레인 판정 ①~⑥)
- 등록부 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
2026-09-15 02:36:25 +09:00

126 lines
5.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""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