NavyDevilDoc commited on
Commit
7c8cee7
·
verified ·
1 Parent(s): 0b7ddd3

Update src/app.py

Browse files
Files changed (1) hide show
  1. src/app.py +31 -41
src/app.py CHANGED
@@ -556,7 +556,7 @@ with tab2:
556
  with tab3:
557
  st.header("⚓ Qualification Board Simulator")
558
 
559
- # 1. MODE SELECTION
560
  col_mode, col_streak = st.columns([3, 1])
561
  with col_mode:
562
  quiz_mode = st.radio(
@@ -564,14 +564,27 @@ with tab3:
564
  ["⚡ Acronym Lightning Round", "📖 Document Deep Dive"],
565
  horizontal=True
566
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
567
 
568
- # Initialize State
569
  quiz = QuizEngine()
570
  qs = st.session_state.quiz_state
571
-
572
- # NEW: Trigger State for "Next Question" chaining
573
- if "quiz_trigger" not in st.session_state:
574
- st.session_state.quiz_trigger = False
575
 
576
  # Display Streak
577
  with col_streak:
@@ -580,7 +593,7 @@ with tab3:
580
 
581
  st.divider()
582
 
583
- # --- GENERATION FUNCTION (Reused for Button AND Auto-Trigger) ---
584
  def generate_question():
585
  with st.spinner("Consulting the Board..."):
586
  # MODE A: ACRONYMS
@@ -610,6 +623,7 @@ with tab3:
610
  300, model_choice, st.session_state.get("user_openai_key")
611
  )
612
 
 
613
  if "SKIP" not in question_text and len(question_text) > 10:
614
  valid_question_found = True
615
  qs["active"] = True
@@ -620,12 +634,11 @@ with tab3:
620
  if not valid_question_found:
621
  st.warning("Tried to find a good engineering question but the available text was too administrative. Try uploading denser technical notes!")
622
 
623
- # 2. AUTO-TRIGGER CHECK
624
- # If the user clicked "Next Question", this runs immediately on rerun
625
  if st.session_state.quiz_trigger:
626
- st.session_state.quiz_trigger = False # Reset flag
627
  generate_question()
628
- st.rerun() # Rerun to display the new question
629
 
630
  # 3. MANUAL START BUTTON
631
  if not qs["active"]:
@@ -637,9 +650,11 @@ with tab3:
637
  if qs["active"]:
638
  st.markdown(f"### {qs['generated_question_text']}")
639
 
 
640
  if "document" in qs.get("question_data", {}).get("type", ""):
641
  st.caption(f"Source: *{qs['question_data']['source_file']}*")
642
 
 
643
  with st.form(key="quiz_response"):
644
  user_ans = st.text_area("Your Answer:")
645
  sub = st.form_submit_button("Submit Answer")
@@ -648,6 +663,7 @@ with tab3:
648
  with st.spinner("Grading..."):
649
  data = qs["question_data"]
650
 
 
651
  if data["type"] == "acronym":
