Spaces:
Sleeping
Sleeping
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
|