Build a Quiz Generator with Gemini
Use the Gemini API to build a Python CLI quiz app with structured JSON output.
Introduction
30 Second Summary
Quizzes are one of the best ways to test your knowledge on a topic. But creating good quiz questions takes time, and finding quizzes tailored to exactly what you want to learn is even harder.
In this project, you will build a command-line quiz generator powered by Google's Gemini AI. You type in any topic, and the app generates a multiple-choice quiz, scores your answers, and explains anything you got wrong.
What You'll Build
A Python CLI application that calls the Gemini API to generate structured quiz questions, presents them interactively, and streams AI explanations for incorrect answers.
By the end of this project, you'll have:
- A working Python script (quiz.py) that sends prompts to the Gemini API and receives structured JSON output.
- An interactive command-line quiz that presents questions one at a time and scores your answers in real time.
- Streaming AI-generated explanations that help you learn from mistakes as the text appears character by character.
- Secret Mission: Add difficulty levels and a study mode that generates follow-up questions on topics you got wrong.
Are there any prerequisites?
You should be comfortable with basic Python concepts like variables, functions, loops, and f-strings. No prior AI or API experience is needed.
Before We Start
Before We Start...
Set Up Python and Get Your Gemini API Key
Before you can build an AI-powered quiz app, you need two things: Python to run your code, and an API key to communicate with Google's Gemini model.
In this step, you'll install Python, create an isolated project environment, and grab a free API key from Google AI Studio.
In this step, get ready to:
- Install and verify Python 3.9+.
- Create a project folder with a virtual environment.
- Get a free Gemini API key and set it as an environment variable.
Check your Python installation
This project requires Python 3.9 or higher. Let's check if you already have it installed.
- Press Cmd+Space (macOS) or the Windows key (Windows) to open your search bar.
- Type Terminal (macOS) or Command Prompt (Windows) and press Enter to open it.
- Check your Python version by running:
macOS
python3 --version
Windows
python --version
✔️ I see version 3.9 or higher
You're all set. Move on to the next substep below.
ⓧ I see an older version
You need to upgrade to Python 3.9 or higher.
- Visit python.org/downloads and download the latest Python installer for your operating system.
- Run the installer. On Windows, make sure to check Add Python to PATH before clicking Install Now.
- Close your terminal and open a new one, then run the version check command again to confirm.
macOS users with an older system Python
macOS may ship with an older Python. After installing a newer version from python.org, use python3 --version to verify the new version is available. The installer adds the newer Python alongside the system default.
ⓧ Command not found
Python is not installed yet. Let's fix that.
- Visit python.org/downloads and download the latest Python installer for your operating system.
- Run the installer. On Windows, make sure to check Add Python to PATH before clicking Install Now.
- Close your terminal and open a new one, then run the version check command again to confirm Python is installed.
Still seeing command not found?
On macOS, try python3 --version instead. On Windows, try restarting your computer after the install so the PATH update takes effect.
help me install Python on my computer
Create your project folder and virtual environment
A virtual environment keeps your project's packages separate from other Python projects on your machine. This prevents version conflicts between projects.
- Move to your Desktop by running this command:
cd ~/Desktop
- Create your project folder and move into it by running these commands:
mkdir quiz-generator
cd quiz-generator
- Confirm the folder exists by running:
ls
You should see an empty output since the folder is brand new.
- Create and activate your virtual environment by running:
macOS
python3 -m venv venv
source venv/bin/activate
Windows
python -m venv venv
venv\Scripts\activate
What does this do?
python3 -m venv venv creates a new virtual environment in a folder called venv. The activation command tells your terminal to use this environment's Python and packages instead of the system-wide ones.
You should see (venv) appear at the beginning of your terminal prompt. This confirms the virtual environment is active.
Don't see (venv) in your prompt?
On Windows, if you get an error about execution policies, run this command first:
Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned
Then try the activation command again. On macOS, make sure you used source before the path.
help me activate my Python virtual environment
Get your free Gemini API key
An API key is like a password that lets your Python script talk to Google's Gemini model. Google AI Studio provides free API keys with no credit card required.
- Open aistudio.google.com in your browser.
- Sign in with your Google account.
- Click Get API Key in the left sidebar.
- Click Create API Key.
- Copy the generated key. You will only see the full key once, so keep it somewhere safe.
Why is this free?
Google AI Studio offers a free tier for the Gemini API that does not require a credit card. The free tier includes generous rate limits that are more than enough for this project.
Now set the API key as an environment variable so your script can use it.
- In the same terminal where your virtual environment is active, set the environment variable by running:
macOS
export GEMINI_API_KEY="your-api-key-here"
Windows
$env:GEMINI_API_KEY="your-api-key-here"
- Replace your-api-key-here with the key you just copied from Google AI Studio.
What does this do?
Setting GEMINI_API_KEY as an environment variable keeps your key out of your source code. The Gemini SDK automatically reads this variable when it initializes, so you never need to paste the key directly into your Python script.
This variable only lasts for the current terminal session. If you close and reopen your terminal, you will need to set it again.
Keep your API key safe
Never share your API key publicly or commit it to a Git repository. Treat it like a password.
Not sure if the variable is set?
Run echo $GEMINI_API_KEY (macOS) or echo $env:GEMINI_API_KEY (Windows PowerShell). You should see the key you pasted printed in your terminal.
help me set my Gemini API key as an environment variable
Your environment is ready. You have Python, a clean virtual environment, and an API key connected to Gemini. Next up, you'll install the Gemini SDK and make your very first API call.
Install the SDK and Make Your First API Call
Your Python environment is ready and your API key is set. Now it's time to connect your project to Gemini, Google's AI model that will power your quiz generator.
In this step, you'll install the official Google GenAI SDK, write a short Python script, and see your first AI-generated response appear in the terminal.
In this step, get ready to:
- Install the Google GenAI SDK.
- Write a script that sends a prompt to Gemini and prints the response.
- Explore system instructions to shape the AI's behavior.
Install the Google GenAI SDK
The Google GenAI SDK is the official Python library for talking to Gemini. It handles authentication, request formatting, and response parsing for you.
- Install the SDK by running this command in your terminal (make sure your virtual environment is still active):
pip install google-genai
What does this command do?
pip install google-genai downloads the Google GenAI SDK from PyPI and installs it into your virtual environment. This gives your Python scripts access to the genai module for making API calls to Gemini.
- You should see output ending with a line that says Successfully installed followed by package names.
Seeing an error during install?
- If you see pip: command not found, your virtual environment might not be activated. Run the activate command from Step 1 again.
- If you see a permissions error, make sure you're inside the virtual environment. You should NOT need sudo.
- If you see a network error, check your internet connection and try again.
Still stuck? Help me troubleshoot my pip install google-genai error
Write your first API call
With the SDK installed, you can now write a Python script that sends a prompt to Gemini and prints the response. This is the foundation of your quiz generator.
- Create a new file called quiz.py in your quiz-generator folder.
- Add the following imports and client initialization to quiz.py:
import json
import os
from google import genai
from google.genai import types
# Initialize the Gemini client
client = genai.Client()
What does this code do?
- json and os are standard Python libraries you'll use later for parsing responses and reading environment variables.
- from google import genai imports the main SDK module.
- from google.genai import types gives you access to configuration objects like GenerateContentConfig.
- genai.Client() creates a client that automatically reads your GEMINI_API_KEY environment variable for authentication.
Now add the code that actually calls the Gemini API.
- Below the client initialization line, add this API call to quiz.py:
response = client.models.generate_content(
model="gemini-2.5-flash",
contents="Tell me a fun fact about space.",
config=types.GenerateContentConfig(
system_instruction="You are a helpful assistant.",
),
)
print(response.text)
What does this code do?
- client.models.generate_content() sends a request to the Gemini API and returns the model's response.
- model="gemini-2.5-flash" specifies which Gemini model to use. Flash is fast and free.
- contents is the prompt you're sending to the model.
- system_instruction tells the model how to behave before it sees your prompt. Think of it as setting the AI's personality.
- response.text extracts just the text content from the model's response.
- Save quiz.py.
- Run your script by executing this command:
python quiz.py
- You should see a fun fact about space printed in your terminal. The exact response will be different each time since the AI generates it dynamically.
Seeing an error instead of a fun fact?
- If you see a message about an invalid API key, double-check that your GEMINI_API_KEY environment variable is set correctly in this terminal session.
- If you see ModuleNotFoundError: No module named 'google', your virtual environment might not be active. Activate it and try again.
- If you see a timeout or connection error, check your internet connection.
Help me debug my Gemini API call error
✔️ Awesome, I've got everything!
Great. Double check you've saved quiz.py and confirmed a response prints in your terminal.
ⓧ I'd like to double check the full code
import json
import os
from google import genai
from google.genai import types
# Initialize the Gemini client
client = genai.Client()
response = client.models.generate_content(
model="gemini-2.5-flash",
contents="Tell me a fun fact about space.",
config=types.GenerateContentConfig(
system_instruction="You are a helpful assistant.",
),
)
print(response.text)
Experiment with the system_instruction parameter
The system_instruction parameter is one of the most powerful tools in prompt engineering. It shapes how the model responds to every prompt, without the user ever seeing it.
What is a system instruction?
A system instruction is a hidden directive that runs before any user prompt. It sets the model's tone, expertise, and output rules.
For example, "You are a helpful assistant" produces neutral, informative answers. But "You are a pirate captain" would make every response sound like it came from the high seas. In later steps, you'll use system instructions to force the model to output structured JSON quiz data.
- Try changing the system_instruction value in quiz.py to something like "You are a stand-up comedian. Make everything funny." and run python quiz.py again.
- Notice how the response changes in tone while still answering the same question.
- When you're done experimenting, set the system_instruction back to "You are a helpful assistant." and save quiz.py.
You've made your first successful API call to Gemini. Next up, you'll use a carefully crafted system instruction to make Gemini output quiz questions as structured JSON data.
Generate Quiz Questions as Structured JSON
Your script can talk to Gemini, but right now it gets free-form text back. For a quiz app, you need the AI to return data in a predictable structure that your Python code can parse and work with.
In this step, you'll design system prompts that instruct Gemini to output quiz questions as structured JSON. You'll also use a config option that forces the model to return valid JSON every time.
In this step, get ready to:
- Design system prompts that control Gemini's output format.
- Build a function that generates quiz questions as structured JSON.
- Test the function and verify the JSON contains expected fields.
Replace your test code with system prompts
System instructions are persistent rules the model follows for every response. By writing a detailed system prompt, you tell Gemini exactly what JSON structure to produce.
- In quiz.py, find the test code you wrote in the previous step (everything below client = genai.Client()):
response = client.models.generate_content(
model="gemini-2.5-flash",
contents="Tell me a fun fact about space.",
config=types.GenerateContentConfig(
system_instruction="You are a helpful assistant.",
),
)
print(response.text)
- Delete all of this code and replace it with the following system prompts:
QUIZ_SYSTEM_PROMPT = """You are a quiz generator. When given a topic, generate exactly 5 multiple-choice questions.
Output your response as a JSON array with this exact structure:
[
{
"question": "The question text",
"options": ["A) First option", "B) Second option", "C) Third option", "D) Fourth option"],
"correct": "A",
"topic_hint": "Brief topic area this question covers"
}
]
Rules:
- Always provide exactly 4 options labeled A, B, C, D
- The "correct" field must be just the letter (A, B, C, or D)
- Questions should be clear and unambiguous
- Only output the JSON array, nothing else"""
EXPLANATION_SYSTEM_PROMPT = """You are a helpful tutor. The student got a quiz question wrong.
Explain why the correct answer is right in 2-3 sentences. Be encouraging and educational."""
What do these prompts do?
QUIZ_SYSTEM_PROMPT tells Gemini to act as a quiz generator. It defines the exact JSON structure you expect, including the fields question, options, correct, and topic_hint.
EXPLANATION_SYSTEM_PROMPT is for a later feature where Gemini explains correct answers when the user gets a question wrong. You're defining it now so both prompts live together at the top of the file.
- Save quiz.py.
You won't see any output yet. The next substep builds a function that uses these prompts.
Build the quiz generation function
Now you need a function that sends a topic to Gemini and gets back structured quiz questions. The key ingredient is response_mime_type, which forces the model to return valid JSON instead of free-form text.
- Below EXPLANATION_SYSTEM_PROMPT, add the following function:
def generate_quiz(topic):
"""Generate quiz questions on the given topic using Gemini."""
response = client.models.generate_content(
model="gemini-2.5-flash",
contents=f"Generate a quiz about: {topic}",
config=types.GenerateContentConfig(
system_instruction=QUIZ_SYSTEM_PROMPT,
response_mime_type="application/json",
),
)
questions = json.loads(response.text)
return questions
What does this function do?
- system_instruction=QUIZ_SYSTEM_PROMPT passes your detailed formatting rules to the model as persistent instructions.
- response_mime_type="application/json" tells the Gemini API to enforce valid JSON output. The model will always return parseable JSON, not free-form text.
- json.loads(response.text) converts the JSON string into a Python list of dictionaries you can loop through.
- To test your function, temporarily add these two lines at the very bottom of quiz.py:
# Temporary test - remove after verifying
questions = generate_quiz("Python basics")
print(json.dumps(questions, indent=2))
- Save quiz.py and run your script:
python quiz.py
You should see a JSON array printed in your terminal with 5 quiz questions about Python basics. Each question object has question, options, correct, and topic_hint fields.
- Once you've confirmed the JSON output looks correct, delete the three temporary test lines you just added (the comment, the generate_quiz call, and the print statement).
- Save quiz.py again.
Not seeing JSON output?
- If you see a JSONDecodeError, make sure you included response_mime_type="application/json" in your config. Without it, the model may return text that isn't valid JSON.
- If you see an authentication error, confirm your GEMINI_API_KEY environment variable is still set in this terminal session.
- If the output has fewer than 5 questions, your system prompt may have a typo. Double check that QUIZ_SYSTEM_PROMPT says "generate exactly 5 multiple-choice questions".
Help me debug my quiz generation function
✔️ Awesome, I've got everything!
Great. Double check you've saved your file after removing the test lines.
ⓧ I'd like to double check the full code
Here's what your complete quiz.py should look like at this point:
import json
import os
from google import genai
from google.genai import types
# Initialize the Gemini client
client = genai.Client()
QUIZ_SYSTEM_PROMPT = """You are a quiz generator. When given a topic, generate exactly 5 multiple-choice questions.
Output your response as a JSON array with this exact structure:
[
{
"question": "The question text",
"options": ["A) First option", "B) Second option", "C) Third option", "D) Fourth option"],
"correct": "A",
"topic_hint": "Brief topic area this question covers"
}
]
Rules:
- Always provide exactly 4 options labeled A, B, C, D
- The "correct" field must be just the letter (A, B, C, or D)
- Questions should be clear and unambiguous
- Only output the JSON array, nothing else"""
EXPLANATION_SYSTEM_PROMPT = """You are a helpful tutor. The student got a quiz question wrong.
Explain why the correct answer is right in 2-3 sentences. Be encouraging and educational."""
def generate_quiz(topic):
"""Generate quiz questions on the given topic using Gemini."""
response = client.models.generate_content(
model="gemini-2.5-flash",
contents=f"Generate a quiz about: {topic}",
config=types.GenerateContentConfig(
system_instruction=QUIZ_SYSTEM_PROMPT,
response_mime_type="application/json",
),
)
questions = json.loads(response.text)
return questions
Your quiz generator can now produce structured data on any topic. Next up, you'll build an interactive loop that presents these questions to the user one by one and tracks their score.
Build the Interactive Quiz Loop
Your app can now generate quiz questions on any topic using the Gemini API. The raw JSON data is ready, but there's no way for a user to actually take the quiz.
In this step, you'll build the interactive quiz loop that ties everything together. It will ask the user for a topic, present questions one at a time, validate their answers, and give them a final score.
In this step, get ready to:
- Create the quiz flow that prompts for a topic and generates questions.
- Present questions one by one with answer validation.
- Display a final score summary with performance feedback.
Create the main quiz flow
The run_quiz() function is the entry point for your entire app. It greets the user, asks for a topic, validates their input, and kicks off the quiz generation.
- In quiz.py, add the following function below your generate_quiz function:
def run_quiz():
"""Main quiz loop."""
print("\n=== AI Quiz Generator ===\n")
topic = input("Enter a topic for your quiz: ").strip()
if not topic:
print("Please enter a topic!")
return
print(f"\nGenerating quiz about '{topic}'...\n")
questions = generate_quiz(topic)
score = 0
total = len(questions)
wrong_answers = []
What does this code do?
- print("\n=== AI Quiz Generator ===\n") displays a banner so the user knows the app has started.
- input().strip() asks the user for a topic and removes any accidental whitespace from their answer.
- The if not topic check catches empty input and exits early with a helpful message.
- score, total, and wrong_answers set up the tracking variables you'll use throughout the quiz.
You won't see a change yet. The next chunk adds the question loop that uses these variables.
Present questions and accept answers
Now you need a loop that presents each question, waits for the user to pick an answer, and checks whether they got it right. The loop also validates that the user enters only A, B, C, or D.
- Still inside the run_quiz() function, add the following code below wrong_answers = []:
for i, q in enumerate(questions, 1):
print(f"Question {i}/{total}: {q['question']}")
for option in q["options"]:
print(f" {option}")
while True:
answer = input("\nYour answer (A/B/C/D): ").strip().upper()
if answer in ["A", "B", "C", "D"]:
break
print("Please enter A, B, C, or D.")
correct = q["correct"]
if answer == correct:
print(" Correct!\n")
score += 1
else:
print(f" Wrong! The correct answer is {correct}.")
wrong_answers.append(q)
What does this code do?
This loop handles the core quiz interaction:
- enumerate(questions, 1) loops through questions with a counter starting at 1, so the user sees "Question 1/5", "Question 2/5", etc.
- The inner for option loop prints each answer choice indented for readability.
- The while True block keeps asking until the user enters a valid letter. .strip().upper() cleans up their input so lowercase answers still work.
- If the answer is wrong, the question gets appended to wrong_answers for later use.
You won't see a change yet. The next chunk adds the score summary and makes the script runnable.
Display the final score and run the quiz
After all questions are answered, the user needs to see how they did. You'll also add the standard Python entry point so the script runs when executed directly.
- Still inside run_quiz(), add the score summary below the for loop (at the same indentation level as the for line):
print("=" * 40)
print(f"\nFinal Score: {score}/{total}")
if score == total:
print("Perfect score! Amazing work!")
elif score >= total * 0.6:
print("Good job! Keep studying to improve.")
else:
print("Keep practicing! You'll get there.")
print()
What does this code do?
- print("=" * 40) draws a separator line to visually mark the end of the quiz.
- The if/elif/else chain picks a performance message based on the score. Scoring 60% or higher counts as a passing result.
- print() at the end adds a blank line so the terminal prompt doesn't crowd the output.
- Now add the entry point at the very bottom of quiz.py, outside and below the run_quiz() function (no indentation):
if __name__ == "__main__":
run_quiz()
What is __name__ == "__main__"?
This is a standard Python pattern. It means "only run this code if the script is executed directly." If you ever import quiz.py from another file, the quiz won't start automatically.
- Save quiz.py.
- Run the quiz by executing this command in your terminal:
python quiz.py
You should see the === AI Quiz Generator === banner, followed by a prompt asking for a topic. Type any topic (like Python basics) and press Enter. After a short wait, questions appear one at a time.
Quiz not running?
- If you see IndentationError: make sure the score summary code is indented at the same level as the for loop (one level inside run_quiz). The if __name__ block should have zero indentation.
- If you see NameError: name 'generate_quiz' is not defined: confirm that run_quiz() is defined below generate_quiz() in your file. Python reads top to bottom.
- If the quiz generates but answers are never accepted: check that the while True block is indented inside the for loop.
Still stuck? Help me debug why my quiz.py won't run or accept answers.
✔️ 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 what your complete quiz.py should look like at this point:
import json
import os
from google import genai
from google.genai import types
# Initialize the Gemini client
client = genai.Client()
QUIZ_SYSTEM_PROMPT = """You are a quiz generator. When given a topic, generate exactly 5 multiple-choice questions.
Output your response as a JSON array with this exact structure:
[
{
"question": "The question text",
"options": ["A) First option", "B) Second option", "C) Third option", "D) Fourth option"],
"correct": "A",
"topic_hint": "Brief topic area this question covers"
}
]
Rules:
- Always provide exactly 4 options labeled A, B, C, D
- The "correct" field must be just the letter (A, B, C, or D)
- Questions should be clear and unambiguous
- Only output the JSON array, nothing else"""
EXPLANATION_SYSTEM_PROMPT = """You are a helpful tutor. The student got a quiz question wrong.
Explain why the correct answer is right in 2-3 sentences. Be encouraging and educational."""
def generate_quiz(topic):
"""Generate quiz questions on the given topic using Gemini."""
response = client.models.generate_content(
model="gemini-2.5-flash",
contents=f"Generate a quiz about: {topic}",
config=types.GenerateContentConfig(
system_instruction=QUIZ_SYSTEM_PROMPT,
response_mime_type="application/json",
),
)
questions = json.loads(response.text)
return questions
def run_quiz():
"""Main quiz loop."""
print("\n=== AI Quiz Generator ===\n")
topic = input("Enter a topic for your quiz: ").strip()
if not topic:
print("Please enter a topic!")
return
print(f"\nGenerating quiz about '{topic}'...\n")
questions = generate_quiz(topic)
score = 0
total = len(questions)
wrong_answers = []
for i, q in enumerate(questions, 1):
print(f"Question {i}/{total}: {q['question']}")
for option in q["options"]:
print(f" {option}")
while True:
answer = input("\nYour answer (A/B/C/D): ").strip().upper()
if answer in ["A", "B", "C", "D"]:
break
print("Please enter A, B, C, or D.")
correct = q["correct"]
if answer == correct:
print(" Correct!\n")
score += 1
else:
print(f" Wrong! The correct answer is {correct}.")
wrong_answers.append(q)
print("=" * 40)
print(f"\nFinal Score: {score}/{total}")
if score == total:
print("Perfect score! Amazing work!")
elif score >= total * 0.6:
print("Good job! Keep studying to improve.")
else:
print("Keep practicing! You'll get there.")
print()
if __name__ == "__main__":
run_quiz()
Your interactive quiz is fully functional. Next up, you'll add streaming AI explanations that teach the user why they got an answer wrong.
Add Streaming Explanations for Wrong Answers
Your quiz already tells the user when they're wrong and reveals the correct answer. That's helpful, but it doesn't explain why the correct answer is right.
In this step, you'll use Gemini's streaming API to generate real-time explanations that print character by character. This gives the quiz a polished, responsive feel instead of making the user wait for the full response.
In this step, get ready to:
- Write a streaming function that explains why the correct answer is right.
- Connect the explanation function to your quiz loop.
- Run the complete quiz and see streaming explanations plus a final score summary.
Write the streaming explanation function
When a user gets an answer wrong, you want Gemini to explain the correct answer in real time. The streaming approach prints each chunk of text as it arrives from the API, so the user sees the explanation build up live instead of waiting for the entire response.
- In quiz.py, find the run_quiz() function definition.
- Add the following stream_explanation function directly above run_quiz(), after the generate_quiz function:
def stream_explanation(question, user_answer, correct_answer):
"""Stream an explanation for why the correct answer is right."""
prompt = (
f"Question: {question['question']}\n"
f"The student chose: {user_answer}) "
f"{next(opt for opt in question['options'] if opt.startswith(user_answer))}\n"
f"The correct answer is: {correct_answer}) "
f"{next(opt for opt in question['options'] if opt.startswith(correct_answer))}\n"
f"Explain why the correct answer is right."
)
print("\n Explanation: ", end="", flush=True)
response = client.models.generate_content_stream(
model="gemini-2.5-flash",
contents=prompt,
config=types.GenerateContentConfig(
system_instruction=EXPLANATION_SYSTEM_PROMPT,
),
)
for chunk in response:
if chunk.text:
print(chunk.text, end="", flush=True)
print("\n")
What does this code do?
The function builds a detailed prompt that gives Gemini context about what the user got wrong. It includes both the user's chosen answer and the correct answer with their full option text.
The key difference from generate_content is generate_content_stream. Instead of waiting for the full response, this method yields chunks as they arrive. The for chunk in response loop prints each piece of text immediately with flush=True to force the output to appear right away.
- Save quiz.py.
Seeing a syntax error?
Make sure the f-string lines inside the prompt variable are all wrapped in parentheses. Python uses the parentheses to continue the string across multiple lines.
Also check that the next(opt for opt in ...) expressions have matching parentheses.
help me fix a syntax error in my stream_explanation function
Connect the explanation to your quiz loop
The function exists, but run_quiz() doesn't call it yet. You need to add one line so that every wrong answer triggers a streaming explanation.
- In quiz.py, scroll down to the run_quiz() function and find the else branch where the wrong answer message is printed.
- Find this code:
else:
print(f" Wrong! The correct answer is {correct}.")
wrong_answers.append(q)
- Add a call to stream_explanation(q, answer, correct) between the print statement and the wrong_answers.append(q) line, so it looks like this:
else:
print(f" Wrong! The correct answer is {correct}.")
stream_explanation(q, answer, correct)
wrong_answers.append(q)
- Save quiz.py.
Run the complete quiz
Everything is wired up. Time to run the full quiz and see the streaming explanations in action alongside the final score summary.
- Run your quiz by executing this command:
python quiz.py
- Enter a topic when prompted.
- Answer at least one question incorrectly on purpose to trigger the streaming explanation.
You should see the explanation text appear character by character after each wrong answer. At the end, your final score prints with a performance message.
What should I see?
After answering incorrectly, you'll see something like:
Wrong! The correct answer is B.
Explanation: The correct answer is B because... [text streams in real time]
At the end of all 5 questions, a score summary prints:
========================================
Final Score: 3/5
Good job! Keep studying to improve.
Explanation not streaming?
If the explanation appears all at once instead of streaming, make sure you used generate_content_stream (not generate_content). Also confirm that flush=True is set in your print call.
If you see a NameError for stream_explanation, make sure the function is defined above run_quiz() in the file. Python reads top to bottom, so it must be defined before it's called.
help me debug why my streaming explanation isn't working
✔️ Awesome, I've got everything!
Great. Double check you've saved quiz.py and your quiz runs with streaming explanations appearing for wrong answers.
ⓧ I'd like to double check the full code
Here is the complete quiz.py file. Compare it against yours:
import json
import os
from google import genai
from google.genai import types
# Initialize the Gemini client
client = genai.Client()
QUIZ_SYSTEM_PROMPT = """You are a quiz generator. When given a topic, generate exactly 5 multiple-choice questions.
Output your response as a JSON array with this exact structure:
[
{
"question": "The question text",
"options": ["A) First option", "B) Second option", "C) Third option", "D) Fourth option"],
"correct": "A",
"topic_hint": "Brief topic area this question covers"
}
]
Rules:
- Always provide exactly 4 options labeled A, B, C, D
- The "correct" field must be just the letter (A, B, C, or D)
- Questions should be clear and unambiguous
- Only output the JSON array, nothing else"""
EXPLANATION_SYSTEM_PROMPT = """You are a helpful tutor. The student got a quiz question wrong.
Explain why the correct answer is right in 2-3 sentences. Be encouraging and educational."""
def generate_quiz(topic):
"""Generate quiz questions on the given topic using Gemini."""
response = client.models.generate_content(
model="gemini-2.5-flash",
contents=f"Generate a quiz about: {topic}",
config=types.GenerateContentConfig(
system_instruction=QUIZ_SYSTEM_PROMPT,
response_mime_type="application/json",
),
)
questions = json.loads(response.text)
return questions
def stream_explanation(question, user_answer, correct_answer):
"""Stream an explanation for why the correct answer is right."""
prompt = (
f"Question: {question['question']}\n"
f"The student chose: {user_answer}) "
f"{next(opt for opt in question['options'] if opt.startswith(user_answer))}\n"
f"The correct answer is: {correct_answer}) "
f"{next(opt for opt in question['options'] if opt.startswith(correct_answer))}\n"
f"Explain why the correct answer is right."
)
print("\n Explanation: ", end="", flush=True)
response = client.models.generate_content_stream(
model="gemini-2.5-flash",
contents=prompt,
config=types.GenerateContentConfig(
system_instruction=EXPLANATION_SYSTEM_PROMPT,
),
)
for chunk in response:
if chunk.text:
print(chunk.text, end="", flush=True)
print("\n")
def run_quiz():
"""Main quiz loop."""
print("\n=== AI Quiz Generator ===\n")
topic = input("Enter a topic for your quiz: ").strip()
if not topic:
print("Please enter a topic!")
return
print(f"\nGenerating quiz about '{topic}'...\n")
questions = generate_quiz(topic)
score = 0
total = len(questions)
wrong_answers = []
for i, q in enumerate(questions, 1):
print(f"Question {i}/{total}: {q['question']}")
for option in q["options"]:
print(f" {option}")
while True:
answer = input("\nYour answer (A/B/C/D): ").strip().upper()
if answer in ["A", "B", "C", "D"]:
break
print("Please enter A, B, C, or D.")
correct = q["correct"]
if answer == correct:
print(" Correct!\n")
score += 1
else:
print(f" Wrong! The correct answer is {correct}.")
stream_explanation(q, answer, correct)
wrong_answers.append(q)
print("=" * 40)
print(f"\nFinal Score: {score}/{total}")
if score == total:
print("Perfect score! Amazing work!")
elif score >= total * 0.6:
print("Good job! Keep studying to improve.")
else:
print("Keep practicing! You'll get there.")
print()
if __name__ == "__main__":
run_quiz()
Secret mission
Add Difficulty Levels and Study Mode
Your quiz generator works great, but every quiz has the same difficulty. What if you could let users choose how hard the questions are? And what if the app could learn from their mistakes and quiz them again on their weak spots?
Clean Up Your Resources
Clean Up Your Resources
This project runs entirely locally and uses the Gemini API free tier, so there are no ongoing costs. Decide whether to keep your resources available, pause them, or delete them entirely.
Resources you used:
- Project folder containing quiz.py and the virtual environment.
- Python virtual environment (venv folder) with the google-genai package installed.
- Gemini API key stored in Google AI Studio.
- GEMINI_API_KEY environment variable in your terminal session.
Keep everything running
No action needed. Choose this if you plan to keep building on this project or experimenting with the Gemini API.
- Your project folder stays on your Desktop.
- Your virtual environment stays ready to activate with source venv/bin/activate (macOS/Linux) or venv\Scripts\activate (Windows).
- Your API key remains active in Google AI Studio at no cost.
- The GEMINI_API_KEY environment variable persists only in your current terminal session. If you close the terminal, you will need to export it again next time.
Pause - I'll come back to this later
Free up terminal resources while keeping your files intact for later.
- Deactivate your virtual environment by running:
- Close your terminal window. This clears the GEMINI_API_KEY environment variable from memory.
- Your project folder and API key in Google AI Studio remain untouched for next time.
deactivate
Delete - I don't want to use this again
Remove all project resources and revoke your API key.
- Delete your project folder by running one of these commands:
macOS
rm -rf ~/Desktop/quiz-generator
Windows
Remove-Item -Recurse -Force ~\Desktop\quiz-generator
- Delete your Gemini API key from Google AI Studio.
- Open the Google AI Studio API Keys page at aistudio.google.com/apikey.
- Find the API key you created for this project.
- Click the trash icon next to the key to delete it.
- Close your terminal to clear the GEMINI_API_KEY environment variable from memory.
Nice Work!
Nice Work!
You just built an AI-powered quiz generator from scratch. Give yourself any topic, and your app calls Gemini to generate questions, scores your answers, and streams explanations in real time.
You've learned how to:
- Called the Gemini API with system instructions to control how an LLM responds.
- Enforced structured JSON output from the model and parsed it into Python data structures.
- Built an interactive CLI with streaming responses that display AI-generated explanations character by character.
- Secret Mission: Added difficulty levels, a study mode for weak areas, CLI arguments, and quiz history saved to a JSON file.
Ready to quiz yourself?