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.
gaygay/Roll_Call_Flask.py

170 lines
5.3 KiB

1 month ago
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)