- Fit: 인용 조항 같음 로직에 이름 1위와 같은 덤(fuse) · 조항 가중 1.5 → 2.0 — 북부청 임도 단산10 1위 GF000214 야면석 채집 → GC001140 인력운반(지게) · 골든 1위 162 → 163(사람 120 · 새 43) · 다른 점 틀림 0 → 1(N006 정답표가 짐작 GF000280 인 줄 — 새 로직이 맞는 근거) - 화면: 근거 칩 툴팁 로직 null 일 때 「null · 기초 없음」 → 「기초 없음」 - test_628: 예시1 시험을 새 뜻(근거 GC001140 · 기초 없음 표지 없음)으로 · 표지 수 19 → 18(공통 1-2-7 인용 블록은 여덟 파일 중 단산10 하나) · 우리 지문표 없으면 만들고 시작 Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
120 lines
5.8 KiB
Python
120 lines
5.8 KiB
Python
"""781-1 · 781-2(요구 628 · 629 · 630) — 출처 책 · 부문 · 옛 책 가림 ·
|
|
「근거 조항 우리 기초에 없음」 표지.
|
|
|
|
책 낱말(임도 · 사방 = 옛 책 · 건설 부문 낱말) · 부문 풀이(북부청임도 단산10 → 건설 공통 1-2-7 ·
|
|
영월 「건설표준품셈 9-1」 → 번호 뜻 안 맞음 = (옛)) · 임도 옛 번호 → 대응표 현행 번호 ·
|
|
조항 견줌은 책 + 부문 · 예시 1(단산10 근거 = 건설 공통 1-2-7 인력운반(지게) GC001140 ·
|
|
782-1 새 로직 · 줄 금액 94,227.7 그대로) · 번호만 같은 다른 부문 · 옛 번호 로직이 1위 · 다섯 안에 안 듦
|
|
(봉화 깬잡석채집 · 영월 콘크리트소운반) · 여덟 파일 표지 수.
|
|
읽기만 · 서버 없음 · master_data 그대로.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from collections import Counter
|
|
|
|
import pytest
|
|
|
|
from M01_MasterData import M01_MasterData_Store as m01
|
|
from M02_MasterTemplete import M02_Hopyo_Basis as hb
|
|
from M02_MasterTemplete import M02_Hopyo_Fit as fit
|
|
from M02_MasterTemplete import M02_Hopyo_Match as hm
|
|
from M02_MasterTemplete import M02_Hopyo_Ours as ours
|
|
from M02_MasterTemplete import M02_Hopyo_ReadEst as est
|
|
from M02_MasterTemplete import M02_Hopyo_Sangeun as sangeun
|
|
from M02_MasterTemplete import M02_Hopyo_SkUnit as skunit
|
|
from M02_MasterTemplete import M02_Hopyo_Units as units
|
|
from M02_MasterTemplete import M02_Hopyo_Verdict as verdict
|
|
from resources.tester import helper_m02_hopyo_golden as golden
|
|
|
|
|
|
@pytest.fixture(scope="module", autouse=True)
|
|
def _ours_ready():
|
|
if not ours.ready(): # 맞춤셈은 우리 지문표가 있어야 돎(판이 바뀌면 다시)
|
|
ours.build()
|
|
|
|
|
|
def _block(tag: str, no: int) -> dict:
|
|
return next(b for b in golden.read(tag)["단산"] if b["번"] == no)
|
|
|
|
|
|
def _unit(tag: str, no: int) -> tuple[dict, dict]:
|
|
"""(블록, 그 블록을 부르는 첫 셈 단위 줄)."""
|
|
for _, block, line in fit.units(golden.read(tag)):
|
|
if block and block.get("번") == no:
|
|
return block, line
|
|
raise AssertionError(f"{tag} 단산{no} 셈 단위 없음")
|
|
|
|
|
|
def test_책_낱말():
|
|
assert est.sources("건설공사표준품셈 1-2-7") == [["건설품셈", "1-2-7"]]
|
|
assert est.sources("임도표준품셈 5-1-2") == [["임도품셈(옛)", "5-1-2"]]
|
|
assert est.sources("사방품셈 4-2-2") == [["사방품셈(옛)", "4-2-2"]]
|
|
assert est.sources("공통품셈 3-1-8") == [["건설품셈 공통", "3-1-8"]]
|
|
assert est.sources("토목품셈 2-7-1") == [["건설품셈 토목", "2-7-1"]]
|
|
assert est.sources("[2025년 산림사업표준품셈 9-14]") == [["산림품셈", "9-14"]]
|
|
assert est.sources("2019년건설표준품셈 3-1-3") == [["건설품셈", "3-1-3"]]
|
|
|
|
|
|
def test_부문_풀이_옛_번호():
|
|
assert _block("북부청임도", 10)["출처"] == [["건설품셈 공통", "1-2-7"]]
|
|
assert _block("동부청영월", 450)["출처"] == [["건설품셈(옛)", "9-1"]]
|
|
assert hb.road_map()["5-1-2"] == "9-13" # 가 · 나 항 → 현행 윗마디
|
|
assert hb.road_map()["3-3-1"] == "9-3-2" and "3-3-2" not in hb.road_map() # 일대다 안 옮김
|
|
assert hb.resolve([["임도품셈(옛)", "2-3"]], "제근") == [["산림품셈", "9-21"]]
|
|
assert hb.resolve([["임도품셈(옛)", "5-5"]], "콘크리트타설") == [["임도품셈(옛)", "5-5"]]
|
|
assert hb.resolve([["건설품셈", "1-2-7"]], "") == [["건설품셈", "1-2-7"]] # 이름 없음 = 모름
|
|
|
|
|
|
def test_조항_견줌_부문():
|
|
ours = hb.ours()
|
|
for code in ("GC001004", "GC000567"): # 유지관리 · 건축 1-2-7
|
|
assert hb.clause([["건설품셈 공통", "1-2-7"]], ours[code])[0] == 0
|
|
assert hb.clause([["건설품셈(옛)", "1-2-7"]], ours[code])[0] == 0
|
|
assert hb.clause([["건설품셈", "1-2-7"]], ours[code])[0] == 1.0 # 부문 모름 = 그대로
|
|
|
|
|
|
def test_예시1_근거_인력운반_지게():
|
|
block, line = _unit("북부청임도", 10)
|
|
assert hb.no_basis(block["출처"]) is None # 782-1 로직이 생겨 기초 없음 아님
|
|
got = verdict.block(block, line, hm.targets())
|
|
assert "기초없음" not in got
|
|
assert got["차례"][0] == "GC001140" # 지게(사람 줄) — 1141 기계설비 · 1142 벽돌 아님
|
|
maker = sangeun.Maker.__new__(sangeun.Maker)
|
|
maker.first, maker.blocks, maker.whole = {10: line}, {10: block}, m01.loaded()[1]
|
|
maker.cache = {fit.unit_key(line): got}
|
|
basis = maker.basis(10)
|
|
assert basis["로직"] == "GC001140" and basis["이름"].startswith("인력운반(지게)")
|
|
judged = skunit.judge(block, units.Units(), lambda sub: None, None, "㎡")
|
|
assert judged["판정"] == "옮길 수 있음" and judged["우리금액"] == pytest.approx(94227.7, abs=1)
|
|
rows = [r for r in judged["더한줄"] if r.get("요소") == "LB000002"]
|
|
assert rows and rows[0]["수량"] == pytest.approx(0.547619, abs=1e-6)
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"tag, no, wrong",
|
|
[
|
|
("봉화", 3, "GC000721"),
|
|
("봉화", 43, "GC000721"),
|
|
("봉화", 51, "GC000721"),
|
|
("봉화", 52, "GC000721"),
|
|
("동부청영월", 450, "GC000677"),
|
|
],
|
|
)
|
|
def test_번호만_같은_로직_안_오름(tag, no, wrong):
|
|
block, line = _unit(tag, no)
|
|
got = verdict.block(block, line, hm.targets())
|
|
assert got["차례"][0] != wrong and got["판정"]["상태"] != "다른 점"
|
|
for code in got["차례"]: # 다섯 안에 번호로 오른 것 없음(지문 점수로만 남을 수 있음)
|
|
our = hb.ours().get(code)
|
|
assert not our or hb.clause(block["출처"], our)[0] == 0 or our["구분"] in block["출처"][0]
|
|
|
|
|
|
def test_여덟_파일_표지_수():
|
|
seen = Counter()
|
|
for tag in golden.FILES:
|
|
for block in golden.read(tag)["단산"]:
|
|
seen[(hb.no_basis(block["출처"]) or {}).get("판정")] += 1
|
|
assert seen["기초 없음"] == 18 # 782-1 로 북부청 임도 단산10(공통 1-2-7) 하나 빠짐
|
|
assert seen["옛 번호"] == 121
|