用 FastAPI + T 分数算法打造智能化成绩分析报表
用 FastAPI + T 分数算法打造智能化成绩分析报表
一、项目缘起:成绩分析为什么需要自动化?
1.1 传统成绩分析的痛点
每次大考过后,教务处都要面对成堆的 Excel 数据:
- 手工汇总慢:一个年级300+学生,汇总成绩要半天
- 分析维度少:只知道总分,不知道各科均衡情况
- 分校数据混:东风校区和诚毅校区入口成绩差100分,混在一起排名不公平
- 报表格式乱:每次做报表都要重新排版,费时费力
1.2 解决方案
用 FastAPI 搭建一个成绩分析后端,输入智学网原始数据,输出排版好的 Word 报表,全程自动化。
二、T 分数算法:让不同校区可以公平比较
2.1 为什么不用原始分数?
东风校区和诚毅校区的学生,入学成绩本来就差了约100分。如果用原始分数直接排名,对诚毅校区的优秀学生不公平。
2.2 T分数公式
T分数 = 50 + 10 × (个人离均差 / 标准差)
T = 50 + 10 × (X - μ) / σ其中:
X = 个人原始分数
μ = 全体平均分
σ = 标准差
T分数的含义:
2.3 分校区独立统计
为保证公平,按校区分别计算 T 分数:
这样,两个校区的学生可以在各自体系内公平竞争!
三、系统架构
3.1 整体流程
3.2 核心数据模型
from dataclasses import dataclass
from typing import Dict, List
@dataclass
class StudentScore:
student_id : str # 学籍号
name : str # 姓名
class_id : str # 班级编号
campus : str # 分校(东风/诚毅)
scores : Dict[str, float] # 各科原始分
total : float # 总分
@dataclass
class ClassReport:
class_id : str
campus : str
subject_stats : Dict[str, SubjectStat] # 各科统计
student_reports : List[StudentReport] # 学生报表
recommendations : List[str] # 教学建议
3.3 T分数计算核心代码
import statistics
def calc_t_score(score: float, mean: float, std: float) -> float:
"""计算 T 分数"""
if std == 0:
return 50.0
return 50 + 10 * (score - mean) / std
def calc_class_stats(scores: List[float]) -> dict:
"""计算班级统计数据"""
mean = statistics.mean(scores)
std = statistics.stdev(scores) if len(scores) > 1 else 0
deviations = [s - mean for s in scores]
return {
"平均分" : round(mean, 2),
"标准差" : round(std, 2),
"离均差" : [round(d, 2) for d in deviations],
"T分数" : [round(calc_t_score(s, mean, std), 1)
for s in scores]
}
四、报表内容设计
4.1 报表结构
每份 Word 报表包含以下内容:
| 模块 | 内容 |
|---|---|
| 一、基本信息 | 考试名称、日期 · 班级、校区 · 参加人数 |
| 二、各科成绩统计 | 科目名称、平均分、标准差、最高分/最低分、T分数区间分布 |
| 三、T分数离均差排名(全班) | 学籍号、姓名、各科T分数、离均差(正负表示高于/低于平均)、班级排名 |
| 四、各科单科第一名单 | 每科最高分学生姓名及分数 |
| 五、综合教学建议 | 班级整体建议 · 重点关注学生名单 · 下次考试目标 |
4.2 T分数离均差表示例
| 学籍号 | 姓名 | 语文T分 | 数学T分 | 英语T分 | 综合离均差 | 班级排名 |
|---|---|---|---|---|---|---|
| 20260101 | 张三 | 58.2 | 61.5 | 55.0 | +8.2 | 1 |
| 20260102 | 李四 | 52.1 | 48.3 | 53.7 | +1.4 | 5 |
| 20260103 | 王五 | 45.3 | 49.0 | 47.2 | -3.8 | 12 |
五、部署与使用
5.1 接口信息
| 项目 | 内容 |
|---|---|
| API 地址 | POST http://49.232.172.211:8089/api/report/generate-v2 |
| 文档地址 | http://49.232.172.211:8089/docs |
| 下载目录 | http://49.232.172.211/reports/ |
| 管理后台 | http://49.232.172.211:8089/admin |
| 超级管理员 | admin / admin123 |
5.2 使用流程
- 登录管理后台
- 上传智学网导出的 ZIP 文件
- 选择生成校区的报表(东风 / 诚毅 / 全部)
- 点击「生成报表」
- 等待处理(约 10~30 秒)
- 在下载目录获取 Word 报表
5.3 数据安全
- 成绩数据仅在服务器内存中处理,不做持久化存储
- 下载链接带有随机文件名,防止猜测
- 报表生成后自动清理临时文件
六、技术亮点
6.1 异步处理大文件
使用 Python 异步处理,不阻塞服务器:
from fastapi import APIRouter, UploadFile, File
router = APIRouter()
@router.post("/api/report/generate-v2")
async def generate_report(file: UploadFile = File(...)):
# 异步读取上传文件
content = await file.read()
# 异步处理数据
result = await process_scores_async(content)
return result
6.2 内存安全
服务器内存仅 2.4GB,文件上传大小限制在 50MB,防止内存溢出。
6.3 报表模板技术
使用 python-docx 模板引擎,将格式预先定义在 Word 模板中,运行时只填充数据,保持报表格式统一专业。
七、已知问题和改进方向
7.1 当前局限
- 仅支持智学网格式的 ZIP 文件(其他系统需要适配)
- 单次最多处理 1000 名学生
- 暂不支持学生进步幅度分析
7.2 未来规划
| 功能 | 说明 | 优先级 |
|---|---|---|
| 多考试对比 | 连续多次考试趋势分析 | 高 |
| 学生进步排名 | 关注进步幅度而非绝对分数 | 高 |
| PDF 导出 | 同时支持 Word 和 PDF | 中 |
| 家长端查询 | 学生/家长扫码查成绩 | 中 |
| 错题统计分析 | 自动汇总高频错题 | 低 |
八、总结
本文介绍了某中学成绩分析报表系统的设计与实现:
- T分数算法 实现不同校区公平比较
- FastAPI 搭建高性能分析后端
- Word报表 自动生成,可直接打印
- 分校区统计 解决入口成绩差异问题
该系统已稳定运行,服务于学校的每一次大考成绩分析工作,大大减轻了教务处的负担。
相关技术栈:Python · FastAPI · python-docx · numpy
访问地址:
http://49.232.172.211:8089/docs
某中学 · 教务教研数字化实践 · 2026

浙公网安备 33010602011771号