Files
Aislo/resources/tester/test_m02_df_standards.py
T
eomsangdonandClaude Opus 5.5 d660f2a12e feat(m02-df): 단위 · 금액 표준 표 처음 값 — 산림품셈 1-2-2 → DataFlow/_standard
- 단위표준.json 73 줄(병합 칸 10 줄 폄 · 소수자리 「-」 = 0 · 단위 「-」 = 없음 · 원문 줄 · 주 ①~③) · 원문 흠 그대로
- 금액단위표준.json 다섯 줄(지위 · 미만버림)
- 시험 test_m02_df_standards.py

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BU9gbNE3aWFUvE61pS2WGt
2026-10-01 19:37:53 +09:00

81 lines
3.4 KiB
Python

"""M02 단가산출 흐름도 — 단위 · 금액 표준 표(35-9 · 정함 11) 시험.
· `_standard/단위표준.json` — 산림품셈 1-2-2 「설계서의 단위 및 소수의 표준」 표 줄 수 · 병합 칸 폄 · 「-」 바꾸기 · 주 ①~③
· `_standard/금액단위표준.json` — 「금액의 단위표준」 다섯 줄 · 미만버림
· 원문 줄 번호가 원문의 그 줄을 가리킴 · 원문 흠은 고치지 않음(사용자가 시험판에서 고침)
"""
from __future__ import annotations
import json
from pathlib import Path
ROOT = Path(__file__).resolve().parents[2]
STD = ROOT / "M02_MasterTemplete" / "DataFlow" / "_standard"
SRC = (
ROOT
/ "resources/knowledge/original/원가계산/산림_표준품셈/본문/제01장_적용기준/1-02_설계_및_수량.md"
)
UNIT = json.loads((STD / "단위표준.json").read_text(encoding="utf-8"))
MONEY = json.loads((STD / "금액단위표준.json").read_text(encoding="utf-8"))
LINES = SRC.read_text(encoding="utf-8").split("\n")
def _cells(no: int) -> list[str]:
return [c.strip() for c in LINES[no - 1].strip().strip("|").split("|")]
def test_단위표준_줄_수_병합_원문줄() -> None:
rows = UNIT["줄"]
# 원문 표 = 머리 · 가름 · 몸 1행(단위 · 소수자리) 다음 73 줄 — 병합 칸 10 줄(주석의 14~15 · 17~20 · 32~33 · 35~36 · 45~47 · 61~63)
assert len(rows) == 73
assert sum(1 for r in rows if r.get("병합")) == 10
spread = {r["종목"] for r in rows if r.get("병합")}
assert spread == {
"견치돌, 깬돌",
"돌쌓기 및 돌붙임",
"목재(판재)",
"말뚝",
"돌망태",
"관류(管類)",
}
for r in rows:
cells = _cells(r["원문 줄"])
assert cells[0] == ("" if r.get("병합") else r["종목"])
assert [r["종목"] for r in rows[:3]] == ["공사연장", "공사폭원", "직공인부"]
assert rows[-1]["종목"] == "마대"
def test_단위표준_바꾸기() -> None:
"""소수자리 「-」 = 0 · 단위 「-」 = 「없음」 · 빈 칸 = null · 원문 글자는 그대로"""
for r in UNIT["줄"]:
src = _cells(r["원문 줄"])
for i, key in [(2, "규격 소수자리"), (4, "단위수량 소수자리")]:
want = 0 if src[i] == "-" else (int(src[i]) if src[i] else None)
assert r[key] == want, (r["원문 줄"], key)
for i, key in [(1, "규격 단위"), (3, "단위수량 단위")]:
want = "없음" if src[i] == "-" else (src[i] or None)
assert r[key] == want, (r["원문 줄"], key)
공사연장 = UNIT["줄"][0]
assert (공사연장["규격 단위"], 공사연장["규격 소수자리"], 공사연장["단위수량 소수자리"]) == (
"m",
2,
0,
)
말뚝 = [r for r in UNIT["줄"] if r["종목"] == "말뚝"]
assert 말뚝[1]["단위수량 단위"] is None # 원문 빈 칸 그대로
assert [n[:1] for n in UNIT["주"]] == ["①", "②", "③"]
def test_금액_다섯_줄() -> None:
rows = MONEY["줄"]
assert [(r["종목"], r["지위"]) for r in rows] == [
("설계서의 총액", 1000),
("설계서의 소계", 1),
("설계서의 금액란", 1),
("일위대가표의 계금", 1),
("일위대가표의 금액란", 0.1),
]
assert all(r["단위"] == "원" and r["비고"] == "미만버림" for r in rows)
assert all(_cells(r["원문 줄"])[0] == r["종목"] for r in rows)