Свой голосовой помощник на 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("Обратитесь к переводчику, начиная со слова 'Переводчик'")
Обзор: