You Made It.
You have reached the end of Python Essentials. You have covered variables, data types, strings, lists, dictionaries, sets, tuples, conditionals, loops, functions, scope, and more. Now it is time to put all of it together into one real project.
In this final project you will build a General Knowledge Quiz Game that runs in the console. You will build it step by step, one piece at a time. Each step introduces a new concept from the course and shows you how it fits into a real working program.
By the end you will have a complete, playable quiz game written entirely by you.
What You Will Build
Your finished quiz game will:
- Store 20 general knowledge questions in a Python dictionary
- Ask the player each question one at a time using
input() - Tell the player immediately if they were right or wrong
- Keep track of the score using a variable
- Show a final score and a grade at the end
- Ask the player if they want to play again using a
whileloop
Everything you need to build this you have already learned. This project is about connecting the pieces together.
Concepts You Will Use
- Dictionaries — to store questions and answers
- Functions — to organise your code into reusable blocks
- For loops — to iterate over the questions
- While loops — to let the player replay the game
- Conditionals — to check answers and assign grades
- String methods — to handle player input cleanly
- f-strings — to display results clearly
- Scope — to understand how variables live inside functions
Step 1 — Set Up Your File
Create a new file in VS Code named quiz_game.py in your final project folder. Add the following comment at the top:
# Python Essentials - Final Project
# General Knowledge Quiz Game
# Your name here
Good habit: always put your name and a description at the top of a project file. It tells anyone reading it what the file is and who wrote it.
Step 2 — Build Your Question Bank
Your questions will be stored in a dictionary. The key is the question and the value is the correct answer. This is a natural fit for a dictionary because every question has exactly one answer.
questions = {
"What is the capital of France?": "paris",
"How many sides does a hexagon have?": "6",
"What is the largest planet in our solar system?": "jupiter",
"Who wrote Romeo and Juliet?": "shakespeare",
"What is the chemical symbol for water?": "h2o",
"How many continents are there on Earth?": "7",
"What is the fastest land animal?": "cheetah",
"In what year did World War Two end?": "1945",
"What is the square root of 144?": "12",
"Which country invented pizza?": "italy",
"How many bones are in the adult human body?": "206",
"What is the longest river in the world?": "nile",
"Which planet is known as the Red Planet?": "mars",
"What language has the most native speakers in the world?": "mandarin",
"How many hours are in a week?": "168",
"What is the hardest natural substance on Earth?": "diamond",
"Which ocean is the largest?": "pacific",
"What is the currency of Japan?": "yen",
"How many strings does a standard guitar have?": "6",
"What is the powerhouse of the cell?": "mitochondria"
}
Notice all answers are stored in lowercase. This is intentional and connects to Step 4 where you will learn why.
Why use a dictionary here instead of two separate lists? Because a dictionary keeps the question and answer together as a pair. With two separate lists you would need to track the index manually to match question[0] with answer[0]. A dictionary makes the relationship explicit and the code much cleaner.
Step 3 — Display a Welcome Message
Every good program greets the user. Add a function called
show_welcome() that prints a welcome message when the game starts.
This is your first function in the project.
def show_welcome():
print("=" * 40)
print(" PYTHON ESSENTIALS QUIZ GAME")
print("=" * 40)
print("Answer all 20 questions.")
print("Type your answer and press Enter.")
print("Answers are not case sensitive.")
print("=" * 40)
The "=" * 40 is string multiplication — it prints 40 equals signs
in one line. A neat trick for creating simple borders in the console.
Call the function below it to test it runs:
show_welcome()
Run the file. You should see your welcome message in the console. Once it works, remove the test call — you will call it properly in Step 8.
Step 4 — Handle Player Input Cleanly
Player input is unpredictable. Someone might type Paris,
PARIS, or paris with a space. All of those should
be accepted as correct.
Python gives you two string methods to handle this:
.lower()— converts the string to lowercase.strip()— removes leading and trailing spaces
Chain them together on the player's input like this:
player_answer = input("Your answer: ").lower().strip()
Because your answers in the dictionary are already lowercase, comparing
player_answer to the dictionary value will work correctly
regardless of how the player typed their answer.
Why chain .lower() and .strip() directly on input()? Because input() returns a string and you can call string methods directly on it. Chaining them means you do not need to store the raw input in a separate variable first. It is cleaner and more Pythonic.
Step 5 — Build the Quiz Function
Now build the main function that runs the quiz. It takes the
questions dictionary as a parameter, iterates over it,
asks each question, checks the answer and keeps score.
def run_quiz(questions):
score = 0
question_number = 1
for question, answer in questions.items():
print(f"\nQuestion {question_number} of {len(questions)}:")
print(question)
player_answer = input("Your answer: ").lower().strip()
if player_answer == answer:
print("✓ Correct!")
score += 1
else:
print(f"✗ Wrong. The answer was: {answer.title()}")
question_number += 1
return score
Walk through this carefully:
score = 0— starts at zero, lives inside the function (local scope)questions.items()— gives you both the key and value on each iterationlen(questions)— tells the player how many questions there are totalscore += 1— increments score when the answer is correctanswer.title()— capitalises the answer nicely when showing the correct answerreturn score— sends the final score back to wherever the function was called
Why does score live inside the function? Because of scope. score is a local variable — it only exists inside run_quiz(). This is correct design. The function does its job, counts the score, and returns it. The calling code decides what to do with the result. Keeping score local means it resets cleanly every time the function is called — perfect for a replay feature.
Step 6 — Show the Final Score and Grade
Build a function that takes the score and total number of questions, calculates a percentage, assigns a grade, and displays the result.
def show_results(score, total):
percentage = (score / total) * 100
print("\n" + "=" * 40)
print(f" GAME OVER")
print(f" You scored {score} out of {total}")
print(f" Percentage: {percentage:.1f}%")
if percentage >= 90:
grade = "A — Excellent!"
elif percentage >= 70:
grade = "B — Good work!"
elif percentage >= 50:
grade = "C — Not bad."
elif percentage >= 30:
grade = "D — Keep practising."
else:
grade = "F — Better luck next time."
print(f" Grade: {grade}")
print("=" * 40)
Notice {percentage:.1f} — this formats the float to one decimal place.
So 75.0 displays as 75.0% instead of
75.00000000000001%.
Why pass score and total as parameters instead of using global variables? Because functions should receive the data they need through parameters, not reach out into the global scope to grab it. This makes show_results() reusable — you could call it from anywhere with any score and total. If it relied on global variables it would be tightly coupled to this specific program and much harder to reuse or test.
Step 7 — Add a Play Again Loop
Use a while True loop to let the player replay the game
without restarting the program. This is the classic use case for
while True — keep running until the player decides to stop.
def ask_play_again():
while True:
choice = input("\nPlay again? (yes / no): ").lower().strip()
if choice == "yes":
return True
elif choice == "no":
return False
else:
print("Please type yes or no.")
This function validates the input — if the player types anything other
than yes or no it keeps asking. This is input
validation using while True exactly as you practised in Module 6.
Step 8 — Connect Everything Together
Now build the main function that connects all the pieces. This is where your program actually runs.
def main():
show_welcome()
while True:
score = run_quiz(questions)
show_results(score, len(questions))
if not ask_play_again():
print("\nThanks for playing. Goodbye!")
break
main()
Walk through the logic:
show_welcome()— runs once at the start- The
while Trueloop keeps the game running run_quiz(questions)— runs the quiz and returns the scoreshow_results()— displays the final scoreask_play_again()— returnsTrueorFalseif not ask_play_again()— if the player says no, break out of the loopmain()— calling the function starts the entire program
Why wrap everything in a main() function? Convention and good practice. Putting your program logic inside a main() function means none of it runs automatically when the file is imported by another script. It also makes your code easier to read — anyone looking at your file can see immediately that main() is the entry point. This is how professional Python programs are structured.
The Complete Program
Here is the full quiz game with everything connected. Compare it carefully against what you have built step by step. They should match.
# Python Essentials - Final Project
# General Knowledge Quiz Game
questions = {
"What is the capital of France?": "paris",
"How many sides does a hexagon have?": "6",
"What is the largest planet in our solar system?": "jupiter",
"Who wrote Romeo and Juliet?": "shakespeare",
"What is the chemical symbol for water?": "h2o",
"How many continents are there on Earth?": "7",
"What is the fastest land animal?": "cheetah",
"In what year did World War Two end?": "1945",
"What is the square root of 144?": "12",
"Which country invented pizza?": "italy",
"How many bones are in the adult human body?": "206",
"What is the longest river in the world?": "nile",
"Which planet is known as the Red Planet?": "mars",
"What language has the most native speakers in the world?": "mandarin",
"How many hours are in a week?": "168",
"What is the hardest natural substance on Earth?": "diamond",
"Which ocean is the largest?": "pacific",
"What is the currency of Japan?": "yen",
"How many strings does a standard guitar have?": "6",
"What is the powerhouse of the cell?": "mitochondria"
}
def show_welcome():
print("=" * 40)
print(" PYTHON ESSENTIALS QUIZ GAME")
print("=" * 40)
print("Answer all 20 questions.")
print("Type your answer and press Enter.")
print("Answers are not case sensitive.")
print("=" * 40)
def run_quiz(questions):
score = 0
question_number = 1
for question, answer in questions.items():
print(f"\nQuestion {question_number} of {len(questions)}:")
print(question)
player_answer = input("Your answer: ").lower().strip()
if player_answer == answer:
print("✓ Correct!")
score += 1
else:
print(f"✗ Wrong. The answer was: {answer.title()}")
question_number += 1
return score
def show_results(score, total):
percentage = (score / total) * 100
print("\n" + "=" * 40)
print(f" GAME OVER")
print(f" You scored {score} out of {total}")
print(f" Percentage: {percentage:.1f}%")
if percentage >= 90:
grade = "A — Excellent!"
elif percentage >= 70:
grade = "B — Good work!"
elif percentage >= 50:
grade = "C — Not bad."
elif percentage >= 30:
grade = "D — Keep practising."
else:
grade = "F — Better luck next time."
print(f" Grade: {grade}")
print("=" * 40)
def ask_play_again():
while True:
choice = input("\nPlay again? (yes / no): ").lower().strip()
if choice == "yes":
return True
elif choice == "no":
return False
else:
print("Please type yes or no.")
def main():
show_welcome()
while True:
score = run_quiz(questions)
show_results(score, len(questions))
if not ask_play_again():
print("\nThanks for playing. Goodbye!")
break
main()
Challenges — Take It Further
If you want to push further, try these extensions on your own:
Challenge 1 — Shuffle the Questions
- Import the
randommodule at the top of your file:import random - Convert the dictionary to a list of tuples, shuffle it, and iterate over that instead:
import random
def run_quiz(questions):
score = 0
question_number = 1
question_list = list(questions.items())
random.shuffle(question_list)
for question, answer in question_list:
# rest of your code unchanged
Now the questions appear in a different order every game.
Challenge 2 — Ask for the Player's Name
- Before the quiz starts ask the player for their name using
input() - Use it in the welcome message and the results screen
- Pass the name as a parameter to
show_welcome()andshow_results()
Challenge 3 — Track the High Score
- Create a variable
high_score = 0in the global scope - After each game compare the score to the high score
- Use the
globalkeyword inside a function to update it - Display the high score on the results screen
- This directly practices what you learned about the
globalkeyword in Module 7
Challenge 4 — Add Your Own Questions
- Replace any of the 20 questions with your own
- Add questions about Python itself — what better way to test what you learned?
What You Just Demonstrated
By completing this project you have shown you can:
- Structure a program using multiple functions
- Use a dictionary as a real data store
- Iterate over a dictionary with
.items() - Handle and validate user input
- Use
while Truewithbreakfor game loops - Return values from functions and use them elsewhere
- Apply scope correctly — local variables inside functions, global data outside
- Format output clearly using f-strings
- Build a complete working program from scratch
That is not a beginner skill set anymore.
🎓 Congratulations
You have completed Python Essentials. You started with variables and data types and you finished by building a complete console application using dictionaries, functions, loops, conditionals, scope, and string manipulation.
Python is a language you learn by building things. You have proven you can do that. The best next step is to keep building — something slightly harder than what you just finished. That is how developers grow.
Well done. Now go build something.
Don't Forget to commit and Push!