Files
Aislo/resources/tester/test_b08_formwork.py
T
eomsangdonandClaude Opus 5 650f660ed1 feat(b08): 옹벽 구멍 셋 — 터파기 기초분 · 원문 값 · 물빼기 칸이 표에 닿음(전후 대조)
① 터파기·되메우기·잔토 — 소광리 「옹벽2.0」에 줄이 없어 브레인 판정대로 기초 폭 + 양쪽 여유 0.3(같은 파일 식생옹벽블럭 기초 터파기)로 수직 · 깊이 기초 0.4 + 버림 0.1 + 기초잡석 · 비탈분 제외(지반선이 제원에 없음) · earthwork 로만
   m당 터파기 1.54 · 되메우기 0.36(터파기 − 기초·전단키·버림·잡석) · 잔토 1.18 · 인계 심도 구분은 판 깊이(0.7 m → 0~1m)
② 관측 값을 원문으로 — 콘크리트 1.35→1.345 · 버림 0.15→0.145 · 유로폼 3.2→3.205 ⇒ 기초잡석 0.30→0.29
③ 물구멍관 — 실무 관측 식(「옹벽2.0」 T31 벽 높이 ÷ 개소당 면적 × 관 0.4)에 제원 칸이 닿음 · 규격 Ø50 이 붙어 자재총괄에서 돌쌓기 물구멍관과 한 줄(33.924 + 3.2 → 37.124 m) · 관 길이는 관측값으로 표시
- 검증 프로젝트 내역 본체 122,848,989 → 124,202,681원(+1,353,692 = 구조물터파기 심도 0~1m 15.4㎥ 1,341,216 + 되메우기 21.0→24.6㎥ +12,476)
- 그림: 터파기 점선·「터파기 폭 2.20 × 깊이 0.70」 · 표 사유와 같은 말 · 옛 값을 박은 시험 8건을 원문 값으로(전 값은 주석)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016VBGFXB9AbJBwXP19z75Qq
2026-09-14 05:59:32 +09:00

122 lines
4.6 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.
"""거푸집 사용횟수 검사 — 품셈 1-7-1 · 2026-09-07 ⑩.
⚠ 사용횟수는 **관측값이 아니라 법**이다 — 품셈 1-7-1 이 구조물 종류별로 정해 둔다.
⚠⚠ **횟수별 재료 환산은 여기서 하지 않는다.** 품셈 12-4 의 비율(%)은 일위대가 재료비에
걸리는 값이라, B08 이 곱해 넘기면 B09 가 또 곱해 두 번 준다.
"""
from __future__ import annotations
import sys
from pathlib import Path
ROOT = Path(__file__).resolve().parents[2]
sys.path.insert(0, str(ROOT))
from B08_Quantity.B08_Quantity_Engine_Formwork import ( # noqa: E402
FORMWORK_NAMES,
NOTE_REUSE_MISSING,
FormworkTable,
annotate,
load_formwork_table,
shoring_status,
)
from B08_Quantity.B08_Quantity_Engine_UnitQuantity import build_table # noqa: E402
def 옹벽() -> dict:
return {
"structure_id": "w1",
"type_id": "retaining_wall",
"start_m": 100.0,
"end_m": 110.0,
"options": {"form": "반중력식", "height_m": 2.0, "length_m": 10.0},
}
def test_원문에_이름이_있는_구조물은_횟수가_붙음() -> None:
"""품셈 1-7-1 의 3회 줄에 「옹벽」이 그대로 있다."""
table = build_table([옹벽()], {"retaining_wall": "옹벽"})
forms = [c for s in table["structures"] for c in s["components"] if c["name"] in FORMWORK_NAMES]
assert forms
assert all(c["reuse_count"] == 3 for c in forms)
assert all("1-7-1" in c["reuse_note"] for c in forms)
assert table["formwork_reuse_missing"] == []
def test_횟수별_비율을_여기서_곱하지_않을것() -> None:
"""⚠ 이 시험이 이 파일의 핵심 — 합판 3회 46.1 % 를 여기서 곱하면 B09 와 겹쳐 두 번 준다.
B08 이 내는 것은 **접촉 면적 그대로**이고 횟수는 옆에 적기만 한다."""
table = build_table([옹벽()], {"retaining_wall": "옹벽"})
euroform = next(
c for s in table["structures"] for c in s["components"] if c["name"] == "유로폼"
)
# 3.205 ㎡/m × 10m — 46.1 % 를 곱하지 않았다(2026-09-14 원문 값 3.205 · 전 라이브러리 3.20 → 32.0)
assert abs(euroform["amount"] - 32.05) < 1e-9
# 비율표는 데이터에 있되 값에 안 걸린다.
assert load_formwork_table().reuse_ratio_pct["plywood"]["3"] == 46.1
def test_모르는_종류는_지어내지_않고_미확보() -> None:
structures = [
{
"type_id": "듣도보도못한구조물",
"name": "무엇",
"components": [{"name": "합판거푸집", "unit": "㎡", "amount": 5.0}],
}
]
notes, missing = annotate(structures)
assert missing == ["듣도보도못한구조물"]
assert structures[0]["components"][0]["reuse_count"] is None
assert structures[0]["components"][0]["reuse_note"] == NOTE_REUSE_MISSING
def test_거푸집이_없는_구조물은_건드리지_않음() -> None:
structures = [
{
"type_id": "retaining_wall",
"components": [{"name": "콘크리트", "unit": "㎥", "amount": 1.0}],
}
]
notes, missing = annotate(structures)
assert notes == [] and missing == []
assert "reuse_count" not in structures[0]["components"][0]
def test_이름은_정확히_일치로만_본다() -> None:
"""부분일치면 「거푸집씻기」(공사용수 항목)가 거푸집으로 잡힌다."""
structures = [
{
"type_id": "retaining_wall",
"components": [{"name": "거푸집씻기", "unit": "㎥", "amount": 1.0}],
}
]
annotate(structures)
assert "reuse_count" not in structures[0]["components"][0]
def test_파일이_없으면_전부_미확보() -> None:
structures = [
{
"type_id": "retaining_wall",
"components": [{"name": "유로폼", "unit": "㎡", "amount": 1.0}],
}
]
notes, missing = annotate(structures, FormworkTable())
assert missing == ["retaining_wall"]
# ── 동바리 ──────────────────────────────────────────────────────────
def test_동바리는_대상이_없으면_없다고_말할것() -> None:
"""0 으로 적으면 「대상이 없음」과 「값이 0」이 구별되지 않는다."""
status = shoring_status()
assert status["applicable"] is False
assert status["reason"]
assert set(status["pending_types"]) == {"box_culvert", "ford_bridge"}
def test_표에도_동바리_상태가_실림() -> None:
assert build_table([옹벽()])["shoring"]["applicable"] is False