You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

81 lines
2.5 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import random
import pandas as pd
from io import BytesIO
class ProbabilityCalculator:
@staticmethod
def weighted_random_selection(students):
"""
基于积分的加权随机点名算法
积分越高,被点概率越低
"""
if not students:
raise ValueError("学生列表不能为空")
base_weight = 100
decay_factor = 8 # 积分衰减系数
weights = []
for student in students:
# 计算权重衰减确保最低权重为15
score_deduction = min(student.total_score * decay_factor, 85)
weight = max(base_weight - score_deduction, 15)
weights.append({
'student': student,
'weight': weight
})
total_weight = sum(item['weight'] for item in weights)
random_value = random.uniform(0, total_weight)
current_sum = 0
for item in weights:
current_sum += item['weight']
if current_sum >= random_value:
return item['student']
return weights[0]['student'] # 兜底返回第一个学生
class ScoreCalculator:
@staticmethod
def calculate_score(answer_type, performance):
"""
根据回答类型和表现计算积分
"""
score_map = {
'repeat_question': {
'correct': 0.5,
'incorrect': -1
},
'answer_question': {
'excellent': 3,
'good': 2,
'normal': 1,
'poor': 0.5
},
'present': {
'present': 1
}
}
return score_map.get(answer_type, {}).get(performance, 0)
class ExcelService:
@staticmethod
def export_scores(students):
"""导出积分数据到Excel"""
data = []
for student in students:
data.append({
'学号': student.student_id,
'姓名': student.name,
'班级': student.class_name,
'总积分': student.total_score
})
df = pd.DataFrame(data)
output = BytesIO()
with pd.ExcelWriter(output, engine='openpyxl') as writer:
df.to_excel(writer, sheet_name='学生积分', index=False)
output.seek(0)
return output