Skip to content

Commit ab19914

Browse files
authored
Refactor update.py for Python 3 compatibility
1 parent 4e58aad commit ab19914

1 file changed

Lines changed: 76 additions & 67 deletions

File tree

update.py

Lines changed: 76 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
1-
#!/usr/bin/env python
1+
# update.py
2+
#!/usr/bin/env python3
23

34
import os
45
from urllib import parse
56

6-
HEADER = """
7-
# 🎯 백준, 프로그래머스, SWEA 문제 풀이 목록
7+
README_PATH = "README.md"
8+
START_MARKER = "<!-- AA-README-START -->"
9+
END_MARKER = "<!-- AA-README-END -->"
10+
11+
GENERATED_HEADER = """
12+
## 📚 Problem Solving
813
"""
914

10-
# 백준 등급 이모지 매핑 (예시)
1115
BOJ_TIER_ORDER = {
1216
"Bronze": "🥉 Bronze",
1317
"Silver": "🥈 Silver",
@@ -17,7 +21,6 @@
1721
"Ruby": "❤️ Ruby"
1822
}
1923

20-
# 프로그래머스 레벨 이모지 매핑 (예시)
2124
PROGRAMMERS_LEVEL = {
2225
"0": "🍼 Lv.0",
2326
"1": "🐣 Lv.1",
@@ -27,112 +30,93 @@
2730
"5": "🦅 Lv.5"
2831
}
2932

30-
# SWEA 단계 이모지 매핑 (예시)
31-
def swea_label(name):
33+
34+
def swea_label(name: str) -> str:
3235
return f"⭐ {name.upper()}"
3336

37+
3438
def parse_problem_folder(folder_name: str) -> str:
35-
"""
36-
'1000. A+B' 같은 폴더 이름을 '1000 - A+B' 로 변환.
37-
폴더명에 '.'이 없으면 그대로 반환.
38-
"""
3939
if "." in folder_name:
4040
parts = folder_name.split(".", 1)
4141
prob_num = parts[0].strip()
4242
prob_title = parts[1].strip()
4343
return f"{prob_num} - {prob_title}"
44-
else:
45-
return folder_name
46-
47-
def extract_problem_number(folder_name: str) -> int:
48-
"""
49-
폴더 이름에서 문제 번호를 추출합니다.
50-
예: "1152. A+B" -> 1152
51-
폴더 이름에 '.'가 없으면 정렬 시 뒤로 밀리도록 큰 값을 반환.
52-
"""
44+
return folder_name
45+
46+
47+
def extract_problem_number(folder_name: str):
5348
if "." in folder_name:
5449
try:
55-
num_part = folder_name.split(".")[0].strip()
56-
return int(num_part)
50+
return int(folder_name.split(".")[0].strip())
5751
except ValueError:
5852
return float("inf")
59-
else:
60-
return float("inf")
53+
return float("inf")
54+
55+
56+
def build_generated_content() -> str:
57+
content = GENERATED_HEADER + "\n"
6158

62-
def main():
63-
content = HEADER + "\n"
64-
65-
# 메인 카테고리 이름들
6659
main_categories = ["백준", "프로그래머스", "SWEA"]
67-
# 데이터 구조:
68-
# data[(메인카테고리, 서브카테고리)] = { 문제폴더이름: [파일경로, ...] }
6960
data = {}
70-
61+
7162
for root, dirs, files in os.walk("."):
72-
# .git, .github, images 폴더는 건너뛰기
7363
dirs[:] = [d for d in dirs if d not in (".git", ".github", "images")]
74-
if root == ".": # 루트 디렉토리는 건너뜁니다.
64+
65+
if root == ".":
7566
continue
76-
77-
# 경로(root)에서 메인 카테고리가 어느 것에 속하는지 체크
67+
7868
main_cat = None
7969
for cat in main_categories:
8070
if os.sep + cat + os.sep in root or root.endswith(os.sep + cat) or root == "./" + cat:
8171
main_cat = cat
8272
break
73+
8374
if main_cat is None:
8475
continue
85-
86-
# 메인 카테고리 바로 아래 폴더(또는 그 아래 하위 경로)를 서브 카테고리(sub_cat)로 간주합니다.
76+
8777
main_path = os.path.join(".", main_cat)
88-
rel_path = os.path.relpath(root, main_path) # 예: 'Bronze/1000. A+B' 등
78+
rel_path = os.path.relpath(root, main_path)
8979
parts = rel_path.split(os.sep)
90-
sub_cat = parts[0] # 예: Bronze 또는 "." (파일이 바로 메인 폴더에 있을 때)
91-
92-
# 문제 폴더가 있다면 (예: "1000. A+B")
80+
sub_cat = parts[0]
81+
9382
problem_folder = None
9483
if len(parts) > 1:
9584
problem_folder = parts[1]
96-
97-
# data 초기화
85+
9886
if (main_cat, sub_cat) not in data:
9987
data[(main_cat, sub_cat)] = {}
100-
88+
10189
if problem_folder is not None:
10290
if problem_folder not in data[(main_cat, sub_cat)]:
10391
data[(main_cat, sub_cat)][problem_folder] = []
104-
92+
10593
for file in files:
106-
if file.lower() == "readme.md": # 문제 설명 파일 제외
94+
if file.lower() == "readme.md":
10795
continue
10896
full_path = os.path.join(root, file)
10997
data[(main_cat, sub_cat)][problem_folder].append(full_path)
110-
else:
111-
# sub_cat 자체가 문제 폴더인 경우(메인 카테고리 폴더에 바로 파일이 있는 경우)
112-
pass
113-
114-
# data의 내용을 바탕으로 content 구성 - 각 서브 카테고리(레벨)별로 하나의 표 생성
98+
11599
for main_cat in main_categories:
116-
# 해당 메인 카테고리에 해당하는 (main_cat, sub_cat) 키 목록
117100
keys = [(k, v) for k, v in data.items() if k[0] == main_cat]
118101
if not keys:
119102
continue
120-
121-
# 메인 카테고리 헤더
103+
122104
content += "---\n"
123105
content += f"## 📚 {main_cat}\n"
124-
125-
# 서브 카테고리(예: Bronze, Silver 등) 정렬
106+
126107
if main_cat == "백준":
127108
order = ["Bronze", "Silver", "Gold", "Platinum", "Diamond", "Ruby"]
128-
keys_sorted = sorted(keys, key=lambda item: order.index(item[0][1]) if item[0][1] in order else 999)
109+
keys_sorted = sorted(
110+
keys,
111+
key=lambda item: order.index(item[0][1]) if item[0][1] in order else 999
112+
)
129113
else:
130114
keys_sorted = sorted(keys, key=lambda x: x[0][1])
131-
115+
132116
for (mc, sub_cat), problem_map in keys_sorted:
133117
if sub_cat == ".":
134118
continue
135-
119+
136120
if mc == "백준":
137121
tier_title = BOJ_TIER_ORDER.get(sub_cat, f"✅ {sub_cat}")
138122
elif mc == "프로그래머스":
@@ -145,17 +129,42 @@ def main():
145129
content += f"### {tier_title}\n"
146130
content += "| 문제 | 링크 |\n"
147131
content += "| ----- | ---- |\n"
148-
149-
# 문제 폴더를 문제 번호 기준(숫자)으로 정렬합니다.
150-
for pfolder, file_list in sorted(problem_map.items(), key=lambda item: extract_problem_number(item[0])):
132+
133+
for pfolder, _ in sorted(problem_map.items(), key=lambda item: extract_problem_number(item[0])):
151134
parsed_name = parse_problem_folder(pfolder)
152135
folder_path = os.path.join(".", mc, sub_cat, pfolder)
153136
content += f"| {parsed_name} | [링크]({parse.quote(folder_path)}) |\n"
154-
137+
155138
content += "\n"
156-
157-
with open("README.md", "w", encoding="utf-8") as fd:
158-
fd.write(content)
139+
140+
return content.strip() + "\n"
141+
142+
143+
def update_readme():
144+
generated = build_generated_content()
145+
146+
if os.path.exists(README_PATH):
147+
with open(README_PATH, "r", encoding="utf-8") as f:
148+
readme = f.read()
149+
else:
150+
readme = ""
151+
152+
block = f"{START_MARKER}\n{generated}{END_MARKER}"
153+
154+
if START_MARKER in readme and END_MARKER in readme:
155+
start = readme.index(START_MARKER)
156+
end = readme.index(END_MARKER) + len(END_MARKER)
157+
updated = readme[:start] + block + readme[end:]
158+
else:
159+
prefix = readme.strip()
160+
if prefix:
161+
updated = prefix + "\n\n---\n\n" + block + "\n"
162+
else:
163+
updated = block + "\n"
164+
165+
with open(README_PATH, "w", encoding="utf-8") as f:
166+
f.write(updated)
167+
159168

160169
if __name__ == "__main__":
161-
main()
170+
update_readme()

0 commit comments

Comments
 (0)