Compare commits

..

No commits in common. 'main' and 'test' have entirely different histories.
main ... test

@ -1,169 +0,0 @@
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)

Binary file not shown.

@ -1,64 +0,0 @@
<!DOCTYPE html>
<html lang="zh-ch">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="main.css">
<link rel="shortcut icon" href="img/fzu.jpg" type="image/x-icon">
<title>代码双侠的点名网站</title>
</head>
<body>
<div class="bg">
<div class="proflieCard">
<div class="logo1">
<img src="img/fzu.jpg" alt="" class="logo2">
</div>
<p class="name">欢迎光临</p>
<div class="buttons">
<button class="button1" onclick="startExtraction()">开始点名</button>
</div>
<footer class="footer">
<p class="footer2">&nbsp 作者 <a>代码双侠</a></p>
</footer>
</div>
<div class="newScreen" style="display: none">
<div class="logo1">
<img src="img/fzu.jpg" alt="" class="logo2">
</div>
<div class="buttons">
<button class="button1" onclick="importFile()">导入文件</button>
<button class="button1" onclick="exportFile()">导出文件</button>
<br>
<button class="button1" onclick="drawStudent()">抽取一次</button>
<button class="button1" onclick="drawTenStudents()">抽取十次</button>
</div>
<div id="selectedStudent"></div>
</div>
</div>
<div class="background" id="background"></div>
<div class="yinghua" id="yinghua"></div>
<div class="background2" id="background2"></div>
<script src="main.js"></script>
<script>
window.onload=load2D_bg();
window.onload=load2D_bg2();
window.onload=load2D_bg2_2();//不写注释一时爽,写完再看火葬场
window.onload=load2D_yinghua();
</script>
</body>
</html>

@ -1,223 +0,0 @@
html {
position: relative;
}
body {
font-family: '汉仪蝶语体简', sans-serif;
padding:0;
margin:0;
}
.bg{
top: -5cm; left: 0;
width: 100%;
height: 100%;
min-height: 100vh;
position: absolute;
z-index: 0;
display: flex;
justify-content: center;
align-items: center;
}
.newScreen {
position: relative;
left:0;
z-index: 0 ;
}
.background{
top: 0; left: 0;
width: 100%;
height: 100%;
min-height: 100vh;
background-image: url("img/background.png");
position: absolute;
z-index: -5;
display: flex;
justify-content: center;
align-items: center;
}
.background2{
top: 0; left: 0;
width: 100%;
height: 100%;
min-height: 100vh;
background-image: url("img/background2.png");
position: absolute;
z-index: -4;
}
.yinghua{
top: 0; left: 0;
width: 100%;
height: 100%;
min-height: 100vh;
background-image: url("img/yinghua.png");
position: absolute;
z-index: -1;
}
@media screen and (max-width : 768px) {
.background {
background-size:cover;
}
.background2 {
background-size:cover;
}
}
@media screen and (max-width : 1000px) {
.background {
background-size:130%;
}
.background2 {
background-size:130%;
}
}
@media screen and (max-width : 2333333px) {
.background {
background-size:130%;
}
.background2 {
background-size:130%;
}
}
.profileCard{
z-index: 0;
}
.logo1{
margin: auto;
margin-top: -100px;
width: 200px;
height: 200px;
/*background-color: rgba(255, 255, 255, 0.4);
border-radius: 50%;
box-shadow: 0px 0px 10px #ffffff;
*/
}
.logo2{
width: 180px;
height: 180px;
margin: 5px 5px;
border-radius: 50%;
border: 2px solid rgba(255, 255, 255, 0.8);
box-shadow: 0px 0px 12px rgba(255, 255, 255, 0.9);
transition: all 1s;
/*box-shadow: 0px 0px 10px #ffffff;*/
}
.logo2:hover{
transform: rotate(360deg);
box-shadow: 0px 0px 50px rgba(255, 255, 255, 1);
transition: all 1s;
/*box-shadow: 0px 0px 10px #ffffff;*/
}
.name{
margin-top: 5px;
text-align: center;
font-size: 30px;
color: white;
font-weight: 500;
text-shadow: 0px 0px 12px white;
transition: all 0.5s;
}
.name:hover{
text-shadow: 0px 0px 30px white;
transition: all 0.5s;
}
.slogan{
margin: auto;
width: 600px;
height: 50px;
background-color: rgba(255, 255, 255, 0.1);
border: 1px solid rgba(255, 255, 255, 0.8);
text-shadow: 0px 0px 12px #ffffff;
box-shadow: 0px 0px 12px #ffffff;
border-radius: 30px;
display: flex;
justify-content: center;
align-items: center;
transition: all 0.5s;
}
.slogan:hover{
background-color: rgba(255, 255, 255, 0.4);
box-shadow: 0px 0px 25px #ffffff;
transition: all 0.5s;
}
.slogan2{
text-align: center;
color: rgba(255, 255, 255, 1);
font-size: 16px;
max-width: 500px;
}
.buttons{
margin-top: 15px;
margin-right: auto;
margin-left: auto;
width: 500px;
height: 100px;
display: flex;
justify-content: center;
align-items: center;
}
.button1{
margin-left: 10px;
margin-right: 10px;
height: 50px;
width: 200px;
border: 1px solid rgba(255, 255, 255, 0.4);
border-radius: 25px;
background-color: rgba(255, 255, 255, 0.1);
color: white;
font-size: 16px;
transition: all 0.5s;
}
.button1:hover{
background-color: rgba(255, 255, 255, 0.4);
color: #ffffff;
box-shadow: 0px 0px 12px #ffffff;
transition: all 0.5s;
}
.lihui{
position: fixed;
background-image: url("img/lihui.texb");
width: 700px;
height: 700px;
left: -100px;
bottom: 0;
background-size: cover;
z-index: -2;
}
.footer{
position: absolute;
left: 50%;
transform: translateX(-50%);
bottom: 0px;
color:rgba(255, 255, 255, 0.8);
font-size: 20px;
}
.footer2{
text-align: center;
}
a{
color: rgba(255, 255, 255, 0.8);
}

