Cвой Джарвис на Python

Cвой Джарвис на Python

PythonGuru

Привет, любитель Python!

Я думаю что все знают голосового помощника Джарвиса из фильма "Железный человек". И много кто мечтал сделать голосового помощника своими руками. В этой статье мы его напишем.

Что понадобится

  1. Python версии 3.6.8
  2. Установленные по порядку модули: Librariespywin32, pipywin32, pyttsx3, SpeechRecognition, PyAudio, fuzzywuzzy, pyowm, python-Levenshtein, CurrencyConverter.

Написание самого помощника

Создаём в папке вот такие файлы:

functions.py

Открываем файл functions.py и импортируем библиотеки и остальные файлы:

import pyttsx3
import speech_recognition as sr
import os
from fuzzywuzzy import fuzz
import datetime
import win32com.client as wincl
import site
import calculator
import envelope
import translator

После этого вставляем данный код и вписываем в строку alias название помощника(у нас pythonguru):

opts = {"alias": ('pythonguru', 'пайтонгуру', 'гурупайтон'),
        "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"

Если у вас не работает микрофон то пробуйте менять значение device_index=1 (например на device_index=2)

Далее вставляем весь этот код (функции разговора ассистента, фунции прослушки микрофона и возможности самого ассистента):

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

Этот файл будет служить для запуска всего ассистента

import functions
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()

site.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', 'aliexpress', 'алиэспресс'], 'http://google.com':['гугл','google'], 'https://www.amazon.com':['амазон', 'amazon'], 'https://www.apple.com/ru':['apple','эпл'] '
https://ttttt.me/gurupython':['пайтонгуру', 'pythonguru']}
    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

calculator.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("Скажите, например: Сколько будет 5+5?")

envelope.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

translator.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("Обратитесь к переводчику, начиная со слова 'Переводчик'")


Как видите сделать своего голосового помощника на Python не так уж сложно, главное иметь знания об основах языка и всё получится.

Совершенствуй знания по Python каждый день у нас на канале, PythonGuru.

Вопросы, реклама - @pythonguru_admin

Поддержать проект (сбербанк):

4817760113082329

Report Page