• Можно ли сгенерированный Literal передать в параметры функции?

    Vindicar
    @Vindicar
    RTFM!
    поэтому о статическом литерале речи не идет

    А ничего, что литералы, как и большинство инструментов type-checking, предназначены для статической проверки кода? Интерпретатор их игнорирует при выполнении. Их использование в discord.py, хотя и красивое, но всё же нестандартное.
    Поэтому само сочетание "динамический литерал" есть бессмыслица.

    Принимай жанр как строку, и проверяй её самостоятельно, либо, если очень хочется, прописывай для жанра свой конвертер.
    Ответ написан
    Комментировать
  • Как в reply_markup добавить больше переменных с копками?

    Vindicar
    @Vindicar
    RTFM!
    bot.send_photo(message.chat.id, photo, " Выберите нужную функцию:",
    parse_mode="html", reply_markup=tg, info)

    reply_markup=tg - аргумент, переданный по имени
    info - аргумент, переданный позиционно.
    Питон не позволяет указывать позиционные аргументы ПОСЛЕ именованных. Укажи для info имя аргумента, в который ты хочешь передать это значение, по аналогии с reply_markup= или parse_mode=.
    Ответ написан
    Комментировать
  • Как разделить текст на части?

    Vindicar
    @Vindicar
    RTFM!
    Т.е., если переформулировать: разбить текст по символу перевода строки так, чтобы размер первой части не превышал N символов?
    text = """Текст слово Текст
    Новая строка
    Ещё новее строка"""
    N = 12
    
    start, rest = text[:N], text[N:] # отделяем ту часть текста, где мы ищем перевод строки, от остатка
    first, _, second = text.rpartition('\n') # ищем последний перевод строки в этой части - до него "начало"
    last = (second + rest) if second else rest # "конец" собираем из того что после перевода строки и остатка
    print('-'*10)
    print(first)
    print('-'*10)
    print(last)
    print('-'*10)

    Если перевода строки в первой части текста нет, то текст будет просто разрезан по N символам.
    Ответ написан
    2 комментария
  • Как из main.py запустить несколько других файлов .py, чтобы они работали параллельно?

    Vindicar
    @Vindicar
    RTFM!
    Другие идеи есть в документации, просто её надо читать.

    subprocess.Popen() БЕЗ использования wait() или communicate().
    Ответ написан
  • Можно ли узнать возврат функции при использовании многопоточности Thread на Python?

    Vindicar
    @Vindicar
    RTFM!
    Лучше используй долгоживущие потоки и пару queue.Queue. Из первой потоки в цикле извлекают задания и обрабатывают их, во вторую складывают ответы. Главный поток - наоборот, кладёт задания в первую очередь и извлекает ответы из второй.

    См. также: паттерн "поставщик-потребитель".
    Ответ написан
    Комментировать
  • Как сделать вывод в лог logging python?

    Vindicar
    @Vindicar
    RTFM!
    Добавь помимо FileHandler еще и StreamHandler.

    И да, я бы не советовал настраивать логи в конструкторе класса. Пусть класс использует getLogger() и пишет в лог, но определять уровни и места, куда лог пишется, должна основная программа.
    Ответ написан
    Комментировать
  • Как убрать лишние знаки?

    Vindicar
    @Vindicar
    RTFM!
    Ещё один не выучил основы языка, но пытается работать с БД.

    fectchone() возвращает кортеж, в твоём случае кортеж с одним элементом. Скобки - это строковое представление кортежа. Как вытащить значение из кортежа - читай по ссылке.

    Кортежи, списки и словари - это вообще азы языка. Их надо знать, и узнавать с первого взгляда.
    Ответ написан
    Комментировать
  • Сделать, что бы две функции работали?

    Vindicar
    @Vindicar
    RTFM!
    asyncio создаёт цикл-реактор (loop) только для главного потока. Если тебе нужен отдельный реактор в другом потоке (что само по себе повод остановиться и задуматься - нахрена?), создавай его сам в начале потока, потом уже вызывай асинхронный код.
    См. asyncio.new_event_loop() и asyncio.set_event_loop().
    Ответ написан
    1 комментарий
  • Почему 2-handler не запускается?

    Vindicar
    @Vindicar
    RTFM!
    @bot.message_handler() означает, что следующая функция будет обслуживать ВСЕ входящие сообщения, независимо от их содержимого. Соответственно, будет вызываться она, а последующие обработчики сообщений - нет.
    Либо используй параметры message_handler(), чтобы сузить круг обрабатываемых этой функцией сообщений.
    Либо помещай всю логику обработки сообщений в эту функцию, т.е. соедини оба обработчика в один.
    Ответ написан
    Комментировать
  • В чем преимущество статического массива перед динамическим?

    Vindicar
    @Vindicar
    RTFM!
    Насколько мне известно...
    Статический массив:
    - Размер должен быть известен на момент компиляции. Твой пример - это нестандартная фишка ряда компиляторов, по-хорошему для статического массива размер не должен быть динамическим (определяться во время выполнения).
    + Компилятор сам позаботится об удалении массива.

    Динамический массив:
    + Размер может определяться во время выполнения.
    - Нужно не забыть освободить память массива самостоятельно.

    А вообще, если нет причин делать иначе, используй std::vector. Если тебе понадобится именно массив в стиле C, вектор позволяет его легко получить методом .data().
    + Размер не просто динамический, вектор может переаллоцировать свою память по мере надобности. Так что для ситуаций, когда размер заведомо неизвестен, вектор весьма удобен.
    + Вектор сам управляет своей памятью. Убил вектор - убил управляемый им массив.
    Ответ написан
    1 комментарий
  • Из за чего появляется ошибка в строке client.run(config.TOKEN)import discord?

    Vindicar
    @Vindicar
    RTFM!
    В чём моя проблема ?

    1. В том, что ты не знаешь питон, а рвёшься писать ботов. Иначе знал бы, что client.run(config.TOKEN)import discord - это и впрямь неверный синтаксис.
    2. В том, что ты не осилил редактор текста на этом сайте, и не озаботился отформатировать код.
    3. Ну и в том, что ты, походу, вставил код бота в файл дважды.
    Ответ написан
    Комментировать
  • Как ипортировать функции из файлов?

    Vindicar
    @Vindicar
    RTFM!
    Ещё один товарищ не учил Питон, но рвётся написать божественного бота...

    Когда ты импортируешь файл (модуль), этот модуль выполняется - практически так же, как если бы ты его запустил непосредственно. Различие есть, но небольшое. Теперь посмотрим на твои файлы.
    В первом файле ты объявляешь переменную bot. Она существует в пространстве имён первого файла (модуля).
    Если ты в нём делаешь import second_file, в нём тоже присутствует создание переменной bot - в локальном пространстве имён этого модуля. Это две разные переменные, и два разных экземпляра класса Telebot.
    Поэтому когда ты выполняешь в одном файле bot.run() (ну или как там бот запускается), ты запускаешь только один экземпляр. Второй остаётся неактивированным, и всё, что к нему привязано, не работает.

    Тебе надо как-то передать переменную bot во-второй файл, не нарвавшись при этом на циклический импорт (чтобы не было "первый импортирует второй, а второй - первый").
    Тут поможет ещё один простой факт: в питоне всё - операторы. Т.е. объявление функции - это оператор. Его можно помещать куда угодно, внутрь любого блока программы: внутрь if, внутрь цикла, внутрь другой функции. Он выполнится при выполнении соответствующего блока.
    Так что ты можешь завернуть свои обработчики из второго файла в функцию, принимающую ссылку на bot. А потом импортировать эту внешнюю функцию в первый файл и там её вызвать.
    #второй файл, second_file.py
    import telebot
    from telebot import types
    # эта функция создаст все обработчики и зарегистрирует их в предоставленном боте
    # вызывай её строго один раз за скрипт
    def register_handlers(bot):
        # а тут уже пошли обработчики
        @bot.message_handler(commands=['start'])
        def start(message):
            markup = types.ReplyKeyboardMarkup(resize_keyboard=True)
            btn0 = types.KeyboardButton(' Каталог фильмов')
            btn1 = types.KeyboardButton(" Каталог фильмов")
            btn2 = types.KeyboardButton(' Случайный фильм')
            btn3 = types.KeyboardButton(' Предложить фильм')
            markup.add(btn0, btn1, btn2, btn3)
            bot.send_message(message.from_user.id, ' Привет, {0.first_name}. Я Kinomorph - бот, с которым ты можешь найти интересный фильм для просмотра вечером\n \n Если у тебя есть номер или название фильма, ввести его можно прямо сейчас'.format(message.from_user), reply_markup=markup)
    
    # любой код, который не должен исполняться при импорте, оформляй так:
    if __name__ == '__main__':   # переменная __name__ содержит имя, под которым импортируется модуль
        print('Этот код выполнится ТОЛЬКО если файл запущен напрямую.')
        print('Он не выполнится при импорте файла.')


    # первый файл, main.py
    import telebot
    import config
    import second_file  # модуль импортируется - в нём __name__ будет равно "second_file", а не "__main__"
    
    # инициализация
    bot = telebot.TeleBot(config.Token)
    second_file.register_handlers(bot)  # тут вызывается импортированная функция
    Ответ написан
    Комментировать
  • Почему не работает bot_func.stop(Client, module Pyrogram)?

    Vindicar
    @Vindicar
    RTFM!
    loop = asyncio.new_event_loop()
    asyncio.set_event_loop(loop)

    Зачем?!
    Если у тебя бот асинхронный, просто сделай саму функцию GetUserByUsername() async.
    Ответ написан
  • Как получить списки в переменные?

    Vindicar
    @Vindicar
    RTFM!
    list_of_lists = [spisok[i:i + n] for i in range(0, len(spisok), n)]
    Ответ написан
    Комментировать
  • Как исправить "io.UnsupportedOperation: read"?

    Vindicar
    @Vindicar
    RTFM!
    fp = open(f'captcha_{str(ran)}.jpg', 'wb')
    fp.write(res.content)

    Ты открыл файловый объект для записи, а чтобы его отправить, нужно чтение.
    Или открой объект для модификации ("wb+") и сделай fp.seek(0, 0) после записи, чтобы вернуться в начало файла.
    Или закрой файл, и открой его снова, уже для чтения ("rb").
    Ответ написан
  • Не выполгяется последняя часть кода @bot.callback_query_handler(func=lambda call:True) def callback2(call): почему и как исправить?

    Vindicar
    @Vindicar
    RTFM!
    @bot.callback_query_handler(func=lambda call:True)
    func говорит боту, когда вызывать обработчик. Бот вызывает только ОДИН обработчик (первый подходящий).
    func=lambda call:True означает, что обработчик должен вызываться для ВСЕХ кнопок.
    Научись различать обработчики по call.data. Например, пусть у одной группы кнопок data начинается с "foo.", а у другой - с "bar.".
    item = types.InlineKeyboardButton('4', callback_data='foo.question1')
    item2 = types.InlineKeyboardButton('3', callback_data='foo.question2')

    gotov = types.InlineKeyboardButton('Готов', callback_data='bar.gotov')

    Тогда ты сможешь прописать два обработчика:
    @bot.callback_query_handler(func=lambda call:call.data.startswith('foo.'))

    и
    @bot.callback_query_handler(func=lambda call:call.data.startswith('bar.'))


    Разумеется, вместо foo и bar можно придумать свои префиксы, в том числе многоуровневые (типа callback_data='questions.q1.answer1').
    Ответ написан
    1 комментарий
  • Sqlite3 операционная ошибка, как исправить?

    Vindicar
    @Vindicar
    RTFM!
    c.execute(f"SELECT * from banking_application WHERE name_p IS {pop}")

    За такое бьют линейкой по пальцам. Собственно, ты уже наткнулся на одну из причин почему. Вторая тут.
    Ну и да, IS используется только как IS NULL или IS NOT NULL. Надо вот так:
    c.execute("SELECT * from banking_application WHERE name_p = ?", pop)
    Ответ написан
  • Как обратится к функции вне handler?

    Vindicar
    @Vindicar
    RTFM!
    global resault_func
    resault_func = fi(fil)

    Примерно так и обращайся.
    Ответ написан
    1 комментарий
  • Как корректно разобрать последовательность байт из COM-порта в python?

    Vindicar
    @Vindicar
    RTFM!
    Но почему каша в serial, и как его ответ сделать только bytes без исключения, требует размышления и осознания. Ведь переменная a - это bytes, и binascii.hexlify(a) это тоже bytes...

    Потому что никакой каши нет. Ответ уже только bytes.
    Просто когда выкидывашеь их в консоль, питон (точнее, метод __str__() класса bytes) пытается их представить "как можно читабельнее", т.е. пробует декодировать как ascii-строку что получится, а что не получится, представляет escape-последовательностями \x??.
    Доказать легко:
    b1 = bytes([1,2,3])
    print(b1)  # b'\x01\x02\x03'
    # начиная с Python 3.8 можно указать разделитель в методе hex()
    print(b1.hex(' ')) # 01 02 03
    
    b2 = bytes([0x57, 0x54, 0x46])
    print(b2)  # b'WTF'
    print(b2.hex(' ')) # 57 54 46

    Как видим, работает идентично
    Ответ написан
    Комментировать
  • Как добавлять произвольные данные в extra в logging python?

    Vindicar
    @Vindicar
    RTFM!
    Чем не устраивает вариант с непосредственной подстановкой данных в строку?
    logger.info("New log data: param1 = %s, param2 = %s", value1, value2)

    Просто если у тебя так много разных вариантов подставляемых данных, то проще это решать на уровне отдельного обращения к логгеру.
    Ответ написан