Голосовой ассистент на Python (Виталий alfa 2.0)

Привет хабр! Меня зовут Глеб Пряхин, мне 14 лет, я написал голосового ассистента на python 3 и скомпилировал его в exe.

(Ссылка на скомпилированный вариант)

(Ссылка на исходник)

Прошу протестировать помощника и позадавать ему вопросы,

если у вас появились вопросы или вы хотите написать в поддержку: в комментах под постом, или на эл. почту glebilic@gmail.com.


Приступим к коду! Для начала импортируем модули:

import pyttsx3
import os
import time
import datetime
import speech_recognition as sr
import random
import webbrowser
import sounddevice as sd

Для добавления голосов скачиваем и устанавливаем RHvoice.

Теперь ассистент читает файл с кол-во просмотров и подгружает файл tts, где хранится нумер голоса. Переменная num123 = количеству просмотров, а tts1 = нумеру голоса в синтезаторе речи.

f = open("sp.txt", "r")
num123 = f.read(1000)
num123 = int(num123)
f.close

f = open("tts.txt", "r")
tts1 = int(f.read(1))
f.close()
#синтез речи
tts = pyttsx3.init()
speak_engine = pyttsx3.init()

voices = speak_engine.getProperty('voices')
speak_engine.setProperty('voice', voices[tts1].id)

Простейшая шапка для программы:

os.system('cls' if os.name == 'nt' else 'clear')
print("ВИТАЛИЙ 2.0 ALFA \nBy Глеб Пряхин\n2021 \n-загрузка...")

Теперь мы читаем файл name и понимаем, что ужас! Наш пациент, ой то есть клиент не зарегистрировался в системе! Вызываем форму регистрации:

f = open('name.txt', 'r')
if f.read(1) == "":
    os.system('cls' if os.name == 'nt' else 'clear')
    tts.say("Добрый день, я Виталий, я здесь, что бы вывести ваше взаимодействие с компьютером на новый, продуктивный уровень. Давайте знакомится. Как вас зовут?")
    tts.runAndWait()


    r = sr.Recognizer()
    with sr.Microphone(device_index = 1) as source:
        print(' ')
        r.adjust_for_ambient_noise(source, duration=0.5) #настройка посторонних шумов
        print('...')
        audio = r.listen(source)
        print(' ')
    try:
        query = r.recognize_google(audio, language = 'ru-RU')
        name = query.lower()
        print(f'Вы сказали: {query.lower()}')
            
    except:
        print('-')

    tts.say("Вас зовут")
    tts.runAndWait()
    tts.say(name)
    tts.runAndWait()
    tts.say("Подтвердите пожалуйста.")
    tts.runAndWait()
    r = sr.Recognizer()
    with sr.Microphone(device_index = 1) as source:
        print(' ')
        r.adjust_for_ambient_noise(source, duration=0.5) #настройка посторонних шумов
        print('...')
        audio = r.listen(source)
        print(' ')
    try:
        query = r.recognize_google(audio, language = 'ru-RU')
        ver = query.lower()
        print(f'Вы сказали: {query.lower()}')
            
    except:
        print('-')
    if "да" in ver or "подтверждаю" in ver:
        f = open('name.txt', 'w')
        f.write(name.title())
        f.close()
        tts.say("Готово! Теперь давайте поболтаем!")
        tts.runAndWait()
    
    else:
        tts.say("напишите свое имя на клавиатуре")
        tts.runAndWait()
        name = input("Ваше имя: ")
        tts.say("Готово! Теперь давайте поболтаем!")
        tts.runAndWait()
        f = open('name.txt', 'w')
        f.write(name.title())
        f.close()

Теперь, мы читаем кол-во просмотров, и понимаем что это "первый раз", поэтому начинаем читать инструктаж:

if num123 == 0:
        tts.say("Но сначала я хочу научить основным командам: И так вот список моих команд:")
        tts.runAndWait()
        tts.say("Тут текст инструктажа")
        tts.runAndWait()

Подготавливаем программу ко входу в центральный цикл:

