U
U
UMFUCHI2021-10-10 13:11:57
Python
UMFUCHI, 2021-10-10 13:11:57

How to make 1 response for 2 commands?

Here is the whole code:

spoiler
import os
import pyautogui
from gtts import gTTS
import random
import time
from time import sleep
import datetime
import playsound
import speech_recognition as sr
import pyautogui as pg




def listen_command():

    r = sr.Recognizer()
    with sr.Microphone() as source:
        print("Скажите вашу команду: ")
        audio = r.listen(source)


    try:
        our_speech = r.recognize_google(audio, language="ru")
        print("Вы сказали: " + our_speech)
        return our_speech
    except sr.UnknownValueError:
        return "ошибка"
    except sr.RequestError:
        return "ошибка"

class VoiceCommandList:
    def __init__(self):
        self.actions = list()

    def on(self, condition):
        if isinstance(condition, str):
            condition = condition.lower()
            predicate = lambda text: condition in text
        elif callable(condition):
            predicate = condition
        else:
            raise TypeError('Condition must be either string or function!')


        def decorator(command_func):
            self.actions.append((predicate, command_func))
            return command_func

        return decorator

    def run_command(self, text):
        text = text.lower()
        for predicate, command in self.actions:
            if predicate(text):
                try:
                    response = command(text)
                    if response is None:
                        response = "Команда выполнена"
                except Exception as err:
                    response = "Ошибка при выполнении команды"
                    print(err)
                if response:
                    say_message(response)
                break
        else:
            say_message("Неизвестная команда")
vcl = VoiceCommandList()



@vcl.on('привет')
def hello(text):
  return "Здравствуйте, сэр!"



def say_message(message):
    voice = gTTS(message, lang="ru")
    file_voice_name = "_audio_" + str(time.time()) + "_" + str(random.randint(0, 100000)) + ".mp3"
    voice.save(file_voice_name)
    playsound.playsound(file_voice_name)
    print("Голосовой ассистент: " + message)


if __name__ == '__main__':
    while True:
        command = listen_command()
        vcl.run_command(command)

How to make, for example
@vcl.on('привет' or 'Здравствуй' or 'Доброе утро')
def hello(text):
  return "Здравствуйте, сэр!"

Responded not only to "Hi", but also to the rest?

Answer the question

In order to leave comments, you need to log in

2 answer(s)
A
Andrey Marchenko, 2021-10-10
@MrSmitix

I think it would be better to use lists than or
In the VCL class, you need to create an on function that will return a decorator, which in turn will save information to a list ala [{func => rules}], Then you just look for the desired steering wheel, and if it exists, you call the function to which it belongs.
In this case, the design will be similar to
@vcl.on(['привет', 'здравствуй, 'доброе утро'])
You can see how it is implemented in VKBottle

S
soremix, 2021-10-10
@SoreMix

Just like with one word, by analogy

def on(self, condition):
    if isinstance(condition, list):
        conditions = [el.lower() for el in condition]
        predicate = lambda text: any(condition in text for condition in conditions)
    elif isinstance(condition, str):
        condition = condition.lower()
        predicate = lambda text: condition in text

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question