Build an AI English Teacher with Python
Build a voice-powered AI English teacher that corrects your grammar in real time.
Introduction
30 Second Summary
Learning a new language is hard when you have no one to practice with. Most language apps test your reading and writing, but they skip the scariest part: actually speaking out loud.
In this project, you will build a Python app that acts as your personal AI English teacher. You speak into your microphone, the teacher listens, corrects your grammar, and talks back to you through your speakers.
What You'll Build
Picture speaking a sentence into your microphone and hearing a patient AI teacher respond aloud, correcting your grammar and asking a follow-up question to keep the conversation going.
By the end of this project, you'll have:
- A voice-powered conversation loop where you speak naturally into your microphone and the teacher responds aloud with corrections and encouragement.
- A real AI English teacher powered by Google's Gemini that catches grammar mistakes, suggests better phrasing, and keeps the conversation flowing.
- A progress report that tracks your grammar corrections throughout the session and shows your accuracy rate when you say goodbye.
- Secret Mission: Add conversation topics and difficulty levels so the teacher adapts to your skill level.
Do I need any special equipment?
You need a working microphone and speakers (or headphones) connected to your computer. Built-in laptop hardware works fine. This guide covers setup for everything else.
Before We Start
Before we dive in, let's lock in what you're about to build and why it matters to you.
Set Up Your Tools and API Key
Before you can build your AI English teacher, you need a way to communicate with Google's Gemini AI and the libraries that handle voice. Getting these out of the way now means every step after this produces something you can see and hear.
You will grab a free API key from Google AI Studio, then install four Python libraries that power speech recognition, text-to-speech, and AI communication.
In this step, get ready to:
- Get a free Gemini API key from Google AI Studio.
- Install four Python libraries for speech, voice, and AI.
- Verify everything works with a single import test.
Get your Gemini API key
Google's Gemini AI will be the brain behind your English teacher. To connect your Python app to Gemini, you need an API key. An API key is a unique code that lets your app talk to Google's servers.
- Open your browser and go to accounts.google.com.
- Create a free Google account, or sign in if you already have one.
- Go to aistudio.google.com and sign in with your Google account.
Google AI Studio automatically creates a default project and API key for new users after you accept the Terms of Service. Your key should already be waiting for you.
- Go to aistudio.google.com/app/apikey to open the API keys page directly.
- You should see an API key listed on the page. Copy it and paste it somewhere safe, like a temporary text file on your Desktop. You will paste this into your code in the next step.
What is an API key?
An API key works like a password for your app. It proves to Google's servers that your code is authorized to use the Gemini API.
The Gemini API free tier does not charge for input or output tokens. You can use it throughout this entire project at no cost.
Keep your API key private
Never share your API key publicly or commit it to a public repository. Treat it like a password. If someone else gets your key, they can make API calls on your behalf.
Install the Python libraries
Your English teacher needs four Python libraries to function. Each one handles a different part of the conversation flow.
- In VS Code, open the terminal by pressing Ctrl+` (backtick key).
- Install all four libraries by running this command:
pip install SpeechRecognition PyAudio pyttsx3 google-genai
You should see download progress bars and "Successfully installed" messages for each package.
What do these libraries do?
- SpeechRecognition captures audio from your microphone and converts it to text using Google's free speech recognition service.
- PyAudio provides the low-level microphone access that SpeechRecognition depends on.
- pyttsx3 converts text into spoken audio using your computer's built-in voice engine. It works completely offline with no API key needed.
- google-genai is Google's official SDK for connecting to the Gemini API.
Seeing a PyAudio error?
PyAudio includes prebuilt wheels for 64-bit Python 3.10 on Windows, so it should install without issues. If you see an error about building wheels or missing tools, you may have 32-bit Python installed.
help me fix a PyAudio installation error on Windows
Verify your setup
All four libraries are installed. Now you will run one command that imports every library at once to confirm nothing is missing.
Before you run this, what do you think will happen if one of the libraries failed to install?
- Verify everything works by running this command in your terminal:
python -c "import speech_recognition; import pyttsx3; from google import genai; print('All libraries installed!')"
If everything installed correctly, you see All libraries installed! printed with no errors. If any library is missing, Python throws an ImportError naming the exact package that failed.
Seeing an ImportError?
The error message tells you exactly which library is missing. Reinstall just that library by running pip install followed by the package name, then run the import test again.
help me fix an ImportError when verifying my Python library installations
Your tools are ready and your API key is saved. Next up, you will create the English teacher script and make the AI talk back to you.
Make the Teacher Talk
Your tools are installed and your API key is ready. Now it is time to write the code that actually talks to Gemini and turns its responses into speech.
Right now you have no way to send your words to the AI or hear anything back. In this step, you will connect your Python script to Gemini, give the teacher a voice with text-to-speech, and build a simple loop where you type a sentence and the teacher responds aloud.
In this step, get ready to:
- Create the project file and connect it to Google's Gemini AI.
- Write functions that let the teacher speak aloud and hold a conversation.
- Build a main loop where you type messages and hear grammar corrections.
Create the project file and connect to Gemini
Every piece of your English teacher lives in a single Python file. This first chunk sets up the connection to Gemini and initializes the libraries you installed in Step 1.
- In VS Code, press Cmd+Shift+P (macOS) or Ctrl+Shift+P (Windows) to open the Command Palette.
- Type File: New File and press Enter.
- Name the file english_teacher.py and save it to your Desktop.
- Set up the Gemini client, text-to-speech engine, and tracking variables by copying this code into your new file:
import speech_recognition as sr
import pyttsx3
from google import genai
from google.genai import types
# Replace with your actual Gemini API key
GEMINI_API_KEY = "your-api-key-here"
client = genai.Client(api_key=GEMINI_API_KEY)
# Set up text-to-speech engine at a comfortable speaking speed
engine = pyttsx3.init()
engine.setProperty("rate", 150)
# Set up speech recognizer for later use
recognizer = sr.Recognizer()
# Track the student's progress across the session
grammar_mistakes = []
total_exchanges = 0
conversation_log = ""
What does this code do?
- genai.Client(api_key=GEMINI_API_KEY) creates a connection to Google's Gemini API using your key. This is how your script sends messages to the AI.
- pyttsx3.init() starts the text-to-speech engine. On Windows, it uses the built-in SAPI5 voice system so it works completely offline.
- sr.Recognizer() creates a speech recognizer. You will not use it until a later step, but setting it up here keeps all initialization in one place.
- grammar_mistakes, total_exchanges, and conversation_log are empty trackers that later steps will fill as you chat with the teacher.
- Replace your-api-key-here with the Gemini API key you copied from Google AI Studio in Step 1.
Keep your API key private
Paste your real key directly into the string. Do not share this file publicly or push it to GitHub with your key visible.
The teacher needs a personality. A system prompt is a set of instructions that tells the AI how to behave before the conversation even begins.
- Add the system prompt below your tracking variables by copying this code:
# Instructions that tell Gemini how to behave as an English teacher
SYSTEM_PROMPT = (
"You are a friendly and patient English teacher having a spoken "
"conversation with a student who is practicing their English. "
"Follow these rules:\n"
"1. Keep responses short (2-3 sentences) so the conversation flows naturally.\n"
"2. If the student makes a grammar mistake, gently correct them by saying: "
"'I think you meant: [corrected sentence].' Then briefly explain the error.\n"
"3. If the student's message seems garbled or has odd words, their "
"pronunciation may need work. Point out which word sounded unclear.\n"
"4. Ask follow-up questions to keep the conversation going.\n"
"5. Occasionally praise the student when they express something well.\n"
"6. Never use emojis, markdown, or special formatting. Speak naturally."
)
What is prompt engineering?
Prompt engineering is the skill of writing instructions that shape how an AI responds. This system prompt tells Gemini to keep replies short, use a specific correction format ("I think you meant..."), and avoid formatting that sounds unnatural when spoken aloud.
The correction format matters. Later steps use the exact phrase "I think you meant" to detect when the teacher corrected your grammar.
- Save english_teacher.py.
- Open a terminal in VS Code by pressing Ctrl+`.
- Navigate to your Desktop and run the file by entering these commands:
cd ~/Desktop
python english_teacher.py
The script runs and exits with no output. That silence is a good sign. It means all four imports loaded, your API key was accepted, and the text-to-speech engine initialized without errors.
Seeing an import error?
- If you see ModuleNotFoundError, one of the libraries from Step 1 did not install correctly. Re-run the pip install command for the missing module.
- If you see an error about your API key, double check that you pasted the full key between the quotes on the GEMINI_API_KEY line.
Help me debug my import or API key error.
Write the speak and chat functions
Your file can connect to Gemini, but it cannot do anything with the responses yet. You need two functions: one to read text aloud, and one to send messages to the AI.
- In english_teacher.py, add the speak() function below the SYSTEM_PROMPT by copying this code:
def speak(text):
# Print the teacher's response and read it aloud
print(f"\nTeacher: {text}")
engine.say(text)
engine.runAndWait()
What does this function do?
- print() shows the teacher's response as text in your terminal so you can read along.
- engine.say() queues the text for the voice engine, and engine.runAndWait() plays it through your speakers and waits until the speech finishes.
- Now add the chat() function below speak() by copying this code:
def chat(user_message):
global conversation_log
# Add the student's message to the conversation history
conversation_log += f"\nStudent: {user_message}"
# Send the conversation to Gemini with teacher instructions
response = client.models.generate_content(
model="gemini-3.6-flash",
contents=conversation_log,
config=types.GenerateContentConfig(
system_instruction=SYSTEM_PROMPT,
max_output_tokens=200,
temperature=0.7,
),
)
# Save the teacher's reply to conversation history and return it
teacher_reply = response.text
conversation_log += f"\nTeacher: {teacher_reply}"
return teacher_reply
What does this function do?
- conversation_log is a running transcript of everything the student and teacher have said. Each new message gets appended before being sent to Gemini.
- client.models.generate_content() sends the full conversation to Gemini along with the system prompt. The AI reads the whole history so it can give context-aware responses.
- temperature=0.7 controls how creative the responses are. A value of 0.7 keeps the teacher natural without being too unpredictable.
Before building the full loop, test that both functions actually work together.
- Add these two test lines at the very bottom of english_teacher.py:
# Temporary test - delete these lines after testing
response = chat("I go to store yesterday")
speak(response)
- Save english_teacher.py and run it:
python english_teacher.py
You should see the teacher's response printed in your terminal AND hear it spoken aloud through your speakers. The teacher should point out the grammar mistake in "I go to store yesterday" and suggest something like "I went to the store yesterday."
Not hearing any voice?
- Make sure your computer's volume is turned up and not muted.
- If you see an error mentioning SAPI5 or voice IDs, your Windows system may not have speech voices installed. Open Settings, search for Speech, and confirm that at least one voice pack is installed.
- If the script hangs or you see an API error, check that your GEMINI_API_KEY value is correct. You can verify it by signing into aistudio.google.com and comparing the key on the API keys page.
Help me debug why the teacher is not speaking.
- Now that the test passed, find and delete the three test lines at the bottom of your file (the comment and the two lines below it).
- Save english_teacher.py.
Write the main loop and run the teacher
Your functions work individually, but the app has no entry point yet. The main loop ties everything together into a real conversation where you type messages and the teacher responds aloud.
- Add the main() function and its entry point at the bottom of english_teacher.py by copying this code:
def main():
# Display a welcome banner
print("=" * 40)
print(" AI ENGLISH TEACHER")
print(" Type to practice your English!")
print(' Type "quit" to end the session.')
print("=" * 40)
# Start with an automatic greeting from the teacher
greeting = chat("Hello, I want to practice English.")
speak(greeting)
# Main conversation loop
while True:
user_text = input("\nYou: ").strip()
if user_text.lower() == "quit":
break
response = chat(user_text)
speak(response)
if __name__ == "__main__":
main()
What does this code do?
- The welcome banner prints a header so you know the app started.
- chat("Hello, I want to practice English.") sends an automatic opening message to Gemini. The teacher greets you without you having to type anything first.
- The while True loop keeps the conversation going until you type quit. Each message you type gets sent to Gemini, and the response is spoken aloud.
- if __name__ == "__main__" ensures main() only runs when you execute the file directly, not when it is imported.
- Save english_teacher.py.
Before you run this, what do you think will happen when you type a sentence with a grammar mistake? Will the teacher just repeat it, or do something more?
- Run your English teacher by entering this command:
python english_teacher.py
- Wait for the teacher's greeting to appear and play through your speakers.
- When you see the You: prompt, type I go to store yesterday and press Enter.
The teacher speaks back with a grammar correction about past tense, something like "I think you meant: I went to the store yesterday." You can see the text in your terminal and hear it through your speakers at the same time.
- Try typing a few more sentences to see how the teacher responds.
- When you are done, type quit and press Enter to exit.
Teacher not responding or hanging?
- If the app prints the banner but hangs at the greeting, your API key may be invalid. Open english_teacher.py and check that GEMINI_API_KEY contains your full key with no extra spaces.
- If you see a PermissionDenied error, your Gemini API key may not be activated yet. Return to aistudio.google.com and confirm your key is listed on the API keys page.
- If the text appears but no voice plays, check your system volume and make sure no other app is blocking audio output.
Help me figure out why my English teacher app is not responding.
✔️ Awesome, I've got everything!
Great. Double check you have saved english_teacher.py and you are ready to move on.
ⓧ I'd like to double check the full code
Scroll up through your file and confirm each section is present in this order:
- Four import lines at the top (speech_recognition, pyttsx3, genai, types).
- GEMINI_API_KEY and client initialization.
- engine, recognizer, and three tracking variables (grammar_mistakes, total_exchanges, conversation_log).
- SYSTEM_PROMPT with six rules.
- speak() function.
- chat() function.
- main() function with the while True loop.
- if __name__ == "__main__" block at the very bottom.
Make sure the three temporary test lines have been deleted. The file should end with the if __name__ block, not the test code.
Your AI teacher can hear you type and talk back. Next up, you will replace the keyboard with your microphone so you can actually practice speaking English out loud.
Add Your Voice
Your teacher speaks back to you with grammar corrections. That is a working AI teacher, but there is one big problem.
You are still typing everything. Typing defeats the whole purpose of practicing spoken English. In this step, you will add voice input so you can speak naturally into your microphone and practice real pronunciation.
In this step, get ready to:
- Write a listen() function that captures audio from your microphone and transcribes it to text.
- Update the main loop to use voice input instead of typed input.
Write the listen() function
Your app needs a way to hear you speak and convert your words into text. The SpeechRecognition library handles this by recording audio from your microphone and sending it to Google's free speech recognition service.
- In english_teacher.py, find your speak() function.
- Add the listen() function directly below it by copying the following code:
def listen():
# Open the microphone as an audio source
with sr.Microphone() as source:
print("\nListening... (speak now)")
# Calibrate for background noise
recognizer.adjust_for_ambient_noise(source, duration=0.5)
try:
# Record audio with a 10s timeout and 15s max phrase
audio = recognizer.listen(source, timeout=10, phrase_time_limit=15)
# Send audio to Google's free speech recognition
text = recognizer.recognize_google(audio)
print(f"You said: {text}")
return text
except sr.UnknownValueError:
return None
except sr.RequestError:
print("Could not connect to Google Speech Recognition.")
return None
except sr.WaitTimeoutError:
return None
What does this code do?
- sr.Microphone() opens your computer's microphone as an audio source.
- adjust_for_ambient_noise() listens for half a second to calibrate against background noise, so it can distinguish your voice from silence.
- recognizer.listen() records audio. timeout=10 waits up to 10 seconds for you to start speaking. phrase_time_limit=15 caps each recorded phrase at 15 seconds.
- recognizer.recognize_google() sends the recorded audio to Google's free speech recognition service and returns the transcribed text.
- If recognition fails (unintelligible speech, no internet, or no speech detected), the function returns None instead of crashing.
- Save english_teacher.py.
Update the main loop to use voice input
Your main() function still uses input() to collect typed messages. You need to swap it for your new listen() function and handle the case where the microphone cannot understand you.
- In english_teacher.py, find your main() function. It currently contains these lines:
while True:
user_text = input("\nYou: ").strip()
if user_text.lower() == "quit":
break
response = chat(user_text)
speak(response)
- Replace the entire main() function with this updated version:
def main():
print("=" * 40)
print(" AI ENGLISH TEACHER")
print(" Speak to practice your English!")
print(' Say "goodbye" to end the session.')
print("=" * 40)
# Start with a greeting from the teacher
greeting = chat("Hello, I want to practice English.")
speak(greeting)
while True:
# Listen for voice input instead of typed input
user_text = listen()
# Handle cases where speech was not understood
if user_text is None:
speak("I didn't catch that. Could you try again?")
continue
response = chat(user_text)
speak(response)
What changed?
- The banner messages now say "Speak" instead of "Type" and "Say goodbye" instead of "Type quit."
- listen() replaces input(). The app now records from your microphone instead of waiting for typed text.
- If listen() returns None (speech was unintelligible or no speech was detected), the teacher asks you to try again and the loop continues with continue.
- Save english_teacher.py.
Your system may ask for microphone access
The first time you run the app, Windows may ask you to allow microphone access for Python. Click Yes or Allow to continue. The app cannot hear you without this permission.
Before you run the app, think about what should happen differently this time. What will you do instead of typing?
- Run your updated app:
python english_teacher.py
- Wait for the teacher's greeting to finish speaking.
- When you see "Listening... (speak now)" in the terminal, say "Hello how are you" into your microphone.
Your words appear as You said: Hello how are you in the terminal. The teacher responds aloud with a grammar correction or a follow-up question.
- Press Ctrl+C to stop the app when you are done testing.
Microphone not working?
- Make sure your microphone is plugged in and set as the default recording device in your system sound settings.
- If you see "Could not connect to Google Speech Recognition," check your internet connection. The recognize_google() method sends audio to Google's servers for transcription.
- If the app keeps timing out without hearing anything, speak louder or move closer to your microphone. You have 10 seconds to start speaking after the "Listening..." prompt appears.
- Help me debug my microphone issue with Python SpeechRecognition.
✔️ Awesome, I've got everything!
Great. Make sure you have saved english_teacher.py.
ⓧ I'd like to double check the full code
The full file is too long to show in one block. Scroll through your english_teacher.py and confirm each section is present in this order:
- Imports: speech_recognition, pyttsx3, genai, and types.
- Setup: GEMINI_API_KEY, client, engine, recognizer, global variables, and SYSTEM_PROMPT.
- Functions in order: speak(), then listen() (new), then chat(), then main().
- Entry point: if __name__ == "__main__": at the bottom calling main().
- In main(): the banner says "Speak" (not "Type"), the loop calls listen() (not input()), and None is handled with a retry.
Your teacher now listens to your voice and responds aloud. Next up, you will add conversation history so the teacher remembers what you discussed across exchanges.
Build the Conversation Loop
In the last step, you gave your teacher ears. The app now listens to your voice, sends your words to Gemini, and speaks the response aloud. Your chat() function already builds a running conversation_log that stores every exchange, so the teacher can remember what you discussed.
But there's a problem. The loop runs forever, and the only way out is force-closing the terminal. In this step, you'll add goodbye detection so the teacher wraps up the session naturally. You'll also start counting exchanges to prepare for the progress report you'll build next.
In this step, get ready to:
- Verify the teacher remembers what you discussed across exchanges.
- Add goodbye detection so the app exits cleanly.
- Track total exchanges for the upcoming progress report.
Verify conversation history works
The chat() function already appends every exchange to a conversation_log string and passes the full log to Gemini on each call. This means the teacher should remember what you discussed earlier. Let's test it.
- Run the app by running this command:
python english_teacher.py
- When the teacher greets you, say something about a specific topic. For example, say "I like to cook pasta" into your microphone.
- After the teacher responds, say a follow-up on the same topic, like "My favorite pasta is spaghetti."
- Say a third sentence on the same topic. The teacher should reference something you said in an earlier exchange, proving it remembers the full conversation.
- Press Ctrl+C to force-quit the app. There's no other way to exit right now.
How does conversation history work?
Every time you speak, chat() appends your message as Student: ... to the conversation_log string. After Gemini responds, the teacher's reply gets appended as Teacher: ... too.
The entire log is sent as contents every time Gemini is called. That growing transcript is what lets the teacher reference earlier topics.
Add goodbye detection and exchange tracking
The teacher remembers your conversation, but having to force-quit with Ctrl+C every time is not a great experience. You need a natural way to end the session.
- In english_teacher.py, find the main() function.
- Find this line at the top of the function:
def main():
- Add global total_exchanges on the next line, so the function can update the exchange counter:
def main():
global total_exchanges
Now update the main loop itself. The current while True block needs three additions: check if the user said goodbye, send a farewell message before exiting, and count each exchange.
- Find the while True: block inside main(). Replace the entire loop with this updated version:
while True:
user_text = listen()
if user_text is None:
speak("I didn't catch that. Could you try again?")
continue
# Check if the student wants to end the session
if "goodbye" in user_text.lower() or "bye" in user_text.lower():
total_exchanges += 1
farewell = chat(user_text)
speak(farewell)
break
# Count this exchange and get the teacher's response
total_exchanges += 1
response = chat(user_text)
speak(response)
What does this code do?
- if user_text is None catches moments where the microphone picked up sound but the speech recognizer could not understand it. Instead of crashing, the teacher politely asks you to repeat yourself.
- The goodbye check uses .lower() so it works whether you say "Goodbye," "goodbye," or "GOODBYE." When triggered, the teacher gets one last chance to respond with a farewell before the loop breaks.
- total_exchanges += 1 counts every exchange, including the goodbye. This counter will power the progress report you build in the next step.
- Save english_teacher.py.
Seeing a NameError for total_exchanges?
- Make sure global total_exchanges is the first line inside def main():, before the print statements. Without it, Python treats total_exchanges as a local variable and cannot find it.
- Check that total_exchanges = 0 exists near the top of the file with the other global variables.
Why is my total_exchanges variable causing a NameError in main()?
Test the full conversation loop
Time to test the complete loop. Before you run the app, think about this: what do you expect to happen when you say "goodbye"?
- Run the app by running this command:
python english_teacher.py
- Say three sentences on the same topic into your microphone. For example, talk about your morning routine.
- After each exchange, check that the teacher's response connects to what you said earlier. The teacher should reference your previous answers, not treat each message as a brand-new conversation.
- Say "goodbye" into your microphone.
The teacher speaks a farewell message, and the app exits back to your terminal prompt. No more Ctrl+C needed.
App doesn't exit when you say goodbye?
- The speech recognizer might transcribe "goodbye" differently than you expect. Check the You said: output in the terminal. If it shows something like "good bye" (two words), the check still works because Python's in operator matches substrings.
- Make sure the goodbye check uses user_text.lower() and not just user_text. Without .lower(), a capitalized "Goodbye" would not match.
- If the microphone is not picking up your voice at all, check that your microphone is set as the default input device in your system sound settings.
My app isn't detecting when I say goodbye. Help me debug the goodbye detection logic.
✔️ Awesome, I've got everything!
Great. Double check you've saved english_teacher.py.
ⓧ I'd like to double check the full code
Scroll up and confirm these pieces are in your english_teacher.py file, in order:
- Imports: speech_recognition, pyttsx3, genai, and types.
- Globals: GEMINI_API_KEY, client, engine, recognizer, grammar_mistakes, total_exchanges, conversation_log, and SYSTEM_PROMPT.
- speak() function: prints and reads text aloud.
- listen() function: captures microphone audio and returns transcribed text or None.
- chat() function: appends to conversation_log and calls Gemini with the full log.
- main() function: starts with global total_exchanges. The while True loop handles None from listen(), checks for goodbye/bye to break, and increments total_exchanges on every exchange.
- if __name__ == "__main__": block at the bottom calling main().
Your AI English teacher now holds a real conversation. It remembers what you talked about, handles moments when it can't hear you, and wraps up naturally when you say goodbye. Next up, you'll add a progress tracking system that shows exactly how your grammar improved over the session.
Track Your Grammar and Show Progress
Your AI teacher now listens to your voice, responds aloud, and remembers the full conversation. But after chatting for ten minutes, how do you know if your English actually got better?
In this step, you'll add a progress tracking system. The app detects whenever the teacher corrects your grammar and logs the mistake. When you say goodbye, a progress report appears showing your total exchanges, corrections, and accuracy rate.
In this step, get ready to:
- Track grammar corrections during each conversation exchange.
- Display a session progress report when you say goodbye.
Write the progress report function
You already have grammar_mistakes and total_exchanges declared at the top of your file. Now you need a function that reads those values and prints a formatted report the learner can review at the end of a session.
- In english_teacher.py, scroll down to the blank space between the chat() function and the main() function.
- Add the following show_progress() function below chat():
def show_progress():
# Print a formatted session report
print("\n" + "=" * 40)
print(" SESSION PROGRESS REPORT")
print("=" * 40)
print(f"Total exchanges: {total_exchanges}")
print(f"Grammar corrections: {len(grammar_mistakes)}")
# List each sentence that was corrected
if grammar_mistakes:
print("\nSentences that needed correction:")
for i, mistake in enumerate(grammar_mistakes, 1):
print(f' {i}. "{mistake}"')
# Calculate and display accuracy percentage
if total_exchanges > 0:
accuracy = ((total_exchanges - len(grammar_mistakes)) / total_exchanges) * 100
print(f"\nAccuracy rate: {accuracy:.0f}%")
print("=" * 40)
What does this code do?
- The function prints a bordered report with the total number of exchanges and how many grammar corrections the teacher made.
- If grammar_mistakes has entries, it lists each corrected sentence with a number.
- The accuracy rate is calculated as the percentage of exchanges where the teacher did not correct your grammar.
- Save english_teacher.py.
Track corrections and connect the report
The show_progress() function is ready, but nothing calls it yet and nothing fills grammar_mistakes. You need two changes inside main(): detect corrections after each response, and display the report on goodbye.
- In english_teacher.py, find the while True: loop inside main().
- Replace the entire while True: loop with this updated version:
while True:
user_text = listen()
if user_text is None:
speak("I didn't catch that. Could you try again?")
continue
# Exit when the student says goodbye
if "goodbye" in user_text.lower() or "bye" in user_text.lower():
total_exchanges += 1
farewell = chat(user_text)
speak(farewell)
show_progress() # Show the session report before exiting
break
total_exchanges += 1
response = chat(user_text)
# Check if the teacher corrected a grammar mistake
if "I think you meant" in response:
grammar_mistakes.append(user_text)
speak(response)
What changed in this loop?
Two things are new here:
- After each teacher response, the code checks if the string "I think you meant" appears. Your system prompt tells the teacher to use that exact phrase when correcting grammar. If it appears, the student's original sentence is saved to grammar_mistakes.
- When the student says goodbye, show_progress() runs right before the loop breaks. This prints the full session report.
- Save english_teacher.py.
Before you run the app, think about this: if you deliberately say "She have a cat," what do you think the teacher will say, and what will you see when you say goodbye?
- Run the app by entering this command in your terminal:
python english_teacher.py
- When the teacher greets you, deliberately say a few incorrect sentences like "She have a cat" and "I goed to school."
- Chat for a few more exchanges, then say "goodbye."
After the teacher's farewell, you should see a SESSION PROGRESS REPORT printed in your terminal. It shows your total exchanges, the number of grammar corrections, each sentence that was corrected, and your accuracy rate as a percentage.
Not seeing the progress report?
- Make sure show_progress() is placed between speak(farewell) and break inside the goodbye block. If it is after break, it will never run.
- Check that the show_progress() function definition sits outside main() at the top level of the file, not indented inside another function.
- If the report shows zero grammar corrections even after saying incorrect sentences, the teacher may not have used the exact phrase "I think you meant" in its response. Try a more obvious error like "I is happy" and check the teacher's printed reply.
Why isn't my progress report showing up after saying goodbye?
✔️ Awesome, I've got everything!
Great. Make sure you've saved english_teacher.py one final time.
ⓧ I'd like to double check the full code
Your english_teacher.py file is over 30 lines now, so instead of pasting the full file here, confirm each section is present in order by scrolling through your file:
- Imports at the top: speech_recognition, pyttsx3, genai, and types.
- Global setup: GEMINI_API_KEY, client, engine, recognizer, grammar_mistakes, total_exchanges, conversation_log, and SYSTEM_PROMPT.
- Functions in order: speak(), listen(), chat(), show_progress(), then main().
- Inside the while True: loop: grammar check with "I think you meant" after each response, and show_progress() before break in the goodbye block.
- The if __name__ == "__main__": block at the very end calling main().
Secret mission
Add Conversation Topics and Difficulty Levels
Your AI teacher works, but every session starts the same way with no structure. A real language class gives you a topic to practice and adjusts difficulty to your level. Can you add a topic menu and difficulty selector that reshape the teacher's personality before each session?
Clean Up Your Resources
Clean Up Your Resources
This project runs entirely on your local machine and uses the free tier of the Gemini API, so there are no ongoing costs. Decide whether to keep your resources as they are, pause for later, or delete them entirely.
Resources you used:
- english_teacher.py file on your machine.
- Python libraries: SpeechRecognition, PyAudio, pyttsx3, google-genai.
- Google Gemini API key (free tier, no charges).
Keep everything running
No action needed. Choose this if you want to keep practicing with the AI English teacher or plan to extend the project further.
- Your API key stays active on the free tier. There are no charges.
- The Python libraries remain installed and available for other projects.
- Your english_teacher.py file stays wherever you saved it.
Pause - I'll come back to this later
Nothing runs in the background, so there is nothing to pause. The app only runs when you explicitly start it.
- Your API key, libraries, and project file all stay in place. Pick up where you left off by running python english_teacher.py again.
Delete - I don't want to use this again
Remove all project resources and start fresh. Follow each step below.
- Delete the project file. In your terminal, navigate to the folder containing english_teacher.py and run the command below.
- On macOS/Linux:
- On Windows (PowerShell):
rm english_teacher.py
On Windows, use this instead:
Remove-Item english_teacher.py
- Uninstall the Python libraries by running:
pip uninstall SpeechRecognition PyAudio pyttsx3 google-genai
What does this command do?
pip uninstall removes each listed package from your Python environment. You will be prompted to confirm each one. Type y and press Enter for each package.
- Delete your Gemini API key. Go to the API keys page in Google AI Studio at aistudio.google.com/apikey.
- Find the API key you created for this project.
- Click the delete icon next to the key to remove it.
Nice Work!
Nice Work!
Nice work! You just built a voice-powered AI English teacher from scratch using Python, Google Gemini, speech recognition, and text-to-speech. You can speak into your microphone, get real-time grammar corrections, and see a progress report at the end of every session.
What you learned:
- Connected a Python app to Google's Gemini AI using the free tier API and engineered a system prompt that turns a general-purpose AI into a focused English teacher with grammar correction skills.
- Added real-time speech recognition using the SpeechRecognition library and made the teacher speak aloud using pyttsx3 to create a full voice conversation loop with AI.
- Built a conversation history system so the teacher remembers context across exchanges, and created a progress tracking report that counts grammar corrections and calculates your accuracy rate.
- Secret Mission: Added structured conversation topics and difficulty levels to customize each practice session.
Ready to quiz yourself?