更新课评系统代码
This commit is contained in:
378
src/unify_class_summaries.py
Normal file
378
src/unify_class_summaries.py
Normal file
@@ -0,0 +1,378 @@
|
||||
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()
|
||||
Reference in New Issue
Block a user