NCTCMumbai commited on
Commit
a59c14d
Β·
verified Β·
1 Parent(s): 05d3040

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +189 -305
app.py CHANGED
@@ -1,21 +1,16 @@
 
1
  import pandas as pd
2
  import json
3
- import gradio as gr
4
  from pathlib import Path
5
- from tempfile import NamedTemporaryFile
6
  from sentence_transformers import CrossEncoder
7
  import numpy as np
8
  from time import perf_counter
9
- from backend.semantic_search import table, retriever
10
- import os
11
- import logging
12
-
13
- # Add Groq imports
14
  from phi.agent import Agent
15
  from phi.model.groq import Groq
16
-
17
- VECTOR_COLUMN_NAME = "vector"
18
- TEXT_COLUMN_NAME = "text"
19
 
20
  # Set up logging
21
  logging.basicConfig(level=logging.INFO)
@@ -26,355 +21,244 @@ api_key = os.getenv("GROQ_API_KEY")
26
  if not api_key:
27
  gr.Warning("GROQ_API_KEY not found. Set it in 'Repository secrets'.")
28
  logger.error("GROQ_API_KEY not found.")
29
- api_key = ""
30
  else:
31
  os.environ["GROQ_API_KEY"] = api_key
32
 
33
- # Initialize Groq Agent for quiz generation
34
- quiz_agent = Agent(
35
- name="Quiz Generation Assistant",
36
- role="You are an expert quiz generator for Customs Manual content",
 
 
 
 
 
 
 
 
 
37
  instructions=[
38
- "You are an expert quiz generator specializing in Customs Manual and trade-related topics.",
39
- "Create exactly 10 multiple choice questions with 4 options each.",
40
- "Base questions strictly on the provided documents from Customs Manual.",
41
- "Return the response in the exact JSON format requested.",
42
- "Ensure questions match the specified difficulty level.",
43
- "Make sure all questions are clear and relevant to customs procedures.",
44
- "Focus on practical customs knowledge for training officers."
45
  ],
46
  model=Groq(id="llama3-70b-8192", api_key=api_key),
47
- markdown=False
 
48
  )
49
 
50
- def retrieve_documents_for_quiz(query, cross_encoder_choice):
51
- """Retrieve and rank documents for quiz generation"""
52
- top_rerank = 25
53
- top_k_rank = 15
54
-
55
- try:
56
- start_time = perf_counter()
57
-
58
- # Encode query and search documents
59
- query_vec = retriever.encode(query)
60
- documents = table.search(query_vec, vector_column_name=VECTOR_COLUMN_NAME).limit(top_rerank).to_list()
61
- documents = [doc[TEXT_COLUMN_NAME] for doc in documents]
62
-
63
- # Re-rank documents using cross-encoder
64
- if cross_encoder_choice == '(ACCURATE) BGE reranker':
65
- cross_encoder_model = CrossEncoder('BAAI/bge-reranker-base')
66
- else:
67
- cross_encoder_model = CrossEncoder('cross-encoder/ms-marco-MiniLM-L-6-v2')
68
-
69
- query_doc_pair = [[query, doc] for doc in documents]
70
- cross_scores = cross_encoder_model.predict(query_doc_pair)
71
- sim_scores_argsort = list(reversed(np.argsort(cross_scores)))
72
- documents = [documents[idx] for idx in sim_scores_argsort[:top_k_rank]]
73
-
74
- logger.info(f"Document retrieval took {perf_counter() - start_time:.2f} seconds")
75
- return documents
76
-
77
- except Exception as e:
78
- logger.error(f"Error in document retrieval: {e}")
79
- return []
80
 
