refactor(B08,B09): 폴더째 old_code 로 옮기고 빈 화면 둘만 남김 (PLAN 7-3)
B08_Quantity 86 · B09_Estimation 111 파일을 old_code/ 로 옮김(지우지 않음). 화면은 메뉴·주소·단계 막대만 남은 빈 틀 둘 — main.py 라우터 13 개는 끊음. B07 이 빌려 쓰던 비탈 길이·면적은 필요한 함수만 B07_DesignDetail_Engine_SlopeGeometry 로 옮겨 적음(면적 적분·노면 면적·측점 묶음은 안 옮김) · 시험 하나를 새로 둠. B07 구조물도 조립(Cad_StandardSheet)은 2026-09-13 에 이미 도면 목록에서 빠져 부르는 곳이 없어 old_code 로 같이 보냄 — 구조물 그림은 되살리지 않음. B06 구조물 몫 조회는 빈 값으로 두어 화면이 그대로 서게 함. B08·B09 를 부르던 시험 25 개도 old_code/resources/tester 로 옮김. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PAdA5ThqmtVSsbzjusk1cJ
This commit is contained in:
@@ -0,0 +1,184 @@
|
||||
"""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당 칸)"
|
||||
)
|
||||
#: 비계는 공㎥(품셈 12-19 밑수) = 면 × 폭 — 울진 단위 칸 「공/m3」 · 시종점 식 ×1.00 은 연장일 수 없음.
|
||||
SCAFFOLD_NOTE = "비계 폭 1.0m 관측(울진)"
|
||||
NOTE_WING = "날개벽 수량 근거 없음(교본·실무 모두 · 판정 ⑤) — 날개벽 줄 안 섬"
|
||||
NOTE_RUBBLE = (
|
||||
"기초잡석 — 근거 둘(예제·울진 집계표)에는 잡석 줄이 없음 — 사용자 확정 3차 ② 로 세움"
|
||||
"(버림이 선 구조물엔 잡석 · 옹벽과 같은 규칙)"
|
||||
)
|
||||
#: 구체 터파기 — 울진 「암거구체 토공(2×2)」: 밑폭 = 버림 폭 + 여유 0.5×2 · 옆면 1:0.5.
|
||||
TRENCH_CLEARANCE_M = 0.5
|
||||
TRENCH_SIDE_SLOPE = 0.5
|
||||
NOTE_TRENCH_MISSING = (
|
||||
"평균 터파기고 칸이 비어 구체 터파기·되메우기가 안 섬 — 칸을 적으면 토공으로 섬"
|
||||
)
|
||||
NOTE_TRENCH = (
|
||||
"구체 터파기 — 밑폭·옆면은 울진 「암거구체 토공(2×2)」(여유 0.5 · 1:0.5)"
|
||||
" · 깊이 = 평균 터파기고 칸 · 되메우기 = 터파기 − 든 것(기초잡석·버림·구체)"
|
||||
" — 원문은 잔토에 구체 전체 · 되메우기 한쪽만이라 옹벽 식(터파기 − 든 것)으로 맞춤"
|
||||
" · 토공집계로만 감(이중계상 방지)"
|
||||
)
|
||||
|
||||
|
||||
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 × 폭 1.0({SCAFFOLD_NOTE})", ""),
|
||||
]
|
||||
notes: list[str] = [SOURCES, NOTE_FORMWORK, NOTE_SHORING_SCAFFOLD, NOTE_WING, NOTE_RUBBLE]
|
||||
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}(개소당 한 번)"
|
||||
)
|
||||
if _num(options.get("trench_depth_m")) <= 0:
|
||||
notes.append(NOTE_TRENCH_MISSING)
|
||||
return components, notes
|
||||
|
||||
|
||||
def box_trench(
|
||||
options: dict[str, Any], rubble_thickness_m: float
|
||||
) -> tuple[list[Component], float] | None:
|
||||
"""구체 터파기·되메우기·잔토(토공 축) — 평균 터파기고가 비면 `None`.
|
||||
|
||||
기초잡석 두께는 원단위표와 **같은 값**을 받음(`build_table` 의 두께) — 두 벌로 안 셈.
|
||||
"""
|
||||
depth, length = _num(options.get("trench_depth_m")), _num(options.get("length_m"))
|
||||
outer_w = _num(options.get("body_width_m")) + 2 * _num(options.get("wall_thickness_m"))
|
||||
outer_h = _num(options.get("body_height_m")) + 2 * _num(options.get("slab_thickness_m"))
|
||||
blinding = _num(options.get("blinding_thickness_m"))
|
||||
if depth <= 0 or length <= 0 or outer_w <= 0:
|
||||
return None
|
||||
base_w = outer_w + 2 * BLINDING_EXTRA_M
|
||||
bottom = base_w + 2 * TRENCH_CLEARANCE_M
|
||||
top = bottom + 2 * TRENCH_SIDE_SLOPE * depth
|
||||
excavation = (bottom + top) / 2 * depth
|
||||
body = min(max(depth - rubble_thickness_m - blinding, 0.0), outer_h)
|
||||
filled = base_w * (rubble_thickness_m + blinding) + outer_w * body
|
||||
notes: list[str] = []
|
||||
rows = [
|
||||
(
|
||||
"터파기",
|
||||
excavation,
|
||||
f"(밑폭 {bottom:.2f}(버림 폭 {base_w:g} + 여유 {TRENCH_CLEARANCE_M:g}×2) + 윗폭"
|
||||
f" {top:.2f}(1:{TRENCH_SIDE_SLOPE:g})) ÷ 2 × 깊이 {depth:g} · {NOTE_TRENCH}",
|
||||
),
|
||||
(
|
||||
"되메우기",
|
||||
excavation - filled,
|
||||
f"터파기 − 든 것 {filled:.3f}(버림 폭 × (잡석 {rubble_thickness_m:g}"
|
||||
f" + 버림 {blinding:g}) + 구체 폭 {outer_w:g} × {body:.2f})",
|
||||
),
|
||||
("잔토처리", filled, "터파기 − 되메우기"),
|
||||
]
|
||||
return [
|
||||
Component(name, "㎥", amount * length, destination, f"{basis} × 연장 {length:g}m")
|
||||
for name, amount, basis in rows
|
||||
if (destination := routed(name, notes))
|
||||
], depth
|
||||
Reference in New Issue
Block a user