|
|
@ -1,66 +1,166 @@
|
|
|
|
import unittest
|
|
|
|
from flask import Flask, render_template, request, redirect, url_for
|
|
|
|
from unittest.mock import patch, MagicMock
|
|
|
|
import pymysql
|
|
|
|
import web # 假设你的Flask app文件命名为web.py
|
|
|
|
import random
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class StartCallTestCase(unittest.TestCase):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def setUp(self):
|
|
|
|
|
|
|
|
self.app = app.test_client()
|
|
|
|
|
|
|
|
self.app.testing = True
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@patch('web.pymysql.connect') # 模拟数据库连接
|
|
|
|
|
|
|
|
def test_start_call_rendering(self, mock_connect):
|
|
|
|
|
|
|
|
# 模拟数据库返回的数据
|
|
|
|
|
|
|
|
mock_cursor = MagicMock()
|
|
|
|
|
|
|
|
mock_cursor.fetchall.return_value = [
|
|
|
|
|
|
|
|
{'id': 1, 'name': 'Alice', 'points': 10.0},
|
|
|
|
|
|
|
|
{'id': 2, 'name': 'Bob', 'points': 5.0},
|
|
|
|
|
|
|
|
{'id': 3, 'name': 'Charlie', 'points': 2.0}
|
|
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
mock_connect.return_value.cursor.return_value = mock_cursor
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 发送GET请求到/start_call
|
|
|
|
|
|
|
|
response = self.app.get('/start_call')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 验证响应状态
|
|
|
|
|
|
|
|
self.assertEqual(response.status_code, 200)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 验证是否渲染了正确的内容
|
|
|
|
|
|
|
|
response_text = response.get_data(as_text=True)
|
|
|
|
|
|
|
|
self.assertIn('pstuents', response_text) # 检查渲染内容
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@patch('web.pymysql.connect') # 模拟数据库连接
|
|
|
|
|
|
|
|
def test_weighted_random_selection(self, mock_connect):
|
|
|
|
|
|
|
|
# 模拟数据库返回的数据
|
|
|
|
|
|
|
|
mock_cursor = MagicMock()
|
|
|
|
|
|
|
|
mock_cursor.fetchall.return_value = [
|
|
|
|
|
|
|
|
{'id': 1, 'name': 'Alice', 'points': 10.0}, # Alice的权重最低
|
|
|
|
|
|
|
|
{'id': 2, 'name': 'Bob', 'points': 5.0}, # Bob的权重次之
|
|
|
|
|
|
|
|
{'id': 3, 'name': 'Charlie', 'points': 2.0} # Charlie的权重最高
|
|
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
mock_connect.return_value.cursor.return_value = mock_cursor
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 存储选择结果的字典
|
|
|
|
|
|
|
|
selection_count = {'Alice': 0, 'Bob': 0, 'Charlie': 0}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 进行多次调用来验证随机性
|
|
|
|
|
|
|
|
for _ in range(100):
|
|
|
|
|
|
|
|
response = self.app.get('/start_call')
|
|
|
|
|
|
|
|
response_text = response.get_data(as_text=True)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 统计每个学生的选择次数
|
|
|
|
|
|
|
|
if 'Alice' in response_text:
|
|
|
|
|
|
|
|
selection_count['Alice'] += 1
|
|
|
|
|
|
|
|
elif 'Bob' in response_text:
|
|
|
|
|
|
|
|
selection_count['Bob'] += 1
|
|
|
|
|
|
|
|
elif 'Charlie' in response_text:
|
|
|
|
|
|
|
|
selection_count['Charlie'] += 1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 验证选择的相对概率
|
|
|
|
|
|
|
|
self.assertTrue(selection_count['Charlie'] > selection_count['Bob'])
|
|
|
|
|
|
|
|
self.assertTrue(selection_count['Bob'] > selection_count['Alice'])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
app = Flask(__name__)
|
|
|
|
|
|
|
|
app.secret_key = 'your_secret_key'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_db_connection():
|
|
|
|
|
|
|
|
connection = pymysql.connect(
|
|
|
|
|
|
|
|
host='localhost',
|
|
|
|
|
|
|
|
user='root',
|
|
|
|
|
|
|
|
password='root',
|
|
|
|
|
|
|
|
db='unicom',
|
|
|
|
|
|
|
|
charset='utf8mb4',
|
|
|
|
|
|
|
|
cursorclass=pymysql.cursors.DictCursor
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
return connection
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@app.route('/')
|
|
|
|
|
|
|
|
def index():
|
|
|
|
|
|
|
|
return render_template('index.html')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@app.route('/start_call')
|
|
|
|
|
|
|
|
def start_call():
|
|
|
|
|
|
|
|
connection = get_db_connection()
|
|
|
|
|
|
|
|
with connection.cursor() as cursor:
|
|
|
|
|
|
|
|
cursor.execute("SELECT * FROM students ORDER BY points ASC")
|
|
|
|
|
|
|
|
students = cursor.fetchall()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
total_weight = sum(1 / (s['points'] + 1) for s in students)
|
|
|
|
|
|
|
|
random_number = random.uniform(0, total_weight)
|
|
|
|
|
|
|
|
cumulative_weight = 0
|
|
|
|
|
|
|
|
selected_student = None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for student in students:
|
|
|
|
|
|
|
|
weight = 1 / (student['points'] + 1)
|
|
|
|
|
|
|
|
cumulative_weight += weight
|
|
|
|
|
|
|
|
if cumulative_weight >= random_number:
|
|
|
|
|
|
|
|
selected_student = student
|
|
|
|
|
|
|
|
break
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return render_template('call.html', student=selected_student)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@app.route('/record_attendance', methods=['POST'])
|
|
|
|
|
|
|
|
def record_attendance():
|
|
|
|
|
|
|
|
student_id = request.form['student_id']
|
|
|
|
|
|
|
|
is_present = request.form['is_present']
|
|
|
|
|
|
|
|
use_shield = request.form.get('use_shield')
|
|
|
|
|
|
|
|
answer_question = request.form.get('answer_question')
|
|
|
|
|
|
|
|
repeat_question = request.form.get('repeat_question')
|
|
|
|
|
|
|
|
score = request.form.get('score')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
connection = get_db_connection()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
with connection.cursor() as cursor:
|
|
|
|
|
|
|
|
if is_present == 'yes':
|
|
|
|
|
|
|
|
if use_shield == 'yes':
|
|
|
|
|
|
|
|
# 使用护盾,积分+2,护盾数量减1
|
|
|
|
|
|
|
|
cursor.execute(
|
|
|
|
|
|
|
|
"UPDATE students SET points = points + 2, has_shield = has_shield - 1, consecutive_calls = consecutive_calls-3 WHERE id = %s AND has_shield > 0",
|
|
|
|
|
|
|
|
(student_id,))
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
cursor.execute("UPDATE students SET points = points + 1 WHERE id = %s", (student_id,))
|
|
|
|
|
|
|
|
if answer_question == 'yes':
|
|
|
|
|
|
|
|
if repeat_question == 'yes':
|
|
|
|
|
|
|
|
cursor.execute("UPDATE students SET points = points + 0.5 WHERE id = %s", (student_id,))
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
cursor.execute("UPDATE students SET points = points - 1 WHERE id = %s", (student_id,))
|
|
|
|
|
|
|
|
cursor.execute("UPDATE students SET consecutive_calls = consecutive_calls + 1 WHERE id = %s",
|
|
|
|
|
|
|
|
(student_id,))
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
cursor.execute("UPDATE students SET consecutive_calls = 0 WHERE id = %s", (student_id,))
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
cursor.execute("UPDATE students SET consecutive_calls = 0 WHERE id = %s", (student_id,))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cursor.execute("SELECT consecutive_calls FROM students WHERE id = %s", (student_id,))
|
|
|
|
|
|
|
|
result = cursor.fetchone()
|
|
|
|
|
|
|
|
if result['consecutive_calls'] >= 3:
|
|
|
|
|
|
|
|
cursor.execute("UPDATE students SET has_shield = has_shield + 1 WHERE id = %s", (student_id,))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if score:
|
|
|
|
|
|
|
|
cursor.execute("UPDATE students SET points = points + %s WHERE id = %s", (float(score), student_id))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
connection.commit()
|
|
|
|
|
|
|
|
connection.close()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return redirect(url_for('start_call'))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@app.route('/rank')
|
|
|
|
|
|
|
|
def show_rank():
|
|
|
|
|
|
|
|
# 连接数据库
|
|
|
|
|
|
|
|
connection = get_db_connection()
|
|
|
|
|
|
|
|
cursor = connection.cursor()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 查询学生积分
|
|
|
|
|
|
|
|
query = "SELECT name, points, has_shield FROM students ORDER BY points DESC"
|
|
|
|
|
|
|
|
cursor.execute(query)
|
|
|
|
|
|
|
|
students = cursor.fetchall()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 关闭数据库连接
|
|
|
|
|
|
|
|
cursor.close()
|
|
|
|
|
|
|
|
connection.close()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 渲染排名页面
|
|
|
|
|
|
|
|
return render_template('rank.html', students=students)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@app.route('/myclass')
|
|
|
|
|
|
|
|
def show_students():
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
|
|
|
connection = get_db_connection()
|
|
|
|
|
|
|
|
cursor = connection.cursor()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
query = "SELECT id, name FROM students"
|
|
|
|
|
|
|
|
cursor.execute(query)
|
|
|
|
|
|
|
|
students = cursor.fetchall() # 获取所有学生
|
|
|
|
|
|
|
|
print(students)
|
|
|
|
|
|
|
|
# 将数据转换为字典列表
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
|
|
print("Error:", e) # 打印错误信息
|
|
|
|
|
|
|
|
students_list = [] # 若发生错误,确保students_list为空
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
finally:
|
|
|
|
|
|
|
|
cursor.close()
|
|
|
|
|
|
|
|
connection.close()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return render_template('myclass.html', students=students)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@app.route('/help')
|
|
|
|
|
|
|
|
def helpme():
|
|
|
|
|
|
|
|
return render_template('帮助中心.html')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@app.route('/mes')
|
|
|
|
|
|
|
|
def mes():
|
|
|
|
|
|
|
|
return render_template('个人信息.html')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@app.route('/cmes')
|
|
|
|
|
|
|
|
def cmes():
|
|
|
|
|
|
|
|
return render_template('课程信息.html')
|
|
|
|
|
|
|
|
@app.route('/us')
|
|
|
|
|
|
|
|
def us():
|
|
|
|
|
|
|
|
return render_template('关于我们.html')
|
|
|
|
|
|
|
|
@app.route('/cus')
|
|
|
|
|
|
|
|
def cus():
|
|
|
|
|
|
|
|
return render_template('联系我们.html')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@app.route('/submit_feedback',methods=['POST'])
|
|
|
|
|
|
|
|
def u():
|
|
|
|
|
|
|
|
return '反馈成功!'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@app.route('/back')
|
|
|
|
|
|
|
|
def back():
|
|
|
|
|
|
|
|
return render_template('用户反馈.html')
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
if __name__ == '__main__':
|
|
|
|
unittest.main()
|
|
|
|
app.run(debug=True)这是web.py的代码测试其中的start_call
|