81
- def generate_quiz_with_agent(topic, difficulty, documents):
82
- """Generate quiz using Groq agent"""
83
- context = "\n\n".join(documents) if documents else ""
84
-
85
- prompt = f"""You are a great teacher and your task is to create 10 questions with 4 choices with {difficulty} difficulty about the topic "{topic}" only from the below given documents from Customs Manual:
86
-
87
- {context}
88
-
89
- Create questions and answers in JSON format with the following structure:
90
- - Questions as "Q1": "question text" to "Q10": "question text"
91
- - Four choices as "Q1:C1": "choice 1" to "Q1:C4": "choice 4" for each question
92
- - Answers as "A1": "Q1:C#" to "A10": "Q10:C#" where # is the correct choice number
93
-
94
- Example format:
95
- {{
96
- "Q1": "What is the procedure for customs clearance?",
97
- "Q1:C1": "Submit documents online",
98
- "Q1:C2": "Visit customs office directly",
99
- "Q1:C3": "File declaration and pay duties",
100
- "Q1:C4": "Contact shipping agent only",
101
- "A1": "Q1:C3"
102
- }}
103
-
104
- Provide complete JSON with all 10 questions, their choices, and answers based strictly on the provided Customs Manual content."""
105
-
106
  try:
107
- response = quiz_agent.run(prompt)
108
- response_text = response.content if hasattr(response, 'content') else str(response)
109
- return response_text
110
  except Exception as e:
111
- logger.error(f"Error in quiz generation: {e}")
112
  return None
113
 
114
- def json_to_excel(output_json):
115
- """Convert quiz JSON to Excel format"""
 
 
 
 
116
  data = []
117
- gr.Warning('Generating Shareable file link..', duration=30)
118
 
119
- for i in range(1, 11):
120
- question_key = f"Q{i}"
121
- answer_key = f"A{i}"
122
-
123
- question = output_json.get(question_key, '')
124
- correct_answer_key = output_json.get(answer_key, '')
125
- correct_answer = correct_answer_key.split(':')[-1].replace('C', '').strip() if correct_answer_key else ''
126
-
127
- # Extract options
128
- option_keys = [f"{question_key}:C{j}" for j in range(1, 5)]
129
- options = [output_json.get(key, '') for key in option_keys]
130
 
131
- # Add data row
132
- data.append([
133
- question, # Question Text
134
- "Multiple Choice", # Question Type
135
- options[0] if len(options) > 0 else '', # Option 1
136
- options[1] if len(options) > 1 else '', # Option 2
137
- options[2] if len(options) > 2 else '', # Option 3
138
- options[3] if len(options) > 3 else '', # Option 4
139
- '', # Option 5 (empty)
140
- correct_answer, # Correct Answer
141
- 30, # Time in seconds
142
- '' # Image Link
143
- ])
144
-
 
145
  # Create DataFrame
146
  df = pd.DataFrame(data, columns=[
147
- "Question Text", "Question Type", "Option 1", "Option 2", "Option 3",
148
- "Option 4", "Option 5", "Correct Answer", "Time in seconds", "Image Link"
 
 
 
 
 
 
 
 
149
  ])
150
-
 
151
  temp_file = NamedTemporaryFile(delete=False, suffix=".xlsx")
152
  df.to_excel(temp_file.name, index=False)
153
  return temp_file.name
154
 
155
- # Global variable to store quiz data
156
- quiz_data = None
 
 
157
 
158
- def generate_quiz_function(topic, difficulty, cross_encoder_choice):
159
- """Main quiz generation function"""
160
- global quiz_data
161
-
162
- if not topic.strip():
163
- return "Please enter a topic for the quiz.", [], None
164
-
165
- gr.Warning('Generating Quiz may take 1-2 minutes. Please wait.', duration=60)
166
 
167
- # Retrieve documents
168
- documents = retrieve_documents_for_quiz(topic, cross_encoder_choice)
 
 
 
 
 
 
 
169
 
170
- if not documents:
171
- return "No relevant documents found for this topic. Please try a different topic.", [], None
 
 
172
 
173
- # Generate quiz
174
- response_text = generate_quiz_with_agent(topic, difficulty, documents)
 
 
 
