Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
@@ -1,15 +1,22 @@
|
|
1 |
-
|
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
-
|
4 |
-
|
5 |
import os
|
6 |
import re
|
7 |
-
|
|
|
8 |
def load_question_sets(directory='questions'):
|
9 |
question_sets = [f.split('.')[0] for f in os.listdir(directory) if f.endswith('.set')]
|
10 |
return question_sets
|
|
|
11 |
exams = load_question_sets()
|
12 |
-
print("question_sets:",exams)
|
13 |
|
14 |
def parse_questions(file_path):
|
15 |
with open(file_path, 'r', encoding='utf-8') as file:
|
@@ -17,7 +24,7 @@ def parse_questions(file_path):
|
|
17 |
questions_raw = re.split(r'## ', content)[1:]
|
18 |
questions = []
|
19 |
for q in questions_raw:
|
20 |
-
parts = q.split('\n')
|
21 |
question_text = parts[0].strip()
|
22 |
options = [opt.strip() for opt in parts[1:] if opt.strip()]
|
23 |
correct_options = [opt for opt in options if opt.startswith('- [x]')]
|
@@ -31,53 +38,56 @@ def parse_questions(file_path):
|
|
31 |
'correct': correct_answer
|
32 |
})
|
33 |
return questions
|
34 |
-
|
|
|
35 |
def select_exam_(exam_name):
|
36 |
questions = parse_questions(f'questions/{exam_name}.set')
|
37 |
-
|
38 |
-
num_questions=
|
39 |
-
num_questions
|
40 |
-
print("num_questions",num_questions)
|
41 |
selected_questions = questions[:int(num_questions)]
|
42 |
cleaned_questions = [
|
43 |
{'question': q['question'],
|
44 |
-
|
45 |
-
|
46 |
for q in selected_questions
|
47 |
]
|
48 |
return cleaned_questions
|
49 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
50 |
# Global variable to store selected questions
|
51 |
selected_questions = []
|
52 |
|
53 |
-
|
|
|
54 |
global selected_questions
|
55 |
-
|
56 |
-
|
57 |
-
# Define the questions for each exam
|
58 |
-
#exam_questions = {
|
59 |
-
# "AWS": [
|
60 |
-
# {'question': 'AWS allows users to manage their resources using a web based user interface. What is the name of this interface?', 'options': ['AWS CLI.', 'AWS API.', 'AWS SDK.', 'AWS Management Console.'], 'correct': 'AWS Management Console.'},
|
61 |
-
# {'question': 'Which of the following is an example of horizontal scaling in the AWS Cloud?', 'options': ['Replacing an existing EC2 instance with a larger, more powerful one.', 'Increasing the compute capacity of a single EC2 instance to address the growing demands of an application.', 'Adding more RAM capacity to an EC2 instance.', 'Adding more EC2 instances of the same size to handle an increase in traffic.'], 'correct': 'Adding more EC2 instances of the same size to handle an increase in traffic.'}
|
62 |
-
# ]
|
63 |
-
#}
|
64 |
-
#selected_questions = exam_questions[exam_choice]
|
65 |
-
|
66 |
-
selected_questions=select_exam_(exam_choice)
|
67 |
-
question, options = display_question(0)
|
68 |
return (
|
69 |
gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), gr.update(visible=False),
|
|
|
70 |
gr.update(visible=True), question, gr.update(choices=options, visible=True), gr.update(visible=True),
|
71 |
-
gr.update(visible=True), gr.update(visible=True), gr.update(visible=True), 0, ""
|
72 |
)
|
73 |
|
74 |
-
|
|
|
75 |
if index < 0 or index >= len(selected_questions):
|
76 |
-
return "No more questions.", []
|
77 |
question_text = selected_questions[index]['question']
|
78 |
choices_options = selected_questions[index]['options']
|
79 |
-
|
|
|
80 |
|
|
|
81 |
def check_answer(index, answer):
|
82 |
correct_answer = selected_questions[index]['correct']
|
83 |
if answer == correct_answer:
|
@@ -85,36 +95,52 @@ def check_answer(index, answer):
|
|
85 |
else:
|
86 |
return f"Incorrect. The correct answer is: {correct_answer}"
|
87 |
|
88 |
-
|
89 |
-
|
90 |
-
|
|
|
91 |
|
92 |
-
|
|
|
93 |
result = check_answer(index, answer)
|
94 |
-
|
|
|
95 |
|
96 |
-
|
|
|
97 |
new_index = min(index + 1, len(selected_questions) - 1)
|
98 |
-
question, options,
|
99 |
-
return question, options, new_index, ""
|
100 |
|
101 |
-
|
|
|
102 |
new_index = max(index - 1, 0)
|
103 |
-
question, options,
|
104 |
-
return question, options, new_index, ""
|
105 |
|
|
|
106 |
def return_home():
|
107 |
return (
|
108 |
gr.update(visible=True), gr.update(visible=True), gr.update(visible=True), gr.update(visible=True),
|
|
|
109 |
gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), gr.update(visible=False),
|
110 |
gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), "", ""
|
111 |
)
|
112 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
113 |
with gr.Blocks() as demo:
|
114 |
# Home page elements
|
115 |
-
title = gr.Markdown(value="Exam Simulator (Quiz)")
|
116 |
-
description = gr.Markdown(value=
|
117 |
exam_selector = gr.Dropdown(label="Select an exam", choices=exams)
|
|
|
118 |
start_button = gr.Button("Start Exam")
|
119 |
|
120 |
# Quiz elements (initially hidden)
|
@@ -126,24 +152,25 @@ with gr.Blocks() as demo:
|
|
126 |
next_button = gr.Button("Next Question", visible=False)
|
127 |
prev_button = gr.Button("Previous Question", visible=False)
|
128 |
home_button = gr.Button("Return to Home", visible=False)
|
129 |
-
|
|
|
130 |
# Layout for the home page
|
131 |
with gr.Row():
|
132 |
gr.Column([title])
|
133 |
with gr.Row():
|
134 |
gr.Column([description])
|
135 |
with gr.Row():
|
136 |
-
gr.Column([exam_selector])
|
137 |
with gr.Row():
|
138 |
gr.Column([start_button])
|
139 |
|
140 |
# Layout for the quiz
|
141 |
with gr.Row():
|
142 |
-
gr.Column([question_text])
|
143 |
with gr.Row():
|
144 |
gr.Column([choices])
|
145 |
with gr.Row():
|
146 |
-
gr.Column([result_text])
|
147 |
with gr.Row():
|
148 |
gr.Column([prev_button], scale=1)
|
149 |
gr.Column([], scale=8)
|
@@ -156,20 +183,21 @@ with gr.Blocks() as demo:
|
|
156 |
# Connect the start button to start the exam
|
157 |
start_button.click(
|
158 |
fn=start_exam,
|
159 |
-
inputs=exam_selector,
|
160 |
outputs=[
|
161 |
title, description, exam_selector, start_button,
|
|
|
162 |
question_text, question_text, choices, answer_button,
|
163 |
-
next_button, prev_button, home_button, question_state, result_text
|
164 |
]
|
165 |
)
|
166 |
-
|
167 |
# Connect the quiz buttons to their functions
|
168 |
-
answer_button.click(fn=handle_answer, inputs=[question_state, choices], outputs=result_text)
|
169 |
-
next_button.click(fn=handle_next, inputs=question_state, outputs=[question_text, choices, question_state, result_text])
|
170 |
-
prev_button.click(fn=handle_previous, inputs=question_state, outputs=[question_text, choices, question_state, result_text])
|
171 |
home_button.click(fn=return_home, inputs=None, outputs=[
|
172 |
title, description, exam_selector, start_button,
|
|
|
173 |
question_text, question_text, choices, answer_button,
|
174 |
next_button, prev_button, home_button, question_state, result_text
|
175 |
])
|
|
|
1 |
+
'''
|
2 |
+
AWS Exam Simulator v.01
|
3 |
+
Program Developed by Ruslan Magana Vsevolovna
|
4 |
+
The purpose of this program is help to practice the questions of AWS Exams.
|
5 |
+
https://ruslanmv.com/
|
6 |
+
'''
|
7 |
|
8 |
+
import gradio as gr
|
9 |
+
from gradio_client import Client
|
10 |
import os
|
11 |
import re
|
12 |
+
|
13 |
+
# Function to load question sets from a directory
|
14 |
def load_question_sets(directory='questions'):
|
15 |
question_sets = [f.split('.')[0] for f in os.listdir(directory) if f.endswith('.set')]
|
16 |
return question_sets
|
17 |
+
|
18 |
exams = load_question_sets()
|
19 |
+
print("question_sets:", exams)
|
20 |
|
21 |
def parse_questions(file_path):
|
22 |
with open(file_path, 'r', encoding='utf-8') as file:
|
|
|
24 |
questions_raw = re.split(r'## ', content)[1:]
|
25 |
questions = []
|
26 |
for q in questions_raw:
|
27 |
+
parts = q.split('\n')
|
28 |
question_text = parts[0].strip()
|
29 |
options = [opt.strip() for opt in parts[1:] if opt.strip()]
|
30 |
correct_options = [opt for opt in options if opt.startswith('- [x]')]
|
|
|
38 |
'correct': correct_answer
|
39 |
})
|
40 |
return questions
|
41 |
+
|
42 |
+
# Function to select exam questions
|
43 |
def select_exam_(exam_name):
|
44 |
questions = parse_questions(f'questions/{exam_name}.set')
|
45 |
+
num_questions = len(questions)
|
46 |
+
#num_questions = 2
|
47 |
+
print("num_questions", num_questions)
|
|
|
48 |
selected_questions = questions[:int(num_questions)]
|
49 |
cleaned_questions = [
|
50 |
{'question': q['question'],
|
51 |
+
'options': [o.replace('- [ ] ', '').replace('- [x] ', '') for o in q['options']],
|
52 |
+
'correct': q['correct'].replace('- [ ] ', '').replace('- [x] ', '')}
|
53 |
for q in selected_questions
|
54 |
]
|
55 |
return cleaned_questions
|
56 |
|
57 |
+
# Text-to-speech function
|
58 |
+
def text_to_speech(text):
|
59 |
+
client = Client("ruslanmv/Text-To-Speech")
|
60 |
+
result = client.predict(
|
61 |
+
text=text,
|
62 |
+
api_name="/predict"
|
63 |
+
)
|
64 |
+
return result # result is already the path to the audio file
|
65 |
+
|
66 |
# Global variable to store selected questions
|
67 |
selected_questions = []
|
68 |
|
69 |
+
# Function to start exam
|
70 |
+
def start_exam(exam_choice, audio_enabled):
|
71 |
global selected_questions
|
72 |
+
selected_questions = select_exam_(exam_choice)
|
73 |
+
question, options, audio_path = display_question(0, audio_enabled)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
74 |
return (
|
75 |
gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), gr.update(visible=False),
|
76 |
+
gr.update(visible=False), # Hide the audio_checkbox
|
77 |
gr.update(visible=True), question, gr.update(choices=options, visible=True), gr.update(visible=True),
|
78 |
+
gr.update(visible=True), gr.update(visible=True), gr.update(visible=True), 0, "", audio_path
|
79 |
)
|
80 |
|
81 |
+
# Function to display a question
|
82 |
+
def display_question(index, audio_enabled):
|
83 |
if index < 0 or index >= len(selected_questions):
|
84 |
+
return "No more questions.", [], None
|
85 |
question_text = selected_questions[index]['question']
|
86 |
choices_options = selected_questions[index]['options']
|
87 |
+
audio_path = text_to_speech(question_text + " " + " ".join(choices_options)) if audio_enabled else None
|
88 |
+
return question_text, choices_options, audio_path
|
89 |
|
90 |
+
# Function to check the answer
|
91 |
def check_answer(index, answer):
|
92 |
correct_answer = selected_questions[index]['correct']
|
93 |
if answer == correct_answer:
|
|
|
95 |
else:
|
96 |
return f"Incorrect. The correct answer is: {correct_answer}"
|
97 |
|
98 |
+
# Function to update the question
|
99 |
+
def update_question(index, audio_enabled):
|
100 |
+
question, options, audio_path = display_question(index, audio_enabled)
|
101 |
+
return question, gr.update(choices=options), index, audio_path
|
102 |
|
103 |
+
# Function to handle the answer submission
|
104 |
+
def handle_answer(index, answer, audio_enabled):
|
105 |
result = check_answer(index, answer)
|
106 |
+
audio_path = text_to_speech(result) if audio_enabled else None
|
107 |
+
return result, audio_path
|
108 |
|
109 |
+
# Function to handle the next question
|
110 |
+
def handle_next(index, audio_enabled):
|
111 |
new_index = min(index + 1, len(selected_questions) - 1)
|
112 |
+
question, options, new_index, audio_path = update_question(new_index, audio_enabled)
|
113 |
+
return question, options, new_index, "", audio_path
|
114 |
|
115 |
+
# Function to handle the previous question
|
116 |
+
def handle_previous(index, audio_enabled):
|
117 |
new_index = max(index - 1, 0)
|
118 |
+
question, options, new_index, audio_path = update_question(new_index, audio_enabled)
|
119 |
+
return question, options, new_index, "", audio_path
|
120 |
|
121 |
+
# Function to return to the home page
|
122 |
def return_home():
|
123 |
return (
|
124 |
gr.update(visible=True), gr.update(visible=True), gr.update(visible=True), gr.update(visible=True),
|
125 |
+
gr.update(visible=True), # Show the audio_checkbox
|
126 |
gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), gr.update(visible=False),
|
127 |
gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), "", ""
|
128 |
)
|
129 |
|
130 |
+
|
131 |
+
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.
|
132 |
+
For more information about the developer, please visit [ruslanmv.com](https://ruslanmv.com/).
|
133 |
+
|
134 |
+
**Get Started with Your Quiz**
|
135 |
+
|
136 |
+
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."""
|
137 |
+
|
138 |
with gr.Blocks() as demo:
|
139 |
# Home page elements
|
140 |
+
title = gr.Markdown(value="**AWS Exam Simulator (Quiz)**")
|
141 |
+
description = gr.Markdown(value=description_str)
|
142 |
exam_selector = gr.Dropdown(label="Select an exam", choices=exams)
|
143 |
+
audio_checkbox = gr.Checkbox(label="Enable Audio", value=True)
|
144 |
start_button = gr.Button("Start Exam")
|
145 |
|
146 |
# Quiz elements (initially hidden)
|
|
|
152 |
next_button = gr.Button("Next Question", visible=False)
|
153 |
prev_button = gr.Button("Previous Question", visible=False)
|
154 |
home_button = gr.Button("Return to Home", visible=False)
|
155 |
+
question_audio = gr.Audio(visible=False, label="Question Audio", autoplay=True)
|
156 |
+
answer_audio = gr.Audio(visible=False,label="Answer Audio",autoplay=True)
|
157 |
# Layout for the home page
|
158 |
with gr.Row():
|
159 |
gr.Column([title])
|
160 |
with gr.Row():
|
161 |
gr.Column([description])
|
162 |
with gr.Row():
|
163 |
+
gr.Column([exam_selector, audio_checkbox])
|
164 |
with gr.Row():
|
165 |
gr.Column([start_button])
|
166 |
|
167 |
# Layout for the quiz
|
168 |
with gr.Row():
|
169 |
+
gr.Column([question_text, question_audio])
|
170 |
with gr.Row():
|
171 |
gr.Column([choices])
|
172 |
with gr.Row():
|
173 |
+
gr.Column([result_text, answer_audio])
|
174 |
with gr.Row():
|
175 |
gr.Column([prev_button], scale=1)
|
176 |
gr.Column([], scale=8)
|
|
|
183 |
# Connect the start button to start the exam
|
184 |
start_button.click(
|
185 |
fn=start_exam,
|
186 |
+
inputs=[exam_selector, audio_checkbox],
|
187 |
outputs=[
|
188 |
title, description, exam_selector, start_button,
|
189 |
+
audio_checkbox, # Ensure the checkbox visibility is updated
|
190 |
question_text, question_text, choices, answer_button,
|
191 |
+
next_button, prev_button, home_button, question_state, result_text, question_audio
|
192 |
]
|
193 |
)
|
|
|
194 |
# Connect the quiz buttons to their functions
|
195 |
+
answer_button.click(fn=handle_answer, inputs=[question_state, choices, audio_checkbox], outputs=[result_text, answer_audio])
|
196 |
+
next_button.click(fn=handle_next, inputs=[question_state, audio_checkbox], outputs=[question_text, choices, question_state, result_text, question_audio])
|
197 |
+
prev_button.click(fn=handle_previous, inputs=[question_state, audio_checkbox], outputs=[question_text, choices, question_state, result_text, question_audio])
|
198 |
home_button.click(fn=return_home, inputs=None, outputs=[
|
199 |
title, description, exam_selector, start_button,
|
200 |
+
audio_checkbox, # Ensure the checkbox visibility is updated
|
201 |
question_text, question_text, choices, answer_button,
|
202 |
next_button, prev_button, home_button, question_state, result_text
|
203 |
])
|