ruslanmv commited on
Commit
7340672
·
1 Parent(s): 9c81979
app.py CHANGED
@@ -1,156 +1,110 @@
1
  '''
2
- AWS Exam Simulator v.03.2
3
  Program Developed by Ruslan Magana Vsevolovna
4
  The purpose of this program is help to practice the questions of AWS Exams.
5
  '''
6
  import gradio as gr
7
- from gradio_client import Client
8
- import os
9
- import json
10
-
11
- # Function to load question sets from a directory
12
- def load_question_sets_vce(directory='questions'):
13
- question_sets = []
14
- for root, dirs, files in os.walk(directory):
15
- for file in files:
16
- if file.endswith(".json"):
17
- question_sets.append(os.path.join( file)[:-5]) # remove the .json extension
18
- return question_sets
19
-
20
- exams = load_question_sets_vce('questions/')
21
- print("question_sets:", exams)
22
-
23
- def select_exam_vce(exam_name):
24
- file_path = os.path.join(os.getcwd(), 'questions', f'{exam_name}.json')
25
- try:
26
- with open(file_path, 'r') as f:
27
- questions = json.load(f)
28
- print(f"Loaded {len(questions)} questions")
29
- return questions # Ensure the questions are returned here
30
- except FileNotFoundError:
31
- print(f"File {file_path} not found.")
32
- return [] # Return an empty list to indicate no questions were found
33
-
34
- import time
35
- import httpx
36
- # Text-to-speech clients
37
- client_1 = Client("ruslanmv/text-to-speech-fast")
38
- client_2 = Client("ruslanmv/Text-To-Speech")
39
- client_3 = Client("ruslanmv/Text-to-Voice-Transformers")
40
- clients = [client_1, client_2, client_3]
41
- # Text-to-speech function with rate limiting, retry mechanism, and client rotation
42
- def text_to_speech(text, retries=3, delay=5):
43
- client_index = 0 # Start with the first client
44
-
45
- for attempt in range(retries):
46
- try:
47
- client = clients[client_index]
48
- print(f"Attempt {attempt + 1}")
49
-
50
- if client_index == 0:
51
- result = client.predict(
52
- language="English",
53
- repo_id="csukuangfj/vits-piper-en_US-hfc_female-medium|1 speaker",
54
- text=text,
55
- sid="0",
56
- speed=0.8,
57
- api_name="/process"
58
- )
59
- else:
60
- result = client.predict(
61
- text=text,
62
- api_name="/predict"
63
- )
64
-
65
- return result
66
-
67
- except httpx.HTTPStatusError as e:
68
- if e.response.status_code == 429:
69
- print(f"Rate limit exceeded. Retrying in {delay} seconds...")
70
- client_index = (client_index + 1) % len(clients) # Rotate to the next client
71
- time.sleep(delay)
72
- else:
73
- raise e
74
-
75
- print("Max retries exceeded. Could not process the request.")
76
- return None
77
-
78
 
79
 
 
 
80
 
 
 
 
 
81
 
82
- # Global variable to store selected questions
83
- selected_questions = []
84
 
85
- # Function to start exam
86
  def start_exam(exam_choice, audio_enabled):
 
87
  global selected_questions
88
  selected_questions = select_exam_vce(exam_choice)
89
  question, options, audio_path = display_question(0, audio_enabled)
90
  return (
 
91
  gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), gr.update(visible=False),
92
- gr.update(visible=False), # Hide the audio_checkbox
 
93
  gr.update(visible=True), question, gr.update(choices=options, visible=True), gr.update(visible=True),
94
- gr.update(visible=True), gr.update(visible=True), gr.update(visible=True), 0, "", audio_path
 
95
  )
96
 
97
- # Function to display a question
98
  def display_question(index, audio_enabled):
 
99
  if index < 0 or index >= len(selected_questions):
100
  return "No more questions.", [], None
101
- question_text_ = selected_questions[index]['question']
102
- question_text = f"**Question {index + 1}:** {question_text_}" # Numbering added
103
- choices_options = selected_questions[index]['options']
104
  audio_path = text_to_speech(question_text_ + " " + " ".join(choices_options)) if audio_enabled else None
105
  return question_text, choices_options, audio_path
106
 
107
- # Function to check the answer
 
 
 
 
 
 
 
 
 
 
 
108
  def check_answer(index, answer):
109
- correct_answer = selected_questions[index]['correct']
 
110
  if answer == correct_answer:
111
  return f"Correct! The answer is: {correct_answer}"
112
  else:
