Python return statement never reached but prints immediately before it

96 Views Asked by At

I am trying to call a take_command() function from main.py.

The system prints the value right before the return call, but doesn't actually return the value to main.py. The take_command() function was working fine before I refactored and added in the start_recognizer() and callback() functions to run constantly and listen for triggers.

I know I must be missing something very simple in my refactor but honestly have not been able to find the issue.

command.py:

import time
import speech_recognition as speech

listener = speech.Recognizer()
keywords = [("randy", 1), ("hey randy", 1), ]
source = speech.Microphone()


def start_recognizer():
    print("Listening...")
    listener.listen_in_background(source, callback)
    time.sleep(1000000)


def callback(recognizer, audio):  # This is called from the background thread
    try:
        speech_as_text = recognizer.recognize_sphinx(audio, keyword_entries=keywords)
        print(speech_as_text)

        # Look for your "Ok Google" keyword in speech_as_text
        if "randy" in speech_as_text or "hey randy":
            take_command()

    except:
        pass


def take_command():
    print("Recognizing Main...")
    voice = listener.listen(source)
    the_command = listener.recognize_google(voice)
    the_command.lower()
    print(the_command)
    return the_command

    # Interpret the user's words however you normally interpret them

main.py:

from lib import jokes
from lib import engine
from lib import time
from lib import command
from lib import wikipedia
from lib import youtube


def run_randy():
    user_command = command.start_recognizer()
    print('in main' + user_command)
    if 'play' in user_command:
        engine.talk('playing' + youtube.play_song(user_command))
    elif 'joke' in user_command:
        engine.talk(jokes.jokes())
    elif 'time' in user_command:
        engine.talk('Current time is ' + time.get_time())
    elif 'who is' in user_command:
        engine.talk(wikipedia.get_person(user_command))
    else:
        engine.talk('Please say the command again.')


while True:
    run_randy()

The output is this:

Listening...
hey randy  randy 
Recognizing Main...
in take_command(): tell me a joke
2

There are 2 best solutions below

0
Anynamer On

It is a bit hard to read, but I think you need to return in the callback() function? i.e. :

def callback(...):
    ...
    return take_command()
0
Code-Apprentice On

There are multiple problems with your code as mentioned in the comments. However, the issue that you are asking about is a problem with your expectations about how the code works. I expect that user_command = command.start_recognizer() is blocking. start_recognizer() certainly never returns an explicit value, so if it ever does return, it will return None, not a command as you seem to expect.

I suggest you find the documentation for the Recognizer class and its listen_in_background() method in order to better understand what your code is doing. My guess is that listen_in_background() has an infinite loop to continue listening to the microphone. This means it will never return back to run_randy() to print out the output there.