|
import streamlit as st |
|
import importlib |
|
import logging |
|
from fpdf import FPDF |
|
import uuid |
|
import json |
|
|
|
|
|
logging.basicConfig(level=logging.INFO) |
|
|
|
|
|
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", |
|
} |
|
|
|
|
|
if 'session_id' not in st.session_state: |
|
st.session_state.session_id = str(uuid.uuid4()) |
|
|
|
|
|
if 'questions' not in st.session_state: |
|
st.session_state.questions = [] |
|
if 'current_index' not in st.session_state: |
|
st.session_state.current_index = 0 |
|
if 'current_module' not in st.session_state: |
|
st.session_state.current_module = None |
|
if 'correct_count' not in st.session_state: |
|
st.session_state.correct_count = 0 |
|
if 'module_correct_count' not in st.session_state: |
|
st.session_state.module_correct_count = {name: 0 for name in module_names} |
|
if 'module_question_count' not in st.session_state: |
|
st.session_state.module_question_count = {name: 0 for name in module_names} |
|
if 'selected_answer' not in st.session_state: |
|
st.session_state.selected_answer = None |
|
if 'pdf_data' not in st.session_state: |
|
st.session_state.pdf_data = None |
|
|
|
def reset_pdf_cache(): |
|
st.session_state.pdf_data = 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 module in module_names.keys(): |
|
pdf.set_text_color(0, 0, 0) |
|
pdf.cell(200, 10, txt=f"Module: {module}", ln=True, align="L") |
|
pdf.ln(5) |
|
correct_count = st.session_state.module_correct_count[module] |
|
total_count = st.session_state.module_question_count[module] |
|
pdf.cell(200, 10, txt=f"Correct Answers: {correct_count}/{total_count}", ln=True, align="L") |
|
pdf.ln(5) |
|
|
|
for entry in st.session_state.questions: |
|
if entry['module'] == module: |
|
question, options, selected, correct, explanation, step_by_step_solution = ( |
|
entry['question'], |
|
entry['options'], |
|
entry['selected'], |
|
entry['correct_answer'], |
|
entry['explanation'], |
|
entry['step_by_step_solution'] |
|
) |
|
pdf.multi_cell(0, 10, f"Q: {question}") |
|
for option in options: |
|
if option == correct: |
|
pdf.set_text_color(0, 128, 0) |
|
pdf.multi_cell(0, 10, f"{option}") |
|
elif option == selected: |
|
pdf.set_text_color(255, 0, 0) |
|
pdf.multi_cell(0, 10, f"{option}") |
|
else: |
|
pdf.set_text_color(0, 0, 0) |
|
pdf.multi_cell(0, 10, f" {option}") |
|
pdf.set_text_color(0, 0, 0) |
|
pdf.multi_cell(0, 10, f"Explanation: {explanation}") |
|
pdf.ln(5) |
|
pdf.multi_cell(0, 10, "Step-by-Step Solution:") |
|
for step in step_by_step_solution: |
|
pdf.multi_cell(0, 10, step) |
|
pdf.ln(10) |
|
|
|
pdf.ln(10) |
|
|
|
return pdf.output(dest='S').encode('latin1', 'replace') |
|
|
|
def load_module(module_name): |
|
module_file = module_names[module_name] |
|
module = importlib.import_module(f'modules.{module_file}') |
|
return module |
|
|
|
def generate_new_question(module_name): |
|
module = load_module(module_name) |
|
question_data = module.generate_question() |
|
|
|
question_data['answered'] = False |
|
return question_data |
|
|
|
def navigate_question(direction): |
|
if direction == "prev" and st.session_state.current_index > 0: |
|
st.session_state.current_index -= 1 |
|
elif direction == "next": |
|
if st.session_state.current_index < len(st.session_state.questions) - 1: |
|
st.session_state.current_index += 1 |
|
else: |
|
|
|
new_question = generate_new_question(st.session_state.current_module) |
|
st.session_state.questions.append(new_question) |
|
st.session_state.current_index += 1 |
|
|
|
|
|
st.sidebar.title("Quiz Modules") |
|
module_name = st.sidebar.radio("Choose a module:", list(module_names.keys()), index=0) |
|
|
|
if module_name != st.session_state.current_module: |
|
st.session_state.current_module = module_name |
|
st.session_state.current_index = 0 |
|
st.session_state.questions = [generate_new_question(module_name)] |
|
|
|
|
|
current_question = st.session_state.questions[st.session_state.current_index] |
|
|
|
|
|
st.title(module_name) |
|
st.write(current_question["question"]) |
|
|
|
|
|
def get_option_style(option): |
|
if current_question.get('answered', False): |
|
if option == current_question['correct_answer']: |
|
return "background-color:#d4edda;padding:10px;border-radius:5px;" |
|
elif option == current_question['selected']: |
|
return "background-color:#f8d7da;padding:10px;border-radius:5px;" |
|
return "background-color:#f0f0f0;padding:10px;border-radius:5px;" |
|
|
|
selected_answer = st.radio( |
|
"Choose an answer:", |
|
current_question['options'], |
|
index=current_question['options'].index(current_question.get('selected', '')) if current_question.get('selected') else None, |
|
key=st.session_state.current_index |
|
) |
|
|
|
if st.button("Submit"): |
|
if not current_question.get('answered', False): |
|
current_question['selected'] = selected_answer |
|
current_question['answered'] = True |
|
st.session_state.module_question_count[module_name] += 1 |
|
|
|
if selected_answer == current_question['correct_answer']: |
|
st.session_state.correct_count += 1 |
|
st.session_state.module_correct_count[module_name] += 1 |
|
|
|
|
|
for option in current_question['options']: |
|
st.markdown(f"<div style='{get_option_style(option)}'>{option}</div>", unsafe_allow_html=True) |
|
|
|
|
|
if current_question.get('answered', False): |
|
st.write(f"**Explanation:** {current_question['explanation']}") |
|
st.write("**Step-by-Step Solution:**") |
|
for step in current_question['step_by_step_solution']: |
|
st.write(step) |
|
|