4

I am using a speech recognition library to create a Siri like program. I hope that in the future I can use the code with an Arduino to control things around my room. Here is my problem:

I have the basic speech recognition code worked out but for the program to understand certain commands I would have to run the speech through a very long list of if-elif-elif-elif-else commands and that might be slow. As most of the time it will be resulting at else as the command will not be recognized I need a faster alternative to a long chain of if-elif-else statements. I am also using a tts engine to talk back to you.

here is my code so far

import pyttsx
import time


engine = pyttsx.init()
voices = engine.getProperty("voices")
spch = "There is nothing for me to say"
userSaid = "NULL"



engine.setProperty("rate", 130)
engine.setProperty("voice", voices[0].id)


def speak():
    engine.say(spch)
    engine.runAndWait()
def command():
    **IF STATEMENT HERE**

r = sr.Recognizer()
with sr.Microphone() as source:
    r.adjust_for_ambient_noise(source) 
    print("CaSPAR is calibrated")
    audio = r.listen(source)
try:
    userSaid = r.recognize_google(audio)
except sr.UnknownValueError:
    spch = "Sorry, I did'nt hear that properly"
except sr.RequestError as e:
    spch = "I cannot reach the speech recognition service"

speak()
print "Done"
HRLD
  • 85
  • 1
  • 8
  • 2
    Welcome to Stack Overflow. Your question is _Too Broad_: There are either too many possible answers, or good answers would be too long for this format. Please add details to narrow the answer set or to isolate an issue that can be answered in a few paragraphs. See http://stackoverflow.com/help/how-to-ask – Selcuk Feb 18 '16 at 14:31
  • 2
    We need to know a bit more about how your code works to provide reasonable answers – Mr. E Feb 18 '16 at 14:31
  • 1
    Please view the answer provided by Aya to a similar question asked previously: http://stackoverflow.com/questions/17166074/most-efficient-way-of-making-an-if-elif-elif-else-statement-when-the-else-is-don – abhi Feb 18 '16 at 14:32
  • @Falafel I have viewed this question before and because I am relatively new to python I didn't fully understand how to use the suggestion – HRLD Feb 18 '16 at 14:36

1 Answers1

2

Try using a dictionary setting in which the key is the value that you are testing for and the entry for that key is a function to process. Some of the text books on Python point out that this is a more elegant solution than a series of if ... elif statements and picks up the entry immediately instead of having to test each possibility. Note that since each key can be of any type, this is better than something like the switch statement in C which requires the switch argument and the cases to be integer values. For example.

def default(command)
    print command, ' is an invalid entry'

mydict = {'create':mycreate, 'delete':mydelete, 'update':myupdate}

action = mydict.get(command, default)
# set up args from the dictionary or as command for the default.
action(*args)

An interesting point is that Most efficient way of making an if-elif-elif-else statement when the else is done the most? states that while the get is more "elegant" it may actually be slower than the code below. However, that may be because the post deals with direct operations and not function calls. YMMV

def default(command)
    print command, ' is an invalid entry'

mydict = {'create':mycreate, 'delete':mydelete, 'update':myupdate}

if command in mydict:
    action = mydict.[command]
    # set up args from the dictionary .
    action(*args)
else:
    default(command)
Community
  • 1
  • 1
sabbahillel
  • 4,357
  • 1
  • 19
  • 36
  • 1
    Instead of checking if the key exists, use the `.get` method of dictionaries with a default value, such as a no-op lambda or notifying print statement. – cat Feb 18 '16 at 14:46
  • 1
    @cat done. That is why I added the comment on setting up args. – sabbahillel Feb 18 '16 at 14:50
  • @cat I also pointed to a post comparing the two methods as far as timing goes and added that information to the post. – sabbahillel Feb 18 '16 at 15:04