• Как правильно прописать проверку ввода чисел на питоне для ТГ бота?

    Vindicar
    @Vindicar
    RTFM!
    try:
      v = int(message.text)
      #на случай если тебе подойдёт не всякое число
      if v < 0 or v > 99: 
        raise ValueError()
    except ValueError:
      bot.send_message(message.chat.id, "Не число, или недопустимое число.")
    else:
      bot.send_message(message.chat.id, f"Ты ввел число {v}")
    Ответ написан
    Комментировать
  • Есть ли коги или что-то им подобное в Telegram?

    Vindicar
    @Vindicar
    RTFM!
    Можно сделать самому.
    Смотри, ключевая возможность в большинстве библиотек для ботов - это регистрация реакции бота на события. И чаще всего она выполняется декоратором, типа @bot.command в discord.py или его эквивалент в aiogram.
    Но что такое декоратор? Если он не имеет параметров, то тогда
    @some_decorator
    def some_func():
        pass

    это то же самое, что и
    def some_func():
        pass
    some_func = some_decorator(some_func)

    Для декораторов с параметрами чуть-чуть сложнее
    @some_decorator(params)
    def some_func():
        pass

    превратится в
    def some_func():
        pass
    wrapper = some_decorator(params)
    some_func = wrapper(some_func)

    Отсюда вывод. Декоратор - это функция, и его можно сохранять в переменные, вызывать и так далее.
    Тогда можно сделать такой трюк: написать декоратор-прокси, который запоминает, что за метод мы декорируем, и чем. Примерно так:
    def proxy(storage, *args, **kwargs):
        def wrapper(func):
            storage.append((func.__name__, args, kwargs))
            return func
        return wrapper

    И применять его примерно так:
    class MyCustomCog:
        methods = []
        def __init__(self, bot):
            #задача конструктора - прочитать список отмеченных методов класса, 
            #и отдекорировать методы своего экземпляра класса (не одно и то же)
            for fn, args, kwargs in self.methods:
                #а тут вызываем декоратор вручную
                #что там вместо bot.event? можно сделать несколько прокси, или добавить еще один параметр
                decorator = bot.event(*args, **kwargs) 
                decorator(getattr(self, fn)) #теперь бот знает про наши обработчики событий
        #декоратор-прокси запоминает все декорированые методы в список methods
        #это можно реализовать и по другому, не суть. Главное, что мы запоминаем,
        #с какими параметрами потом вызывать декоратор реального бота - всё, что после methods
        @proxy(methods, "параметры", for="декоратора бота")
        async def some_handler(self, params):
            pass #обработчик того или иного события

    Эту логику можно спрятать в базовый класс, и наследоваться от него, чтоб не повторяться по сто раз. Да и сам proxy() можно сделать методом этого базового класса.
    Ответ написан
    1 комментарий
  • Python, как упаковать текст в квадратную форму?

    fox_12
    @fox_12 Куратор тега Python
    Расставляю биты, управляю заряженными частицами
    pip install tabulate
    from tabulate import tabulate
    
    table = [
        ["Sun",696000,1989100000],
        ["Earth",6371,5973.6],
        ["Moon",1737,73.5],
        ["Mars",3390,641.85]
    ]
    headers = ['planet', 'R(km)', 'mass']
    
    print(tabulate(table, headers, tablefmt="grid"))

    +----------+---------+---------------+
    | planet   |   R(km) |          mass |
    +==========+=========+===============+
    | Sun      |  696000 |    1.9891e+09 |
    +----------+---------+---------------+
    | Earth    |    6371 | 5973.6        |
    +----------+---------+---------------+
    | Moon     |    1737 |   73.5        |
    +----------+---------+---------------+
    | Mars     |    3390 |  641.85       |
    +----------+---------+---------------+


    Да и самостоятельно несложно реализовать:
    num = 20
    print('-'*num, '|'+'test'.center(num-2)+'|', '-'*num, sep='\n')


    --------------------
    |       test       |
    --------------------
    Ответ написан
    Комментировать