175
 
176
- if not response_text:
177
- return "Error generating quiz. Please try again.", [], None
 
 
 
178
 
179
- try:
180
- # Extract JSON from response
181
- start_index = response_text.find('{')
182
- end_index = response_text.rfind('}')
183
- cleaned_response = response_text[start_index:end_index + 1] if start_index != -1 and end_index != -1 else ''
184
-
185
- if not cleaned_response:
186
- return "Could not extract quiz data. Please try again.", [], None
187
-
188
- output_json = json.loads(cleaned_response)
189
- quiz_data = output_json
190
-
191
- # Generate Excel file
192
- excel_file = json_to_excel(output_json)
193
-
194
- # Create question components
195
- question_components = []
196
- for question_num in range(1, 11):
197
- question_key = f"Q{question_num}"
198
-
199
- question_text = output_json.get(question_key)
200
- if not question_text:
201
- continue
202
-
203
- choice_keys = [f"{question_key}:C{i}" for i in range(1, 5)]
204
- choice_list = [output_json.get(choice_key, f"Choice {i} not found") for i, choice_key in enumerate(choice_keys, 1)]
205
-
206
- question_components.append((question_text, choice_list))
207
-
208
- return "Quiz Generated Successfully!", question_components, excel_file
209
-
210
- except json.JSONDecodeError as e:
211
- logger.error(f"Failed to decode JSON: {e}")
212
- return "Error parsing quiz data. Please try again.", [], None
213
- except Exception as e:
214
- logger.error(f"Error in quiz generation: {e}")
215
- return "Error generating quiz. Please try again.", [], None
216
 
217
- def check_answers_function(answers):
218
- """Check quiz answers and calculate score"""
219
- global quiz_data
220
 
221
- if not quiz_data:
222
- return "No quiz data available. Please generate a quiz first."
 
223
 
 
 
 
 
224
  score = 0
225
- total_questions = 0
226
 
227
- for question_num in range(1, 11):
228
- answer_key = f"A{question_num}"
229
- correct_answer_key = quiz_data.get(answer_key)
230
-
231
- if not correct_answer_key:
232
- continue
233
 
234
- correct_answer = quiz_data.get(correct_answer_key, "")
235
- user_answer = answers[question_num - 1] if question_num - 1 < len(answers) else ""
236
-
237
- total_questions += 1
238
- if user_answer == correct_answer:
239
- score += 1
240
-
241
- if score > 7:
242
- message = f"### Excellent! You got {score} out of {total_questions}!"
243
- elif score > 5:
244
- message = f"### Good! You got {score} out of {total_questions}!"
 
 
 
 
 
 
 
 
 
245
  else:
246
- message = f"### You got {score} out of {total_questions}! Don't worry. You can prepare well and try better next time!"
247
 
248
  return message
249
 
250
- # Gradio Interface
251
- with gr.Blocks(title="ADWITIYA Quiz Maker", theme=gr.themes.Default(primary_hue="cyan", secondary_hue="yellow", neutral_hue="purple")) as demo:
252
-
253
- # Header section
 
254
  with gr.Row():
255
  with gr.Column(scale=2):
256
- try:
257
- gr.Image(value='logo.png', height=200, width=200)
258
- except:
259
- gr.HTML("<div style='height: 200px; width: 200px; background-color: #f0f0f0; display: flex; align-items: center; justify-content: center;'>Logo</div>")
260
  with gr.Column(scale=6):
261
  gr.HTML("""
262
  <center>
263
- <h1><span style="color: purple;">ADWITIYA</span> Customs Manual Quizbot</h1>
264
- <h2>Generative AI-powered Capacity building for Training Officers</h2>
265
- <i>⚠️ NACIN Faculties create quiz from any topic dynamically for classroom evaluation after their sessions ! ⚠️</i>
266
  </center>
267
  """)
