Свой голосовой помощник на Python

Свой голосовой помощник на Python

overlamer1

Технологии не стоят на месте, поэтому только на сегодняшний день мы уже имеем множество вариантов голосовых ассистентов - искусственные интеллекты, способные выполнять множество задач для нас.


Как насчёт попробовать написать на языке Python такого помощника? Конечно же он будет наипростейший, ибо всяких Яндекс Алис, Сири и т.п. делают целые команды профессиональных программистов.


Ну что же, давайте начнём:

Для начала скачаем python 3.6.8 (ИМЕННО 3.6.8) https://www.python.org/ftp/python/3.6.8/python-3.6.8-amd64.exe

С установкой думаю, вы сами разберётесь, ничего сложного.


После успешной установки могу вам предложить 2 варианта:

1. Писать код прямо в IDLE (устанавливается вместе с python)

2. Скачать другую, более удобную IDE (Visial Studio, pycharm и т.д.)


Лично я буду писать код в pycharm - https://www.jetbrains.com/pycharm/download/#section=windows


Теперь создаём вот такие файлы (.py):

Открываем файл funcs.py и если вы пишете код в pycharm, как я, то нажимаем комбинацию ctrl+alt+s

Откроется окно, где надо будет выбрать pip и скачать все эти библиотеки:

Librariespywin32, pipywin32, pyttsx3 (важен порядок установки)

SpeechRecognition, PyAudio, fuzzywuzzy, pyowm, python-Levenshtein, CurrencyConverter


Но если же вы пишите код в других IDE, то надо будет открыть cmd и каждую библиотеку прописывать "pip install название библиотеки".


funcs.py

После того, как все библиотеки установлены, импортируем их в funcs.py:

import pyttsx3
import speech_recognition as sr
import os
from fuzzywuzzy import fuzz
import datetime
import win32com.client as wincl
import time

Также подключаем остальные файлы, которые мы создали:

import anekdot
import browser
import calc
import convert
import translate

Далее прописываем имя ассистента (в нашем случае лолзтим), различные обращения к нему и возможности:

opts = {"alias": ('порнозем', 'порн', 'порно'),
        "tbr": ('скажи', 'расскажи', 'покажи', 'сколько', 'произнеси', 'как','сколько','поставь','переведи', "засеки",'запусти','сколько будет'),
        "cmds":
            {"ctime": ('текущее время', 'сейчас времени', 'который час', 'время'),
             'startStopwatch': ('запусти секундомер', "включи секундомер", "начини"),
             'stopStopwatch': ('останови секундомер', "выключи секундомер", "прекрати"),
             "stupid1": ('расскажи анекдот', 'рассмеши меня', 'ты знаешь анекдоты', "шутка"),
             "calc": ('прибавить','умножить','разделить','степен','вычесть','поделить','х','+','-','/'),
             "shutdown": ('выключи', 'выключить', 'отключение', 'отключи', 'выключи компьютер'),
             "conv": ("валюта", "конвертер","доллар",'руб','евро'),
             "internet": ("открой", "вк", "гугл", "сайт", 'вконтакте', "ютуб"),
             "translator": ("переводчик","translate"),
             "deals": ("дела","делишки", 'сам')}}

Подключаем микро и голос:

startTime = 0
speak_engine = pyttsx3.init()
voices = speak_engine.getProperty('voices')
speak_engine.setProperty('voice', voices[2].id)
r = sr.Recognizer()
m = sr.Microphone(device_index=1)
voice = "str"

Возможно индекс вашего микрофона другой, поэтому попробуйте разные значения.


Функции разговора нашего ассистента:

def speak(what):
     print(what)
     speak = wincl.Dispatch("SAPI.SpVoice")
     speak.Speak(what)

def callback(recognizer, audio):
    try:
        global voice
        voice = recognizer.recognize_google(audio, language="ru-RU").lower()

        print("[log] Распознано: " + voice)

        if voice.startswith(opts["alias"]):
            cmd = voice

            for x in opts['alias']:
                cmd = cmd.replace(x, "").strip()

            for x in opts['tbr']:
                cmd = cmd.replace(x, "").strip()
            voice = cmd
            # распознаем и выполняем команду
            cmd = recognize_cmd(cmd)
            execute_cmd(cmd['cmd'])


    except sr.UnknownValueError:
        print("[log] Голос не распознан!")
    except sr.RequestError as e:
        print("[log] Неизвестная ошибка, проверьте интернет!")

