Задать вопрос
  • Как исправить ошибку?

    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)

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

    Vindicar
    @Vindicar
    RTFM!
    Ответ написан
    Комментировать
  • Как устроен вызов классов в 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) для закрытия файла.
    Ответ написан
    Комментировать
  • Механика боя, код?

    Vindicar
    @Vindicar
    RTFM!
    Готовый код ищи в опенсорс играх. В остальном - только общие принципы.
    Если бы мне пришлось реализовывать боёвку, я бы опирался на две идеи:

    1. Автоматы состояний, в т. ч. ортогональные (т.е. несколько параллельных независимых автоматов). См. паттерн "состояние" из паттернов банды четырёх.
    Например, для скилла у персонажа могут быть такие состояния:
    Idle - скилл не используется
    ChargeUp - персонаж готовит атаку
    Active - персонаж выполняет атаку
    Cooldown - персонаж восстанавливается после атаки
    Для мгновенных атак скилл перейдёт из Active в Cooldown сразу же, для длительных - может какое-то время сидеть в Active. По сути, скиллами можно описать вообще всё, от дефолтных атак до использования предметов.

    2. Подписка на события
    Это полезно для реализации статус-эффектов. Т.е. перс имеет несколько событий: игровой тик, получение урона, нанесение урона, переход навыка в следующее состояние, и т.д. При этом события должны позволять менять происходящее. Скажем, обработчик события "получение урона" должен иметь возможность изменить получаемый урон или отменить его вообще.
    Когда на перса накладывают статус-эффект, объект этого статус-эффекта подписывается на соответствующие события. Например, эффект "горю" подписывается на событие "игровой тик", и генерирует урон персонажу через заданное количество тиков. По снятию статус-эффекта объект должен отписаться от событий.
    Если на событие подписаны несмколько эффектов, их обработчики событий отрабатывают поочерёдно.
    Также нужна система приоритетов, чтобы одни эффекты срабатывали строго до других, а не зависели от порядка их наложения. Иными словами, список активных эффектов должен сортироваться при добавлении новых эффектов.
    Ответ написан
    Комментировать
  • Pytest. Почему декоратор не записывает в файл логи?

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

    Немедленно по выходу из with файл закроется, и будет удалён.
    Ответ написан
    2 комментария
  • Почему у пересланного сообщения нет свойств, которые у него должны быть Aiogram?

    Vindicar
    @Vindicar
    RTFM!
    Доки говорят:
    reply_to_message: Message | None
    Optional. For replies in the same chat and message thread, the original message. Note that the Message object in this field will not contain further reply_to_message fields even if it itself is a reply.

    Может, это и к сведениям о форварде относится.

    Я бы просто заставил бота сохранять в базу ID оригинального сообщения, ID чата, где оно было отправлено, и ID форварда. Тогда впоследствии можно было бы выбрать из базы по ID форварда оригинал, и ответить на него.
    Ответ написан
    6 комментариев
  • Как сделать чтобы VS code видел прочие файлы?

    Vindicar
    @Vindicar
    RTFM!
    Дай угадаю, ты везде используешь относительные пути в файлам?
    Тогда дело в текущем рабочем каталоге. Это школьный курс информатики, если что.
    Вспомнить всё

    Есть два типа путей к файлам - абсолютные (начинаются с буквы диска и идут от корня диска, скажем, C:\Windows\System32\cmd.exe) и относительные (идут не от корня, например, cmd.exe). Для работы с файлом системе в итоге будет нужен абсолютный путь.
    Если же ты используешь относительный путь, этот абсолютный путь рассчитывается исходя из текущего рабочего каталога твоей программы. Т.е. если ты обращаешься к app.py, а твой текущий каталог C:\Users\Chupep32\Desktop, то ты обратишься к C:\Users\Chupep32\Desktop\app.py.
    Рабочий каталог каталог может, но не обязан совпадать с каталогом, где лежит код программы, и может, но не обязан меняться в ходе её выполнения. У каждой запущенной программы свой текущий рабочий каталог, он может, но не обязан совпадать с текущим каталогом какой-либо другой запущенной программы.

    PyCharm перед запуском скрипта выставляет в качестве текущего рабочего каталога папку проекта, поэтому относительные пути работают сразу и без проблем. Но поскольку скрипты можно запускать очень по-разному, то и текущий каталог при запуске может быть разным. Как следствие, полагаться на относительные пути нельзя, как ты только что убедился на горьком опыте.
    Если тебе нужно обратиться к файлу именно рядом с твоим скриптом, построй абсолютный путь к нему сам. Встроенный модуль pathlib в помощь.
    import sys
    from pathlib import Path
    
    SCRIPT_DIR = Path(sys.argv[0]).parent.resolve()  # путь к каталогу твоего скрипта
    SOME_FILE = SCRIPT_DIR / 'image.png'  # путь к файлу в этом каталоге
    with open(SOME_FILE, 'rb') as img:  # с этим путём работаешь как обычно, преобразуешь его в str, если надо
       ...
    Ответ написан
  • Как одновременно вывести изображение с 4 пк (и более) на один монитор?

    Vindicar
    @Vindicar
    RTFM!
    Вывести изображение вполне реально, так видео с камер наблюдения сводят в одну сетку. Поищи video multiplexer. Вот только удалённое управление через него не организуешь.
    Можно, конечно, использовать KVM для отдельного переключения управления, но всё равно будет убого.
    Ответ написан
    5 комментариев
  • Почему не работает бот на aiogram?

    Vindicar
    @Vindicar
    RTFM!
    1. Sanity check №1: как ты указываешь токен? Я надеюсь как TOKEN = "тут-твой-токен", а не TOKEN = getenv("тут-твой-токен").
    Sanity check №2: если щелкнуть по окну виндового терминала, он войдёт в режим выбора текста (в заголовке будет слово "Выбрать"), а нажав Enter, выбранное скопируется в буфер обмена. В этом режиме программа НЕ выполняется, пока не закончишь выбор текста! Проверь, не твой ли это случай.
    2. Отлаживай. Расставь несколько print() в ключевых местах, например, до и после bot = Bot(...), а также в начале обработчиков. Это хотя бы позволит понять, что выполняется, а что нет. Измени строку
    logging.basicConfig(level=logging.INFO, stream=sys.stdout)
    , заменив INFO на DEBUG, выводится ли что-то?
    Ответ написан
  • Как правильно записать список из словарей в JSON файл?

    Vindicar
    @Vindicar
    RTFM!
    JSON и нормальный вид не особенно совместимы. JSON машинночитаем, а нормальный вид нужен человеку.
    Ты, конечно, можешь извратиться, преобразовывать словари в JSON по отдельности, а потом сделать что-то типа
    "[\n" + ",\n".join(jsoned_dicts) + "\n]"
    Но всё равно на таблицу будет не очень похоже. Я бы не заморачивался ни с чем, что нелья решить с помощью параметра indent в json.dump().
    Ответ написан
    Комментировать
  • Как сделать поиск объектов на скриншоте из игры?

    Vindicar
    @Vindicar
    RTFM!
    Т.е. размер искомого объекта известен заранее, поворотов и прочих искажений нет? Положение отпечатков на скриншоте всегда одинаковое? Вытаскиваешь их со скрина срезами (slice), тривиальная задача в opencv.
    А дальше Template matching в помощь, его тут должно хватить. Template matching составляет для изображения карту похожести. Чем больше значение в карте, тем больше окрестность этого пикселя похожа на заданный образец.
    Так что берешь каждый кусок отпечатка, делаешь template matching с самим собой (чтобы понять, какое значение похожести считать идеальным), потом делаешь template matching с отпечатком. Ищешь в карте похожести максимум. Если этот максимум сравним с идеальным (разница в пределах N%, придётся подбирать), значит, такой кусок на отпечатке есть. Если этот максимум значительно меньше, значит, такого куска на отпечатке нет.
    Скриншоты и мышетыканье в окно - это отдельные модули, за ними в гугл. Хотя поначалу можно просто выводить в консоль номера кусков отпечатка, которые нашлись.

    P.S.: код не проси. Приходи со своим (а не чатгптшным!), тогда будет что обсуждать.
    Ответ написан
    1 комментарий
  • Почему не подключается фласк?

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

    Vindicar
    @Vindicar
    RTFM!
    Ответ немного абстрактный, но, имхо, таблица расхода должна иметь вид "ID товара - ID расходника - количество".
    Тогда можно будет отсеять расходники по товару, а дальше уже работать с фильтрованным списком.
    Ну и одними формулами тут не обойдёшься, конечно - они не могут просто изменить константу в какой-то ячейке. Нужен AppScript хотя бы.
    Ответ написан
    Комментировать
  • Почему callback-функция не повторяется второй раз?

    Vindicar
    @Vindicar
    RTFM!
    Есть маааааленькая проблемка. Ты забыл/не знал, как работают файлы. А именно, у них есть такая штука как "текущая позиция", по которой выполняется чтение-запись. В итоге:
    1. Ты открываешь файл в начале кода. Его текущая позиция - в начале файла.
    2. Ты делаешь отправку файла. Бот читает содержимое файла до конца для отправки. Теперь текущая позиция - в конце файла.
    3. Ты снова пытаешься отправить тот же файл. Бот не может прочитать содержимое файла, потому что текущая позиция - в конце, читать в конце уже нечего. А в начало бот сам не "перематывает", он же без понятия, что у тебя за файл.

    Просто открывай файл каждый раз при отправке (и не забудь закрыть, оператор with в помощь), а не один раз в начале скрипта.
    Либо, если прямо очень-очень хочется держать файл открытым, каждый раз перед отправкой "перемотай" файл на начало методом seek().
    Ответ написан
    Комментировать
  • Как создать шахматную доску в tkinter, используя create_image?

    Vindicar
    @Vindicar
    RTFM!
    ничего не получается

    Не получаться может очень по разному. Какие симптомы?
    Ну и по коду много вопросов...
    class Game:
        def __init__(self):
            self.tk = Tk()
            ...
            self.running == True:  # <-- это вообще некорректный синтаксис, программа даже не запустится с таким
    
        def mainloop(self):  # зачем вообще этот метод? чем self.tk.mainloop() не угодил?
            while 1:  # почему вечный цикл? Зачем тогда self.running?
                if self.running == True:  # незачем. достаточно просто if self.running: 
                self.tk.update_idletasks()  # где отступы? непонятно, где заканчивается if. Тоже не запустится.
                self.tk.update()
                time.sleep(0.01)
    Ответ написан
  • Как отправить запрос в 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, если тебе лучше работать асинхронно), они позволяют всё это делать. Просто нужно выучить, как.
    Ответ написан
    Комментировать
  • Почему питон не дастает файл из директории?

    Vindicar
    @Vindicar
    RTFM!
    А как насчёт документацию почитать?

    Параметры:
    chat_id (int or str) – Уникальный id чата или username канала (в формате @channelusername)
    sticker (str or telebot.types.InputFile) – Стикер для отправки. Передайте file_id (String), чтобы отправить файл, который уже загружен на сервера Telegram (рекомендуется), передайте HTTP URL (String), чтобы отправить .webp файл из интернета или загрузите новый с помощью multipart/form-data.

    Выделение моё. Т.е. параметр стикер интерпретирует принятую строку только двумя способами:
    1. Как ID уже загруженного стикера
    2. Как ссылку на стикер из интернета
    Про путь на локальной машине тут ничего не говорится. Зато упоминается про тип InputFile. Примеры по ссылке показывают, что в этот тип можно обернуть путь к локальному файлу, чтобы загрузить его в телегу, а после этого уже полученный объект InputFile можно передать в нужный метод.
    Т.е. сначала заверни свой путь в telebot.types.InputFile, а потом передай его вторым параметром в send_sticker().
    Ответ написан
    1 комментарий
  • Как исправить значения оси X в графике Windows Forms?

    Vindicar
    @Vindicar
    RTFM!
    Как насчёт документацию открыть?
    На нужной тебе chart area ищешь AxisX, а у неё уже свойства Interval, IntervalOffset, и всё что с ними связано.
    Ответ написан
  • Несколько запросов к API с помощью python?

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