Search code examples
pythonscopeclosuresglobal-variables

pls help me fix this weird UnboundLocalError


i try to make an Alexa Vitual Assistant but the code throw an UnboundLocalError .Pls help

import speech_recognition as sr
import pyttsx3
import datetime


listener = sr.Recognizer()
engine = pyttsx3.init()
voices = engine.getProperty("voices")
engine.setProperty('voice', voices[1].id)
def talk(text):
    engine.say(text)
    engine.runAndWait()
talk("Hi i'm Alexa ,your assistant")
talk("How can i help you ?")
print("Hi i'm Alexa")

def take_request():
    try:
        with sr.Microphone() as source:
            talk("i am listening")
            print("listening ....")
            voice = listener.listen(source)
            command = listener.recognize_google(voice)
            print(command)
            #command = input("say sth : ")
            commands= command.lower()
            if "a" in commands:
                print(commands)

    except:
        pass
    return commands


def run_alexa():
    #global commands
    cm = take_request()
    if "play" in cm:
        print("playing music")
        talk("playing music")
    elif "time" in cm:
        time = datetime.datetime.now().strftime("%H:%M")
        print(time)
        talk("your current time is "+time)
    else:
        talk('Please say the command again.')
        print("pls talk again !!!")


while True:
    run_alexa()

and the error

Hi i'm Alexa
listening ....
Traceback (most recent call last):
  File "C:\Users\USER\Desktop\autobot\Hana assistant.py", line 50, in <module>
    run_alexa()
  File "C:\Users\USER\Desktop\autobot\Hana assistant.py", line 36, in run_alexa
    cm = take_request()
  File "C:\Users\USER\Desktop\autobot\Hana assistant.py", line 32, in take_request
    return commands
UnboundLocalError: local variable 'commands' referenced before assignment

i can input the command by hand and it works without error ! i try the global commands but it not work


Solution

  • If an exception is raised, you won't assign commands. You can assign a default value before the try block.

    def take_request():
        commands = ""
        try:
            with sr.Microphone() as source:
                talk("i am listening")
                print("listening ....")
                voice = listener.listen(source)
                command = listener.recognize_google(voice)
                print(command)
                #command = input("say sth : ")
                commands= command.lower()
                if "a" in commands:
                    print(commands)
    
        except:
            pass
        return commands