268
-
269
- # Input components
270
- topic_input = gr.Textbox(
271
- label="Enter the Topic for Quiz",
272
- placeholder="Write any topic/details from Customs Manual"
273
- )
274
-
275
  with gr.Row():
276
- difficulty_radio = gr.Radio(
277
- choices=["easy", "average", "hard"],
278
- label="How difficult should the quiz be?",
279
- value="average"
280
- )
281
- cross_encoder_radio = gr.Radio(
282
- choices=['(FAST) MiniLM-L6v2', '(ACCURATE) BGE reranker'],
283
- value='(ACCURATE) BGE reranker',
284
- label="Embeddings Model",
285
- info="Select the model for document ranking"
286
- )
287
-
288
- generate_btn = gr.Button("Generate Quiz!πŸš€", variant="primary")
289
- status_text = gr.Textbox(label="Status", interactive=False)
290
-
291
- # Quiz display area
292
- quiz_state = gr.State([])
293
- question_radios = []
294
-
295
- with gr.Column(visible=False) as quiz_section:
296
- gr.Markdown("## Quiz Questions")
297
- for i in range(10):
298
- question_radios.append(
299
- gr.Radio(label=f"Question {i+1}", visible=False, interactive=True)
300
- )
301
-
302
- check_btn = gr.Button("Check Score", variant="secondary")
303
- score_display = gr.Markdown()
304
 
305
- excel_file = gr.File(label="Download Excel", visible=False)
 
 
 
 
 
306
 
 
 
 
 
307
  # Event handlers
308
- def update_quiz_display(topic, difficulty, cross_encoder):
309
- status, questions, excel = generate_quiz_function(topic, difficulty, cross_encoder)
310
-
311
- if not questions:
312
- return (
313
- status,
314
- gr.Column(visible=False),
315
- gr.File(visible=False),
316
- questions,
317
- *[gr.Radio(visible=False) for _ in range(10)]
318
- )
319
-
320
- # Update question radios
321
- question_updates = []
322
- for i, (question_text, choices) in enumerate(questions):
323
- if i < 10:
324
- question_updates.append(
325
- gr.Radio(
326
- label=question_text,
327
- choices=choices,
328
- visible=True,
329
- interactive=True
330
- )
331
- )
332
- else:
333
- question_updates.append(gr.Radio(visible=False))
334
-
335
- # Fill remaining slots if less than 10 questions
336
- while len(question_updates) < 10:
337
- question_updates.append(gr.Radio(visible=False))
338
-
339
- return (
340
- status,
341
- gr.Column(visible=True),
342
- gr.File(value=excel, visible=True) if excel else gr.File(visible=False),
343
- questions,
344
- *question_updates
345
- )
346
-
347
- def check_quiz_answers(*answers):
348
- return check_answers_function(list(answers))
349
-
350
- # Connect events
351
- generate_btn.click(
352
- fn=update_quiz_display,
353
- inputs=[topic_input, difficulty_radio, cross_encoder_radio],
354
- outputs=[status_text, quiz_section, excel_file, quiz_state] + question_radios
355
- )
356
-
357
- check_btn.click(
358
- fn=check_quiz_answers,
359
- inputs=question_radios,
360
- outputs=score_display
361
  )
362
-
363
- # Example questions
364
- gr.Examples(
365
- examples=[
366
- 'Customs clearance procedures',
367
- 'Import duty calculation',
368
- 'Export documentation requirements',
369
- 'Customs valuation methods',
370
- 'Special economic zones regulations'
371
- ],
372
- inputs=topic_input,
373
- label="Try these example topics:"
374
  )
375
 
376
  if __name__ == "__main__":
377
- demo.launch(server_name="0.0.0.0", server_port=7860)
378
  # import pandas as pd
379
  # import json
380
  # import gradio as gr
 
1
+ import gradio as gr
2
  import pandas as pd
3
  import json
 
