Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -7,58 +7,56 @@ selected_questions = []
|
|
7 |
|
8 |
description_str = """Developed by Ruslan Magana, this interactive quiz platform is designed to help you prepare and assess your knowledge in a variety of exams.
|
9 |
For more information about the developer, please visit [ruslanmv.com](https://ruslanmv.com/).
|
10 |
-
|
11 |
-
**Get Started with Your Quiz**
|
12 |
Select an exam from the dropdown menu below and start testing your skills. You can also choose to enable audio feedback to enhance your learning experience. Simply toggle the "Enable Audio" checkbox to turn it on or off."""
|
13 |
|
14 |
# --- FUNCTION DEFINITIONS ---
|
15 |
|
16 |
def start_exam(exam_choice, start_question, audio_enabled):
|
17 |
-
"""Starts the exam by selecting questions
|
18 |
global selected_questions
|
19 |
selected_questions = select_exam_vce(exam_choice)
|
20 |
|
21 |
if start_question >= len(selected_questions):
|
22 |
-
start_question = 0 # Default to the first question if
|
23 |
|
24 |
question, options, audio_path = display_question(start_question, audio_enabled)
|
25 |
|
26 |
return (
|
27 |
-
# Hide
|
28 |
gr.update(visible=False), # Hide title
|
29 |
-
gr.update(visible=False),
|
30 |
-
gr.update(visible=False),
|
31 |
-
gr.update(visible=False),
|
32 |
gr.update(visible=False), # Hide the audio_checkbox
|
33 |
gr.update(visible=False), # Hide start_question_slider
|
34 |
# Show quiz elements
|
35 |
-
gr.update(visible=True),
|
36 |
-
question,
|
37 |
-
gr.update(choices=options, visible=True), # Update Radio choices
|
38 |
-
gr.update(visible=True),
|
39 |
-
gr.update(visible=True)
|
40 |
-
gr.update(visible=True),
|
41 |
-
gr.update(visible=True),
|
42 |
-
start_question, "",
|
43 |
-
audio_path,
|
44 |
-
gr.update(visible=True),
|
45 |
gr.update(visible=True),
|
46 |
-
None
|
47 |
)
|
48 |
|
49 |
def display_question(index, audio_enabled):
|
50 |
-
"""Displays a question with options and generates audio if enabled."""
|
51 |
if index < 0 or index >= len(selected_questions):
|
52 |
return "No more questions.", [], None
|
53 |
-
|
54 |
question_text_ = selected_questions[index].get('question', 'No question text available.')
|
55 |
-
question_text = f"**Question {index}:** {question_text_}"
|
56 |
choices_options = selected_questions[index].get('options', [])
|
57 |
audio_path = text_to_speech(question_text_ + " " + " ".join(choices_options)) if audio_enabled else None
|
58 |
return question_text, choices_options, audio_path
|
59 |
|
60 |
def show_explanation(index):
|
61 |
-
"""Shows the explanation for the current question."""
|
62 |
if 0 <= index < len(selected_questions):
|
63 |
explanation = selected_questions[index].get('explanation', 'No explanation available for this question.')
|
64 |
return (
|
@@ -78,77 +76,67 @@ def check_answer(index, answer):
|
|
78 |
return f"Incorrect. The correct answer is: {correct_answer}"
|
79 |
|
80 |
def update_question(index, audio_enabled):
|
81 |
-
"""Updates the displayed question when
|
82 |
question, options, audio_path = display_question(index, audio_enabled)
|
83 |
return question, gr.update(choices=options), index, audio_path
|
84 |
|
85 |
def handle_answer(index, answer, audio_enabled, current_audio):
|
86 |
-
"""Handles answer submission and generates
|
|
|
87 |
if answer is None:
|
88 |
return "Please select an option before submitting.", None, None
|
89 |
|
90 |
-
# Stop
|
91 |
stop_audio = True if current_audio else False
|
92 |
result = check_answer(index, answer)
|
93 |
answer_audio_path = text_to_speech(result) if audio_enabled else None
|
94 |
return result, answer_audio_path, stop_audio
|
95 |
|
|
|
96 |
def handle_next(index, audio_enabled):
|
97 |
-
"""Moves to the next question."""
|
98 |
new_index = min(index + 1, len(selected_questions) - 1)
|
99 |
question, options, new_index, audio_path = update_question(new_index, audio_enabled)
|
100 |
-
|
101 |
-
return question, options, new_index, "", audio_path, gr.update(visible=False)
|
102 |
|
103 |
def handle_previous(index, audio_enabled):
|
104 |
-
"""Moves to the previous question."""
|
105 |
new_index = max(index - 1, 0)
|
106 |
question, options, new_index, audio_path = update_question(new_index, audio_enabled)
|
107 |
-
|
108 |
-
return question, options, new_index, "", audio_path, gr.update(visible=False)
|
109 |
|
110 |
def return_home():
|
111 |
"""Returns to the home screen."""
|
112 |
return (
|
113 |
# Show start screen elements
|
114 |
-
gr.update(visible=True),
|
115 |
-
gr.update(visible=True), #
|
116 |
-
gr.update(visible=
|
117 |
-
gr.update(visible=
|
118 |
-
gr.update(visible=
|
119 |
-
gr.update(visible=True), # start_question_slider
|
120 |
-
# Hide quiz elements
|
121 |
-
gr.update(visible=False), gr.update(visible=False), gr.update(visible=False),
|
122 |
-
gr.update(visible=False), gr.update(visible=False), gr.update(visible=False),
|
123 |
-
gr.update(visible=False), 0, "", gr.update(visible=False), gr.update(visible=False), None
|
124 |
)
|
125 |
|
126 |
-
with gr.Blocks(
|
127 |
# Home page elements
|
128 |
-
title = gr.Markdown(value="**Exam Simulator (Quiz)**")
|
129 |
description = gr.Markdown(value=description_str)
|
130 |
exam_selector = gr.Dropdown(label="Select an exam", choices=exams, value=None)
|
131 |
audio_checkbox = gr.Checkbox(label="Enable Audio", value=True, visible=False)
|
132 |
-
start_question_slider = gr.Slider(minimum=0, maximum=50, step=1, label="Select starting question", visible=False)
|
133 |
start_button = gr.Button("Start Exam", visible=False)
|
134 |
|
135 |
# Quiz elements (initially hidden)
|
136 |
question_state = gr.State(0)
|
137 |
-
current_audio_state = gr.State(None)
|
138 |
-
|
139 |
-
# Use elem_id to link to our CSS for vertical display
|
140 |
question_text = gr.Markdown(visible=False, elem_id="question-text")
|
141 |
-
choices = gr.Radio(visible=False, label="Options"
|
142 |
-
|
143 |
result_text = gr.Markdown(visible=True)
|
144 |
explanation_text = gr.Markdown(visible=False)
|
145 |
-
|
146 |
answer_button = gr.Button("Submit Answer", visible=False)
|
147 |
next_button = gr.Button("Next Question", visible=False)
|
148 |
prev_button = gr.Button("Previous Question", visible=False)
|
149 |
home_button = gr.Button("Return to Home", visible=False)
|
150 |
explain_button = gr.Button("Explain", visible=False)
|
151 |
-
|
152 |
question_audio = gr.Audio(visible=False, label="Question Audio", autoplay=True)
|
153 |
answer_audio = gr.Audio(visible=False, label="Answer Audio", autoplay=True)
|
154 |
|
@@ -182,63 +170,38 @@ with gr.Blocks(css="style1.css") as demo: # <--- Include your custom CSS file h
|
|
182 |
|
183 |
# Show settings after exam selection
|
184 |
def show_settings(exam_choice):
|
185 |
-
# When an exam is chosen, show the audio checkbox, slider, and start button
|
186 |
return gr.update(visible=True), gr.update(visible=True), gr.update(visible=True)
|
187 |
|
188 |
-
|
189 |
-
|
190 |
-
inputs=[exam_selector],
|
191 |
-
outputs=[audio_checkbox, start_question_slider, start_button]
|
192 |
-
)
|
193 |
|
194 |
-
# Connect start button
|
195 |
start_button.click(
|
196 |
fn=start_exam,
|
197 |
inputs=[exam_selector, start_question_slider, audio_checkbox],
|
198 |
outputs=[
|
199 |
title, description, exam_selector, start_button,
|
200 |
-
audio_checkbox,
|
|
|
201 |
question_text, question_text, choices, answer_button,
|
202 |
next_button, prev_button, home_button, question_state, result_text, question_audio,
|
203 |
-
explain_button, result_text, current_audio_state
|
204 |
]
|
205 |
)
|
206 |
|
207 |
-
# Connect quiz
|
208 |
-
answer_button.click(
|
209 |
-
|
210 |
-
|
211 |
-
outputs=[result_text, answer_audio, current_audio_state]
|
212 |
-
)
|
213 |
|
214 |
-
|
215 |
-
fn=handle_next,
|
216 |
-
inputs=[question_state, audio_checkbox],
|
217 |
-
outputs=[question_text, choices, question_state, result_text, question_audio, explanation_text]
|
218 |
-
)
|
219 |
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
fn=show_explanation,
|
228 |
-
inputs=[question_state],
|
229 |
-
outputs=[explanation_text, result_text, explanation_text]
|
230 |
-
)
|
231 |
-
|
232 |
-
home_button.click(
|
233 |
-
fn=return_home,
|
234 |
-
inputs=None,
|
235 |
-
outputs=[
|
236 |
-
title, description, exam_selector, start_button,
|
237 |
-
audio_checkbox, start_question_slider,
|
238 |
-
question_text, question_text, choices, answer_button,
|
239 |
-
next_button, prev_button, home_button, question_state,
|
240 |
-
result_text, explanation_text, explain_button, current_audio_state
|
241 |
-
]
|
242 |
-
)
|
243 |
|
244 |
-
demo.launch()
|
|
|
7 |
|
8 |
description_str = """Developed by Ruslan Magana, this interactive quiz platform is designed to help you prepare and assess your knowledge in a variety of exams.
|
9 |
For more information about the developer, please visit [ruslanmv.com](https://ruslanmv.com/).
|
10 |
+
**Get Started with Your Quiz**
|
|
|
11 |
Select an exam from the dropdown menu below and start testing your skills. You can also choose to enable audio feedback to enhance your learning experience. Simply toggle the "Enable Audio" checkbox to turn it on or off."""
|
12 |
|
13 |
# --- FUNCTION DEFINITIONS ---
|
14 |
|
15 |
def start_exam(exam_choice, start_question, audio_enabled):
|
16 |
+
"""Starts the exam by selecting questions, setting up UI."""
|
17 |
global selected_questions
|
18 |
selected_questions = select_exam_vce(exam_choice)
|
19 |
|
20 |
if start_question >= len(selected_questions):
|
21 |
+
start_question = 0 # Default to the first question if the input exceeds available questions
|
22 |
|
23 |
question, options, audio_path = display_question(start_question, audio_enabled)
|
24 |
|
25 |
return (
|
26 |
+
# Hide start screen elements
|
27 |
gr.update(visible=False), # Hide title
|
28 |
+
gr.update(visible=False), # Hide description
|
29 |
+
gr.update(visible=False), # Hide exam_selector
|
30 |
+
gr.update(visible=False), # Hide start_button
|
31 |
gr.update(visible=False), # Hide the audio_checkbox
|
32 |
gr.update(visible=False), # Hide start_question_slider
|
33 |
# Show quiz elements
|
34 |
+
gr.update(visible=True), # Show question_text
|
35 |
+
question, # Question to display
|
36 |
+
gr.update(choices=options, visible=True), # Update Radio choices and make visible
|
37 |
+
gr.update(visible=True), # Show answer_button
|
38 |
+
gr.update(visible=True),# Show next_button
|
39 |
+
gr.update(visible=True), # Show prev_button
|
40 |
+
gr.update(visible=True), # Show home_button
|
41 |
+
start_question, "", # Update the question state
|
42 |
+
audio_path, # Provide the audio_path
|
43 |
+
gr.update(visible=True), # Show explain_button
|
44 |
gr.update(visible=True),
|
45 |
+
None # None for the audio stop signal
|
46 |
)
|
47 |
|
48 |
def display_question(index, audio_enabled):
|
49 |
+
"""Displays a question with options and generates audio (if enabled)."""
|
50 |
if index < 0 or index >= len(selected_questions):
|
51 |
return "No more questions.", [], None
|
|
|
52 |
question_text_ = selected_questions[index].get('question', 'No question text available.')
|
53 |
+
question_text = f"**Question {index }:** {question_text_}"
|
54 |
choices_options = selected_questions[index].get('options', [])
|
55 |
audio_path = text_to_speech(question_text_ + " " + " ".join(choices_options)) if audio_enabled else None
|
56 |
return question_text, choices_options, audio_path
|
57 |
|
58 |
def show_explanation(index):
|
59 |
+
"""Shows the explanation for the current question and hides previous results."""
|
60 |
if 0 <= index < len(selected_questions):
|
61 |
explanation = selected_questions[index].get('explanation', 'No explanation available for this question.')
|
62 |
return (
|
|
|
76 |
return f"Incorrect. The correct answer is: {correct_answer}"
|
77 |
|
78 |
def update_question(index, audio_enabled):
|
79 |
+
"""Updates the displayed question when the index changes."""
|
80 |
question, options, audio_path = display_question(index, audio_enabled)
|
81 |
return question, gr.update(choices=options), index, audio_path
|
82 |
|
83 |
def handle_answer(index, answer, audio_enabled, current_audio):
|
84 |
+
"""Handles answer submission, provides feedback, and generates audio."""
|
85 |
+
# Handle the case when no answer is selected
|
86 |
if answer is None:
|
87 |
return "Please select an option before submitting.", None, None
|
88 |
|
89 |
+
# Stop the current question audio before playing the answer audio
|
90 |
stop_audio = True if current_audio else False
|
91 |
result = check_answer(index, answer)
|
92 |
answer_audio_path = text_to_speech(result) if audio_enabled else None
|
93 |
return result, answer_audio_path, stop_audio
|
94 |
|
95 |
+
|
96 |
def handle_next(index, audio_enabled):
|
97 |
+
"""Moves to the next question and updates the UI."""
|
98 |
new_index = min(index + 1, len(selected_questions) - 1)
|
99 |
question, options, new_index, audio_path = update_question(new_index, audio_enabled)
|
100 |
+
return question, options, new_index, "", audio_path, gr.update(visible=False) # Hide explanation
|
|
|
101 |
|
102 |
def handle_previous(index, audio_enabled):
|
103 |
+
"""Moves to the previous question and updates the UI."""
|
104 |
new_index = max(index - 1, 0)
|
105 |
question, options, new_index, audio_path = update_question(new_index, audio_enabled)
|
106 |
+
return question, options, new_index, "", audio_path, gr.update(visible=False) # Hide explanation
|
|
|
107 |
|
108 |
def return_home():
|
109 |
"""Returns to the home screen."""
|
110 |
return (
|
111 |
# Show start screen elements
|
112 |
+
gr.update(visible=True), gr.update(visible=True), gr.update(visible=True), gr.update(visible=True),
|
113 |
+
gr.update(visible=True), # Show the audio_checkbox
|
114 |
+
gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), gr.update(visible=False),
|
115 |
+
gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), "", "", gr.update(visible=False), gr.update(visible=False),
|
116 |
+
gr.update(visible=False) # Hide explain button
|
|
|
|
|
|
|
|
|
|
|
117 |
)
|
118 |
|
119 |
+
with gr.Blocks() as demo:
|
120 |
# Home page elements
|
121 |
+
title = gr.Markdown(value="**AWS Exam Simulator (Quiz)**")
|
122 |
description = gr.Markdown(value=description_str)
|
123 |
exam_selector = gr.Dropdown(label="Select an exam", choices=exams, value=None)
|
124 |
audio_checkbox = gr.Checkbox(label="Enable Audio", value=True, visible=False)
|
125 |
+
start_question_slider = gr.Slider(minimum=0, maximum=50, step=1, label="Select starting question", visible=False) # Slider for selecting the starting question
|
126 |
start_button = gr.Button("Start Exam", visible=False)
|
127 |
|
128 |
# Quiz elements (initially hidden)
|
129 |
question_state = gr.State(0)
|
130 |
+
current_audio_state = gr.State(None) # State to track the current audio playing
|
|
|
|
|
131 |
question_text = gr.Markdown(visible=False, elem_id="question-text")
|
132 |
+
choices = gr.Radio(visible=False, label="Options")
|
|
|
133 |
result_text = gr.Markdown(visible=True)
|
134 |
explanation_text = gr.Markdown(visible=False)
|
|
|
135 |
answer_button = gr.Button("Submit Answer", visible=False)
|
136 |
next_button = gr.Button("Next Question", visible=False)
|
137 |
prev_button = gr.Button("Previous Question", visible=False)
|
138 |
home_button = gr.Button("Return to Home", visible=False)
|
139 |
explain_button = gr.Button("Explain", visible=False)
|
|
|
140 |
question_audio = gr.Audio(visible=False, label="Question Audio", autoplay=True)
|
141 |
answer_audio = gr.Audio(visible=False, label="Answer Audio", autoplay=True)
|
142 |
|
|
|
170 |
|
171 |
# Show settings after exam selection
|
172 |
def show_settings(exam_choice):
|
|
|
173 |
return gr.update(visible=True), gr.update(visible=True), gr.update(visible=True)
|
174 |
|
175 |
+
# Connect exam selection to display settings section
|
176 |
+
exam_selector.change(fn=show_settings, inputs=[exam_selector], outputs=[audio_checkbox, start_question_slider, start_button])
|
|
|
|
|
|
|
177 |
|
178 |
+
# Connect the start button to start the exam
|
179 |
start_button.click(
|
180 |
fn=start_exam,
|
181 |
inputs=[exam_selector, start_question_slider, audio_checkbox],
|
182 |
outputs=[
|
183 |
title, description, exam_selector, start_button,
|
184 |
+
audio_checkbox, # Ensure the checkbox visibility is updated
|
185 |
+
start_question_slider, # Ensure the slider is hidden
|
186 |
question_text, question_text, choices, answer_button,
|
187 |
next_button, prev_button, home_button, question_state, result_text, question_audio,
|
188 |
+
explain_button, result_text, current_audio_state # Add current_audio_state to the outputs
|
189 |
]
|
190 |
)
|
191 |
|
192 |
+
# Connect the quiz buttons to their functions
|
193 |
+
answer_button.click(fn=handle_answer, inputs=[question_state, choices, audio_checkbox, current_audio_state], outputs=[result_text, answer_audio, current_audio_state])
|
194 |
+
next_button.click(fn=handle_next, inputs=[question_state, audio_checkbox], outputs=[question_text, choices, question_state, result_text, question_audio, explanation_text])
|
195 |
+
prev_button.click(fn=handle_previous, inputs=[question_state, audio_checkbox], outputs=[question_text, choices, question_state, result_text, question_audio, explanation_text])
|
|
|
|
|
196 |
|
197 |
+
explain_button.click(fn=show_explanation, inputs=[question_state], outputs=[explanation_text, result_text, explanation_text])
|
|
|
|
|
|
|
|
|
198 |
|
199 |
+
home_button.click(fn=return_home, inputs=None, outputs=[
|
200 |
+
title, description, exam_selector, start_button,
|
201 |
+
audio_checkbox, # Ensure the checkbox visibility is updated
|
202 |
+
#start_question_slider, # Ensure the slider is shown
|
203 |
+
question_text, question_text, choices, answer_button,
|
204 |
+
next_button, prev_button, home_button, question_state, result_text, explanation_text, explain_button
|
205 |
+
])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
206 |
|
207 |
+
demo.launch()
|