Files
Aislo/resources/tester/scratch/audit_page_boundary_overlaps.py
T

97 lines
5.1 KiB
Python

import os, sys, re
sys.stdout.reconfigure(encoding='utf-8')
target_files = [
# 02_토목부문
'resources/knowledge/original/원가계산/건설공사_표준품셈/02_토목부문/제1장_도로포장공사.md',
'resources/knowledge/original/원가계산/건설공사_표준품셈/02_토목부문/제2장_하천공사.md',
'resources/knowledge/original/원가계산/건설공사_표준품셈/02_토목부문/제3장_터널공사.md',
'resources/knowledge/original/원가계산/건설공사_표준품셈/02_토목부문/제4장_궤도공사.md',
'resources/knowledge/original/원가계산/건설공사_표준품셈/02_토목부문/제5장_강구조공사.md',
'resources/knowledge/original/원가계산/건설공사_표준품셈/02_토목부문/제6장_관부설및접합공사.md',
'resources/knowledge/original/원가계산/건설공사_표준품셈/02_토목부문/제7장_항만공사.md',
'resources/knowledge/original/원가계산/건설공사_표준품셈/02_토목부문/제8장_지반조사.md',
'resources/knowledge/original/원가계산/건설공사_표준품셈/02_토목부문/제9장_측량.md',
# 05_유지관리부문
'resources/knowledge/original/원가계산/건설공사_표준품셈/05_유지관리부문/제1장_공통.md',
'resources/knowledge/original/원가계산/건설공사_표준품셈/05_유지관리부문/제2장_토목.md',
'resources/knowledge/original/원가계산/건설공사_표준품셈/05_유지관리부문/제3장_건축.md',
'resources/knowledge/original/원가계산/건설공사_표준품셈/05_유지관리부문/제4장_기계설비.md',
# 04_기계설비부문 제13장
'resources/knowledge/original/원가계산/건설공사_표준품셈/04_기계설비부문/제13장_플랜트설비공사.md',
]
print("=== Scanning for Page Boundary Duplicate/Overlapped Rows ===")
page_markers = [
r'^\s*→\s*\d+',
r'^\s*\d+\s*[가-힣]+부문',
r'^\s*[가-힣]+부문\s*\d+',
r'^\s*제\d+장\s*[가-힣]+\s*\d+',
r'^\s*\d+\s*제\d+장',
r'^\s*→\s*$',
r'^\s*→[가-힣]+부문\d+',
]
page_regex = re.compile('|'.join(page_markers))
boundary_cases = []
for fpath in target_files:
fname = os.path.basename(fpath)
with open(fpath, 'r', encoding='utf-8') as f:
lines = f.readlines()
for idx, line in enumerate(lines):
line_str = line.strip()
if page_regex.search(line_str):
l_no = idx + 1
# Found page boundary at l_no
# Look at 30 lines before and 30 lines after
before_lines = [lines[i].strip() for i in range(max(0, idx-30), idx) if lines[i].strip().startswith('|')]
after_lines = [lines[i].strip() for i in range(idx+1, min(len(lines), idx+31)) if lines[i].strip().startswith('|')]
# Filter out divider lines
before_data = [l for l in before_lines if not all(re.match(r'^:?-+:?$', c) for c in [x.strip() for x in l.split('|')[1:-1]] if c)]
after_data = [l for l in after_lines if not all(re.match(r'^:?-+:?$', c) for c in [x.strip() for x in l.split('|')[1:-1]] if c)]
if not before_data or not after_data:
continue
# Check for duplicate rows or squashed rows between before and after
for b_idx, bl in enumerate(before_data):
b_cells = [c.strip() for c in bl.split('|')[1:-1]]
b_nums = set(re.findall(r'\b\d+(?:\.\d+)?\b', bl))
b_words = set(re.findall(r'[가-힣A-Za-z0-9]+', bl))
for a_idx, al in enumerate(after_data):
a_cells = [c.strip() for c in al.split('|')[1:-1]]
# 1. Exact match
if b_cells == a_cells and len([c for c in b_cells if c not in ["", "-", "〃"]]) >= 2:
boundary_cases.append({
'file': fname,
'boundary_line': l_no,
'marker': line_str,
'type': 'exact_match_across_boundary',
'before_row': bl[:80],
'after_row': al[:80]
})
# 2. After row contains multiple before rows (squashed overlap)
a_words = set(re.findall(r'[가-힣A-Za-z0-9]+', al))
a_nums = set(re.findall(r'\b\d+(?:\.\d+)?\b', al))
if len(b_nums) >= 2 and b_nums.issubset(a_nums) and len(b_words.intersection(a_words)) >= 2:
boundary_cases.append({
'file': fname,
'boundary_line': l_no,
'marker': line_str,
'type': 'squashed_overlap_across_boundary',
'before_row': bl[:80],
'after_row': al[:80]
})
print(f"Total boundary cases found: {len(boundary_cases)}")
for bc in boundary_cases:
print(f"[{bc['file']}:L{bc['boundary_line']}] {bc['marker']} - {bc['type']}")
print(f" Before: {bc['before_row']}")
print(f" After: {bc['after_row']}")