import streamlit as st import importlib import logging from fpdf import FPDF # Configure logging logging.basicConfig(level=logging.INFO) # List of available modules with shorter names and icons module_names = { "Bases": "presentation_bases", "Validity": "valid_invalid_numbers", "Conversion": "conversion_bases", "Grouping": "grouping_techniques", "Addition": "addition_bases", "2's Complement": "twos_complement", "Negative Numbers": "negative_binary", "Subtraction": "subtraction_bases", } # Initialize session state variables if 'correct_count' not in st.session_state: st.session_state.correct_count = 0 if 'question_count' not in st.session_state: st.session_state.question_count = 0 if 'current_module' not in st.session_state: st.session_state.current_module = None if 'question_queue' not in st.session_state: st.session_state.question_queue = [] if 'submitted' not in st.session_state: st.session_state.submitted = False if 'current_question' not in st.session_state: st.session_state.current_question = None if 'options' not in st.session_state: st.session_state.options = [] if 'correct_answer' not in st.session_state: st.session_state.correct_answer = None if 'explanation' not in st.session_state: st.session_state.explanation = None if 'selected_answer' not in st.session_state: st.session_state.selected_answer = None def generate_pdf_report(): pdf = FPDF() pdf.add_page() pdf.set_font("Arial", size=12) pdf.cell(200, 10, txt="Quiz Report", ln=True, align="C") pdf.ln(10) for idx, entry in enumerate(st.session_state.question_queue): question, options, selected, correct, explanation = entry pdf.multi_cell(0, 10, f"Q{idx+1}: {question}") for option in options: if option == correct: pdf.multi_cell(0, 10, f"Correct: {option}") elif option == selected: pdf.multi_cell(0, 10, f"Your Choice: {option}") else: pdf.multi_cell(0, 10, f" {option}") pdf.multi_cell(0, 10, f"Explanation: {explanation}") pdf.ln(10) return pdf.output(dest='S').encode('latin1', 'replace') # Logging for debugging logging.info(f"Current Module: {st.session_state.current_module}") logging.info(f"Question Count: {st.session_state.question_count}") logging.info(f"Correct Count: {st.session_state.correct_count}") logging.info(f"Submitted: {st.session_state.submitted}") logging.info(f"Current Question: {st.session_state.current_question}") logging.info(f"Options: {st.session_state.options}") logging.info(f"Selected Answer: {st.session_state.selected_answer}") logging.info(f"Correct Answer: {st.session_state.correct_answer}") logging.info(f"Explanation: {st.session_state.explanation}") # Streamlit interface st.sidebar.title("Quiz Modules") module_name = st.sidebar.radio("Choose a module:", list(module_names.keys()), index=0) if module_name: if st.session_state.current_module != module_name: st.session_state.current_module = module_name st.session_state.question_count = 0 st.session_state.correct_count = 0 st.session_state.question_queue = [] st.session_state.current_question = None st.session_state.submitted = False logging.info("Module changed. Resetting session state.") module_file = module_names[module_name] try: module = importlib.import_module(f'modules.{module_file}') generate_question = module.generate_question title = getattr(module, 'title', f"{module_name} Module") description = getattr(module, 'description', "Description is not available") # Show module title and description st.title(title) st.write(description) # Handle question generation and submission if st.session_state.current_question is None or st.session_state.submitted: st.session_state.current_question, st.session_state.options, st.session_state.correct_answer, st.session_state.explanation = generate_question() st.session_state.submitted = False st.session_state.selected_answer = None logging.info("Generated new question.") if st.session_state.question_count > 0: correct_percentage = (st.session_state.correct_count / st.session_state.question_count) * 100 st.write(f"**Correct Answers:** {st.session_state.correct_count}/{st.session_state.question_count} ({correct_percentage:.2f}%)") st.write(f"**Question {st.session_state.question_count + 1}:** {st.session_state.current_question}") st.session_state.selected_answer = st.radio("Choose an answer:", st.session_state.options, key=st.session_state.question_count) if st.button("Submit"): st.session_state.submitted = True st.session_state.question_count += 1 st.session_state.question_queue.append(( st.session_state.current_question, st.session_state.options, st.session_state.selected_answer, st.session_state.correct_answer, st.session_state.explanation )) if st.session_state.selected_answer == st.session_state.correct_answer: st.session_state.correct_count += 1 st.success("Correct!") else: st.error("Incorrect.") logging.info("Answer submitted.") logging.info(f"Selected Answer: {st.session_state.selected_answer}") logging.info(f"Correct Answer: {st.session_state.correct_answer}") # Explanation with proper width st.markdown( f"""
Explanation: {st.session_state.explanation}
""", unsafe_allow_html=True ) # Display the "Next", "Prev", and "Download PDF Report" buttons above the question col1, col2, col3 = st.columns([1, 1, 2]) with col1: if st.session_state.submitted: if st.button("➡️ Next"): st.session_state.current_question = None logging.info("Navigated to next question.") with col2: if st.session_state.question_count > 1: if st.button("⬅️ Prev"): st.session_state.question_count -= 1 st.session_state.submitted = False question_data = st.session_state.question_queue[st.session_state.question_count - 1] st.session_state.current_question = question_data[0] st.session_state.options = question_data[1] st.session_state.selected_answer = question_data[2] st.session_state.correct_answer = question_data[3] st.session_state.explanation = question_data[4] logging.info("Navigated to previous question.") with col3: if st.session_state.question_count > 0: pdf = generate_pdf_report() st.download_button( label="Download PDF Report 📄", data=pdf, file_name="quiz_report.pdf", mime="application/pdf" ) logging.info("PDF report generated.") except ModuleNotFoundError as e: st.error(f"The module '{module_name}' was not found. Please select another module.") logging.error(f"Error: {e}") except Exception as e: st.error(f"An unexpected error occurred: {str(e)}") logging.error(f"Error: {str(e)}")