Найти - Пользователи
Полная версия: проблема с обработкой команд с аргументами в боте для телеграм
Начало » Python для новичков » проблема с обработкой команд с аргументами в боте для телеграм
1
weber
Всем доброго времени суток! Решил поучить “питон” и первый учебный свой проект решил посвятить написанию бота в “телегу”. После PHP (где таких проблем нет) мне тут головной боли добавил синтаксис (отступы и т.д.), на которые среда кодинга (PyCharm) ругается порой по “черному”… Но с этим я вроде справляюсь, суть в другом.

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

/rand 1 500

из чего понятно, что я говорю боту выдать случайное число в диапазоне от 1 до 500, при этом скрипт должен обработать введенные данные и понять, правильный формат команды или нет. если аргументы не являются числами или вовсе не введены, то бот должен ответить, что команда введена не верно.
Скрипт в принципе работает(когда ввожу команду верно), но если я неправильно укажу команду (без аргументов или это не цифры и т.д.),то получается с ошибкой, которая приводит к крашу скрипта…

 IndexError: list index out of range

т.е. ругается на строчку с:
 x_min = int(message.text.split()[1])

уже мозг сломал, не могу понять в чем дело…

вот сам код полностью:

 import telebot
import random
API_BOT = "бота токен"
ADMIN_USER_ID: list[int] = [мой айди в телеге]
THIS_BOT = telebot.TeleBot(API_BOT)
@THIS_BOT.message_handler(commands=['start'])
def cmd_start(message):
    THIS_BOT.send_message(message.chat.id,
                          f'<b>Привет, {message.from_user.first_name}! Я Ваш интерактивный помошник.</b>',
                          parse_mode='html')
@THIS_BOT.message_handler(commands=['rand'])
def cmd_rand(message):
    x_min = int(message.text.split()[1])
    x_max = int(message.text.split()[2])
    if x_min < x_max:
        result = random.randint(x_min, x_max)
        THIS_BOT.send_message(message.chat.id, f"Случайное число: {result} ", parse_mode='html')
    else:
        THIS_BOT.send_message(message.chat.id, f"Ошибка! Неправильно указаны аргументы команды. \n Вы написали "
                                               f"следующее: /rand {x_min} {x_max}", parse_mode='html')
@THIS_BOT.message_handler()
def msg(message):
    if (message.text == "debug_info") and (message.from_user.id in ADMIN_USER_ID) is True:
        THIS_BOT.send_message(message.chat.id, message, parse_mode='html')
if __name__ == "__main__":
    THIS_BOT.polling(none_stop=True)

weber
нашел решение, которое помогло корректно работать обработчику команды, не знаю насколько это правильно, но как то так.. вот код:

 import telebot
import random
API_BOT = "токен бота"
ADMIN_USER_ID: list[int] = [айди пользователя бота-админа]
THIS_BOT = telebot.TeleBot(API_BOT)
@THIS_BOT.message_handler(commands=['start'])
def cmd_start(message):
    THIS_BOT.send_message(message.chat.id,
                          f'<b>Привет, {message.from_user.first_name}! Я Ваш интерактивный помошник.</b>',
                          parse_mode='html')
@THIS_BOT.message_handler(commands=['rand'])
def cmd_rand(message):
    if len(message.text.split()[1:]) == 2:
        x_min = int(message.text.split()[1])
        x_max = int(message.text.split()[2])
    else:
        x_min = 0
        x_max = 0
    if x_min and x_max != 0:
        result = random.randint(x_min, x_max)
        THIS_BOT.send_message(message.chat.id, f"Случайное число: {result} ", parse_mode='html')
    else:
        THIS_BOT.send_message(message.chat.id, f"Ошибка! Неправильно указаны аргументы команды. \n Правильный пример: "
                                               f"/rand 1 100 \n Вы написали следующее: {message.text}", parse_mode='html')
@THIS_BOT.message_handler()
def msg(message):
    if (message.text == "debug_info") and (message.from_user.id in ADMIN_USER_ID) is True:
        THIS_BOT.send_message(message.chat.id, message, parse_mode='html')
if __name__ == "__main__":
    THIS_BOT.polling(none_stop=True)

Как видно из положения вышел, проверяя количество элементов внутри массива, если их там реально не столько, сколько должно быть, то бот отвечает, советуя исправить формат ввода команды. Теперь другая проблема, корректно проверять, что это не текст, а числа.
py.user.next
weber
Решил поучить “питон”
Тебе надо не столько язык учить какой-то новый, сколько само программирование доязыковое. Знаешь, да, что такое псевдокод? Вот тебе надо сначала на псевдокоде учиться писать. К счастью, питон очень приближен к псевдокоду, поэтому он как раз в роли псевдокода и выступит.

weber
После PHP (где таких проблем нет)
Проблема PHPшников в том, что у них складывается одинаковое мышление, которое сильно тупообразное. Поэтому в своей среде они чувствуют себя наверху горы и могут годами там классно писать всё, но когда они попадают в другие языки типа компилируемых, это их мышление просто оказывается непригодным и им надо учиться всему заново.

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

weber
нашел решение, которое помогло корректно работать обработчику команды, не знаю насколько это правильно
Ты бы на псевдокоде сначала написал бы очень конкретно, что тебе нужно получить в конечном итоге, так оно было бы оптимально, а потом бы ты это переписал уже на питон и всё бы получилось сразу.

Надо было записать так:
  
x_min = x_max = None
 
text = message.text
chatid = message.chat.id
 
args = text.split()[1:]
if len(args) != 2:
    bot.send_message(chatid, 'Error: should be two arguments')
    return
 
try:
    x_min = int(args[0])
except ValueError:
    pass
 
try:
    x_max = int(args[1])
except ValueError:
    pass
 
if x_min is None:
    bot.send_message(chatid, 'Error: can\'t read min argument')
    return
if x_max is None:
    bot.send_message(chatid, 'Error: can\'t read max argument')
    return
 
if x_min == 0:
    bot.send_message(chatid, 'Error: zero min argument')
    return
if x_max == 0:
    bot.send_message(chatid, 'Error: zero max argument')
    return
 
bot.send_message(
    chatid,
    'Ok. See min argument {} and max argument {}'.format(
        x_min, x_max)
)
Как видишь, в моём коде, после того как он пройден интерпретатором, не осталось сомнений, что в нём что-то пропущено или что-то упущено. Каждая проверка дала свой результат и сразу отмерла. Также в нём всегда можно внедриться посередине (в любой точке кода) и вставить дополнительную проверку, ничего не разделяя, потому что всё разделено заранее как раз для этого. Благодаря этому код можно писать послойно. Написал слой, отладил его, всё работает; после этого поверх этого слоя снова пишешь слой, отлаживаешь его и всё работает. И так ты послойно приводишь программу к крепкому виду. При этом тебе не надо её переделывать по сто раз в разных фрагментах, ты её просто дописываешь, дописываешь, дописываешь.

Вот это всё вырабатывается, когда учишься реальному программированию, проходя все классические этапы обучения. Надо уметь и словесно описывать программу, и на блок-схемах описывать программу, и на псевдокоде её записывать разными способами (псевдокод тоже бывает разный, различается по уровням детализации), и в разных стилях всё это писать. Сначала ты всё это пишешь, потом это всё постепенно формируется прямо в мозгах и ты только в воображении всё это пишешь. Так ты приходишь к тому, что программы ты пишешь прямо в голове, когда по улице идёшь и гуляешь, а на компе ты их потом просто записываешь, переписывая их готовые из головы в комп.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB