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:
@@ -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 |
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -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()
|
||||
Reference in New Issue
Block a user