Ответы пользователя по тегу Python
  • Как сплитовать с aiohttp?

    Vindicar
    @Vindicar
    RTFM!
    1. Прочитать ответ из объекта ClientResponse, а не пытаться использовать его как есть.
    2. Для разбора URL на кусочки есть стандартный модуль urllib.parse
    Ответ написан
    Комментировать
  • Нужно спарсить номера телефонов, но они появляются полсе нажатии на кнопку, как их спарсить?

    Vindicar
    @Vindicar
    RTFM!
    а) разобраться, как сайт получает номер телефона, и повторить. Если номер подгружается отдельным запросом, выяснить каким, попробовать сделать запрос самому. Если номер спрятан в теле страницы, выяснить где, как он зашифрован, извлечь. расшифровать. Муторно, но требует меньше ресурсов.
    б) вместо requests использовать безголовый браузер (selenium), имитировать клик на кнопку, пусть сайт сам всё за нас сделает. Легче, но такие вещи прожорливы по памяти и CPU.
    Ответ написан
    1 комментарий
  • Как получить значение из словаря, не зная имени ключа?

    Vindicar
    @Vindicar
    RTFM!
    1. Сформулируй, по какому критерию определять нужное значение
    2. Перебирай значения в словаре, пока не найдешь соответствующее критерию
    Ответ написан
  • Как упростить мой код?

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

    Vindicar
    @Vindicar
    RTFM!
    Я же тебе уже говорил: если нет ответа на сообщение, то message.reply_to_message будет иметь значение None, и взять у него атрибут from_user не получится (о чём и говорит ошибка).
    Проверяй, что message.reply_to_message не None, если это не так, то думай - или подставляй какое-то другое значение, или просто сообщай об ошибке.
    Ответ написан
  • Как вставить видео в картинку?

    Vindicar
    @Vindicar
    RTFM!
    Ну для начала уточни, что ты хочешь получить в результате. Видео с рамкой? А тебе точно для этого нужна своя программа? Утилита ffmpeg может с этим справиться, хотя и муторно будет.
    Если очень хочешь сам, то пакет opencv-python в помощь, смотри классы cv2.VideoCapture() и cv2.VideoWriter(), ну и базовые операции преобразования изображения заодно.
    Потом может потребоваться перекодировать полученное видео тем же ffmpeg'ом.
    Ответ написан
  • Как создать сообщение об ошибке в написании команды?

    Vindicar
    @Vindicar
    RTFM!
    Ну для начала, неплохо бы писать в вопросе сообщение об ошибке.
    Я, конечно, догадываюсь, что дело в обращении к message.reply_to_message.username, и догадываюсь, что message.reply_to_message будет иметь значение None, если сообщение не является ответом... но я могу и ошибаться.

    А если я прав, то проверяй, является ли обрабатываемое сообщение ответом, а потом уже пытайся читать сведения об "отвеченном" сообщении.
    Ответ написан
    Комментировать
  • Как преобразовать значение при использовании dataclass?

    Vindicar
    @Vindicar
    RTFM!
    Я в таких случаях создаю фабричный метод.
    @dataclass
    class Person:
        first_name: str
        last_name: str
        bdate: date
    
        @classmethod
        def make(cls, first_name: str, last_name: str, bdate: str) -> 'Person':
            _bdate = datetime.strptime(bdate, '%Y%m%d').date()
            return cls(first_name=first_name, last_name=last_name, bdate=_bdate)
    
    data = {
        'first_name': 'Adam', 
        'last_name': 'Smith', 
        'bdate': '20220617'
    }
    person = Person.make(**data)

    Просто, коротко, позволяет реализовать любую логику приведения типов и вычисления значений по умолчанию, использует базовые механизмы Питона, при необходимости можно проигнорировать и использовать обычный конструктор (который мы не ломаем).

    Но вообще это неправильное распределение обязанностей. Обязанность датакласса - хранить данные, а не менять их представление. За смену представления пусть отвечает тот код, который получает значение строки.
    Ответ написан
    Комментировать
  • Ошибка - name 'self' is not defined. Как исправить?

    Vindicar
    @Vindicar
    RTFM!
    Декоратор отрабатывает при создании собственно класса. На этот момент никаких экземпляров ещё нет.
    self имеет смысл только в контексте тела метода класса, но не "снаружи" методов.

    Так что стоит задуматься, а что именно ты пытаешься сделать. Есть ли смысл в твоём классе-обёртке?

    А если прямо очень надо, можно вспомнить, как работает декоратор, и что его можно вызывать вручную, например, в конструкторе класса.
    @some_decorator_with_params(params)
    def some_func(...):
        ...
    # это всего лишь синтаксический сахар для
    def some_func(...):
        ...
    
    decorator = some_decorator_with_params(params)
    some_func = decorator(some_func)  # вызываем декоратор вручную
    Ответ написан
    Комментировать
  • Почему Telegram бот не хочет отправлять сообщение в котором содержатся кнопки?

    Vindicar
    @Vindicar
    RTFM!
    Дай угадаю, реагирует на /start, и всё.
    Сравни с официальным примером и подумай.
    Подумал?

    - get_mood() не отмечено декоратором @bot.message_handler(), бот про эту функцию ничего не знает. Он знает только про welcome().
    - если не заметил, клавиатура должна отправляться вместе с сообщением, параметром reply_markup. Ты же отправляешь сообщение, потом создаёшь клавиатуру, и далее ничего с ней не делаешь.
    Ответ написан
    Комментировать
  • Ошибка Disnake.py, кто поможет?

    Vindicar
    @Vindicar
    RTFM!
    Ну тебе же английским по белому написали: у объекта класса ApplicationCommandInteraction нет атрибута message. Если залезть в доки, его и впрямь нет. А ты зачем-то дергаешь inter.message.author. Если тебе нужен отправитель команды, то у объекта inter есть такое поле author. Почитай по ссылке.
    Ответ написан
    4 комментария
  • Почему regex работает некорректно?

    Vindicar
    @Vindicar
    RTFM!
    Упрощённый пример: что сматчит "\d+" в строке "123456"? Очевидно, всё - потому что умолчанию квантификаторы + и * жадные, т.е. пытаются сматчить как можно больше. У тебя .* - т.е. "матчи всё подряд, сколько получится", а ограничивается только тем, что "дальше должна идти запятая и пробел". Обрати внимание на ещё одну запятую с пробелом в конце твоей строки data.
    Что делать?
    а) сделать квантификатор не жадным: type=(.*?), Тогда он будет пытаться сматчить как можно меньше.
    б) уточнить, какие именно символы могут захватываться группой type=([a-zA-Z0-9_]+),
    Ответ написан
    Комментировать
  • Как исправить ошибку при использование requests python3?

    Vindicar
    @Vindicar
    RTFM!
    requests не умеет "догадываться" об используемом протоколе, это не браузер, который тупо подставлят https:// где надо и где не надо.
    Тебе придётся указывать протокол (либо https:// либо http://, зависит от ресурса) самому в начале запрашиваемой ссылки.
    Ответ написан
    Комментировать
  • Как создать окно с кнопкой Старт Стоп для данного кода?

    Vindicar
    @Vindicar
    RTFM!
    # if the 'q' key is pressed, stop the loop
    if key == ord("q"):
        break

    А зачем останавливать отладку, когда у тебя уже в коде есть выход по горячей клавише? Или код не твой, ты просто разместил объяву?
    А вообще GUI-средства cv2 нужны сугубо для отладки и для экспериментов, они мало подходят для написания сложного приложения. Так что если хочешь кнопки и поля ввода, придётся дружить cv2 с каким-то GUI-фреймворком.
    Ответ написан
    Комментировать
  • Как связать WEB UI с Python?

    Vindicar
    @Vindicar
    RTFM!
    Пусть Flask-приложение стартует первым и запускает твой worker-скрипт в отдельном процессе. Так они друг другу мешать не будут, и если твой worker вылетит, Flask выживет и сможет сообщить о случившемся (ну и перезапустить worker, если надо будет).
    Вопрос тут в выборе способа обмена данными между скриптом и Flask, а также между Flask и браузером.

    1. Worker -> Flask:
    - запуск worker через multiprocessing, обмен данными через очередь (multiprocessing.Queue).
    Плюс: возможен обмен простыми структурами данных, типа списков и кортежей.
    Минус: требует переделки скрипта-worker, чтобы вместо print() он отправлял данные в Queue, да и в целом его надо будет импортировать в Flask-приложение. Что-то кроме питона той же версии так не запустишь.
    - запуск worker через subprocess, обмен данными через перехват stdout.
    Плюс: worker остаётся без изменений, и может быть запущен отдельно. Строго говоря, любая консольная программа, не требующая ввода, может быть так запущена.
    Минус: обмен данными только как последовательность строк. Что-то другое потребует сериализации на стороне воркера, и десериализации на стороне Flask.

    2. Flask -> browser:
    - Самый простой и дубовый способ - long-running request.
    Твой обработчик запроса на Flask запускает воркера, но не закрывает соединение, а потихоньку читает поступающие от воркера данные и отдаёт клиенту. Проблема в том, что если клиент отрубился, восстановить соединение будет нельзя.
    - Чуточку более сложный - polling. Один обработчик запроса на Flask запускает воркера и всё. Другой обработчик пытается прочитать накопившиеся у воркера данные, и отдаёт их клиенту. Тогда на клиенте должен крутиться JS-скрипт, который будет периодически дергать второй обработчик. Проблема в том, что если данные от воркера долго не считываются (клиент отключился), очередь/pipe для связи между процессами переполнится, и воркер "подвиснет" на операции отдачи данных Flask. Также этот подход не будет работать с двумя и более клиентами.
    - Ещё более сложный, но надёжный - buffered polling. Данные от worker помещаются в какое-то хранилище (грубо говоря, в переменную). Хранилище может хранить как полную историю вывода, так и только последний полученный блок данных - смотря что тебе интересно. Тогда Flask-приложение должно отдельным потоком забирать данные у worker, и помещать их в хранилище. Основной поток будет обслуживать запросы, и отдельный обработчик запроса будет отдавать клиенту текущее состояние хранилища (целиком или последние изменения, смотря сколько хранишь).
    Плюс: такая схема будет работать при любом разумном числе клиентов, в том числе при нуле.
    Минус: доступ к хранилищу нужно аккуратно синхронизировать, например, с помощью threading.Lock().
    Ответ написан
    Комментировать
  • Почему не записываются данные в бд?

    Vindicar
    @Vindicar
    RTFM!
    def user_exists(self, user_id):
        with self.connection:
            ...
    def add_user(self, user_id):
        with self.connection:


    По выходу из блока with соединение закроется. Второй блок with его уже не переоткроет.
    В таких ситуациях блок with использовать не надо.
    Ответ написан
    Комментировать
  • Как дать имя отдельным секторам в изображении?

    Vindicar
    @Vindicar
    RTFM!
    Вообще ответ зависит от конкретной задачи.
    У тебя преобразование каждого кусочка идёт независимо от остальных?
    Если да, то всё сильно упрощается. Опиши функцию вида:
    def process_one_part(part: numpy.ndarray) -> numpy.ndarray:
        ...

    Которая будет обрабатывать один фрагмент изображения.
    А дальше собрать их абсолютно тривиально, точно также, как ты их резал:
    # пустое изображение такого же размера, как исходное, с тремя каналами по 8 бит на канал
    # если на выходе у тебя другое число каналов или тип данных, поправишь
    result = numpy.zeros(image.shape[:2] + (3,), numpy.uint8)
    
    for i in range(img_h // bl_h):
      for j in range(img_w // bl_w):
        cropped = image[i*bl_h:(i+1)* bl_h, j*bl_w:(j+1)*bl_w]
        processed = process_one_part(cropped)
        # нужно, чтобы присваиваемый фрагмент имел такой же размер, как "окно" присваивания
        result[i*bl_h:(i+1)* bl_h, j*bl_w:(j+1)*bl_w] = processed
    # дальше делаешь с result что тебе нужно


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

    Vindicar
    @Vindicar
    RTFM!
    Ну для начала неплохо бы внятно описать, как задаются желаемые элементы.
    Если по индексам, то да, твоё решение через __getitem__() вполне работоспособно.
    import typing as t
    lst = ['a', 'b', 'c', 'd', 'e']  #  не называй переменную list
    
    def split(lst: t.List[t.Any], indices: t.Iterable[int]) -> t.Tuple[t.List[t.Any], t.List[t.Any]]:
        selected = list(map(lst.__getitem__, indices))
        remainder = list(lst)
        # удаляем с конца, чтобы еще не обработанные индексы не поехали
        # вот только с отрицательными индексами это уже не прокатит
        # их придётся самомму пересчитывать в положительные
        for i in sorted(indices, reverse=True):
            del remainder[i]
        return selected, remainder
    
    print(split(lst, [0, 3]))  # (['a', 'd'], ['b', 'c', 'e'])
    Ответ написан
    1 комментарий
  • Как в легенде диаграммы сделать один из элементов в конце списка?

    Vindicar
    @Vindicar
    RTFM!
    Сортируй без "Другие", а его добавляй уже после сортировки.
    Ответ написан
    Комментировать
  • Как вызвать файловый диалог Windows без сторонних библиотек (Python)?

    Vindicar
    @Vindicar
    RTFM!
    comdlg32.dll в помощь, в частности GetOpenFileNameA().
    Более новые диалоги используют Component Object Model для работы. Сразу скажу, мне доводилось общаться с COM-интерфейсами на чистом ctypes, и это тот ещё гемморой.
    Ответ написан
    Комментировать