File size: 8,549 Bytes
7ba3b4e 795b9ba 764cfc6 bad6a07 e0f928e d924141 764cfc6 795b9ba 2a56f14 660fa89 e0f928e 7b17e7d e9df8e8 795b9ba 169cec0 054ca33 9d5f38a 32f2e18 795b9ba 169cec0 795b9ba bad6a07 169cec0 9d5f38a 169cec0 e9df8e8 169cec0 81e422f 169cec0 f1969d5 81e422f 169cec0 9d5f38a 169cec0 9d5f38a 169cec0 9d5f38a 169cec0 9d5f38a 169cec0 81e422f 169cec0 32f2e18 8e6cd67 32f2e18 e9df8e8 795b9ba e9df8e8 81e422f f1969d5 81e422f 2a4a631 f1969d5 81e422f ee53acf e9df8e8 169cec0 e9df8e8 7b6a611 e9df8e8 e0f928e e9df8e8 81e422f e9df8e8 054ca33 81e422f 660fa89 81e422f 199933f 660fa89 58d0b6d d015779 9dd5a05 58d0b6d 199933f 81e422f 199933f d015779 660fa89 81e422f d015779 81e422f d015779 81e422f 58d0b6d 660fa89 d015779 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 |
import streamlit as st
import importlib
import logging
from fpdf import FPDF
import uuid
# 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",
}
# Module descriptions
module_descriptions = {
"Bases": "This module covers the presentation of numbers in various bases, including binary, octal, decimal, and hexadecimal.",
"Validity": "This module helps determine the validity of numbers in different bases.",
"Conversion": "This module covers conversion techniques between different bases, including with and without fractions.",
"Grouping": "This module focuses on grouping techniques for conversion between bases such as binary and hexadecimal.",
"Addition": "This module covers addition operations in bases like binary, octal, and hexadecimal.",
"2's Complement": "This module explains the 2's complement method for representing negative numbers.",
"Negative Numbers": "This module covers negative binary numbers and their representation.",
"Subtraction": "This module focuses on subtraction operations in binary using the 2's complement method.",
}
# Initialize unique session state
if 'session_id' not in st.session_state:
st.session_state.session_id = str(uuid.uuid4())
# Initialize session state variables
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'] if entry['selected'] is not None else "Not Answered", # Handle case where selected is None
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) # Green for correct
pdf.multi_cell(0, 10, f"{option}")
elif option == selected:
pdf.set_text_color(255, 0, 0) # Red for incorrect
pdf.multi_cell(0, 10, f"{option}")
else:
pdf.set_text_color(0, 0, 0) # Default color for others
pdf.multi_cell(0, 10, f" {option}")
pdf.set_text_color(0, 0, 0) # Reset color
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) # Add space after each module
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()
# Ensure 'answered' is initialized to False and add the 'module' and 'selected' keys
question_data['answered'] = False
question_data['module'] = module_name # Add the module name to the question data
question_data['selected'] = None # Initialize 'selected' to None
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:
# Generate a new question if at the end of the list
new_question = generate_new_question(st.session_state.current_module)
st.session_state.questions.append(new_question)
st.session_state.current_index += 1
# Streamlit interface
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)]
# Load the current module's question
current_question = st.session_state.questions[st.session_state.current_index]
# Display module title and description
st.title(module_name)
st.write(module_descriptions.get(module_name, "No description available for this module."))
st.write(current_question["question"])
# Render options without pre-selection
if not current_question.get('answered', False):
selected_answer = st.radio(
"Choose an answer:",
options=current_question['options'],
key=f"question_{st.session_state.current_index}",
index=None # No pre-selection
)
if st.button("Submit"):
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
# Trigger a UI update
st.set_query_params(dummy=not st.session_state.get('dummy', False))
# Show correct/incorrect feedback after submission
if current_question.get('answered', False):
for option in current_question['options']:
if option == current_question['correct_answer']:
st.write(f"**Correct Answer:** {option}")
elif option == current_question['selected']:
st.write(f"**Your Answer:** {option} (Incorrect)")
# Show explanation and step-by-step solution
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)
# Navigation buttons (placed after question and options)
col1, col2 = st.columns([1, 1])
with col1:
if st.button("⬅️ Prev", disabled=st.session_state.current_index == 0):
navigate_question("prev")
with col2:
if st.button("➡️ Next"):
navigate_question("next")
# PDF Download Button (at the bottom)
if len(st.session_state.questions) > 0:
pdf = generate_pdf_report()
st.session_state.pdf_data = pdf # Reset PDF cache
st.download_button(
label="Download PDF Report 📄",
data=st.session_state.pdf_data,
file_name="quiz_report.pdf",
mime="application/pdf"
)
|