prepit / app.py
ishans24's picture
Update app.py
7beb714 verified
import streamlit as st
import json
import random
import time
from pathlib import Path
# Set page configuration
st.set_page_config(
page_title="Prepit: Interactive Quiz App",
page_icon="πŸ“š"
)
# Custom CSS for styling
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)
# Load questions from JSON files
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
# Initialize session state
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
# Landing page
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()
# Practice mode
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 # Set index to None to start with no selection
)
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("---")
# Test mode
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
# Calculate score
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
# Show results
st.success(f"Test completed! Your score: {st.session_state.test_score:.2f}%")
st.info(f"Time taken: {time_taken:.2f} seconds")
# Show review
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)
# Subject page
def show_subject_page(subject, questions):
st.title(f"{subject} Quiz")
# Sidebar components
with st.sidebar:
if st.button("Home"):
st.session_state.page = 'landing'
st.rerun()
# Mode selection
mode = st.radio(
"Select Mode:",
['Practice', 'Test'],
key="mode_selection"
)
# Week 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():
# Initialize session state
init_session_state()
# Load CSS
load_css()
# Load questions
questions_data = load_questions()
if not questions_data:
st.error("No question data available. Please check the data folder.")
return
# Initialize page state if not exists
if 'page' not in st.session_state:
st.session_state.page = 'landing'
# Navigation
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()