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

    Vindicar
    @Vindicar
    RTFM!
    Не работал с джангой, но...
    time = datetime.time(11, 00, 0, tzinfo=timezone(timedelta(hours=0)))

    Это время в UTC.
    А вот что используется при выводе... может, как раз твоё TIME_ZONE = 'Europe/Moscow'?
    Ответ написан
  • Извлечение таблиц со спецификациями из PDF чертежей металлоконструкций - решаемо? Или я встрял?

    Vindicar
    @Vindicar
    RTFM!
    Имхо без комбинации подходов ловить вообще нечего. Найди инструмент (и набор предобработок), который найдёт тебе разметку таблиц, выдерни содержимое отдельных ячеек, и подбирай предобработки+инструмент, который будет распознавать ячейки.
    Ответ написан
    Комментировать
  • Как ловить exceptions в библиотеке которую я не использую напрямую?

    Vindicar
    @Vindicar
    RTFM!
    где я его должен ловить учитывая что саму urllib3 я через import не подключаю

    Ну так подключай её в свой код и лови в своём коде. from urllib3.exceptions import LocationParseError
    Раз requests её уже использует, затраты на import в твоём скрипте будут околонулевые.
    requests поступает вполне логично, не изобретает велосипед (т.е. своё исключение с тем же смыслом), а задействует тип исключения из используемой стандартной библиотеки языка.
    Ответ написан
    Комментировать
  • Какую библиотеку лучше использовать для discord бота на python?

    Vindicar
    @Vindicar
    RTFM!
    discord.py уже давно начал деятельность обратно. На момент написания этого коммента на гитхабе последний коммит 3 месяца назад, issue закрыт считанные дни назад.
    Ответ написан
    Комментировать
  • Почему возникают ошибки несовместимости версий Python и как решить проблему с установкой PySimpleGUI?

    Vindicar
    @Vindicar
    RTFM!
    Разобраться, какие версии библиотек всё-таки нужны. Ты не написал, для каких пакетов возникает ошибка.
    Возможно, стоит смягчить требования - например, не требовать определённую версию пакета, а любую, или ограничится только первой цифрой. Скажем, вместо somepackage==1.2.3 указать somepackage==1.* или вообще somepackage без версии.
    Ответ написан
    Комментировать
  • Можно ли улучшить приложенный AutoEnum (см. код ниже) в python?

    Vindicar
    @Vindicar
    RTFM!
    Очевидно, что декоратор должен находить и заменять объявленные константы сам, так как всё остальное уже отработало.
    Если хочешь полагаться на метакласс, ему можно передавать аргументы при наследовании. ЕМНИП:
    class MyMeta(type):
        def __new__(metacls, name, bases, namespace, **kwargs):
            print(f"__new__(): {name}({kwargs})")
            return super().__new__(metacls, name, bases, namespace)
    
    class MyBase(metaclass=MyMeta):  # __new__(): MyBase({})
        pass
    
    class MyClass(MyBase, foo='bar'):  # __new__(): MyClass({'foo': 'bar'})
        pass

    А вообще я не вижу выигрыша в твоём классе. Статическая типизация, к слову, барахлить не начнёт? Среда разработки будет правильно опознавать TestAutoEnum.FIRST как экземпляр TestAutoEnum?
    Ответ написан
    Комментировать
  • Почему api золотого яблока блокирует все запросы?

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

    Vindicar
    @Vindicar
    RTFM!
    Я верно понимаю, что нужно найти слова не короче заданной длины, которые можно составить из букв данного слова?
    Во-первых, может иметь смысл сразу отбросить слова, содержащие буквы не из данного слова, чтобы в дальнейшем анализировать только сравнительно допустимые слова. Также может иметь смысл использовать для подсчёта количества букв collections.Counter.
    Например, так
    from collections import Counter
    
    main_word = 'АКСИЛИРОВАНИЕ' + '\n'  # основное слово + перенос строки, чтобы не вызывать str.rstrip()
    main_set = frozenset(main_word)  # множество букв слова без учёта повторов
    main_len = len(main_word)
    min_length = 8
    with open('D:\\Program Files\\Text\\слова\\1.txt', 'r') as f:
        candidates = [  # слова-кандидаты, состоящие из тех же букв и подходящие по длине
            (word, Counter(word))  # само слово и его состав по буквам
            for word in f  # для всех слов в файле
            # проверяем длину слова и соответствие набора букв без учёта их количества
            if min_length<=len(word)<=main_len and main_set.issuperset(word)  
        ]
    main_counter = Counter(main_word)  # подсчёт числа букв в основном слове
    results = [  # итоговый результат
        word  # те слова
        for word, counter in candidates  # из числа слов-кандидатов
        if all(counter[key] <= main_counter[key] for key in counter)  # у которых нет превышения ни по одной букве
    ]


    Во-вторых, важна структура файла. Например, если строки в файле расположены по возрастанию длины, мы можем попробовать быстренько пропустить короткие слова в начале файла, обработать то, что идёт после, и остановиться, когда дойдём до слов длиннее заданного.
    В-третьих, если вместо текстового файла использовать, скажем, pickle-файл, и хранить в нём предрассчитанные количества букв для каждого слова, то это потенциально может ускорить процесс.
    Но чтобы проверить скорость работы кода, нужна ссылка на пример файла со словами. И уточни, как обрабатывается буква Ё.
    Ответ написан
    Комментировать
  • Как создать task в __init__ asyncio?

    Vindicar
    @Vindicar
    RTFM!
    Тебе довольно прямо сказано: "AttributeError: loop attribute cannot be accessed in non-async contexts."
    Иными словами, атрибут Bot.loop (ссылку на рабочий цикл asyncio) можно читать, только если ты находишься внутри async def функции, прямо или косвенно.
    Причина простая - asyncio.run() или эквивалентная функция как раз создаёт и запускает рабочий цикл asyncio (обычно называемый event loop или просто loop). Если рабочий цикл ещё не создан, то что должен вернуть атрибут Bot.loop? На этот вопрос просто нет правильного ответа. Поэтому доступ к атрибуту блокируется.

    И насчёт решения тоже подсказано: "Consider using either an asynchronous main function and passing it to asyncio.run or using asynchronous initialisation hooks such as Client.setup_hook". Иными словами, тебе нужно сделать так, чтобы твой код, обращающийся к Bot.loop, выполнялся в асинхронной (async def) функции. Это можно сделать двумя способами.

    Первый: вынести твой код из конструктора (который не может быть асинхронным) в отдельный метод. Например, Bot (и его предок Client) позволяют вызвать асинхронный метод on_ready() при запуске бота. Тут есть много оговорок - в частности, on_ready() может быть вызван неоднократно, если есть проблемы с соединением. Это нужно иметь ввиду.

    Второй: завернуть вызов всего твоего конструктора в асинхронный метод. Упрощённо, вместо
    import discord
    from discord.ext import commands
    
    intents = discord.Intents.default()
    intents.members = True
    intents.message_content = True
    
    bot = commands.Bot(command_prefix='!', intents=intents)
    # ...
    bot.run('token')

    можешь попробовать что-то вроде
    import discord
    from discord.ext import commands
    
    
    async def main():
        # асинхронная функция может быть выполнена ТОЛЬКО внутри рабочего цикла
        # значит, рабочий цикл уже точно существует и выполняется
        intents = discord.Intents.default()
        intents.members = True
        intents.message_content = True
        # конструктор сам по себе не асинхронный, но он выполняется в асинхронном контексте
        bot = commands.Bot(command_prefix='!', intents=intents)  
        # ...
        # мы уже в асинхронной функции, поэтому используем await start() вместо run()
        await bot.start('token')  # main() не завершит работу, пока бот не завершит работу
    
    
    if __name__ == '__main__':
        asyncio.run(main())  # создаём рабочий цикл. он будет работать, пока main() не завершит работу


    Но я соглашусь с Everything_is_bad - сначала разберись, как работает asyncio. Строить сложные конструкции с несколькими долгоживущими корутинами методом проб и ошибок - это слишком муторно.

    Ну и очень большой вопрос от меня: ты, я вижу, мастеришь систему плагинов. Чем тебя не устроили коги?
    Ответ написан
    3 комментария
  • Как исправить ошибку?

    Vindicar
    @Vindicar
    RTFM!
    Объясняю на пальцах:
    UPDATE trial SET trialactive = 0 WHERE trialkey = 'vless:-test'
    - обновить запись, где столбец trialkey равен строке "vless:-test"
    UPDATE trial SET trialactive = 0 WHERE trialkey = vless:-test
    - обновить запись, где столбец trialkey равен столбцу vless:-test, а такого столбца у тебя нет.

    А причина - потому что ты не озаботился как следует посмотреть примеры работы с БД в питоне, и сразу побежал херачить текст запроса с помощью f-строк, хотя каждый первый туториал предупреждает что так делать нельзя, а нужно использовать placeholder'ы.

    Ссылку на https://docs.python.org/3/library/sqlite3.html#sql... тебе выше дали, разобрать её несложно.
    Первый пример кода (который помечен # Never do this -- insecure!) допускает ту же самую ошибку, что и твоё
    cursor.execute(f'UPDATE trial SET trialactive = 0 WHERE trialkey = {results}')
    и другие запросы.
    А второй пример кода показывает, как правильно.
    # This is the qmark style used in a SELECT query:
    params = (1972,)
    cur.execute("SELECT * FROM lang WHERE first_appeared = ?", params)

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

    Vindicar
    @Vindicar
    RTFM!
    Насколько я это понимаю:
    1. Вызов класса транслируется в обращение к метаклассу, т.е. klass.__class__.__call__()
    2. По умолчанию метакласс обращается к klass.__new__(). Если класс не определяет этот метод, он ищется по предкам. Задача __new__() - вернуть экземпляр класса, который был "сконструирован". Это не обязательно новый экземпляр, у нас может быть синглтон или ещё что-то.
    3. Получив экземпляр instance, метакласс обращается к instance.__class__.__init__(), чтобы проинициализировать возвращённый экземпляр. Вроде где-то упоминалось, что если __new__() возвращает экземпляр другого класса, то и __init__() будет вызван от этого другого класса.
    4. После того, как экземпляр был проинициализирован, klass.__class__.__call__() его возвращает программе
    Это подтверждается таким тестовым кодом:
    class MetaTest(type):
        def __call__(self, *args, **kwargs):
            print('MetaTest.__call__() is being called...')
            instance = super().__call__(*args, **kwargs)
            print(f'MetaTest.__call__() returning {instance=}')
            return instance
    
    class Test(metaclass=MetaTest):
        def __new__(cls):
            print('Test.__new__() is being called...')
            instance = super().__new__(cls)
            print(f'Test.__new__() returning {instance=}')
            return instance
        
        def __init__(self):
            print(f'Test.__init__() has been called on instance = {self}')
    
    
    t = Test()

    И вот результат выполнения:
    MetaTest.__call__() is being called...
    Test.__new__() is being called...
    Test.__new__() returning instance=<__main__.Test object at 0x0000028EC8E41700>
    Test.__init__() has been called on instance = <__main__.Test object at 0x0000028EC8E41700>
    MetaTest.__call__() returning instance=<__main__.Test object at 0x0000028EC8E41700>
    Ответ написан
    7 комментариев
  • Как правильно обрабатывать ошибки при чтении файла?

    Vindicar
    @Vindicar
    RTFM!
    Тебе правильно написали про with, а я добавлю в чём проблема:
    # допустим, это наш код
        try:
            file = open("config.json", "r")  # исключение может произойти тут
            config = json.load(file)  # или тут
            print(config)
        except FileNotFoundError:
            print(">>> Файл не найден!")
        except PermissionError:
            print(">>> Доступ запрещен!")
        finally:
            print(">>> Файл закрылся!")
            file.close()

    У тебя две разные ошибки, на которые требуются разные реакции.
    Если исключение произойдёт в open(), то переменная file не будет создана, так как до присваивания дело просто не дойдёт. Если же исключение произойдёт в load(), то переменная file будет существовать, файл бдует открыт, и его нужно будет закрыть. Таким образом, тебе нужно или обработать эти ошибки отдельно, или использовать другие средства (вроде оператора with) для закрытия файла.
    Ответ написан
    Комментировать
  • Pytest. Почему декоратор не записывает в файл логи?

    Vindicar
    @Vindicar
    RTFM!
    with tempfile.NamedTemporaryFile(dir=custom_dir, delete=False, mode="w") as temp_file:

    Немедленно по выходу из with файл закроется, и будет удалён.
    Ответ написан
    2 комментария
  • Как отправить запрос в LM Studio?

    Vindicar
    @Vindicar
    RTFM!
    Примеры использую утилиту curl. В них прописаны:
    1. URL запроса, например, localhost:1234/api/v0/chat/completions
    2. Заголовки, например, Content-Type: application/json
    3. Тело запроса, например,
    {
        "model": "granite-3.0-2b-instruct",
        "messages": [
          { "role": "system", "content": "Always answer in rhymes." },
          { "role": "user", "content": "Introduce yourself." }
        ],
        "temperature": 0.7,
        "max_tokens": -1,
        "stream": false
      }


    Как уже выше написали, читаешь доки на модуль requests (ну или aiohttp, если тебе лучше работать асинхронно), они позволяют всё это делать. Просто нужно выучить, как.
    Ответ написан
    Комментировать
  • Несколько запросов к API с помощью python?

    Vindicar
    @Vindicar
    RTFM!
    Используй цикл for, самое простое решение.
    Ответ написан
    Комментировать
  • Python Flet - как записать код во вкладку?

    Vindicar
    @Vindicar
    RTFM!
    Читаем документацию. Там прописано, что у контрола Tabs есть два события: on_click для щелчка по вкладке, и on_change для перехода между вкладками (потому что вкладки можно переключать не только мышкой).
    Полагаю, что нужно передать в конструктор ft.Tabs() соответствующий параметр с функцией-обработчиком события примерно такого вида:
    def on_tab_changed(e):
        current_tab = t.selected_index  # см. свойство https://flet.dev/docs/controls/tabs#selected_index
        # далее в зависимости от current_tab выполняешь тот или иной код
        # это может выглядеть как-то так:
        if current_tab == 0:
            tab_a_code()
        elif current_tab == 1:
            ...
    
    def tab_a_code():
        ...  # тут что-то делаешь при открытии первой вкладки


    А вот как засунуть целую работающую программу в функцию - это, извини, уже совсем отедльный вопрос...
    Ответ написан
    Комментировать
  • Поможете исправить ошибку в Python коде?

    Vindicar
    @Vindicar
    RTFM!
    Дробные числа во многих языках программирования представляются в формате с плавающей точкой. Как это выглядит - можешь погуглить, а сейчас важно знать, что точность этих чисел ограничена, а многие числа (даже сравнительно "несложные" с нашей точки зрения) вообще точно не представимы. Собственно, вышеприведённый сайт (https://0.30000000000000004.com/) подробно это объясняет.
    Для многих задач эта погрешность настолько мала, что абсолютно незначительна, поэтому числа с плавающей точкой по прежнему используются. Но эта погрешность медленно, но верно накапливается с каждой операцией, и это нужно иметь ввиду. Так, математически эквивалентные операции могут давать разные результаты:
    print(f'{(10 + 20) / 100:.40f}')  # 0.2999999999999999888977697537484345957637
    print(f'{0.1 + 0.2:.40f}')  # 0.3000000000000000444089209850062616169453
    print(30 / 100 == 0.1 + 0.2)  # False - результаты отличаются!

    Решение зависит от того, что, собственно, является проблемой. Если тебе просто нужен красивый вывод, то ты можешь отформатировать число при выводе, например, так:
    # вывести значения переменных rub и kop2 
    # как числа с плавающей точкой (f), 
    # округлив их до 0 знаков после запятой.
    print(f'{rub:.0f} {kop2:.0f}')

    Этот способ хорош тем, что само значение в переменной не округляется, так что дальнейшие расчёты будут идти без округления.
    Альтернативно, ты можешь использовать представление с фиксированной точкой. В твоём случае можно просто вести все расчёты в копейках, а под конец разделять сумму в копейках на рубли и остаток:
    total_sum = 1234  # тыт ты рассчитываешь сумму в копейках, я написал число для простоты
    rub = total_sum // 100  # оператор // выполняет деление нацело, отбрасывая остаток
    kop = total_sum % 100  # оператор % выполняет нахождение остатка от деления
    print(rub, kop)  # и rub и kop - целые числа, поэтому погрешности от плавающей точки нет

    Как я понял, это ты и пытался сделать, просто не осилил нагуглить оператор деления с остатком.

    Третий вариант - развитие второго, только более автоматизированный. Тип данных Decimal как раз и даёт представление числа с фиксированной точкой, хотя работает медленнее. Его часто советуют использовать для финансовых расчётов.
    from decimal import Decimal
    x = Decimal(30)
    print(x, x / 100)  # 30 0.3
    print(Decimal('30') / 100 == Decimal('0.1') + Decimal('0.2'))  # True - результат один и тот же!


    Думаю, в твоём случае лучше подойдёт вариант 2.
    Ответ написан
    2 комментария
  • Можно ли на Python написать простой сайт без фреймворков?

    Vindicar
    @Vindicar
    RTFM!
    То есть, по аналогии с PHP создаём условный index.py, в нём роутинг на несколько url и включаемые файлы.

    Роутинг реализуется фреймворками. Ты или пишешь HTTP-сервер с нуля (ну или сам реализуешь CGI/WSGI), прежде чем добраться до собственно логики сайта, или поручаешь это фреймворку.
    Ответ написан
    Комментировать
  • Почему антивирус ругается на exe Python?

    Vindicar
    @Vindicar
    RTFM!
    Это постоянно так. Используй более старую версию упаковщика, она уже должна быть в белых списках. Но проблемы всё равно могут быть.
    Ответ написан