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
@@ -26,3 +26,5 @@
|---|---|
| 조달청_시설자재/ | 조달청 시설공사 자료실 「21년 하반기 시설자재 가격정보공개」 첨부 zip (게시 2021-09-24) |
| 경남교육청_일위대가/ | 2026년도 경상남도교육청 일위대가 xlsx 2개 (게시 2026-03-24 · 공공누리 상업적 이용금지·변경금지) |
| 조달청_시설자재_22하/ | 조달청 · https://www.pps.go.kr/kor/bbs/view.do?bbsSn=2209300017&key=00038 · 기준 2022 하반기 · 받은 날 2026-09-20 · 표 시설공통자재_22하.csv |
+9
View File
@@ -135,3 +135,12 @@
- 유가전력 — 휘발유·경유 새 판 반영 없음.
- 원본 받기 — 문서 URL(게시글 uuid · seq)을 반기마다 `collect_cost_sources.py` 상수에 손으로 갱신.
- 판 최신 여부 표 없음 — `resources/tester/test_master_sources.py` 가 가리키는 `resources/data_master_sources/` 가 이 저장소에 없음.
## 시설자재가격 (지식DB 표 · 마스터 아님)
| 항목 | 값 |
| --- | --- |
| 출처 | 조달청 시설공사 자료실 「시설자재 가격정보공개」 첨부 xlsx · `원가계산/자재단가/조달청_시설자재_22하/` |
| 받는 법 | pps.go.kr 시설공사 게시판(key=00038)에서 글 찾아 첨부 내려받기(키 불필요) |
| 주기 | 연 2회(상·하반기) — 게시판 최신 반기 글은 2022 하반기 |
| 빌더 | `scripts/build_시설자재가격.py` (csv 씀 · `--count` 로 재료 글자 수 셈) |
@@ -42,3 +42,26 @@
- `resources/knowledge/original/원가계산/자재단가/조달청_시설자재/시설자재가격_21하.zip`
- `resources/knowledge/original/원가계산/자재단가/경남교육청_일위대가/일위대가_1.xlsx` (건축) · `일위대가_2.xlsx` (토목)
## 최신 반기 자료 대조 (조달청 2022 하반기 시설공통자재)
- 자료 — 게시글 bbsSn=2209300017 · `조달청_시설자재_22하/` · 표 `시설공통자재_22하.csv` 6,950줄(빌더 `scripts/build_시설자재가격.py`).
- 이 게시판의 반기 자료는 2022 하반기가 마지막 — 2023 이후는 게시글 없음(2026 수시조사 글만).
| 12 재료 | 자료 안 줄 수 (품명·규격에 글자 포함) |
|---|---|
| 합판 | 37 |
| 각재 | 8 |
| 건설용거푸집(유로폼) | 24 |
| 비계 | 7 |
| 클램프 | 18 |
| 철선 | 13 |
| 못 | 39 (짧은 글자라 딴 품명 섞임) |
| 동바리 · 파이프서포트 · 폼타이 · 유공관 · 종자 · 방부 · 잡석 | 0 |
| `_없는_재료.md` 111 줄 | 결과 |
|---|---|
| 자료에 있음 (이름 글자 포함) | 에폭시 2 · 보호막 1 · 실리콘 11 · 노즐 2 · 아스팔트싱글 3 |
| 나머지 | 없음 (2글자 이하 이름은 품명 전체 일치만 봄) |
- 위 줄은 이름 글자만 겹침 — 종류·규격 대조는 안 함. 마스터에 넣지 않음.
@@ -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()