4
  from pathlib import Path
 
5
  from sentence_transformers import CrossEncoder
6
  import numpy as np
7
  from time import perf_counter
8
+ from pydantic import BaseModel, Field
 
 
 
 
9
  from phi.agent import Agent
10
  from phi.model.groq import Groq
11
+ from tempfile import NamedTemporaryFile
12
+ import os
13
+ import logging
14
 
15
  # Set up logging
16
  logging.basicConfig(level=logging.INFO)
 
21
  if not api_key:
22
  gr.Warning("GROQ_API_KEY not found. Set it in 'Repository secrets'.")
23
  logger.error("GROQ_API_KEY not found.")
 
24
  else:
25
  os.environ["GROQ_API_KEY"] = api_key
26
 
27
+ # Pydantic Model for Quiz Structure
28
+ class QuizItem(BaseModel):
29
+ question: str = Field(..., description="The quiz question")
30
+ choices: list[str] = Field(..., description="List of 4 multiple-choice options")
31
+ correct_answer: str = Field(..., description="The correct choice (e.g., 'C1')")
32
+
33
+ class QuizOutput(BaseModel):
34
+ items: list[QuizItem] = Field(..., description="List of 10 quiz items")
35
+
36
+ # Initialize Quiz Generator Agent
37
+ quiz_generator = Agent(
38
+ name="Quiz Generator",
39
+ role="Generates structured quiz questions and answers",
40
  instructions=[
41
+ "Create 10 questions with 4 choices each based on the provided topic and documents.",
42
+ "Use the specified difficulty level (easy, average, hard) to adjust question complexity.",
43
+ "Ensure questions are derived only from the provided documents.",
44
+ "Return the output in a structured format using the QuizOutput Pydantic model.",
45
+ "Each question should have a unique correct answer from the choices (labeled C1, C2, C3, C4)."
 
 
46
  ],
47
  model=Groq(id="llama3-70b-8192", api_key=api_key),
48
+ response_model=QuizOutput,
49
+ markdown=True
50
  )
51
 
52
+ VECTOR_COLUMN_NAME = "vector"
53
+ TEXT_COLUMN_NAME = "text"
54
+ proj_dir = Path.cwd()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
55
 
56
+ # Import backend functions
57
+ from backend.semantic_search import table, retriever
58
+
59
+ def generate_quiz_data(question_difficulty, topic, documents_str):
60
+ prompt = f"""Generate a quiz with {question_difficulty} difficulty on topic '{topic}' using only the following documents:\n{documents_str}"""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
  try:
62
+ response = quiz_generator.run(prompt)
63
+ return response.content
 
64
  except Exception as e:
65
+ logger.error(f"Failed to generate quiz: {e}")
66
  return None
67
 
68
+ def quiz_to_excel(quiz_data):
69
+ """Convert quiz data to Excel format"""
70
+ if not quiz_data or not quiz_data.items:
71
+ return None
72
+
73
+ gr.Warning('Generating Excel file...', duration=10)
74
  data = []
 
75
 
76
+ for i, item in enumerate(quiz_data.items, 1):
77
+ # Get correct answer index
78
+ correct_answer_index = int(item.correct_answer[1]) - 1 # 'C3' -> index 2
 
 
 
 
 
 
 
 
79
 
80
+ # Prepare row data
81
+ row = [
82
+ item.question, # Question Text
83
+ "Multiple Choice", # Question Type
84
+ item.choices[0] if len(item.choices) > 0 else '', # Option 1
85
+ item.choices[1] if len(item.choices) > 1 else '', # Option 2
86
+ item.choices[2] if len(item.choices) > 2 else '', # Option 3
87
+ item.choices[3] if len(item.choices) > 3 else '', # Option 4
88
+ '', # Option 5 (empty)
89
+ str(correct_answer_index + 1), # Correct Answer (1-4)
90
+ 30, # Time in seconds
91
+ '' # Image Link
92
+ ]
93
+ data.append(row)
94
+
95
  # Create DataFrame
