Files
Aislo/resources/tester/test_m02_hopyo_match.py
eomsangdonandClaude Opus 5.5 48848bb287 refactor(785-7): 옛 맞춤 층 Python 지움 · 서버 새 길로 정리 · 낡은 시험 정리
- 지움(git rm) 10 파일 3,374 줄: M02_Hopyo_Finger · Ours · Option · Fit · Combine · Verdict · Line · SkLink · SkPatch · Basis
- Match: 흐름 몫(candidates · name_cands · fix_typo · clause · b_order · _logic_specs · _line_mod · units_of · _state · view · guess · picks · chain) 지움 · 이름 도구 몫 · line_key 남김
- Words: conds · cond_score · close · cosine · jacc 지움 / Shares: sections 지움(trade · eq_key 남김)
- 옮김: Finger.kind_of → Fixed.kind_of · SkLink(sk_line · kept · left · LEFT · WHY) → Sangeun · SkPatch 기계 몫(MACH_IN · MACHINE · SOLO · _mach_logics) → Units.mach_logics
- Sangeun: 옛 /sangeun 몸(build · _sure · Maker.basis · judge · plan · make) 지움 · Kids: first · proposal · order 지움 · Build: build() · unlinked() 지움(모두 고정 Builder · build_all · _order · _origins 남김)
- Router: 옛 길 지움(GET hopyo/{키}/{번} · guess · hopyo-picks · hopyo-build · hopyo-unlinked · hopyo/{키}/sangeun) · GET hopyo/{키} = Judge.view(1차 줄 판정 줄상태 · 만든 · 블록 풀이 셈)
- Marks: 칠 = Judge.judged 만 · Forget: 맞춤 캐시 지움 줄 걷음 · Ledger: Ours.version 판 칸 걷음 · Item: Kids.first 걷음
- Row(덧): 단산 줄 = 장부 짝이 있어도 늘 「2차 필요」(장부 = 1차 후보 힌트만)

시험 정리(까닭 = 지운 길 · 모듈만 시험함):
- 지움 11 파일: test_m02_hopyo_finger · fit · golden · option · ours · basis · seam · flow · draft_calc · test_635 · test_628(지문 · 순위 · 옵션 거꾸로 · 맡은 절 · 옛 확인 흐름)
- 함수 지움: /sangeun · /hopyo-build · /hopyo-unlinked · hopyo-picks · 옛 줄 맞춤 보기를 부르던 것(572 · 718_1 · 729 · 739_1 · 777_1 · 778_5 · 780_1 · labor_national · 705_3 · m02_hopyo_match · 746_1)
- test_621 S2(지문 해시) 지움 · S1 남김 · test_m02_hopyo_build = 장부 길 시험만(PUT 으로 심음)
- 새 길로: 779_2(줄상태 = 1차 판정 · 칠 셈 전 None) · grid · stmate(hopyo-judge 줄 판) · 778_1 · 778_2(Units.mach_logics) · 642_6(Marks 원문) · 642_3 장부 짝 단산 줄 2차 지킴

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 01:15:20 +09:00

