Introduction
This project guides you through building an Interactive Quiz App using Python and Streamlit. The app presents multiple-choice questions one at a time, tracks the user's score with st.session_state, and gives instant feedback after every answer. If you like data-driven apps, this quiz pairs naturally with the Pandas dashboard tutorial.
Prerequisites
pip install streamlitStep 1: Create the Script
Create quiz_app.py and paste the following:
import streamlit as st
st.set_page_config(page_title="Quiz App", page_icon="๐ง ")
st.title("๐ง Interactive Quiz App")
QUESTIONS = [
{
"question": "What is the capital of France?",
"options": ["Berlin", "Madrid", "Paris", "Rome"],
"answer": "Paris",
},
{
"question": "Which planet is known as the Red Planet?",
"options": ["Earth", "Mars", "Jupiter", "Venus"],
"answer": "Mars",
},
{
"question": "What is the highest mountain in the world?",
"options": ["K2", "Kangchenjunga", "Mount Everest", "Lhotse"],
"answer": "Mount Everest",
},
{
"question": "How many sides does a hexagon have?",
"options": ["5", "6", "7", "8"],
"answer": "6",
},
{
"question": "Which language is primarily used for web styling?",
"options": ["Python", "JavaScript", "CSS", "SQL"],
"answer": "CSS",
},
]
for key, default in [("score", 0), ("current", 0), ("finished", False)]:
if key not in st.session_state:
st.session_state[key] = default
if st.session_state.finished:
total = len(QUESTIONS)
score = st.session_state.score
st.balloons()
st.subheader("๐ Quiz Complete!")
st.metric("Your Score", f"{score} / {total}")
pct = score / total * 100
if pct >= 80:
st.success("Excellent work! ๐")
elif pct >= 60:
st.info("Good job! Keep practising. ๐")
else:
st.warning("Keep trying โ you will get there! ๐ช")
if st.button("๐ Restart Quiz"):
st.session_state.update({"score": 0, "current": 0, "finished": False})
st.rerun()
else:
idx = st.session_state.current
q = QUESTIONS[idx]
st.progress(idx / len(QUESTIONS), text=f"Question {idx + 1} of {len(QUESTIONS)}")
st.subheader(q["question"])
selected = st.radio("Choose your answer:", q["options"], key=f"q_{idx}")
if st.button("Submit Answer"):
if selected == q["answer"]:
st.success("โ
Correct!")
st.session_state.score += 1
else:
st.error(f"โ Wrong! The correct answer was **{q['answer']}**.")
st.session_state.current += 1
if st.session_state.current >= len(QUESTIONS):
st.session_state.finished = True
st.rerun()Step 2: Run the App
streamlit run quiz_app.pyStep 3: Use the App
The quiz shows one question at a time with a progress bar at the top. Select an answer and click Submit Answer to get instant feedback. After the final question the score screen appears with a performance message.
How It Works
The quiz is a state machine: questions live in a Python list of dicts, and st.session_state["q_num"] tracks where the user is. Each rerun renders the current question with st.radio, and the Submit button checks the answer, stores the result, and increments the counter โ triggering a rerun that shows the next question.
Because Streamlit re-executes the whole script per interaction, all progress *must* live in st.session_state; anything stored in a plain variable evaporates on rerun. That single concept โ session state as the app's memory โ is the core lesson of this project.
At the end, results render as a score plus st.balloons(). With a few more lines the answers list becomes a DataFrame and you get per-question analytics with st.bar_chart, exactly the technique from the data dashboard.
Key Concepts
What to Try Next
time.time().pandas.Common Errors & Fixes
st.session_state.on_click callback form or guard with if st.button(...) and not answered.st.session_state.setdefault("q_num", 0).key and reset it when advancing questions.FAQ
How do I load questions from a file?
Read a JSON/CSV into the questions list at startup โ the structure matches the blog content files pattern: one object per question.
Can I add a timer per question?
Yes โ record time.time() when the question renders and compare on submit; Streamlit's st_autorefresh component can force the check.
How do I show a results breakdown?
Convert the results list to a DataFrame and use st.bar_chart(df) โ five lines, covered in the dashboard tutorial.