Files
ClassFeedback/src/unify_class_summaries.py
2026-06-02 23:01:58 +08:00

378 lines
12 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import os
import re
CLASS_DIR = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), '.claude', 'memory', 'class')
def extract_file_info(file_path):
parts = os.path.normpath(file_path).split(os.sep)
filename = os.path.basename(file_path)
class_name = ''
for i, p in enumerate(parts):
if p == 'summaries' and i >= 1:
class_name = parts[i-1]
break
date_match = re.match(r'(\d{4})(\d{2})(\d{2})_', filename)
date_str = ''
if date_match:
date_str = f'{date_match.group(1)}-{date_match.group(2)}-{date_match.group(3)}'
course_match = re.search(r'(AICODE03|SPIKE|DISC|CREATE|MECH|TUBE|INVENT|WEDO)-(\d+)', filename)
course_code = ''
if course_match:
prefix = course_match.group(1)
if prefix == 'WEDO':
prefix = 'CREATE'
num = course_match.group(2).zfill(3)
course_code = f'{prefix}-{num}'
return {
'class_name': class_name,
'date': date_str,
'course_code': course_code,
'filename': filename,
}
def is_new_format(text):
return '## 本周课评状态' in text and '## 本周班级整体情况' in text
def is_v2_format(text):
return '## 本周概览' in text
def is_v3_format(text):
return '课评状态面板' in text or '## 📊' in text
def detect_format(text):
if is_new_format(text):
return 'v1'
if is_v2_format(text):
return 'v2'
if is_v3_format(text):
return 'v3'
return 'unknown'
def extract_week(text):
m = re.search(r'第(\d+)周', text)
return m.group(1) if m else ''
def extract_theme(text):
lines = text.split('\n')
for line in lines:
if '课程主题' in line:
m = re.search(r'[:]\s*(.*)', line)
if m:
return m.group(1).strip()
return ''
def extract_name_from_header(text):
text = re.sub(r'\s*[(][^)]*[)]', '', text)
text = re.sub(r'\s*[-—]\s*.*', '', text)
text = re.sub(r'^\d+[.、]\s*', '', text)
text = re.sub(r'\s*☑.*', '', text)
text = re.sub(r'\[.*?\]', '', text)
return text.strip()
def extract_student_feedbacks(text):
feedbacks = []
lines = text.split('\n')
i = 0
current_student = {}
content = []
in_feedback = False
while i < len(lines):
line = lines[i]
stripped = line.strip()
if any(stripped.startswith(p) for p in ['## 班级整体观察', '## 本周班级整体情况', '## 教师周记', '## 数据统计', '## 本周概览', '## 详细课评']):
if current_student and current_student.get('name'):
current_student['content'] = '\n'.join(content).strip()
feedbacks.append(current_student)
current_student = {}
content = []
in_feedback = False
if re.match(r'^###\s+\S', stripped) and '### 课程信息' not in stripped and '### 学生表现' not in stripped and '### 快速统计' not in stripped and '### 学生状态' not in stripped and '### 课程目标' not in stripped:
if current_student and current_student.get('name'):
current_student['content'] = '\n'.join(content).strip()
feedbacks.append(current_student)
full_line = stripped
student_name = extract_name_from_header(full_line)
if student_name:
current_student = {'name': student_name}
content = []
in_feedback = True
i += 1
continue
if in_feedback:
content.append(line)
i += 1
if current_student and current_student.get('name'):
current_student['content'] = '\n'.join(content).strip()
feedbacks.append(current_student)
return feedbacks
def extract_v2_feedbacks(text):
feedbacks = []
lines = text.split('\n')
i = 0
current_student = None
content = []
in_detail = False
while i < len(lines):
line = lines[i]
stripped = line.strip()
if stripped.startswith('## 班级整体观察') or stripped.startswith('## 教师周记') or stripped.startswith('## 数据统计') or stripped.startswith('## 本周班级整体情况'):
if current_student:
current_student['content'] = '\n'.join(content).strip()
feedbacks.append(current_student)
current_student = None
content = []
in_detail = False
if stripped == '## 详细课评':
in_detail = True
i += 1
continue
if in_detail and re.match(r'^###\s+\S', stripped):
if current_student:
current_student['content'] = '\n'.join(content).strip()
feedbacks.append(current_student)
full_line = stripped[4:]
student_name = extract_name_from_header(full_line)
if student_name:
current_student = {'name': student_name}
content = []
i += 1
continue
if in_detail and current_student:
content.append(line)
i += 1
if current_student:
current_student['content'] = '\n'.join(content).strip()
feedbacks.append(current_student)
return feedbacks
def extract_overall(text):
overall_lines = []
lines = text.split('\n')
in_overall = False
capturing = False
for line in lines:
stripped = line.strip()
if stripped == '## 班级整体观察' or stripped == '## 本周班级整体情况':
in_overall = True
capturing = True
continue
if stripped in ['## 教师周记', '## 数据统计', '## 详细课评', '## 本周概览', '## 本周课评状态']:
capturing = False
continue
if in_overall and capturing:
overall_lines.append(line)
return '\n'.join(overall_lines).strip()
def v2_to_v1(text, file_info):
week = extract_week(text)
theme = extract_theme(text)
feedbacks = extract_v2_feedbacks(text)
overall = extract_overall(text)
lines = []
lines.append(f'# {file_info["class_name"]}{week}周汇总')
lines.append('')
lines.append(f'> 课程代码:{file_info["course_code"]}')
if theme:
lines.append(f'> 课程主题:{theme}')
lines.append(f'> 上课日期:{file_info["date"]}')
lines.append(f'> 班级人数:待确认')
lines.append('')
lines.append('---')
lines.append('')
lines.append('## 本周课评状态')
lines.append('')
lines.append('| 学生 | 状态 | 类型 | 档案位置 | 操作 |')
lines.append('|:-----|:----:|:----:|:---------|:----:|')
for fb in feedbacks:
lines.append(f'| {fb["name"]} | ✅ 已保存 | 常规学生 | 本班 | [查看] |')
lines.append('')
lines.append('---')
lines.append('')
lines.append('## 学生课评列表')
lines.append('')
for fb in feedbacks:
lines.append(f'### {fb["name"]} - 常规学生 ✅')
lines.append('')
if fb.get('content'):
lines.append(fb['content'])
lines.append('')
lines.append('**教师备注**')
lines.append('- 状态:已保存')
lines.append('- 个人档案:已同步')
lines.append('- 亮点:待补充')
lines.append('')
lines.append('---')
lines.append('')
lines.append('## 本周班级整体情况')
lines.append('')
if overall:
lines.append(overall)
else:
lines.append('### 课程目标达成度')
lines.append('- **知识点掌握**:待补充')
lines.append('- **技能操作**:待补充')
lines.append('')
lines.append('### 共性亮点')
lines.append('1. ')
lines.append('')
lines.append('### 共性问题')
lines.append('1. 无明显共性问题')
lines.append('')
lines.append('---')
lines.append('')
lines.append(f'*生成时间:{file_info["date"]}*')
return '\n'.join(lines)
def v3_to_v1(text, file_info):
week = extract_week(text)
theme = extract_theme(text)
feedbacks = extract_student_feedbacks(text)
overall = extract_overall(text)
lines = []
lines.append(f'# {file_info["class_name"]}{week}周汇总')
lines.append('')
lines.append(f'> 课程代码:{file_info["course_code"]}')
if theme:
lines.append(f'> 课程主题:{theme}')
lines.append(f'> 上课日期:{file_info["date"]}')
lines.append(f'> 班级人数:待确认')
lines.append('')
lines.append('---')
lines.append('')
lines.append('## 本周课评状态')
lines.append('')
lines.append('| 学生 | 状态 | 类型 | 档案位置 | 操作 |')
lines.append('|:-----|:----:|:----:|:---------|:----:|')
for fb in feedbacks:
lines.append(f'| {fb["name"]} | ✅ 已保存 | 常规学生 | 本班 | [查看] |')
lines.append('')
lines.append('---')
lines.append('')
lines.append('## 学生课评列表')
lines.append('')
for fb in feedbacks:
lines.append(f'### {fb["name"]} - 常规学生 ✅')
lines.append('')
if fb.get('content'):
lines.append(fb['content'])
lines.append('')
lines.append('**教师备注**')
lines.append('- 状态:已保存')
lines.append('- 个人档案:已同步')
lines.append('- 亮点:待补充')
lines.append('')
lines.append('---')
lines.append('')
lines.append('## 本周班级整体情况')
lines.append('')
if overall:
lines.append(overall)
else:
lines.append('### 课程目标达成度')
lines.append('- **知识点掌握**:待补充')
lines.append('- **技能操作**:待补充')
lines.append('')
lines.append('### 共性亮点')
lines.append('1. ')
lines.append('')
lines.append('### 共性问题')
lines.append('1. 无明显共性问题')
lines.append('')
lines.append('---')
lines.append('')
lines.append(f'*生成时间:{file_info["date"]}*')
return '\n'.join(lines)
def process_summary(file_path, force=False):
with open(file_path, 'r', encoding='utf-8') as f:
text = f.read()
file_info = extract_file_info(file_path)
fmt = detect_format(text)
if fmt == 'v1' and not force:
return False
if fmt == 'v1' and force:
pass
elif fmt == 'v2':
pass
elif fmt == 'v3':
pass
else:
return False
new_text = v2_to_v1(text, file_info) if fmt in ['v1', 'v2'] else v3_to_v1(text, file_info)
with open(file_path, 'w', encoding='utf-8') as f:
f.write(new_text)
return True
def main():
import sys
force = '--force' in sys.argv
updated = 0
skipped = 0
errors = 0
for root, dirs, files in os.walk(CLASS_DIR):
if 'summaries' not in root.split(os.sep):
continue
for f in files:
if not f.endswith('.md'):
continue
file_path = os.path.join(root, f)
try:
if process_summary(file_path):
updated += 1
rel = os.path.relpath(file_path, CLASS_DIR)
print(f' ✅ 已更新: {rel}')
else:
skipped += 1
except Exception as e:
errors += 1
rel = os.path.relpath(file_path, CLASS_DIR)
print(f' ❌ 错误: {rel} - {e}')
print(f'\n{"="*50}')
print(f'更新完成!')
print(f' ✅ 已更新: {updated} 个文件')
print(f' ⏭️ 已跳过(已是最新格式): {skipped} 个文件')
print(f' ❌ 错误: {errors} 个文件')
if __name__ == '__main__':
main()