From 32140059f25d1be517aa0b5455d590d99b3c48de Mon Sep 17 00:00:00 2001 From: umsangdon Date: Fri, 18 Sep 2026 03:50:04 +0900 Subject: [PATCH] =?UTF-8?q?feat(b08):=20=EB=AF=B8=ED=8C=90=EB=8F=85=2012?= =?UTF-8?q?=20=E2=86=92=209=20=E2=80=94=20=EB=B6=84=EB=AA=A8=EA=B0=80=20?= =?UTF-8?q?=EB=98=90=EB=A0=B7=ED=95=9C=20=EC=85=8B=20=EC=B1=84=EC=9B=80(?= =?UTF-8?q?=E3=80=8Cha=EB=8B=B9=20=EC=86=8C=EC=9A=94=EB=9F=89=E3=80=8D?= =?UTF-8?q?=C2=B7=E3=80=8C=EC=A1=B0/ha=EB=8B=B9=E3=80=8D)=20=C2=B7=20?= =?UTF-8?q?=ED=99=95=EB=B3=B4=20246?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 브레인 3바퀴 차례 ③. 미판독 열둘을 원문에서 하나씩 열어 봄. - **채운 셋** — F0050·F0052 페인트·마킹테이프 「재료비 (ha당 소요량)」 · F0224 페르몬 유인트랩 「소요인력(조/ha당)」. 다 **1ha당**. 밑수 확보 243 → 246 · 미확보 87 → 84 ⚠ 자동 판정을 넓히지 않고 표마다 적음 — 숫자 없는 「<단위>당」을 받으면 규격 칸 (「(무한궤도,0.7㎥)」)이 밑수로 둔갑함(옛날에 다섯 건 걸렸던 병) - **안 채운 아홉은 다 거절 자리** — 「(단위 : 인)」 셋은 2026-09-09 오독 판정 자리(8-6-2·8-6-3) · 「㎥/1인/1일」·「1ha당, 100본당」·「1대 1조, 시간당」·「인 당」은 분모가 둘 이상 - **더하기만** — 원문 셀 453/453 그대로 · 밑수 바뀐 표 셋 다 빈칸에서 참 - ⭐ reference 는 재검사에서 **오분류 0** 으로 닫힘(실값 13 옮김 · 설계 규격표 14 유지) ⬜ **브레인 판정 하나 — [주] 낱말 뜻이 갈림**(마스터가 더 가진 17건) md 쪽 읽기는 이어짐을 `- ①②`·`- -`·`※*·` 로만 보아 「- 4. 고철공제 : A=1㎥×0.008×…」 같은 **번호 달린 규칙**에서 끊음. 마스터는 그것을 [주]로 봄. ⚠ md 규칙을 그대로 쓰면 **2바퀴에서 잘렸다가 3바퀴에 되살린 고철 공제 50kg/㎥ 가 다시 사라짐.** 그래서 마스터를 안 깎고 장부에 사유와 함께 적어 둠 Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01QsGw1Dz9HmhuAxGisxmDPF --- ...B08_Quantity_Build_WorkItemMaster_Forms.py | 8 +++++ .../data_master_labels/labels_2026-01-01.json | 2 +- .../data_work_item_master/_manifest.json | 10 +++---- .../_manifest_const.json | 4 +-- .../basis_missing_2026-01-01.json | 21 ------------- .../const_work_item_master_2026-01-01.json | 2 +- .../work_item_master_2026-01-01.json | 26 ++++++++-------- .../work_item_master_source_known.json | 30 ++----------------- .../tester/test_work_item_key_registry.py | 11 +++++-- 9 files changed, 40 insertions(+), 74 deletions(-) diff --git a/B08_Quantity/B08_Quantity_Build_WorkItemMaster_Forms.py b/B08_Quantity/B08_Quantity_Build_WorkItemMaster_Forms.py index 353df302..629a41a2 100644 --- a/B08_Quantity/B08_Quantity_Build_WorkItemMaster_Forms.py +++ b/B08_Quantity/B08_Quantity_Build_WorkItemMaster_Forms.py @@ -276,6 +276,14 @@ BASIS_JUDGMENTS: dict[str, tuple[str, float, str, str]] = { # ⚠ 「공㎥」(공간체적)는 자동 판정의 단위 목록에 없어 못 읽던 자리 — 원문 L6634 「(단위: 공㎥당)」. # 단위 목록을 넓히면 규격 칸이 밑수로 둔갑하므로, 이 표만 사람 판정으로 둔다(2026-09-18). "F0366": ("12-19", 1.0, "공㎥", "강관비계 — 원문 「(단위: 공㎥당)」"), + # ── 미판독 12 가운데 **분모가 하나로 또렷한 셋** (2026-09-18) ──────────────────── + # ⚠ 자동 판정을 넓히지 않고 표마다 적는다 — 「ha당 소요량」·「조/ha당」 꼴을 규칙으로 잡으려면 + # 숫자 없는 「<단위>당」을 받아야 하는데, 그러면 규격 칸(「(무한궤도,0.7㎥)」)이 밑수로 둔갑한다. + # 나머지 아홉은 안 채운다 — 「(단위 : 인)」 셋은 2026-09-09 오독 판정 자리이고, + # 「㎥/1인/1일」·「1ha당, 100본당」·「1대 1조, 시간당」·「인 당」은 분모가 둘 이상이다. + "F0050": ("2-1-4", 1.0, "ha", "페인트·마킹테이프 — 표머리 「재료비 (ha당 소요량)」"), + "F0052": ("2-1-4", 1.0, "ha", "위와 같음(다른 표)"), + "F0224": ("8-5", 1.0, "ha", "페르몬 유인트랩 — 표머리 「소요인력(조/ha당)」"), } diff --git a/resources/data_master_labels/labels_2026-01-01.json b/resources/data_master_labels/labels_2026-01-01.json index 70a3527e..366ea7a3 100644 --- a/resources/data_master_labels/labels_2026-01-01.json +++ b/resources/data_master_labels/labels_2026-01-01.json @@ -6363,7 +6363,7 @@ "name_ko": "밑수 못 찾은 표", "summary": "기준 수량을 못 읽은 품셈 표. 1 단위당으로 단정하면 곱셈이 틀린다.", "shape": "list", - "rows": 87, + "rows": 84, "columns": [ { "key": "pum_table_id", diff --git a/resources/data_work_item_master/_manifest.json b/resources/data_work_item_master/_manifest.json index 1ad71315..4332766d 100644 --- a/resources/data_work_item_master/_manifest.json +++ b/resources/data_work_item_master/_manifest.json @@ -1,7 +1,7 @@ { "schema_version": "1.0", "dataset_id": "data_work_item_master_manifest", - "generated_at": "2026-09-18T03:14:14+09:00", + "generated_at": "2026-09-18T03:43:54+09:00", "built_by": "B08_Quantity/B08_Quantity_Build_WorkItemMaster.py", "source": { "dataset_id": "pum_forest", @@ -12,8 +12,8 @@ "files": [ { "file": "work_item_master_2026-01-01.json", - "sha256": "574ac7c0556ed514838bef6f592097b66217df008b72770a226210c600937509", - "size_bytes": 1081351 + "sha256": "4e3a9d45776274099c58effe1dec29b4ccc22d7704d6652e4fcda8911807928a", + "size_bytes": 1081560 }, { "file": "form_undetermined_2026-01-01.json", @@ -22,8 +22,8 @@ }, { "file": "basis_missing_2026-01-01.json", - "sha256": "63895255047e849f5d70a1ab6551839d551d9e09609a8b32d487cfdb53892bf9", - "size_bytes": 20017 + "sha256": "194ccc0066b9b91fdaf91973bb4fe13305c6e073ecf5b99b8d04f3d8350d85e9", + "size_bytes": 19381 } ] } \ No newline at end of file diff --git a/resources/data_work_item_master/_manifest_const.json b/resources/data_work_item_master/_manifest_const.json index ba21db16..2f53ba9b 100644 --- a/resources/data_work_item_master/_manifest_const.json +++ b/resources/data_work_item_master/_manifest_const.json @@ -1,7 +1,7 @@ { "schema_version": "1.0", "dataset_id": "data_work_item_master_manifest", - "generated_at": "2026-09-18T03:15:03+09:00", + "generated_at": "2026-09-18T03:44:44+09:00", "built_by": "B08_Quantity/B08_Quantity_Build_WorkItemMaster.py", "source": { "dataset_id": "pum_const", @@ -12,7 +12,7 @@ "files": [ { "file": "const_work_item_master_2026-01-01.json", - "sha256": "6b9d3bde5af18ab00abb07f379b0700cca5ab75c52f21a366b287be09e3e9fe5", + "sha256": "91239832a71e6bcf6560a9570dec049fc323ce5630afcc7c986292bfa4dd9e91", "size_bytes": 4501303 }, { diff --git a/resources/data_work_item_master/basis_missing_2026-01-01.json b/resources/data_work_item_master/basis_missing_2026-01-01.json index c6522fd5..47bf2ad0 100644 --- a/resources/data_work_item_master/basis_missing_2026-01-01.json +++ b/resources/data_work_item_master/basis_missing_2026-01-01.json @@ -18,20 +18,6 @@ "line": 1328, "why": "원문 부재 — 원문에 밑수가 아예 없음(채우면 지어내는 꼴)" }, - { - "pum_table_id": "F0050", - "section": "2-1-4. 페인트 및 마킹테이프", - "pum_form": "requirement", - "line": 1417, - "why": "미판독 — 원문이 적었는데 우리가 못 읽음" - }, - { - "pum_table_id": "F0052", - "section": "2-1-4. 페인트 및 마킹테이프", - "pum_form": "requirement", - "line": 1444, - "why": "미판독 — 원문이 적었는데 우리가 못 읽음" - }, { "pum_table_id": "F0057", "section": "2-1-7. 소각, 매몰, 훈증, 박피", @@ -459,13 +445,6 @@ "line": 4364, "why": "원문 부재 — 원문에 밑수가 아예 없음(채우면 지어내는 꼴)" }, - { - "pum_table_id": "F0224", - "section": "8-5. 페르몬 유인트랩", - "pum_form": "requirement", - "line": 4450, - "why": "미판독 — 원문이 적었는데 우리가 못 읽음" - }, { "pum_table_id": "F0228", "section": "8-6-2. 드론방제", diff --git a/resources/data_work_item_master/const_work_item_master_2026-01-01.json b/resources/data_work_item_master/const_work_item_master_2026-01-01.json index c86ebb75..8294fc63 100644 --- a/resources/data_work_item_master/const_work_item_master_2026-01-01.json +++ b/resources/data_work_item_master/const_work_item_master_2026-01-01.json @@ -4,7 +4,7 @@ "effective_date": "2026-01-01", "pum_edition": "2026-01-01", "toc_edition": "2026-01-01", - "generated_at": "2026-09-18T03:15:03+09:00", + "generated_at": "2026-09-18T03:44:44+09:00", "dataset_version": { "dataset_id": "pum_const", "effective_date": "2026-01-01", diff --git a/resources/data_work_item_master/work_item_master_2026-01-01.json b/resources/data_work_item_master/work_item_master_2026-01-01.json index af8dcf65..b4c093e2 100644 --- a/resources/data_work_item_master/work_item_master_2026-01-01.json +++ b/resources/data_work_item_master/work_item_master_2026-01-01.json @@ -4,7 +4,7 @@ "effective_date": "2026-01-01", "pum_edition": "2026-01-01", "toc_edition": "산림청고시제2025-82호", - "generated_at": "2026-09-18T03:14:14+09:00", + "generated_at": "2026-09-18T03:43:54+09:00", "dataset_version": { "dataset_id": "pum_forest", "effective_date": "2026-01-01", @@ -25,10 +25,10 @@ "tables_attached": 453, "tables_orphan": 22, "form_undetermined": 0, - "basis_found": 243, - "basis_missing": 87, + "basis_found": 246, + "basis_missing": 84, "basis_absent_in_source": 75, - "basis_unparsed": 12, + "basis_unparsed": 9, "basis_grouped": 57, "axis_roles": { "general_provision": 78, @@ -4830,9 +4830,9 @@ "source_line": 1417, "pum_form": "requirement", "form_basis": "'소요량'", - "basis_quantity": null, - "basis_unit": null, - "basis_source": null, + "basis_quantity": 1.0, + "basis_unit": "ha", + "basis_source": "사람 판정 — 페인트·마킹테이프 — 표머리 「재료비 (ha당 소요량)」", "resource_shares": {}, "partial_ratio": false, "expression_cells": [], @@ -4916,9 +4916,9 @@ "source_line": 1444, "pum_form": "requirement", "form_basis": "'소요량'", - "basis_quantity": null, - "basis_unit": null, - "basis_source": null, + "basis_quantity": 1.0, + "basis_unit": "ha", + "basis_source": "사람 판정 — 위와 같음(다른 표)", "resource_shares": {}, "partial_ratio": false, "expression_cells": [], @@ -20571,9 +20571,9 @@ "source_line": 4450, "pum_form": "requirement", "form_basis": "직종 표기((인)·인부·공)", - "basis_quantity": null, - "basis_unit": null, - "basis_source": null, + "basis_quantity": 1.0, + "basis_unit": "ha", + "basis_source": "사람 판정 — 페르몬 유인트랩 — 표머리 「소요인력(조/ha당)」", "resource_shares": {}, "partial_ratio": false, "expression_cells": [], diff --git a/resources/tester/fixtures/work_item_master_source_known.json b/resources/tester/fixtures/work_item_master_source_known.json index d2b169a0..57f49f80 100644 --- a/resources/tester/fixtures/work_item_master_source_known.json +++ b/resources/tester/fixtures/work_item_master_source_known.json @@ -18,7 +18,8 @@ "notes 2026-09-18 — 마스터가 더 가진 쪽 — 인용 산출예시 뒤·별표 줄·긴 표의 [주] 를 마스터는 읽고 md 쪽 추출은 아직 끊긴다.", "form 2026-09-18 — 표 성격 — 사람 판정이 자동 판정을 이긴 자리.", "form_blind 2026-09-18 — 표 성격을 시험이 못 가리는 자리 — 사람 판정으로 둔다.", - "cost_rule 2026-09-18 — 비목 구성표 — 2026-09-18 에 `sub_requirement`(값은 실값 · 자리는 상위 공종 종속)로 가름. `requirement` 면 상위 공종이 이미 세는 몫을 두 번 세고 `reference` 면 금액이 0원 증발한다." + "cost_rule 2026-09-18 — 비목 구성표 — 2026-09-18 에 `sub_requirement`(값은 실값 · 자리는 상위 공종 종속)로 가름. `requirement` 면 상위 공종이 이미 세는 몫을 두 번 세고 `reference` 면 금액이 0원 증발한다.", + "⬜ **낱말 뜻이 갈린 자리** — 마스터가 더 가진 쪽(master_only) 17건. md 쪽 읽기는 이어짐을 `- ①②` · `- -` · `※*·` 로만 보아 「- 4. 고철공제 : A=1㎥×0.008×…」 같은 **번호 달린 규칙**에서 끊는다. 마스터는 그것을 [주]로 본다. ⚠ md 규칙을 그대로 쓰면 **2바퀴에서 잘렸다가 3바퀴에 되살린 고철 공제 50kg/㎥ 가 다시 사라진다.** 어느 쪽이 [주]인지는 브레인 판정 자리 (2026-09-18 데스크탑 서브)." ], "place": { "F0452": { @@ -47,24 +48,6 @@ "인" ] }, - "F0050": { - "section": "2-1-4", - "md": [ - 1.0, - "ha" - ], - "md_evidence": "표머리 재료비 (ha당 소요량)", - "master": null - }, - "F0052": { - "section": "2-1-4", - "md": [ - 1.0, - "ha" - ], - "md_evidence": "표머리 재료비 (ha당 소요량)", - "master": null - }, "F0068": { "section": "2-2-5", "md": null, @@ -165,15 +148,6 @@ "md_evidence": "(대/ton)", "master": null }, - "F0224": { - "section": "8-5", - "md": [ - 1.0, - "ha" - ], - "md_evidence": "표머리 소요인력(조/ha당)", - "master": null - }, "F0225": { "section": "8-6-1", "md": null, diff --git a/resources/tester/test_work_item_key_registry.py b/resources/tester/test_work_item_key_registry.py index 5ad70ee0..d45a106f 100644 --- a/resources/tester/test_work_item_key_registry.py +++ b/resources/tester/test_work_item_key_registry.py @@ -61,7 +61,7 @@ MASTER = OUT_DIR / "work_item_master_2026-01-01.json" #: 2026-09-17 랩탑 메인 둘째 — 헛단위 뺌(인용을 제목으로 읽은 13-3 표 셋 · 부록 사례 번호 겹침 일곱)으로 다시 뜸 #: (옛 be88f730…). 바뀐 줄은 13-3·4-1·4-2·2-1·2-2·3-1·3-2·3-3·13-4-1·13-5-2 의 표 귀속뿐 — #: `test_work_item_master_toc` 가 자리를 잼 · 단가표 대조는 그 파일 머리. -BASELINE_WORK_ITEMS_SHA = "fc3bb5efdc1f1a954f1054543807b7acf78c8f9ea954be4ffcdfdf14fbe7d9c2" +BASELINE_WORK_ITEMS_SHA = "8d438798609b2a80a269c983448f107a0a176202c5e26c80d84b68116f5fdd66" #: 열쇠 작업이 새로 얹은 칸. 지문을 잴 때만 떼어낸다. ADDED_FIELDS = ( @@ -469,9 +469,12 @@ def test_밑수_미확보를_둘로_가른다(master: dict) -> None: from pathlib import Path as _Path stats = master["stats"] - assert stats["basis_missing"] == 87 + assert stats["basis_missing"] == 84 assert stats["basis_absent_in_source"] == 75 - assert stats["basis_unparsed"] == 12 + # 2026-09-18 미판독 12 → 9 — 분모가 하나로 또렷한 셋(「ha당 소요량」·「조/ha당」)을 채움. + # ⚠ 남은 아홉은 **거절 자리**다 — 「(단위 : 인)」 셋(2026-09-09 오독 판정) · + # 「㎥/1인/1일」·「1ha당, 100본당」·「1대 1조, 시간당」·「인 당」은 분모가 둘 이상이다. + assert stats["basis_unparsed"] == 9 assert stats["basis_absent_in_source"] + stats["basis_unparsed"] == stats["basis_missing"] items = _json.loads( _Path("resources/data_work_item_master/basis_missing_2026-01-01.json").read_text( @@ -482,6 +485,8 @@ def test_밑수_미확보를_둘로_가른다(master: dict) -> None: # 「공㎥」 처럼 단위 목록에 없던 자리는 사람 판정으로 채웠다 — 목록을 넓히면 규격이 밑수가 된다 by_id = {t["pum_table_id"]: t for it in master["work_items"] for t in it["tables"]} assert by_id["F0366"]["basis_unit"] == "공㎥" + for table_id in ("F0050", "F0052", "F0224"): + assert by_id[table_id]["basis_quantity"] == 1.0 and by_id[table_id]["basis_unit"] == "ha" def test_원문_대조_밑수_판정(master: dict) -> None: