Build a Python Quiz Game

Build an interactive terminal quiz game using Python fundamentals.

Introduction

30 Second Summary

Everyone loves a good quiz. Whether you are testing a friend on trivia or challenging yourself with flashcards, quizzes turn learning into a game. Building one from scratch is a perfect way to learn programming.

In this project, you will build an interactive multiple-choice quiz game in Python that runs in your terminal. The game asks 5 questions, checks your answers, and gives you a final score with a grade.

What You'll Build

A Python script that stores quiz questions in a data structure, loops through them one by one, validates player input, and calculates a percentage-based grade at the end.

By the end of this project, you'll have:

  • A working quiz game with 5 multiple-choice questions that runs entirely in your terminal.
  • A data-driven question bank using lists and dictionaries that you can easily expand with new questions.
  • A scoring system with input validation, percentage calculation, and letter grades.
  • Secret Mission: Add a timer that tracks how fast the player completes the quiz and displays their speed alongside the final score.

Are there any prerequisites?

None. You just need Python installed on your computer. Step 1 walks you through verifying your setup and creating your project file from scratch.

Before We Start

Before you start building the quiz game, you need to make sure your computer is ready to run Python code.

In this step, you'll confirm Python is installed, create a project folder, and run a quick test to verify everything is connected.

In this step, get ready to:
  • Verify Python is installed and check your version number.
  • Create your project folder and a new Python file.
  • Run a test to confirm everything works.
Open your terminal and check your Python version

Your terminal is where you'll run Python scripts throughout this project. Let's open it and make sure Python is ready to go.

  • Press Cmd+Space (macOS) or the Windows key (Windows) to open your search bar.
  • Type Terminal (macOS) or PowerShell (Windows) and press Enter to open it.
  • Check your Python version by running this command:
python --version

You should see a version number printed, like Python 3.14.5 or Python 3.10.12.

✔️ I see version 3.10 or higher

Your Python installation is ready. You can move on to creating your project folder.

ⓧ I see an older version

This project requires Python 3.10 or higher. You'll need to install a newer version.

  • Go to python.org/downloads in your browser.
  • Download and run the latest Python installer for your operating system.
  • On Windows, the installer will ask if you want to add Python to PATH. Make sure to check that option.
  • Close and reopen your terminal after the install finishes.
  • Run python --version again to confirm you see 3.10 or higher.

macOS users

On macOS, the system-installed Python may be older. If python --version still shows the old version after installing, try running python3 --version instead. If that works, use python3 in place of python for the rest of this project.

ⓧ Command not found

Python is not installed on your machine yet. Let's install it now.

  • Go to python.org/downloads in your browser.
  • Download the latest Python installer for your operating system.
  • Run the installer. On Windows, check the box to Add Python to PATH before clicking Install Now.
  • On macOS, open the downloaded .pkg file and follow the prompts.
  • Close and reopen your terminal after installation.
  • Run python --version again. You should now see a version number 3.10 or higher.

macOS users

If python --version still doesn't work after installing, try python3 --version. macOS often registers the command as python3 instead. Use python3 for the rest of this project if that's the case.

Create your project folder and file

You need a dedicated folder to keep your quiz game code organized. You'll create it on your Desktop so it's easy to find.

  • Move to your Desktop by running this command:
cd ~/Desktop
  • Create your project folder and move into it by running these commands:
mkdir quiz-game
cd quiz-game
  • Confirm the folder was created by running:
pwd

You should see a path ending in quiz-game, confirming you're in the right place.

Now create your Python file. Open your Python editor (IDLE, VS Code, or whichever editor you have installed).

  • Press Cmd+Space (macOS) or the Windows key (Windows) to open your search bar.
  • Type the name of your editor (for example, IDLE) and press Enter to open it.
  • In your editor, create a new file. In IDLE, click File, then New File.
  • Save the empty file immediately. Click File, then Save As.
  • Navigate to the quiz-game folder on your Desktop.
  • Name the file quiz_game.py and click Save.

Why quiz_game.py and not quiz-game.py?

Python file names use underscores instead of hyphens. Hyphens are interpreted as minus signs in Python, which would cause errors when you try to import or reference the file later.

Can't find the quiz-game folder in Save As?

Make sure you navigate to your Desktop first in the Save As dialog. The quiz-game folder should be visible there since you just created it in the terminal.

help me find my quiz-game folder to save my Python file

Write and run a test print statement

Before writing the full quiz, let's confirm that your file runs correctly. You'll add a simple print statement and execute it from the terminal.

  • In your quiz_game.py file, type the following code:
print("Hello, Quiz Game!")

What does this code do?

The print() function displays text in your terminal. This single line confirms that Python can find your file, read it, and execute it successfully.

  • Save the file. In IDLE, press Ctrl+S (Windows) or Cmd+S (macOS).
  • Switch back to your terminal. Make sure you're still in the quiz-game folder.
  • Run your script by entering this command:
python quiz_game.py

You should see Hello, Quiz Game! printed in your terminal.

Seeing an error or no output?

If you see No such file or directory, your terminal is not in the right folder. Run cd ~/Desktop/quiz-game and try again.

If you see a SyntaxError, double-check that your code matches exactly. Make sure the quotes around the text are straight quotes, not curly quotes.

On macOS, if python is not recognized, try python3 quiz_game.py instead.

help me troubleshoot running my first Python script

✔️ Awesome, I've got everything!

Great. Double check you've saved your file.

ⓧ I'd like to double check the full code

Here's what your quiz_game.py should look like right now:

print("Hello, Quiz Game!")

Your environment is ready. Next up, you'll build the data structure that holds all of your quiz questions.

Verify Your Python Setup

Before writing any game logic, you need a working Python environment. This step makes sure Python is installed, your project folder is ready, and your editor can save and run code.

You'll confirm your Python version, create a dedicated project folder on your Desktop, and run a quick test to prove everything works end to end.

In this step, get ready to:
  • Confirm Python is installed and running version 3.10 or higher.
  • Create a project folder and a new Python file called quiz_game.py.
  • Run a test print statement to verify your full setup works.
Check your Python version

Python is the programming language you'll use to build the quiz game. You need version 3.10 or higher installed on your machine.

  • Press Cmd+Space (macOS) or the Windows key (Windows) to open your search bar.
  • Type Terminal (macOS) or PowerShell (Windows) and press Enter to open it.
  • Check your Python version by running this command:
python --version

You should see a version number like Python 3.10.x or higher printed in your terminal.

Not seeing a version number?

On macOS, try python3 --version instead. Some macOS installations use python3 as the command name.

On Windows, try py --version as an alternative. If neither works, download Python from python.org/downloads and install it.

Why can't my terminal find Python?

Create your project folder

Every project needs a dedicated folder to keep files organized. You'll create a folder called quiz-game on your Desktop so you can find it easily.

  • Move to your Desktop by running this command:
cd ~/Desktop
  • Create your project folder and move into it by running these commands:
mkdir quiz-game
cd quiz-game
  • Confirm the folder exists by running:
ls

The folder is empty right now, so you won't see any output. That's expected.

Seeing a 'No such file or directory' error?

Make sure you ran cd ~/Desktop first. If you're on Windows Command Prompt (not PowerShell), try cd %USERPROFILE%\Desktop instead.

Help me navigate to my Desktop in the terminal.

Write and run your first test

Now you'll create the file that will hold your quiz game code and run a quick test to confirm your editor and terminal are working together.

  • Press Cmd+Space (macOS) or the Windows key (Windows) to open your search bar.
  • Type IDLE and press Enter to open it.

What is IDLE?

IDLE is Python's built-in code editor. It ships with every Python installation, so you already have it. You'll use it to write and save your code throughout this project.

  • Click File in the menu bar.
  • Click New File to open a blank editing window.
  • Type the following code into the new window:
print("Hello, Quiz Game!")

What does this code do?

print() is a built-in Python function that displays text in your terminal. If this runs successfully, it proves your file, editor, and terminal are all connected.

  • Click File in the menu bar, then click Save As....
  • Navigate to your Desktop folder, then open the quiz-game folder you created earlier.
  • Type quiz_game.py as the file name and click Save.

Now switch back to your terminal to run the file.

  • Run your file by entering this command:
python quiz_game.py

You should see Hello, Quiz Game! printed in your terminal.

Seeing 'No such file or directory'?

Make sure your terminal is inside the quiz-game folder. Run cd ~/Desktop/quiz-game to get there.

Also check that you saved the file as quiz_game.py (with an underscore, not a hyphen) inside the quiz-game folder on your Desktop.

Help me run my Python file from the terminal.

✔️ Awesome, I've got everything!

Great. Make sure you've saved quiz_game.py and you're ready for the next step.

ⓧ I'd like to double check the full code

Here's the complete quiz_game.py file at this point:

print("Hello, Quiz Game!")

Your environment is ready. Next up, you'll build the question bank that powers your quiz game.

Build Your Question Bank

Your Python environment is confirmed and ready to go. Now it's time to build the foundation of your quiz game: the questions themselves.

Every quiz game needs a bank of questions to draw from. In this step, you'll store your questions using a data-driven approach where each question, its answer options, and the correct answer are organized in a structured format that Python can easily work with.

In this step, get ready to:
  • Define a function that returns your question bank as a list of dictionaries.
  • Store 5 multiple-choice questions with 4 options each.
  • Print the first question and its options to verify the data structure works.
Create a list of dictionaries for your questions

A dictionary in Python holds key-value pairs, like a labelled container. A list holds items in order. By putting dictionaries inside a list, you get a structured question bank where each entry contains everything the game needs to ask one question.

  • In quiz_game.py, delete the print("Hello, Quiz Game!") line.
  • Replace it with the following function that returns your question bank:
def load_questions():
    """Return the quiz questions as a list of dictionaries."""
    return [
        {
            "question": "What is the capital of France?",
            "options": ["London", "Berlin", "Paris", "Madrid"],
            "answer": 2
        },
        {
            "question": "Which planet is known as the Red Planet?",
            "options": ["Venus", "Mars", "Jupiter", "Saturn"],
            "answer": 1
        },
        {
            "question": "What is the largest ocean on Earth?",
            "options": ["Atlantic", "Indian", "Arctic", "Pacific"],
            "answer": 3
        },
        {
            "question": "How many continents are there?",
            "options": ["5", "6", "7", "8"],
            "answer": 2
        },
        {
            "question": "What programming language are you learning right now?",
            "options": ["JavaScript", "Python", "Java", "C++"],
            "answer": 1
        }
    ]

What does this code do?

load_questions() is a function that returns a list containing 5 dictionaries. Each dictionary represents one quiz question.

Each dictionary has three keys: "question" (the question text), "options" (a list of 4 answer choices), and "answer" (the index of the correct option).

The answer value is a zero-based index. For example, "answer": 2 means the third option is correct because Python counts positions starting from 0.

Why store questions in a function?

Wrapping your data in a function keeps it separate from the game logic. This means you can add, remove, or edit questions without touching the code that runs the quiz.

This separation is a pattern called data-driven design. It scales to any number of questions without code changes.

You won't see output yet. The next chunk adds a print statement to test this function.

Print the first question to verify your data structure

Your function is defined, but you need proof that the data is structured correctly. Adding a quick print test lets you visually confirm everything is wired up before building the game logic on top of it.

  • Below the load_questions() function, add the following verification code:
# Verify the data structure
questions = load_questions()
print(questions[0]["question"])
for i, option in enumerate(questions[0]["options"], 1):
    print(f"  {i}. {option}")

What does this code do?

  • questions = load_questions() calls your function and stores the returned list in a variable.
  • questions[0] grabs the first dictionary in the list (index 0).
  • enumerate(questions[0]["options"], 1) loops through the options list, numbering them starting from 1 instead of 0 so they display as 1, 2, 3, 4.
  • The f" {i}. {option}" is an f-string that inserts the number and option text into the printed line.
  • Save quiz_game.py.
  • Run the script in your terminal by running this command:
python quiz_game.py
  • You should see the first question printed, followed by its four numbered options:
What is the capital of France?
  1. London
  2. Berlin
  3. Paris
  4. Madrid

Seeing an error instead of the question?

  • Check for a SyntaxError pointing at a missing comma between dictionaries. Every } before the next { needs a comma after it.
  • If you see IndentationError, make sure everything inside the function is indented with 4 spaces. The return keyword should be one level in from def.
  • Make sure you deleted the old print("Hello, Quiz Game!") line. It won't cause an error, but confirms you're starting fresh.

Help me debug my quiz_game.py file

✔️ Awesome, I've got everything!

Great. Double check you've saved your file before moving on.

ⓧ I'd like to double check the full code

Here's the complete quiz_game.py so far. Make sure yours matches:

def load_questions():
    """Return the quiz questions as a list of dictionaries."""
    return [
        {
            "question": "What is the capital of France?",
            "options": ["London", "Berlin", "Paris", "Madrid"],
            "answer": 2
        },
        {
            "question": "Which planet is known as the Red Planet?",
            "options": ["Venus", "Mars", "Jupiter", "Saturn"],
            "answer": 1
        },
        {
            "question": "What is the largest ocean on Earth?",
            "options": ["Atlantic", "Indian", "Arctic", "Pacific"],
            "answer": 3
        },
        {
            "question": "How many continents are there?",
            "options": ["5", "6", "7", "8"],
            "answer": 2
        },
        {
            "question": "What programming language are you learning right now?",
            "options": ["JavaScript", "Python", "Java", "C++"],
            "answer": 1
        }
    ]

# Verify the data structure
questions = load_questions()
print(questions[0]["question"])
for i, option in enumerate(questions[0]["options"], 1):
    print(f"  {i}. {option}")

Your question bank is structured and verified. Next up, you'll build the game loop that presents each question to the player and tracks their score.

Create the Game Loop

Your question bank is loaded and verified. Now you need something to actually use that data.

In this step, you'll write the core game logic: a function that displays each question, collects the player's answer, validates their input, and tells them whether they got it right.

In this step, get ready to:
  • Write a function that displays questions and collects validated input.
  • Loop through all questions and track the player's score.
Write the ask_question function

Right now, your file ends with some test code that prints the first question. That was useful for verifying your data structure, but now you'll replace it with a proper function that handles any question.

  • In quiz_game.py, find and delete the verification code at the bottom of your file (everything below the load_questions() function):
# Verify the data structure
questions = load_questions()
print(questions[0]["question"])
for i, option in enumerate(questions[0]["options"], 1):
    print(f"  {i}. {option}")
  • Replace it with the following ask_question() function:
def ask_question(question_data, question_number):
    """Display a question and return True if the player answers correctly."""
    print(f"\nQ{question_number}: {question_data['question']}")

    for i, option in enumerate(question_data["options"], 1):
        print(f"  {i}. {option}")

    while True:
        try:
            choice = int(input("\nYour answer (1-4): "))
            if 1 <= choice <= 4:
                break
            print("Please enter a number between 1 and 4.")
        except ValueError:
            print("That's not a valid number! Try again.")

    if choice - 1 == question_data["answer"]:
        print("Correct!")
        return True
    else:
        correct_option = question_data["options"][question_data["answer"]]
        print(f"Wrong! The correct answer was: {correct_option}")
        return False

What does this function do?

This function handles one complete question-and-answer cycle. It takes a question dictionary and a question number, then does three things:

  • Displays the question text and its numbered options using enumerate() to count from 1.
  • Collects input inside a while True loop that keeps asking until the player types a valid number between 1 and 4. The try/except ValueError catches anything that is not a number at all (like letters or symbols).
  • Checks the answer by comparing choice - 1 (converting from 1-based player input to 0-based list index) against the stored correct answer. Returns True for correct, False for wrong.

Why while True for input validation?

A while True loop runs forever until you explicitly break out of it. This is the standard Python pattern for validated input. You keep asking until the player gives you something acceptable, then break exits the loop.

Without this, a player who types "hello" would crash your entire game with a ValueError.

  • Save quiz_game.py.

You won't see a change yet. The function is defined but nothing calls it. The next chunk adds the loop that puts it to work.

Seeing a syntax error when you save?

  • Make sure you deleted ALL of the old verification code. Leftover lines from the previous step can conflict with the new function.
  • Check that the def ask_question(question_data, question_number): line is at the same indentation level as def load_questions(): (no extra spaces before it).
  • Verify that the while True: block and the if choice - 1 block are indented inside the function (one level in from def).

My ask_question function has a syntax error

Loop through all questions and track the score

The function handles one question at a time. Now you need a loop that feeds every question from your bank into that function and keeps a running score.

  • Add the following code below your ask_question() function (at the bottom of the file, with no indentation):
questions = load_questions()
score = 0
total = len(questions)

for i, question in enumerate(questions, 1):
    if ask_question(question, i):
        score += 1

What does this code do?

  • questions = load_questions() loads all 5 question dictionaries into a list.
  • score = 0 creates a counter that starts at zero.
  • enumerate(questions, 1) pairs each question with a number starting from 1 (so Q1, Q2, Q3...).
  • if ask_question(question, i): calls your function. If it returns True (correct answer), the score goes up by 1.
  • Save quiz_game.py.
  • Run the game by running this command in your terminal:
python quiz_game.py

You should see the first question appear with 4 numbered options and a prompt asking for your answer. Answer all 5 questions to play through the full quiz.

Test the input validation

Try typing a letter like abc or a number like 9 when prompted. You should see your error messages appear and the game should keep asking until you enter 1, 2, 3, or 4.

Game crashes or nothing happens?

  • If you see NameError: name 'load_questions' is not defined, make sure the loop code is BELOW both function definitions, not above them.
  • If the game prints nothing and exits immediately, check that your loop code has no indentation. It should be at the far left of the file, not inside a function.
  • If you see IndentationError, make sure there is a blank line between the end of ask_question() and the questions = load_questions() line.

Help me debug my quiz game loop

✔️ Awesome, I've got everything!

Great. Double check you've saved your file before moving on.

ⓧ I'd like to double check the full code

Here is the full quiz_game.py file as it should look right now:

def load_questions():
    """Return the quiz questions as a list of dictionaries."""
    return [
        {
            "question": "What is the capital of France?",
            "options": ["London", "Berlin", "Paris", "Madrid"],
            "answer": 2
        },
        {
            "question": "Which planet is known as the Red Planet?",
            "options": ["Venus", "Mars", "Jupiter", "Saturn"],
            "answer": 1
        },
        {
            "question": "What is the largest ocean on Earth?",
            "options": ["Atlantic", "Indian", "Arctic", "Pacific"],
            "answer": 3
        },
        {
            "question": "How many continents are there?",
            "options": ["5", "6", "7", "8"],
            "answer": 2
        },
        {
            "question": "What programming language are you learning right now?",
            "options": ["JavaScript", "Python", "Java", "C++"],
            "answer": 1
        }
    ]


def ask_question(question_data, question_number):
    """Display a question and return True if the player answers correctly."""
    print(f"\nQ{question_number}: {question_data['question']}")

    for i, option in enumerate(question_data["options"], 1):
        print(f"  {i}. {option}")

    while True:
        try:
            choice = int(input("\nYour answer (1-4): "))
            if 1 <= choice <= 4:
                break
            print("Please enter a number between 1 and 4.")
        except ValueError:
            print("That's not a valid number! Try again.")

    if choice - 1 == question_data["answer"]:
        print("Correct!")
        return True
    else:
        correct_option = question_data["options"][question_data["answer"]]
        print(f"Wrong! The correct answer was: {correct_option}")
        return False


questions = load_questions()
score = 0
total = len(questions)

for i, question in enumerate(questions, 1):
    if ask_question(question, i):
        score += 1

Your game loop is working. You can play through all 5 questions and the game handles bad input gracefully. Next up, you'll add a scoring system that gives the player a final grade when they finish.

Add Scoring and Feedback

Your game loop is working. Players can answer all five questions and your code tracks how many they get right.

But right now the quiz just ends with no summary. Players deserve to see how they did overall. In this step, you'll calculate a percentage score, assign a letter grade, and display a polished results screen using f-strings.

In this step, get ready to:
  • Calculate the player's percentage score after the loop finishes.
  • Create a function that returns a letter grade based on the percentage.
  • Display a formatted results screen with the player's name, score, and grade.
Calculate the player's percentage score

After the for loop finishes, the score variable holds how many questions the player got right. To give meaningful feedback, you need to convert that into a percentage.

  • In quiz_game.py, find the for loop at the bottom of your file:
for i, question in enumerate(questions, 1):
    if ask_question(question, i):
        score += 1
  • Add this line directly below the for loop (after the score += 1 line, at the same indent level as the for keyword):
percentage = (score / total) * 100

What does this line do?

This divides the number of correct answers by the total number of questions, then multiplies by 100 to get a percentage. If the player got 3 out of 5, the result is 60.0.

You won't see a change yet. The next chunk uses this percentage to assign a grade.

Create the get_grade() function

A raw percentage is useful, but a letter grade gives instant feedback. You'll create a function that takes a percentage and returns both a grade letter and a short message.

  • In quiz_game.py, find the end of the ask_question() function (the return False line). Add the following new function below it, leaving a blank line between the two functions:
def get_grade(percentage):
    """Return a grade and message based on the percentage score."""
    if percentage >= 90:
        return "A", "Amazing work!"
    elif percentage >= 80:
        return "B", "Great job!"
    elif percentage >= 70:
        return "C", "Not bad!"
    elif percentage >= 60:
        return "D", "Keep practicing!"
    else:
        return "F", "Better luck next time!"

What does this code do?

This function uses if/elif/else to check the percentage against thresholds in descending order. The first condition that matches wins.

Each return statement sends back two values as a tuple: a grade letter and a feedback message. Python lets you return multiple values this way, separated by a comma.

  • Save quiz_game.py.

You won't see visible output yet. The next substep calls this function and displays the results.

Seeing a syntax error when you save?

Make sure the function is at the top level of the file (no indentation on the def line). Check that every elif and else lines up with the if at the same indentation level.

Help me fix an indentation error in my get_grade function

Display the final results with f-strings

Now you'll bring everything together. The quiz needs to ask the player's name at the start, then show a formatted results screen at the end that includes their name, score, percentage, and grade.

  • In quiz_game.py, scroll down to the main code at the bottom of your file. Find this line:
questions = load_questions()
  • Add this line directly above questions = load_questions() to collect the player's name before the quiz starts:
name = input("What is your name? ")
  • Now find the percentage = (score / total) * 100 line you added earlier. Add the following code below it to call get_grade() and print the results:
grade, message = get_grade(percentage)

print("\n" + "=" * 40)
print("          QUIZ RESULTS")
print("=" * 40)
print(f"  Player:     {name}")
print(f"  Score:      {score}/{total}")
print(f"  Percentage: {percentage:.0f}%")
print(f"  Grade:      {grade}")
print(f"  {message}")
print("=" * 40)

What does this code do?

The first line unpacks the tuple returned by get_grade() into two separate variables: grade and message.

The "=" * 40 creates a line of 40 equal signs to frame the results. The f-strings (lines starting with f") let you embed variables directly inside strings using curly braces.

The :.0f inside {percentage:.0f} is a format specifier that rounds the number to zero decimal places. So 60.0 displays as 60.

  • Save quiz_game.py.
  • Run your quiz by entering this command in your terminal:
python quiz_game.py
  • Type your name when prompted, answer all 5 questions, and confirm you see a results box showing your name, score, percentage, and letter grade.

Seeing a NameError for name or grade?

If you see an error mentioning name is not defined, make sure name = input("What is your name? ") appears above questions = load_questions() in your main code.

If the error mentions grade or get_grade, check that your get_grade() function is defined above the main code (not inside another function).

Help me debug a NameError in my Python quiz game

✔️ Awesome, I've got everything!

Double check you've saved your file.

ⓧ I'd like to double check the full code

Here is the full quiz_game.py file at this point. Compare it against yours:

def load_questions():
    """Return the quiz questions as a list of dictionaries."""
    return [
        {
            "question": "What is the capital of France?",
            "options": ["London", "Berlin", "Paris", "Madrid"],
            "answer": 2
        },
        {
            "question": "Which planet is known as the Red Planet?",
            "options": ["Venus", "Mars", "Jupiter", "Saturn"],
            "answer": 1
        },
        {
            "question": "What is the largest ocean on Earth?",
            "options": ["Atlantic", "Indian", "Arctic", "Pacific"],
            "answer": 3
        },
        {
            "question": "How many continents are there?",
            "options": ["5", "6", "7", "8"],
            "answer": 2
        },
        {
            "question": "What programming language are you learning right now?",
            "options": ["JavaScript", "Python", "Java", "C++"],
            "answer": 1
        }
    ]


def ask_question(question_data, question_number):
    """Display a question and return True if the player answers correctly."""
    print(f"\nQ{question_number}: {question_data['question']}")

    for i, option in enumerate(question_data["options"], 1):
        print(f"  {i}. {option}")

    while True:
        try:
            choice = int(input("\nYour answer (1-4): "))
            if 1 <= choice <= 4:
                break
            print("Please enter a number between 1 and 4.")
        except ValueError:
            print("That's not a valid number! Try again.")

    if choice - 1 == question_data["answer"]:
        print("Correct!")
        return True
    else:
        correct_option = question_data["options"][question_data["answer"]]
        print(f"Wrong! The correct answer was: {correct_option}")
        return False


def get_grade(percentage):
    """Return a grade and message based on the percentage score."""
    if percentage >= 90:
        return "A", "Amazing work!"
    elif percentage >= 80:
        return "B", "Great job!"
    elif percentage >= 70:
        return "C", "Not bad!"
    elif percentage >= 60:
        return "D", "Keep practicing!"
    else:
        return "F", "Better luck next time!"


name = input("What is your name? ")
questions = load_questions()
score = 0
total = len(questions)

for i, question in enumerate(questions, 1):
    if ask_question(question, i):
        score += 1

percentage = (score / total) * 100
grade, message = get_grade(percentage)

print("\n" + "=" * 40)
print("          QUIZ RESULTS")
print("=" * 40)
print(f"  Player:     {name}")
print(f"  Score:      {score}/{total}")
print(f"  Percentage: {percentage:.0f}%")
print(f"  Grade:      {grade}")
print(f"  {message}")
print("=" * 40)

Your quiz now gives players a complete experience from start to finish. Next up, you'll organize all of this code into clean, reusable functions and add the ability to play again.

Organize with Functions

Your quiz works, but the game logic at the bottom of your file is "loose" code. It runs immediately when you execute the file, and there's no way to replay without running the script again.

In this step, you'll wrap everything into a clean run_quiz() function and add a play-again loop. This makes your code reusable and gives the player a better experience.

In this step, get ready to:
  • Wrap the full game flow into a run_quiz() function with a welcome banner and question shuffling.
  • Add a __main__ guard and play-again loop so the player can restart without re-running the script.
Create the run_quiz() function

Right now, the game logic at the bottom of your file runs as soon as Python reads the file. Wrapping it in a function gives you control over when and how the game starts.

  • In quiz_game.py, add this import at the very top of your file (above the load_questions() function):
import random
  • Now scroll down to the bottom of your file and find all the loose code that starts with name = input("What is your name? "):
name = input("What is your name? ")
questions = load_questions()
score = 0
total = len(questions)

for i, question in enumerate(questions, 1):
    if ask_question(question, i):
        score += 1

percentage = (score / total) * 100
grade, message = get_grade(percentage)

print("\n" + "=" * 40)
print("          QUIZ RESULTS")
print("=" * 40)
print(f"  Player:     {name}")
print(f"  Score:      {score}/{total}")
print(f"  Percentage: {percentage:.0f}%")
print(f"  Grade:      {grade}")
print(f"  {message}")
print("=" * 40)
  • Delete all of that loose code and replace it with this function:
def run_quiz():
    """Run the full quiz game."""
    print("=" * 40)
    print("   WELCOME TO THE PYTHON QUIZ GAME!")
    print("=" * 40)

    name = input("\nWhat is your name? ")
    print(f"\nHi {name}! Let's test your knowledge.")
    print("Answer each question by typing 1, 2, 3, or 4.\n")

    # Load questions and shuffle them for variety
    questions = load_questions()
    random.shuffle(questions)

    score = 0
    total = len(questions)

    # Loop through each question and track correct answers
    for i, question in enumerate(questions, 1):
        if ask_question(question, i):
            score += 1

    # Calculate results
    percentage = (score / total) * 100
    grade, message = get_grade(percentage)

    # Display the final scoreboard
    print("\n" + "=" * 40)
    print("          QUIZ RESULTS")
    print("=" * 40)
    print(f"  Player:     {name}")
    print(f"  Score:      {score}/{total}")
    print(f"  Percentage: {percentage:.0f}%")
    print(f"  Grade:      {grade}")
    print(f"  {message}")
    print("=" * 40)

What does this code do?

The run_quiz() function wraps all the game logic into one callable unit. Here's what it adds compared to the loose code you deleted:

  • A welcome banner using printed equals signs so the game feels polished.
  • A greeting that uses the player's name and explains the input format.
  • random.shuffle(questions) randomizes the question order each time, so replays feel fresh.

Why wrap code in a function?

Loose code runs automatically whenever Python reads the file. A function only runs when you call it. This gives you control to call run_quiz() multiple times, test it, or import it from another file without the game launching unexpectedly.

Don't run the file yet. Right now there's no code calling run_quiz(), so nothing would happen. You'll fix that in the next substep.

Add the main guard and play-again loop

Python uses a special pattern to detect whether a file is being run directly or imported by another file. This guard ensures the game only starts when you run the script yourself.

  • At the very bottom of quiz_game.py (after the run_quiz() function), add the main guard with a play-again loop:
if __name__ == "__main__":
    while True:
        run_quiz()
        play_again = input("\nPlay again? (yes/no): ").lower().strip()
        if play_again != "yes":
            print("Thanks for playing! Goodbye!")
            break

What does this code do?

if __name__ == "__main__": checks whether this file is being run directly (not imported). If it is, the code inside executes.

The while True loop calls run_quiz() and then asks the player if they want to go again. If they type anything other than yes, the loop breaks and the program exits.

  • Save quiz_game.py.
  • Run the game by entering this command in your terminal:
python quiz_game.py
  • You should see a welcome banner with equals signs, your name greeting, and questions in a randomized order. After the results display, you'll see Play again? (yes/no): at the bottom.
  • Type yes to confirm the game restarts. Then type no to confirm you see the goodbye message.

Nothing happens when you run the file?

  • Make sure you deleted ALL the old loose code. If any remains above the if __name__ block, it will run instead of your new function.
  • Check your indentation. The while True: loop must be indented one level inside the if __name__ block.
  • Confirm that import random is at the very top of the file. If it's missing, you'll see a NameError when the game tries to shuffle questions.

Help me debug why my quiz game isn't running after I added the __main__ guard.

✔️ Awesome, I've got everything!

Great. Double check you've saved your file and the game runs with a welcome banner, randomized questions, and a play-again prompt.

ⓧ I'd like to double check the full code

Here's the complete quiz_game.py file. Compare yours against it:

import random


def load_questions():
    """Return the quiz questions as a list of dictionaries."""
    return [
        {
            "question": "What is the capital of France?",
            "options": ["London", "Berlin", "Paris", "Madrid"],
            "answer": 2
        },
        {
            "question": "Which planet is known as the Red Planet?",
            "options": ["Venus", "Mars", "Jupiter", "Saturn"],
            "answer": 1
        },
        {
            "question": "What is the largest ocean on Earth?",
            "options": ["Atlantic", "Indian", "Arctic", "Pacific"],
            "answer": 3
        },
        {
            "question": "How many continents are there?",
            "options": ["5", "6", "7", "8"],
            "answer": 2
        },
        {
            "question": "What programming language are you learning right now?",
            "options": ["JavaScript", "Python", "Java", "C++"],
            "answer": 1
        }
    ]


def ask_question(question_data, question_number):
    """Display a question and return True if the player answers correctly."""
    print(f"\nQ{question_number}: {question_data['question']}")

    for i, option in enumerate(question_data["options"], 1):
        print(f"  {i}. {option}")

    while True:
        try:
            choice = int(input("\nYour answer (1-4): "))
            if 1 <= choice <= 4:
                break
            print("Please enter a number between 1 and 4.")
        except ValueError:
            print("That's not a valid number! Try again.")

    if choice - 1 == question_data["answer"]:
        print("Correct!")
        return True
    else:
        correct_option = question_data["options"][question_data["answer"]]
        print(f"Wrong! The correct answer was: {correct_option}")
        return False


def get_grade(percentage):
    """Return a grade and message based on the percentage score."""
    if percentage >= 90:
        return "A", "Amazing work!"
    elif percentage >= 80:
        return "B", "Great job!"
    elif percentage >= 70:
        return "C", "Not bad!"
    elif percentage >= 60:
        return "D", "Keep practicing!"
    else:
        return "F", "Better luck next time!"


def run_quiz():
    """Run the full quiz game."""
    print("=" * 40)
    print("   WELCOME TO THE PYTHON QUIZ GAME!")
    print("=" * 40)

    name = input("\nWhat is your name? ")
    print(f"\nHi {name}! Let's test your knowledge.")
    print("Answer each question by typing 1, 2, 3, or 4.\n")

    questions = load_questions()
    random.shuffle(questions)

    score = 0
    total = len(questions)

    for i, question in enumerate(questions, 1):
        if ask_question(question, i):
            score += 1

    percentage = (score / total) * 100
    grade, message = get_grade(percentage)

    print("\n" + "=" * 40)
    print("          QUIZ RESULTS")
    print("=" * 40)
    print(f"  Player:     {name}")
    print(f"  Score:      {score}/{total}")
    print(f"  Percentage: {percentage:.0f}%")
    print(f"  Grade:      {grade}")
    print(f"  {message}")
    print("=" * 40)


if __name__ == "__main__":
    while True:
        run_quiz()
        play_again = input("\nPlay again? (yes/no): ").lower().strip()
        if play_again != "yes":
            print("Thanks for playing! Goodbye!")
            break

Your quiz game is fully organized and polished. Every piece of logic lives inside a named function, questions shuffle each round, and the player can replay without restarting the script. Next up, you'll tackle the Secret Mission and add a timer to track how fast the player finishes.

Secret mission

Add a Quiz Timer

Your quiz works great, but how fast can someone actually complete it? Add a timer that tracks how long the player takes to answer all 5 questions, then reward them with a speed bonus if they finish in under 30 seconds.

Clean Up Your Resources

Clean Up Your Resources

This project runs entirely locally, so there are no ongoing costs. Decide whether to keep your project files to continue experimenting, or delete them to tidy up your Desktop.

Resources you used:

  • Project folder containing quiz_game.py on your Desktop.

Keep everything running

No action needed. Choose this if you want to keep experimenting with your quiz game, add more questions, or try new features.

  • Your project folder stays on your Desktop. You can run python quiz_game.py any time to play again.
  • Python remains installed on your system for future projects.

Pause - I'll come back to this later

Since this is a local project with no running processes, there is nothing to pause. Your files sit quietly on disk until you come back.

  • No background services or servers are running. Your project folder takes up minimal disk space.

Delete - I don't want to use this again

Remove your project folder entirely. This deletes quiz_game.py and any other files inside the folder.

  • On macOS or Linux, run this in your terminal:
cd ~/Desktop
rm -rf quiz-game
  • On Windows, run this in Command Prompt:
cd %USERPROFILE%\Desktop
rmdir /s /q quiz-game

Nice Work!

Nice Work!

Nice work! You just built your first Python program from scratch. Your quiz game takes input, validates it, tracks a score, and gives personalised feedback.

Here's what you learned:

  • Built an interactive quiz game that runs in the terminal, collecting user input and responding with real-time feedback.
  • Organised data using lists and dictionaries to create a data-driven question bank that scales to any number of questions without code changes.
  • Structured your code into reusable functions with input validation, loops, and conditionals to control program flow.
  • Secret Mission: Added a quiz timer that tracks how fast the player completes the quiz and rewards speed with a bonus message.

Ready to quiz yourself?