0

This program is basically a hardcoded personal assistant which I use to do basic stuff. I tell the program to 'Open Firefox', it opens it perfectly, When I give another command, lets say 'Open Sublime', it will still open Firefox. Why is that? I don't want it to open other applications if I didn't ask it to. Is it happening because I'm running the application but I am not closing it through the script, Like I press 'X' and close the window. Really stuck on this one!

Here is my code...

import speech_recognition as sr
import pyttsx3
import json
import random
import os
import subprocess

engine = pyttsx3.init('sapi5')
voices = engine.getProperty('voices')
engine.setProperty('voice', voices[1].id)

def text2speech(audio):
    engine.setProperty('rate', 180) # Sets speed percent can be more than 100
    engine.say(audio)
    engine.runAndWait()

def takeCommand():
    r = sr.Recognizer()

    with sr.Microphone() as source:
        r.adjust_for_ambient_noise(source)
        print('Listening...')
        r.pause_threshold = 1
        audio = r.listen(source)

    try:
        print('Recognizing...')
        query = r.recognize_google(audio, language = 'en-in')
        print('You: ', query)
    except Exception as e:
        print(e)
        print('Unable to recognize your voice.')
        return 'None'
    return query

def rubysays(key): # key is the tag or key element in the data.json which contains the responses
    length = len(data[key])
    # print(length)
    say_this = data[key][random.randint(0, length - 1)]
    return say_this

def startruby():
    query = takeCommand().lower()

    if 'open firefox' or 'pen firefox' or 'firefox' or 'fire fox' in query: # opens Visual Studio Code
        say_this = 'Opening Firefox Browser'
        print(say_this)
        text2speech(say_this)
        # os.startfile(r'C:\Program Files\Mozilla Firefox\firefox.exe')
        os.system(r'C:\Program Files\Mozilla Firefox\firefox.exe')
    
    elif 'open code' or 'pen code' in query: # opens Visual Studio Code
        say_this = 'Opening Visual Studio Code'
        print(say_this)
        text2speech(say_this)
        # os.startfile(r'C:\Program Files\Microsoft VS Code\Code.exe')
        os.system(r'C:\Program Files\Microsoft VS Code\Code.exe')
    
    elif 'open sublime' or 'pen sublime' or 'open sub lime' or 'pen sub lime'in query: # opens Sublime Text
        say_this = 'Opening Sublime Text'
        print(say_this)
        text2speech(say_this)
        # os.startfile(r'C:\Program Files\Sublime Text 3\sublime_text.exe')
        os.system(r'C:\Program Files\Sublime Text 3\sublime_text.exe')

    elif 'open cmd' or 'c m d' in query: # opens command prompt
        say_this = 'Opening Windows Terminal'
        print(say_this)
        text2speech(say_this)
        # os.startfile(r'C:\Users\JasonPC\AppData\Local\Microsoft\WindowsApps\wt.exe')
        os.system(r'C:\Users\JasonPC\AppData\Local\Microsoft\WindowsApps\wt.exe')

    elif 'open discord' or 'discord' in query: # opens Discord
        say_this = 'Opening Discord'
        print(say_this)
        text2speech(say_this)
        # os.startfile(r'C:\Users\JasonPC\AppData\Local\Discord\Update.exe')
        os.system(r'C:\Users\JasonPC\AppData\Local\Discord\Update.exe')
    
    elif 'open steam' or 'steam' in query: # opens Steam
        say_this = 'Opening Steam'
        print(say_this)
        text2speech(say_this)
        # os.startfile(r'C:\Program Files (x86)\Steam\steam.exe')
        os.system(r'C:\Program Files (x86)\Steam\steam.exe')
    
    elif 'open calculator' or 'calculator' in query: # opens Calculator
        say_this = 'Opening Calculator'
        print(say_this)
        text2speech(say_this)
        # os.startfile(r'C:\Windows\System32\calc.exe')
        os.system(r'C:\Windows\System32\calc.exe')
    
    elif 'open discord' or 'discord' in query: # opens Camera
        say_this = 'Opening Camera'
        print(say_this)
        text2speech(say_this)
        os.system('start microsoft.windows.camera:')
    
    elif 'whatsapp' or 'whats app' or 'whats up' or "what's app" or "what's up" in query: # opens WhatsApp
        say_this = 'Opening WhatsApp'
        print(say_this)
        text2speech(say_this)
        # os.startfile(r'C:\Users\JasonPC\AppData\Local\WhatsApp\WhatsApp.exe')
        os.system(r'C:\Users\JasonPC\AppData\Local\WhatsApp\WhatsApp.exe')


if __name__ == '__main__':
    # use the json
    f = open('data.json')  
    data = json.load(f)

    text2speech('Hey this is Ruby!')

    while True:
        query = takeCommand().lower()

        if 'ruby' in query or 'rubi' in query:
            say_this = rubysays('greeting')
            print('You:', say_this)
            text2speech(say_this)
            startruby()
        
        if 'bye' in query or 'goodbye' in query:
            say_this = rubysays('bye')
            print(say_this)
            text2speech(say_this)
            exit()
Jason Abba
  • 23
  • 2
  • 1
    `a or b in c` is not the same as `a in c or b in c` – Charles Duffy Aug 16 '21 at 20:09
  • 1
    This is a typical problem, thinking Python understands your English intent. `if 'some nonempty string'` is always true. In the future, I strongly recommend stripping the problem down to a [mcve]. Remove branches and the speech to text and microphone stuff until you're left with a single branch that exhibits the behavior, then the problem and solution are obvious. See also [Why does `a == x or y or z` always evaluate to True?](https://stackoverflow.com/questions/20002503/why-does-a-x-or-y-or-z-always-evaluate-to-true) – ggorlen Aug 16 '21 at 20:11
  • BTW, consider using regular expressions (compiled and reused) instead of a succession of individual substring matches. A good regex engine can process an input string in a single pass without backtracking even when there are multiple possible substrings that might be matched. – Charles Duffy Aug 16 '21 at 20:24
  • Your second comment has definitely cleared out some logical mistakes, thank you very much @CharlesDuffy – Jason Abba Aug 16 '21 at 20:37

1 Answers1

0

See How to test multiple variables against a single value?

The line: if 'open firefox' or 'pen firefox' or 'firefox' or 'fire fox' in query: will be always true as you are testing a string not if the string is in query.

For example:

In [1]: query = "xxx"

In [2]: bool('open firefox' or 'pen firefox' or 'firefox' or 'fire fox' in query)
Out[2]: True

In [3]: bool('fire fox' in query)
Out[3]: False

In [4]: bool('open firefox')
Out[4]: True
Andrew
  • 146
  • 5
  • 1
    There's already at least a couple canonical threads for this: [How to test multiple variables against a single value?](https://stackoverflow.com/questions/15112125/how-to-test-multiple-variables-against-a-single-value) or [Why does `a == x or y or z` always evaluate to True?](https://stackoverflow.com/questions/20002503/why-does-a-x-or-y-or-z-always-evaluate-to-true). I suggest letting the finely-honed answers in that thread speak to the solution rather than reinventing it all over again here. – ggorlen Aug 16 '21 at 20:12
  • Thanks, should have checked for that answer first – Andrew Aug 16 '21 at 20:15
  • (On the above point, see [How to Answer](https://stackoverflow.com/help/how-to-answer), and the section _Answer Well-Asked Questions_ therein, particularly the bullet point regarding questions that "...have already been asked and answered many times before") – Charles Duffy Aug 16 '21 at 20:16
  • Thanks for the response! @Andrew I'll apply the fix – Jason Abba Aug 16 '21 at 20:39