Emmimal P. Alexander — ‘You don’t build AI to replace human intelligence. You build it to discover what human intelligence was trying to become all along.
Hey there! Welcome to our coding session where we’ll create a virtual assistant from scratch. I’m going to walk you through this just like we’re sitting at the same table, working through each piece together.
What We’ll Build Today – AI Virtual Assistant
By the time we’re done, you’ll have a working virtual assistant that can:
- Listen to what you say
- Talk back to you
- Tell you the current time and date
- Look up information on Wikipedia
- Open programs on your computer
- Do basic math
- Tell jokes when you need a laugh
No coding experience? No problem. I’ll explain everything as we go.
Step 1: Getting Our Tools Ready
Before we start building, we need to set up our workspace. It’s like preparing ingredients before cooking.
What You Need
- Python – Our programming language
- A text editor – Where we’ll write our code
- Some helper libraries – Pre-built tools that save us time
Installing Python
First, let’s get Python on your computer:
- Go to python.org
- Download Python 3.9 or newer
- Install it (just click through the installer)
- Check “Add Python to PATH” during installation
To make sure Python installed correctly, open your command prompt (Windows) or terminal (Mac/Linux) and type:
python --version
You should see something like “Python 3.9.7”.
Installing Helper Libraries
Now we need some tools. Open your command prompt and type these commands one by one:
pip install pyttsx3
pip install SpeechRecognition
pip install pyaudio
pip install requests
pip install wikipedia
pip install pyjokes
Here’s what each tool does:
- pyttsx3: Makes your computer talk
- SpeechRecognition: Helps your computer understand speech
- pyaudio: Handles audio input and output
- requests: Fetches information from the internet
- wikipedia: Gets Wikipedia articles
- pyjokes: Provides jokes
Step 2: Understanding the Basics
Let me explain how a virtual assistant works without getting too technical.
What is a Virtual Assistant?
A virtual assistant is a program that can understand when you speak, figure out what you want, and respond back to you. The process works like this:
- Listen – Record what you say
- Convert – Turn your speech into text
- Process – Figure out what you want
- Act – Do the task or find information
- Respond – Give you an answer
How the Process Works
Your Voice → Microphone → Text → Processing → Action → Response → Speaker → Your Ears
Now let’s build this step by step.
Step 3: Making Your Computer Talk
Let’s start with something simple. Create a new file called simple_assistant.py
and write this code:
Step 1: First Words
import pyttsx3
# Create a speech engine
engine = pyttsx3.init()
# Make your computer say hello
engine.say("Hello! I am your virtual assistant.")
engine.runAndWait()
Let me break this down:
import pyttsx3
: Brings in our text-to-speech libraryengine = pyttsx3.init()
: Creates the speech engineengine.say("text")
: Tells the engine what to sayengine.runAndWait()
: Actually speaks the words
Try it out! Save the file and run it:
python simple_assistant.py
Your computer should speak to you!
Step 2: Making the Voice Better
import pyttsx3
# Create the engine
engine = pyttsx3.init()
# Get available voices
voices = engine.getProperty('voices')
# Customize the voice
engine.setProperty('voice', voices[1].id) # Female voice (voices[0] for male)
engine.setProperty('rate', 150) # Speaking speed
engine.setProperty('volume', 0.9) # Volume level
# Test the new voice
engine.say("Hi there! I sound different now!")
engine.runAndWait()
What changed:
voices = engine.getProperty('voices')
: Gets all available voicesengine.setProperty('voice', voices[1].id)
: Changes to a different voiceengine.setProperty('rate', 150)
: Sets how fast it talksengine.setProperty('volume', 0.9)
: Sets volume level
Step 4: Teaching Your Computer to Listen
Now let’s make it understand what you say.
Step 3: Basic Listening
import speech_recognition as sr
import pyttsx3
# Set up speech recognition
recognizer = sr.Recognizer()
microphone = sr.Microphone()
# Set up text-to-speech
engine = pyttsx3.init()
engine.setProperty('rate', 150)
def speak(text):
"""Make the assistant speak"""
engine.say(text)
engine.runAndWait()
def listen():
"""Listen and convert speech to text"""
try:
with microphone as source:
print("Listening...")
# Adjust for background noise
recognizer.adjust_for_ambient_noise(source)
# Record audio
audio = recognizer.listen(source, timeout=5)
print("Processing...")
# Convert speech to text using Google's service
text = recognizer.recognize_google(audio)
print(f"You said: {text}")
return text.lower()
except sr.UnknownValueError:
speak("Sorry, I didn't understand that.")
return None
except sr.RequestError:
speak("There's a problem with the speech service.")
return None
except sr.WaitTimeoutError:
speak("I didn't hear anything.")
return None
# Test it out
speak("Hi! Say something to me.")
user_input = listen()
if user_input:
speak(f"You said: {user_input}")
This is more complex, so let me explain each part:
The speak function: Instead of writing the same speech code everywhere, we created a function that we can call easily.
The listen function: This does the heavy lifting:
with microphone as source:
– Opens the microphonerecognizer.adjust_for_ambient_noise(source)
– Adjusts for room noiseaudio = recognizer.listen(source, timeout=5)
– Records for up to 5 secondstext = recognizer.recognize_google(audio)
– Converts speech to text using Googlereturn text.lower()
– Returns lowercase text for easier processing
Error handling: The try/except
blocks handle different problems:
- When speech isn’t clear enough
- When the internet connection fails
- When no speech is detected
Step 5: Building the Brain
Now let’s create the part that decides what to do based on what you say.
Step 4: Command Processing
import speech_recognition as sr
import pyttsx3
import datetime
import webbrowser
import os
import wikipedia
import pyjokes
import requests
# Set up components
recognizer = sr.Recognizer()
microphone = sr.Microphone()
engine = pyttsx3.init()
engine.setProperty('rate', 150)
def speak(text):
"""Convert text to speech"""
print(f"Assistant: {text}")
engine.say(text)
engine.runAndWait()
def listen():
"""Listen and convert speech to text"""
try:
with microphone as source:
print("Listening...")
recognizer.adjust_for_ambient_noise(source)
audio = recognizer.listen(source, timeout=5)
print("Processing...")
text = recognizer.recognize_google(audio)
print(f"You said: {text}")
return text.lower()
except sr.UnknownValueError:
speak("I didn't catch that. Could you repeat?")
return None
except sr.RequestError:
speak("There's a problem with the speech service.")
return None
except sr.WaitTimeoutError:
speak("I'm still listening...")
return None
def get_current_time():
"""Get current time and date"""
now = datetime.datetime.now()
current_time = now.strftime("%I:%M %p")
current_date = now.strftime("%A, %B %d, %Y")
return current_time, current_date
def search_wikipedia(query):
"""Look up information on Wikipedia"""
try:
# Clean up the search query
search_query = query.replace("what is", "").replace("who is", "").replace("tell me about", "").strip()
# Get information from Wikipedia
summary = wikipedia.summary(search_query, sentences=2)
return summary
except wikipedia.exceptions.DisambiguationError as e:
# Multiple results found, use the first one
summary = wikipedia.summary(e.options[0], sentences=2)
return summary
except wikipedia.exceptions.PageError:
return "I couldn't find information about that topic."
except Exception as e:
return "There was an error searching for that information."
def tell_joke():
"""Get a random joke"""
joke = pyjokes.get_joke()
return joke
def open_website(url):
"""Open a website"""
webbrowser.open(url)
def process_command(command):
"""Figure out what to do based on the command"""
if command is None:
return
# Greetings
if any(word in command for word in ['hello', 'hi', 'hey']):
speak("Hello there! How can I help you today?")
# Time requests
elif 'time' in command:
current_time, current_date = get_current_time()
speak(f"The current time is {current_time}")
# Date requests
elif 'date' in command:
current_time, current_date = get_current_time()
speak(f"Today is {current_date}")
# Wikipedia searches
elif any(phrase in command for phrase in ['what is', 'who is', 'tell me about']):
speak("Let me search for that information.")
result = search_wikipedia(command)
speak(result)
# Jokes
elif 'joke' in command:
joke = tell_joke()
speak(joke)
# Opening websites
elif 'open youtube' in command:
speak("Opening YouTube")
open_website("https://www.youtube.com")
elif 'open google' in command:
speak("Opening Google")
open_website("https://www.google.com")
# Exit commands
elif any(word in command for word in ['goodbye', 'bye', 'exit', 'quit']):
speak("Goodbye! It was nice talking to you.")
return False
# Unknown commands
else:
speak("I'm not sure how to help with that. Try asking me about the time, date, or search for something.")
return True
# Main program
def main():
speak("Hello! I'm your virtual assistant. How can I help you today?")
while True:
user_input = listen()
if not process_command(user_input):
break
# Run the assistant
if __name__ == "__main__":
main()
Let me explain the new parts:
New Libraries:
datetime
: Gets current time and datewebbrowser
: Opens web pageswikipedia
: Searches Wikipediapyjokes
: Provides jokes
Key Functions:
get_current_time():
datetime.datetime.now()
: Gets current date and timestrftime("%I:%M %p")
: Formats time like “2:30 PM”strftime("%A, %B %d, %Y")
: Formats date like “Monday, January 15, 2024”
search_wikipedia(query): This function handles different types of errors that can happen when searching Wikipedia.
process_command(command): This is where the magic happens. It uses several text operations to understand what you want.
Understanding Text Operations:
Let me show you the text methods we’re using:
.lower()
: Makes all letters lowercasetext = "HELLO WORLD" print(text.lower()) # prints: "hello world"
.replace(old, new)
: Swaps texttext = "what is python" clean_text = text.replace("what is", "") print(clean_text) # prints: " python"
.strip()
: Removes extra spacestext = " python " clean_text = text.strip() print(clean_text) # prints: "python"
in
operator: Checks if text contains somethingcommand = "what time is it" if 'time' in command: print("User asked about time") # This will run
any()
function: Checks if any item in a list matchesgreetings = ['hello', 'hi', 'hey'] command = "hello there" if any(word in command for word in greetings): print("User said hello") # This will run
Step 6: Adding More Features
Let’s make our assistant smarter by adding calculator functions.
Step 5: Calculator Feature
import re
def calculate(expression):
"""Do basic math calculations"""
try:
# Replace words with math symbols
expression = expression.replace("plus", "+")
expression = expression.replace("minus", "-")
expression = expression.replace("times", "*")
expression = expression.replace("multiplied by", "*")
expression = expression.replace("divided by", "/")
# Remove calculation trigger words
words_to_remove = ['calculate', 'compute', 'what is']
for word in words_to_remove:
expression = expression.replace(word, '')
expression = expression.strip()
# Only allow safe characters
allowed_chars = '0123456789+-*/.()'
if all(c in allowed_chars or c.isspace() for c in expression):
result = eval(expression)
return f"The result is {result}"
else:
return "I can only do basic math with numbers and operators."
except ZeroDivisionError:
return "I can't divide by zero!"
except:
return "I couldn't calculate that. Please try a simpler expression."
# Add this to your process_command function
elif any(word in command for word in ['calculate', 'compute', 'plus', 'minus', 'times', 'divided']):
result = calculate(command)
speak(result)
Step 6: Opening Applications
def open_application(app_name):
"""Open programs on your computer"""
applications = {
'notepad': 'notepad.exe',
'calculator': 'calc.exe',
'paint': 'mspaint.exe'
}
try:
if app_name in applications:
os.startfile(applications[app_name])
return f"Opening {app_name}"
else:
return f"I don't know how to open {app_name}"
except Exception as e:
return f"I couldn't open {app_name}"
# Add this to your process_command function
elif 'open' in command:
for app in ['notepad', 'calculator', 'paint']:
if app in command:
result = open_application(app)
speak(result)
break
Step 7: Making It More Reliable
Let’s add better error handling so our assistant doesn’t crash when something goes wrong.
Step 7: Error Handling
import logging
# Set up logging to track what happens
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
def safe_speak(text):
"""Speak with error protection"""
try:
print(f"Assistant: {text}")
engine.say(text)
engine.runAndWait()
logging.info(f"Spoke: {text}")
except Exception as e:
print(f"Error in speech: {e}")
logging.error(f"Speech Error: {e}")
def safe_listen():
"""Listen with retry capability"""
max_attempts = 3
attempt = 0
while attempt < max_attempts:
try:
with microphone as source:
print("Listening...")
recognizer.adjust_for_ambient_noise(source, duration=1)
audio = recognizer.listen(source, timeout=5, phrase_time_limit=10)
print("Processing...")
text = recognizer.recognize_google(audio)
print(f"You said: {text}")
logging.info(f"Heard: {text}")
return text.lower()
except sr.UnknownValueError:
attempt += 1
if attempt < max_attempts:
safe_speak("I didn't catch that. Please try again.")
else:
safe_speak("I'm having trouble understanding. Let's try something else.")
except sr.RequestError as e:
safe_speak("There's an issue with the speech service.")
logging.error(f"Speech service error: {e}")
return None
except sr.WaitTimeoutError:
attempt += 1
if attempt < max_attempts:
safe_speak("I didn't hear anything. Please speak up.")
except Exception as e:
logging.error(f"Unexpected error: {e}")
safe_speak("Something went wrong. Please try again.")
return None
return None
Step 8: Complete Assistant Code
import speech_recognition as sr
import pyttsx3
import datetime
import webbrowser
import wikipedia
import pyjokes
import logging
import os
import sys
# Set up logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler('assistant.log'),
logging.StreamHandler()
]
)
class VirtualAssistant:
"""Your personal virtual assistant"""
def __init__(self):
self.name = "Alex"
self.setup_components()
self.setup_voice()
self.running = True
# Lists of words to recognize
self.greetings = ['hello', 'hi', 'hey', 'good morning', 'good afternoon']
self.goodbyes = ['goodbye', 'bye', 'see you later', 'exit', 'quit', 'stop']
def setup_components(self):
"""Set up speech recognition and text-to-speech"""
try:
self.recognizer = sr.Recognizer()
self.microphone = sr.Microphone()
self.engine = pyttsx3.init()
# Adjust for room noise
with self.microphone as source:
self.recognizer.adjust_for_ambient_noise(source)
logging.info("All components ready")
except Exception as e:
logging.error(f"Setup failed: {e}")
sys.exit(1)
def setup_voice(self):
"""Configure the voice"""
try:
voices = self.engine.getProperty('voices')
if len(voices) > 1:
self.engine.setProperty('voice', voices[1].id) # Female voice
self.engine.setProperty('rate', 150) # Speaking speed
self.engine.setProperty('volume', 0.9) # Volume
logging.info("Voice configured")
except Exception as e:
logging.error(f"Voice setup failed: {e}")
def speak(self, text):
"""Make the assistant speak"""
try:
print(f"{self.name}: {text}")
self.engine.say(text)
self.engine.runAndWait()
logging.info(f"Said: {text}")
except Exception as e:
print(f"Speech error: {e}")
logging.error(f"Speech error: {e}")
def listen(self):
"""Listen for user speech"""
try:
with self.microphone as source:
print("Listening...")
self.recognizer.adjust_for_ambient_noise(source, duration=0.5)
audio = self.recognizer.listen(source, timeout=5, phrase_time_limit=10)
print("Processing...")
text = self.recognizer.recognize_google(audio)
print(f"You said: {text}")
logging.info(f"Heard: {text}")
return text.lower()
except sr.UnknownValueError:
self.speak("I didn't understand. Could you repeat that?")
return None
except sr.RequestError:
self.speak("There's a problem with the speech service.")
return None
except sr.WaitTimeoutError:
print("No speech detected")
return None
except Exception as e:
self.speak("Something went wrong while listening.")
logging.error(f"Listen error: {e}")
return None
def get_time_date(self):
"""Get current time and date"""
now = datetime.datetime.now()
return {
'time': now.strftime("%I:%M %p"),
'date': now.strftime("%A, %B %d, %Y"),
'day': now.strftime("%A")
}
def search_wikipedia(self, query):
"""Search Wikipedia for information"""
try:
# Clean the search terms
search_terms = ['what is', 'who is', 'tell me about']
for term in search_terms:
query = query.replace(term, '')
query = query.strip()
if not query:
return "What would you like me to search for?"
self.speak(f"Looking up {query}")
# Get Wikipedia summary
summary = wikipedia.summary(query, sentences=3)
return summary
except wikipedia.exceptions.DisambiguationError as e:
try:
# Multiple results found, use first one
summary = wikipedia.summary(e.options[0], sentences=3)
return f"Found multiple results. Here's about {e.options[0]}: {summary}"
except Exception:
return f"There are several results for {query}. Be more specific."
except wikipedia.exceptions.PageError:
return f"Couldn't find information about {query}."
except Exception as e:
logging.error(f"Wikipedia error: {e}")
return "Had trouble searching. Try again."
def tell_joke(self):
"""Get a random joke"""
try:
joke = pyjokes.get_joke()
return joke
except Exception:
return "Why don't scientists trust atoms? Because they make up everything!"
def calculate(self, expression):
"""Do basic math"""
try:
# Replace words with symbols
replacements = {
'plus': '+',
'add': '+',
'minus': '-',
'subtract': '-',
'times': '*',
'multiply': '*',
'divide': '/',
'divided by': '/'
}
for word, symbol in replacements.items():
expression = expression.replace(word, symbol)
# Remove trigger words
triggers = ['calculate', 'compute', 'what is']
for trigger in triggers:
expression = expression.replace(trigger, '')
expression = expression.strip()
# Safety check - only allow basic math characters
allowed = '0123456789+-*/.()'
if not all(c in allowed or c.isspace() for c in expression):
return "I can only do basic math with numbers."
result = eval(expression)
return f"The answer is {result}"
except ZeroDivisionError:
return "Cannot divide by zero!"
except:
return "That doesn't look like a math problem I can solve."
def open_application(self, app_name):
"""Open computer programs"""
apps = {
'notepad': 'notepad.exe',
'calculator': 'calc.exe',
'paint': 'mspaint.exe'
}
try:
if app_name in apps:
os.startfile(apps[app_name])
return f"Opening {app_name}"
else:
return f"Don't know how to open {app_name}"
except Exception:
return f"Couldn't open {app_name}"
def open_website(self, site_name):
"""Open websites"""
sites = {
'google': 'https://www.google.com',
'youtube': 'https://www.youtube.com',
'wikipedia': 'https://www.wikipedia.org'
}
try:
if site_name in sites:
webbrowser.open(sites[site_name])
return f"Opening {site_name}"
else:
# Search for it instead
search_url = f"https://www.google.com/search?q={site_name}"
webbrowser.open(search_url)
return f"Searching for {site_name}"
except Exception:
return f"Couldn't open {site_name}"
def process_command(self, command):
"""Decide what to do based on what was said"""
if not command:
return True
command = command.lower().strip()
# Greetings
if any(greeting in command for greeting in self.greetings):
greetings = [
f"Hello! I'm {self.name}. How can I help?",
f"Hi there! What can I do for you?",
f"Hey! {self.name} here, ready to help!"
]
import random
self.speak(random.choice(greetings))
# Goodbyes
elif any(goodbye in command for goodbye in self.goodbyes):
farewells = [
"Goodbye! Have a great day!",
"See you later!",
"Bye! Take care!"
]
import random
self.speak(random.choice(farewells))
return False
# Time
elif 'time' in command:
time_info = self.get_time_date()
self.speak(f"It's {time_info['time']}")
# Date
elif 'date' in command or 'today' in command:
time_info = self.get_time_date()
self.speak(f"Today is {time_info['date']}")
# Wikipedia searches
elif any(phrase in command for phrase in ['what is', 'who is', 'tell me about']):
result = self.search_wikipedia(command)
self.speak(result)
# Jokes
elif 'joke' in command:
joke = self.tell_joke()
self.speak(joke)
# Math
elif any(word in command for word in ['calculate', 'compute', 'plus', 'minus', 'times', 'divided']):
result = self.calculate(command)
self.speak(result)
# Open applications
elif 'open' in command:
apps = ['notepad', 'calculator', 'paint']
for app in apps:
if app in command:
result = self.open_application(app)
self.speak(result)
break
else:
# Try opening as website
sites = ['google', 'youtube', 'wikipedia']
for site in sites:
if site in command:
result = self.open_website(site)
self.speak(result)
break
# Web search
elif 'search' in command:
if 'search for' in command:
query = command.split('search for')[1].strip()
else:
query = command.replace('search', '').strip()
if query:
self.speak(f"Searching for {query}")
search_url = f"https://www.google.com/search?q={query.replace(' ', '+')}"
webbrowser.open(search_url)
# About the assistant
elif 'your name' in command or 'who are you' in command:
self.speak(f"I'm {self.name}, your virtual assistant. I can help with time, information, calculations, and more!")
# Help
elif 'help' in command or 'what can you do' in command:
help_text = """I can help you with several things:
Tell you the time or date
Search for information
Tell jokes
Do basic math
Open programs like notepad
Search the internet
Just talk to me naturally!"""
self.speak(help_text)
# Unknown commands
else:
responses = [
"Not sure what you mean. Try asking about time, searching for something, or say 'help'.",
"Didn't understand that. You can ask me to tell time, search, or open programs.",
"Sorry, don't know how to do that. Try something else!"
]
import random
self.speak(random.choice(responses))
return True
def run(self):
"""Start the assistant"""
self.speak(f"Hi! I'm {self.name}. Say 'help' to see what I can do!")
while self.running:
try:
user_input = self.listen()
if user_input:
keep_running = self.process_command(user_input)
if not keep_running:
break
except KeyboardInterrupt:
self.speak("Goodbye!")
logging.info("Stopped by user")
break
except Exception as e:
logging.error(f"Main loop error: {e}")
self.speak("Had an error, but I'm still here!")
# Start the assistant
if __name__ == "__main__":
try:
assistant = VirtualAssistant()
assistant.run()
except Exception as e:
print(f"Couldn't start assistant: {e}")
Now let’s put everything together into our final assistant:
Step 9: Understanding Text Processing
Let me show you exactly how the text operations work with real examples.
Text Method Examples
# Example text for testing
sample = " Hello World! How are you today? "
command = "what is the weather in London today"
# Case changes
print("Original:", sample)
print("Lowercase:", sample.lower()) # " hello world! how are you today? "
print("Uppercase:", sample.upper()) # " HELLO WORLD! HOW ARE YOU TODAY? "
print("Title case:", sample.title()) # " Hello World! How Are You Today? "
# Removing spaces
print("No edge spaces:", sample.strip()) # "Hello World! How are you today?"
print("No left spaces:", sample.lstrip()) # "Hello World! How are you today? "
print("No right spaces:", sample.rstrip()) # " Hello World! How are you today?"
# Checking content
print("Starts with 'Hello':", sample.strip().startswith("Hello")) # True
print("Ends with 'today?':", sample.strip().endswith("today?")) # True
print("Contains 'World':", "World" in sample) # True
print("Position of 'World':", sample.find("World")) # Shows position
print("Count of 'o':", sample.count("o")) # How many 'o's
# Replacing text
print("Replace 'World' with 'Universe':", sample.replace("World", "Universe"))
# Splitting and joining
words = sample.strip().split()
print("Split into words:", words) # ['Hello', 'World!', 'How', 'are', 'you', 'today?']
print("Join with dashes:", "-".join(words)) # "Hello-World!-How-are-you-today?"
# Advanced splitting
parts = command.split("in")
print("Split by 'in':", parts) # ['what is the weather ', ' London today']
# String formatting
name = "Alex"
time = "2:30 PM"
message = f"Hi, I'm {name}. The time is {time}."
print("Formatted message:", message)
# Character checking
test = "Hello123"
print("All letters:", test.isalpha()) # False (has numbers)
print("All numbers:", "123".isnumeric()) # True
print("Letters and numbers:", test.isalnum()) # True
Real-World Text Processing Examples
Let me show you how these methods work in actual assistant scenarios:
def clean_user_input(text):
"""Clean up what the user said"""
# Make it lowercase for easier matching
cleaned = text.lower()
# Remove extra spaces
cleaned = cleaned.strip()
# Remove filler words people often say
filler_words = ["um", "uh", "like", "you know"]
words = cleaned.split()
words = [word for word in words if word not in filler_words]
cleaned = " ".join(words)
# Remove punctuation that might cause problems
punctuation = ".,!?;:"
for p in punctuation:
cleaned = cleaned.replace(p, "")
return cleaned
# Test it out
user_says = "Um, like, what is the weather, you know?"
clean_text = clean_user_input(user_says)
print(f"User said: {user_says}")
print(f"Cleaned up: {clean_text}") # Result: "what is the weather"
def extract_search_terms(command):
"""Pull out what the user wants to search for"""
# Words that indicate a search request
search_words = ["search for", "look up", "find", "tell me about"]
query = command.lower()
# Find which search word was used
for search_word in search_words:
if search_word in query:
# Split by the search word and take everything after it
parts = query.split(search_word)
if len(parts) > 1:
search_term = parts[1].strip()
return search_term
return None
# Test examples
test_commands = [
"search for artificial intelligence",
"tell me about machine learning",
"look up python programming"
]
for cmd in test_commands:
result = extract_search_terms(cmd)
print(f"Command: {cmd}")
print(f"Search for: {result}\n")
Step 10: Testing Your Assistant
Before we call it done, let’s make sure everything works properly.
Step 8: Testing Functions
def test_assistant_features():
"""Test all the main features"""
# Create an assistant instance for testing
assistant = VirtualAssistant()
test_commands = [
"hello",
"what time is it",
"what date is it today",
"tell me about python programming",
"tell me a joke",
"calculate 5 plus 3",
"what can you do",
"goodbye"
]
print("Testing assistant features...")
print("=" * 50)
for command in test_commands:
print(f"\nTesting: '{command}'")
print("-" * 30)
assistant.process_command(command)
print("-" * 30)
# You can run this to test everything
# test_assistant_features()
Step 9: Adding a Simple Interface
Let’s create a simple graphical interface so you don’t have to use the command line:
import tkinter as tk
from tkinter import scrolledtext, messagebox
import threading
class AssistantGUI:
"""Simple graphical interface for the assistant"""
def __init__(self):
self.assistant = VirtualAssistant()
self.setup_window()
def setup_window(self):
"""Create the main window"""
self.root = tk.Tk()
self.root.title("Virtual Assistant")
self.root.geometry("600x500")
# Text area to show conversation
self.conversation = scrolledtext.ScrolledText(
self.root,
wrap=tk.WORD,
width=70,
height=20,
state=tk.DISABLED
)
self.conversation.pack(padx=10, pady=10)
# Buttons
button_area = tk.Frame(self.root)
button_area.pack(pady=10)
self.listen_button = tk.Button(
button_area,
text="Listen",
command=self.start_listening,
bg="green",
fg="white",
font=("Arial", 12),
width=10
)
self.listen_button.pack(side=tk.LEFT, padx=5)
self.stop_button = tk.Button(
button_area,
text="Stop",
command=self.stop_assistant,
bg="red",
fg="white",
font=("Arial", 12),
width=10
)
self.stop_button.pack(side=tk.LEFT, padx=5)
# Text input area
input_area = tk.Frame(self.root)
input_area.pack(pady=10, fill=tk.X, padx=10)
self.text_input = tk.Entry(input_area, font=("Arial", 12))
self.text_input.pack(side=tk.LEFT, fill=tk.X, expand=True)
self.text_input.bind("<Return>", self.handle_text_input)
self.send_button = tk.Button(
input_area,
text="Send",
command=self.handle_text_input,
bg="blue",
fg="white"
)
self.send_button.pack(side=tk.RIGHT, padx=(5, 0))
self.add_message("Assistant: Hi! I'm ready to help you!")
def add_message(self, text):
"""Add a message to the conversation area"""
self.conversation.config(state=tk.NORMAL)
self.conversation.insert(tk.END, text + "\n")
self.conversation.see(tk.END)
self.conversation.config(state=tk.DISABLED)
def start_listening(self):
"""Start listening in a separate thread so the interface doesn't freeze"""
def listen_process():
self.add_message("Listening...")
user_input = self.assistant.listen()
if user_input:
self.add_message(f"You: {user_input}")
response = self.get_assistant_response(user_input)
self.add_message(f"Assistant: {response}")
# Run in background so interface stays responsive
threading.Thread(target=listen_process, daemon=True).start()
def handle_text_input(self, event=None):
"""Handle typed input"""
user_input = self.text_input.get().strip()
if user_input:
self.add_message(f"You: {user_input}")
response = self.get_assistant_response(user_input)
self.add_message(f"Assistant: {response}")
self.text_input.delete(0, tk.END)
def get_assistant_response(self, user_input):
"""Get a response from the assistant"""
# This connects to your assistant's brain
user_input = user_input.lower()
if any(greeting in user_input for greeting in ['hello', 'hi', 'hey']):
return "Hello! How can I help you today?"
elif 'time' in user_input:
import datetime
now = datetime.datetime.now()
return f"The current time is {now.strftime('%I:%M %p')}"
elif 'date' in user_input:
import datetime
now = datetime.datetime.now()
return f"Today is {now.strftime('%A, %B %d, %Y')}"
elif 'joke' in user_input:
return self.assistant.tell_joke()
elif any(calc_word in user_input for calc_word in ['calculate', 'plus', 'minus', 'times']):
return self.assistant.calculate(user_input)
else:
return "I'm still learning! Try asking me about the time, date, or for a joke."
def stop_assistant(self):
"""Close the application"""
self.root.quit()
def run(self):
"""Start the graphical interface"""
self.root.mainloop()
# To use the GUI version, uncomment this:
# if __name__ == "__main__":
# gui = AssistantGUI()
# gui.run()
Step 11: Common Problems and Solutions
Let me help you solve issues you might run into.
Problem 1: Microphone Not Working
def test_microphone():
"""Check if your microphone is working"""
try:
recognizer = sr.Recognizer()
microphone = sr.Microphone()
print("Available microphones:")
for index, name in enumerate(sr.Microphone.list_microphone_names()):
print(f"{index}: {name}")
with microphone as source:
print("Say something now...")
recognizer.adjust_for_ambient_noise(source)
audio = recognizer.listen(source, timeout=5)
text = recognizer.recognize_google(audio)
print(f"I heard: {text}")
return True
except Exception as e:
print(f"Microphone problem: {e}")
print("Try checking:")
print("- Is your microphone plugged in?")
print("- Do other apps can use your microphone?")
print("- Is your internet working? (needed for speech recognition)")
return False
# Run this to test your microphone
# test_microphone()
Problem 2: Speech Recognition Not Working Well
def improve_speech_recognition():
"""Better settings for speech recognition"""
recognizer = sr.Recognizer()
microphone = sr.Microphone()
# Better settings
recognizer.energy_threshold = 300 # Lower = more sensitive
recognizer.pause_threshold = 1 # How long to wait for speech to end
recognizer.dynamic_energy_threshold = True # Auto-adjust sensitivity
with microphone as source:
print("Adjusting for background noise... (this takes a moment)")
recognizer.adjust_for_ambient_noise(source, duration=2)
return recognizer, microphone
Problem 3: Assistant Crashes
def safe_assistant_loop():
"""Run the assistant with crash protection"""
assistant = VirtualAssistant()
while True:
try:
user_input = assistant.listen()
if user_input:
should_continue = assistant.process_command(user_input)
if not should_continue:
break
except KeyboardInterrupt:
assistant.speak("Goodbye!")
break
except Exception as e:
print(f"Something went wrong: {e}")
assistant.speak("I had a problem, but I'm still here!")
# Keep running instead of crashing
Step 12: Making Your Assistant Better
Here are ways to expand your assistant once you have it working.
Ideas for New Features
- Remember Things: Save user preferences
- Set Reminders: Alert you about appointments
- Control Smart Devices: Turn lights on/off
- Learn Your Voice: Recognize who’s talking
- Multiple Languages: Understand different languages
- Send Messages: Email or text people for you
Adding a Memory System
import json
import os
class AssistantMemory:
"""Help the assistant remember things"""
def __init__(self):
self.memory_file = "assistant_memory.json"
self.memory = self.load_memory()
def load_memory(self):
"""Load saved memories"""
if os.path.exists(self.memory_file):
try:
with open(self.memory_file, 'r') as f:
return json.load(f)
except:
return {}
return {}
def save_memory(self):
"""Save memories to file"""
try:
with open(self.memory_file, 'w') as f:
json.dump(self.memory, f, indent=2)
except Exception as e:
print(f"Couldn't save memory: {e}")
def remember(self, key, value):
"""Remember something"""
self.memory[key] = value
self.save_memory()
def recall(self, key):
"""Recall something"""
return self.memory.get(key)
def forget(self, key):
"""Forget something"""
if key in self.memory:
del self.memory[key]
self.save_memory()
# Add to your assistant:
# self.memory = AssistantMemory()
Performance Improvements
import time
class ResponseCache:
"""Cache responses to make the assistant faster"""
def __init__(self):
self.cache = {}
self.cache_lifetime = 300 # 5 minutes
def get(self, key):
"""Get cached response if it's still fresh"""
if key in self.cache:
response, timestamp = self.cache[key]
if time.time() - timestamp < self.cache_lifetime:
return response
else:
# Remove old cache entry
del self.cache[key]
return None
def set(self, key, response):
"""Cache a response"""
self.cache[key] = (response, time.time())
# Use in your assistant:
# self.cache = ResponseCache()
Step 13: What You’ve Built
Let’s take a step back and look at what you’ve accomplished.
Your Assistant’s Capabilities
Your virtual assistant can now:
- Listen to your voice and understand speech
- Speak back to you with a natural voice
- Tell you the current time and date
- Search Wikipedia for information
- Perform basic math calculations
- Tell jokes when you need them
- Open programs on your computer
- Search the web for information
- Handle errors without crashing
- Work through a simple graphical interface
Programming Skills You’ve Learned
Through building this assistant, you’ve mastered:
- Working with Libraries: Using pre-built tools to save time
- Text Processing: Cleaning and analyzing user input
- Error Handling: Making programs that don’t crash
- Object-Oriented Programming: Organizing code into classes
- User Interface Creation: Building graphical interfaces
- API Integration: Connecting to external services
- Audio Processing: Working with speech and sound
- File Operations: Saving and loading data
Text Processing Mastery
You now understand these essential string operations:
.lower()
,.upper()
– Changing text case.strip()
– Removing extra spaces.replace(old, new)
– Swapping text.split()
,.join()
– Breaking apart and combining text.find()
,.count()
– Searching within text.startswith()
,.endswith()
– Checking text patternsin
operator – Finding substrings- F-strings – Formatting text with variables
Step 14: Your Next Steps
You’ve built something remarkable. Here’s how to keep growing:
Immediate Next Steps
- Test Everything: Try all the features with different commands
- Customize It: Change the name, voice, and responses
- Add Features: Pick one new capability and build it
- Share It: Show friends and family what you created
- Document It: Write down how everything works
Learning Path Forward
- Explore Machine Learning: Make your assistant smarter
- Study Natural Language Processing: Better understand human speech
- Learn Database Management: Give your assistant long-term memory
- Experiment with Hardware: Connect to sensors and smart devices
- Build Mobile Apps: Put your assistant on phones and tablets
Project Ideas
- Smart Home Controller: Control lights, temperature, music
- Personal Productivity Assistant: Manage calendar, emails, tasks
- Educational Tutor: Help with homework and learning
- Gaming Companion: Voice commands for games
- Accessibility Tool: Help people with disabilities
Getting Help
When you get stuck (and you will – we all do):
- Read error messages carefully
- Search online for specific problems
- Join programming communities
- Practice regularly
- Don’t be afraid to experiment
Conclusion
You started this tutorial knowing little or nothing about programming, and now you have a working AI virtual assistant. That’s no small achievement.
Your assistant may seem simple compared to commercial ones, but you built it yourself. You understand how every part works. You can modify it, extend it, and make it your own. That’s something special.
The skills you’ve learned here – text processing, error handling, working with libraries, creating user interfaces – these are the building blocks of larger projects. You’re not just someone who can follow a tutorial anymore. You’re someone who can build software.
Programming is a journey, not a destination. Each project teaches you something new. Each problem you solve makes you better. Your virtual assistant is just the beginning.
What will you build next?
Remember: Every expert was once a beginner. Every professional started with simple projects like this one. Keep building, keep learning, and most importantly, have fun with it.
Additional Resources
Feel free to share your projects or ask questions in the comments below. We’d love to hear about your experiences and any additional features you’ve added to your AI virtual assistant.
[…] Offers advanced language models like GPT-3 and GPT-4 for NLP tasks such as text completion, translation, and summarization. Developers can integrate […]