Files
Aislo/resources/tester/test_b08_structure_figure_small.py
T
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

112 lines
4.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.
"""구조물도 그림 — 기슭막이·골막이·떼흙막이·바닥막이·개거 (2026-09-14 · 표 = 그림).
표를 세운 그 전개(`build_table`)로 장을 만들고 그림 글자가 **표 근거와 같은 수**를 보이는지 대조.
"""
from __future__ import annotations
import re
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_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
from B08_Quantity.B08_Quantity_Engine_UnitQuantity_Revetment import ( # noqa: E402
BED_SILL_TRENCH_NOTE,
SOIL_GUARD_SOD,
)
def _sheet(type_id: str, rubble=None, **options) -> dict:
structure = {
"structure_id": type_id,
"type_id": type_id,
"start_m": 0.0,
"end_m": float(options.get("length_m") or 0.0),
"options": options,
}
table = build_table([structure], None, rubble_base_thickness_m=rubble)
payload = build_standard_sheets(table)
attach_figures(payload, rubble)
return payload["sheets"][0]
def _texts(sheet: dict) -> list[str]:
return [shape["text"] for shape in sheet["figure"] or [] if shape["kind"] == "text"]
def _basis(sheet: dict, name: str) -> str:
return next(row["basis"] for row in sheet["rows"] if row["name"] == name)
def test_기슭막이_돌쌓기형은_돌쌓기_그림이고_기울기_두께가_표와_같다() -> None:
sheet = _sheet("revetment", form="돌쌓기(메)", height_m=2.0, back_len_cm=35, length_m=10)
texts = _texts(sheet)
assert sheet["figure_reason"] is None
slope = re.search(r"1:([\d.]+)", _basis(sheet, "돌쌓기")).group(1) # 메쌓기 표준경사
assert f"1 : {slope}" in texts
top = re.search(r"상부 ([\d.]+)", _basis(sheet, "입적")).group(1)
assert f"상부 {top} m" in texts
concrete = _sheet("revetment", form="콘크리트", height_m=2.0, length_m=10)
assert concrete["figure"] is None and "콘크리트 기슭막이" in concrete["figure_reason"]
def test_골막이_그림_치수는_표_두께식과_같다() -> None:
sheet = _sheet(
"erosion_check", form="돌", height_m=1.5, top_length_m=4, bottom_length_m=2, back_len_cm=45
)
texts = _texts(sheet)
thickness = re.search(r"평균두께 ([\d.]+)m", _basis(sheet, "입적")).group(1)
label = next(t for t in texts if t.startswith("상부"))
assert f"평균 {float(thickness):.2f}" in label
trench = next(t for t in texts if t.startswith("바닥파기"))
width = re.search(r"× ([\d.]+) \)", _basis(sheet, "터파기").replace(")", " )")).group(1)
assert f"폭 {float(width):.2f}" in trench
band = [s for s in sheet["figure"] if s["kind"] == "path" and s["dash"]][0]
assert min(y for _x, y in band["points"]) < 0 # 바닥파기 띠가 밑변 바깥(아래)에 섬
def test_떼흙막이_붙박이_치수로_표_두_줄이_다시_나온다() -> None:
d = SOIL_GUARD_SOD["dims"]
sod = (
d["top_m"] * d["sod_m"]
+ d["bottom_m"] * d["sod_m"]
+ (d["top_m"] + d["bottom_m"]) / 2 * d["height_m"]
+ d["slant_m"] * d["sod_m"] * 2
)
trench = (d["slant_m"] * d["trench_width_m"] * d["trench_depth_m"] * 2) + (
d["bottom_m"] * d["trench_width_m"] * d["trench_depth_m"]
)
rows = {row[0]: row[2] for row in SOIL_GUARD_SOD["rows"]}
assert round(sod, 2) == rows["떼"] and round(trench, 2) == rows["터파기"]
assert (
abs(((d["top_m"] - d["bottom_m"]) / 2) ** 2 + d["height_m"] ** 2 - d["slant_m"] ** 2) < 0.01
)
sheet = _sheet("soil_guard", form="떼", height_m=0.5, length_m=10)
assert sheet["figure"] and sheet["unit_label"] == "개소당"
other = _sheet("soil_guard", form="돌(찰)", height_m=0.5, length_m=10)
assert other["figure"] is None and "떼흙막이" in other["figure_reason"]
def test_바닥막이_그림_사유는_표와_같은_말이고_기초잡석은_산출_조건() -> None:
sheet = _sheet("bed_sill", rubble=0.3, form="돌붙임(찰)", area_m2=12, height_m=0.3)
texts = _texts(sheet)
assert BED_SILL_TRENCH_NOTE in sheet["notes"] and BED_SILL_TRENCH_NOTE in texts
assert "기초잡석 T=0.3 m — 산출 조건" in texts
dry = _sheet("bed_sill", form="돌붙임(메)", area_m2=12, height_m=0.3)
assert (
not any("기초잡석" in t for t in _texts(dry)) and BED_SILL_TRENCH_NOTE not in dry["notes"]
)
def test_개거는_표가_서도_치수를_못_정한_까닭() -> None:
sheet = _sheet("open_ditch", ditch_spec="콘크리트 개거 150×200", length_m=5)
assert sheet["rows"] and sheet["figure"] is None and "확인 대기" in sheet["figure_reason"]
l_type = _sheet("open_ditch", ditch_spec="L형수로 H=0.2", length_m=5)
assert l_type["rows"] and "단면 그림이 없어" in l_type["figure_reason"]