Spaces:
Running
Running
import gradio as gr | |
from tool2 import * # Assuming this module contains your exam data and text-to-speech functionality | |
from backend1 import * | |
# Global variable to store the currently selected set of exam questions | |
selected_questions = [] | |
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. | |
For more information about the developer, please visit [ruslanmv.com](https://ruslanmv.com/). | |
**Get Started with Your Quiz** | |
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. | |
""" | |
# --- FUNCTION DEFINITIONS --- | |
def start_exam(exam_choice, start_question, audio_enabled): | |
"""Starts the exam by selecting questions, setting up UI.""" | |
global selected_questions | |
selected_questions = select_exam_vce(exam_choice) | |
if start_question >= len(selected_questions): | |
start_question = 0 # Default to the first question if the input exceeds available questions | |
question, options, audio_path = display_question(start_question, audio_enabled) | |
return ( | |
# Hide start screen elements | |
gr.update(visible=False), # Hide title | |
gr.update(visible=False), # Hide description | |
gr.update(visible=False), # Hide exam_selector | |
gr.update(visible=False), # Hide start_button | |
gr.update(visible=False), # Hide the audio_checkbox | |
gr.update(visible=False), # Hide start_question_slider | |
# Show quiz elements | |
gr.update(visible=True), # Show question_text | |
question, # Question to display | |
gr.update(choices=options, visible=True), # Update Radio choices | |
gr.update(visible=True), # Show answer_button | |
gr.update(visible=True), # Show next_button | |
gr.update(visible=True), # Show prev_button | |
gr.update(visible=True), # Show home_button | |
start_question, # Update the question_state | |
"", # Clear result_text | |
audio_path, # Provide the question audio path | |
gr.update(visible=True), # Show explain_button | |
gr.update(visible=True), # Show result_text (for explanation) | |
None # current_audio_state = None | |
) | |
def display_question(index, audio_enabled): | |
"""Displays a question with options and generates audio (if enabled).""" | |
if index < 0 or index >= len(selected_questions): | |
return "No more questions.", [], None | |
question_text_ = selected_questions[index].get('question', 'No question text available.') | |
question_text = f"**Question {index}:** {question_text_}" | |
choices_options = selected_questions[index].get('options', []) | |
audio_path = text_to_speech(question_text_ + " " + " ".join(choices_options)) if audio_enabled else None | |
return question_text, choices_options, audio_path | |
def show_explanation(index): | |
"""Shows the explanation for the current question.""" | |
if 0 <= index < len(selected_questions): | |
explanation = selected_questions[index].get('explanation', 'No explanation available for this question.') | |
return ( | |
f"**Explanation:** {explanation}", | |
gr.update(visible=True), # Show explanation_text | |
gr.update(visible=True) # Show result_text | |
) | |
else: | |
return "No explanation available for this question.", gr.update(visible=False), gr.update(visible=False) | |
def check_answer(index, answer): | |
"""Checks the given answer against the correct answer.""" | |
correct_answer = selected_questions[index].get('correct', 'No correct answer provided.') | |
if answer == correct_answer: | |
return f"Correct! The answer is: {correct_answer}" | |
else: | |
return f"Incorrect. The correct answer is: {correct_answer}" | |
def update_question(index, audio_enabled): | |
"""Updates the displayed question when the index changes.""" | |
question, options, audio_path = display_question(index, audio_enabled) | |
return question, gr.update(choices=options), index, audio_path | |
def handle_answer(index, answer, audio_enabled, current_audio): | |
""" | |
Handles answer submission: | |
1) Stop the question audio. | |
2) Provide and play the answer audio (if enabled). | |
""" | |
if answer is None: | |
# No answer was selected | |
return "Please select an option before submitting.", None, None, gr.update(value=None) | |
# Stop the current question audio | |
stop_audio = True if current_audio else False | |
# Check answer and generate answer audio | |
result = check_answer(index, answer) | |
answer_audio_path = text_to_speech(result) if audio_enabled else None | |
# Return result (shown as text), | |
# the new answer audio, | |
# updated current_audio_state, | |
# and question_audio set to None so it stops playing | |
return result, answer_audio_path, stop_audio, gr.update(value=None) | |
def handle_next(index, audio_enabled): | |
"""Moves to the next question and updates the UI.""" | |
new_index = min(index + 1, len(selected_questions) - 1) | |
question, options, new_index, audio_path = update_question(new_index, audio_enabled) | |
# Hide explanation when moving to next question | |
return question, options, new_index, "", audio_path, gr.update(visible=False) | |
def handle_previous(index, audio_enabled): | |
"""Moves to the previous question and updates the UI.""" | |
new_index = max(index - 1, 0) | |
question, options, new_index, audio_path = update_question(new_index, audio_enabled) | |
# Hide explanation when moving to previous question | |
return question, options, new_index, "", audio_path, gr.update(visible=False) | |
def return_home(): | |
"""Returns to the home screen.""" | |
return ( | |
# Show start screen elements | |
gr.update(visible=True), # title | |
gr.update(visible=True), # description | |
gr.update(visible=True), # exam_selector | |
gr.update(visible=True), # start_button | |
gr.update(visible=True), # audio_checkbox | |
gr.update(visible=False), # start_question_slider | |
# Hide quiz elements | |
gr.update(visible=False), # question_text | |
"", # question_text value | |
gr.update(visible=False), # choices | |
gr.update(visible=False), # answer_button | |
gr.update(visible=False), # next_button | |
gr.update(visible=False), # prev_button | |
gr.update(visible=False), # home_button | |
0, # question_state | |
"", # result_text | |
gr.update(value=None), # question_audio | |
gr.update(visible=False), # explain_button | |
gr.update(visible=False), # result_text (for explanation) | |
None # current_audio_state | |
) | |
with gr.Blocks() as demo: | |
# Home page elements | |
title = gr.Markdown(value="**AWS Exam Simulator (Quiz)**") | |
description = gr.Markdown(value=description_str) | |
exam_selector = gr.Dropdown(label="Select an exam", choices=exams, value=None) | |
audio_checkbox = gr.Checkbox(label="Enable Audio", value=True, visible=False) | |
start_question_slider = gr.Slider( | |
minimum=0, maximum=50, step=1, label="Select starting question", visible=False | |
) | |
start_button = gr.Button("Start Exam", visible=False) | |
# Quiz elements (initially hidden) | |
question_state = gr.State(0) | |
current_audio_state = gr.State(None) # State to track the current question audio | |
question_text = gr.Markdown(visible=False, elem_id="question-text") | |
choices = gr.Radio(visible=False, label="Options") | |
result_text = gr.Markdown(visible=True) | |
explanation_text = gr.Markdown(visible=False) | |
answer_button = gr.Button("Submit Answer", visible=False) | |
next_button = gr.Button("Next Question", visible=False) | |
prev_button = gr.Button("Previous Question", visible=False) | |
home_button = gr.Button("Return to Home", visible=False) | |
explain_button = gr.Button("Explain", visible=False) | |
# We use two different audio players for question and answer | |
question_audio = gr.Audio(visible=False, label="Question Audio", autoplay=True) | |
answer_audio = gr.Audio(visible=False, label="Answer Audio", autoplay=True) | |
# Layout for the home page | |
with gr.Row(): | |
gr.Column([title]) | |
with gr.Row(): | |
gr.Column([description]) | |
with gr.Row(): | |
gr.Column([exam_selector]) | |
with gr.Row(): | |
gr.Column([audio_checkbox, start_question_slider]) | |
with gr.Row(): | |
gr.Column([start_button]) | |
# Layout for the quiz | |
with gr.Row(): | |
gr.Column([question_text, question_audio]) | |
with gr.Row(): | |
gr.Column([choices]) | |
with gr.Row(): | |
gr.Column([result_text, explanation_text, answer_audio]) | |
with gr.Row(): | |
gr.Column([prev_button], scale=1) | |
gr.Column([], scale=8) | |
gr.Column([next_button], scale=1) | |
with gr.Row(): | |
gr.Column([answer_button, explain_button]) | |
with gr.Row(): | |
gr.Column([home_button]) | |
# Show settings after exam selection | |
def show_settings(exam_choice): | |
return ( | |
gr.update(visible=True), | |
gr.update(visible=True), | |
gr.update(visible=True) | |
) | |
# Connect exam selection to display settings section | |
exam_selector.change( | |
fn=show_settings, | |
inputs=[exam_selector], | |
outputs=[audio_checkbox, start_question_slider, start_button] | |
) | |
# Connect the start button to start the exam | |
start_button.click( | |
fn=start_exam, | |
inputs=[exam_selector, start_question_slider, audio_checkbox], | |
outputs=[ | |
title, | |
description, | |
exam_selector, | |
start_button, | |
audio_checkbox, # Hide the checkbox | |
start_question_slider, # Hide the slider | |
question_text, # Show question_text | |
question_text, # question content | |
choices, # show choices | |
answer_button, | |
next_button, | |
prev_button, | |
home_button, | |
question_state, | |
result_text, | |
question_audio, | |
explain_button, | |
result_text, | |
current_audio_state | |
] | |
) | |
# Connect the quiz buttons to their functions | |
answer_button.click( | |
fn=handle_answer, | |
inputs=[question_state, choices, audio_checkbox, current_audio_state], | |
# We now also update question_audio -> set it to None to stop playback. | |
outputs=[result_text, answer_audio, current_audio_state, question_audio] | |
) | |
next_button.click( | |
fn=handle_next, | |
inputs=[question_state, audio_checkbox], | |
outputs=[question_text, choices, question_state, result_text, question_audio, explanation_text] | |
) | |
prev_button.click( | |
fn=handle_previous, | |
inputs=[question_state, audio_checkbox], | |
outputs=[question_text, choices, question_state, result_text, question_audio, explanation_text] | |
) | |
explain_button.click( | |
fn=show_explanation, | |
inputs=[question_state], | |
outputs=[explanation_text, result_text, explanation_text] | |
) | |
home_button.click( | |
fn=return_home, | |
inputs=None, | |
outputs=[ | |
title, | |
description, | |
exam_selector, | |
start_button, | |
audio_checkbox, | |
start_question_slider, | |
question_text, | |
question_text, | |
choices, | |
answer_button, | |
next_button, | |
prev_button, | |
home_button, | |
question_state, | |
result_text, | |
question_audio, | |
explain_button, | |
result_text, | |
current_audio_state | |
] | |
) | |
demo.launch() | |