#!/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()