96
  df = pd.DataFrame(data, columns=[
97
+ "Question Text",
98
+ "Question Type",
99
+ "Option 1",
100
+ "Option 2",
101
+ "Option 3",
102
+ "Option 4",
103
+ "Option 5",
104
+ "Correct Answer",
105
+ "Time in seconds",
106
+ "Image Link"
107
  ])
108
+
109
+ # Save to temporary file
110
  temp_file = NamedTemporaryFile(delete=False, suffix=".xlsx")
111
  df.to_excel(temp_file.name, index=False)
112
  return temp_file.name
113
 
114
+ def retrieve_and_generate_quiz(question_difficulty, topic):
115
+ gr.Warning('Generating quiz may take 1-2 minutes. Please wait.', duration=60)
116
+ top_k_rank = 10
117
+ documents = []
118
 
119
+ document_start = perf_counter()
120
+ query_vec = retriever.encode(topic)
121
+ documents = [doc[TEXT_COLUMN_NAME] for doc in table.search(query_vec, vector_column_name=VECTOR_COLUMN_NAME).limit(top_k_rank).to_list()]
 
 
 
 
 
122
 
123
+ # Apply BGE reranker
124
+ cross_encoder = CrossEncoder('BAAI/bge-reranker-base')
125
+ query_doc_pair = [[topic, doc] for doc in documents]
126
+ cross_scores = cross_encoder.predict(query_doc_pair)
127
+ sim_scores_argsort = list(reversed(np.argsort(cross_scores)))
128
+ documents = [documents[idx] for idx in sim_scores_argsort[:top_k_rank]]
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, excel_file):
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
 
144
+ radio_updates = []
145
+ for i, item in enumerate(quiz_data.items[:10]):
146
+ choices = item.choices
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 simple score message
182
+ if answered_questions == 0:
183
+ message = "⚠�� Please answer at least one question!"
184
+ elif score == answered_questions:
185
+ message = f"πŸ† PERFECT SCORE! You got {score} out of {answered_questions} correct! Outstanding performance! 🌟"
186
+ elif score > answered_questions * 0.7:
187
+ message = f"πŸŽ‰ EXCELLENT! You got {score} out of {answered_questions} correct! Great job! πŸ’ͺ"
188
+ elif score > answered_questions * 0.5:
189
+ message = f"πŸ‘ GOOD JOB! You got {score} out of {answered_questions} correct! Well done! πŸ“š"
190
  else:
191
+ message = f"πŸ’ͺ KEEP TRYING! You got {score} out of {answered_questions} correct! Practice makes perfect! πŸ“–βœ¨"
192
 
193
  return message
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
+ # Header
200
  with gr.Row():
201
  with gr.Column(scale=2):
202
+ gr.Image(value='logo.png', height=200, width=200)
 
 
 
203
  with gr.Column(scale=6):
204
  gr.HTML("""
205
  <center>
206
+ <h1><span style="color: purple;">CBSE GYAN</span> Quiz Bot</h1>
207
+ <h2>Generative AI-powered Learning for CBSE Students</h2>
208
+ <i>⚠️ Students can create quiz from any topic from CBSE curriculum and evaluate themselves! ⚠️</i>
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
+ # Quiz questions (hidden initially)
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
+ # Check score button
231
+ check_score_btn = gr.Button("Check Score", variant="primary", size="lg")
232
+ score_output = gr.Textbox(label="Your Results", visible=False)
233
+
234
  # Event handlers
235
+ generate_quiz_btn.click(
236
+ fn=retrieve_and_generate_quiz,
237
+ inputs=[difficulty_radio, topic],
238
+ outputs=[quiz_data_state, excel_download]
239
+ ).then(
240
+ fn=update_quiz_components,
241
+ inputs=[quiz_data_state, excel_download],
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