• Есть ли либа, которая сможет матчить слова, которые похожи друг на друга?

    @nakem Автор вопроса
    я нашел это https://github.com/schollz/closestmatch
    Немного потестил, вроде все как я хотел. Правда я не понял, что такое bag size, но вроде с дефолтным 2 из примера все работает
    Ответ написан
    Комментировать
  • Есть ли курсы по Go наподобие JavaRush?

    @nakem
    gotour https://go.dev/tour/welcome/1
    Это обязательно для прохождения
    Ответ написан
    Комментировать
  • Golang в чём смысл?

    @nakem
    Я тоже раньше мыслил такими категориями. Мне тоже казалось, что самые крутые технологии - это те, которые на бенчмарках всех выносят и на хабрах хвалят. "Топ 5 языков для изучения в 2019\20\21\22\23..."
    Нет)) Это не так. Можно принять это за догму:)))
    Ответ написан
    Комментировать
  • Как обработать голосовое сообщение во фреймворке для телеграм ботов telebot?

    @nakem Автор вопроса
    Я разобрался. Может кому-нибудь будет полезно.
    Голосовые сообщения, отправленные в телеграмм - это Опус ogg.
    То есть, хендлить все голосовые сообщения нужно так
    bot.Handle(tb.OnVoice, voiceHandler)
    любой хендлер в этом фреймворке должен иметь такой прототип `func fun(msg *tb.Message)`

    msg - это структура, которая хранит в себе всю инфу о сообщении. Соответственно, в хендлере голосовых сообщениях будет доступен `msg.Voice`
    Это уже структура голосового сообщения с контентом вида `audio/opus`
    В структуру voice встроена структура file. У нее есть fileID. С таким айди файл нашего голосового сообщения хранится на серверах телеги. С помощью функции `bot.FileURLByID(msg.Voice.FileID)` мы можем получить URL, куда сделаем запрос и получим наши байтики аудио.
    Вот код
    func (r *RecognitionVoiceHandler) VoiceRecognize(msg *tb.Message) {
    	ctx := context.TODO()
    	isFmt, encoding := checkFmt(msg, r.TeleContent())
    	if encoding == "ogg" {
    		encoding = "opus"
    	}
    	if !isFmt {
    		r.logger.Warnf(ctx, "Wrong format: %s", msg.Voice.MIME)
    		r.bot.Send(msg.Sender, fmt.Sprintf(formatError, msg.Voice.MIME))
    	}
    
    	fileURL, err := r.bot.FileURLByID(msg.Voice.FileID)
    	if err != nil {
    		r.logger.Error(ctx, "Can't get URL from fileID")
    		r.bot.Send(msg.Sender, telegramError)
    	}
    
    	text, err := r.recognize(ctx, fileURL, encoding)
    	if err != nil {
    		r.bot.Send(msg.Sender, telegramError)
    	}
    	if _, err = r.bot.Send(msg.Sender, text); err != nil {
    		r.logger.Error(ctx, "Can't send telegram response")
    	}
    }

    Если нужно обрабатывать аудио файлы типа mp3 и тд, то это структура Audio и контент endpoint tb.OnAudio.
    Если нужно ваф и тд, то это структура Document и endpoint tb.OnDocument
    Ответ написан
    Комментировать
  • Как написать программу на СИ?

    @nakem
    Мой совет. Попросите кого-то из знакомых программистов. Здесь вряд ли кто-то будет писать за вас. Вот если бы вы что-то набросали сами, а потом пришли сюда с просьбой найти ошибки или попросили бы совет как лучше сделать, то это другое дело. Попробуйте нагуглить код, если в русском сегменте ничего не нашлось, то стоит перевести поисковый запрос на английский язык.
    По поводу задачи. Как я понял условие. Подается два аргумента. Первый строка с нным количеством слов. И вторая строка с одним таргетным словом. Нужно найти кол-во слов в первой строке, которые заканчиваются и начинаются с таргетного слова.
    Предположим, что пробелов в начале и в конце может быть произвольное кол-во. Между словами тоже самое.
    Запускаем цикл пока i не равно '\0' .
    Далее нам нужно написать функцию skip_spaces. Она будет скипать пробелы до тех пор, пока не встретиться любой символ или '\0'. На символ проверяем через таблицу Ascii. Пишем в терминале man ascii пролистываем до таблицы в десятичной системе счисления(decimal) и ищем значения букв. То есть, строчные буквы от 97(а) до 122(z).
    Далее в цикле используем нашу написанную SkipSpaces, чтобы увеличить наше i и пропустить пробелы перед началом потока слов.
    Далее мы встречаем первое слово. Нам нужно написать функцию check_word, которая будет возвращать булеву переменную в зависимости от того есть ли в нем таргетное слово. Мы передаем в эту функцию указатель на символ, на котором сейчас стоим &words[i] и таргетное слово. Далее в самой функции check_word(char *word, char *target) нам нужно сохранить начало слова в переменную start. Посчитать кол-во символов в слове size_word. То есть просто проскакать по word до первого пробела. Далее просто for (i:=0; i < len(target); i++) мы сравниваем начало word с таргетом, если все ок, то идем дальше, если что-то не ок, то возвращаем false. Во втором цикле for (i := size_word - len(target); j := 0; i < size_word; i++; j++) мы уже находим таргет в конце нашего слова. Если все ок, все совпало, то возвращаем true.
    Дальше в нашем мейне нам необходимо увеличить count_valid_words, если check_word вернула true. Далее, необходимо скипнуть символы. Аналогично как с skip_spaces().
    На этом все.
    Пока писал этот текст успел пожалеть, что просто не накидал код ахахах. Но я очень надеюсь, что ты сам решишь эту задачку, а не будешь списывать. Начни программировать, это очень интересно!)
    Ответ написан
  • Как правильно передать множество параметров в функцию в Golang?

    @nakem
    В некоторых кейсах функциональные опции могут оказаться более подходящим решением.
    Дейв Чейни подробно писал об этом https://dave.cheney.net/2014/10/17/functional-opti...
    Ответ написан
    Комментировать
  • Как понять причину отмененного контекста?

    @nakem Автор вопроса
    Решил проблему! Все дело в автосгенерированном моке. В моке бекенда `h.backend.Denoise()` не было чтения из канала audioChunks. Поэтому происходил дедлок и соответствующая отмена контекста. А если добавить буфер в канал, то программа не застревала. Для меня был главный вопрос почему программа возвращала StatusOK если проблемы с чтением из канала, но я забыл, что я сам добавил возврат слайс байт из мока, поэтому программа и отрабатывала. Спасибо всем, кто хотел помочь!
    Ответ написан
    Комментировать