Функции прослушки нашего микрофона ассистентом:

def listen():
    with m as source:
        r.adjust_for_ambient_noise(source)
    stop_listening = r.listen_in_background(m, callback)
    while True: time.sleep(0.1)

def recognize_cmd(cmd):
    RC = {'cmd': '', 'percent': 0}
    for c, v in opts['cmds'].items():
        for x in v:
            vrt = fuzz.ratio(cmd, x)
            if vrt > RC['percent']:
                RC['cmd'] = c
                RC['percent'] = vrt
    return RC

И прописываем возможности помощника:

ef execute_cmd(cmd):
    global startTime
    if cmd == 'ctime':
        now = datetime.datetime.now()
        speak("Сейчас {0}:{1}".format(str(now.hour), str(now.minute)))
    elif cmd == 'shutdown':
        os.system('shutdown -s')
        speak("Выключаю...")
    elif cmd == 'calc':
        calc.calculator()
    elif cmd == 'conv':
        convert.convertation()
    elif cmd == 'translator':
        translate.translate()
    elif cmd == 'stupid1':
        anekdot.fun()
    elif cmd == 'internet':
        browser.browser()
    elif cmd == 'startStopwatch':
        speak("Секундомер запущен")
        startTime = time.time()
    elif cmd == "stopStopwatch":
        if startTime != 0:
            Time = time.time() - startTime
            speak(f"Прошло {round(Time // 3600)} часов {round(Time // 60)} минут {round(Time % 60, 2)} секунд")
            startTime = 0
        else:
            speak("Секундомер не включен")
    elif cmd == 'deals':
        speak("Голова пока цела. Я имею ввиду процессор.")
    else:
        print("Команда не распознана")


start.py

Это будет главный файл для запуска нашего ассистента, импортируем туда funcs, прописываем приветствие и прослушку:

import funcs
import time
import datetime


now = datetime.datetime.now()

if now.hour >= 6 and now.hour < 12:
    funcs.speak("Доброе утро!")
elif now.hour >= 12 and now.hour < 18:
    funcs.speak("Добрый день!")
elif now.hour >= 18 and now.hour < 23:
    funcs.speak("Добрый вечер!")
else:
    funcs.speak("Доброй ночи!")

funcs.listen()

Уже на данном этапе наш ассистент работает и может выполнять некоторые функции. Давайте немного расширим его возможности и пропишем код в остальных, созданных нами файлах:

anekdot.py

from random import choice
import funcs
def fun():
    anekdots = ["Хрен вам, а не налоги на недвижемость!- приговаривала Баба- Яга, приделывая к избушке куринные ножки.",
                "— Дорогая, что ты подумала, когда я пришел пьяный и с фингалом? — Когда ты пришел – фингала еще не было",
                "Почему кошки научились видеть в темноте? Потому что не достают до выключателя.",
                "Учительница спрашивает Вовочку: — Вовочка, ты зачем так мелко пишешь? — Чтобы ошибки были не так заметны, Марь Иванна",
                "Урок химии. — Вова, что ты можешь сказать о молекулах соли? — Они хорошо сочетаются с молекулами огурца.",
                "— Можно выйти? — Вовочка, до звонка никто не выходит! — Мариванна, я с вами случайно в одной маршрутке еду!",
                "— Алло, скорая?! Приезжайте, тут людям плохо! — Диктуйте адрес. — Россия.",
                "Муж смотрит телевизор и вслух говорит: — Не иди туда. Ну не иди дурак… Жена спрашивает: — Что смотришь? Ужасы? Муж: — Нашу свадьбу...",
                "В 3 часа ночи звонок в дверь:" "— Кто там?" " — Грабители, нам нужно 100 кг золота." " — А 105 кг не надо??" " — Ну давайте 105. " "— Ксюшенька, золотце, вставай за тобой пришли.",
                "Преподаватель — студенту: — Вы были в армии? Студент: — Нет, а что? Препод: — Да так... могу устроить."]
    funcs.speak(choice(anekdots))

Или можете поместить список анекдотов в файл и читать из него.


browser.py

