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)