I'm currently learning how to code with python, and I thought the best way would be learning by doing so I tried to create a voice assistant but it just stops working after a few iterations.
The code below isn't very efficient nor clean, but it works except for the part that it stops after a few iterations of listening.
there are no error mesages nor does the code actually stop it just doesn't do anything
thank you for every suggestion in advance
import speech_recognition as sr
import pyttsx3
import datetime as dt
# import wikipedia
# import webbrowser
import os
# import time
# import subprocess
# import ecapture as ec
# import wolframalpha
# import json
# import requests
# from gtts import gTTS
import random as ran
from docx import Document
document = Document()
note_new = ""
note_complete = ""
adding_more = True
second = dt.datetime.now().second
minute = dt.datetime.now().minute
hour = dt.datetime.now().hour
hour_str = str(hour)
minute_str = str(minute)
second_str = str(second)
time = hour_str + ":" + minute_str + ":" + second_str + " "
# initialising the text to speech engine
engine = pyttsx3.init()
voices = engine.getProperty('voices')
engine.setProperty('voice', voices[2].id)
# <editor-fold desc="Listening to the Users input">
# listening to the Users input
statement = ""
def listen():
global statement
r = sr.Recognizer()
with sr.Microphone() as source:
print("Listening...")
audio = r.listen(source)
try:
statement = r.recognize_google(audio, language='en-in')
except Exception as e:
# speak("Pardon me, please say that again")
return "None"
return statement
# </editor-fold>
# <editor-fold desc="Talking">
def talk(text):
engine.say(text)
engine.runAndWait()
# </editor-fold>
# <editor-fold desc="Key Words">
# KeyWord Functions
def hello():
random_text = ran.randint(1, 3)
if random_text == 1:
print("Hello Sir, welcome home.")
talk("Hello Sir, welcome home.")
elif random_text == 2:
print("Hello, welcome home.")
talk("Hello, welcome home.")
elif random_text == 3:
print("Welcome back.")
talk("Welcome back.")
def minecraft():
random_text = ran.randint(1, 3)
if random_text == 1:
print("Initialising Minecraft...")
talk("Initialising Minecraft")
elif random_text == 2:
print("Minecraft coming right up...")
talk("Minecraft coming right up")
elif random_text == 3:
print("Starting Minecraft")
talk("Starting Minecraft")
os.startfile("C:\Spiele\Minecraft\MinecraftLauncher.exe")
def chrome():
random_text = ran.randint(1, 3)
if random_text == 1:
print("Initialising Chrome...")
talk("Initialising Chrome")
elif random_text == 2:
print("Chrome coming right up...")
talk("Chrome coming right up")
elif random_text == 3:
print("Starting Chrome...")
talk("Starting Chrome")
os.startfile("C:\Program Files (x86)\Google\Chrome\Application\chrome.exe")
def valorant():
random_text = ran.randint(1, 3)
if random_text == 1:
print("Initialising Valorant...")
talk("Initialising Valorant")
elif random_text == 2:
print("Valorant coming right up...")
talk("Valorant coming right up")
elif random_text == 3:
print("Starting Valorant...")
talk("Starting Valorant")
os.startfile("C:/Spiele/Riot Games/VALORANT/live/VALORANT.exe")
def aim_lab():
random_text = ran.randint(1, 3)
if random_text == 1:
print("Initialising Aim Lab...")
talk("Initialising Aim Lab")
elif random_text == 2:
print("Aim Lab coming right up...")
talk("Aim Lab coming right up")
elif random_text == 3:
print("Starting Aim Lab...")
talk("Starting Aim Lab")
os.startfile("steam://rungameid/714010")
def clock():
global second
global minute
global hour
global hour_str
global minute_str
global second_str
global time
second = dt.datetime.now().second
minute = dt.datetime.now().minute
hour = dt.datetime.now().hour
hour_str = str(hour)
minute_str = str(minute)
second_str = str(second)
time = hour_str + ":" + minute_str + ":" + second_str + " "
print("It's " + hour_str + " hours and " + minute_str + " minutes")
talk("It's " + hour_str + " hours and " + minute_str + " minutes")
def note():
global adding_more
global note_new
global note_complete
print("How should i call the note?")
talk("How should i call the note?")
listen()
note_name = statement
while adding_more:
print("Ok you can start talking:")
talk("Ok you can start talking:")
listen()
note_new = statement
print("new: " + note_new)
note_complete = note_complete + " " + note_new
print("new: " + note_complete)
print("Do you want to add more?")
talk("Do you want to add more?")
listen()
if "yes" in statement.lower():
adding_more = True
if "no" in statement.lower():
adding_more = False
print("printing...")
talk("printing..")
note_name_txt = note_name + ".txt"
note_name_complete = note_name_txt
f = open(note_name_complete, "w+")
f.write(note_complete)
f.close()
print("ready")
talk("ready")
print("should i open the note?")
talk("should i open the note?")
listen()
if "yes" in statement.lower():
note_name_complete = str(note_name_complete)
note_name_path = note_name_complete.replace(" ", "_")
os.startfile("D:/Python/Projekts/Jarvis/" + note_name_complete)
def dice():
number = 6
print("What sould be the range")
talk("What sould be the range")
listen()
try:
number = int(statement)
except:
print("I could not understand you sorry Sir!")
dice()
random_number = ran.randint(1, number)
print("The D " + str(number) + " says " + str(random_number))
talk("The D" + str(number) + "says" + str(random_number))
def stop():
global hour
if hour <= 12:
print("have a good day!")
talk("have a good day!")
if 19 >= hour < 12:
print("Goodbye")
talk("bye")
if hour > 19:
print("Goodnight!")
talk("Goodnight")
quit()
# </editor-fold>
if __name__ == '__main__':
while True:
statement = " "
listen()
print(statement)
command = statement.lower()
if "jarvis" in command:
if "hello" in command:
hello()
if "minecraft" in command:
minecraft()
if "chrome" in command:
chrome()
if "valorant" in command:
valorant()
if "time" in command or "clock" in command:
clock()
if "note" in command:
note()
if "dice" in command:
dice()
if "aim" in command or "lab" in command:
aim_lab()
if "stop" in command or "bye" in command or "goodbye" in command or "goodnight" in command:
stop()
If you report:
stops working after a few iterations
Then I would look for the loop (where iterations happen usually). I found the only obvious loop in the main block:
Shorten the loops
if __name__ == '__main__':
while True:
statement = '' # initialize as empty string
listen()
print(statement)
execute_command(statement.lower())
Extracted your command switch into a method execute_command:
def execute_command(command):
if "jarvis" in command:
if "hello" in command:
hello()
if "minecraft" in command:
minecraft()
if "chrome" in command:
chrome()
if "valorant" in command:
valorant()
if "time" in command or "clock" in command:
clock()
if "note" in command:
note()
if "dice" in command:
dice()
if "aim" in command or "lab" in command:
aim_lab()
if "stop" in command or "bye" in command or "goodbye" in command or "goodnight" in command:
stop()
Then watch out to the understood command that is printed.
Which command was the last printed before the loop stopped?
Design pure functions (returning a value)
This goes hand in hand with another common programming advice:
Don't use global variables!
def listen():
statement = '' # remove global, make it local and return
r = sr.Recognizer()
with sr.Microphone() as source:
print("Listening...")
audio = r.listen(source)
try:
statement = r.recognize_google(audio, language='en-in')
except Exception as e:
# speak("Pardon me, please say that again")
return "None"
return statement # you had the return already; use it!
Then your main (and other usage locations) would change to:
if __name__ == '__main__':
while True:
statement = listen() # use the return
print(statement)
execute_command(statement.lower())
Related
I am creating an AI called b/12 in python. I'm trying to add a wake word to it the way that Alexa works IRL. If you currently say b/12 (It's wake word).. It expects an immediate command in the same sentence. But I'd love to have it that you have to say B/12, then the command after it activates.
This is my current code on pastebin: https://pastebin.com/CM2uqXKW
from distutils.log import info
from multiprocessing.sharedctypes import Value
import string
import speech_recognition as sr
import pyttsx3
import pywhatkit
import datetime
import wikipedia
import pyjokes
import os
import random
from playsound import playsound
import sys
import time
from threading import Thread
clear = lambda: os.system('cls')
listener = sr.Recognizer()
def RandomAudioWaking():
AudioPath="Audio\\waking"
AudioSelect = random.choice(os.listdir(AudioPath))
AudioPlay = str(AudioPath + "\\" + AudioSelect)
playsound(AudioPlay)
def RandomAudioTalkingShort():
AudioPath="Audio\\Talking\\Short"
AudioSelect = random.choice(os.listdir(AudioPath))
AudioPlay = str(AudioPath + "\\" + AudioSelect)
playsound(AudioPlay)
def RandomAudioTalkingMedium():
AudioPath="Audio\\Talking\\Medium"
AudioSelect = random.choice(os.listdir(AudioPath))
AudioPlay = str(AudioPath + "\\" + AudioSelect)
playsound(AudioPlay)
def RandomAudioTalkingLong():
AudioPath="Audio\\Talking\\Long"
AudioSelect = random.choice(os.listdir(AudioPath))
AudioPlay = str(AudioPath + "\\" + AudioSelect)
playsound(AudioPlay)
def DidNotUnderstand():
time.sleep(0.04)
string = 'I did not understand that.'
for char in string:
sys.stdout.write(char)
sys.stdout.flush()
time.sleep(0.04)
time.sleep(3.0)
def NameCall():
time.sleep(0.04)
string = 'That is my name!'
for char in string:
sys.stdout.write(char)
sys.stdout.flush()
time.sleep(0.04)
def take_command():
try:
with sr.Microphone() as source:
clear()
print("š“ B12: Sleeping")
listener.adjust_for_ambient_noise(source, duration=0.2)
voice = listener.listen(source)
command = listener.recognize_google(voice)
command = command.lower()
if 'b12' in command:
clear()
print("š¢ B12: Active")
RandomAudioWaking()
return command
except:
pass
def run_b12():
command = take_command()
if command == None:
return take_command
if 'b12' == command:
print("\nš¬ User said: '" + command + "'")
thread1 = Thread(target=RandomAudioTalkingShort)
thread2 = Thread(target=NameCall)
thread1.start()
thread2.start()
time.sleep(3.5)
elif 'play' in command:
print("\nš¬ User said: '" + command + "'")
command = command.replace('b12', '')
song = command.replace('play', '')
def NowPlaying():
time.sleep(0.04)
string = 'Now playing:' + song
for char in string:
sys.stdout.write(char)
sys.stdout.flush()
time.sleep(0.04)
thread1 = Thread(target=RandomAudioTalkingMedium)
thread2 = Thread(target=NowPlaying)
thread1.start()
thread2.start()
pywhatkit.playonyt(song)
time.sleep(3.5)
elif 'time' in command:
print("\nš¬ User said: '" + command + "'")
command = command.replace('b12', '')
currenttime = datetime.datetime.now().strftime('%I:%M %p')
elif 'who is' in command:
print("\nš¬ User said: '" + command + "'")
command = command.replace('b12', '')
person = command.replace('who is', '')
infoperson = wikipedia.summary(person, sentences=1, auto_suggest=False)
def whois():
string = 'I found this: \n' + infoperson
for char in string:
sys.stdout.write(char)
sys.stdout.flush()
time.sleep(0.09)
thread1 = Thread(target=RandomAudioTalkingLong)
thread2 = Thread(target=whois)
thread1.start()
thread2.start()
time.sleep(3.0)
thread1.start
time.sleep(3.5)
elif 'joke' in command:
print("\nš¬ User said: '" + command + "'")
command = command.replace('b12', '')
print(pyjokes.get_joke())
else:
clear()
print("š¢ B12: Active")
command = command.replace('b12', '')
print("\nš¬ User said: '" + command + "'")
thread1 = Thread(target=RandomAudioTalkingShort)
thread2 = Thread(target=DidNotUnderstand)
thread1.start()
thread2.start()
time.sleep(3.5)
return run_b12
while True:
run_b12()
This is a program related to windows operations. I have made different versions of this program. So I tried writing a version using classes. I am a beginner and thought this will help me understand the concept but I am getting some errors like
Method 'shutdown_windows' may be 'static'
There are many errors like this and I would like to get some insight about them and how to solve them
This is my code:
import os
import datetime
import time
class WindowsOperations(object):
def __init__(self, shutdown, restart, open_app, close_app):
self.shutdown = shutdown
self.restart = restart
self.open_app = open_app
self.close_app = close_app
def shutdown_windows(self):
time.sleep(remaining_time)
while True:
if time_hour == datetime.datetime.now().hour and time_minutes == datetime.datetime.now().minute: #
os.system("shutdown /s /t 1")
break
def restart_windows(self):
time.sleep(remaining_time)
while True:
if time_hour == datetime.datetime.now().hour and time_minutes == datetime.datetime.now().minute:
os.system("shutdown /r /t 1")
break
def open_application(self):
app_name_open = input("Enter the application name you want to open: ").lower() + ".exe"
time.sleep(remaining_time)
while True:
if time_hour == datetime.datetime.now().hour and time_minutes == datetime.datetime.now().minute:
os.startfile(app_name_open)
break
def close_application(self):
app_name_close = input("Enter the application name you want to close: ").lower() + ".exe"
time.sleep(remaining_time)
while True:
if time_hour == datetime.datetime.now().hour and time_minutes == datetime.datetime.now().minute:
os.system("TASKKILL /F /IM " + app_name_close)
break
choice = int(input("Enter your choice \n1.Shutdown Windows \n2.Restart Windows "
"\n3.Open an application \n4.Close an application \n:"))
time_hour = int(input("Enter hour: "))
time_minutes = int(input("Enter minutes: "))
time_now = datetime.datetime.now()
remaining_time = ((time_minutes - time_now.minute) * 60 + (time_hour - time_now.hour) * 3600) % 86400
print(remaining_time)
my_windows_operation = WindowsOperations('shutdown', 'restart', 'open_app', 'close_app')
if choice == 1:
my_windows_operation.shutdown_windows()
elif choice == 2:
my_windows_operation.restart_windows()
elif choice == 3:
my_windows_operation.open_application()
elif choice == 4:
my_windows_operation.close_application()
else:
print("Please enter a valid input")
Please do modify the code if necessary and give me some tips
The second "Parameter 'shutdown' unfilled" is an error. It's coming because you've defined WindowsOperations intitializer to take 4 parameters:
def __init__(self, shutdown, restart, open_app, close_app):
But when actually creating the object you are passing noothing:
my_windows_operation = WindowsOperations()
You definitely need to fix that.
The first "Method 'shutdown_windows' may be 'static'" is more of a suggestion. It's coming because the method shutdown_windows does not use self - i.e. it need not be part of the class to do it's job.
There was a looping error with add, but now that I can add data to my txt file, there is this error using 'see' to list my data. Below is the erro:
TypeError:list_champs() takes 0 positional arguments but 1 was given.
I cannot see where I added a parameter unknowingly that doesn't need one in my current code.
# file = open("champs.txt", "w+")
FILENAME = "champs.txt"
def write_champs(champs):
with open(FILENAME, "w") as file:
for champ in champs:
file.write(champ + "\n")
def read_champs():
champs = []
with open(FILENAME) as file:
for line in file:
line = line.replace("\n", "")
champs.append(line)
return champs
def list_champs():
for i in range(len(champs)):
champ = champs[i]
print(str(i+1) + " - " + champs)
print()
def add_champ(champs):
champ = input("Champion: ")
#year = input("Season: ")
#champ = []
champs.append(champ)
#champ.append(year)
write_champs(champs)
print(champ + " was added.\n")
def display_menu():
print("Premier League Champions")
print("++++++++++++++++++++++++")
print("COMMANDS")
print("see - See the list of Champions")
print("add - Add a Champion to the list")
print("exit - Exit program")
print()
def main():
display_menu()
champs = read_champs()
while True:
command = input("Enter command: ")
if command == "see":
list_champs(champs)
elif command == "add":
add_champ(champs)
elif command == "exit":
print("Later!")
break
else:
print("Input not valid. Try again.")
if __name__ == "__main__":
main()
As always help is much appreciated!
You need to change your def list_champs to support arguments:
def list_champs(champs):
for i in range(len(champs)):
champ = champs[i]
print(str(i+1) + " - " + champs)
print()
function definition
def list_champs():
function call
list_champs(champs)
Do you want the function to take an argument, or not?
Fix one or the other, depending on your intended design.
This question already has answers here:
UnboundLocalError trying to use a variable (supposed to be global) that is (re)assigned (even after first use)
(14 answers)
Closed 6 years ago.
I am (attempting) to make a hacking game like Hack Run or Hacknet. But only the terminal. I get this error when I try to print the variable 'currentip' at line 86 ("print("You are currently at " + currentip + ".")"):
UnboundLocalError: local variable 'currentip' referenced before assignment
This looks like a simple error but I cannot figure it out. I have assigned it. Multiple times. Maybe I am reading the order execution wrong but I can't find any info that says I am doing it wrong...
Any ideas for cleaning up and making it neater/better is also very much appreciated.
import os
import random
from time import sleep
os.system("cls")
save = {}
ips = {"1337.1337.1337.1337": "Cheater's Stash"}
shells = []
storyips = ["Bitwise Test PC"]
currentip = "1.1.1.1"
homeip = "1.1.1.1"
def resetip():
ip1 = random.randint(1, 999)
ip2 = random.randint(1, 999)
ip3 = random.randint(1, 999)
ip4 = random.randint(1, 999)
homeip = str(ip1) + "." + str(ip2) + "." + str(ip3) + "." + str(ip4)
if homeip in ips:
resetip()
else:
ips[homeip] = "Your Computer"
currentip = homeip
def storyreset():
for x in storyips:
ip = (0, 0, 0, 0)
ip1 = random.randint(1, 999)
ip2 = random.randint(1, 999)
ip3 = random.randint(1, 999)
ip4 = random.randint(1, 999)
ip = str(ip1) + "." + str(ip2) + "." + str(ip3) + "." + str(ip4)
if ip in ips:
storyreset()
else:
ips[ip] = x
def start():
os.system("cls")
print("Python 3.5, HackSim 1.1")
print("")
print("Loading modules...")
print("")
sleep(1)
print("OS Loaded.")
sleep(0.5)
print("HELP Loaded.")
sleep(0.5)
print("FILE USE Loaded.")
sleep(1)
print("CONNECTIONS Loaded.")
sleep(0.5)
print("UTILS Loaded.")
sleep(0.5)
print("HACKS Loaded.")
print("")
sleep(1)
print("Initiating command line...")
sleep(1)
commandline()
def usecommand(c):
if c == "reboot":
print("Rebooting...")
sleep(3)
start()
elif c == "clear":
os.system("cls")
elif c == "quit":
quit()
elif c == "forkbomb":
del ips[currentip]
if homeip in ips:
currentip = "Your Computer"
else:
resetip()
currentip = "Your Computer"
elif "connect " in c:
if c[8:] in ips:
connectip = ips[c[8:]]
print("Connecting to ", connectip, " ", c[8:], "...")
currentip = connectip
else:
print("This ip does not exist.")
elif c == "connect":
print("You are currently at " + currentip + ".")
print("The syntax of this command is: connect <ip>.")
else:
print("Invalid command. Either the command does not exist or check the required syntax.")
def commandline():
while True:
command = input("> ")
usecommand(command)
storyreset()
resetip()
start()
Thanks!
The problem is that you have global variables in your code and you are trying to access them from inside the function without first declaring them global. You need to put a line global currentip at the beginning of your usecommand function.
Also note that if you only used the variable currentip in your function it would work, but if you are both using it and assigning it within the same function the interpreter assumes it is a local variable you are using. Take a look at this:
x = 10
def f():
print x
def f2(arg):
if arg:
x = 20
else:
print x
Running function f() will print 10, but running function f2(0) will produce an error because the interpreter is once again unsure of whether the variable you are using is local or global and assumes it is a local one.
HTH.
I am working on a Python chat script, the client looks like this:
import sys
import util
import thread
import socket
class ClientSocket():
rbufsize = -1
wbufsize = 0
def __init__(self, address, nickname=''):
if type(address) == type(()) and type(address[0]) == type('') and
type(address[1])== type(1):
pass
else:
print ('Address is of incorrect type. \n' +
'Must be (serverHost (str), serverPort (int)).')
sys.exit(1)
if nickname:
self.changeNick(nickname)
else:
self.changeNick(raw_input('Nickname: '))
self.prompt_on = False
self.address = address
def connect(self):
self.connection=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.connection.connect(self.address)
self.rfile = self.connection.makefile('rb', self.rbufsize)
self.wfile = self.connection.makefile('wb', self.wbufsize)
self.wfile.write('/nick ' + self.nickname + '\n')
def serve_forever(self):
self.connect()
thread.start_new_thread(self.acceptinput,())
line = ""
while line not in ('/exit','/quit', '/q'):
self.prompt_on = True
line = raw_input(self.prompt)
self.prompt_on = False
if line[:2] == '/n' or line[:5] == '/nick':
self.changeNick(line.split(' ', 1)[1].strip())
self.wfile.write(line + '\n')
self.close()
self.connection.shutdown(socket.SHUT_RDWR)
self.connection.close()
def changeNick(self, newNick):
self.nickname = newNick
self.prompt = self.nickname+': '
self.backspace = '\b' * len(self.prompt)
def acceptinput(self):
while 1:
data = self.rfile.readline().strip()
if data:
self.writedata(data)
if 'Nickname successfully changed to' in data:
self.changeNick(data.split('"')[1])
def writedata(self, data):
if self.prompt_on:
output = data if len(data) >= len(self.prompt) else data + ' '
(len(self.prompt) - len(data))
sys.stdout.write(self.backspace + output + '\n' + self.prompt)
sys.stdout.flush()
else:
print data
def close(self):
if not self.wfile.closed:
self.wfile.flush()
self.wfile.close()
self.rfile.close()
def main():
serverHost = raw_input('Server IP/Hostname: ')
if not serverHost:
serverHost = util.getIP()
else:
serverHost = socket.gethostbyname(serverHost)
serverPort = input('Server Port: ')
address = (serverHost, serverPort)
client = ClientSocket(address)
print 'Connecting to server on %s:%s' % (serverHost, serverPort)
client.serve_forever()
if __name__ == '__main__':
main()
I was wondering if there would be a way to play a sound every time a new messages. Possible using winsound ? (http://stackoverflow.com/questions/307305/play-a-sound-with-python)
Thanks:)
I am pleasantly surprised that winsound is standard library module. Just note that is only available on Windows.
What happens in your writa_data function you do this after the flush. Does this get your desired effect?
import winsound
# Play Windows exit sound.
winsound.PlaySound("SystemExit", winsound.SND_ALIAS)
Okay, figured it out !!! Thanks for the help! :DDD
You add the winsound.PlaySound("SystemExit", winsound.SND_ALIAS) on line 101, above the sys.stdout.write(self.backspace + output + '\n' + self.prompt). Now whenever a new message comes through, it plays a 'ding!'. If you wanted to use a custom .wav sound from the same directory the script is running from, add a winsound.PlaySound("ding.wav", winsound.SND_FILENAME) on line #101 instead. Enjoy!