113
  return f"Incorrect. The correct answer is: {correct_answer}"
114
 
115
- # Function to update the question
116
  def update_question(index, audio_enabled):
 
117
  question, options, audio_path = display_question(index, audio_enabled)
118
  return question, gr.update(choices=options), index, audio_path
119
 
120
- # Function to handle the answer submission
121
- def handle_answer(index, answer, audio_enabled):
 
 
 
 
 
 
122
  result = check_answer(index, answer)
123
- audio_path = text_to_speech(result) if audio_enabled else None
124
- return result, audio_path
 
125
 
126
- # Function to handle the next question
127
  def handle_next(index, audio_enabled):
 
128
  new_index = min(index + 1, len(selected_questions) - 1)
129
  question, options, new_index, audio_path = update_question(new_index, audio_enabled)
130
- return question, options, new_index, "", audio_path
131
 
132
- # Function to handle the previous question
133
  def handle_previous(index, audio_enabled):
 
134
  new_index = max(index - 1, 0)
135
  question, options, new_index, audio_path = update_question(new_index, audio_enabled)
136
- return question, options, new_index, "", audio_path
137
 
138
- # Function to return to the home page
139
  def return_home():
 
140
  return (
 
141
  gr.update(visible=True), gr.update(visible=True), gr.update(visible=True), gr.update(visible=True),
142
- gr.update(visible=True), # Show the audio_checkbox
 
143
  gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), gr.update(visible=False),
144
- gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), "", ""
 
145
  )
146
 
147
- 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.
148
- For more information about the developer, please visit [ruslanmv.com](https://ruslanmv.com/).
149
-
150
- **Get Started with Your Quiz**
151
-
152
- 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."""
153
-
154
  with gr.Blocks() as demo:
155
  # Home page elements
156
  title = gr.Markdown(value="**AWS Exam Simulator (Quiz)**")
@@ -159,15 +113,18 @@ with gr.Blocks() as demo:
159
  audio_checkbox = gr.Checkbox(label="Enable Audio", value=True)
160
  start_button = gr.Button("Start Exam")
161
 
162
- #Quiz elements (initially hidden)
163
  question_state = gr.State(0)
 
164
  question_text = gr.Markdown(visible=False, elem_id="question-text")
165
  choices = gr.Radio(visible=False, label="Options")
166
  result_text = gr.Markdown(visible=True)
 
167
  answer_button = gr.Button("Submit Answer", visible=False)
168
  next_button = gr.Button("Next Question", visible=False)
169
  prev_button = gr.Button("Previous Question", visible=False)
170
  home_button = gr.Button("Return to Home", visible=False)
 
171
  question_audio = gr.Audio(visible=False, label="Question Audio", autoplay=True)
172
  answer_audio = gr.Audio(visible=False, label="Answer Audio", autoplay=True)
173
 
@@ -187,16 +144,16 @@ with gr.Blocks() as demo:
187
  with gr.Row():
188
  gr.Column([choices])
189
  with gr.Row():
190
- gr.Column([result_text, answer_audio])
191
  with gr.Row():
192
  gr.Column([prev_button], scale=1)
193
  gr.Column([], scale=8)
194
  gr.Column([next_button], scale=1)
195
  with gr.Row():
196
- gr.Column([answer_button])
197
  with gr.Row():
198
  gr.Column([home_button])
199
-
200
  # Connect the start button to start the exam
201
  start_button.click(
202
  fn=start_exam,
@@ -205,21 +162,23 @@ with gr.Blocks() as demo:
205
  title, description, exam_selector, start_button,
206
  audio_checkbox, # Ensure the checkbox visibility is updated
207
  question_text, question_text, choices, answer_button,
208
- next_button, prev_button, home_button, question_state, result_text, question_audio
 
209
  ]
210
  )
 
211
  # Connect the quiz buttons to their functions
212
- answer_button.click(fn=handle_answer, inputs=[question_state, choices, audio_checkbox], outputs=[result_text, answer_audio])
213
- next_button.click(fn=handle_next, inputs=[question_state, audio_checkbox], outputs=[question_text, choices, question_state, result_text, question_audio])
214
- prev_button.click(fn=handle_previous, inputs=[question_state, audio_checkbox], outputs=[question_text, choices, question_state, result_text, question_audio])
 
 
 
215
  home_button.click(fn=return_home, inputs=None, outputs=[
216
  title, description, exam_selector, start_button,
217
  audio_checkbox, # Ensure the checkbox visibility is updated
218
  question_text, question_text, choices, answer_button,
219
- next_button, prev_button, home_button, question_state, result_text
220
  ])
221
 
222
  demo.launch()
223
-
224
- ### Notes revision v0.3.1
225
- #In this revised code, JavaScript is used to stop any currently playing audio when a new audio is about to be played. The _js parameter is added to the click function of the buttons that play audio (answer_button, next_button, and prev_button) to ensure that no multiple audios are played simultaneously
 
1
  '''
2
+ AWS Exam Simulator v.05
3
  Program Developed by Ruslan Magana Vsevolovna
4
  The purpose of this program is help to practice the questions of AWS Exams.
5
  '''
6
  import gradio as gr
7
+ from tool import * # Assuming this module contains your exam data and text-to-speech functionality
8
+ from backend1 import *
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
 
10
 
11
+ # Global variable to store the currently selected set of exam questions
12
+ selected_questions = []
13
 
14
+ 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.
15
+ For more information about the developer, please visit [ruslanmv.com](https://ruslanmv.com/).
16
+ **Get Started with Your Quiz**
17
+ 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."""
18
 
19
+ # --- FUNCTION DEFINITIONS ---
 
20
 
 
21
  def start_exam(exam_choice, audio_enabled):
22
+ """Starts the exam by selecting questions, setting up UI."""
23
  global selected_questions
24
  selected_questions = select_exam_vce(exam_choice)
25
  question, options, audio_path = display_question(0, audio_enabled)
26
  return (
27
+ # Hide start screen elements
28
  gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), gr.update(visible=False),
29
+ gr.update(visible=False), # Hide the audio_checkbox
30
+ # Show quiz elements
31
  gr.update(visible=True), question, gr.update(choices=options, visible=True), gr.update(visible=True),
32
+ gr.update(visible=True), gr.update(visible=True), gr.update(visible=True), 0, "", audio_path, gr.update(visible=True),
33
+ gr.update(visible=True), None # None for the audio stop signal
34
  )
