Spaces:
Sleeping
Sleeping
Update app.py
Browse files
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 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
-
|
339 |
-
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
-
|
344 |
-
|
345 |
-
|
346 |
-
|
347 |
-
|
348 |
-
|
349 |
-
|
350 |
-
|
351 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
352 |
if isinstance(questions, dict) and "error" in questions:
|
353 |
-
|
354 |
-
|
355 |
-
|
356 |
-
|
357 |
-
|
358 |
-
|
359 |
-
|
360 |
-
|
361 |
-
|
362 |
-
|
363 |
-
|
364 |
-
|
365 |
-
|
366 |
-
|
367 |
-
|
368 |
-
|
369 |
-
|
370 |
-
|
371 |
-
|
372 |
-
|
373 |
-
|
374 |
-
|
375 |
-
|
376 |
-
|
377 |
-
|
378 |
-
|
379 |
-
|
380 |
-
|
381 |
-
|
382 |
-
questions
|
383 |
-
|
384 |
-
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
389 |
questions = args[-1]
|
390 |
selections = args[:-1]
|
391 |
if not questions:
|
392 |
-
return gr.update(value="β No questions
|
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 |
-
|
400 |
-
correct_key =
|
401 |
-
|
402 |
-
if selected_index is not None:
|
403 |
-
user_key = list(
|
404 |
-
|
405 |
-
|
406 |
else:
|
407 |
-
|
408 |
-
|
409 |
-
if
|
410 |
score += 1
|
|
|
411 |
results.append(f"""
|
412 |
-
|
413 |
-
|
414 |
-
|
415 |
-
|
416 |
-
|
417 |
-
|
418 |
-
|
419 |
-
|
420 |
-
|
421 |
-
|
422 |
-
|
423 |
-
|
424 |
-
|
425 |
-
"""
|
426 |
-
|
427 |
-
|
428 |
-
|
429 |
-
|
430 |
-
|
431 |
-
|
432 |
-
|
433 |
-
|
434 |
-
|
435 |
-
|
436 |
-
|
437 |
-
|
438 |
-
|
439 |
-
|
440 |
-
|
441 |
-
|
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("""
|