#тут мы добавляем просмотр к счетчику просмотров
f = open("sp.txt", "w")
num123 = num123 + 1
num123 = str(num123)
num123 = f.write(num123)
f.close
#а тут читаем имя и создаем рандомное число
f = open('name.txt', 'r')
name = f.read(10)
r = random.randint(1,10)

В прошлом блоке мы сгенерировали рандомное число и занесли его в переменную r, теперь создадим elif`ки и зададим переменные cont, они понадобятся нам позже:

cont = ""
if r == 1:
    tts.say("Добрый день")
    tts.runAndWait()
    tts.say(name)
    tts.runAndWait()
    tts.say("Как дела?")
    tts.runAndWait()
elif r == 2:
    tts.say("Привет")
    tts.runAndWait()
    tts.say(name)
    tts.runAndWait()
    tts.say("Чем могу помочь?")
    tts.runAndWait()
elif r == 3:
    tts.say("Привет привет")
    tts.runAndWait()
    tts.say(name)
    tts.runAndWait()
    tts.say("Чем займемся?")
    tts.runAndWait()
elif r == 4:
    tts.say("Добрый день")
    tts.runAndWait()
    tts.say(name)
    tts.runAndWait()
    tts.say("Хотите открою почту?")
    tts.runAndWait()
    cont = ("почта")

elif r == 5:
    tts.say("Добрый день")
    tts.runAndWait()
    tts.say(name)
    tts.runAndWait()
    tts.say("Открыть ютуб?")
    tts.runAndWait()
    cont = "ютуб"
elif r == 6:
    tts.say("Привет")
    tts.runAndWait()
    tts.say(name)
    tts.runAndWait()
    tts.say("Посмотрим кино?")
    tts.runAndWait()
    cont = "кино"
elif r == 7:
    tts.say("Добрый день")
    tts.runAndWait()
    tts.say(name)
    tts.runAndWait()
    tts.say("Что хотите узнать?")
    tts.runAndWait()
elif r == 8:
    tts.say("Приветики")
    tts.runAndWait()
    tts.say(name)
    tts.runAndWait()
    tts.say("Хотите почитать последние новости?")
    tts.runAndWait()
    cont = "новости"
elif r == 9:
    tts.say("Добрый день")
    tts.runAndWait()
    tts.say(name)
    tts.runAndWait()
    tts.say("Где вы были?")
    tts.runAndWait()
elif r == 10:
    tts.say("Добрый день")
    tts.runAndWait()
    tts.say(name)
    tts.runAndWait()
    tts.say("Как дела?")
    tts.runAndWait()

Входим в цикл:

while True:
    cikl = cikl + 1
    ca = 0
    ra = random.randint(1,10)
    an = ""
    #распознание
    r = sr.Recognizer()
    with sr.Microphone(device_index = 1) as source:
        print(' ')
        r.adjust_for_ambient_noise(source, duration=0.5) 
        print('...')
        audio = r.listen(source)
        print(' ')
    try:
        query = r.recognize_google(audio, language = 'ru-RU')
        an = query.lower()
        print(f'Вы сказали: {query.lower()}')
            
    except:
        print('-')

И создадим первую команду "да", помните переменную cont? Так вот она отличает ответ "да" на вопрос "открыть ютуб?", и "да" на вопрос "Включить новости?", если контекста нет, то он просто ответит стандартным ответом.

 #да
    if "да" in an and len(an) == 2 or "давай" in an or "почему-бы и нет" in an:
        ca = 1
        if cont == "почта":
            f = open('email.txt', 'r')
            if f.read(1) == "":
                tts.say("Я совсем забыл, на каком сервисе зарегистрирована ваша почта! Пожайлуста выберете на экране нужную.")
                tts.runAndWait()
                a = 1
                while True:
                    v = input("Вставьте ссылку для почтового сервиса.")
                    f = open('email.txt', 'w')
                    if "https" in v:
                        web = v
                        f.write(web)
                        f.close()
                        break

            tts.say("открываю почту")
            f = open('email.txt', 'r')
            web = f.read(97)
            f.close()
            tts.runAndWait()
            webbrowser.open(web)
        
        elif cont == "ютуб":
            tts.say("Хорошо, включаю его")
            tts.runAndWait()
            webbrowser.open('https://www.youtube.com/')

        elif cont == "кино":
            tts.say("Давайте подберем что нибудь на око")
            tts.runAndWait()
            webbrowser.open('https://okko.tv/')

        elif cont == "новости":
            tts.say("Открываю евроньюс!")
            tts.runAndWait()
            webbrowser.open('https://www.youtube.com/watch?v=E3rH3KdVWcc')
        
        elif cont == "ютубпр":
            tts.say("Вот, надеюсь вам понравится")
            tts.runAndWait()
            webbrowser.open('https://www.youtube.com/channel/UCy0uukwm4dOSFCGyfp8g2sw')
        else:
            tts.say("Это очень хорошо.")
            tts.runAndWait()

Теперь перейдем к интернет командам. Я приведу по 1 примеру на каждый их вид:

Супер простая команда открывающая один сайт:

elif "вк " in an or "вконтакте" in an:
        ca = 1
        tts.say("Включаю вконтакте")
        tts.runAndWait()
        webbrowser.open("https:/vk.com")

Команда, которая выполняет поиск по сайту:

elif "найди в интернете" in an:
        ca = 1
        tts.say("Выполняю поиск по запросу")
        tts.runAndWait()
        tts.say(an[an.find("ете")+3:])
        tts.runAndWait()
        sear = an[an.find("ете")+3:]
        webbrowser.open("https://www.google.com/search?q=" + sear)

Команда открывающая сайт, который сохранен в файл, и может изменятся:

elif "почт" in an:
        ca = 1
        f = open('email.txt', 'r')
        if f.read(1) == "":
            tts.say("Я совсем забыл, на каком сервисе зарегистрирована ваша почта! Пожайлуста выберете на экране нужную.")
            tts.runAndWait()
            a = 1
            while True:
                v = input("Вставьте ссылку для почтового сервиса.")
                f = open('email.txt', 'w')
                if "https" in v:
                    web = v
                    f.write(web)
                    f.close()
                    break

Далее перейдем к командам для компа:

Команда на выполнение команды в командной строке:

elif "если я скажу это" in an:
        ca = 1
        os.system('то помощник выполнит эту команду через командную строку')
        tts.say("И скажет это")
        tts.runAndWait()
        tts.say(name) #а потом имя произнесет.
        tts.runAndWait()

Команда на выключение компа:

  elif "выключи компьютер" in an or "заверши работу" in an:
        ca = 1
        tts.say("Досвидания")
        tts.runAndWait()
        tts.say(name)
        tts.runAndWait()
        tts.say("До новых встреч. Идет завершение работы.")
        tts.runAndWait()
        for i in range(10):
            os.system('cls' if os.name == 'nt' else 'clear')
            print("Выключение через", i, "секунд.")
            time.sleep(1)
        print("Выключение...")
        time.sleep(1)
        os.system('shutdown -s')

Заметки. Ассистент умеет хранить заметки, вот какой код работает для этого:

#память    
    elif "запомни" in an or "напомни" in an:
        ca = 1
        f = open("z1.txt", "a")
        if an[len("запомни"):] == "":
            tts.say("Заметка не может быть пустой! Если хотите создать новую, скажите запомни и то что вы хотите сохранить.")
            tts.runAndWait()
            print("Ошибка! Вы пытаетесь создать пустую заметку!")
        else:
            tts.say("Я запомнил, что бы прочитать эту заметку скажите, что ты помнишь?")
            tts.runAndWait()
            an45 = an[len("запомни"):] + ","
            f.write(an45)
            f.close()
    elif "помн" in an:
        ca = 1
        f = open("z1.txt", "r")
        if f.read(1) == "":
            tts.say("Похоже у вас еще нет заметок. Если хотите создать новую, скажите запомни и то что вы хотите сохранить.")
            tts.runAndWait()
        else:
            st = f.read()
            print(st)
            tts.say("И так вот что я помню:")
            tts.runAndWait()
            tts.say(st)
            tts.runAndWait()
            tts.say("Если хотите их удалить, скажите удалить все заметки.")
            tts.runAndWait()
            f.close()
    elif "удалить все заметки" in an or "удали все заметки" in an:
        ca = 1
        print("Вы уверены?")
        tts.say("Вы хотите удалить все заметки? Подтвердите пожайлуста.")
        tts.runAndWait()
        #распознание
        r = sr.Recognizer()
        with sr.Microphone(device_index = 1) as source:
            print(' ')
            r.adjust_for_ambient_noise(source, duration=0.5) #настройка посторонних шумов
            print('...')
            audio = r.listen(source)
            print(' ')
        try:
            query = r.recognize_google(audio, language = 'ru-RU')
            an = query.lower()
            print(f'Вы сказали: {query.lower()}')
            
        except:
            print('-')
        if an == "да" or "подтверждаю" in an or "утверждаю" in an:
            ca = 1
            print("Удаление...")
            f = open("z1.txt", "w")
            f.write("")
            tts.say("Удаление заметок завершено.")
            tts.runAndWait()
        else:
            print("Отмена...")
            tts.say("Подтверждение не получено, заметки не удалены. Ну вы меня и напугали...")
            tts.runAndWait()
        f.close()

Еще пара полезных функций:

elif "настройки" in an:
				ca = 1
        tts1 = input("введите номер голоса:")
        f = open("tts.txt", "w")
        f.write(tts1)
        f.close()
 elif "замолчи" in an or "стоп" in an:
        ca = 1
        tts.say("Хорошо, микрофон выключен. Для продолжения работы нажмите энтр")
        tts.runAndWait()
        an4925479864 = input("[ПАУЗА] Нажмите enter: ")
        tts.say("Привет-привет, чем займемся?.")
        tts.runAndWait()

Смол толк. У меня он может быть выключен, если коротко, то смол толк это "разговор ни о чем" типа "как дела".

elif "виталий активируй диалоги" in an:
        ca = 1
        tts.say("Возможность диалогов активирована, О чём поговорим?")
        tts.runAndWait()
        f = open('dialogset.txt', 'w')
        f.write("1")
        f.close()
    elif "виталий выключи диалоги" in an:
        ca = 1
        tts.say("Возможность диалогов отключена.")
        tts.runAndWait()
        f = open('dialogset.txt', 'w')
        f.write("0")
        f.close()
    f = open('dialogset.txt', 'r')
    an4897987 = f.read(1)
    f.close()

    

    if an4897987 == "1":
        rsm = random.randint(1,3)
        if "привет" in an or "здрав" in an:
            ca = 1
            if rsm == 1:
                tts.say("Привет, чем могу пом очь?.")
                tts.runAndWait()
            elif rsm == 2:
                tts.say("Добрый день.")
                tts.runAndWait()
            elif rsm == 3:
                tts.say("Хэлоу.")
                tts.runAndWait()
         #пример фразы смол толк`а
        elif "в1" in an or "в2" in an:
            ca = 1
            if rsm == 1:
                tts.say("1в ответа")
                tts.runAndWait()
            elif rsm == 2:
                tts.say("2в ответа.")
                tts.runAndWait()
            elif rsm == 3:
                tts.say("3в ответа")
                tts.runAndWait()
        
        elif "как" in an and "дел" in an:
            ca = 1
            if rsm == 1:
                tts.say("Как сказала-бы Алиса, у меня всё хорошо, но немного одиноко, обращайтесь ко мне по-чаще.")
                tts.runAndWait()
            elif rsm == 2:
                tts.say("У меня прекрасно! Заходил на официальный канал проекта. Там очень интересно. Хотите посмотреть?")
                tts.runAndWait()
                cont = "ютубпр"
                cikl = 0
            elif rsm == 3:
                tts.say("У меня всё прекрасно! А у вас?")
                tts.runAndWait()   

        elif "хорошо" in an or "прекрасно" in an:
            ca = 1
            if rsm == 1:
                tts.say("Я рад за вас, чем займемся?")
                tts.runAndWait()
            elif rsm == 2:
                tts.say("Я рад за вас, у меня тоже всё хорошо.")
                tts.runAndWait()
            elif rsm == 3:
                tts.say("Я рад за вас.")
                tts.runAndWait()