147 lines
6.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.
"""일위대가 실무자료 이름 도구(PLAN 324-2 · 785-7 · `M02_Hopyo_Match`) — 규격 → 입력값 · 단위 · 환산 ·
자재 다듬기 · 전국 품목. 옛 맞춤 흐름(차례 · 보기 · 미리 셈) 시험은 785-7 에서 지움.
"""
import pytest
from M02_MasterTemplete import M02_Hopyo_Match as hm
# ruff: noqa: F811
mm = hm.mm
# ── 규격 · 단위 · 환산 ─────────────────────────────────────────────────
def test_규격_이름_붙은_수():
assert hm.numbers("D=1,000mm,일반형") == {"D": (1000, "mm")}
assert hm.numbers("H:1.2m") == {"H": (hm.Decimal("1.2"), "m")}
assert {k: float(v) for k, (v, _) in hm.numbers("B=2.3,H=0.4,야면석").items()} == {
"B": 2.3,
"H": 0.4,
}
assert hm.numbers("L3=35cm적용,장비사용") == {"L3": (35, "cm")}
assert hm.numbers("Φ40×200") == {} and mm.plain_spec("Φ40×200") == "ø40x200"
def test_단위_정규화():
got = [mm.plain_unit(u) for u in ("㎥", "M", "Ton", "TON", "EA", "㎡")]
assert got == ["m3", "m", "톤", "톤", "개", "m2"]
@pytest.mark.parametrize(
("have", "want", "spec", "times", "kind"),
[
("㎥", "㎥", "", 1, "같음"),
("M", "m", "", 1, "같음"),
("kg", "ton", "", 0.001, "단위표"),
("㎡", "㎥", "T=150mm", 0.15, "추정"),
("M", "㎡", "B=2.3,H=0.4", 2.3, "추정"),
("M", "㎥", "B=2.3,T=0.2", 0.46, "추정"),
("개소", "㎥", "", None, "입력"),
("㎥", "㎡ · ㎥", "", 1, "두 단위"),
("M", "㎡ · ㎥", "", None, "입력"),
],
)
def test_환산(have, want, spec, times, kind):
assert hm.factor(have, want, spec) == {"배": times, "갈래": kind}
SPECS = [
{"이름": "뒷길이", "단위": "㎝", "고르기": [25, 35, 45], "자동값": None},
{"이름": "관경", "단위": "mm", "자동값": None},
{"이름": "설치높이", "단위": "m", "자동값": None},
{
"이름": "기계",
"고르기": ["0201-0020", "0201-0060"],
"고르기이름": {
"0201-0020": "굴착기(무한궤도) 0.2㎥",
"0201-0060": "굴착기(무한궤도) 0.6㎥",
},
"자동값": None,
},
{"이름": "횟수", "고르기": ["3회사용시", "4회사용시"], "자동값": None},
{"이름": "단위당", "고르기": ["㎡당", "㎥당"], "자동값": None},
{"이름": "지역", "고르기": ["전국평균", "서울"], "자동값": "전국평균"},
{"이름": "보정작업", "고르기": ["해당 없음", "전석섞인토사"], "자동값": None},
]
def test_규격에서_입력값():
line = {"이름": "찰붙임(4회)", "규격": "L3=35cm적용,굴삭기0.6㎥,D=1,000mm,H:1.2m", "단위": "㎥"}
values, unread = hm.spec_inputs(line, SPECS)
assert values == {
"뒷길이": 35,
"관경": 1000,
"설치높이": 1.2,
"기계": "0201-0060",
"횟수": "4회사용시",
"단위당": "㎥당",
}
assert unread == ["보정작업"] # 지역 = 자동값 · 못 읽은 것만 표시
other = {"이름": "찰붙임", "규격": "L3=40cm", "단위": "㎡"}
values, unread = hm.spec_inputs(other, SPECS[:1])
assert values == {} and unread == ["뒷길이"] # 고르기 밖 수 = 빈 값 + 표시
MATERIAL_ANSWER = { # 북부청 임도 자재 · 별도계상 줄 → 우리 자재(정답 표 · 사람 확인)
("면목", "0.03×0.03×0.0424"): "MT007567", # 면 목 42, 30×30(0.03 m = 30 mm)
("자물쇠", "50m/m"): "MT008011",
("열연강판", "3.0mm"): "MT000884", # 3.0≤t<4.5 kg(같은 단위 먼저)
("원형돌망태(몸통)", "#8,45×45"): "MT006349",
("원형돌망태(뚜껑)", "#8,45×45"): "MT006350",
}
def test_자재_다듬기_규격_수():
from M02_MasterTemplete import M02_Hopyo_Material as hmat
line, apart = hmat.clean({"이름": "조약돌(별도계상)", "규격": "Ø100~200mm내외", "갈래": "자재"})
assert apart and line["이름"] == "조약돌"
assert hmat.clean({"이름": "레미콘(25-21-120)", "규격": "별도계상"})[0]["규격"] == ""
assert hmat.base("레미콘(관급)-강원도(홍천군(내면 제외))") == hmat.base("레미콘(서울)-사급")
assert (
hmat.base("와이어메쉬(용접철망)관급")
== hmat.base("와이어메쉬(용접철망),서울")
== "와이어메쉬"
)
row = {"spec": "", "nums": [42.0, 30.0, 30.0], "ranges": []}
assert hmat.spec_fit({"이름": "면목", "규격": "0.03×0.03×0.0424"}, row) == 1.0
rng = {"spec": "", "nums": [], "ranges": hmat._ranges("2.0≤T<3.0")}
assert hmat.spec_fit({"이름": "열연강판", "규격": "3.0mm"}, rng) == 0.0 # 끝 3.0 은 안 듦
got = hmat.marks(
{"이름": "레미콘", "규격": "별도계상", "갈래": "별도계상", "비고": "운반비 별도"}
)
assert got == {"별도계상": "별도계상", "자재구분": "관급", "운반비": "미포함"}
assert hmat.marks({"이름": "면목", "단가": {"재료비": 360}}, "면 목") == {
"별도계상": "직접계산",
"자재구분": "사급",
}
REMICON = {"이름": "레미콘(25-21-120)", "규격": "별도계상", "단위": "㎥", "갈래": "별도계상"}
H_BEAM = {"이름": "H 형강", "규격": "SS275, 100*100*6*8mm", "단위": "Ton", "갈래": "자재"}
def test_전국_지역_줄글_전국품목():
from M02_MasterTemplete import M02_Hopyo_Material as hmat
rows, tags = hmat.sure(hmat.clean(REMICON)[0]) # 지역 낱말 없음 · (전국) 품목 없음
assert rows[0]["one"] == {
"전국": True,
"이름": "레미콘(전국)-관급",
"규격": "25-21-120",
"단위": "㎥",
}
assert tags == [hmat.NATIONAL_TAG] and all("자재" in r["one"] for r in rows[1:])
paid = {**REMICON, "규격": "", "갈래": "자재", "단가": {"재료비": 90000}}
assert hmat.national(paid)["이름"] == "레미콘(전국)-사급" # 재료비 줄 = 사급 꼬리
named = {**REMICON, "비고": "강원도 강릉시"} # 줄 글에 지역 = 그 지역(원문)
rows, tags = hmat.sure(hmat.clean(named)[0])
assert rows[0]["one"]["이름"] == "레미콘(관급)-강원도(강릉시)" and tags == [hmat.REGION_TAG]
assert hmat.national(named) is None
rows, tags = hmat.sure(hmat.clean(H_BEAM)[0]) # (전국) 품목 있음 = 그것
assert rows[0]["one"]["자재"] == "MT001694" and tags == []
assert hmat.national(H_BEAM) is None
seoul = hmat.sure(hmat.clean({**H_BEAM, "비고": "서울"})[0])[0][0]["one"]
assert seoul["이름"] == "H 형강(서울)"