124 lines
4.5 KiB
Python
124 lines
4.5 KiB
Python
import json
|
|
import sys
|
|
import re
|
|
from pathlib import Path
|
|
|
|
sys.stdout.reconfigure(encoding='utf-8')
|
|
|
|
# Load MD
|
|
with open("resources/knowledge/original/행정규칙/임도 품셈 적용기준 (현 산림사업 표준품셈)/첨부/(산림청고시 제2025-82호) 산림사업 표준품셈.md", "r", encoding="utf-8") as f:
|
|
md_lines = f.readlines()
|
|
|
|
# Load Master
|
|
with open('resources/data_work_item_master/work_item_master_2026-01-01.json', 'r', encoding='utf-8') as f:
|
|
master = json.load(f)
|
|
|
|
sys.path.insert(0, str(Path(__file__).parent.parent))
|
|
from scratch.enrich_tables import tables, get_chapter
|
|
|
|
# Map master tables
|
|
master_tables = {}
|
|
wi_of_table = {}
|
|
for wi in master['work_items']:
|
|
for t in wi.get('tables', []):
|
|
tid = t.get('pum_table_id')
|
|
if tid:
|
|
master_tables[tid] = t
|
|
wi_of_table[tid] = wi
|
|
|
|
for t in master.get('orphan_tables', []):
|
|
tid = t.get('pum_table_id')
|
|
if tid:
|
|
master_tables[tid] = t
|
|
|
|
# Patterns for basis in pre_context:
|
|
# e.g., "[100㎡ 당]", "[10a 당]", "[100m 당]", "[10㎥ 당]", "[본당]", "[1공당]", "[개소당]", "[1m3 당]"
|
|
# Also patterns in table header or first line
|
|
basis_pattern = re.compile(r'\[\s*([0-9\.\,]*)\s*([a-zA-Z㎡㎥㏊ha본개공mkm㎏gtonLℓ대인組]+)\s*당\s*\]')
|
|
basis_pattern2 = re.compile(r'\(단위\s*:\s*([^\)]+)\)')
|
|
|
|
basis_audit = []
|
|
|
|
for i, t in enumerate(tables):
|
|
tid = t['table_id']
|
|
chapter = t['chapter']
|
|
pre_lines = t['pre_context']
|
|
|
|
# 1. Search pre-context for basis
|
|
found_basis_qty = None
|
|
found_basis_unit = None
|
|
found_basis_src = None
|
|
|
|
# Search backwards in pre_lines
|
|
for pl in reversed(pre_lines):
|
|
m = basis_pattern.search(pl)
|
|
if m:
|
|
qty_str = m.group(1).replace(',', '').strip()
|
|
found_basis_qty = float(qty_str) if qty_str else 1.0
|
|
found_basis_unit = m.group(2).strip()
|
|
found_basis_src = f"pre_context: '{pl}'"
|
|
break
|
|
m2 = basis_pattern2.search(pl)
|
|
if m2:
|
|
u = m2.group(1).strip()
|
|
found_basis_qty = 1.0
|
|
found_basis_unit = u
|
|
found_basis_src = f"unit_parenthesis: '{pl}'"
|
|
break
|
|
|
|
# 2. Search table header cells
|
|
header_line = t['lines'][0] if t['lines'] else ""
|
|
# Look for "단위수량", "단위", etc.
|
|
|
|
# 3. Compare with master
|
|
mt = master_tables.get(tid)
|
|
if not mt:
|
|
continue
|
|
|
|
m_qty = mt.get('basis_quantity')
|
|
m_unit = mt.get('basis_unit')
|
|
pform = mt.get('pum_form')
|
|
|
|
# Check if MD has explicit basis but master is None or different
|
|
if found_basis_unit is not None:
|
|
if m_unit is None or m_qty is None:
|
|
basis_audit.append({
|
|
'table_id': tid,
|
|
'chapter': chapter,
|
|
'line': t['start_line'],
|
|
'section': t['section'],
|
|
'pum_form': pform,
|
|
'issue': 'MD_HAS_BASIS_MASTER_MISSING',
|
|
'md_qty': found_basis_qty,
|
|
'md_unit': found_basis_unit,
|
|
'md_src': found_basis_src,
|
|
'master_qty': m_qty,
|
|
'master_unit': m_unit
|
|
})
|
|
elif m_qty != found_basis_qty or m_unit != found_basis_unit:
|
|
# Check unit normalization (e.g. ㎡ vs m2)
|
|
if not (str(found_basis_qty) == str(m_qty) and found_basis_unit.replace('㎡','m2').replace('㎥','m3') == m_unit.replace('㎡','m2').replace('㎥','m3')):
|
|
basis_audit.append({
|
|
'table_id': tid,
|
|
'chapter': chapter,
|
|
'line': t['start_line'],
|
|
'section': t['section'],
|
|
'pum_form': pform,
|
|
'issue': 'BASIS_MISMATCH',
|
|
'md_qty': found_basis_qty,
|
|
'md_unit': found_basis_unit,
|
|
'md_src': found_basis_src,
|
|
'master_qty': m_qty,
|
|
'master_unit': m_unit
|
|
})
|
|
|
|
print(f"Total Basis issues identified: {len(basis_audit)}")
|
|
from collections import Counter
|
|
print("By issue type:", Counter(b['issue'] for b in basis_audit))
|
|
print("By chapter:", Counter(b['chapter'] for b in basis_audit))
|
|
|
|
print("\n--- Sample Basis Issues (First 15) ---")
|
|
for b in basis_audit[:15]:
|
|
print(f"[{b['table_id']} | Line {b['line']}] {b['chapter']} | {b['section']}")
|
|
print(f" MD: {b['md_qty']} {b['md_unit']} ({b['md_src']}) vs Master: {b['master_qty']} {b['master_unit']} (form: {b['pum_form']})")
|