File size: 5,988 Bytes
e1c798c 78447bc b688782 e1c798c b688782 78447bc 4648733 78447bc c17c125 ab240d1 c17c125 ab240d1 c17c125 ab240d1 d72d0a0 c17c125 ab240d1 91f4d25 ab240d1 148d537 78447bc d72d0a0 78447bc d72d0a0 78447bc 0df3de5 |
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) |