35
 
 
36
  def display_question(index, audio_enabled):
37
+ """Displays a question with options and generates audio (if enabled)."""
38
  if index < 0 or index >= len(selected_questions):
39
  return "No more questions.", [], None
40
+ question_text_ = selected_questions[index].get('question', 'No question text available.')
41
+ question_text = f"**Question {index + 1}:** {question_text_}"
42
+ choices_options = selected_questions[index].get('options', [])
43
  audio_path = text_to_speech(question_text_ + " " + " ".join(choices_options)) if audio_enabled else None
44
  return question_text, choices_options, audio_path
45
 
46
+ def show_explanation(index):
47
+ """Shows the explanation for the current question and hides previous results."""
48
+ if 0 <= index < len(selected_questions):
49
+ explanation = selected_questions[index].get('explanation', 'No explanation available for this question.')
50
+ return (
51
+ f"**Explanation:** {explanation}",
52
+ gr.update(visible=True), # Show explanation_text
53
+ gr.update(visible=True) # Show result_text
54
+ )
55
+ else:
56
+ return "No explanation available for this question.", gr.update(visible=False), gr.update(visible=False)
57
+
58
  def check_answer(index, answer):
59
+ """Checks the given answer against the correct answer."""
60
+ correct_answer = selected_questions[index].get('correct', 'No correct answer provided.')
61
  if answer == correct_answer:
62
  return f"Correct! The answer is: {correct_answer}"
63
  else:
64
  return f"Incorrect. The correct answer is: {correct_answer}"
65
 
 
66
  def update_question(index, audio_enabled):
67
+ """Updates the displayed question when the index changes."""
68
  question, options, audio_path = display_question(index, audio_enabled)
69
  return question, gr.update(choices=options), index, audio_path
70
 
71
+ def handle_answer(index, answer, audio_enabled, current_audio):
72
+ """Handles answer submission, provides feedback, and generates audio."""
73
+ # Handle the case when no answer is selected
74
+ if answer is None:
75
+ return "Please select an option before submitting.", None, None
76
+
77
+ # Stop the current question audio before playing the answer audio
78
+ stop_audio = True if current_audio else False
79
  result = check_answer(index, answer)
80
+ answer_audio_path = text_to_speech(result) if audio_enabled else None
81
+ return result, answer_audio_path, stop_audio
82
+
83
 
 
84
  def handle_next(index, audio_enabled):
85
+ """Moves to the next question and updates the UI."""
86
  new_index = min(index + 1, len(selected_questions) - 1)
87
  question, options, new_index, audio_path = update_question(new_index, audio_enabled)
