rivapereira123 commited on
Commit
624779f
Β·
verified Β·
1 Parent(s): 4a8ec40

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +163 -101
app.py CHANGED
@@ -325,121 +325,183 @@ def create_optimized_gradio_interface():
325
  show_safety_output = gr.Markdown(label="Safety Check")
326
 
327
 
328
- # Scenario Generator Tab
329
  with gr.Tab("πŸ§ͺ Scenario Generator"):
330
- scenario_query_input = gr.Textbox(label="Enter a medical topic")
331
- num_questions_slider = gr.Slider(1, 10, value=5, step=1, label="Number of Questions")
332
- scenario_submit = gr.Button("πŸš€ Generate Scenario")
333
- # -- Output containers --
334
- scenario_quiz_block = gr.Column(visible=False)
335
- scenario_result_output = gr.Markdown(visible=False, elem_classes=["quiz-result-output"])
336
- questions_state = gr.State()
337
-
338
- # -- Pre-allocate up to 10 quiz slots --
339
- quiz_questions = []
340
- with scenario_quiz_block:
341
- for i in range(10):
342
- q_md = gr.Markdown(visible=False)
343
- q_radio = gr.Radio(choices=[], type="index", visible=False)
344
- quiz_questions.append((q_md, q_radio))
345
- submit_quiz_btn = gr.Button("βœ… Submit Answers")
346
-
347
-
348
-
349
-
350
- def on_generate_click(query, num_q):
351
- questions = get_mcq_data(query, num_q)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
352
  if isinstance(questions, dict) and "error" in questions:
353
- updates = []
354
- for _ in range(10): # Hide all markdowns
355
- updates.append(gr.update(visible=False))
356
- for _ in range(10): # Hide all radios
357
- updates.append(gr.update(visible=False))
358
- updates.extend([
359
- gr.update(visible=False), # scenario_quiz_block
360
- gr.update(value=f"❌ Error: {questions['error']} – {questions['details']}", visible=True), # scenario_result_output
361
- None # questions_state
362
- ])
363
- return tuple(updates)
364
- # Success path
365
- updates = []
366
- for i in range(10):
367
- if i < len(questions):
368
- q = questions[i]
369
- updates.append(gr.update(value=f"**Q{i+1}: {q['question']}**", visible=True)) # markdown
370
- else:
371
- updates.append(gr.update(visible=False)) # markdown fallback
372
- for i in range(10):
373
- if i < len(questions):
374
- q = questions[i]
375
- choices = [f"{k}: {v}" for k, v in q["options"].items()]
376
- updates.append(gr.update(choices=choices, visible=True, value=None)) # radio
377
- else:
378
- updates.append(gr.update(visible=False)) # radio fallback
379
- updates.extend([
380
- gr.update(visible=True), # scenario_quiz_block
381
- gr.update(value="", visible=False), # scenario_result_output
382
- questions # questions_state
383
- ])
384
- return tuple(updates)
385
-
386
-
387
-
388
- def evaluate_quiz(*args):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
389
  questions = args[-1]
390
  selections = args[:-1]
391
  if not questions:
392
- return gr.update(value="❌ No questions to evaluate", visible=True)
393
  results = []
394
  score = 0
395
  total = len(questions)
396
  for i, selected_index in enumerate(selections):
397
  if i >= len(questions):
398
  break
399
- q = questions[i]
400
- correct_key = q["correct_answer"]
401
- correct_label = f"{correct_key}: {q['options'][correct_key]}"
402
- if selected_index is not None:
403
- user_key = list(q["options"].keys())[selected_index]
404
- user_label = f"{user_key}: {q['options'][user_key]}"
405
- correct = user_key == correct_key
406
  else:
407
- user_label = "No answer selected"
408
- correct = False
409
- if correct:
410
  score += 1
 
