Spaces:
Running
Running
| import streamlit as st | |
| import sys, os | |
| # β FIX: Add project root first | |
| sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) | |
| from config import APP_TITLE, APP_ICON, MAX_QUESTIONS | |
| # β FIRST Streamlit call | |
| st.set_page_config( | |
| page_title=APP_TITLE, | |
| page_icon=APP_ICON, | |
| layout="centered", | |
| ) | |
| # Add project root to path | |
| sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) | |
| from src.evaluator import score_quiz | |
| from app.components import ( | |
| render_question_card, | |
| render_result_card, | |
| render_score_summary | |
| ) | |
| # βββββββββββββββββββββββββββββββββββββββββββββ | |
| # CACHE MODEL (important for performance) | |
| # βββββββββββββββββββββββββββββββββββββββββββββ | |
| def load_pipeline(): | |
| from src.mcq_builder import build_quiz | |
| return build_quiz | |
| build_quiz = load_pipeline() | |
| # βββββββββββββββββββββββββββββββββββββββββββββ | |
| # SESSION STATE | |
| # βββββββββββββββββββββββββββββββββββββββββββββ | |
| def init_state(): | |
| defaults = { | |
| "screen": "input", | |
| "mcqs": [], | |
| "current_q": 0, | |
| "user_answers": [], | |
| "quiz_result": None, | |
| } | |
| for k, v in defaults.items(): | |
| if k not in st.session_state: | |
| st.session_state[k] = v | |
| init_state() | |
| # βββββββββββββββββββββββββββββββββββββββββββββ | |
| # RESET | |
| # βββββββββββββββββββββββββββββββββββββββββββββ | |
| def reset(): | |
| st.session_state.screen = "input" | |
| st.session_state.mcqs = [] | |
| st.session_state.current_q = 0 | |
| st.session_state.user_answers = [] | |
| st.session_state.quiz_result = None | |
| # βββββββββββββββββββββββββββββββββββββββββββββ | |
| # SCREEN 1: INPUT | |
| # βββββββββββββββββββββββββββββββββββββββββββββ | |
| def screen_input(): | |
| st.title(f"{APP_ICON} {APP_TITLE}") | |
| st.write("Paste text to generate MCQs") | |
| passage = st.text_area( | |
| "Your passage", | |
| height=250, | |
| placeholder="Paste content here..." | |
| ) | |
| num_questions = st.slider( | |
| "Number of questions", | |
| 3, | |
| MAX_QUESTIONS, | |
| 5 | |
| ) | |
| if st.button("Generate Quiz", type="primary"): | |
| if not passage or len(passage.split()) < 30: | |
| st.warning("Enter at least 30 words") | |
| return | |
| with st.spinner("Generating questions..."): | |
| try: | |
| mcqs = build_quiz(passage, num_questions=num_questions) | |
| except Exception as e: | |
| st.error(f"Error: {e}") | |
| return | |
| if not mcqs: | |
| st.error("Failed to generate questions") | |
| return | |
| st.session_state.mcqs = mcqs | |
| st.session_state.user_answers = [-1] * len(mcqs) | |
| st.session_state.current_q = 0 | |
| st.session_state.screen = "quiz" | |
| st.rerun() | |
| # βββββββββββββββββββββββββββββββββββββββββββββ | |
| # SCREEN 2: QUIZ | |
| # βββββββββββββββββββββββββββββββββββββββββββββ | |
| def screen_quiz(): | |
| mcqs = st.session_state.mcqs | |
| current = st.session_state.current_q | |
| total = len(mcqs) | |
| mcq = mcqs[current] | |
| st.progress(current / total, text=f"Q {current+1}/{total}") | |
| selected_label = render_question_card(mcq, current) | |
| col1, col2, col3 = st.columns([1, 2, 1]) | |
| # Previous | |
| with col1: | |
| if current > 0: | |
| if st.button("β Prev"): | |
| st.session_state.current_q -= 1 | |
| st.rerun() | |
| # Next / Submit | |
| with col3: | |
| if selected_label: | |
| idx = ord(selected_label) - ord("A") | |
| st.session_state.user_answers[current] = idx | |
| if current < total - 1: | |
| if st.button("Next β", type="primary"): | |
| if selected_label is None: | |
| st.warning("Select an answer") | |
| else: | |
| st.session_state.current_q += 1 | |
| st.rerun() | |
| else: | |
| if st.button("Submit", type="primary"): | |
| result = score_quiz( | |
| st.session_state.mcqs, | |
| st.session_state.user_answers | |
| ) | |
| st.session_state.quiz_result = result | |
| st.session_state.screen = "results" | |
| st.rerun() | |
| # Quit | |
| with col2: | |
| if st.button("Quit"): | |
| reset() | |
| st.rerun() | |
| # βββββββββββββββββββββββββββββββββββββββββββββ | |
| # SCREEN 3: RESULTS | |
| # βββββββββββββββββββββββββββββββββββββββββββββ | |
| def screen_results(): | |
| result = st.session_state.quiz_result | |
| st.title("Quiz Complete") | |
| render_score_summary(result) | |
| for i, r in enumerate(result["results"]): | |
| render_result_card(r, i + 1) | |
| col1, col2 = st.columns(2) | |
| with col1: | |
| if st.button("New Quiz"): | |
| reset() | |
| st.rerun() | |
| with col2: | |
| if st.button("Retry"): | |
| st.session_state.user_answers = [-1] * len(st.session_state.mcqs) | |
| st.session_state.current_q = 0 | |
| st.session_state.screen = "quiz" | |
| st.rerun() | |
| # βββββββββββββββββββββββββββββββββββββββββββββ | |
| # ROUTER | |
| # βββββββββββββββββββββββββββββββββββββββββββββ | |
| if st.session_state.screen == "input": | |
| screen_input() | |
| elif st.session_state.screen == "quiz": | |
| screen_quiz() | |
| elif st.session_state.screen == "results": | |
| screen_results() |