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()