Files
Aislo/resources/tester/test_b08_structure_figure_observed.py
eomsangdonandClaude Opus 5 7b6fe3873b feat(b08): 구조물도 그림 2조각 — 집수정(□형 Ø800) · 물넘이포장 · 날개벽·돌집수정은 까닭
- 집수정 □형 Ø800 — 관측 줄에 원문 치수(소광리 「집수정구조도(800)」 설계조건 칸·산출식)를 싣고 그 치수로 표 수량이 원문 식대로 다시 나오는지 시험
  원문 값으로: 콘크리트 2.84 → 2.83752 · 합판거푸집 21.28 → 21.2843 · 철근 D13 4.78 → 4.776 · 면목 12.67 → 12.6728(터파기·되메우기·잔토 그대로)
  그림: 긴 벽 정면(바닥기초·관·방수로·터파기) + 평면 · 관·방수로 자리는 원문 입체도 모식이라 적음
- 물넘이포장 — 슬래브 T(규격) · 와이어메쉬 2/3T(소광리 「포장」 그림) · 터파기 · 새 사유 「원문 둘이 다름: 소광리 포장 와이어매쉬 1.0·비닐 2㎡ ↔ 이 표(울진 1공구) 1.16·비닐 없음」을 표·그림이 같이 씀
- 날개벽 5종 — 원문 탭에 구조도 그림이 없고 날개 모양이 손으로 적은 수뿐이라 까닭 · 돌집수정 ㄷ·ㄴ형 — 집계표 관측값이라 치수 원문 없음 까닭
- 사유 문구(브레인 판정): 개거 150×200 「원문 둘이 다름(산출식 0.3×0.1 ↔ 그림 홈 150×200 + 밑 보 400×200)」 · 바닥막이 「옹벽은 버림·잡석까지 팜 — 바닥막이는 정본이 돌 두께만이라 다름」

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

114 lines
4.6 KiB
Python
Raw Permalink 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.
"""구조물도 그림 — 집수정 · 날개벽 · 물넘이포장 (관측 원단위, 2026-09-14 · 표 = 그림).
⚠ 집수정 □형 Ø800 — 그림 치수(`section`)로 **표 수량이 원문 식 그대로** 다시 나와야 함.
원문 값으로 바꿈: 콘크리트 2.84 → 2.83752 · 합판거푸집 21.28 → 21.2843 ·
철근 4.78 → 4.776 · 면목 12.67 → 12.6728.
"""
from __future__ import annotations
import math
import sys
from pathlib import Path
ROOT = Path(__file__).resolve().parents[2]
if str(ROOT) not in sys.path:
sys.path.insert(0, str(ROOT))
from B08_Quantity.B08_Quantity_Engine_ObservedUnit import load_observed_table # noqa: E402
from B08_Quantity.B08_Quantity_Engine_StructureFigure import attach_figures # noqa: E402
from B08_Quantity.B08_Quantity_Engine_StructureSheet import build_standard_sheets # noqa: E402
from B08_Quantity.B08_Quantity_Engine_UnitQuantity import build_table # noqa: E402
BASIN_SPEC = {
"inlet_basin_form": "□형(기본형)",
"inlet_basin_material": "콘크리트",
"pipe_diameter_mm": "800",
}
def _sheets(**options) -> list[dict]:
pipe = {
"structure_id": "p1",
"type_id": "pipe",
"start_m": 0.0,
"end_m": 0.0,
"options": {"pipe_kind": "흄관", **options},
}
payload = build_standard_sheets(build_table([pipe], None))
attach_figures(payload)
return payload["sheets"]
def _sheet(sheets: list[dict], type_id: str) -> dict:
return next(sheet for sheet in sheets if sheet["type_id"] == type_id)
def test_집수정_치수로_표_수량이_원문_식대로_다시_나온다() -> None:
entry = load_observed_table().find("pipe_inlet_basin", BASIN_SPEC)
s = entry["section"]
amounts = {item["name"]: item["amount"] for item in entry["components"]}
inner, wall, base = s["inner"], s["wall_m"], s["base_m"]
ol, ow, h = inner["length_m"] + 2 * wall, inner["width_m"] + 2 * wall, inner["height_m"]
il, iw = inner["length_m"], inner["width_m"]
sp = s["spillway"]
notch = (sp["top_m"] + sp["bottom_m"]) / 2 * sp["depth_m"]
hole = 3.14 * (s["pipe_d_m"] / 2) ** 2 # 원문이 3.14 로 셈
concrete = ol * ow * h - il * iw * h - sp["count"] * notch * wall - hole * wall + ol * ow * base
slant = math.hypot((sp["top_m"] - sp["bottom_m"]) / 2, sp["depth_m"])
form = (
(ol * h - hole)
+ (ol * h - notch)
+ (ow * h - notch) * 2
+ (il * h - hole)
+ (il * h - notch)
+ (iw * h - notch) * 2
+ (ol + ow) * base * 2
+ slant * wall * sp["count"] * 2
)
chamfer = ol + il * 2 + slant * sp["count"] + sp["bottom_m"] * sp["count"] + wall * 4
trench = (ol + s["dig"]["extra_length_m"]) * s["dig"]["width_m"] * (h + base)
backfill = trench - il * iw * (h + base)
assert abs(concrete - amounts["콘크리트"]) < 1e-9 # 2.83752
assert abs(form - amounts["합판거푸집"]) < 5e-5 # 21.28432
assert abs(chamfer - amounts["면목"]) < 5e-5 # 12.67279
assert abs(trench - amounts["터파기"]) < 1e-9
assert abs(backfill - amounts["되메우기"]) < 1e-9
assert abs(trench - backfill - amounts["잔토처리"]) < 1e-9
def test_집수정_그림이_서고_날개벽은_까닭() -> None:
sheets = _sheets(wing_wall_type="A-TYPE", **BASIN_SPEC)
basin = _sheet(sheets, "pipe_inlet_basin")
texts = [s["text"] for s in basin["figure"] if s["kind"] == "text"]
assert "안 3×1×1.2 · 벽 0.2 · 바닥기초 3.4×1.4×0.2 m" in texts
assert "터파기 3.8 × 2 × 깊이 1.4 m" in texts
wing = _sheet(sheets, "pipe_wing_wall")
assert (
wing["rows"] and wing["figure"] is None and "구조도 원본 확보 대기" in wing["figure_reason"]
)
def test_돌집수정은_치수_원문이_없어_까닭() -> None:
basin = _sheet(
_sheets(pipe_diameter_mm="800", inlet_basin_form="돌집수정 ㄷ형"), "pipe_inlet_basin"
)
assert basin["rows"] and basin["figure"] is None and "집계표 관측값" in basin["figure_reason"]
def test_물넘이포장_그림과_표에_원문_차이_사유가_같다() -> None:
structure = {
"structure_id": "f1",
"type_id": "ford_pavement",
"start_m": None,
"end_m": None,
"options": {"ford_width_m": 5, "length_m": 10, "thickness_cm": 20},
}
payload = build_standard_sheets(build_table([structure], None))
attach_figures(payload)
sheet = payload["sheets"][0]
texts = [s["text"] for s in sheet["figure"] if s["kind"] == "text"]
diff = [note for note in sheet["notes"] if "원문 둘이 다름" in note]
assert diff and diff[0] in texts
assert "와이어메쉬 — 밑에서 0.133 m (2/3T)" in texts