88
+ return question, options, new_index, "", audio_path, gr.update(visible=False) # Hide explanation
89
 
 
90
  def handle_previous(index, audio_enabled):
91
+ """Moves to the previous question and updates the UI."""
92
  new_index = max(index - 1, 0)
93
  question, options, new_index, audio_path = update_question(new_index, audio_enabled)
94
+ return question, options, new_index, "", audio_path, gr.update(visible=False) # Hide explanation
95
 
 
96
  def return_home():
97
+ """Returns to the home screen."""
98
  return (
99
+ # Show start screen elements
100
  gr.update(visible=True), gr.update(visible=True), gr.update(visible=True), gr.update(visible=True),
101
+ gr.update(visible=True), # Show the audio_checkbox
102
+ # Hide quiz elements
103
  gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), gr.update(visible=False),
104
+ gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), "", "", gr.update(visible=False), gr.update(visible=False),
105
+ gr.update(visible=False) # Hide explain button
106
  )
107
 
 
 
 
 
 
 
 
108
  with gr.Blocks() as demo:
109
  # Home page elements
110
  title = gr.Markdown(value="**AWS Exam Simulator (Quiz)**")
 
113
  audio_checkbox = gr.Checkbox(label="Enable Audio", value=True)
114
  start_button = gr.Button("Start Exam")
115
 
116
+ # Quiz elements (initially hidden)
117
  question_state = gr.State(0)
118
+ current_audio_state = gr.State(None) # State to track the current audio playing
119
  question_text = gr.Markdown(visible=False, elem_id="question-text")
120
  choices = gr.Radio(visible=False, label="Options")
121
  result_text = gr.Markdown(visible=True)
122
+ explanation_text = gr.Markdown(visible=False)
123
  answer_button = gr.Button("Submit Answer", visible=False)
124
  next_button = gr.Button("Next Question", visible=False)
125
  prev_button = gr.Button("Previous Question", visible=False)
126
  home_button = gr.Button("Return to Home", visible=False)
127
+ explain_button = gr.Button("Explain", visible=False)
128
  question_audio = gr.Audio(visible=False, label="Question Audio", autoplay=True)
129
  answer_audio = gr.Audio(visible=False, label="Answer Audio", autoplay=True)
130
 
 
144
  with gr.Row():
145
  gr.Column([choices])
146
  with gr.Row():
147
+ gr.Column([result_text, explanation_text, answer_audio])
148
  with gr.Row():
149
  gr.Column([prev_button], scale=1)
150
  gr.Column([], scale=8)
151
  gr.Column([next_button], scale=1)
152
  with gr.Row():
153
+ gr.Column([answer_button, explain_button])
154
  with gr.Row():
155
  gr.Column([home_button])
156
+
157
  # Connect the start button to start the exam
158
  start_button.click(
159
  fn=start_exam,
 
162
  title, description, exam_selector, start_button,
163
  audio_checkbox, # Ensure the checkbox visibility is updated
164
  question_text, question_text, choices, answer_button,
165
+ next_button, prev_button, home_button, question_state, result_text, question_audio,
166
+ explain_button, current_audio_state # Add current_audio_state to the outputs
167
  ]
168
  )
169
+
170
  # Connect the quiz buttons to their functions
171
+ answer_button.click(fn=handle_answer, inputs=[question_state, choices, audio_checkbox, current_audio_state], outputs=[result_text, answer_audio, current_audio_state])
172
+ next_button.click(fn=handle_next, inputs=[question_state, audio_checkbox], outputs=[question_text, choices, question_state, result_text, question_audio, explanation_text])
173
+ prev_button.click(fn=handle_previous, inputs=[question_state, audio_checkbox], outputs=[question_text, choices, question_state, result_text, question_audio, explanation_text])
174
+
175
+ explain_button.click(fn=show_explanation, inputs=[question_state], outputs=[explanation_text, result_text, explanation_text]) # Output to both to toggle visibility
176
+
177
  home_button.click(fn=return_home, inputs=None, outputs=[
178
  title, description, exam_selector, start_button,
179
  audio_checkbox, # Ensure the checkbox visibility is updated
180
  question_text, question_text, choices, answer_button,
181
+ next_button, prev_button, home_button, question_state, result_text, explanation_text, explain_button
182
  ])
183
 
184
  demo.launch()
 
 
 
questions/GCP-ML-vA.json CHANGED
The diff for this file is too large to render. See raw diff
 
questions/MLS-C01-v0624.json CHANGED
The diff for this file is too large to render. See raw diff
 
questions/SAA-C03-v2.json CHANGED
The diff for this file is too large to render. See raw diff