Quiz Game

Python Projects (Beginner)
Course 4 ยท Chapter 5 ยท Quiz Game

๐Ÿง  Quiz Game

A multiple-choice quiz that scores itself โ€” questions stored as a list of dictionaries, presented one at a time, with a running score tallied and reported as a percentage at the end.

๐ŸŽฎ What We're Building

A quiz that presents a series of multiple-choice questions, checks each answer as it's given, and prints a final score out of the total, plus a percentage.

Step 1: Representing Questions

questions = [
    {
        "question": "What does CPU stand for?",
        "choices": ["Central Processing Unit", "Computer Personal Unit", "Central Program Utility"],
        "answer": "A"
    },
    {
        "question": "Which keyword defines a function in Python?",
        "choices": ["func", "def", "function"],
        "answer": "B"
    },
]

Each question is a dict (Course 1, Chapter 7) with three keys; the whole quiz is a list of these dicts, reusing exactly the "list of dicts" shape Chapter 4's to-do app used for tasks. "answer" stores the correct choice's letter, not its full text โ€” comparing letters is simpler than comparing whole sentences.

Step 2: Presenting a Question

letters = "ABC"

def ask_question(q):
    print(q["question"])
    for i, choice in enumerate(q["choices"]):
        print(f"  {letters[i]}. {choice}")

enumerate (Course 1, Chapter 4) pairs each choice with its position; letters[i] reuses plain string indexing (Course 1, Chapter 5) to turn that position into the matching letter โ€” letters[0] is "A", letters[1] is "B", and so on.

Step 3: Checking Answers & Scoring

def check_answer(q, user_answer):
    return user_answer.strip().upper() == q["answer"]
โš  Normalize User Input Before Comparing

A player typing "b", " B", or "B " should all count as correct โ€” but "b" == "B" is False (Course 1's string comparisons are case-sensitive), and stray whitespace from pressing Enter carelessly breaks an exact match too. .strip() (Course 1, Chapter 5) removes surrounding whitespace, .upper() normalizes case โ€” chaining both before comparing is standard practice for any free-text-ish user input.

Step 4: The Quiz Loop & Final Score

score = 0

for q in questions:
    ask_question(q)
    user_answer = input("Your answer: ")
    if check_answer(q, user_answer):
        print("Correct!\n")
        score += 1
    else:
        print(f"Nope โ€” the answer was {q['answer']}.\n")

percentage = (score / len(questions)) * 100
print(f"Final score: {score}/{len(questions)} ({percentage:.0f}%)")

score is the accumulator pattern one more time (Course 1, Chapter 4) โ€” incremented once per correct answer, read only after the loop finishes. score / len(questions) reuses the average-style division from earlier chapters, scaled to a percentage and formatted to a whole number with :.0f (Course 1, Chapter 5).

๐Ÿ The Complete Quiz Game

questions = [
    {
        "question": "What does CPU stand for?",
        "choices": ["Central Processing Unit", "Computer Personal Unit", "Central Program Utility"],
        "answer": "A"
    },
    {
        "question": "Which keyword defines a function in Python?",
        "choices": ["func", "def", "function"],
        "answer": "B"
    },
]

letters = "ABC"

def ask_question(q):
    print(q["question"])
    for i, choice in enumerate(q["choices"]):
        print(f"  {letters[i]}. {choice}")

def check_answer(q, user_answer):
    return user_answer.strip().upper() == q["answer"]

score = 0

for q in questions:
    ask_question(q)
    user_answer = input("Your answer: ")
    if check_answer(q, user_answer):
        print("Correct!\n")
        score += 1
    else:
        print(f"Nope โ€” the answer was {q['answer']}.\n")

percentage = (score / len(questions)) * 100
print(f"Final score: {score}/{len(questions)} ({percentage:.0f}%)")

List of dicts

Each question is a dict; the quiz is a list of them โ€” same shape as Chapter 4's tasks.

enumerate + string indexing

Turns each choice's position into a letter label (A, B, C...).

Normalized comparison

.strip().upper() before comparing user input to the stored answer.

Scoring

An accumulator, converted to a percentage at the end.

๐Ÿš€ Extend This Project

Try these on your own:

  • Use random.shuffle(questions) so the question order is different each playthrough.
  • Load questions from an external JSON file (Course 2, Chapter 7) instead of hardcoding them, so new quizzes don't require editing the code.
  • Add a category field to each question, and let the player choose a category before starting.
  • Track and display which specific questions were missed at the end, not just the final score.

๐ŸŽฏ What's Next

Next chapter: Contact Book โ€” file I/O and CRUD operations against a JSON file.