Задать вопрос
  • Как учесть списание комплектующих по спианию продукта?

    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, самое простое решение.
    Ответ написан
    Комментировать
  • 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():
        ...  # тут что-то делаешь при открытии первой вкладки


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

    Vindicar
    @Vindicar
    RTFM!
    Сначала создай курсор, потом на нём уже вызывай execute() для выполнения запросов. Когда закончишь работать с курсором - вызови close(). Это часть спецификации DB-API 2.0, которому следует большинство библиотек для работы с БД на питоне.
    Ответ написан
    Комментировать
  • Почему данные в БД SQlite добавляются в новую строку?

    Vindicar
    @Vindicar
    RTFM!
    Потому что ты выполняешь два запроса INSERT. Запрос INSERT добавляет новую строку. Всё логично.
    Тебе нужно сделать одно из двух:
    Вариант 1. Изменить код так, чтобы бот накапливал сведения в памяти, и только на самом последнем этапе заносить собранное в БД. Я вижу, ты используешь FSM - отлично! Этот механизм позволяет хранить произвольные данные в контексте состояния.
    Вариант 2. Сделать, как сделал Pasha выше - вносишь первую порцию данных через INSERT, остальные - через UPDATE. Тогда у тебя на последующих этапах будут обновляться существующая строка.
    Можно сделать, как предложил fenrir - использовать UPSERT, который сводится к "если строки нет, делай INSERT, если есть, делай UPDATE", но я бы не советовал его тут использовать - лучше сначала чётко разобраться, что и как работает.

    Разница между вариантами будет в ситуации, когда бот отвалился в процессе регистрации. В первом случае собранные частичные данные будут забыты, и пользователю придётся регаться с начала. Во втором случае у тебя в базе будет недореганный пользователь, что может "всплыть" (спровоцировать ошибки) в дальнейшем. Так что я бы предпочёл вариант 1.

    В любом случае, поддерживаю замечание насчёт первичного ключа - это основное понятие! Пойми, что это такое, и задай его для своей таблицы.
    Ответ написан
    1 комментарий
  • Поможете исправить ошибку в 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!
    Это постоянно так. Используй более старую версию упаковщика, она уже должна быть в белых списках. Но проблемы всё равно могут быть.
    Ответ написан
  • Как создать установщик?

    Vindicar
    @Vindicar
    RTFM!
    Стэковерфлоу не согласен. Можно создать ярлык в папке автозагрузки у пользователя.
    Если нужен выбор, создай компонент и привяжи задачу к нему.
    [Components]
    Name: "main"; Description: "Программа"; Types: full; Flags: fixed
    Name: "autorun"; Description: "Автозапуск"; Types: full
    
    [Icons] 
    Name: "{userstartup}\My Program"; Filename: "{app}\MyProg.exe"; Component: autorun

    Ну или для всех пользователей (если под админом). Аналогично, можно закинуть ключ в нужную ветку реестра.
    Просто нужно немножечко напрячься и погуглить.
    Ну или если пробовали и не вышло, то подробно это написать в вопросе.
    Ответ написан
    3 комментария
  • Можно ли узнать типы сигнатуры std::function?

    Vindicar
    @Vindicar
    RTFM!
    Обычно ты должен УЖЕ знать сигнатуру функции, чтобы принять ссылку на неё. Иначе как ты её вызовешь?
    Ответ написан
  • Провайдер блокирует vless vpn, как обойти блокировку?

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

    Так что позарез нужно настраивать клиент-прокси так, чтобы пускал через сервер только заблокированное, а в X-UI ставить галки "не ходить на ресурсы из Китай/Ирана/России".
    Как долго сервер висит в сером списке - я фз, можешь у хостера заказать смену IP адреса на новый, но при неосторожном использовании новый IP улетит туда же. Может, стоит временно использовать клиентское решение типа goodbyedpi, чтобы про сервер "забыли".
    Ответ написан
    4 комментария
  • Долгая обработка SQL запроса?

    Vindicar
    @Vindicar
    RTFM!
    Какое лютое извращение.
    user_parsing_ok = cur.fetchall()
        korteg = ()
        for k in user_parsing_ok:
            korteg += k
            step += 1

    Во-первых, вы вытаскиваете 3 миллиона записей в память как питоновские объекты. Это не очень хорошая идея.
    Во-вторых, вместо того, чтобы по-человечески сделать
    korteg = tuple(item[0] for item in user_parsing_ok)
    вы делаете конкатенацию кортежей по одному. Напомню, что при конкатенации создаётся новый кортеж - так что при добавлении трёхмиллионного элемента у вас в памяти будет один кортеж с 2999999 элементами и один кортеж с 3000000 элементами. Это дело будет люто, бешено, неиллюзорно жрать память, а значит, свопиться на диск. Что не прибавит скорости.
    Как написали выше, просто используйте подзапрос. Вам совершенно незачем таскать эти айдишники из БД в питон, а потом из питона в БД. Пусть они обрабатываются только в рамках БД.
    Ответ написан
    Комментировать
  • Как настроить Nekoray оптимальным образом?

    Vindicar
    @Vindicar
    RTFM!
    Добавляешь правило по доменам вида
    domain:google.com,
    domain:googleusercontent.com,
    domain:googlevideo.com,
    domain:gstatic.com,
    domain:youtu.be,
    domain:youtube.com,
    domain:ytimg.com

    и ставишь тег прокси.
    Ниже добавляешь правило "port 0-65535" и ставишь тег direct.
    Как-то так.
    Ответ написан
  • Мультиязычность на python как стоит оптимизировать?

    Vindicar
    @Vindicar
    RTFM!
    Ну кэшировать результаты приведённого кода, пожалуй, стоит, всё же открывать-закрывать файл на каждый чих - не лучшая идея. functools.lru_cache в помощь.
    Но вообще, если встаёт вопрос "оптимизировать или нет", то первое, что нужно сделать - понять, что именно стоит оптимизировать. Если у тебя заметная доля времени выполнения тратится на указанный код, то да, стоит.
    Профилируй свой код (можно с помощью модулей profile/cProfile или стороннего профилировщика), и выясняй.
    Ответ написан
    Комментировать
  • Что нужно сделать чтобы код заработал как надо?

    Vindicar
    @Vindicar
    RTFM!
    проверяет условие 42 <= r1 and r2 <= 88

    if 42 <= r1 <= 88 and 42 <= r2 <= 88:

    Это разные условия. Какое из двух тебе нужно?
    И если на то пошло, какой именно неправильный ответ выдаёт код? Не находит решение, когда оно должно быть? Или находит решение, когда его не должно быть? Или находит неправильное решение?
    Ответ написан
    2 комментария