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.

170 lines
5.3 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 io
from flask import Flask, request, jsonify, render_template, send_file
import pandas as pd
import os
import random
from flask_cors import CORS
app = Flask(__name__)
CORS(app)
# 学生类,包含姓名、学号和积分
class Student:
def __init__(self, id, name, score=0.0):
self.id = id
self.name = name
self.score = score
# 从Excel文件中读取学生名单
def Original_Reading(file):
df = pd.read_excel(file)
# 检查是否存在“积分”列如果不存在则初始化一个积分列并设置为0
if '积分' not in df.columns:
df['积分'] = 0.0
students = []
for i, row in df.iterrows():
students.append(Student(row['学号'], row['姓名'], row['积分']))
return students
# 从排行榜文件中读取学生名单
def Leaderboard_Reading(file):
if not os.path.exists(file):
return None
df = pd.read_excel(file)
s = []
for i, row in df.iterrows():
s.append(Student(row['学号'], row['姓名'], row['积分']))
return s
# 随机选择一个学生
def Select_Student(students):
total = sum(s.score for s in students)
if total == 0:
# 如果总积分为零所有学生的权重都为1
w = [1] * len(students)
else:
w = [(total - student.score + 1) for student in students]
selected_student = random.choices(students, weights=w, k=1)[0]
return selected_student
# 更新学生的积分
def update_score(s, arrived, repeated, correct):
if arrived == 1:
s.score += 1.0
if repeated == 1:
s.score += 0.5
elif repeated == 2:
s.score -= 1.0
if correct:
s.score += correct
# 将学生列表转换为DataFrame并按积分从大到小排序
def students_to_dataframe(students):
total = sum(s.score for s in students)
if total == 0:
# 如果总积分为零所有学生的权重都为1
weights = [1] * len(students)
else:
weights = [(total - s.score + 1) for s in students]
total_weight = sum(weights)
pro = [weight / total_weight * 100 for weight in weights]
data = {'学号': [s.id for s in students],
'姓名': [s.name for s in students],
'积分': [s.score for s in students],
'抽取概率(%)': pro}
df = pd.DataFrame(data)
df = df.sort_values(by='积分', ascending=False).reset_index(drop=True)
return df
# 主程序
students = []
@app.route('/')
def index():
return render_template('index.html')
@app.route('/upload', methods=['POST'])
def upload_file():
global students
file = request.files['file']
if file and file.filename.endswith('.xlsx'):
students = Original_Reading(file)
return jsonify({'success': True})
return jsonify({'success': False})
@app.route('/select_student', methods=['GET'])
def select_student():
global students
if not students:
return jsonify({'error': 'No students available'})
selected_student = Select_Student(students)
return jsonify({'name': selected_student.name, 'id': selected_student.id, 'score': selected_student.score})
@app.route('/update_score', methods=['POST'])
def update_student_score():
global students
data = request.json
student_id = data.get('id')
arrived = data.get('arrived')
repeated = data.get('repeated')
correct = data.get('correct')
student = next((s for s in students if s.id == student_id), None)
if student:
update_score(student, arrived, repeated, correct)
return jsonify({'success': True, 'score': student.score})
return jsonify({'success': False, 'error': '未找到该学生'})
@app.route('/export_file', methods=['GET'])
def export_file():
global students
if not students:
return jsonify({'error': 'No students available'})
df = students_to_dataframe(students)
output = io.BytesIO()
with pd.ExcelWriter(output, engine='xlsxwriter') as writer:
df.to_excel(writer, sheet_name='students', index=False)
output.seek(0)
return send_file(output, download_name='students.xlsx', as_attachment=True)
@app.route('/check_probability', methods=['GET'])
def check_probability():
global students
student_id = request.args.get('id')
student = next((s for s in students if s.id == student_id), None)
if student:
total = sum(s.score for s in students)
if total == 0:
probability = 1 / len(students)
else:
probability = (total - student.score + 1) / total
return jsonify({'probability': probability})
return jsonify({'error': 'Student not found'})
@app.route('/select_ten_students', methods=['GET'])
def select_ten_students():
global students
if not students:
return jsonify({'error': 'No students available'})
selected_students = []
for _ in range(10):
selected_student = Select_Student(students)
selected_students.append({
'name': selected_student.name,
'id': selected_student.id,
'score': selected_student.score
})
return jsonify({'students': selected_students})
if __name__ == '__main__':
app.run(debug=True)