Ответы пользователя по тегу Python
  • Не могу найти ошибку в коде Python?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    Не надо ловить абстрактный Exception вообще никогда! Тем более игнорировать его и даже не выводить в консоль. Произошла ошибка, а какая, почему произошла - ваще непонятно.

    Какие тут могут случиться ошибки? Ну, например, если в user_dict нет записи с ключом chat_id, то случится KeyError. Или если в getRegData возвращается невалидный markdown-текст, то случится ошибка ApiException.

    А далее после обработки exception путём его игнорирования тут снова вызывается register_next_step_handler, который приводит к тому, что вводимые пользователем данные снова попадают в тот же обработчик и - вероятно - натыкаются на ту же самую ошибку. Например, KeyError: конечно, ведь как при прошлом запуске этого обработчика не было значения с таким ключом, так и при последующих не появится.

    До кучи, не надо вызывать постоянно bot.get_me(). Это каждый раз будет вызов API. Неужели имя бота меняется каждую минуту? Достаточно запомнить при запуске бота - и достаточно.
    Ответ написан
    Комментировать
  • Как отправить сообщение от лица бота в чат где он состоит?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    И в чат так же можно, если у бота есть доступ к написанию сообщений в группу и в качестве chat_id передан правильный id чата.
    Ответ написан
  • Sqlite3 не работает update?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    А почему name в запросе идёт первым, а user_id - вторым - при этом в передаваемых параметрах наоборот?

    cursor.execute("UPDATE gaming SET name =  ? WHERE user_id = ?", [user_id, text])
    Ответ написан
  • Aiogram. Как отправить сообщение повторно зная его message_id?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    Нет, невозможно через Bot API получить информацию по ранее отправленным сообщениям. Следовало сохранять эти сообщения или исходную информацию, на которой они были основаны.
    Ответ написан
    Комментировать
  • Как удалить пересланное сообщение Aiogram?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    В этом примере бот получает сообщение с ТЕКСТОМ /delete, пытается найти в нём forward_from_message_id (откуда???) и удалить в чате с пользователем-отправителем сообщение с таким id. Довольно очевидно, что это работать не будет вообще никак.

    Какая вообще задача стояла?
    Ответ написан
    8 комментариев
  • Как сделать приветственное сообщение в AIogram?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    Это меняется в свойствах бота у BotFather.
    Ответ написан
    Комментировать
  • Как передать логин и пароль через requests (директива запаролена с помощью htaccess)?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    Для Basic Auth:

    from requests.auth import HTTPBasicAuth
    
    r = requests.get(url, auth=HTTPBasicAuth(login, password))


    Для других способов авторизации можно написать свой класс. Например, для Bearer:

    class BearerAuth(requests.auth.AuthBase):
      def __init__(self, token):
        self.token = token
      def __call__(self, r):
        r.headers["authorization"] = "Bearer " + self.token
        return r
    
    r = requests.get(url, auth=BearerAuth(my_token))
    Ответ написан
  • При обновлении данных в БД sqlite3, обновляет только 1 строку, как сделать, что бы обновляло сразу все?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    cursor.execute возвращает генератор, который возвращает кортежи значений. Таким образом, в конструкции:

    for i in qwe.execute(""" SELECT vk_id FROM stata """):


    значением i будет не значение vk_id, а кортеж из одного значения (vk_id,).

    Далее, в этом цикле делается запрос с (i,), который даёт ((vk_id,),), то есть одно значение. Кроме того, внутри итерации по курсору выполняется другой запрос с тем же курсором с затиранием внутренних данных курсора от предыдущего запроса, поэтому при заходе на вторую итерацию уже не возвращается ничего. Получается один запрос по одному vk_id. Всё работает ровно так, как написано.

    Что тут можно сделать?

    Вариант 1. В executemany имеет смысл передать список не из одного значения, а из множества (иначе нет смысла в executemany, проще обычный execute). Например, их можно получить путём накопления в цикле в список с последующим отдельным (вне цикла) вызовом executemany. Но если с данными запроса ничего особого делать не нужно, то и цикл тут лишний, можно получить всё сразу через fetchall().

    Вариант 2. Обойтись средствами SQL. Примеры:

    -- добавить всем 1
    UPDATE stata SET coins = coins+1;
    -- добавить удвоенный доход всем с вип-статусом, если срок его действия ещё не истёк
    UPDATE stata SET coins = coins+dohod*2 WHERE vip_status=1 AND vip_status_end>=NOW();
    Ответ написан
    Комментировать
  • Ошибка авторизации VK API?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    Авторизация по логину и паролю является неподдерживаемым способом и давно работает через пень-колоду. Следует использовать OAuth2.
    Ответ написан
  • Как сделать так, чтобы бот выполнял команду 1 раз?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    Ох, ну тут всё неправильно.

    Не надо пихать ещё одну функцию send_message внутри send_message. Их надо вынести на один уровень. И вообще, назвать более адекватно их содержанию. Ведь первая обрабатывает команду /weather, а вторая - название города. Странно называть их одинаково неопределённым send_message (чтоб враги не догадались?).

    Что происходит в этом коде? Сначала мы регистрируем обработчики команд /weather и /start с помощью декоратора. При вызове /weather мы КАЖДЫЙ раз (ведь это часть функции-обработчика на следующем уровне вложенности!) заново определяем обработчик для content_type=text. Далее после первого вызова /weather этот обработчик начинает работать на все текстовые сообщения. Причём на сообщения ВСЕХ пользователей нашего бота. То есть реально, один вызывает /weather и тем самым изменяет поведение бота для всех пользователей сразу. Если в боте будет где-то ещё определяться таким же "внутренним" описанием ещё один обработчик content_type=text, то он будет всегда игнорироваться до следующего перезапуска бота, ведь один обработчик текстовых сообщений уже есть и он всегда будет применяться.

    Чего удивительного в том, что бот работает ровно так же странно, как странно написано в его коде?

    Надо понимать, что обработчик сообщения принимает ОДНО сообщение и его обрабатывает. Он не может принять сообщение и ещё сразу же следующее. Каждое обработается своим обработчиком. Чтобы обработка сообщений зависела от ряда сообщений, используют FSM (Finite State Machine), машину состояний. В telebot есть довольно простая в использовании FSM на основе вызова register_next_step_handler. Вызов register_next_step_handler переопределяет то, каким обработчиком будет обработано следующее сообщение с этим пользователем (точнее, в этом chat_id, который может быть и идентификатором группы).

    Собственно, принцип работы такой: когда пользователь вызывает /weather, мы должны с помощью вызова bot.register_next_step_handler зарегистрировать кастомный обработчик следующего сообщения. Этот обработчик будет обрабатывать только сообщения этого пользователя, подобное поведение не будет влиять на других пользователей. Для более сложных взаимодействий можно делать длинные и даже ветвящиеся цепочки обработчиков, спрашивать у пользователя разные данные, предлагать изменить ранее введённые данные итд итп.

    Официальный пример использования смотреть тут.
    Ответ написан
    1 комментарий
  • Как остановить выполнение цикла командой?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    Нужно вместо while True гонять цикл по какому-то другому условию, которое рано или поздно изменится. Например, можно завести глобальную переменную, задавать ей True в команде запуска, а в команде остановки выставлять False. Да, это очень дурацкое решение, так как нельзя будет использовать команду в разных каналах одновременно. Но как бы и задача сама по себе очень дурацкая, явно попытка научиться делать ну хоть что-нибудь...

    Обычно если нужно делать какие-то регулярные задачи для бота, применяют другие решения. Например, расширение tasks или модуль aioschedule. Длинный цикл в обработчике команды - это часто не очень хорошее решение. Например, если бот будет перезапущен, цикл не будет запущен заново, а если задачи цикла хранятся в сохраняемой между перезапусками очереди - то перезапуск бота не будет влиять на этот функционал.
    Ответ написан
    3 комментария
  • Какие библиотеки использовать для парсинга текстовых файлов (Python)?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    Допустим, мы напряжёмся и пропарсим миллион файлов не за полтора часа, а за час, потратив три часа на разработку и отдалку кода. И зачем? Чего мы тут сэкономим? Обычно для разовых операций временем работы заботятся тогда, когда оно действительно велико. Например, если требуется месяц непрерывной работы, то я бы ещё подумал, можно ли его сократить до недели.

    Библиотека numba нужна для ускорения собственноручно написанных вычислительных алгоритмов. В парсинге текстовых файлов, скорее всего, узким местом будут исключительно операции ввода-вывода, так что тут она ничем не поможет.
    Ответ написан
    Комментировать
  • Проверка на пользователя в бан листе?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    Во-первых,

    event.user_id != banned_ids

    неверно, надо

    event.user_id not in banned_ids

    Во-вторых, user_id скорее всего число, а в файле будут строки. Поэтому:

    banned_ids = [int(user_id) for user_id in BanUsers.read().splitlines()]
    Ответ написан
  • Как спарсить pdf файлы с сайта?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    Вообще говоря, в данном случае скачать совсем не проблема безо всяких скриптов, достаточно wget:

    wget -r -np https://codernet.ru/media/
    Ответ написан
    3 комментария
  • В одинаковых файлах разный hash?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    Ошибка тут:

    with open(cFile, 'w') as f3:

    Надо открывать файл как бинарный ('wb').

    А также тут:

    c = str(i)

    При приведении бинарных данных к строке они могут исказиться.
    Ответ написан
    2 комментария
  • Как избежать ошибки?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    Вплоть до версии 3.35 в sqlite нельзя было удалять колонки вообще https://sqlite.org/changes.html#version_3_35_0
    Ответ написан
    Комментировать
  • Телеграм-бот не обрабатывает сообщения, что не так (pytelegrambotapi)?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    Так, как написано сейчас, работать не будет. Потому что регистрируется несколько обработчиков с одинаковым условием content_types=text, и применяется только первый. Надо как раз использовать bot.register_next_step_handler (или городить свой велосипед на замену). Смысл обработчиков именно в том, что они получают сообщение, обрабатывают его и завершаются. Ждать следующего сообщения не нужно.

    И зачем вообще внутри одной функции описывать другую? Так иногда делают, но в данном случае это не имеет смысла.
    Ответ написан
  • Как исправить ошибку при работе с inline mode?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    А что делает message_text у InlineQueryResultArticle? Это параметр конструктора InputTextMessageContent. Неудивительно, что ругается.
    Ответ написан
    Комментировать
  • Что делать если не работают команды кроме bot event?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    Это весьма популярная проблема, и решение есть в официальном FAQ https://discordpy.readthedocs.io/en/stable/faq.htm...
    Ответ написан
    Комментировать
  • Как заставить бота работать?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    А как он должен работать, если ты в обработчике zodiac создаёшь переменную msg, но никаких сообщений не отправляешь? До кучи, как по-твоему это будет работать, если call.data на всех кнопках одинаковый, как бот их будет различать?
    Ответ написан