Задать вопрос
Ответы пользователя по тегу Python
  • Как бот должен понимать что нужно нажимать кнопку во время qte?

    Vindicar
    @Vindicar
    RTFM!
    Template matching попробуй.
    Ответ написан
    Комментировать
  • Почему IDLE и командная строка не видят модуль keyboard?

    Vindicar
    @Vindicar
    RTFM!
    keyboard - это сторонний модуль. Ты его установил через pip?
    Ответ написан
  • Создание, сохранение, проверка ключей доступа?

    Vindicar
    @Vindicar
    RTFM!
    Ну если совсем извратиться, то:
    * зашифровать программу желаемым ключом
    * написать лоадер, который просит у пользователя пароль, загружает файлы основной программы в память, расшифровывает их введённым ключом и пытается запустить точку входа в основную программу.

    Тогда подглядеть ключ в лоадере не получится, как и оторвать сам лоадер. Разве что брутфорсить ключ, пытаясь найти такой ключ, который даст на выходе корректные питоновские скрипты.

    Примерный путь будет:
    1. Загрузить бинарные данные из файла как bytes
    2. Расшифровать в памяти, получив исходники
    3. Использовать exec()

    Альтернативно, вместо исходников можно шифровать байткод, но тогда придётся соображать, как превратить bytes в code object, который можно выполнить через exec(). Теоретически, может помочь marshal.

    Схема не 100% надёжная, разумеется.

    А вообще, какая у тебя задача? Может, pyarmor подойдёт?
    Ответ написан
  • Можно ли узнать какая корутина вызвала ошибку в asyncio.gather?

    Vindicar
    @Vindicar
    RTFM!
    Вообще-то gather() возвращает исключения и результаты в том же порядке, в котором переданы корутины. Всегда.
    Но ты сам себе выстрелил в ногу вот этим: *{f1(), f2()}
    Ты указал литерал множества, а это не упорядоченная коллекция. Так что в каком порядке были переданы корутины - хз.
    Положи их в кортеж или в список перед отдачей в gather(), и проблема уйдёт - элемент выходного списка с индексом i будет соответствовать корутине с индексом i в исходном кортеже/списке.
    Ответ написан
    Комментировать
  • Почему метод find_all из bs4 возвращает пустой список?

    Vindicar
    @Vindicar
    RTFM!
    А ты уверен, что то, что ты видишь в браузере - это то же, что получает на вход BS?
    Инста может либо детектить тебя как бота, и отдавать другую страницу, или просто использовать JS для динамической подгрузки контента, отдавая статически только "болванку". BS не выполняет JS код, так что болванка - это всё, что он увидит в таком случае.
    Скинь page.text в файл и посмотри, что там.
    Ответ написан
    Комментировать
  • Установление значений для маркеров в Matplotlib?

    Vindicar
    @Vindicar
    RTFM!
    Я бы использовал pyplot.text() или pyplot.annotate() (ну или соответствующие методы ax).
    Они позволяют указывать координаты текста в единицах данных (т.е. в координатных осях на твоём графике). А маркеры по умолчанию ставятся на каждую точку данных, так что привязать текст к тем же точкам что и маркеры будет тривиально - просто цикл по данным и вызов метода на каждую позицию.
    for xv, yv in zip(x, y):
        caption = f'{yv:.0f}'  # тут генеришь надпись так, как тебе надо
        ax.text(xv, yv, caption, ha='center', va='top')  # по умолчанию координаты задаются по данным
    Ответ написан
    Комментировать
  • Как из fetchall() сделать строку?

    Vindicar
    @Vindicar
    RTFM!
    Как, как... Каком кверху!
    Итерируешься по списку через for row in cursor:, распаковываешь кортеж через login, pass = row (ну или по индексу login = row[0]), дальше с переменными делаешь что нужно.
    Азы языка! Если ты их не знаешь, какого баклажана берёшься за БД?

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

    Vindicar
    @Vindicar
    RTFM!
    cards = trees() #ФУНКЦИЯ ПАРСИНГА
    Ну вот тут уже проблема. Ты в асинхронном боте делаешь длительный синхронный вызов.
    Перепиши свой парсер на асинхронный код, запусти его через asyncio.create_task() и сохрани полученный объект задачи в глобальную переменную (если у тебя может быть не более одного активного парсера).
    Для отмены проверь, что в глобальной переменной лежит не None, а искомый объект. Если так, то вызови у него метод cancel().
    Это спровоцирует исключение CancelledError в функции парсера, что позволит прервать её выполнение, но в то же время аккуратно отработать освобождению ресурсов и т.п.
    Ответ написан
    Комментировать
  • Как заменить/обновить данные в sqlite (Python)?

    Vindicar
    @Vindicar
    RTFM!
    Во-первых, следует различать сценарий "я знаю, что строка есть, её надо обновить" (UPDATE) и "строки может не быть, если так, её надо создать" (INSERT OR REPLACE или INSERT ON CONFLICT UPDATE). Уточни, какой у тебя.

    Во-вторых, приведи код создания таблицы. У тебя link - первичный ключ?
    Ответ написан
  • Как запустить асинхронную функцию внутри синхронной flask?

    Vindicar
    @Vindicar
    RTFM!
    Ну для начала, проверка на вменяемость. Асинхронному боту для работы нужен рабочий цикл-реактор (event loop). Где и как ты его запускаешь, с учётом того, что Flask тоже требует рабочий цикл, а у тебя, вроде как, один поток?

    Я бы посоветовал использовать асинхронный веб-фреймворк. Например, доки на Flask упоминают Quart как максимально похожий, но изначально асинхронный фреймворк. Тебе всё ещё придётся разобраться, как параллельно запустить две длительные корутины (рабочий цикл Quart и рабочий цикл бота), но это уже решаемо. Вместо Quart можно использовать любой другой асинхронный веб-фреймворк.

    Альтернативно, можно запустить фласк и бота в разных потоках. Мешать асинхронность с многопоточностью - тоже та ещё идея, но если очень неохота уходить от Flask, то можно попробовать. Однако в этом случае нужно будет очень осторожно выполнять вызовы методов бота. В документации есть пример, как вызвать корутину в другом потоке ОС и дождаться ответа от неё.
    Ответ написан
    1 комментарий
  • Как создать новый словарь, не меняя старый?

    Vindicar
    @Vindicar
    RTFM!
    rows = self.rows
    НО! В тоже время изменяется из self.rows, который является другим списком.

    Не является. Твой оператор просто присвоил переменной rows ссылку на тот же самый список, что и self.rows.
    Это легко проверить оператором is или сравнением id():
    print(rows is self.rows, id(rows) == id(self.rows))  # True True

    Более того, если ты только скопируешь сам список:
    rows = self.rows.copy()
    То всё ещё поймаешь проблемы, так как скопируются ссылки на элементы, а не их значения:
    print(rows is self.rows, id(rows) == id(self.rows))  # False False
    print(rows[0] is self.rows[0], id(rows[0]) == id(self.rows[0]))  # True True

    Тебе нужно сделать глубокую копию (deepcopy). Это можно сделать вручную, так как у тебя всего два уровня вложенности (список-словарь):
    rows = [rowdict.copy() for rowdict in self.rows]
    Для более глубоких уровней есть функция copy.deepcopy(), но у неё есть свои подводные камни. Цитата:
    Two problems often exist with deep copy operations that don’t exist with shallow copy operations:
    Recursive objects (compound objects that, directly or indirectly, contain a reference to themselves) may cause a recursive loop.
    Because deep copy copies everything it may copy too much, such as data which is intended to be shared between copies.
    Ответ написан
    Комментировать
  • Зачем нужен декоратор @dp и все в этом духе, типо @dp.message_handler() в aiogram?

    Vindicar
    @Vindicar
    RTFM!
    На пальцах: чтобы бот работал, его функции должны вызываться при наступлении определённых событий (например, входящего сообщения). Проблема в том, что aiogram знает о возможных событиях, но ему нужно сказать, какие функции когда вызывать. Обычно это называется "зарегистрировать обработчик".
    В питоне функции - объекты первого рода, т.е. их можно сохранять в переменные, передавать как параметры, возвращать как результат и вообще поступать с ними как с любым другим значением.
    Т.е. по идее можно было бы сделать так:
    async def echo(message: Message):
        text = f"Привет, ты написал {message.text}"
        await bot.send_message(chat_id=message.from_user.id, text=text)
    
    dp.register_function_for_message(echo)  # это не настоящий метод aiogram, только пример

    Тогда каждому объявленному обработчику событий соответствовал бы вызов метода, ответственного за регистрацию этого обработчика.

    Но то же самое можно сделать через декораторы. Декоратор - это сокращённый вызов функции, которая принимает в качестве параметра другую функцию.
    Т.е. вот это
    @dp.message_handler()
    async def echo(message: Message):
        text = f"Привет, ты написал {message.text}"
        await bot.send_message(chat_id=message.from_user.id, text=text)

    абсолютно эквивалентно вот этому
    _decorator = dp.message_handler()
    
    async def echo(message: Message):
        text = f"Привет, ты написал {message.text}"
        await bot.send_message(chat_id=message.from_user.id, text=text)
    
    echo = _decorator(echo)

    Как видишь, очень похоже на "простую" регистрацию обработчика, но записывается чуть короче.
    Ответ написан
  • Как удалить слова из списка в строке, почему не работает?

    Vindicar
    @Vindicar
    RTFM!
    split() разбивает по пробельным символам. У тебя в списке list_of_words будет 'Москва.', а не 'Москва' и '.'
    Ответ написан
    2 комментария
  • Почему в приведенном примере есть разница в расположении raise StopAsyncIteration?

    Vindicar
    @Vindicar
    RTFM!
    Я подозреваю, что по исчерпанию self.r (а range() - это не список, это одноразовая последовательность!) попытка вхождения в async for x in self.r приведёт к тому, что self.r просигнализирует об исчерпании последовательности. Как следствие, тело async for не выполнится ни разу, и управление выйдет за цикл. А за циклом - ничего, конец корутины. Поэтому, так как явного return не было, будет неявный return None. Что ты и наблюдаешь.
    Соответственно, ты никогда не получишь выброс StopIteration - его будет выкидывать self.r.__anext__(), но исключение будет перехватываться async for.
    Так что нужно добавить raise StopIteration() после async for, чтобы по опустошению self.r оно гарантировано выбрасывалось.
    Ответ написан
    1 комментарий
  • Aiogram как перейти на другой @dp message_handler()?

    Vindicar
    @Vindicar
    RTFM!
    Что у тебя за каша с вложенными обработчиками? Нет никаких гарантий, что это вообще будет работать.
    Научись пользоваться finite state machine.
    Ответ написан
    Комментировать
  • Как определять количества целых чисел на отрезке, интервале, полуинтервале?

    Vindicar
    @Vindicar
    RTFM!
    Разбей задачу на меньшие.
    1. Научиться разбирать входную строку. Можно регулярными выражениями, можно вручную с помощью split().
    В итоге у тебя должно быть 4 значения: начало интервала, входит ли начало (открытый/закрытый левый край), конец интервала, входит ли конец (открытый/закрытый правый край).
    2. Найти количество чисел в интервале.
    2.1. Округли левый край вверх (math.ceil()) чтобы найти первое целое число, входящее в интервал. Если результат округления равен левому краю И интервал открыт слева, прибавь к числу 1.
    2.2. Округли правый край вниз (math.floor()) чтобы найти последнее целое число. Если результат округления равен правому краю И интервал открыт справа, вычти из числа 1.
    2.3. Зная первое и последнее целое число, входящее в интервал, нужно вычесть первое из последнего и прибавить 1. Т.е. если первое число 2 а последнее 4, то в интервале 4 - 2 + 1 = 3 числа (2, 3, 4).
    Вот и всё. На питон переведёшь самостоятельно.
    Ответ написан
    1 комментарий
  • Как навсегда изменить цвет кнопки при нажатии в Python?

    Vindicar
    @Vindicar
    RTFM!
    Свяжи обработчик событий с кнопкой.
    Заведи глобальную переменную, которая считает, сколько раз была нажата кнопка.
    В обработчике событий читай эту переменную, увеличь её на 1, в зависимости от значения вызывай self.pushButton.setStyleSheet() с разными стилями.
    Ответ написан
    1 комментарий
  • Как правильно использовать run_in_executor?

    Vindicar
    @Vindicar
    RTFM!
    Ну для начала посмотри пакет arsenic, это селениум с асинхронной обёрткой. Можно будет переписать твой парсер на асинхронный подход, и не париться по поводу блокировки бота.
    Ответ написан
    Комментировать
  • Как работает перенаправление вывода скрипта python?

    Vindicar
    @Vindicar
    RTFM!
    Скорее всего, проблема в работе с одним файлом через два дескриптора (один - stdout твоего скрипта, второй - stdout вызываемого). Попробуй принудительно сбрасывать данные в файл:
    print('Пытаемся запустить файл 1:', flush=True)
    Ответ написан
    1 комментарий