|
import streamlit as st |
|
import json |
|
import random |
|
import time |
|
from pathlib import Path |
|
|
|
|
|
st.set_page_config( |
|
page_title="Prepit: Interactive Quiz App", |
|
page_icon="π" |
|
) |
|
|
|
|
|
def load_css(): |
|
st.markdown(""" |
|
<style> |
|
.stButton button { |
|
width: 100%; |
|
border-radius: 5px; |
|
height: 3em; |
|
background-color: #4CAF50; |
|
color: white; |
|
} |
|
.correct-answer { |
|
color: green; |
|
font-weight: bold; |
|
} |
|
.wrong-answer { |
|
color: red; |
|
font-weight: bold; |
|
} |
|
.question-card { |
|
background-color: #f5f5f5; |
|
padding: 20px; |
|
border-radius: 10px; |
|
margin: 10px 0; |
|
} |
|
</style> |
|
""", unsafe_allow_html=True) |
|
|
|
|
|
def load_questions(): |
|
questions_data = {} |
|
data_folder = Path("data") |
|
|
|
if not data_folder.exists(): |
|
st.error("Data folder not found! Please create a 'data' folder with subject JSON files.") |
|
return {} |
|
|
|
for file in data_folder.glob("*.json"): |
|
with open(file, 'r') as f: |
|
data = json.load(f) |
|
questions_data[data["subject"]] = data["questions"] |
|
|
|
return questions_data |
|
|
|
|
|
def init_session_state(): |
|
if 'current_mode' not in st.session_state: |
|
st.session_state.current_mode = 'Practice' |
|
if 'test_start_time' not in st.session_state: |
|
st.session_state.test_start_time = None |
|
if 'test_answers' not in st.session_state: |
|
st.session_state.test_answers = {} |
|
if 'test_score' not in st.session_state: |
|
st.session_state.test_score = 0 |
|
if 'test_completed' not in st.session_state: |
|
st.session_state.test_completed = False |
|
|
|
|
|
def show_landing_page(subjects): |
|
st.title("π Interactive Quiz Application") |
|
st.write("Welcome to the Interactive Quiz App! Choose a subject to begin your learning journey.") |
|
|
|
cols = st.columns(len(subjects)) |
|
for idx, subject in enumerate(subjects): |
|
with cols[idx]: |
|
if st.button(subject, key=f"subject_{idx}"): |
|
st.session_state.selected_subject = subject |
|
st.session_state.page = 'subject' |
|
st.rerun() |
|
|
|
|
|
def practice_mode(questions, selected_week=None): |
|
if selected_week: |
|
questions = [q for q in questions if q['week'] == selected_week] |
|
|
|
for idx, question in enumerate(questions): |
|
with st.container(): |
|
st.markdown(f"### Question {idx + 1}") |
|
st.write(question['question']) |
|
|
|
options = [ |
|
question['option1'], |
|
question['option2'], |
|
question['option3'], |
|
question['option4'] |
|
] |
|
|
|
user_answer = st.radio( |
|
"Choose your answer:", |
|
options, |
|
key=f"practice_{idx}", |
|
index=None |
|
) |
|
|
|
if user_answer: |
|
correct_answer = options[question['correct'] - 1] |
|
if user_answer == correct_answer: |
|
st.success("Correct! β
") |
|
else: |
|
st.error(f"Incorrect! The correct answer is: {correct_answer}") |
|
|
|
st.markdown("---") |
|
|
|
|
|
def test_mode(questions, selected_week=None): |
|
if not st.session_state.test_start_time: |
|
st.session_state.test_start_time = time.time() |
|
|
|
if selected_week: |
|
questions = [q for q in questions if q['week'] == selected_week] |
|
|
|
test_questions = questions |
|
|
|
with st.form("test_form"): |
|
for idx, question in enumerate(test_questions): |
|
st.markdown(f"### Question {idx + 1}") |
|
st.write(question['question']) |
|
|
|
options = [ |
|
question['option1'], |
|
question['option2'], |
|
question['option3'], |
|
question['option4'] |
|
] |
|
|
|
answer = st.radio( |
|
"Choose your answer:", |
|
options, |
|
key=f"test_{idx}", |
|
index=None |
|
) |
|
st.session_state.test_answers[idx] = { |
|
'question': question['question'], |
|
'user_answer': answer, |
|
'correct_answer': options[question['correct'] - 1] |
|
} |
|
|
|
st.markdown("---") |
|
|
|
submitted = st.form_submit_button("Submit Test") |
|
|
|
if submitted: |
|
end_time = time.time() |
|
time_taken = end_time - st.session_state.test_start_time |
|
st.session_state.test_start_time = end_time |
|
|
|
|
|
correct_count = 0 |
|
for idx, answer_data in st.session_state.test_answers.items(): |
|
if answer_data['user_answer'] == answer_data['correct_answer']: |
|
correct_count += 1 |
|
|
|
st.session_state.test_score = (correct_count / len(test_questions)) * 100 |
|
st.session_state.test_completed = True |
|
st.session_state.time_taken = time_taken |
|
|
|
|
|
st.success(f"Test completed! Your score: {st.session_state.test_score:.2f}%") |
|
st.info(f"Time taken: {time_taken:.2f} seconds") |
|
|
|
|
|
st.markdown("### Review Your Answers") |
|
for idx, answer_data in st.session_state.test_answers.items(): |
|
if answer_data['user_answer'] == answer_data['correct_answer']: |
|
color_class = "correct-answer" |
|
else: |
|
color_class = "wrong-answer" |
|
|
|
with st.expander(f"Question {idx + 1}", expanded=True): |
|
if answer_data['user_answer'] == answer_data['correct_answer']: |
|
st.success(f"{answer_data['question']}") |
|
st.markdown(f"Your answer: {answer_data['user_answer']}") |
|
st.markdown(f"Correct answer: {answer_data['correct_answer']}") |
|
st.markdown(f"<div class='{color_class}'>Correct! β
</div>", unsafe_allow_html=True) |
|
else: |
|
st.error(f"{answer_data['question']}") |
|
st.markdown(f"Your answer: {answer_data['user_answer']}") |
|
st.markdown(f"Correct answer: {answer_data['correct_answer']}") |
|
st.markdown(f"<div class='{color_class}'>Incorrect β</div>", unsafe_allow_html=True) |
|
|
|
|
|
|
|
|
|
def show_subject_page(subject, questions): |
|
st.title(f"{subject} Quiz") |
|
|
|
|
|
with st.sidebar: |
|
if st.button("Home"): |
|
st.session_state.page = 'landing' |
|
st.rerun() |
|
|
|
|
|
mode = st.radio( |
|
"Select Mode:", |
|
['Practice', 'Test'], |
|
key="mode_selection" |
|
) |
|
|
|
|
|
weeks = sorted(list(set(q['week'] for q in questions))) |
|
selected_week = st.selectbox( |
|
"Select Week:", |
|
[None] + weeks, |
|
format_func=lambda x: "All Weeks" if x is None else f"Week {x}" |
|
) |
|
|
|
if mode == 'Practice': |
|
practice_mode(questions, selected_week) |
|
else: |
|
test_mode(questions, selected_week) |
|
|
|
def main(): |
|
|
|
init_session_state() |
|
|
|
|
|
load_css() |
|
|
|
|
|
questions_data = load_questions() |
|
|
|
if not questions_data: |
|
st.error("No question data available. Please check the data folder.") |
|
return |
|
|
|
|
|
if 'page' not in st.session_state: |
|
st.session_state.page = 'landing' |
|
|
|
|
|
if st.session_state.page == 'landing': |
|
show_landing_page(questions_data.keys()) |
|
elif st.session_state.page == 'subject': |
|
show_subject_page( |
|
st.session_state.selected_subject, |
|
questions_data[st.session_state.selected_subject] |
|
) |
|
|
|
if __name__ == "__main__": |
|
main() |
|
|