|
|
|
@ -28,254 +28,7 @@ graph TD;
|
|
|
|
|
导入students名单-->开始点名
|
|
|
|
|
开始点名-->提出问题
|
|
|
|
|
提出问题-->回答
|
|
|
|
|
三.编程代码
|
|
|
|
|
前端代码
|
|
|
|
|
|
|
|
|
|
<!DOCTYPE html>
|
|
|
|
|
<html lang="zh">
|
|
|
|
|
<head>
|
|
|
|
|
<meta charset="UTF-8">
|
|
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
|
|
|
<title>FZU软工学生点名系统</title>
|
|
|
|
|
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
|
|
|
|
<style>
|
|
|
|
|
body {
|
|
|
|
|
font-family: Arial, sans-serif;
|
|
|
|
|
margin: 0;
|
|
|
|
|
padding: 0;
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
align-items: center;
|
|
|
|
|
justify-content: center;
|
|
|
|
|
height: 100vh;
|
|
|
|
|
background: linear-gradient(to bottom, #e0f7fa, #ffffff);
|
|
|
|
|
color: #333;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
h1, h2 {
|
|
|
|
|
color: #00796b;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
button {
|
|
|
|
|
background-color: #00796b;
|
|
|
|
|
color: white;
|
|
|
|
|
border: none;
|
|
|
|
|
padding: 10px 20px;
|
|
|
|
|
margin: 10px;
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
border-radius: 5px;
|
|
|
|
|
transition: background-color 0.3s;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
button:hover {
|
|
|
|
|
background-color: #004d40;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
input[type="file"],
|
|
|
|
|
input[type="text"] {
|
|
|
|
|
padding: 10px;
|
|
|
|
|
margin: 10px;
|
|
|
|
|
border: 1px solid #ccc;
|
|
|
|
|
border-radius: 5px;
|
|
|
|
|
width: 200px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
input[type="hidden"] {
|
|
|
|
|
display: none;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
p {
|
|
|
|
|
font-size: 18px;
|
|
|
|
|
margin: 10px;
|
|
|
|
|
}
|
|
|
|
|
</style>
|
|
|
|
|
<script>
|
|
|
|
|
function uploadStudents() {
|
|
|
|
|
const fileInput = $('#fileInput')[0];
|
|
|
|
|
const formData = new FormData();
|
|
|
|
|
formData.append('file', fileInput.files[0]);
|
|
|
|
|
|
|
|
|
|
$.ajax({
|
|
|
|
|
url: '/upload_students',
|
|
|
|
|
type: 'POST',
|
|
|
|
|
processData: false,
|
|
|
|
|
contentType: false,
|
|
|
|
|
data: formData,
|
|
|
|
|
success: function(response) {
|
|
|
|
|
alert(response.message);
|
|
|
|
|
},
|
|
|
|
|
error: function(xhr) {
|
|
|
|
|
alert("请求失败: " + xhr.responseJSON.message);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function callStudent() {
|
|
|
|
|
$.ajax({
|
|
|
|
|
url: '/call_student',
|
|
|
|
|
type: 'POST',
|
|
|
|
|
success: function(response) {
|
|
|
|
|
$('#studentInfo').text(`被点到的学生: ${response.name} (学号: ${response.student_id})`);
|
|
|
|
|
$('#studentIndex').val(response.index);
|
|
|
|
|
},
|
|
|
|
|
error: function(xhr) {
|
|
|
|
|
alert("请求失败: " + xhr.responseJSON.message);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function updatePoints() {
|
|
|
|
|
const answer = $('#answer').val();
|
|
|
|
|
const studentIndex = $('#studentIndex').val();
|
|
|
|
|
|
|
|
|
|
$.ajax({
|
|
|
|
|
url: '/update_points',
|
|
|
|
|
type: 'POST',
|
|
|
|
|
contentType: 'application/json',
|
|
|
|
|
data: JSON.stringify({ index: studentIndex, answer: answer }),
|
|
|
|
|
success: function(response) {
|
|
|
|
|
alert(response.message);
|
|
|
|
|
$('#points').text(`当前积分: ${response.points}`);
|
|
|
|
|
},
|
|
|
|
|
error: function(xhr) {
|
|
|
|
|
alert("请求失败: " + xhr.responseJSON.message);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
</script>
|
|
|
|
|
</head>
|
|
|
|
|
<body>
|
|
|
|
|
<h1>学生管理系统</h1>
|
|
|
|
|
|
|
|
|
|
<h2>上传学生名单</h2>
|
|
|
|
|
<input type="file" id="fileInput" accept=".xlsx,.xls">
|
|
|
|
|
<button onclick="uploadStudents()">上传</button>
|
|
|
|
|
|
|
|
|
|
<h2>随机点名</h2>
|
|
|
|
|
<button onclick="callStudent()">点名</button>
|
|
|
|
|
<p id="studentInfo"></p>
|
|
|
|
|
<input type="hidden" id="studentIndex">
|
|
|
|
|
|
|
|
|
|
<h2>回答问题1+1=?</h2>
|
|
|
|
|
<input type="text" id="answer" placeholder="输入你的答案">
|
|
|
|
|
<button onclick="updatePoints()">提交答案</button>
|
|
|
|
|
<p id="points">当前积分: 0</p>
|
|
|
|
|
|
|
|
|
|
<h2>特殊模式</h2>
|
|
|
|
|
<button id="toggleSpecialMode" onclick="toggleSpecialMode()">开启特殊模式</button>
|
|
|
|
|
|
|
|
|
|
</body>
|
|
|
|
|
</html>
|
|
|
|
|
后端代码
|
|
|
|
|
|
|
|
|
|
from flask import Flask, request, jsonify, send_from_directory
|
|
|
|
|
import pandas as pd
|
|
|
|
|
import random
|
|
|
|
|
from flask_sqlalchemy import SQLAlchemy
|
|
|
|
|
from flask_cors import CORS
|
|
|
|
|
|
|
|
|
|
app = Flask(__name__)
|
|
|
|
|
CORS(app) # 启用 CORS
|
|
|
|
|
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///students.db'
|
|
|
|
|
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
|
|
|
|
|
app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024 # 最大上传文件限制
|
|
|
|
|
db = SQLAlchemy(app)
|
|
|
|
|
|
|
|
|
|
class Student(db.Model):
|
|
|
|
|
id = db.Column(db.Integer, primary_key=True)
|
|
|
|
|
name = db.Column(db.String(100), nullable=False)
|
|
|
|
|
student_id = db.Column(db.String(20), unique=True, nullable=False)
|
|
|
|
|
points = db.Column(db.Float, default=0)
|
|
|
|
|
called_count = db.Column(db.Integer, default=0)
|
|
|
|
|
|
|
|
|
|
@app.route('/upload_students', methods=['POST'])
|
|
|
|
|
def upload_students():
|
|
|
|
|
if 'file' not in request.files:
|
|
|
|
|
return jsonify(message="未找到文件"), 400
|
|
|
|
|
|
|
|
|
|
file = request.files['file']
|
|
|
|
|
|
|
|
|
|
if file.filename == '':
|
|
|
|
|
return jsonify(message="没有选择文件"), 400
|
|
|
|
|
|
|
|
|
|
if not (file.filename.endswith('.xlsx') or file.filename.endswith('.xls')):
|
|
|
|
|
return jsonify(message="文件格式不支持,请上传 Excel 文件"), 400
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
df = pd.read_excel(file)
|
|
|
|
|
|
|
|
|
|
if '姓名' not in df.columns or '学号' not in df.columns:
|
|
|
|
|
return jsonify(message="Excel 文件必须包含 '姓名' 和 '学号' 列"), 400
|
|
|
|
|
|
|
|
|
|
for _, row in df.iterrows():
|
|
|
|
|
student = Student(name=row['姓名'], student_id=row['学号'])
|
|
|
|
|
db.session.add(student)
|
|
|
|
|
db.session.commit()
|
|
|
|
|
return jsonify(message="学生名单上传成功"), 200
|
|
|
|
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
print(f"Error: {e}")
|
|
|
|
|
return jsonify(message=f"文件处理失败: {str(e)}"), 500
|
|
|
|
|
|
|
|
|
|
@app.route('/call_student', methods=['POST'])
|
|
|
|
|
def call_student():
|
|
|
|
|
students = Student.query.all()
|
|
|
|
|
total_points = sum(student.points for student in students)
|
|
|
|
|
|
|
|
|
|
if total_points == 0:
|
|
|
|
|
chosen_student = random.choice(students)
|
|
|
|
|
else:
|
|
|
|
|
probabilities = [(student, 1 - (student.points / total_points)) for student in students]
|
|
|
|
|
total_prob = sum(prob[1] for prob in probabilities)
|
|
|
|
|
chosen_student = random.choices(
|
|
|
|
|
[prob[0] for prob in probabilities],
|
|
|
|
|
weights=[prob[1] / total_prob for prob in probabilities]
|
|
|
|
|
)[0]
|
|
|
|
|
|
|
|
|
|
chosen_student.called_count += 1
|
|
|
|
|
chosen_student.points += 1 # 点到后增加积分
|
|
|
|
|
db.session.commit()
|
|
|
|
|
|
|
|
|
|
return jsonify(name=chosen_student.name, student_id=chosen_student.student_id, index=chosen_student.id)
|
|
|
|
|
|
|
|
|
|
@app.route('/update_points', methods=['POST'])
|
|
|
|
|
def update_points():
|
|
|
|
|
data = request.json
|
|
|
|
|
student = Student.query.get(data['index'])
|
|
|
|
|
answer = data['answer']
|
|
|
|
|
|
|
|
|
|
score = 0
|
|
|
|
|
question = "1+1=?" # 假设提问内容
|
|
|
|
|
|
|
|
|
|
if answer == question:
|
|
|
|
|
score += 0.5
|
|
|
|
|
result_message = "回答正确!"
|
|
|
|
|
else:
|
|
|
|
|
score -= 1
|
|
|
|
|
result_message = "回答错误!"
|
|
|
|
|
|
|
|
|
|
# 模拟准确回答的情况
|
|
|
|
|
if "Ezio" == answer:
|
|
|
|
|
score += random.uniform(0.5, 3.0)
|
|
|
|
|
result_message = "回答非常正确!"
|
|
|
|
|
|
|
|
|
|
student.points += score
|
|
|
|
|
db.session.commit()
|
|
|
|
|
|
|
|
|
|
if student.points < 0:
|
|
|
|
|
student.points = 0 # 确保积分不为负值
|
|
|
|
|
db.session.commit()
|
|
|
|
|
|
|
|
|
|
return jsonify(points=student.points, message=result_message)
|
|
|
|
|
|
|
|
|
|
@app.route('/')
|
|
|
|
|
def index():
|
|
|
|
|
return send_from_directory('', 'index.html')
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
|
with app.app_context():
|
|
|
|
|
db.create_all()
|
|
|
|
|
app.run(debug=True)
|
|
|
|
|
四.反思
|
|
|
|
|
此次编程任务虽然大体完成了作业的提出的要求,但是点名系统的登录界面还是没有能够实现出来,同时这次编程任务也让我了解到了和同学一起进行编程任务的乐趣,以及两个一起沟通交流的快乐。我与搭档密切合作,收获颇丰。我们共同分析问题、设计解决方案,充分发挥了各自的优势。在编程过程中,我们及时沟通,互相审查代码,提高了代码质量和效率。通过结对编程,我学会了倾听他人意见、尊重不同的编程风格,也提升了自己的问题解决能力和团队协作能力。这次经历让我深刻认识到结对编程的优势,期待在未来的项目中继续运用这种高效的开发方式。
|
|
|
|
|
#三.反思
|
|
|
|
|
###此次编程任务虽然大体完成了作业的提出的要求,但是点名系统的登录界面还是没有能够实现出来,同时这次编程任务也让我了解到了和同学一起进行编程任务的乐趣,以及两个一起沟通交流的快乐。我与搭档密切合作,收获颇丰。我们共同分析问题、设计解决方案,充分发挥了各自的优势。在编程过程中,我们及时沟通,互相审查代码,提高了代码质量和效率。通过结对编程,我学会了倾听他人意见、尊重不同的编程风格,也提升了自己的问题解决能力和团队协作能力。这次经历让我深刻认识到结对编程的优势,期待在未来的项目中继续运用这种高效的开发方式。
|
|
|
|
|
|
|
|
|
|