94 lines
3.9 KiB
Python
94 lines
3.9 KiB
Python
import os, sys, re, json
|
|
|
|
sys.stdout.reconfigure(encoding='utf-8')
|
|
|
|
base_dir = "resources/knowledge/original/원가계산/건설공사_표준품셈"
|
|
|
|
all_md_files = []
|
|
for root, dirs, files in os.walk(base_dir):
|
|
for f in files:
|
|
if f.endswith('.md') and not f.startswith('_') and '개정사항' not in f and '2026년_건설공사_표준품셈.md' not in f:
|
|
if '01_공통부문\\제8장' in os.path.join(root, f) or '01_공통부문/제8장' in os.path.join(root, f):
|
|
continue
|
|
all_md_files.append(os.path.join(root, f))
|
|
|
|
# Also add merged file
|
|
all_md_files.append(os.path.join(base_dir, "2026년_건설공사_표준품셈.md"))
|
|
|
|
print(f"Auditing {len(all_md_files)} files for 2 flaws...")
|
|
|
|
header_divider_mismatches = []
|
|
spec_3row_shift_candidates = []
|
|
|
|
for fpath in all_md_files:
|
|
rel_path = os.path.relpath(fpath, base_dir)
|
|
with open(fpath, 'r', encoding='utf-8') as f:
|
|
lines = f.readlines()
|
|
|
|
in_table = False
|
|
header_rows = []
|
|
divider_cols = 0
|
|
divider_line = 0
|
|
|
|
for idx, line in enumerate(lines):
|
|
line_num = idx + 1
|
|
line_str = line.strip()
|
|
|
|
if line_str.startswith('|') and line_str.endswith('|'):
|
|
cells = [c.strip() for c in line_str.split('|')[1:-1]]
|
|
|
|
# Check if this is a divider row
|
|
if all(re.match(r'^:?-+:?$', c) for c in cells if c):
|
|
divider_cols = len(cells)
|
|
divider_line = line_num
|
|
# Check preceding header row
|
|
if header_rows:
|
|
last_hdr = header_rows[-1]
|
|
if len(last_hdr['cells']) != divider_cols:
|
|
header_divider_mismatches.append({
|
|
"file": rel_path,
|
|
"line": divider_line,
|
|
"header_line": last_hdr['line'],
|
|
"header_cols": len(last_hdr['cells']),
|
|
"divider_cols": divider_cols,
|
|
"header_snippet": last_hdr['snippet']
|
|
})
|
|
in_table = True
|
|
elif not in_table:
|
|
header_rows.append({
|
|
"line": line_num,
|
|
"cells": cells,
|
|
"snippet": line_str[:80]
|
|
})
|
|
else:
|
|
# Table body row
|
|
# Check Flaw 1: 3-row spec shifted (e.g. output ㎾ on a row alone or pushed to next line)
|
|
# Looking for orphaned spec line with ㎾, ton, HP etc. where rest of row is empty or mismatched
|
|
if len(cells) > 2:
|
|
c0 = cells[0]
|
|
c1 = cells[1] if len(cells) > 1 else ""
|
|
# If first cell is just a unit/spec like "출력 ㎾" or "㎾" and following data columns are misaligned
|
|
if re.match(r'^(출력|규격|용량)?\s*(\(?㎾\)?|\(?ton\)?|\(?HP\)?|\(?PS\)?)$', c0):
|
|
spec_3row_shift_candidates.append({
|
|
"file": rel_path,
|
|
"line": line_num,
|
|
"snippet": line_str[:100]
|
|
})
|
|
else:
|
|
in_table = False
|
|
header_rows = []
|
|
|
|
print(f"\n1. Header vs Divider column mismatches: {len(header_divider_mismatches)}")
|
|
for m in header_divider_mismatches:
|
|
print(f" {m['file']} L{m['line']}: header={m['header_cols']} vs divider={m['divider_cols']} ({m['header_snippet']})")
|
|
|
|
print(f"\n2. Spec 3-row shifted candidates: {len(spec_3row_shift_candidates)}")
|
|
for s in spec_3row_shift_candidates:
|
|
print(f" {s['file']} L{s['line']}: {s['snippet']}")
|
|
|
|
with open('scratch/laptop_sub_flaws_audit.json', 'w', encoding='utf-8') as f:
|
|
json.dump({
|
|
"header_divider_mismatches": header_divider_mismatches,
|
|
"spec_3row_shift_candidates": spec_3row_shift_candidates
|
|
}, f, ensure_ascii=False, indent=2)
|