- 지움(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>
147 lines
6.6 KiB
Python
147 lines
6.6 KiB
Python
"""일위대가 실무자료 이름 도구(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 형강(서울)"
|