import webbrowser
import funcs
def browser():
    sites = {"https://vk.com":["vk","вк"], 'https://www.youtube.com/':['youtube', 'ютуб'],
             'https://ru.wikipedia.org': ["вики", "wiki"], 'https://ru.aliexpress.com':['али', 'ali'],
             'http://google.com':['гугл','google'], 'https://www.amazon.com':['амазон', 'amazon'],
             'https://www.apple.com/ru':['apple','эпл']}
    site = funcs.voice.split()[-1]
    for k, v in sites.items():
        for i in v:
            if i not in site.lower():
                open_tab = None
            else:
                open_tab = webbrowser.open_new_tab(k)
                break

        if open_tab is not None:
            break

Также в список сайтов не забудьте добавить лолзтим))


calc.py

Простейший калькулятор:

import funcs
def calculator():
    try:
        list_of_nums = funcs.voice.split()
        num_1,num_2 = int((list_of_nums[-3]).strip()), int((list_of_nums[-1]).strip())
        opers = [list_of_nums[0].strip(),list_of_nums[-2].strip()]
        for i in opers:
            if 'дел' in i or 'множ' in i or 'лож' in i or 'приба' in i or 'выч' in i or i == 'x' or i == '/' or i =='+' or i == '-' or i == '*':
                oper = i
                break
            else:
                oper = opers[1]
        if oper == "+" or 'слож' in oper:
            ans = num_1 + num_2
        elif oper == "-" or 'выче' in oper:
            ans = num_1 - num_2
        elif oper == "х" or 'множ' in oper:
            ans = num_1 * num_2
        elif oper == "/" or 'дел' in oper:
            if num_2 != 0:
                ans = num_1 / num_2
            else:
                funcs.speak("Деление на ноль невозможно")
        elif "степен" in oper:
            ans = num_1 ** num_2
        funcs.speak("{0} {1} {2} = {3}".format(list_of_nums[-3], list_of_nums[-2], list_of_nums[-1], ans))
    except:
        funcs.speak("Скажите, например: Сколько будет 2+2?")


convert.py

from currency_converter import CurrencyConverter
import funcs
def convertation():
    class CurrencyError(Exception):
        pass
    c = CurrencyConverter()
    money = None
    from_currency = None
    to_currency = None
    list_of_conv = funcs.voice.split()
    if len(list_of_conv) > 4:
        list_of_conv = list_of_conv[1:]
    else:
        print()
    while money is None:
        try:
            money = list_of_conv[0]
        except ValueError:
            funcs.speak("Скажите, к примеру: 50 долларов в рубли")
            break
    while from_currency is None:
        try:
            list_of_conv[0] = int(list_of_conv[0])
        except ValueError:
            funcs.speak("Скажите, к примеру: 50 долларов в рубли")
            break
        try:
            if "руб" in list_of_conv[1]:
                from_currency = "RUB"
            elif "дол" in list_of_conv[1]:
                from_currency = "USD"
            elif "евр" in list_of_conv[1]:
                from_currency = "EUR"
            if from_currency not in c.currencies:
                raise CurrencyError

        except (CurrencyError, IndexError):
            from_currency = None
            funcs.speak("Скажите, например: 50 долларов в рубли")
            break

    while to_currency is None:
        try:
            list_of_conv[0] = int(list_of_conv[0])
        except ValueError:
            return None
        try:
            if "руб" in list_of_conv[3]:
                to_currency = "RUB"
            elif "дол" in list_of_conv[3]:
                to_currency = "USD"
            elif "евр" in list_of_conv[3]:
                to_currency = "EUR"
            if to_currency not in c.currencies:
                raise CurrencyError

        except (CurrencyError, IndexError):
            to_currency = None
            funcs.speak("Скажите, например: 50 долларов в рубли")
            break
    while True:
        try:
            funcs.speak(f"{money} {from_currency} в {to_currency} - "
                f"{round(c.convert(money, from_currency, to_currency), 2)}")
            break
        except ValueError:
            funcs.speak("Скажите, например: 50 долларов в рубли")
            break


translate.py

import requests
import funcs

def translate():
    url = 'https://translate.yandex.net/api/v1.5/tr.json/translate?'
    key = 'trnsl.1.1.20190227T075339Z.1b02a9ab6d4a47cc.f37d50831b51374ee600fd6aa0259419fd7ecd97'
    text = funcs.voice.split()[1:]
    lang = 'en-ru'
    r = requests.post(url, data={'key': key, 'text': text, 'lang': lang}).json()
    try:
        funcs.speak(r["text"])
    except:
        funcs.speak("Обратитесь к переводчику, начиная со слова 'Переводчик'")


Обзор:



Report Page