capradeepgujaran commited on
Commit
418545a
1 Parent(s): 51fcc77

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +118 -103
app.py CHANGED
@@ -43,14 +43,8 @@ class QuizApp:
43
  try:
44
  response = client.chat.completions.create(
45
  messages=[
46
- {
47
- "role": "system",
48
- "content": "You are a quiz generator. Create clear questions with concise answer options."
49
- },
50
- {
51
- "role": "user",
52
- "content": prompt
53
- }
54
  ],
55
  model="llama-3.2-3b-preview",
56
  temperature=0.3,
@@ -67,11 +61,9 @@ class QuizApp:
67
  for q in questions:
68
  if not all(key in q for key in ["question", "options", "correct_answer"]):
69
  continue
70
-
71
  clean_options = [opt.strip()[:100] for opt in q["options"] if isinstance(opt, str)]
72
  if len(clean_options) != 4:
73
  continue
74
-
75
  clean_q = {
76
  "question": q["question"].strip(),
77
  "options": clean_options,
@@ -92,7 +84,7 @@ class QuizApp:
92
 
93
  total = len(self.current_questions)
94
  correct = 0
95
- results = [] # Store whether each answer was correct
96
 
97
  for i, (q, a) in enumerate(zip(self.current_questions, answers)):
98
  try:
@@ -102,25 +94,19 @@ class QuizApp:
102
  if is_correct:
103
  correct += 1
104
  results.append({
105
- "question_index": i,
106
- "selected_index": selected_index,
107
- "correct_index": q["correct_answer"],
108
- "is_correct": is_correct
109
  })
110
  else:
111
  results.append({
112
- "question_index": i,
113
- "selected_index": None,
114
- "correct_index": q["correct_answer"],
115
- "is_correct": False
116
  })
117
  except (ValueError, TypeError) as e:
118
  print(f"Error processing answer {i}: {e}")
119
  results.append({
120
- "question_index": i,
121
- "selected_index": None,
122
- "correct_index": q["correct_answer"],
123
- "is_correct": False
124
  })
125
 
126
  return (correct / total) * 100, results
@@ -129,8 +115,6 @@ def create_quiz_interface():
129
  quiz_app = QuizApp()
130
 
131
  with gr.Blocks(title="CertifyMe AI", theme=gr.themes.Soft()) as demo:
132
- current_questions = gr.State([])
133
-
134
  # Header
135
  gr.Markdown("""
136
  # 🎓 CertifyMe AI
@@ -139,7 +123,7 @@ def create_quiz_interface():
139
 
140
  # Tabs
141
  with gr.Tabs() as tabs:
142
- # Step 1: Profile Setup (remains largely the same)
143
  with gr.Tab("📋 Step 1: Profile Setup") as tab1:
144
  with gr.Row():
145
  name = gr.Textbox(label="Full Name", placeholder="Enter your full name")
@@ -167,139 +151,170 @@ def create_quiz_interface():
167
 
168
  # Step 2: Take Assessment
169
  with gr.Tab("📝 Step 2: Take Assessment") as tab2:
170
- assessment_status = gr.Markdown("")
171
- with gr.Group() as question_group:
172
- questions = []
173
- for i in range(5):
174
- with gr.Group(visible=False) as qgroup:
175
- question_md = gr.Markdown("", elem_id=f"question_{i}")
176
- radio = gr.Radio(
177
- choices=[],
178
- label="Select your answer:",
179
- interactive=True,
180
- elem_id=f"answer_{i}"
181
- )
182
- result_md = gr.Markdown("", elem_id=f"result_{i}")
183
- questions.append({"group": qgroup, "md": question_md, "radio": radio, "result": result_md})
184
 
185
  submit_btn = gr.Button("Submit Assessment", variant="primary", size="lg")
186
- result_modal = gr.Markdown("")
187
 
188
  # Step 3: Get Certified
189
  with gr.Tab("🎓 Step 3: Get Certified") as tab3:
190
  score_display = gr.Number(label="Your Score")
191
- result_message = gr.Markdown("")
192
  course_name = gr.Textbox(
193
  label="Certification Title",
194
  value="Professional Assessment Certification"
195
  )
196
  certificate_display = gr.Image(label="Your Certificate")
197
 
 
 
 
198
  def update_questions(text, num_questions):
199
  if not text.strip():
200
- return [
201
- gr.update(visible=False) for _ in range(5)
202
- ], "⚠️ Please enter some text content to generate questions.", [], 0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
203
 
204
- success, generated_questions = quiz_app.generate_questions(text, num_questions)
 
205
 
206
- if not success or not generated_questions:
207
- return [
208
- gr.update(visible=False) for _ in range(5)
209
- ], "❌ Failed to generate questions. Please try again.", [], 0
210
 
211
- updates = []
212
- for i in range(5):
213
- if i < len(generated_questions):
214
- q = generated_questions[i]
215
- updates.append(gr.update(
216
- visible=True,
217
- value={
218
- "md": f"### Question {i+1}\n{q['question']}",
219
- "radio": gr.update(choices=q["options"], value=None),
220
- "result": ""
221
- }
222
- ))
223
- else:
224
- updates.append(gr.update(visible=False))
225
 
226
- return updates, "", generated_questions, 1
227
-
228
- def submit_quiz(answers, questions):
229
- if not all(a is not None for a in answers[:len(questions)]):
230
- return (
231
- gr.update(value="⚠️ Please answer all questions before submitting."),
232
- score_display.value,
233
- 0
234
- )
 
 
 
 
 
 
 
 
 
 
235
 
236
  score, results = quiz_app.calculate_score(answers)
237
 
238
- # Update result display for each question
239
- updates = []
240
  for i, result in enumerate(results):
241
  if result["is_correct"]:
242
- status = "✅ Correct!"
243
- color = "green"
 
 
244
  else:
245
- status = f"❌ Incorrect. Correct answer: {questions[i]['options'][result['correct_index']]}"
246
- color = "red"
247
-
248
- updates.append(gr.update(
249
- visible=True,
250
- value=f'<div style="color: {color};">{status}</div>'
251
- ))
 
252
 
253
- # Add result message
254
  if score >= 80:
255
  message = f"""
256
- ## 🎉 Congratulations!
257
  You passed the assessment with a score of {score:.1f}%
258
  Your certificate has been generated.
259
  """
260
  else:
261
  message = f"""
262
- ## Try Again
263
  Your score: {score:.1f}%
264
  You need 80% or higher to pass and receive a certificate.
265
  """
266
 
267
- return updates, message, score, 2
268
-
269
  # Event handlers
270
  generate_btn.click(
271
  fn=update_questions,
272
  inputs=[text_input, num_questions],
273
  outputs=[
274
- *[q["group"] for q in questions],
275
- assessment_status,
276
- current_questions,
277
- gr.State(1)
 
 
278
  ]
279
  ).then(
280
  fn=lambda x: gr.update(selected=x),
281
- inputs=[gr.State(1)],
282
  outputs=tabs
283
  )
284
 
285
  submit_btn.click(
286
- fn=submit_quiz,
287
- inputs=[
288
- *[q["radio"] for q in questions],
289
- current_questions
290
- ],
291
  outputs=[
292
- *[q["result"] for q in questions],
293
- result_modal,
294
  score_display,
295
- gr.State(2)
296
  ]
297
  ).then(
298
  fn=lambda x: gr.update(selected=x),
299
- inputs=[gr.State(2)],
300
  outputs=tabs
301
  )
302
 
 
 
 
 
 
 
 
303
  def generate_certificate(score, name, course_name, company_logo=None, participant_photo=None):
304
  """
305
  Generate a certificate with custom styling and optional logo/photo
 
43
  try:
44
  response = client.chat.completions.create(
45
  messages=[
46
+ {"role": "system", "content": "You are a quiz generator. Create clear questions with concise answer options."},
47
+ {"role": "user", "content": prompt}
 
 
 
 
 
 
48
  ],
49
  model="llama-3.2-3b-preview",
50
  temperature=0.3,
 
61
  for q in questions:
62
  if not all(key in q for key in ["question", "options", "correct_answer"]):
63
  continue
 
64
  clean_options = [opt.strip()[:100] for opt in q["options"] if isinstance(opt, str)]
65
  if len(clean_options) != 4:
66
  continue
 
67
  clean_q = {
68
  "question": q["question"].strip(),
69
  "options": clean_options,
 
84
 
85
  total = len(self.current_questions)
86
  correct = 0
87
+ results = []
88
 
89
  for i, (q, a) in enumerate(zip(self.current_questions, answers)):
90
  try:
 
94
  if is_correct:
95
  correct += 1
96
  results.append({
97
+ "is_correct": is_correct,
98
+ "correct_answer": q["options"][q["correct_answer"]]
 
 
99
  })
100
  else:
101
  results.append({
102
+ "is_correct": False,
103
+ "correct_answer": q["options"][q["correct_answer"]]
 
 
104
  })
105
  except (ValueError, TypeError) as e:
106
  print(f"Error processing answer {i}: {e}")
107
  results.append({
108
+ "is_correct": False,
109
+ "correct_answer": q["options"][q["correct_answer"]]
 
 
110
  })
111
 
112
  return (correct / total) * 100, results
 
115
  quiz_app = QuizApp()
116
 
117
  with gr.Blocks(title="CertifyMe AI", theme=gr.themes.Soft()) as demo:
 
 
118
  # Header
119
  gr.Markdown("""
120
  # 🎓 CertifyMe AI
 
123
 
124
  # Tabs
125
  with gr.Tabs() as tabs:
126
+ # Step 1: Profile Setup
127
  with gr.Tab("📋 Step 1: Profile Setup") as tab1:
128
  with gr.Row():
129
  name = gr.Textbox(label="Full Name", placeholder="Enter your full name")
 
151
 
152
  # Step 2: Take Assessment
153
  with gr.Tab("📝 Step 2: Take Assessment") as tab2:
154
+ question_box = gr.Markdown("")
155
+ answers = []
156
+ feedback = []
157
+
158
+ for i in range(5):
159
+ radio = gr.Radio(
160
+ choices=[],
161
+ label=f"Question {i+1}",
162
+ visible=False
163
+ )
164
+ answers.append(radio)
165
+ fb = gr.Markdown(visible=False)
166
+ feedback.append(fb)
 
167
 
168
  submit_btn = gr.Button("Submit Assessment", variant="primary", size="lg")
169
+ result_message = gr.Markdown("")
170
 
171
  # Step 3: Get Certified
172
  with gr.Tab("🎓 Step 3: Get Certified") as tab3:
173
  score_display = gr.Number(label="Your Score")
174
+ completion_message = gr.Markdown("")
175
  course_name = gr.Textbox(
176
  label="Certification Title",
177
  value="Professional Assessment Certification"
178
  )
179
  certificate_display = gr.Image(label="Your Certificate")
180
 
181
+ # Store questions state
182
+ questions_state = gr.State([])
183
+
184
  def update_questions(text, num_questions):
185
  if not text.strip():
186
+ return (
187
+ gr.update(value="Please enter content to generate questions."),
188
+ *[gr.update(visible=False) for _ in range(5)], # Radio buttons
189
+ *[gr.update(visible=False) for _ in range(5)], # Feedback
190
+ [], # questions state
191
+ 1, # tab index
192
+ "Please enter content to generate questions." # result message
193
+ )
194
+
195
+ success, questions = quiz_app.generate_questions(text, num_questions)
196
+ if not success:
197
+ return (
198
+ gr.update(value="Failed to generate questions. Please try again."),
199
+ *[gr.update(visible=False) for _ in range(5)],
200
+ *[gr.update(visible=False) for _ in range(5)],
201
+ [],
202
+ 1,
203
+ "Failed to generate questions. Please try again."
204
+ )
205
 
206
+ # Create question display with embedded radio buttons
207
+ questions_md = "# 📝 Assessment Questions\n\n"
208
 
209
+ # Update radio buttons and create question display
210
+ radio_updates = []
211
+ feedback_updates = []
 
212
 
213
+ for i, q in enumerate(questions):
214
+ questions_md += f"### Question {i+1}\n{q['question']}\n\n"
215
+ radio_updates.append(gr.update(
216
+ choices=q["options"],
217
+ label=f"Select your answer for Question {i+1}:",
218
+ visible=True,
219
+ value=None
220
+ ))
221
+ feedback_updates.append(gr.update(visible=False, value=""))
 
 
 
 
 
222
 
223
+ # Hide unused radio buttons
224
+ for i in range(len(questions), 5):
225
+ radio_updates.append(gr.update(visible=False))
226
+ feedback_updates.append(gr.update(visible=False))
227
+
228
+ return (
229
+ gr.update(value=questions_md),
230
+ *radio_updates,
231
+ *feedback_updates,
232
+ questions,
233
+ 1,
234
+ ""
235
+ )
236
+
237
+ def submit_answers(q1, q2, q3, q4, q5, questions):
238
+ answers = [q1, q2, q3, q4, q5][:len(questions)]
239
+
240
+ if not all(a is not None for a in answers):
241
+ return [gr.update() for _ in range(5)], 0, "Please answer all questions before submitting."
242
 
243
  score, results = quiz_app.calculate_score(answers)
244
 
245
+ # Create feedback for each answer
246
+ feedback_updates = []
247
  for i, result in enumerate(results):
248
  if result["is_correct"]:
249
+ feedback_updates.append(gr.update(
250
+ visible=True,
251
+ value='<div style="color: green; margin-top: 10px;">✅ Correct!</div>'
252
+ ))
253
  else:
254
+ feedback_updates.append(gr.update(
255
+ visible=True,
256
+ value=f'<div style="color: red; margin-top: 10px;">❌ Incorrect. Correct answer: {result["correct_answer"]}</div>'
257
+ ))
258
+
259
+ # Add empty updates for unused feedback slots
260
+ for _ in range(len(results), 5):
261
+ feedback_updates.append(gr.update(visible=False))
262
 
263
+ # Create result message
264
  if score >= 80:
265
  message = f"""
266
+ ### 🎉 Congratulations!
267
  You passed the assessment with a score of {score:.1f}%
268
  Your certificate has been generated.
269
  """
270
  else:
271
  message = f"""
272
+ ### Please Try Again
273
  Your score: {score:.1f}%
274
  You need 80% or higher to pass and receive a certificate.
275
  """
276
 
277
+ return feedback_updates, score, message
278
+
279
  # Event handlers
280
  generate_btn.click(
281
  fn=update_questions,
282
  inputs=[text_input, num_questions],
283
  outputs=[
284
+ question_box,
285
+ *answers,
286
+ *feedback,
287
+ questions_state,
288
+ gr.State(1),
289
+ result_message
290
  ]
291
  ).then(
292
  fn=lambda x: gr.update(selected=x),
293
+ inputs=gr.State(1),
294
  outputs=tabs
295
  )
296
 
297
  submit_btn.click(
298
+ fn=submit_answers,
299
+ inputs=[*answers, questions_state],
 
 
 
300
  outputs=[
301
+ *feedback,
 
302
  score_display,
303
+ result_message
304
  ]
305
  ).then(
306
  fn=lambda x: gr.update(selected=x),
307
+ inputs=gr.State(2),
308
  outputs=tabs
309
  )
310
 
311
+ # Certificate generation event handler
312
+ score_display.change(
313
+ fn=generate_certificate,
314
+ inputs=[score_display, name, course_name, company_logo, participant_photo],
315
+ outputs=[certificate_display, completion_message]
316
+ )
317
+
318
  def generate_certificate(score, name, course_name, company_logo=None, participant_photo=None):
319
  """
320
  Generate a certificate with custom styling and optional logo/photo