Ответы пользователя по тегу Python
  • Как вызвать файловый диалог Windows без сторонних библиотек (Python)?

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

    Vindicar
    @Vindicar
    RTFM!
    Не уверен, что у тебя за либа, но читай про state machine. Эта фишка есть во многих библиотеках для создания ботов.
    Ответ написан
  • Почему функция возвращает 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
    Ответ написан
    Комментировать
  • Почему бот дискорд не включается через 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
    Ответ написан
    Комментировать
  • Как написать исправить этот код?

    Vindicar
    @Vindicar
    RTFM!
    Ну во-первых, обычно не имеет смысл объявлять функции из одного оператора, особенно если они вызываются лишь однажды. Это только усложняет код.
    Во-вторых, строка rub = 'рубль' or 'рублей' or 'рубля' не имеет ни смысла, ни эффекта. Просто убери её.
    В-третьих, чтобы определить последнюю цифру (две) достаточно операции деления с остатком на 10 (100). Делить число нацело не требуется.
    В-четвёртых, составь сначала алгоритм словами:
    если две последние цифры 11, 12, 13, 14 или последняя цифра 0, 5, 6, 7, 8, 9 - "рублей"
    иначе если последняя цифра 2, 3, 4 - "рубля",
    иначе - "рубль"

    Можно проверить вхождение значения в список так:
    if last_digit in (0, 5, 6, 7, 8, 9):
        ...

    Это удобнее, чем цепочка or.

    Дальше на питон перепишешь сам.
    Ответ написан
    5 комментариев
  • Почему не копируется список внутри класса?

    Vindicar
    @Vindicar
    RTFM!
    Запомни одну простую вещь: переменная в питоне - это просто ссылка, ярлык!
    Покажу на примере:
    a = [1, 2, 3]  # а содержит ссылку на некий список
    b = a  # b содержит ссылку на тот же список!
    print(b is a)  # True. b - это тот же объект, что и a
    a.append(4)  # Ссылка а не меняется, меняется объект по этой ссылке!
    print(a)  # [1, 2, 3, 4]
    print(b)  # [1, 2, 3, 4] так как b ссылается на то же, что и a
    a = [1, 2]  # теперь a хранит ссылку на другой объект-список!
    print(b is a)  # False. Даже если бы содержимое списков совпало, это два разных объекта.
    print(a)  # [1, 2]
    print(b)  # [1, 2, 3, 4] так как b хранит ссылку на старый список
    a.append(5)
    print(a)  # [1, 2, 5] изменили объект, на который ссылается a
    print(b)  # [1, 2, 3, 4] b ссылается на другой объект, он остался не изменён.


    Соответственно, у твоей проблемы есть четыре разных решения.
    1. Делай копию тогда, когда она тебе понадобится (т.е. тогда, когда в исходном списке уже лежат нужные значения). Не полагайся на то, что две доступные извне переменные всегда будут указывать на один и тот же список.
    2а. Не заменяй список на другой. Если ты хочешь заменить именно содержимое списка, а не заменять один объект-список на другой, можно написать так: a[:] = [1, 2, 3, 4] Для надёжности можешь этот список показать как read-only property вместо обычного поля класса - тогда можно будет модифицировать объект списка (добавлять/удалять элементы), но нельзя будет заменить список на другой.
    2б. Покажи наружу список как read-write property, при записи в property записывай список в обе переменные.
    3. Добавь в класс методы для управления элементами списка, сам список наружу не показывай.
    Ответ написан
    3 комментария
  • Как параллельно обрабатывать API запросы?

    Vindicar
    @Vindicar
    RTFM!
    Я бы сделал несколько по другому.
    Оформил бы отдельно рабочий поток/процесс, и заставил бы их общаться через пару очередей (классический паттерн producer-consumer). Подходящие классы очереди можно найти в multiprocessing (ну или в threading, если ты очень хочешь потоки вместо процессов).

    Основной (корневой) процесс запускает рабочие процессы, потом слушает входящие запросы. Получив запрос, кидает его в очередь. Первый свободный процесс извлекает запрос из очереди, обрабатывает, отправляет ответ на запрос, и снова ждёт появления элемента в очереди. Проблема в том, что при использовании процессов придётся передавать между ними сложный объект Request - я не уверен, что это будет просто. Можешь попробовать потоки, но в питоне потоки не всегда хорошо работают.

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

    Vindicar
    @Vindicar
    RTFM!
    У тебя сначала self.storage.clear_text(), а потом print(self.storage.text). Это вообще какой смысл имеет?
    В итоге у тебя хоть что-то выведется только если звёзды сойдутся, и процесс-поставщик успеет засунуть свой контент в общую переменную в промежутке между этими вызовами.
    Защити общий ресурс мьютексом (Lock), чтобы гонки не было, и поправь порядок операций.

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

    Vindicar
    @Vindicar
    RTFM!
    Настрой свой редактор на отступ четырьмя пробелами и не путайся.
    Я навскидку вижу только это
    with open("citilink4.html") as file:
       src = file.read()

    Перед src явно три пробела.
    Ответ написан
    Комментировать
  • Наработает цикл for в цикле while что делать?

    Vindicar
    @Vindicar
    RTFM!
    Ну положим, в первом коде ты делаешь запрос с Num_bd = 0, а во втором ты начинаешь с Num_bd = 1 и так далее. У тебя в БД точно есть подходящие данные?
    Кроме того, else для for работает не так как ты думаешь. Ветка else отработает, если цикл for не был прерван оператором break.
    Ответ написан
  • Правильно ли я понимаю вызов декоратора?

    Vindicar
    @Vindicar
    RTFM!
    Да, первая запись - синтаксический сахар для второй.
    Ответ написан
    Комментировать
  • Почему список превращается в None при добавлении значения?

    Vindicar
    @Vindicar
    RTFM!
    Метод append() изменяет список "на месте", а не создаёт изменённую копию.
    Чтобы подчеркнуть это, append() возвращает None.
    Ответ написан
    Комментировать
  • Как правильно работать с циклом?

    Vindicar
    @Vindicar
    RTFM!
    Вместо итерации по списку сделай цикл по индексам. Цикл должен быть не for, а while, так как ты будешь менять параметр цикла (текущий индекс в списке) самостоятельно.
    Сначала текущий индекс 0.
    Если введена пустая строка, то индекс +1. Если индекс стал равен длине списка, решай что делать дальше.
    Если введена не пустая строка, то используешь метод index() чтобы найти индекс введённого элемента. Имей ввиду, если такого элемента нет, будет выброшено исключение. Его надо поймать.
    Ответ написан
    5 комментариев
  • Почему выводится ошибка ValueError на строке 10: I/O operation on closed file? Может с отступами что не так?

    Vindicar
    @Vindicar
    RTFM!
    Дай угадаю.
    1. Ты рассчитываешь стандартное отклонение последовательности.
    2. Последовательность заканчивается нулём.
    3. Ты это делаешь в рамках какой-то олимпиады или конкурса, где код выполняется в тестовом окружении (песочнице) с фиксированным вводом.

    Тестовое окружение подаёт на стандартный ввод твоей программы элементы последовательности. Твоя программа поглощает эти элементы вызовами input() в рамках первого цикла while.
    Подав всю последовательность, тестовое окружение, очевидно, закрывает стандартный ввод.
    Но ты СНОВА обращаешься к стандартному вводу (input()) в рамках цикла for! Поскольку ввод уже закрыт, генерируется исключение IOError.

    Что делать?
    Вариант 1. Сохраняй элементы в коллекцию, например в список, и итерируйся по списку для расчёта среднего и дисперсии. Может провалиться, если есть ограничение на потребление памяти при очень длинной последовательности на вводе.
    Вариант 2. Гугли one-pass dispersion calculation (однопроходный расчёт дисперсии). Есть формулы для расчёты среднего и дисперсии, которые позволяют их считать, не храня последовательность целиком, а только читая каждый элемент по мере его поступления.
    Зная дисперсию, найти стандартное отклонение тривиально.
    Ответ написан
    2 комментария
  • Uniqueviolation: duplicate key value violates unique constraint?

    Vindicar
    @Vindicar
    RTFM!
    Криво написан SQL.
    INSERT INTO memcfc (photo , name , discription) VALUES
            (' ? ',' ? ',' ? ');

    Ты передаёшь в качестве значений строки " ? ". Именно строку "пробел вопросительный знак пробел". Это НЕ плейсхолдер для подстановки параметра, подставляемые параметры в этом запросе игнорируются.
    Я так подозреваю, ты имел ввиду
    INSERT INTO memcfc (photo , name , discription) VALUES (?, ?, ?);

    (И да, правильно пишется dEscription)
    Ответ написан
    2 комментария
  • Как распределить цифры в питоне?

    Vindicar
    @Vindicar
    RTFM!
    Obbi-Man, абсолютно учебное задание, делай сам.
    Всё, что тебе нужно, это
    random.randint(), len() и оператор del

    Всё равно непонятно!
    Сделай список нужных чисел, генери случайный индекс (от 0 до длины списка - 1), добавь число по этому индексу в итоговый список, удали число по индексу из исходного списка. Повторяй, пока исходный список не пуст.
    Ответ написан
    Комментировать