411
  results.append(f"""
412
- ### Question {i+1}
413
- **Your Answer:** {user_label}
414
- **Correct Answer:** {correct_label}
415
- {"βœ… Correct!" if correct else "❌ Incorrect."}
416
- πŸ’‘ **Explanation:** {q['feedback']}
417
- ---""")
418
- percentage = (score / total) * 100 if total > 0 else 0
419
- summary = f"""
420
- # πŸ“Š Quiz Results
421
- **Final Score: {score}/{total} ({percentage:.0f}%)**
422
- {'πŸŽ‰ Excellent!' if percentage >= 80 else 'πŸ‘ Good job!' if percentage >= 60 else 'πŸ“š Keep practicing!'}
423
- ---
424
- ## Detailed Feedback:
425
- """
426
- return gr.update(value=summary + "\n".join(results), visible=True), gr.HTML.update(value="<script>scrollToQuizResult()</script>")
427
-
428
-
429
-
430
- # Event handlers for scenario generator
431
- scenario_submit.click(
432
- fn=on_generate_click,
433
- inputs=[scenario_query_input, num_questions_slider],
434
- outputs=[q[0] for q in quiz_questions] + [q[1] for q in quiz_questions] +
435
- [scenario_quiz_block, scenario_result_output, questions_state],
436
- show_progress=True
437
- )
438
- submit_quiz_btn.click(
439
- fn=evaluate_quiz,
440
- inputs=[q[1] for q in quiz_questions] + [questions_state],
441
- outputs=[scenario_result_output]
442
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
443
 
444
 
445
  gr.HTML("""
 
325
  show_safety_output = gr.Markdown(label="Safety Check")
326
 
327
 
 
328
  with gr.Tab("πŸ§ͺ Scenario Generator"):
329
+ gr.Markdown("### Generate an Interactive Medical Scenario")
330
+ # Input controls
331
+ scenario_query_input = gr.Textbox(
332
+ label="Enter a medical topic",
333
+ placeholder="e.g., 'burns', 'fractures', 'CPR'",
334
+ value=""
335
+ )
336
+ num_questions_slider = gr.Slider(
337
+ minimum=1,
338
+ maximum=10,
339
+ value=5,
340
+ step=1,
341
+ label="Number of Questions"
342
+ )
343
+ scenario_submit = gr.Button("πŸš€ Generate Scenario", variant="primary")
344
+
345
+ # Status display
346
+ scenario_status = gr.Markdown("Ready to generate quiz...")
347
+
348
+ # Output containers
349
+ scenario_quiz_block = gr.Column(visible=False)
350
+ scenario_result_output = gr.Markdown(visible=False, elem_classes=["quiz-result-output"])
351
+ questions_state = gr.State()
352
+
353
+ # Pre-allocate quiz components (up to 10 questions)
354
+ quiz_questions = []
355
+ with scenario_quiz_block:
356
+ gr.Markdown("## πŸ§ͺ Interactive Medical Quiz")
357
+ for i in range(10):
358
+ q_md = gr.Markdown(visible=False)
359
+ q_radio = gr.Radio(choices=[], type="index", visible=False)
360
+ quiz_questions.append((q_md, q_radio))
361
+ submit_quiz_btn = gr.Button("βœ… Submit Answers", variant="primary")
362
+
363
+ def on_generate_click(query, num_q):
364
+ try:
365
+ if not query.strip():
366
+ return generate_error_response("Please enter a medical topic")
367
+ if num_q < 1 or num_q > 10:
368
+ return generate_error_response("Number of questions must be between 1 and 10")
369
+ questions = get_mcq_data(query.strip(), num_q)
370
  if isinstance(questions, dict) and "error" in questions:
371
+ error_msg = f"❌ Error: {questions['error']}"
372
+ if "details" in questions:
373
+ error_msg += f" – {questions['details']}"
374
+ return generate_error_response(error_msg)
375
+ if not questions or not isinstance(questions, list):
376
+ return generate_error_response("No valid questions were generated")
377
+ return generate_success_response(questions, query)
378
+ except Exception as e:
379
+ logger.error(f"Error in on_generate_click: {e}")
380
+ return generate_error_response(f"Unexpected error: {str(e)}")
381
+
382
+ def generate_error_response(error_message):
383
+ updates = []
384
+ for _ in range(10):
385
+ updates.append(gr.update(visible=False))
386
+ for _ in range(10):
387
+ updates.append(gr.update(visible=False))
388
+ updates.extend([
389
+ gr.update(visible=False),
390
+ gr.update(value=error_message, visible=True),
391
+ None,
392
+ gr.update(value=error_message)
393
+ ])
394
+ return tuple(updates)
395
+
396
+ def generate_success_response(questions, query):
397
+ updates = []
398
+ for i in range(10):
399
+ if i < len(questions):
400
+ q = questions[i]
401
+ updates.append(gr.update(value=f"**Question {i+1}:** {q['question']}", visible=True))
402
+ else:
403
+ updates.append(gr.update(visible=False))
404
+ for i in range(10):
405
+ if i < len(questions):
406
+ q = questions[i]
407
+ choices = [f"{k}: {v}" for k, v in q["options"].items()]
408
+ updates.append(gr.update(choices=choices, visible=True, value=None, label=f"Select your answer for Question {i+1}:"))
409
+ else:
410
+ updates.append(gr.update(visible=False, choices=[]))
411
+ updates.extend([
412
+ gr.update(visible=True),
413
+ gr.update(value="", visible=False),
414
+ questions,
415
+ gr.update(value=f"βœ… Generated {len(questions)} questions about '{query}'. Answer the questions below and click Submit!")
416
+ ])
417
+ return tuple(updates)
418
+
419
+ def evaluate_quiz(*args):
420
+ try:
421
+ if not args:
422
+ return gr.update(value="❌ No data received for evaluation", visible=True)
423
  questions = args[-1]
424
  selections = args[:-1]
425
  if not questions:
426
+ return gr.update(value="❌ No questions available for evaluation", visible=True)
427
  results = []
428
  score = 0
429
  total = len(questions)
430
  for i, selected_index in enumerate(selections):
431
  if i >= len(questions):
432
  break
433
+ question = questions[i]
434
+ correct_key = question["correct_answer"]
435
+ correct_answer = f"{correct_key}: {question['options'][correct_key]}"
436
+ if selected_index is not None and selected_index < len(question["options"]):
437
+ user_key = list(question["options"].keys())[selected_index]
438
+ user_answer = f"{user_key}: {question['options'][user_key]}"
439
+ is_correct = user_key == correct_key
440
  else:
441
+ user_answer = "No answer selected"
442
+ is_correct = False
443
+ if is_correct:
444
  score += 1
445
+ status_icon = "βœ…" if is_correct else "❌"
446
  results.append(f"""
447
+ ### Question {i + 1}
448
+ **{question['question']}**
449
+
450
+ πŸ”Ή **Your Answer:** {user_answer}
451
+ πŸ”Ή **Correct Answer:** {correct_answer}
452
+ πŸ”Ή **Result:** {status_icon} {'Correct!' if is_correct else 'Incorrect'}
453
+
454
+ πŸ’‘ **Explanation:** {question.get('feedback', 'No explanation provided.')}
455
+
456
+ ---
457
+ """)
458
+ percentage = (score / total) * 100 if total > 0 else 0
459
+ if percentage >= 90:
460
+ grade_emoji, grade_text = "πŸ†", "Outstanding!"
461
+ elif percentage >= 80:
462
+ grade_emoji, grade_text = "πŸŽ‰", "Excellent work!"
463
+ elif percentage >= 70:
464
+ grade_emoji, grade_text = "πŸ‘", "Good job!"
465
+ elif percentage >= 60:
466
+ grade_emoji, grade_text = "πŸ“š", "Keep studying!"
467
+ else:
468
+ grade_emoji, grade_text = "πŸ’ͺ", "More practice needed!"
469
+ summary = f"""
470
+ # πŸ“Š Quiz Results
471
+
472
+ ## {grade_emoji} Final Score: {score}/{total} ({percentage:.0f}%)
473
+
474
+ **{grade_text}**
475
+
476
+ ---
477
+
478
+ ## πŸ“ Detailed Feedback:
479
+
480
+ """
481
+ return gr.update(value=summary + "\n".join(results), visible=True)
482
+ except Exception as e:
483
+ logger.error(f"Error in evaluate_quiz: {e}")
484
+ return gr.update(value=f"❌ Error evaluating quiz: {str(e)}", visible=True)
485
+
486
+ scenario_submit.click(
487
+ fn=on_generate_click,
488
+ inputs=[scenario_query_input, num_questions_slider],
489
+ outputs=[
490
+ quiz_questions[0][0], quiz_questions[1][0], quiz_questions[2][0], quiz_questions[3][0], quiz_questions[4][0],
491
+ quiz_questions[5][0], quiz_questions[6][0], quiz_questions[7][0], quiz_questions[8][0], quiz_questions[9][0],
492
+ quiz_questions[0][1], quiz_questions[1][1], quiz_questions[2][1], quiz_questions[3][1], quiz_questions[4][1],
493
+ quiz_questions[5][1], quiz_questions[6][1], quiz_questions[7][1], quiz_questions[8][1], quiz_questions[9][1],
494
+ scenario_quiz_block, scenario_result_output, questions_state, scenario_status
495
+ ],
496
+ show_progress=True
497
+ )
498
+
499
+ submit_quiz_btn.click(
500
+ fn=evaluate_quiz,
501
+ inputs=[q[1] for q in quiz_questions] + [questions_state],
502
+ outputs=[scenario_result_output]
503
+ )
504
+
505
 
506
 
507
  gr.HTML("""