File size: 5,988 Bytes
3d20c28 cdfb731 a2274a8 0bcd8e4 cdfb731 3d20c28 cdfb731 3d20c28 cdfb731 3d20c28 cdfb731 a2274a8 0bcd8e4 cdfb731 19abad4 cdfb731 a2274a8 cdfb731 a2274a8 0bcd8e4 cdfb731 0bcd8e4 cdfb731 0bcd8e4 cdfb731 0bcd8e4 cdfb731 27db724 3d20c28 9dc9ac8 3d20c28 a2274a8 9dc9ac8 3d20c28 27db724 a2274a8 27db724 3d20c28 a2274a8 9d9efff 285b774 27db724 a2274a8 9d9efff cdfb731 0bcd8e4 cdfb731 9dc9ac8 0bcd8e4 a2274a8 0bcd8e4 cdfb731 a2274a8 3d20c28 cdfb731 0bcd8e4 98960e8 3d20c28 98960e8 b2165cc 0bcd8e4 98898c2 0bcd8e4 27db724 0bcd8e4 98960e8 0bcd8e4 a2274a8 0bcd8e4 cdfb731 3d20c28 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 |
import eventlet
# Force eventlet to be used as the async mode for Flask-SocketIO
eventlet.monkey_patch()
from flask import Flask, render_template, request
from flask_socketio import SocketIO, emit, join_room, leave_room
import backend # Import backend functions
import matplotlib.pyplot as plt
import base64
from io import BytesIO
import random
import logging
# Configure the logging level
logging.getLogger('eventlet.wsgi.server').setLevel(logging.ERROR)
app = Flask(__name__)
app.config['SECRET_KEY'] = 'your_secret_key'
socketio = SocketIO(app, async_mode='eventlet')
exams = backend.load_question_sets() # Load available exams
selected_questions = [] # Global variable to store the selected questions
current_question = {"index": 0, "answers": {}, "started": False}
participants = {}
@app.route('/')
def index():
return render_template('index.html')
@app.route('/client')
def client():
return render_template('client.html')
@app.route('/host')
def host():
return render_template('host.html', exams=exams)
@socketio.on('join')
def on_join(data):
username = data['username']
user_id_number = random.randint(1000, 9999)
participants[request.sid] = {"user_id_number": user_id_number, "username": username, "score": 0}
join_room('quiz')
emit('update_participants', {"participants": participants, "count": len(participants)}, room='quiz')
print(f"{username} (ID: {user_id_number}) joined the quiz.")
@socketio.on('disconnect')
def on_leave():
if request.sid in participants:
username = participants[request.sid]["username"]
leave_room('quiz')
del participants[request.sid]
emit('update_participants', {"participants": participants, "count": len(participants)}, room='quiz')
print(f"{username} left the quiz.")
@socketio.on('load_quiz')
def load_quiz(data):
global selected_questions, current_question
exam_name = data['exam_name']
start_question = data.get('start_question', 1) - 1 # Default to question 1 if not provided
selected_questions = backend.select_exam(exam_name)
if selected_questions:
num_questions = len(selected_questions)
current_question['index'] = start_question # Set the starting question index
emit('quiz_loaded', {"success": True, "num_questions": num_questions, "start_question": start_question + 1}, room=request.sid)
else:
emit('quiz_loaded', {"success": False}, room=request.sid)
@socketio.on('start_quiz')
def start_quiz():
if participants and selected_questions:
current_question['started'] = True
index = current_question['index']
question = selected_questions[index]
# Send the starting question to all clients
emit('new_question', {"question": question["question"], "options": question["options"], "index": index + 1}, room='quiz')
emit('enable_end_quiz', room=request.sid) # Enable "End Quiz" for the host
@socketio.on('restart_quiz')
def restart_quiz():
reset_quiz()
emit('quiz_reset', room='quiz')
start_quiz()
@socketio.on('submit_answer')
def receive_answer(data):
username = participants[request.sid]["username"]
answer = data['answer']
current_question['answers'][username] = answer
print(f"{username} submitted an answer: {answer}")
@socketio.on('check_answers')
def check_answers():
index = current_question['index']
if index < len(selected_questions):
question = selected_questions[index]
correct_answer = question['correct']
results = {
"question": question["question"],
"answers": current_question["answers"],
"correct_answer": correct_answer
}
chart_base64 = generate_chart(current_question["answers"], question["options"])
emit('display_results', {"results": results, "chart": chart_base64}, room='quiz')
for sid, participant in participants.items():
if current_question['answers'].get(participant["username"]) == correct_answer:
participants[sid]["score"] += 1
@socketio.on('next_question')
def next_question():
current_question['index'] += 1
current_question['answers'] = {}
if current_question['index'] < len(selected_questions):
question = selected_questions[current_question['index']]
emit('clear_results', room='quiz')
emit('new_question', {"question": question["question"], "options": question["options"], "index": current_question['index'] + 1}, room='quiz')
else:
final_results = calculate_final_results()
emit('display_final_results', final_results, room='quiz')
@socketio.on('end_quiz')
def end_quiz():
if current_question['started']: # Ensure the quiz has started before ending it
final_results = calculate_final_results()
emit('display_final_results', final_results, room='quiz')
reset_quiz() # Reset the quiz state
def generate_chart(answers, options):
letters = [chr(65 + i) for i in range(len(options))] # Dynamically generate letters for options
counts = [list(answers.values()).count(option) for option in options]
plt.figure(figsize=(6, 4))
plt.bar(letters, counts)
plt.xlabel('Options')
plt.ylabel('Number of Votes')
plt.title('Results')
buf = BytesIO()
plt.savefig(buf, format='png')
buf.seek(0)
chart_base64 = base64.b64encode(buf.read()).decode('utf-8')
buf.close()
plt.close()
return chart_base64
def calculate_final_results():
sorted_scores = sorted(participants.values(), key=lambda x: x['score'], reverse=True)
return [{"username": p["username"], "score": p["score"]} for p in sorted_scores]
def reset_quiz():
global selected_questions, current_question
current_question = {"index": 0, "answers": {}, "started": False}
for participant in participants.values():
participant["score"] = 0
if __name__ == '__main__':
socketio.run(app, host='0.0.0.0', port=7860, debug=False) |