knowledge(마스터): 조달청 2022하 시설자재가격 받기 · 표 빌더 · 12 재료·없는 재료 대조

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PAdA5ThqmtVSsbzjusk1cJ
This commit is contained in:
2026-09-20 23:01:18 +09:00
co-authored by Claude Sonnet 5
parent 53151917ba
commit eb88cf9a67
12 changed files with 7071 additions and 0 deletions
@@ -0,0 +1,86 @@
# -*- coding: utf-8 -*-
"""조달청 시설공통자재 xlsx(4분야) → 품명·규격·단위·금액 csv (지식DB 폴더 안). 마스터 JSON 은 안 만짐.
쓰기: ./venv/Scripts/python.exe resources/master_data/scripts/build_시설자재가격.py
세기: ... build_시설자재가격.py --count (12 재료 · ref/_없는_재료.md 이름이 자료에 몇 줄인지 출력)
"""
from __future__ import annotations
import csv
import re
import sys
from pathlib import Path
import openpyxl
ROOT = Path(__file__).resolve().parents[3]
DIR = ROOT / "resources/knowledge/original/원가계산/자재단가/조달청_시설자재_22하"
OUT = DIR / "시설공통자재_22하.csv"
MISSING = ROOT / "resources/master_data/ref/_없는_재료.md"
TWELVE = [
"합판",
"각재",
"건설용거푸집",
"동바리",
"파이프서포트",
"비계",
"클램프",
"철선",
"",
"폼타이",
"유공관",
"종자",
"방부",
"잡석",
]
def rows():
for f in sorted(DIR.glob("시설공통자재_*.xlsx")):
ws = openpyxl.load_workbook(f, read_only=True, data_only=True).worksheets[0]
head = None
for r in ws.iter_rows(values_only=True):
if head is None:
head = r if r and r[0] == "물품분류번호" else None
continue
if r[2]:
yield (
f.stem.split("_")[1],
r[2],
r[3] or "",
r[4] or "",
str(r[5] or "").replace(",", ""),
)
def count(data, words):
return {w: sum(1 for d in data if w in f"{d[1]}{d[2]}") for w in words}
def main():
data = list(rows())
if "--count" in sys.argv:
print(len(data), "")
for w, n in count(data, TWELVE).items():
print("12재료", w, n)
for m in re.finditer(
r"^\| MP\d+ \| ([^|]+?) \|", MISSING.read_text(encoding="utf-8"), re.M
):
name = re.sub(r"\(.*", "", m.group(1)).strip()
n = (
count(data, [name])[name]
if len(name) >= 3
else sum(1 for d in data if d[1] == name)
) # 짧은 이름은 품명 전체 일치만
print(f"없는재료 {name} {n}")
return
with OUT.open("w", encoding="utf-8-sig", newline="") as fp:
w = csv.writer(fp)
w.writerow(["분야", "품명", "규격", "단위", "금액"])
w.writerows(data)
print(OUT.name, len(data), "")
if __name__ == "__main__":
main()