Задать вопрос
  • Как игровые движки понимают инородные языки?

    Vindicar
    @Vindicar
    RTFM!
    1. Встраивают интерпретатор нужного языка, при необходимости урезают стандартную библиотеку (чтобы не давать коду плагинов лишних возможностей) и подсовывают туда средства общения с хост-программой.
    2. Если нет нужды изолировать плагин от остальной программы, то полагаю что да, накладные расходы на поддержку плагинов уменьшатся в случае, когда плагин написан на том же языке, что и программа. В противном случае организация "песочницы" может занять столько же усилий, сколько встраивание интерпретатора.
    3. Лучше, если язык плагина является или интерпретируемым (как Lua или JS), или компилируется в байткод (как Python/Java/C#). Также желательно, чтобы язык плагина имел средства интроспекции.
    Ответ написан
    Комментировать
  • Как исправить ошибку при использование 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!
    Зависит от того, какое API предлагает твой источник данных о курсе.
    Если он работает просто в режиме "запрос-ответ", то единственный вариант - периодически его опрашивать и смотреть, насколько изменился курс. По какому алгоритму определять, значимое ли изменение, решай сам, так как постоянные мелкие колебания наверняка будут.
    Если же он позволяет так или иначе получать оповещение об изменении курса, можешь попробовать задействовать этот канал. Тут ключевая задача - добиться выполнения питон-кода в ответ на оповещение от сервиса.

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

    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, и это тот ещё гемморой.
    Ответ написан
    Комментировать
  • Как в хендлер инлайн кнопки добавить значение, которое введёт пользователь?

    Vindicar
    @Vindicar
    RTFM!
    Не уверен, что у тебя за либа, но читай про state machine. Эта фишка есть во многих библиотеках для создания ботов.
    Ответ написан
  • Реализация многопоточности в vk bot?

    Vindicar
    @Vindicar
    RTFM!
    Ну для начала, что должен делать этот новый поток?
    Оформи его действия отдельной функцией, и её и задавай.
    Другой вопрос, ты уверен что тебе нужны потоки для этого? И уверен ли ты, что с vk-api можно работать из нескольких потоков?
    Ответ написан
  • Почему функция возвращает None?

    Vindicar
    @Vindicar
    RTFM!
    Ты в последней строке просто вызываешь sum(), но не возвращаешь значение.
    А функция, которая не возвращает значение явно, возвращает None.
    Ответ написан
    4 комментария
  • Как сделать так, что бы при нажатии на Button активировался CheckButton?

    Vindicar
    @Vindicar
    RTFM!
    Назначь but_5 обработчик клика, который сделает but_4.config(state='normal')
    И приучайся давать осмысленные имена переменным.
    Ответ написан
  • Как сохранять данные о поле в классе?

    Vindicar
    @Vindicar
    RTFM!
    Это у тебя просто класс с полем класса? Или это датакласс?
    Потому что у датаклассов можно прикрутить метаданные к полям, и потом извлечь их.

    Но вообще твоя задача достаточно просто решается "в лоб".
    class X:
        meta = {}
        a: int
        meta['a'] = {'foo': 'bar'}
    
    print(X.meta['a'])


    Да, можно замутить более хитрый синтаксис, вроде:
    class metadata(dict):
        pass
    
    class X(Metaclass):
        a: int = metadata(foo='bar')

    А потом описать класс Metaclass так, чтобы он находил поля с метаданными, и складывал их описания в одну структуру данных. По сути, dataclasses.field() примерно так и работает. Но честно, овчинка выделки не стоит. Слишком много мороки, а результат не сильно короче простого словаря.
    Ответ написан
    Комментировать
  • Почему у двух разных функций одинаковые ссылки?

    Vindicar
    @Vindicar
    RTFM!
    Распарси скобки в выводе корректно, и загадка исчезнет.
    <\bound method Aliases.new_alias of 
        <\aliases.py.Aliases object at 0x7fcf55c104c0>
    >

    Два разных метода одного объекта (с одним адресом).

    И да, имей ввиду, что если ты берешь адрес метода на экземпляре объекта - ты получаешь не адрес функции в классе, а адрес специального объекта-обёртки bound method, который эту функцию привязывает к конкретному экземпляру класса. Иными словами:
    import inspect
    
    class A:
        def test(self, x):
            print(x)
    
    a = A()
    print(A.test)  # <function A.test at 0x0000029692C0FB50>
    print(a.test)  # <bound method A.test of <__main__.A object at 0x0000029692BF3040>>
    print(inspect.signature(A.test))  # <Signature (self, x)>
    print(inspect.signature(a.test))  # <Signature (x)> так как значение self зафиксировано - это a
    # причём обёртка создаётся каждый раз новая, это НЕ один и тот же объект
    print(a.test is a.test)  # False
    # но две обёртки одного метода равны.
    print(a.test == a.test)  # True
    # а метод класса всегда один и тот же
    print(A.test is A.test)  # True
    print(A.test == A.test)  # True
    Ответ написан
    Комментировать
  • Как исправить TypeError: object of type 'Entry' has no len()?

    Vindicar
    @Vindicar
    RTFM!
    Достаточно включить голову. У тебя написано
    x = phonenumbers.parse(self.ent_1, 'None')
    В то же время ниже:
    self.ent_1 = Entry(self,width=36)
    Я очень сомневаюсь, что метод parse() принимает первым параметром поле ввода. Скорее, ему нужна строка, т.е. содержимое поля ввода. Как извлечь содержимое поля ввода, можно нагуглить. Подсказка: у поля ввода есть метод get().

    Вообще в коде много странного. Например,
    carrier_2 = print(carrier_1)
    carrier_2 всегда будет None, так как print() выводит текст в консоль и возвращает None.
    Что ты тут пытался сделать?
    Ответ написан
    Комментировать
  • Почему бот дискорд не включается через heroku?

    Vindicar
    @Vindicar
    RTFM!
    А зачем ты импортируешь turtle? heroku не поддерживает графический интерфейс.
    2022-08-10T07:55:34.087638+00:00 app[worker.1]: File "/app/core/core.py", line 4, in
    2022-08-10T07:55:34.087730+00:00 app[worker.1]: from turtle import title
    Ответ написан
    Комментировать