Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
@@ -33,7 +33,9 @@ class QuizItem(BaseModel):
|
|
33 |
class QuizOutput(BaseModel):
|
34 |
items: list[QuizItem] = Field(..., description="List of 10 quiz items")
|
35 |
|
36 |
-
# Initialize
|
|
|
|
|
37 |
quiz_generator = Agent(
|
38 |
name="Quiz Generator",
|
39 |
role="Generates structured quiz questions and answers",
|
@@ -53,7 +55,7 @@ VECTOR_COLUMN_NAME = "vector"
|
|
53 |
TEXT_COLUMN_NAME = "text"
|
54 |
proj_dir = Path.cwd()
|
55 |
|
56 |
-
#
|
57 |
from backend.semantic_search import table, retriever
|
58 |
|
59 |
def generate_quiz_data(question_difficulty, topic, documents_str):
|
@@ -129,15 +131,9 @@ def retrieve_and_generate_quiz(question_difficulty, topic):
|
|
129 |
|
130 |
documents_str = '\n'.join(documents)
|
131 |
quiz_data = generate_quiz_data(question_difficulty, topic, documents_str)
|
132 |
-
|
133 |
-
# Generate Excel file
|
134 |
-
excel_file = None
|
135 |
-
if quiz_data:
|
136 |
-
excel_file = quiz_to_excel(quiz_data)
|
137 |
-
|
138 |
-
return quiz_data, excel_file
|
139 |
|
140 |
-
def update_quiz_components(quiz_data
|
141 |
if not quiz_data or not quiz_data.items:
|
142 |
return [gr.update(visible=False) for _ in range(10)] + [gr.update(value="Error: Failed to generate quiz.", visible=True), None]
|
143 |
|
@@ -147,56 +143,88 @@ def update_quiz_components(quiz_data, excel_file):
|
|
147 |
radio_update = gr.update(visible=True, choices=choices, label=item.question, value=None)
|
148 |
radio_updates.append(radio_update)
|
149 |
|
|
|
|
|
|
|
150 |
return radio_updates + [gr.update(value="Please select answers and click 'Check Score'.", visible=True), excel_file]
|
151 |
|
|
|
152 |
def collect_answers_and_calculate(*all_inputs):
|
153 |
-
print(f"Total inputs received: {len(all_inputs)}")
|
154 |
|
155 |
# The last input is quiz_data, the first 10 are radio values
|
156 |
-
radio_values = all_inputs[:10]
|
157 |
-
quiz_data = all_inputs[10]
|
158 |
|
159 |
-
print(f"Received radio_values: {radio_values}")
|
160 |
-
print(f"Received quiz_data: {quiz_data}")
|
161 |
|
162 |
-
# Calculate score
|
163 |
score = 0
|
164 |
answered_questions = 0
|
165 |
|
166 |
for i, (user_answer, quiz_item) in enumerate(zip(radio_values, quiz_data.items[:10])):
|
167 |
-
if user_answer is not None:
|
168 |
answered_questions += 1
|
169 |
|
170 |
-
# Convert correct answer code to actual choice text
|
171 |
-
correct_answer_index = int(quiz_item.correct_answer[1]) - 1
|
172 |
correct_answer_text = quiz_item.choices[correct_answer_index]
|
173 |
|
174 |
-
print(f"Q{i+1}: User='{user_answer}' vs Correct='{correct_answer_text}'")
|
175 |
|
176 |
if user_answer == correct_answer_text:
|
177 |
score += 1
|
178 |
|
179 |
-
print(f"Calculated score: {score}/{answered_questions}")
|
180 |
|
181 |
-
# Create
|
182 |
if answered_questions == 0:
|
183 |
-
|
|
|
|
|
|
|
|
|
184 |
elif score == answered_questions:
|
185 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
186 |
elif score > answered_questions * 0.7:
|
187 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
188 |
elif score > answered_questions * 0.5:
|
189 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
190 |
else:
|
191 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
192 |
|
193 |
-
return
|
194 |
|
195 |
-
# Define theme
|
196 |
colorful_theme = gr.themes.Default(primary_hue="cyan", secondary_hue="yellow", neutral_hue="purple")
|
197 |
|
198 |
with gr.Blocks(title="CBSE Gyan Quiz Bot", theme=colorful_theme) as QUIZBOT:
|
199 |
-
#
|
200 |
with gr.Row():
|
201 |
with gr.Column(scale=2):
|
202 |
gr.Image(value='logo.png', height=200, width=200)
|
@@ -209,56 +237,56 @@ with gr.Blocks(title="CBSE Gyan Quiz Bot", theme=colorful_theme) as QUIZBOT:
|
|
209 |
</center>
|
210 |
""")
|
211 |
|
212 |
-
# Input controls
|
213 |
topic = gr.Textbox(label="Enter the Topic for Quiz", placeholder="Write any CHAPTER NAME from CBSE curriculum")
|
214 |
|
215 |
with gr.Row():
|
216 |
difficulty_radio = gr.Radio(["easy", "average", "hard"], label="How difficult should the quiz be?")
|
217 |
model_radio = gr.Radio(choices=['(ACCURATE) BGE reranker'], value='(ACCURATE) BGE reranker', label="Embeddings")
|
218 |
|
219 |
-
# Generate quiz button
|
220 |
generate_quiz_btn = gr.Button("Generate Quiz!π")
|
221 |
quiz_msg = gr.Textbox(label="Status", interactive=False)
|
222 |
-
|
223 |
-
# Excel download
|
224 |
-
excel_download = gr.File(label="Download Excel", visible=False)
|
225 |
|
226 |
-
#
|
227 |
question_radios = [gr.Radio(visible=False, label="", choices=[""], value=None) for _ in range(10)]
|
228 |
quiz_data_state = gr.State(value=None)
|
229 |
|
230 |
-
#
|
|
|
|
|
231 |
check_score_btn = gr.Button("Check Score", variant="primary", size="lg")
|
232 |
-
|
|
|
|
|
233 |
|
234 |
-
#
|
235 |
generate_quiz_btn.click(
|
236 |
fn=retrieve_and_generate_quiz,
|
237 |
inputs=[difficulty_radio, topic],
|
238 |
-
outputs=[quiz_data_state
|
239 |
).then(
|
240 |
fn=update_quiz_components,
|
241 |
-
inputs=[quiz_data_state
|
242 |
outputs=question_radios + [quiz_msg, excel_download]
|
243 |
).then(
|
244 |
-
fn=lambda: gr.update(visible=True),
|
245 |
inputs=[],
|
246 |
outputs=[excel_download]
|
247 |
)
|
248 |
|
|
|
249 |
check_score_btn.click(
|
250 |
fn=collect_answers_and_calculate,
|
251 |
-
inputs=question_radios + [quiz_data_state],
|
252 |
outputs=[score_output],
|
253 |
api_name="check_score"
|
254 |
).then(
|
255 |
-
fn=lambda: gr.update(visible=True),
|
256 |
inputs=[],
|
257 |
outputs=[score_output]
|
258 |
)
|
259 |
|
260 |
if __name__ == "__main__":
|
261 |
-
QUIZBOT.queue().launch(server_name="0.0.0.0", server_port=7860)
|
262 |
# import pandas as pd
|
263 |
# import json
|
264 |
# import gradio as gr
|
|
|
33 |
class QuizOutput(BaseModel):
|
34 |
items: list[QuizItem] = Field(..., description="List of 10 quiz items")
|
35 |
|
36 |
+
# Initialize Agents
|
37 |
+
groq_agent = Agent(model=Groq(model="llama3-70b-8192", api_key=api_key), markdown=True)
|
38 |
+
|
39 |
quiz_generator = Agent(
|
40 |
name="Quiz Generator",
|
41 |
role="Generates structured quiz questions and answers",
|
|
|
55 |
TEXT_COLUMN_NAME = "text"
|
56 |
proj_dir = Path.cwd()
|
57 |
|
58 |
+
# Calling functions from backend (assuming they exist)
|
59 |
from backend.semantic_search import table, retriever
|
60 |
|
61 |
def generate_quiz_data(question_difficulty, topic, documents_str):
|
|
|
131 |
|
132 |
documents_str = '\n'.join(documents)
|
133 |
quiz_data = generate_quiz_data(question_difficulty, topic, documents_str)
|
134 |
+
return quiz_data
|
|
|
|
|
|
|
|
|
|
|
|
|
135 |
|
136 |
+
def update_quiz_components(quiz_data):
|
137 |
if not quiz_data or not quiz_data.items:
|
138 |
return [gr.update(visible=False) for _ in range(10)] + [gr.update(value="Error: Failed to generate quiz.", visible=True), None]
|
139 |
|
|
|
143 |
radio_update = gr.update(visible=True, choices=choices, label=item.question, value=None)
|
144 |
radio_updates.append(radio_update)
|
145 |
|
146 |
+
# Generate Excel file after successful quiz generation
|
147 |
+
excel_file = quiz_to_excel(quiz_data)
|
148 |
+
|
149 |
return radio_updates + [gr.update(value="Please select answers and click 'Check Score'.", visible=True), excel_file]
|
150 |
|
151 |
+
# FIXED FUNCTION: Changed parameter signature to accept all arguments positionally
|
152 |
def collect_answers_and_calculate(*all_inputs):
|
153 |
+
print(f"Total inputs received: {len(all_inputs)}") # Debug print
|
154 |
|
155 |
# The last input is quiz_data, the first 10 are radio values
|
156 |
+
radio_values = all_inputs[:10] # First 10 inputs are radio button values
|
157 |
+
quiz_data = all_inputs[10] # Last input is quiz_data
|
158 |
|
159 |
+
print(f"Received radio_values: {radio_values}") # Debug print
|
160 |
+
print(f"Received quiz_data: {quiz_data}") # Debug print
|
161 |
|
162 |
+
# Calculate score by comparing user answers with correct answers
|
163 |
score = 0
|
164 |
answered_questions = 0
|
165 |
|
166 |
for i, (user_answer, quiz_item) in enumerate(zip(radio_values, quiz_data.items[:10])):
|
167 |
+
if user_answer is not None: # Only count if user answered
|
168 |
answered_questions += 1
|
169 |
|
170 |
+
# Convert correct answer code (e.g., 'C3') to actual choice text
|
171 |
+
correct_answer_index = int(quiz_item.correct_answer[1]) - 1 # 'C3' -> index 2
|
172 |
correct_answer_text = quiz_item.choices[correct_answer_index]
|
173 |
|
174 |
+
print(f"Q{i+1}: User='{user_answer}' vs Correct='{correct_answer_text}'") # Debug
|
175 |
|
176 |
if user_answer == correct_answer_text:
|
177 |
score += 1
|
178 |
|
179 |
+
print(f"Calculated score: {score}/{answered_questions}") # Debug print
|
180 |
|
181 |
+
# Create colorful HTML message
|
182 |
if answered_questions == 0:
|
183 |
+
html_message = """
|
184 |
+
<div style="text-align: center; padding: 20px; border-radius: 10px; background: linear-gradient(135deg, #ff6b6b, #ee5a24);">
|
185 |
+
<h2 style="color: white; margin: 0;">β οΈ Please answer at least one question!</h2>
|
186 |
+
</div>
|
187 |
+
"""
|
188 |
elif score == answered_questions:
|
189 |
+
html_message = f"""
|
190 |
+
<div style="text-align: center; padding: 20px; border-radius: 10px; background: linear-gradient(135deg, #00d2d3, #54a0ff); box-shadow: 0 4px 15px rgba(0,0,0,0.2);">
|
191 |
+
<h1 style="color: white; margin: 0; text-shadow: 2px 2px 4px rgba(0,0,0,0.3);">π PERFECT SCORE! π</h1>
|
192 |
+
<h2 style="color: #fff3cd; margin: 10px 0;">You got {score} out of {answered_questions} correct!</h2>
|
193 |
+
<p style="color: white; font-size: 18px; margin: 0;">Outstanding performance! π</p>
|
194 |
+
</div>
|
195 |
+
"""
|
196 |
elif score > answered_questions * 0.7:
|
197 |
+
html_message = f"""
|
198 |
+
<div style="text-align: center; padding: 20px; border-radius: 10px; background: linear-gradient(135deg, #2ed573, #7bed9f); box-shadow: 0 4px 15px rgba(0,0,0,0.2);">
|
199 |
+
<h1 style="color: white; margin: 0; text-shadow: 2px 2px 4px rgba(0,0,0,0.3);">π EXCELLENT! π</h1>
|
200 |
+
<h2 style="color: #fff3cd; margin: 10px 0;">You got {score} out of {answered_questions} correct!</h2>
|
201 |
+
<p style="color: white; font-size: 18px; margin: 0;">Great job! Keep it up! πͺ</p>
|
202 |
+
</div>
|
203 |
+
"""
|
204 |
elif score > answered_questions * 0.5:
|
205 |
+
html_message = f"""
|
206 |
+
<div style="text-align: center; padding: 20px; border-radius: 10px; background: linear-gradient(135deg, #ffa726, #ffcc02); box-shadow: 0 4px 15px rgba(0,0,0,0.2);">
|
207 |
+
<h1 style="color: white; margin: 0; text-shadow: 2px 2px 4px rgba(0,0,0,0.3);">π GOOD JOB! π</h1>
|
208 |
+
<h2 style="color: #fff3cd; margin: 10px 0;">You got {score} out of {answered_questions} correct!</h2>
|
209 |
+
<p style="color: white; font-size: 18px; margin: 0;">Well done! Room for improvement! π</p>
|
210 |
+
</div>
|
211 |
+
"""
|
212 |
else:
|
213 |
+
html_message = f"""
|
214 |
+
<div style="text-align: center; padding: 20px; border-radius: 10px; background: linear-gradient(135deg, #ff7675, #fd79a8); box-shadow: 0 4px 15px rgba(0,0,0,0.2);">
|
215 |
+
<h1 style="color: white; margin: 0; text-shadow: 2px 2px 4px rgba(0,0,0,0.3);">πͺ KEEP TRYING! πͺ</h1>
|
216 |
+
<h2 style="color: #fff3cd; margin: 10px 0;">You got {score} out of {answered_questions} correct!</h2>
|
217 |
+
<p style="color: white; font-size: 18px; margin: 0;">Don't worry! Practice makes perfect! πβ¨</p>
|
218 |
+
</div>
|
219 |
+
"""
|
220 |
|
221 |
+
return html_message
|
222 |
|
223 |
+
# Define a colorful theme
|
224 |
colorful_theme = gr.themes.Default(primary_hue="cyan", secondary_hue="yellow", neutral_hue="purple")
|
225 |
|
226 |
with gr.Blocks(title="CBSE Gyan Quiz Bot", theme=colorful_theme) as QUIZBOT:
|
227 |
+
# Create a single row for the HTML and Image
|
228 |
with gr.Row():
|
229 |
with gr.Column(scale=2):
|
230 |
gr.Image(value='logo.png', height=200, width=200)
|
|
|
237 |
</center>
|
238 |
""")
|
239 |
|
|
|
240 |
topic = gr.Textbox(label="Enter the Topic for Quiz", placeholder="Write any CHAPTER NAME from CBSE curriculum")
|
241 |
|
242 |
with gr.Row():
|
243 |
difficulty_radio = gr.Radio(["easy", "average", "hard"], label="How difficult should the quiz be?")
|
244 |
model_radio = gr.Radio(choices=['(ACCURATE) BGE reranker'], value='(ACCURATE) BGE reranker', label="Embeddings")
|
245 |
|
|
|
246 |
generate_quiz_btn = gr.Button("Generate Quiz!π")
|
247 |
quiz_msg = gr.Textbox(label="Status", interactive=False)
|
|
|
|
|
|
|
248 |
|
249 |
+
# Pre-defined radio buttons for 10 questions
|
250 |
question_radios = [gr.Radio(visible=False, label="", choices=[""], value=None) for _ in range(10)]
|
251 |
quiz_data_state = gr.State(value=None)
|
252 |
|
253 |
+
# Excel download file
|
254 |
+
excel_download = gr.File(label="Download Excel", visible=False)
|
255 |
+
|
256 |
check_score_btn = gr.Button("Check Score", variant="primary", size="lg")
|
257 |
+
|
258 |
+
# HTML output for colorful score display at bottom
|
259 |
+
score_output = gr.HTML(visible=False, label="Your Results")
|
260 |
|
261 |
+
# Register the click event for Generate Quiz without @ decorator
|
262 |
generate_quiz_btn.click(
|
263 |
fn=retrieve_and_generate_quiz,
|
264 |
inputs=[difficulty_radio, topic],
|
265 |
+
outputs=[quiz_data_state]
|
266 |
).then(
|
267 |
fn=update_quiz_components,
|
268 |
+
inputs=[quiz_data_state],
|
269 |
outputs=question_radios + [quiz_msg, excel_download]
|
270 |
).then(
|
271 |
+
fn=lambda: gr.update(visible=True), # Make Excel download visible
|
272 |
inputs=[],
|
273 |
outputs=[excel_download]
|
274 |
)
|
275 |
|
276 |
+
# FIXED: Register the click event for Check Score with correct input handling
|
277 |
check_score_btn.click(
|
278 |
fn=collect_answers_and_calculate,
|
279 |
+
inputs=question_radios + [quiz_data_state], # This creates a list of 11 inputs
|
280 |
outputs=[score_output],
|
281 |
api_name="check_score"
|
282 |
).then(
|
283 |
+
fn=lambda: gr.update(visible=True), # Make score output visible after calculation
|
284 |
inputs=[],
|
285 |
outputs=[score_output]
|
286 |
)
|
287 |
|
288 |
if __name__ == "__main__":
|
289 |
+
QUIZBOT.queue().launch(server_name="0.0.0.0", server_port=7860, share=True)
|
290 |
# import pandas as pd
|
291 |
# import json
|
292 |
# import gradio as gr
|