А если ошибка? Или, что бот будет делать в случае, если не найдет ответа? Вот что. Кстати ассистент понимает, что не выполнил за цикл ни одной команды, если переменная ca = 0.

      if an == "":
            print("")
            ca = 0
      if ca == 0:
        print("ошибка")

        if ra == 1 or ra ==2:
            tts.say("Ну наверное...")
            tts.runAndWait()
        elif ra == 3 or ra == 4:
            tts.say("Даже не знаю.")
            tts.runAndWait()
        elif ra == 5 or ra == 6:
            tts.say("Незнаю что на это ответить.")
            tts.runAndWait()
        elif ra == 7 or ra == 8:
            tts.say("Я вас не то что бы понял, но по смыслу понял")
            tts.runAndWait()
        elif ra == 9 or ra == 10:
            tts.say("Наверное я вас не правильно понял.")
            tts.runAndWait()

Осталось только "обнулить", нет не этого, а переменный, что бы не было повторных сработок:

    an = ""
    if cikl == 2:
        cikl = 0
        cont = ""

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

Жду ваших советов, идей и критики в комментариях под постом и на почте: glebilic@gmail.com.

Пока!

Ads
AdBlock has stolen the banner, but banners are not teeth — they will be back

More

Comments 34

    0
    1) Вы уверены, что именно скомпилировали в exe?
    2)image
      –1
      Добрый день! большое спасибо, что заметили. Ссылка действительно была рабочая, но гугл диск изза наплыва её убил. В срочном порядке на виксе лепим одно страничку, что бы возобновить работу.
        0
        Файл обновил.
        +4
        (сорри, не могу удержаться)
        — Я ДЖВА ГОДА ЖДАЛ ЭТОГО ГОЛОСОВОГО АССИСТЕНТА!!!
          –4
          Спасибо!
          +5

          Добавь поддержку gpt3, вполне по силам должно быть и потом приходи.


          А пока скрой в черновиках. Ничего личного, но ты понимаешь что если не минусовать подобные статьи (даже если автопу 14-ть), то завтра здесь будет ещё десяток хелоу-ворлдов.

            +2

            Вы уверены что человек, который ещё не освоил циклы, может добавить поддержку gpt3?

              0

              Ну если из примеров, то там наверное и циклы не понадобятся.


              Но по крайней мере простимулирует что-то новое изучить в процессе прикрутки. Это же не значит приходи завтра, потратит месяцок плотно, уже толк будет.


              Тем более если у jottygroups попоосит пару раз код реаью сделать.

                –5
                Еще раз посмотрите исходный код, большая часть ассистента — это гигантский цикл.
                  0
                  Вы не поняли. Весь этот непподерживаемый ужас Ужс можно заменить на

                  In [1]: from time import sleep
                  
                  In [2]: for i in range(10, 0, -1):
                     ...:     print(f"Shutting down in {i} seconds", end="\r")
                     ...:     sleep(1)
                  


                  И подобных мест там много… Будете писать код — все будет, но пока похвастаться нечем.
                –4
                Уже работаем!
                  –4
                  Я решил в поиске по запросу «голосовой ассистент на python» на хабре найти пример проекта подобного ассистента с gpt3. И и и… ЕГО НЕТ! Абсолютно все результаты поиска их около 5, использую elif. По этому считаю вашу претензию без основательной.
                  Если есть возможность — скиньте пост с примером такого ассистента.
                    0

                    Я прошу прощения, а по какой логике можно было добавить наращение к числу 14?

                    +9
                    Ну давай с самого начала. Ссылка на «ассистента» битая. Можно было бы и проверить ее работоспособность перед тем, как выкладывать пост на хабр. И большой пипец, который у тебя есть — названия переменных. Это что-то. num123, tts1 и tts (как понять отличие по названию переменной?), cont, an, an45, ca и прочее-прочее-прочее. Что это?.. смысл переменных должен быть понятен сразу по названию, тем более, у тебя не большой прод-код, а небольшая программка. И да, не стоит называть переменные русскими словами, написанными английскими буквами.
                    Проверки-проверки-проверки...
                    image

                    If..elif..elif..elif..elif..elif....
                    Есть такая замечательная штука, как функции, списки, кортежи и библиотека random стандартная. Написал функцию send_start_message, в качестве аргумента принимаешь кортеж из трёх элементов — first_message, second_message и cont. У тебя cont заполняется не везде, поэтому можно, где его нет, оставить None и не париться, а в функции устанавливать cont, если он в кортеже не None. Дальше список из кортежей данного типа. И изюминка. Всё работает в 10 строках, а не в овер 70 строках. Ну и вызов — send_start_message(random.choise(hello_messages)). Усё.
                    И, кстати, у тебя где-то cont — кортеж, где-то — строка. Почему?
                    Для чтения файлов (и не только для этого, конечно же) придумали оператор with, который ты решил не использовать.
                    И что у тебя с табуляцией в коде? Там 8 пробелов, там 4, а в одном месте вообще ca улетел на Марс:
                    ca на Марсе
                    image

                    Без комментариев
                    image

                    Циклы? Не, не слышали. Повторяющийся код — плохо, когда его легко можно заменить циклом.
                    В общем, код плох и даже хуже. Но это нормально — учись и всё будет классно.
                    Про сам пост как он есть: как будто тебе было насрать на читателя. Ну ты же в журнальчик с охватом в 100 человек статью выкладываешь, а на хабр. Что за глупые шутки про пациента-клиента?
                    В прошлом блоке мы сгенерировали рандомное число и занесли его в переменную r, теперь создадим elif`ки и зададим переменные cont, они понадобятся нам позже:

                    Что? Зачем cont? что за нагромождение elif'ок? что делает этот код? Ты понять не дал.
                    И создадим первую команду «да», помните переменную cont? Так вот она отличает ответ «да» на вопрос «открыть ютуб?», и «да» на вопрос «Включить новости?», если контекста нет, то он просто ответит стандартным ответом.

                    Окей, поняли зачем cont. А что за остальные переменные в коде выше? Если уж делаешь переменную, например ca, то будь добр, поясни, что она делает…

                    Обобщим. Статья больше похожа на отписку. Будто ты сделал это за минут 20, быстренько скомпилил и го писать статью на Хабр, крутым буду. Это немного не так работает. Код надо прорабатывать, статью надо прорабатывать, всё подробно рассказывать. А ты просто посмотрел видео Хауди, «хочу быть таким же крутым», и вышло в итоге что вышло.
                      +3

                      И ссылки на бинарники вообще моветон, может собирали на компе с пятью троянами.


                      Разбор полётов хорош.

                        –1
                        Кстати про помощника Хауди, я действительно часто смотрю этого ютубера, но напомню, что продемонстрированный им «образец» не был зациклен (то есть после выполнения команды он вырубался), 2 — Там помощник был сделан для примера (просто гайд), по этому там было 3 — 4 функции, 3 — Я уже работаю над выводом распознавания в отдельную функцию и благодарю вас за составленную мини статью, которая поможет закрыть «косяки» старой версии.
                        –5

                        Как же вас троллят, комментаторы)

                          +2

                          Хорошое начало, но ещё много надо учиться и тренироваться и тут вам должна помочь лень потому что копипаст не выход :)

                            –1
                            Ассистент оригинален, и не является копиркой ассистента Хаудио Хо, и других ассистентов.
                              –1
                              Благодарим за отзыв.
                              0
                              if an == "":
                                          print("")
                                          ca = 1
                                  if ca == 0:

                              Очень смущают эти строчки. Ставишь флаг равным 1, и сразу проверяешь его на равенство 0
                                –2
                                Полетели пробелы в редакторе статей, уже работаю над исправлением, скоро прикреплю нормальную ссылку на архив с исходником и тд.
                                0

                                Код использовать не буду, ссылку на этот пост потеряю.


                                P.S. Амбиции в 14 лет похвальны — продолжать стоит, но писать статьи рано — код на 14 лет, а статьи читают дядьки по старше...

                                  0
                                  Благодарю за оставленный вами отзыв, благодаря Хабр я могу получить конструктивную критику от действующих специалистов, и усовершенствовать свой проект в будущем.
                                  +1

                                  Молодец что учишься, наверняка статья по итоге уйдёт в глубокий минус, но это заслуженно, потому как код нечитаемый. А здесь вам бесплатно делают код-ревью опытные программисты.
                                  Запомните, одной из главных обязанностей программиста писать такой код, который будет понятен другим (и даже тебе через полгода).
                                  И кстати для выбора команд хорошо использовать стейт машину или автомат состояний. Вам надо хранить текущее состояние, ну или шаг на котором находится ваш бот. С применением такой технологии можно легко перемещаться по дереву состояний.

                                    –2
                                    Добрый день, с приложенным кодом явно вышел косяк, улетел пробелы, а изза не полной публикации «центрального списка» со всеми командами, начались вопросы по типу «где циклы?» скоро налеплю нормальную ссылку на скомпилированный вариант с приложенными исходниками.
                                    –2
                                    ВНИМАНИЕ! ССЫЛКУ НА СКОМПИЛИРОВАННЫЙ ВАРИАНТ ОБНОВИЛИ (если снова упадет — пишите) ССЫЛКУ НА ИСХОДНИК ДОБАВИЛ (что бы вопросов «а где циклы и тд не возникало»).
                                    Также благодарю вас за конструктивную критику.
                                      +1

                                      В целом это большой прогресс. Я в 14 лет не сумел реализовать path finding (книжек не было) для клона lines на спектруме. Шарики просто прыгали сквозь соседние — но я всё равно был счастлив, потому что оно работало.

                                        0
                                        Благодарю за оставленный вами отзыв, благодаря Хабр я могу получить конструктивную критику от действующих специалистов, и усовершенствовать свой проект в будущем.
                                        0
                                        Ты молодец, это правда, желаю тебе не останавливаться на достигнутом и не терять мотивации. Но как видишь Хабр не для таких статей, тут аудитория намного старше твоего возраста, но твое желание поделиться с другими своими достижениями и попробовать себя в роли серьезного разработчика понятно и вызывает умиление. Лет через 6 тебе возможно будет немного стыдно за эту статью, но советую не удалять ее, а просто скрыть в черновик, чтобы прочитать ее как повзрослеешь, уверен, это принесет тебе некоторые эмоции. Надеюсь в будущем увидеть от тебя действительно полезных и познавательных статей. А остальным советую не быть такими злюками, а то честное слово, как будто сами детьми не были.
                                          0

                                          Я даже попытался скачать исходник, поднять и слегка порефакторить но слижком уж неудобно.


                                          Автор, вот вам пара идей:


                                          • Публикуйте исходники на Github и указывайте все зависимости.
                                          • Подключите себе какой-нибудь линтер (например flake + black)
                                          • Используйте функции (Очень много кода повторяется)
                                          • Почитайте Дзен питона там все довольно просто и есть умные мысли
                                          • Подумайте или проверьте как будет ваш скрипт работать если в системе нет микрофона? А аудио выхода? (спойлер: она даже не запустится)
                                          • Хоть как то опишите что именно у вас лежит в пачке txt файлов
                                            –1
                                            Спасибо!
                                              0
                                              Думаете стоит сделать возможность текстового ввода? Функции и списки добавлю в при следующем апдейте. Большое спасибо за интересный и содержательный комментарий.
                                                0

                                                Отделите логику обработки команды от логики получения этой самой команды и потом прикручивайте любые варианты, не меняя основную логику

                                            Only users with full accounts can post comments. Log in, please.