Spaces:
Sleeping
Sleeping
Update src/app.py
Browse files- src/app.py +100 -45
src/app.py
CHANGED
|
@@ -469,71 +469,126 @@ with tab2:
|
|
| 469 |
|
| 470 |
# === TAB 3: QUIZ MODE ===
|
| 471 |
with tab3:
|
| 472 |
-
st.header("
|
| 473 |
-
|
| 474 |
-
|
| 475 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 476 |
quiz = QuizEngine()
|
| 477 |
qs = st.session_state.quiz_state
|
| 478 |
-
|
| 479 |
-
# METRICS ROW
|
| 480 |
-
m1, m2, m3 = st.columns(3)
|
| 481 |
-
m1.metric("Streak", qs["streak"])
|
| 482 |
|
| 483 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 484 |
if not qs["active"]:
|
| 485 |
-
if st.button("🚀
|
| 486 |
-
|
| 487 |
-
|
| 488 |
-
|
| 489 |
-
|
| 490 |
-
|
| 491 |
-
|
| 492 |
-
|
| 493 |
-
|
| 494 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 495 |
|
| 496 |
-
|
| 497 |
-
|
| 498 |
-
|
| 499 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 500 |
|
| 501 |
-
#
|
| 502 |
-
|
| 503 |
-
|
| 504 |
-
user_input = st.text_input("Your Definition:", value=qs.get("user_answer_temp", ""))
|
| 505 |
-
submit_btn = st.form_submit_button("Submit Answer")
|
| 506 |
|
| 507 |
-
|
| 508 |
-
|
|
|
|
| 509 |
|
| 510 |
-
|
| 511 |
-
with st.spinner("
|
| 512 |
-
|
| 513 |
-
term = qs["question_data"]["term"]
|
| 514 |
-
correct_def = qs["question_data"]["correct_definition"]
|
| 515 |
-
prompt = quiz.construct_grading_prompt(term, correct_def, user_input)
|
| 516 |
|
| 517 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 518 |
msgs = [{"role": "user", "content": prompt}]
|
| 519 |
-
grade,
|
| 520 |
-
msgs,
|
| 521 |
)
|
| 522 |
|
| 523 |
qs["feedback"] = grade
|
| 524 |
|
| 525 |
-
#
|
| 526 |
if "GRADE:** PASS" in grade or "GRADE:** Pass" in grade:
|
| 527 |
qs["streak"] += 1
|
| 528 |
elif "GRADE:** FAIL" in grade:
|
| 529 |
qs["streak"] = 0
|
| 530 |
|
| 531 |
-
|
| 532 |
-
|
| 533 |
-
|
| 534 |
-
|
| 535 |
-
|
|
|
|
|
|
|
|
|
|
| 536 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 537 |
st.rerun()
|
| 538 |
|
| 539 |
# 4. FEEDBACK DISPLAY
|
|
|
|
| 469 |
|
| 470 |
# === TAB 3: QUIZ MODE ===
|
| 471 |
with tab3:
|
| 472 |
+
st.header("⚓ Qualification Board Simulator")
|
| 473 |
+
|
| 474 |
+
# 1. MODE SELECTION
|
| 475 |
+
col_mode, col_streak = st.columns([3, 1])
|
| 476 |
+
with col_mode:
|
| 477 |
+
quiz_mode = st.radio(
|
| 478 |
+
"Select Quiz Mode:",
|
| 479 |
+
["⚡ Acronym Lightning Round", "📖 Document Deep Dive"],
|
| 480 |
+
horizontal=True
|
| 481 |
+
)
|
| 482 |
+
|
| 483 |
+
# Initialize State
|
| 484 |
quiz = QuizEngine()
|
| 485 |
qs = st.session_state.quiz_state
|
|
|
|
|
|
|
|
|
|
|
|
|
| 486 |
|
| 487 |
+
# Display Streak
|
| 488 |
+
with col_streak:
|
| 489 |
+
st.metric("Current Streak", qs["streak"])
|
| 490 |
+
if st.button("Reset"): qs["streak"] = 0
|
| 491 |
+
|
| 492 |
+
st.divider()
|
| 493 |
+
|
| 494 |
+
# 2. START BUTTON (Logic branches based on mode)
|
| 495 |
if not qs["active"]:
|
| 496 |
+
if st.button("🚀 Generate New Question", type="primary"):
|
| 497 |
+
|
| 498 |
+
with st.spinner("Consulting the Board..."):
|
| 499 |
+
# MODE A: ACRONYMS
|
| 500 |
+
if "Acronym" in quiz_mode:
|
| 501 |
+
q_data = quiz.get_random_acronym()
|
| 502 |
+
if q_data:
|
| 503 |
+
qs["active"] = True
|
| 504 |
+
qs["question_data"] = q_data
|
| 505 |
+
qs["feedback"] = None
|
| 506 |
+
qs["generated_question_text"] = q_data["question"]
|
| 507 |
+
st.rerun()
|
| 508 |
+
else:
|
| 509 |
+
st.error("No acronyms found! Run the extractor first.")
|
| 510 |
|
| 511 |
+
# MODE B: DOCUMENTS
|
| 512 |
+
else:
|
| 513 |
+
q_ctx = quiz.get_document_context(st.session_state.username)
|
| 514 |
+
if q_ctx:
|
| 515 |
+
# We have the text, now we need the LLM to write the question
|
| 516 |
+
prompt = quiz.construct_question_generation_prompt(q_ctx["context_text"])
|
| 517 |
+
|
| 518 |
+
# Generate Question using your existing query helper
|
| 519 |
+
msgs = [{"role": "user", "content": prompt}]
|
| 520 |
+
question_text, usage = query_model_universal(
|
| 521 |
+
msgs, 300, model_choice, st.session_state.get("user_openai_key")
|
| 522 |
+
)
|
| 523 |
+
|
| 524 |
+
qs["active"] = True
|
| 525 |
+
qs["question_data"] = q_ctx
|
| 526 |
+
qs["generated_question_text"] = question_text # Store the LLM-generated question
|
| 527 |
+
qs["feedback"] = None
|
| 528 |
+
st.rerun()
|
| 529 |
+
else:
|
| 530 |
+
st.error("No documents found! Upload some .txt or .md files first.")
|
| 531 |
+
|
| 532 |
+
# 3. QUIZ INTERFACE
|
| 533 |
+
if qs["active"]:
|
| 534 |
+
st.markdown(f"### {qs['generated_question_text']}")
|
| 535 |
|
| 536 |
+
# Hints for Doc Mode
|
| 537 |
+
if "document" in qs.get("question_data", {}).get("type", ""):
|
| 538 |
+
st.caption(f"Source: *{qs['question_data']['source_file']}*")
|
|
|
|
|
|
|
| 539 |
|
| 540 |
+
with st.form(key="quiz_response"):
|
| 541 |
+
user_ans = st.text_area("Your Answer:")
|
| 542 |
+
sub = st.form_submit_button("Submit Answer")
|
| 543 |
|
| 544 |
+
if sub and user_ans:
|
| 545 |
+
with st.spinner("Grading..."):
|
| 546 |
+
data = qs["question_data"]
|
|
|
|
|
|
|
|
|
|
| 547 |
|
| 548 |
+
# BRANCH GRADING LOGIC
|
| 549 |
+
if data["type"] == "acronym":
|
| 550 |
+
prompt = quiz.construct_acronym_grading_prompt(
|
| 551 |
+
data["term"], data["correct_definition"], user_ans
|
| 552 |
+
)
|
| 553 |
+
else:
|
| 554 |
+
prompt = quiz.construct_grading_prompt(
|
| 555 |
+
qs["generated_question_text"], user_ans, data["context_text"]
|
| 556 |
+
)
|
| 557 |
+
|
| 558 |
+
# Get Grade
|
| 559 |
msgs = [{"role": "user", "content": prompt}]
|
| 560 |
+
grade, _ = query_model_universal(
|
| 561 |
+
msgs, 500, model_choice, st.session_state.get("user_openai_key")
|
| 562 |
)
|
| 563 |
|
| 564 |
qs["feedback"] = grade
|
| 565 |
|
| 566 |
+
# Streak Logic
|
| 567 |
if "GRADE:** PASS" in grade or "GRADE:** Pass" in grade:
|
| 568 |
qs["streak"] += 1
|
| 569 |
elif "GRADE:** FAIL" in grade:
|
| 570 |
qs["streak"] = 0
|
| 571 |
|
| 572 |
+
st.rerun()
|
| 573 |
+
|
| 574 |
+
# 4. FEEDBACK AREA
|
| 575 |
+
if qs["feedback"]:
|
| 576 |
+
if "PASS" in qs["feedback"]:
|
| 577 |
+
st.success("✅ CORRECT")
|
| 578 |
+
else:
|
| 579 |
+
st.warning("⚠️ NEEDS IMPROVEMENT")
|
| 580 |
|
| 581 |
+
st.markdown(qs["feedback"])
|
| 582 |
+
|
| 583 |
+
# For documents, show the source text so you can learn
|
| 584 |
+
if qs["question_data"]["type"] == "document":
|
| 585 |
+
with st.expander("Show Source Text (Answer Key)"):
|
| 586 |
+
st.info(qs["question_data"]["context_text"])
|
| 587 |
+
|
| 588 |
+
if st.button("Next Question ➡️"):
|
| 589 |
+
qs["active"] = False
|
| 590 |
+
qs["question_data"] = None
|
| 591 |
+
qs["feedback"] = None
|
| 592 |
st.rerun()
|
| 593 |
|
| 594 |
# 4. FEEDBACK DISPLAY
|