652
  prompt = quiz.construct_acronym_grading_prompt(
653
  data["term"], data["correct_definition"], user_ans
@@ -664,6 +680,7 @@ with tab3:
664
 
665
  qs["feedback"] = grade
666
 
 
667
  if "GRADE:** PASS" in grade or "GRADE:** Pass" in grade:
668
  qs["streak"] += 1
669
  elif "GRADE:** FAIL" in grade:
@@ -671,7 +688,7 @@ with tab3:
671
 
672
  st.rerun()
673
 
674
- # 5. FEEDBACK AREA
675
  if qs["feedback"]:
676
  st.divider()
677
  if "PASS" in qs["feedback"]:
@@ -684,7 +701,7 @@ with tab3:
684
 
685
  st.markdown(qs["feedback"])
686
 
687
- # Display Correct Answer
688
  data = qs["question_data"]
689
  if data["type"] == "acronym":
690
  st.info(f"**Official Definition:** {data['correct_definition']}")
@@ -692,36 +709,9 @@ with tab3:
692
  with st.expander("Show Source Text (Answer Key)"):
693
  st.info(data["context_text"])
694
 
695
- # FIXED: "Next Question" now sets the trigger flag instead of just resetting state
696
  if st.button("Next Question ➡️"):
697
  st.session_state.quiz_trigger = True
698
- qs["active"] = False
699
- qs["question_data"] = None
700
- qs["feedback"] = None
701
- st.rerun()
702
-
703
- # 4. FEEDBACK AREA (MERGED & FIXED)
704
- if qs["feedback"]:
705
- st.divider()
706
- if "PASS" in qs["feedback"]:
707
- st.success("✅ CORRECT")
708
- else:
709
- if "FAIL" in qs["feedback"]:
710
- st.error("❌ INCORRECT")
711
- else:
712
- st.warning("⚠️ PARTIAL / COMMENTARY")
713
-
714
- st.markdown(qs["feedback"])
715
-
716
- # Display Correct Answer based on type
717
- data = qs["question_data"]
718
- if data["type"] == "acronym":
719
- st.info(f"**Official Definition:** {data['correct_definition']}")
720
- elif data["type"] == "document":
721
- with st.expander("Show Source Text (Answer Key)"):
722
- st.info(data["context_text"])
723
-
724
- if st.button("Next Question ➡️"):
725
  qs["active"] = False
726
  qs["question_data"] = None
727
  qs["feedback"] = None
 
556
  with tab3:
557
  st.header("⚓ Qualification Board Simulator")
558
 
559
+ # 1. MODE SELECTION & RESET LOGIC
560
  col_mode, col_streak = st.columns([3, 1])
561
  with col_mode:
562
  quiz_mode = st.radio(
 
564
  ["⚡ Acronym Lightning Round", "📖 Document Deep Dive"],
565
  horizontal=True
566
  )
567
+
568
+ # Initialize Session State Variables if missing
569
+ if "last_quiz_mode" not in st.session_state:
570
+ st.session_state.last_quiz_mode = quiz_mode
571
+
572
+ if "quiz_trigger" not in st.session_state:
573
+ st.session_state.quiz_trigger = False
574
+
575
+ # GHOST IMAGE FIX: Detect Mode Switch
576
+ # If the user toggled the radio button since the last run, wipe the state.
577
+ if st.session_state.last_quiz_mode != quiz_mode:
578
+ st.session_state.quiz_state["active"] = False
579
+ st.session_state.quiz_state["question_data"] = None
580
+ st.session_state.quiz_state["feedback"] = None
581
+ st.session_state.quiz_state["generated_question_text"] = ""
582
+ st.session_state.last_quiz_mode = quiz_mode
583
+ st.rerun() # Force a clean refresh immediately
584
 
585
+ # Initialize Engine & Shortcut to State
586
  quiz = QuizEngine()
587
  qs = st.session_state.quiz_state
 
 
 
 
588
 
589
  # Display Streak
590
  with col_streak:
 
593
 
594
  st.divider()
595
 
596
+ # --- GENERATION FUNCTION ---
597
  def generate_question():
598
  with st.spinner("Consulting the Board..."):
599
  # MODE A: ACRONYMS
 
623
  300, model_choice, st.session_state.get("user_openai_key")
624
  )
625
 
626
+ # Filter out skips or empty responses
627
  if "SKIP" not in question_text and len(question_text) > 10:
628
  valid_question_found = True
629
  qs["active"] = True
 
634
  if not valid_question_found:
635
  st.warning("Tried to find a good engineering question but the available text was too administrative. Try uploading denser technical notes!")
636
 
637
+ # 2. AUTO-TRIGGER (Chained Question Logic)
 
638
  if st.session_state.quiz_trigger:
639
+ st.session_state.quiz_trigger = False
640
  generate_question()
641
+ st.rerun()
642
 
643
  # 3. MANUAL START BUTTON
644
  if not qs["active"]:
 
650
  if qs["active"]:
651
  st.markdown(f"### {qs['generated_question_text']}")
652
 
653
+ # Context Hint
654
  if "document" in qs.get("question_data", {}).get("type", ""):
655
  st.caption(f"Source: *{qs['question_data']['source_file']}*")
656
 
657
+ # Answer Form
658
  with st.form(key="quiz_response"):
659
  user_ans = st.text_area("Your Answer:")
660
  sub = st.form_submit_button("Submit Answer")
 
663
  with st.spinner("Grading..."):
664
  data = qs["question_data"]
665
 
666
+ # Grading Logic Branch
667
  if data["type"] == "acronym":
668
  prompt = quiz.construct_acronym_grading_prompt(
669
  data["term"], data["correct_definition"], user_ans
 
680
 
681
  qs["feedback"] = grade
682
 
683
+ # Streak Logic
684
  if "GRADE:** PASS" in grade or "GRADE:** Pass" in grade:
685
  qs["streak"] += 1
686
  elif "GRADE:** FAIL" in grade:
 
688
 
689
  st.rerun()
690
 
691
+ # 5. FEEDBACK AREA (Deduplicated)
692
  if qs["feedback"]:
693
  st.divider()
694
  if "PASS" in qs["feedback"]:
 
701
 
702
  st.markdown(qs["feedback"])
703
 
704
+ # Display Answer Key
705
  data = qs["question_data"]
706
  if data["type"] == "acronym":
707
  st.info(f"**Official Definition:** {data['correct_definition']}")
 
709
  with st.expander("Show Source Text (Answer Key)"):
710
  st.info(data["context_text"])
711
 
712
+ # Next Question Button
713
  if st.button("Next Question ➡️"):
714
  st.session_state.quiz_trigger = True
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
715
  qs["active"] = False
716
  qs["question_data"] = None
717
  qs["feedback"] = None