@ -1,299 +0,0 @@
const randomPhrases = [
"就决定是你了!: ${name} (${id}), 积分: ${score}",
"真相只有一个!: ${name} (${id}), 积分: ${score}",
"你被选中了!: ${name} (${id}), 积分: ${score}",
"幸运儿是你!: ${name} (${id}), 积分: ${score}",
"命运之轮转动!: ${name} (${id}), 积分: ${score}",
"你想成为一个【大人物】吗?: ${name} (${id}), pipis: ${score}",
"你醒啦?你现在是一个 ${name} 了,不要忘了(${id}), 你还能活 ${score}天"
];
function load2D_bg(){
var background = document.getElementById("background");
var range = 40;
var calcValue = function calcValue(a, b) {
return (a / b * range - range / 2).toFixed(1);
};
var timeout = void 0;
document.addEventListener('mousemove',
function(_ref) {
var x = _ref.x,
y = _ref.y;
if (timeout) {
window.cancelAnimationFrame(timeout);
}
timeout = window.requestAnimationFrame(function() {
var yValue = calcValue(y, window.innerHeight);
var xValue = calcValue(x, window.innerWidth);
background.style.backgroundPositionX = xValue * 1 -200+ "px ";
background.style.backgroundPositionY = (-yValue * 0.75-50 ) + "px";
})
},false);
}
function load2D_bg2(){
var background = document.getElementById("background2");
var range = 40;
var calcValue = function calcValue(a, b) {
return (a / b * range - range / 2).toFixed(1);
};
var timeout = void 0;
document.addEventListener('mousemove',
function(_ref) {
var x = _ref.x,
y = _ref.y;
if (timeout) {
window.cancelAnimationFrame(timeout);
}
timeout = window.requestAnimationFrame(function() {
var yValue = calcValue(y, window.innerHeight);
var xValue = calcValue(x, window.innerWidth);
background.style.backgroundPositionX = xValue *1 -200+ "px ";
background.style.backgroundPositionY = (-yValue * 0.75-50 ) + "px";
})
},false);
}
function load2D_bg2_2(){
var background = document.getElementById("background2");
document.onmousemove=function(){
console.log(window.outerHeight);
background.style.opacity=1-(getMousePos()/window.outerHeight*2.5);
}
}
function getMousePos(event) {
var e = event || window.event;
var scrollY = document.documentElement.scrollTop || document.body.scrollTop;
var y = e.pageY || e.clientY + scrollY;
return y;
}
function load2D_yinghua(){
var background = document.getElementById("yinghua");
var range = 40;
var calcValue = function calcValue(a, b) {
return (a / b * range - range / 2).toFixed(1);
};
var timeout = void 0;
document.addEventListener('mousemove',
function(_ref) {
var x = _ref.x,
y = _ref.y;
if (timeout) {
window.cancelAnimationFrame(timeout);
}
timeout = window.requestAnimationFrame(function() {
var yValue = calcValue(y, window.innerHeight);
var xValue = calcValue(x, window.innerWidth);
background.style.backgroundPositionX = xValue * 1.5 -200+ "px ";
background.style.backgroundPositionY = (-yValue * 1-50 ) + "px";
})
},false);
}
var i=0;
function startExtraction() {
// 渐隐现有画面
document.querySelector('.proflieCard').style.transition = 'opacity 1s';
document.querySelector('.proflieCard').style.opacity = '0';
// 1秒后显示新画面
setTimeout(function() {
document.querySelector('.proflieCard').style.display = 'none';
document.querySelector('.newScreen').style.display = 'block';
document.querySelector('.newScreen').style.opacity = '1';
}, 1000);
}
function importFile() {
const input = document.createElement('input');
input.type = 'file';
input.accept = '.xlsx';
input.onchange = function(event) {
const file = event.target.files[0];
if (file) {
const formData = new FormData();
formData.append('file', file);
fetch('http://127.0.0.1:5000/upload', {
method: 'POST',
body: formData
})
.then(response => response.json())
.then(data => {
if (data.success) {
alert('导入成功');
} else {
alert('导入失败');
}
})
.catch(error => {
console.error('Error:', error);
alert('导入失败');
});
}
};
input.click();
}
function drawStudent() {
// 发送请求到服务器的 /select_student 路由
fetch('http://127.0.0.1:5000/select_student')
.then(response => {
// 确保我们得到了一个成功的响应
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(data => {
// 将抽取的学生信息显示在界面上
if (data && data.name && data.id) {
const studentInfo = document.getElementById('selectedStudent');
const randomPhrase = randomPhrases[Math.floor(Math.random() * randomPhrases.length)];
const phraseWithData = randomPhrase
.replace('${name}', data.name)
.replace('${id}', data.id)
.replace('${score}', data.score);
studentInfo.innerHTML = `
<p style="font-size: 24px;">${phraseWithData}</p>
<button class = button1 id = "arrivedButton">到达课堂</button>
<div id="scoreButtons" style="display: none;">
<button class = button1 id="repeatedButton" style="margin: 40px 0; left = 1cm">正确重复</button>
<button class = button1 id="distractedButton" style="margin: 10px 0;">上课走神</button>
<br>
<input type="number" id="correctInput" placeholder="输入分数" style = "width: 200px;">
<button class = button1 id="addScoreButton" style="margin: 10px 0;">加分</button>
</div>
`;
// 添加事件监听器
const arrivedButton = document.getElementById('arrivedButton');
const repeatedButton = document.getElementById('repeatedButton');
const distractedButton = document.getElementById('distractedButton');
const correctInput = document.getElementById('correctInput');
const addScoreButton = document.getElementById('addScoreButton');
const scoreButtons = document.getElementById('scoreButtons');
arrivedButton.onclick = () => {
updateScore(data.id, 1, 0, 0);
scoreButtons.style.display = 'block';
};
repeatedButton.onclick = () => updateScore(data.id, 0, 1, 0);
distractedButton.onclick = () => updateScore(data.id, 0, 2, 0);
addScoreButton.onclick = () => {
const correct = parseFloat(correctInput.value) || 0;
updateScore(data.id, 0, 0, correct);
};
if (data.score >= 1) {
fetch(`http://127.0.0.1:5000/check_probability?id=${data.id}`)
.then(response => response.json())
.then(probData => {
if (probData.probability < 0.02) {
alert(`恭喜${data.name}同学喜提超级无敌终极宇宙至尊非酋称号!!!`);
} else if (probData.probability < 0.1) {
alert(`恭喜${data.name}同学喜提万中挑一的非酋称号!!!`);
}
})
.catch(error => {
console.error('Error:', error);
});
}
} else {
const studentInfo = document.getElementById('selectedStudent');
studentInfo.innerHTML = '<p>No student selected.</p>';
}
})
.catch(error => {
console.error('你的fetch被GAY了:', error);
});
}
function updateScore(studentId, arrived, repeated, correct) {
fetch('http://127.0.0.1:5000/update_score', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
id: studentId,
arrived: arrived,
repeated: repeated,
correct: correct
})
})
.then(response => response.json())
.then(data => {
if (data.success) {
alert(`更新积分成功。新的积分: ${data.score}`);
} else {
alert(`难以更新积分: ${data.error}`);
}
})
.catch(error => {
console.error('你的fetch被GAY了:', error);
});
}
function exportFile() {
fetch('http://127.0.0.1:5000/export_file')
.then(response => response.blob())
.then(blob => {
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'students.xlsx';
document.body.appendChild(a);
a.click();
a.remove();
})
.catch(error => {
console.error('Error:', error);
alert('导出文件失败');
});
}
function drawTenStudents() {
// 发送请求到服务器的 /select_ten_students 路由
fetch('http://127.0.0.1:5000/select_ten_students')
.then(response => {
// 确保我们得到了一个成功的响应
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(data => {
// 将抽取的十个学生信息显示在界面上
if (data && data.students) {
const studentInfo = document.getElementById('selectedStudent');
studentInfo.innerHTML = ''; // 清空之前的内容
data.students.forEach(student => {
studentInfo.innerHTML += `
<p style="font-size: 24px;">人多力量大: ${student.name} (${student.id}), 积分: ${student.score}</p>
`;
});
} else {
const studentInfo = document.getElementById('selectedStudent');
studentInfo.innerHTML = '<p>No students selected.</p>';
}
})
.catch(error => {
console.error('你的fetch被GAY了:', error);
});
}

@ -0,0 +1 @@
undefined
Loading…
Cancel
Save