Задать вопрос
Ответы пользователя по тегу Python
  • Когда требуется использовать await при вызове async функции?

    Vindicar
    @Vindicar
    RTFM!
    Следует различать вызов асинхронной функции и её выполнение.
    В твоём случае, вызов work(p) завершится немедленно (без входа в тело функции), и вернёт объект Future.
    Этот объект описывает выполняемую асинхронную операцию (ввод-вывод, выполнение функции и т.п.).
    Затем следует запланировать выполнение этого объекта в рамках цикла реактора (loop в т ерминах asyncio).
    Для этого можно использовать два способа. Если ты находишься в синхронном коде, ты должен использовать loop.create_task() (или более старую функцию, loop.ensure_future()).
    Если ты находишься в асинхронном коде, то твоя текущая функция уже завёрнута в свой собственный Future, и уже выполняется в рамках цикла реактора. Тогда ты можешь использовать await для того, чтобы "уступить место" вызываемой функции - запланировать её выполнение в рамках того же цикла, что и вызывающая функция, а вызывающую функцию приостановить до завершения выполнения вызываемой. Либо, если тебе не требуется дожидаться результата выполнения вызываемой функции, можешь также использовать первый способ.

    Таким образом, когда ты "вызываешь асинхронную функцию через await", ты на самом деле получаешь future-объект и тут же планируешь его выполнение.
    Т.е.
    X = await foo()
    будет тем же самым что
    future_X = foo()
    #future_X можно хранить, но если он будет удалён без выполнения - это даст ошибку never awaited
    X = await future_X
    Ответ написан
    Комментировать
  • Как мне сообщить пользователю в телеграмм боте, что он должен нажать на кнопки?

    Vindicar
    @Vindicar
    RTFM!
    > if message.text == 'Технология(Мальчики)':
    Имел ввиду elif? У тебя вообще довольно много elif пропущено.

    Вообще я бы посоветовал использовать словарь.
    #код неполный! вставишь эти фрагменты в свой самостоятельно
    #все задания описаны тут
    tasks = {
      'Математика': 'Параграф 4 учить РТ 3',
      #ну и так далее.
    }
    #делаем кнопки
    buttons = [types.KeyboardButton(name) for name in tasks] #по кнопке на каждое задание
    markup = types.ReplyKeyboardMarkup(resize_keyboard=True)
    markup.add(*buttons) #добавить все элементы списка buttons, как если бы мы написали их по одному
    
    #Проверка полученной кнопки
    if message.chat.type == 'private':
        task = tasks.get(message.text, None) #ищем текст, соответствующий кнопке
        if task is None: #не нашли
            bot.send_message(message.chat.id, 'Пожалуйста, нажми на кнопки')
        else:
            bot.send_message(message.chat.id, task)

    И никакой лестницы if-elif
    Ответ написан
    Комментировать
  • Можете объяснить как это работает?

    Vindicar
    @Vindicar
    RTFM!
    Жесть. Развернём её снаружи внутрь:
    value_mid = sum(
        value:=value[
            :[
                i for i in range(len(value)) if value[i] < 0
            ][0]
        ]
     ) /len(value)


    Снаружи сумма какого-то ряда чисел (не введённого) деленная на количество.
    Далее идёт присваивание внутри выражения (одна из новых фишек питона, по сути value переопределяется.
    Как следствие, len(value) уже будет содержать количество элементов в новом value, а не в оригинальном.
    Далее идёт срез value[:X], то есть от начала и до указанног элемента НЕ включительно.
    X это [i for i in range(len(value)) if value[i] < 0][0], то есть нулевой элемент списка, заданного выражением
    [i for i in range(len(value)) if value[i] < 0]. Это выражение будет содержать индексы всех отрицательных элементов value, соответственно X будет содержать индекс первого отрицательного элемента value.
    Тогда сумма будет считаться от начала списка и до первого отрицательного элемента (не включая), и количество тоже будет считаться также.
    Вывод: выражение считает среднее значение элементов списка от начала и до первого отрицательного элемента, и делает это через чрезвычайно хитрозакрученную задницу.
    Ответ написан
    1 комментарий
  • Какую библиотеку использовать для выполнения большого количества задач в определенное время Python?

    Vindicar
    @Vindicar
    RTFM!
    Schedule дату не учитывает. Но прямо говоря, реализовать самостоятельно не слишком сложно.
    from typing import Dict, List, Tuple, Callable
    import datetime
    import time
    
    def time_matches_mask(now: datetime.datetime, mask: Dict[str, float], delta: datetime.timedelta) -> bool:
        'Проверяем, совпало ли текущее время с заданной маской с указанной точностью'
        target = now.replace(**mask)
        return abs(now - target) < delta
    
    jobs: List[Tuple[Dict, Callable, Tuple]] = [] #Список элементов: маска, функция, аргументы
    
    def call_pending(jobs, now: datetime.datetime, delta: datetime.timedelta):
        for mask, func, args in jobs:
            if time_matches_mask(now, mask, delta):
                func(*args)
    
    jobs.append( ({'seconds':30}, print, ('Hello world!',)) ) #когда число секунд = 30, вызвать print('Hello world!')
    
    delta = datetime.timedelta(seconds=1) #с какой точностью измерять время?
    while True:
        time.sleep(1)
        call_pending(jobs, datetime.datetime.now(), delta)


    Правда, есть и тонкости. Стоит избегать вызовов 2 раза подряд из-за большой delta, можно заменить секундный цикл на ожидание до ближайшей задачи (с прерыванием, если список задач изменился). Ну и так далее.
    Ответ написан
    Комментировать
  • Почему код бота не работает на сервере?

    Vindicar
    @Vindicar
    RTFM!
    > ImageFont.truetype('arial.ttf', size=20)
    А файл со шрифтом присутствует и доступен боту?
    > f'{path}\\user_card.png'
    os.path.join() и pathlib для кого придумали? Под линуксом разделитель каталогов не \ а /.
    Ответ написан
    5 комментариев
  • Как исправить Atribute Error?

    Vindicar
    @Vindicar
    RTFM!
    Никак. 1 - это экземпляр класса int, который не поддерживает context manager protocol, т.е. не может использоваться с оператором with.
    С этим оператором могут использоваться только классы, описывающие магические методы __enter__() и __exit__().
    Ответ написан
    Комментировать
  • Как загрузить на сервер python скрипт через консоль?

    Vindicar
    @Vindicar
    RTFM!
    Если скрипт небольшой, то можно скопировать его локально, запустить в SSH-сессии простой редактор типа nano, и вставить туда. Под виндой Putty это умеет.
    Другой вариант - выложить скрипт в сеть, и скачать по прямой ссылке через wget.
    Третий вариант, пожалуй, предпочтительный - использовать scp, или вариант этой утилиты из пакета Putty (тыц)

    В любом случае вопрос не имеет отношения к Python.
    Ответ написан
    1 комментарий
  • Почему не работает ИЛИ в re python?

    Vindicar
    @Vindicar
    RTFM!
    Ты ищешь следующее:
    WHERE, за которым следует 0 или более точек, пробельных символов (в т.ч. табуляций) или табуляций, за которыми следует либо GROUP BY, либо ;

    Что именно ты пытаешься извлечь из строки?
    Ответ написан
    2 комментария
  • Как я могу запустить python скрипт на vps?

    Vindicar
    @Vindicar
    RTFM!
    0. Получить SSH-доступ и подключиться.
    1. Поставить нужную версию питона, если она не установлена. Если она доступна в репозитории, то использовать yum или apt-get, в зависимости от того какой дистрибутив linux установлен на вашей VPS.
    2. Используя эту версию питона, запустить pip (python3 m -pip ......... ) чтобы поставить требуемые пакеты.
    3. Запустить скрипт, используя эту версию питона (возможно придётся указать полный путь до исполняемого файла python).
    4. Если нужно, чтобы скрипт запускался при рестарте VPS и работал в фоне, создать по образцу init.d скрипт или systemd модуль (в зависимости от дистрибутива), поместив в него команду запуска.
    Ответ написан
    Комментировать
  • Как заменить текст в виджете?

    Vindicar
    @Vindicar
    RTFM!
    Нужно сохранять где-то ссылку на объект кнопки, разуемеется.
    Ответ написан
    Комментировать
  • Как заменить client в когах?

    Vindicar
    @Vindicar
    RTFM!
    Ты можешь прописать id тип не int, а discord.Member, если не путаю. Тогда и fetch_user() не понадобится.

    P.S.: Вот только команда unban довольно бесполезная, через интерфейс дискорда это сделать быстрее. =p
    Ответ написан
  • Как найти ближайшие точки на координатной плоскости?

    Vindicar
    @Vindicar
    RTFM!
    Координаты строго целочисленные?
    Тогда обходи точки с помощью алгоритма floodfill, с центром в исходной точке.
    Например, для небольшого участка порядок будет таким:
    5 4 3 4 5
    4 2 1 2 4
    3 1 X 1 3
    4 2 1 2 4
    5 4 3 4 5

    Цифра - на какой итерации проверяются эти позиции.
    Т.е. сначала проверяешь соседние с исходной, потом соседние с ними, потом соседние с теми, и так далее.
    Если в позиции есть точка, добавляешь её в список найденных. Когда в списке найденных набралось 3 точки, останавливаешься.
    Ответ написан
    3 комментария
  • Как сделать подключение python программы к серверу?

    Vindicar
    @Vindicar
    RTFM!
    Ответ написан
    Комментировать
  • Библиотека для чертежей?

    Vindicar
    @Vindicar
    RTFM!
    Пакетов для рисования хватает. Pillow и opencv для произвольного рисования, matplotlib для графиков, большинство GUI-фреймворков имеют элемент canvas для произвольного рисования. Даже черепашка (turtle), и то есть.

    А вот для черчения... Тут много специфической мороки, так что невольно напрашивается вопрос: какую задачу решаете? Может, лучше взять тот же Компас-3D, и заскриптовать его?
    Ответ написан
    5 комментариев
  • Как сделать неопределённое наследование в python?

    Vindicar
    @Vindicar
    RTFM!
    Вообще сама необходимость в таком коде уже признак серьёзных проблем.
    Но если очень надо... В питоне классы - это объекты первой категории. С ними можно делать всё то же, что и с другими объектами, например, возвращать их из функций. Так что незачем возиться с class_name.
    Ответ написан
    3 комментария
  • Как нарисовать фигуру в pyhton с помощью TKinter?

    Vindicar
    @Vindicar
    RTFM!
    Используй canvas, метод create_polygon() для внешней границы, и creat_circle() для внутреннего круга.
    Надеюсь, формула для расчёта координат границы у тебя есть.
    Ответ написан
    Комментировать
  • Как написать бота в ВК для редактирования фото?

    Vindicar
    @Vindicar
    RTFM!
    Как, как - взять и написать!
    Что за библиотеку используешь для работы с чатами ВК? Открываешь её документацию, ищешь обработку сообщений, учишься извлекать прикреплённые изображения. Если не получится извлечь как файл, то хотя бы как URL.
    Если фото - URL, то далее в зависимости от того, какую ВК-библиотеку используешь. Если бот синхронный - скачивай картинку через requests, если асинхронный - через aiohttp. Так или иначе у тебя будет содержимое файла картинки, его и скармливаешь Pillow.
    В конце опять лезешь в документацию по либе ВК, смотришь как прикрепить файл к сообщению. Используешь это для того, чтобы отдать пользователю обработанную фотку.

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

    Vindicar
    @Vindicar
    RTFM!
    У тебя два вечных цикла - один это bot.polling(), другой содержит schedule.run_pending(), и они обязательно будут конфликтовать.
    Я не вполне понял почему твой бот вообще работает - он не должен бы, хотя бы потому что reminder() нигде не вызывается, и ничем не декорируется. Разве что ты чего-то не показываешь.

    Есть два варианта их подружить по-человечески.
    1. засунуть один из циклов (лучше schedule) в отдельный поток
    2. использовать асинхронную библиотеку вроде pyrogram, и заменить time.sleep() на await asyncio.sleep().
    Ответ написан
    2 комментария
  • Как использовать multiprocessing в tkinter?

    Vindicar
    @Vindicar
    RTFM!
    Исходи из того, что между процессами лучше передавать только примитивные типы данных и простые коллекции (списки, кортежи, словари). Так что не надо передавать объекты Tkinter как есть, извлеки из них требуемые данные и передавай их.
    EDIT:
    Идеальный сценарий - использование пары multiprocessing.Queue.
    Код дочернего процесса слушает одну очередь, и обрабатывает полученные там задания, а потом пишет в другую ответы.
    Код материнского процесса занимается работой с GUI, складывает задания в первую очередь, и время от времени мониторит вторую очередь на предмет новых ответов. Используй root.after() для мониторинга.
    Ответ написан