2311061111-lyt/autograde/aggregate_final_grade.py

214 lines
7.2 KiB
Python
Raw Normal View History

2025-12-14 18:19:41 +08:00
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
aggregate_final_grade.py - 聚合最终成绩脚本
将编程测试报告评分等各部分成绩聚合为最终成绩
"""
import json
import argparse
from typing import Dict, Any
def parse_args():
"""解析命令行参数"""
parser = argparse.ArgumentParser(description='Final Grade Aggregation Script')
parser.add_argument('--programming', required=True, help='编程测试评分结果文件')
parser.add_argument('--report', required=True, help='REPORT.md评分结果文件')
parser.add_argument('--frontend', required=True, help='FRONTEND.md评分结果文件')
parser.add_argument('--out', required=True, help='输出最终成绩文件')
parser.add_argument('--summary', required=True, help='输出最终成绩摘要文件')
return parser.parse_args()
def load_grade_file(file_path: str) -> Dict[str, Any]:
"""加载评分结果文件"""
with open(file_path, 'r', encoding='utf-8') as f:
return json.load(f)
def aggregate_grades(
programming_grade: Dict[str, Any],
report_grade: Dict[str, Any],
frontend_grade: Dict[str, Any]
) -> Dict[str, Any]:
"""聚合各部分成绩"""
# 各部分权重配置
weights = {
'programming': 0.6, # 编程测试占60%
'report': 0.25, # 报告占25%
'frontend': 0.15 # 前端报告占15%
}
# 计算各部分成绩
programming_score = programming_grade.get('total', 0.0)
report_score = report_grade.get('total', 0.0)
frontend_score = frontend_grade.get('total', 0.0)
# 计算加权平均分
final_score = (
programming_score * weights['programming'] +
report_score * weights['report'] +
frontend_score * weights['frontend']
)
# 计算各部分的标准化得分(占总分的百分比)
programming_percentage = (programming_score / 100.0) * weights['programming'] * 100.0
report_percentage = (report_score / 100.0) * weights['report'] * 100.0
frontend_percentage = (frontend_score / 100.0) * weights['frontend'] * 100.0
# 生成聚合结果
result = {
'final_score': final_score,
'breakdown': {
'programming': {
'score': programming_score,
'percentage': programming_percentage,
'weight': weights['programming']
},
'report': {
'score': report_score,
'percentage': report_percentage,
'weight': weights['report']
},
'frontend': {
'score': frontend_score,
'percentage': frontend_percentage,
'weight': weights['frontend']
}
},
'weights': weights,
'details': {
'programming': programming_grade,
'report': report_grade,
'frontend': frontend_grade
},
'status': 'completed',
'timestamp': '2025-12-14T18:00:00Z'
}
return result
def generate_summary(aggregate_result: Dict[str, Any]) -> str:
"""生成最终成绩摘要"""
summary = "# 最终成绩报告\n\n"
# 总体成绩
final_score = aggregate_result['final_score']
summary += f"## 总体成绩\n"
summary += f"**最终得分**: {final_score:.2f}/100\n\n"
# 成绩分布
summary += f"## 成绩分布\n"
summary += "| 部分 | 得分 | 权重 | 占总分百分比 |\n"
summary += "|------|------|------|------------|\n"
for part, data in aggregate_result['breakdown'].items():
part_name = {
'programming': '编程测试',
'report': '后端与系统设计报告',
'frontend': '前端界面与交互设计报告'
}.get(part, part)
summary += f"| {part_name} | {data['score']:.2f} | {data['weight']*100:.0f}% | {data['percentage']:.2f} |\n"
summary += "\n"
# 详细说明
summary += f"## 详细说明\n"
# 编程测试
programming = aggregate_result['details']['programming']
programming_total = programming.get('total', 0.0)
summary += f"### 编程测试 ({aggregate_result['weights']['programming']*100:.0f}%)\n"
summary += f"- 原始得分: {programming_total:.2f}/100\n"
summary += f"- 测试通过率: {len([g for g in programming.get('groups', []) if g['passed'] > 0])}/{len(programming.get('groups', []))}\n"
for group in programming.get('groups', []):
summary += f" - {group['group_name']}: {group['passed']}/{group['total']} 测试通过\n"
summary += "\n"
# 报告评分
report = aggregate_result['details']['report']
report_total = report.get('total', 0.0)
summary += f"### 后端与系统设计报告 ({aggregate_result['weights']['report']*100:.0f}%)\n"
summary += f"- 原始得分: {report_total:.2f}/100\n"
if report.get('feedback'):
summary += f"- 反馈摘要: {report['feedback'][:100]}...\n"
summary += "\n"
# 前端报告评分
frontend = aggregate_result['details']['frontend']
frontend_total = frontend.get('total', 0.0)
summary += f"### 前端界面与交互设计报告 ({aggregate_result['weights']['frontend']*100:.0f}%)\n"
summary += f"- 原始得分: {frontend_total:.2f}/100\n"
if frontend.get('feedback'):
summary += f"- 反馈摘要: {frontend['feedback'][:100]}...\n"
summary += "\n"
# 评分等级
if final_score >= 90:
grade_level = "优秀"
elif final_score >= 80:
grade_level = "良好"
elif final_score >= 70:
grade_level = "中等"
elif final_score >= 60:
grade_level = "及格"
else:
grade_level = "不及格"
summary += f"## 评分等级\n"
summary += f"根据最终得分 {final_score:.2f}/100该作业的评分等级为**{grade_level}**\n"
# 建议
summary += f"## 改进建议\n"
summary += "1. 编程测试部分可以进一步提高测试覆盖率\n"
summary += "2. 报告内容可以更加详细和系统化\n"
summary += "3. 前端设计可以考虑更多用户体验细节\n"
return summary
def main():
"""主函数"""
args = parse_args()
# 加载各部分评分结果
print(f"📁 加载编程测试评分: {args.programming}")
programming_grade = load_grade_file(args.programming)
print(f"📁 加载报告评分: {args.report}")
report_grade = load_grade_file(args.report)
print(f"📁 加载前端报告评分: {args.frontend}")
frontend_grade = load_grade_file(args.frontend)
# 聚合成绩
print("📊 聚合最终成绩...")
final_result = aggregate_grades(programming_grade, report_grade, frontend_grade)
# 保存最终成绩
print(f"💾 保存最终成绩: {args.out}")
with open(args.out, 'w', encoding='utf-8') as f:
json.dump(final_result, f, ensure_ascii=False, indent=2)
# 生成摘要
print(f"📝 生成最终成绩摘要: {args.summary}")
summary = generate_summary(final_result)
with open(args.summary, 'w', encoding='utf-8') as f:
f.write(summary)
print(f"✅ 成绩聚合完成! 最终得分: {final_result['final_score']:.2f}/100")
if __name__ == '__main__':
main()