- 새 M02_Hopyo_MatSame — ㉮ 이름 같은 품목(빈칸 · 괄호 차례 · 등급 · 점 · 소리 표기 넷) + 규격 수 묶음 같음(차례 · 단위 배 · 한쪽 듦) + 규격 낱말 안 부딪힘 + 우리 품목 하나 → 이음 · ㉯ 이름 같은 묶음 = 규격 어근 품은 줄 · 덧말 적은 줄 1 순위 · 규격 수 같은 후보 먼저 - M02_Hopyo_Row 재료 길 = 바탕 이름 유일 짝 뒤 ㉮ › 옛 후보 하나 › ㉯ + 옛 후보 - M02_San_Link — 별도계상 줄 = 요소 잇기 없음 + 표지 「별도계상 · 품목은 프로젝트에서」 · 못 이은 재료 까닭에 1 순위 이름 · 규격 - 전수(원파일 2,220 · 엑셀 1,021) 재료 이음 88.0 → 93.5 % · 새 이음 112 줄 51 종 · 끊긴 이음 0 · 금액 그대로 · 치즐 0.7 이 엉뚱한 0.2 줄에서 0.7 줄로 옮김 - 시험 test_817_1_material_find(과녁 100 줄 · 틀린 이음 막기 · 별도계상 표지) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
193 lines
10 KiB
Python
193 lines
10 KiB
Python
"""817-1 불러오기 재료 찾기 — 표기만 다름 ㉮ 이음 · ㉯ 후보 좁힘 · 틀린 이음 막기 · 별도계상 표지(요구 773-5 · 774).
|
||
|
||
과녁 = 사용자 시트 「수동연결(자재)」 100 줄(브레인 과녁 `_과녁_773_자재표기.tsv` 를 우리 자재표로 다시 확인한 결과).
|
||
「후보」 줄 키 = 1 순위를 굳힌 줄만(종자 · 그레이팅 · 표기만 다름인데 수 묶음 · 이름이 안 맞아 ㉯ 로 둔 줄) · None = 이음만 안 됨.
|
||
"""
|
||
|
||
import sys
|
||
from pathlib import Path
|
||
|
||
import pytest
|
||
|
||
ROOT = Path(__file__).resolve().parents[2]
|
||
sys.path[:0] = [str(ROOT), str(ROOT / "resources" / "master_data" / "scripts")]
|
||
|
||
from M02_MasterTemplete import M02_Hopyo_MatSame as ms # noqa: E402
|
||
from M02_MasterTemplete import M02_Hopyo_Row as hrow # noqa: E402
|
||
from M02_MasterTemplete import M02_San_Link as sl # noqa: E402
|
||
|
||
TABLE = [
|
||
("접착제", "", "후보", None), # 1
|
||
("패널(유로폼)", "600*1200mm", "이음", "MT000467"), # 2
|
||
("각재", "외송", "후보", "MT000393"), # 3
|
||
("요소", "", "후보", "MT006763"), # 4
|
||
("내부코너패널(유로폼)", "(100x200)x1200mm", "이음", "MT000470"), # 5
|
||
("결속선(철선)", "#20 , 0.9M/M", "후보", None), # 6
|
||
("각재 (외송)", "", "후보", "MT000393"), # 7
|
||
("파형강관", "별도계상", "후보", None), # 8
|
||
("금강사", "", "없음", None), # 9
|
||
("고무테이프", "0.5mm×19mm×10m", "이음", "MT009202"), # 10
|
||
("낙석방지책", "H2500×W2000(표준)", "후보", None), # 11
|
||
("낙석방지책", "H2500×W2000(단부)", "후보", None), # 12
|
||
("종자", "초본류", "후보", "MT006646"), # 13
|
||
("종자", "목본류", "후보", "MT006648"), # 14
|
||
("어닐링철선(결속선)", "#20 0.9mm 200.4m/kg", "이음", "MT000209"), # 15
|
||
("내수합판1급", "12mmx1220x2440", "이음", "MT000018"), # 16
|
||
("어닐링철선(결속선)", "#20 0.9M/M", "이음", "MT000209"), # 17
|
||
("유로폼(패널)", "600*1200", "이음", "MT000467"), # 18
|
||
("내부코너패널", "(200+200)*1200", "이음", "MT000472"), # 19
|
||
("합판(내수)", "12×1220×2440", "이음", "MT000018"), # 20
|
||
("조임철물", "(직교자재)", "이음", "MT000499"), # 21
|
||
("에폭시수지", "YD-128", "후보", None), # 22
|
||
("종자", "생태복원형,초본류", "후보", "MT006646"), # 23
|
||
("종자", "생태복원형,목본류", "후보", "MT006648"), # 24
|
||
("내부코너패널(유로폼)", "(100+200)*1200mm", "이음", "MT000470"), # 25
|
||
("유로폼(패널)", "600×1200", "이음", "MT000467"), # 26
|
||
("콘테이너하우스", "창고용(3.0m×6.0m×2.6m)", "이음", "MT007111"), # 27
|
||
("전기뇌관(MS)", "3.5m×500개(하이데토)", "이음", "MT005677"), # 28
|
||
("BUTTON BIT", "Ø38×76㎜", "후보", None), # 29
|
||
("유압드릴샹크", "T38×CM470", "후보", None), # 30
|
||
("유압식드릴스리브", "T38×190mm", "후보", "MT005687"), # 31
|
||
("미송(판재)", "", "후보", None), # 32
|
||
("산림종자", "참싸리(박피)", "이음", "MT006664"), # 33
|
||
("유기질퇴비", "", "후보", None), # 34
|
||
("PVC지수판", "200x5T KSM3805", "이음", "MT006544"), # 35
|
||
("PVC용접봉", "Ø3.2 (국산)", "후보", None), # 36
|
||
("PVC파이프(일반용VG2)", "50㎜ × 4m", "이음", "MT002926"), # 37
|
||
("혼합골재", "영월", "후보", None), # 38
|
||
("이형철근", "별도계상", "후보", None), # 39
|
||
("안전표지판", "삼각,D=900", "후보", "MT003202"), # 40
|
||
("표지판지주", "D=76.3mm, 3.5M", "후보", None), # 41
|
||
("블레이드(커터)", 'd=320 400mm 14"xt3.2', "이음", "MT005749"), # 42
|
||
("떼", "", "없음", None), # 43
|
||
("강관비계", "φ48.6m/m×2.3mm", "이음", "MT000481"), # 44
|
||
("철물", "", "후보", None), # 45
|
||
("각재(말뚝)", "Φ60", "후보", None), # 46
|
||
("강관써포트", "V4 2600-4000mm 14.3kg", "후보", None), # 47
|
||
("안고초", "", "이음", "MT006667"), # 48
|
||
("비수리", "", "이음", "MT006665"), # 49
|
||
("내수합판1급", "12m/m 1220×2440", "이음", "MT000018"), # 50
|
||
("각재(외송)", "3.6×3.0×3.0", "이음", "MT000393"), # 51
|
||
("내수합판1급", "12mm 1220×2440", "이음", "MT000018"), # 52
|
||
("각재(거푸집용,외송)", "3.6×3.0×3.0", "이음", "MT000393"), # 53
|
||
("다이아몬드톱날", 'Ø14"×3.2t(콘크리트용)', "후보", None), # 54
|
||
("아세틸렌", "용접용", "후보", "MT003163"), # 55
|
||
("산소", "고압가스", "이음", "MT003166"), # 56
|
||
("신나", "KSM6060 2종(조합페인트류)", "이음", "MT003398"), # 57
|
||
("초류종자(국내산)", "참싸리,비수리,낭아초등", "후보", None), # 58
|
||
("종 자", "초본형", "후보", "MT006646"), # 59
|
||
("소나무우드칩(멀칭재)", "", "후보", None), # 60
|
||
("3단코어비트", '5"(125mm)', "후보", None), # 61
|
||
("P V C PIPE", "Φ50M/M,VG1", "이음", "MT002861"), # 62
|
||
("콘테이너(창 고)", "3×6×2.6", "이음", "MT007111"), # 63
|
||
("강관비계", "48.6mm×2.3mm×6m", "후보", None), # 64
|
||
("철물", "직교자재", "이음", "MT000499"), # 65
|
||
("문양거푸집(ABS코팅품)", "600×1200", "이음", "MT000453"), # 66
|
||
("와이어매쉬", "#6 100×100", "이음", "MT007136"), # 67
|
||
("지수판", "T5×200", "이음", "MT006544"), # 68
|
||
("용접봉(연강용)", "3.2m/m", "후보", None), # 69
|
||
("어닐링철선 (결속선)", "#6 4.0mm 10.1m/kg", "후보", None), # 70
|
||
("구역화물자동차(4.5Ton)", "80km이내", "이음", "MT023493"), # 71
|
||
("구역화물자동차(4.5Ton)", "60km이내", "이음", "MT023491"), # 72
|
||
("산소(6000ℓ)", "99%,120kg/㎠", "이음", "MT003165"), # 73
|
||
("아세칠렌", "AC 98%,용접용", "이음", "MT003163"), # 74
|
||
("서비스볼트(고장력볼트)", "M20×60", "이음", "MT002536"), # 75
|
||
("보조강재(열연강판)", "T=9-12", "후보", None), # 76
|
||
("구역화물자동차(8Ton)", "10km이내", "이음", "MT023654"), # 77
|
||
("구역화물자동차(8Ton)", "20km이내", "이음", "MT023655"), # 78
|
||
("참싸리(박피)", "", "없음", None), # 79
|
||
("부산물비료", "20kg/포", "후보", None), # 80
|
||
("참싸리", "박피", "없음", None), # 81
|
||
("복합비료", "21-17-17 20kg/포", "이음", "MT006490"), # 82
|
||
("퇴비(천연부엽토)", "20㎏/포", "후보", None), # 83
|
||
("문양거푸집(ABS코팅폼)", "600×1200×20~30mm", "이음", "MT000453"), # 84
|
||
("P.V.C PIPE", "VG1(50mm)", "이음", "MT002861"), # 85
|
||
("다웰바(DOWEL BAR)", "Ø32×1,000", "이음", "MT006540"), # 86
|
||
("P.V.C PIPE", "VG1(35mm)", "이음", "MT002859"), # 87
|
||
("휠라", "T=15mm,1000×1000mm", "없음", None), # 88
|
||
("측구수로관", "300×300×2000×120,앵글포함", "이음", "MT015883"), # 89
|
||
("중하중그레이팅", "395×995×52", "후보", "MT007025"), # 90
|
||
("측구수로관", "500×500×2000×150,앵글포함", "이음", "MT015887"), # 91
|
||
("중하중그레이팅", "595×995×67", "후보", "MT007032"), # 92
|
||
("잔디", "0.18×0.18×0.01", "이음", "MT006796"), # 93
|
||
("강관비계", "4000×48.6mm×2.3mm", "이음", "MT000481"), # 94
|
||
("삼각표지판", "삼각,900mm", "후보", None), # 95
|
||
("표지판지주", "D=76.3mm×3.0m", "이음", "MT003241"), # 96
|
||
("공사안내표지판", "300×1500", "후보", None), # 97
|
||
("공사안전PE드럼", "500×800", "후보", "MT003311"), # 98
|
||
("윙카호스", "10cm", "후보", None), # 99
|
||
("조합페인트", "KSM6020 2급,백색", "이음", "MT003372"), # 100
|
||
]
|
||
|
||
|
||
def _link(name, spec):
|
||
key, mark = sl.m01("재료", {"이름": name, "규격": spec, "단위": "", "갈래": "재료"})
|
||
return key, mark, hrow.m01_picks("재료", {"이름": name, "규격": spec, "단위": ""})
|
||
|
||
|
||
@pytest.mark.parametrize("name,spec,want,key", TABLE)
|
||
def test_target_rows(name, spec, want, key):
|
||
got, _mark, picks = _link(name, spec)
|
||
if want == "이음":
|
||
assert got == key
|
||
else:
|
||
assert got is None
|
||
assert bool(picks) == (want == "후보")
|
||
if key:
|
||
assert picks[0]["키"] == key
|
||
|
||
|
||
def test_counts():
|
||
linked = sum(1 for *_x, w, _k in TABLE if w == "이음")
|
||
assert linked == 51
|
||
|
||
|
||
@pytest.mark.parametrize(
|
||
"name,spec,bad",
|
||
[
|
||
("용접봉(연강용)", "3.2m/m", "MT003195"), # 연강용 ↔ 주철용
|
||
("PVC용접봉", "Ø3.2 (국산)", "MT003195"), # PVC 용접봉 ↔ 용접봉
|
||
("어닐링철선 (결속선)", "#6 4.0mm 10.1m/kg", "MT000199"), # #6 ↔ #8
|
||
("잔디", "0.18×0.18×0.01", "MT019017"), # 0.01 ↔ 0.03
|
||
("표지판지주", "D=76.3mm, 3.5M", "MT003241"), # 3.5M ↔ 3000
|
||
("신나", "KSM6060 2종(조합페인트류)", "MT018835"), # 신나 ↔ 신나무
|
||
("강관비계", "48.6mm×2.3mm×6m", "MT000481"), # 6m ↔ 4.0m
|
||
],
|
||
)
|
||
def test_no_wrong_link(name, spec, bad):
|
||
got, _mark, picks = _link(name, spec)
|
||
assert got != bad
|
||
if name == "신나":
|
||
assert got == "MT003398" # 신너(조합페인트용)
|
||
|
||
|
||
def test_seed_narrow():
|
||
assert [x["자재"] for x in ms.narrow({"이름": "종자", "규격": "초본류"})][:3] == [
|
||
"MT006646",
|
||
"MT006647",
|
||
"MT006649",
|
||
]
|
||
|
||
|
||
def test_spec_forms():
|
||
assert ms.num_fit(ms._bag("3.6×3.0×3.0"), ms._bag("30×30×3600mm"))[0] == 2
|
||
assert ms.num_fit(ms._bag("T5×200"), ms._bag("200×5T"))[0] == 3
|
||
assert ms.num_fit(ms._bag("Ø32×1,000"), ms._bag("Φ32*1000"))[0] == 3
|
||
assert ms._item("PVC지수판", "200x5T KSM3805")["bag"] == ms._item("PVC지수판", "200×5T")["bag"]
|
||
assert ms._item("유로폼(패널)", "")["chars"] == ms._item("유로폼패널", "")["chars"]
|
||
assert ms._item("P.V.C PIPE", "")["core"] == ms._item("PVC파이프(일반관),서울", "")["core"]
|
||
assert ms._item("아세칠렌", "")["core"] == "아세틸렌"
|
||
|
||
|
||
def test_apart_mark():
|
||
key, mark, _ = _link("파형강관", "별도계상")
|
||
assert key is None and mark == f"{sl.NOTE}{sl.APART}"
|
||
assert (
|
||
sl.why({"자원": {"갈래": "재료", "이름": "철근(별도계상)", "규격": "별도계상"}}) == sl.APART
|
||
)
|
||
|
||
|
||
def test_why_shows_first():
|
||
got = sl.why({"자원": {"갈래": "재료", "이름": "종자", "규격": "초본류"}})
|
||
assert got == "자재 후보 여럿 — 고름 · 1 순위 종 자 초본위주형"
|