Задать вопрос
  • Как прослушать несколько портов в python?

    Vindicar
    @Vindicar
    RTFM!
    Можно, открыв несколько сокетов и проверяя их все.
    Но начиная с определенного числа команд проще будет использовать SSH или иную форму удалённого управления.
    Ответ написан
    Комментировать
  • Есть ли датасеты текстур майнкрафта до 12.2 включительно с указанными айдишниками от mcpi,?

    Vindicar
    @Vindicar
    RTFM!
    %APPDATA%\.minecraft\versions\{Версия}\client.jar
    Открываешь его винраром или другим архиватором (jar - это zip-архив).
    Идёшь в assets\minecraft\textures\block
    профит.
    Ответ написан
    2 комментария
  • Как отсортировать элементы с определенным id в mongodb (pymongo) и записать их в список?

    Vindicar
    @Vindicar
    RTFM!
    В первом случае ты ищешь все элементы, у которых server_id НЕ совпадает (!=) с message.guild.id.
    Во втором случае ты ищешь все элементы, у которых server_id совпадает с message.guild.id.

    Исходя из твоего результата, я бы сказал, что у тебя в базе нет элемента с таким id. Ты уверен, что он там есть? Что насчёт типов данных - нет ли тут косяка, вроде "храню id как строку, а передаю при поиске как целое число"?

    И да, говори правильно. То, что ты делаешь - поиск/фильтрация, а не сортировка.
    Ответ написан
  • Как обрабатывать ошибки в асинхронном коде?

    Vindicar
    @Vindicar
    RTFM!
    try: 
        loop.create_task(exc())
    except ZeroDivisionError as ex:
        print(f"Ошибка {ex} обработана")

    1. Ты создаёшь задачу на базе корутины exc(). Созданная задача не выполнится немедленно, а только встанет в очередь исполнения (хотя в питоне 3.12 это поведение можно изменить, но по умолчанию это так). При этом с корутиной ассоциируется future-объект, который находится в состоянии "ожидание", так как корутина ещё не завершила работу.
    2. Ты проверяешь, не возникло ли исключение в процессе создания задачи. Это может произойти, только если exc() - не корутина. В остальных случаях операция будет успешна независимо от содержания exc(), так как см. пункт 1.
    3. Ты вызываешь loop.run_forever(). Рабочий цикл (loop) смотрит в очередь исполнения, и видит в нём только корутину exc(). Она получает управление.
    4. Корутина exc() выбрасывает исключение, но не ловит его. Ассоциированный с корутиной future-объект переходит из состояния "ожидание" в состояние "отказ", и сохраняет информацию об исключении. exc() завершает работу.
    5. Рабочий цикл проверяет, кто хранит ссылку на task - и понимает, что никто. Как следствие, даже в будущем никто не сможет узнать, что корутина выкинула исключение. Поскольку рабочий цикл - штука типовая, он понятия не имеет, что делала наша корутина и как надо реагировать на исключение в ней. А потому единственный вариант для него - написать в журнал работы о непойманном исключении и надеяться, что программист это увидит и поправит.
    task = asyncio.create_task(exc())
    try:
        # await asyncio.gather(task)  # <- gather() не нужно, если у тебя одна задача
        await task
    except ZeroDivisionError as ex:
        print(f"Ошибка {ex} обработана")

    1. Ты создаёшь задачу (успешно), а потом с помощью await-вызова просишь дождаться её завершения и получить результат.
    2. Корутина main() приостанавливает своё выполнение и сохраняет свой контекст, а также встаёт в очередь, ожидая, когда сработает future-объект, связанный с task.
    3. Рабочий цикл (loop) asyncio смотрит в очередь выполнения и видит, что корутина exc() готова выполняться (она не находится в await вызове, а только начала работу).
    4. Корутина exc() получает управление, выполняется, и генерирует исключение, которое не поймано внутри этой корутины. Future-объект, связанный с этой корутиной, переходит из состояния "ожидание" в состояние "отказ", и сохраняет информацию об исключении. Корутина exc() завершает выполнение. При этом о её future-объекте знает корутина main(), поэтому рабочий цикл не дёргается по этому поводу - у main() будет возможность отреагировать на происходящее.
    5. Рабочий цикл (loop) смотрит в очередь выполнения и видит, что там только корутина main(), причём она готова выполняться - future-объект, который она ждёт, более не находится в состоянии ожидания.
    6. Корутина main() получает управление и восстанавливает свой контекст, продолжая с того места, где она остановилась. Так как future-объект находится в состоянии "отказ", оператор await читает из него информацию об исключении и перевыбрасывает это исключение внутри main().
    7. Это исключение обрабатывается блоком try-except в main() как обычно.
    Ответ написан
    Комментировать
  • Почему когда отвечаю на сообщение в чате, сообщение не присылается пользователю в бота обртано?

    Vindicar
    @Vindicar
    RTFM!
    У тебя handle_message() стоит первым - поэтому бот будет пытаться использовать его для любых текстовых сообщений. А поскольку у тебя там тупо if, без какой-либо реакции на неожиданные сообщения, то если if не выполнился, бот молча ничего не сделает.
    Ответ написан
    Комментировать
  • Как отправлять данные пользователю из бота telegram?

    Vindicar
    @Vindicar
    RTFM!
    У тебя, походу, button() прописан как обработчик для всех кнопок. А вот внутри него не прописана ветка для data == 'send_purchase'. На текущем шаге добавь во ВСЕ цепочки if ... elif ... elif ... ветку else, которая выводит отладочное сообщение - тогда хоть будет понятно, какой обработчик вызвался и с каким значением.
    Ответ написан
    1 комментарий
  • Как сделать свять вежду python игрой и сайтом на html?

    Vindicar
    @Vindicar
    RTFM!
    1. Ты должен выбрать себе схему URL, по аналогии с тем, как это делает телеграм с его схемой tg:// или стим (steam://).
    2. Научись упаковывать свою игру в exe-файл с помощью любого упаковщика - например, auto-py-to-exe.
    3. Подразумевается, что игра уже установлена на компьютере пользователя. При установке она регистрирует себя как обработчик для данной схемы. Это делается по-разному для винды и для линукса.
    Для винды нужно будет залезть в реестр через стандартный модуль registry

    Тебе нужно создать ключ реестра HKEY_CLASSES_ROOT/ИмяТвоейСхемы. Убедись, что такого ключа нет, перед тем как его создавать!
    В ключе создаёшь строковое значение с именем URL Protocol и пустым значением.
    Создаёшь вложенный ключ: HKEY_CLASSES_ROOT/ИмяТвоейСхемы/shell
    Внутри вложенного ключа создаёшь строковое значение с именем command и значением такого вида: "C:\путь\к\твоей\игре.exe" "%1"

    После этого при попытке ввести в браузере ссылку, начинающуюся с твоей схемы, должна запуститься твоя игра.
    3. Твоя игра должна проверять параметры командной строки (читай про sys.argv). Если игра запущена без параметров - её запустили просто ярлыком. Если игра запущена с одним параметром, и он начинается с твоей схемы - её запустил клик по ссылке. Разбирай текст ссылки в параметре и решай, что игра должна сделать.

    Технически, ты не обязан сам лезть в реестр в python-скрипте - ты можешь сделать это ручками через regedit или поручить это установщику, типа NullSoft. Он же позаботится о том, чтобы снести созданные ключи при удалении игры.
    Я бы сначала попробовал зарегистрировать URL вручную, убедился что это работает, а потом уже игрался бы с установщиком.
    Ответ написан
    Комментировать
  • SyntaxError: 'await' outside function. Как исправить ошибку кода, который должен пересылать удаленные сообщения в телеграмме в избранное?

    Vindicar
    @Vindicar
    RTFM!
    await client.run_until_disconnected()
    Эта строка где находится? Вне функции? А почему?
    Выглядит как будто ей место в main().
    Ответ написан
    Комментировать
  • Как обойти ошибку Tcl_AsyncDelete: async handler deleted by the wrong thread?

    Vindicar
    @Vindicar
    RTFM!
    Поясню ответ выше: насколько я знаю, графические интерфейсы строго однопоточны. Как минимум под Windows это так, а потому ни один графический фреймворк не поддерживает обращение к окнам и их элементам из других потоков.
    Как следствие, если ты хочешь организовать фоновый поток с "обратной связью" в GUI, обычно требуется использовать очередь, например, queue.Queue. В эту очередь фоновый поток должен класть сообщения, объясняющие, что надо сделать - например, сведения о прогрессе операции, или команды на смену состояния, или ещё что. Это зависит от твоей задачи.
    Тогда основной поток программы, который и отвечает за GUI, должен использовать средства фреймворка для периодической проверки очереди на предмет сообщений. Например, в обычном tkinter это будет реализовано через метод after().
    Если в очереди есть сообщения, основной поток читает их и выполняет соответствующие действия - например, меняет положение прогресс-бара, включает/выключает кнопки, и т.д.
    Если фоновый (рабочий) поток живёт долго, то может иметь смысл организовать вторую очередь для передачи команд из GUI-потока в рабочий. Идея та же самая: рабочий поток ждёт появления команды в своей входной очереди, и выполняет её, а потом сбрасывает уведомления в исходящую очередь.
    Ответ написан
    Комментировать
  • Как вывести роли discord сервера, кроме заблокированных?

    Vindicar
    @Vindicar
    RTFM!
    В discord.py ты можешь просто сравнивать роли. Но ты пытаешься сделать это вручную...
    Если заглянуть в исходники либы, то можно увидеть, что там проверяется свойство position. Причем вроде как меньший position означает меньшие привилегии, с поправкой на то что роль @everyone меньше всех.
    Тогда решением твоей задачи будет:
    1. Определить список ролей твоего токена на рассматриваемом сервере.
    2. Определить наибольший position среди этих ролей.
    3. Получить список всех ролей на рассматриваемом сервере.
    4. Отсеять роли, у которых position больше твоего наибольшего.

    Если я напутал и меньший position означает большую роль, то логика примерно та же самое, только меняешь больше на меньше.
    Ответ написан
  • Как добавить фон скрипту, запускаемому через консоль?

    Vindicar
    @Vindicar
    RTFM!
    Полноценную картинку в консоли не покажешь, тут тебе не линукс. Но ASCII-арт можно - вопрос только как разделить вывод текста игры и вывод ascii-арта. Например, сделать два логических "окна" в одном терминале.

    Ставишь пакет windows-curses, после этого можно будет и на винде использовать стандартный модуль curses. Он и это умеет, и цветной вывод.
    Ответ написан
    Комментировать
  • Как добавить несколько изображений к locateOnScreen?

    Vindicar
    @Vindicar
    RTFM!
    Никак, функция ищёт одно изображение.
    Если тебе нужно несколько, ищи их последовательно, пока не найдётся хотя бы одно из них.
    Ответ написан
    2 комментария
  • Как можно в Linux настроить маршрутизацию для доменов 1-ого уровня?

    Vindicar
    @Vindicar
    RTFM!
    Никак, маршрутизация работает на более низком уровне и не имеет понятия о доменном имени.
    С точки зрения таблицы маршрутов нет разницы между обращением по доменному адресу и обращением по IP, потому что доменное имя преобразуется в IP адрес до этого.
    Один вариант: используй связку прокси+прокси или прокси+впн, если ПО поддерживает работу с прокси.
    Второй вариант: настраивай маршруты на соответствующие IP диапазоны, но тогда любые обращения по этим диапазонам пойдут через соответствующий шлюз.
    Ответ написан
    Комментировать
  • Не могу сделать sql запрос с внутренней переменной python, как?

    Vindicar
    @Vindicar
    RTFM!
    Ignis138, ты основы питона почитай немножечко, чтобы хоть понимать, где у тебя в коде что.
    Ты в тексте запроса указал, что у тебя в запросе есть подставляемое значение по имени degress_id. Это имя никак не обязанно коррелировать с именем переменных, sqlalchemy ничего не знает о твоих переменных. Так что теперь ты должен указать, какое значение должно быть подставлено.
    with Session(self.engine) as s:
        query = """
            SELECT direction, profile,budget,commerce,min
            FROM directions
            WHERE d_id = %(degress_id)s
            """
        rows = s.execute(text(query))  # вот где-то тут

    Заглядываем в документацию (окей, гугл, sqlalchemy Session execute).
    Быстренько находим ссылку на описание самого класса Session (в противоположность общим объяснениям как им пользоваться).
    Ищем описание метода execute().
    Читаем список параметров:

    statement – An executable statement (i.e. an Executable expression such as select()).

    Иными словами, запрос, который надо выполнить. Ты его передаёшь как text(query).

    params – Optional dictionary, or list of dictionaries, containing bound parameter values. If a single dictionary, single-row execution occurs; if a list of dictionaries, an “executemany” will be invoked. The keys in each dictionary must correspond to parameter names present in the statement.

    Словарь или список словарей. У тебя один запрос, так что нужен один словарь. Ключи словаря должны соответствовать именам параметров. У тебя в запросе указан один параметр degress_id.

    Таким образом, приходим к тому, что вторым параметром нужно передать словарь, в котором есть один ключ "degress_id" и сопоставленное ему значение.

    И вот тут мы снова подходим к началу поста: если б ты озаботился почитать про основы языка, в частности, что такое словари (окей, гугл, python словарь).
    Тогда, глядишь, дошёл бы и до такой конструкции:
    degress_id_value = ...  # тут ты определяешь, какое значение подставляешь в запрос
    rows = s.execute(text(query), {"degress_id": degress_id_value})
    Ответ написан
    Комментировать
  • Стоит ли использовать ООП для бота на Telebot?

    Vindicar
    @Vindicar
    RTFM!
    Ну почему бы и нет?
    Вон, discord.py вообще реализует механизм когов (cogs), который позволяет заключать отдельные наборы поведений в класс, и подгружать/выгружать этот класс по ходу работы.
    Нечто подобное можно построить на базе почти любой библиотеки чат-ботов, особенно если с выгрузкой заморачиваться не требуется.
    Просто если у тебя только один набор связанных поведений, то и класс с обработчиками будет один - и смысл тогда?
    Ответ написан
    Комментировать
  • Как работает запуск корутин в asyncio?

    Vindicar
    @Vindicar
    RTFM!
    3FANG,
    насчёт твоего второго вопроса: всё предельно просто. Ты запустил 10 копий корутины, они все выполнили print('start') и ушли в спячку на две секунды - практически одновременно!
    Точнее, первая корутина встала в очередь, create_task() закончила свою работу и вернула управление в твой цикл запуска корутин. И так 10 раз. Все корутины стоят в очереди плотно друг за другом.
    Затем ты входишь в цикл ожидания корутин, пишешь в консоль "старт", дожидаешься первой корутины, при этом main() встаёт в очередь на вызов. Первая корутина запустилась, написала start, и ушла в ожидание. Следующая в очереди готова вторая корутина. Она запустилась, написала start, ушла в ожидание. И так далее. В конце main() снова оказывается в начале очереди - но она ждёт первую корутину, она ещё не готова выполняться. Она отправляется в конец очереди. Поэтому программа ждёт первую корутину, но ожидание-то тикает у всех!
    Тогда первая корутина отработала - но прежде чем ты вернёшься из await-вызова в main(), сначала успеют отработать всё стоящие в очереди корутины, потому что их время тоже подошло, и они стоят в очереди раньше! И ты видишь последовательность start-finish внутри корутин.
    Затем очередь вызова доходит до main() и ты видишь "финиш" ожидания первой корутины. Ты начинаешь ждать вторую (старт) - но она уже отработала, поэтому main() единственная в очереди, и она тут же получает управление обратно (финиш). И так с оставшимися корутинами.

    Если ты сделаешь так, чтобы каждая следующая копия корутины ждала дольше предыдущей, то ситуация будет интереснее:
    код
    import asyncio 
    from time import time, sleep
    
    
    async def waste_time(i, delay):
        print(f"Start work {i}...")
        await asyncio.sleep(delay)
        print(f"End work {i}!")
    
    
    async def main():
        tasks = []
    
        for i in range(10):
            task = asyncio.create_task(waste_time(i+1, (i+1)*1.0))
            tasks.append(task)
    
        for i, task in enumerate(tasks, 1):
            print(f'start wait {i}')
            await task
            print(f'end wait{i}')
    
    if __name__ == '__main__':
        start = time()
        asyncio.run(main())
        print(time() - start)

    вывод
    start wait 1
    Start work 1...
    Start work 2...
    Start work 3...
    Start work 4...
    Start work 5...
    Start work 6...
    Start work 7...
    Start work 8...
    Start work 9...
    Start work 10...
    End work 1!
    end wait1
    start wait 2
    End work 2!
    end wait2
    start wait 3
    End work 3!
    end wait3
    start wait 4
    End work 4!
    end wait4
    start wait 5
    End work 5!
    end wait5
    start wait 6
    End work 6!
    end wait6
    start wait 7
    End work 7!
    end wait7
    start wait 8
    End work 8!
    end wait8
    start wait 9
    End work 9!
    end wait9
    start wait 10
    End work 10!
    end wait10
    10.012470483779907
    Ответ написан
    5 комментариев
  • Как решить disnake.ext.commands.errors.CommandInvokeError: Command raised an exception: AttributeError: 'str' object has no attribute 'timeout'?

    Vindicar
    @Vindicar
    RTFM!
    Включаем логику.
    Ты хочешь, чтобы бот сделал вот это:
    await member.timeout(reason=reason, until=duration)  # timeout() - метод класса discord.Member

    Но! У тебя заголовок функции-обработчика описан так:
    async def mute(self, inter, member, duration = "Навсегда", reason: str = "Не указана"):

    Ты не указал тип member - по умолчанию это будет строка. Если тебе нужно, чтобы тут была ссылка на участника сервера, ты должен был указать соответствующий тип, как это показано в документации на библиотеку. Для discord.py ссылка тут, в disnake это должно делаться похожим образом, так как диснейк базируется на дискорд пи. В любом случае, если что-то непонятно - сначала находишь и читаешь документацию и примеры в ней.

    В твоём случае этого примера должно быть достаточно, чтобы понять, что нужно изменить в заголовке mute().
    Ответ написан
    Комментировать
  • Имитация веб-камеры - как автоматизировать на python (linux)?

    Vindicar
    @Vindicar
    RTFM!
    Извини, а у тебя ничего не ёкнуло вот тут?
    sudo apt install v4l2loopback
    pip install v4l2loopback
    Ты понимаешь разницу между этими двумя командами?
    Первая - задействует системный менеджер пакетов для дистрибутивов на базе debian (deb-пакетов).
    Вторая - задействует встроенный менеджер пакетов питона.
    Это совершенно разные вещи, и они работают с совершенно разными репозиториями.
    Установить deb-пакет в систему, на которой будешь тестить, достаточно будет один раз.
    Прописать мод можно в /etc/modules, но можно и тупо делать modprobe при загрузке системы.
    И то и то, я полагаю, можно сделать хоть на живой системе, хоть внутри докера.

    После этого в автотесте запускаешь ffmpeg, можно даже тупо через subprocess вместо питоновских модулей. Сюрприз, сюрприз! Они все, насколько я знаю, именно так и делают под капотом. Я не видел модуля, который бы имел интегрированный ffmpeg.
    Ответ написан
    3 комментария
  • Ошибка TypeError: work_command() missing 1 required positional argument: 'points' что делать?

    Vindicar
    @Vindicar
    RTFM!
    @bot.message_handler(content_types=['text'])
    def work_command(message, points):


    Бот ничего не знает про points и откуда оно берётся. Бот ожидает, что любая функция, отмеченная как обработчик сообщений, принимает ровно один параметр - объект принятого сообщения. Если это условие не выполняется, это твой косяк.

    если делать global points то будет у всех один баланс

    Вовсе нет. Ты не обратил внимание, что у тебя points - словарь, где ключ - id пользователя? (к слову, кто код писал? уж точно не разраб-крут). У тебя для разных id пользователей будут отдельные элементы в словаре, с отдельными значениями.

    Другое дело, что словарь не переживёт перезапуска бота...
    Ответ написан
  • Как сделать бота поддержки с при помощи библиотеки telebot?

    Vindicar
    @Vindicar
    RTFM!
    Не пытайся объявлять обработчики событий динамически, внутри других обработчиков. Это не будет работать так, как ты это ожидаешь!
    А для начала определись с ответом на вопрос: если есть несколько одновременных обращений, то как бот поймёт, кому отвечает оператор?

    Один из вариантов

    Оператор должен явно отвечать (через соотв. пункт меню) на сообщение бота.
    Тогда бот должен хранить список вида "id сообщения в группе, id пользователя. Можешь хранить в БД или ином хранилище (БД в конечном итоге будет проще всего).

    В этом случае логика бота по обработке сообщения будет такая:
    1. Если сообщение в личке: отправить копию сообщения в группу, сохранить в БД id пользователя и id отправленного ботом сообщения.
    2. Если сообщение в группе, и это ответ: поискать в БД id сообщения, на которое ответ. Если id найдено - извлечь соответствующее id пользователя, отправить ему копию сообщения.
    3. Если id не найдено: что должен сделать бот?
    4. Если сообщение в группе, но это не ответ: что должен сделать бот?

    Можно также прикреплять к записи в БД дату, чтобы время от времени можно было выкидывать из БД старые сообщения. Это уже упражнение для читателя.
    Ответ написан
    Комментировать