"""338-1 엑셀 지문(`M02_Hopyo_Finger` · `_Words` · `_Shares`) — 식 풀기 일곱 꼴 · 합판 지문 · 고임돌 섞음 · 몫 · STmate 자원 · 기계 줄 · 직접 줄 호표. 실물 = 북부청 임도(읽기만).""" import pytest from M02_MasterTemplete import M02_Hopyo_Finger as finger from M02_MasterTemplete import M02_Hopyo_Shares as shares from M02_MasterTemplete.M02_Hopyo_Words import conds, mtypes, parse_rhs from resources.tester.helper_m02_hopyo_golden import line_of approx = pytest.approx # ── 식 풀기 ──────────────────────────────────────────────────────────── def test_식_단가_떼고_품(): got = parse_rhs("273,540 × 3인 ÷ 55㎥ × 2 = 29,840.7") assert got["단가"] == 273540 and got["품"] == approx(0.10909, abs=1e-5) and got["율"] == [] def test_식_퍼센트_율(): got = parse_rhs("59,020 ÷ 23.1 × 90% = 2,299.5") assert got["품"] == approx(0.03896, abs=1e-5) assert got["밑품"] == approx(1 / 23.1) and got["율"] == [[0.9, "%"]] def test_식_인당_단위_섞음(): got = parse_rhs("172,068 × 0.3인/㎥ × 10% = 5,162") assert got["품"] == approx(0.03) and got["밑품"] == approx(0.3) def test_식_바꿔_쓴_식은_앞_율을_이어받음(): got = parse_rhs("215,907 × 4인 ÷ P × 1.2(할증) = 215,907 × 0.104 × 1.2 = 26,945") assert got["품"] == approx(0.1248) and got["밑품"] == approx(0.104) assert got["율"] == [[1.2, "할증"]] def test_식_횟수_품할증(): got = parse_rhs("172,068 × 0.05인 × 2회 = 17,206") assert got["품"] == approx(0.1) and got["밑품"] == approx(0.05) and got["율"] == [[2.0, "회"]] got = parse_rhs("273,540 × 0.1 × 1.2(품할증) = 32,824") assert got["밑품"] == approx(0.1) and got["율"] == [[1.2, "품할증"]] def test_식_못_풀면_역산(): assert parse_rhs("273,540 × P = 30,000") is None block = {"번": 1, "이름": "시험", "단위": "㎥", "글": [" 특별인부 : 273,540 × P = 27,354"]} fp = finger.excel(block, {"이름": "시험", "규격": "", "단위": "㎥"}) assert fp["인력"]["특별인부"]["품"] == approx(0.1) and fp["인력"]["특별인부"]["어떻게"] == [ "역산" ] def test_장비_갈래_조건_낱말(): assert mtypes("유압식 백호우 0.7㎥") == {"굴착기"} and mtypes("펌프카 41m") == {"콘크리트펌프"} assert conds("합판거푸집 4회 보통")["횟수"] == {"4회"} assert conds("구조물터파기(암)")["토질"] == {"암"} # ── 실물 지문 ────────────────────────────────────────────────────────── def test_합판_4회_지문(): block, line = line_of("N001") fp = finger.excel(block, line) assert fp["인력"]["형틀목공"]["품"] == approx(0.1111, abs=1e-4) assert fp["인력"]["보통인부"]["품"] == approx(0.0444, abs=1e-4) assert "4회" in fp["조건"]["횟수"] and fp["출처"] == [["건설품셈", "6-3-1"]] assert {m["이름"][:4] for m in fp["자재"] if m["품"]} >= {"내수합판"} def test_레미콘_소량_지문_장비_시간(): block, line = line_of("N000") fp = finger.excel(block, line) assert fp["인력"]["콘크리트공"]["품"] == approx(0.10909, abs=1e-5) assert [(m["갈래"], round(m["시간"], 2)) for m in fp["장비"]] == [(["굴착기"], 0.29)] def test_고임돌_섞음_율과_몫(): block, line = line_of("N005") fp = finger.excel(block, line) labor = fp["인력"]["보통인부"] assert labor["밑품"] == approx(0.3, abs=1e-3) and labor["품"] == approx(0.03, abs=1e-3) assert any(note in ("%", "섞음") and v == approx(0.1) for v, note in labor["율"]) parts = fp["몫"] assert any(p["노임"] and not p["장비"] for p in parts) # 인력 몫 assert any(p["장비"] and not p["노임"] for p in parts) # 장비 몫 def test_몫_절마다_노임_장비(): texts = [ " 1. 굴착기 0.6㎥ 채집(90%)", " 노무비 : 59,020 ÷ 23.1 × 90% = 2,299", " 2. 인력채집(10%)", " 보통인부 : 172,068 × 0.3인/㎥ × 10% = 5,162", " 3. 합 계", " 보통인부 : 172,068 × 1 = 172,068", ] parts = shares.sections(texts) assert [p["제목"] for p in parts] == ["굴착기 0.6㎥ 채집(90%)", "인력채집(10%)"] assert parts[0]["장비"] == {"굴착기|0.6": approx(0.9 / 23.1)} assert parts[1]["노임"] == {"보통인부": approx(0.03)} def test_STmate_자원_지문(): block = { "글": ["잔토처리 (기계100%) 건설표준품셈9-3", "q = 0.7 , K = 0.9"], "자원": [ {"갈래": "L", "코드": "L00002", "이름": "보통인부", "규격": "", "품": 0.2}, *[ { "갈래": "X", "코드": "X00205", "이름": "굴삭기(무한궤도)", "규격": "0.7㎥", "품": 0.0229, } ] * 3, {"갈래": "M", "코드": "M00001", "이름": "모래", "규격": "", "품": 1.2}, ], } fp = finger.excel(block, {"이름": "잔토처리", "규격": "토사", "단위": "M3"}) assert fp["인력"] == {"보통인부": {"품": 0.2, "밑품": 0.2, "율": [], "어떻게": ["QTY"]}} assert [(m["갈래"], m["규격"], m["시간"]) for m in fp["장비"]] == [(["굴착기"], [0.7], 0.0229)] assert fp["자재"] == [{"이름": "모래", "품": 1.2, "밑품": 1.2}] and fp["계수"]["K"] == 0.9 def test_기계_줄_블록_없음(): fp = finger.excel(None, {"이름": "콘크리트 펌프차", "규격": "41m,80~95㎥/hr", "단위": "hr"}) assert [(m["갈래"], m["시간"]) for m in fp["장비"]] == [(["콘크리트펌프"], 1.0)] assert 41.0 in fp["장비"][0]["규격"] and fp["인력"] == {} def test_직접_줄_호표(): hopyo = { "이름": "돌붙임", "규격": "", "단위": "㎡", "줄": [ {"이름": "석 공", "규격": "", "수량": 0.1, "단위": "인", "갈래": "기타"}, {"이름": "보통인부", "규격": "", "수량": 0.05, "단위": "인", "갈래": "기타"}, {"이름": "굴착기", "규격": "0.6㎥", "수량": 0.2, "단위": "hr", "갈래": "기계"}, ], } fp = finger.direct(hopyo) assert fp["인력"]["석공"]["품"] == 0.1 and fp["인력"]["보통인부"]["품"] == 0.05 assert [(m["갈래"], m["시간"]) for m in fp["장비"]] == [(["굴착기"], 0.2)] assert finger.direct({**hopyo, "줄": hopyo["줄"][2:]}) is None # 노임 없으면 호표 통째 아님