Задать вопрос
  • Проблема со вставкой аргументов в sql запрос python, в чем причина?

    Vindicar
    @Vindicar
    RTFM!
    Ни в коем случае не делайте так
    cur.execute("""INSERT INTO commands (user_id, date, command_name) VALUES (7 , {} , 'd')""".format(time_now))

    Поймаете SQL injection, да и косяков со строками тоже будет немеряно. На один вы уже наткнулись.
    Правильно будет так:
    cur.execute("INSERT INTO commands (user_id, date, command_name) VALUES (7 , ?, 'd')", (time_now,))

    В этом случае передаваемый аргумент будет правильно экранирован, завернут в кавычки и пр.
    Это написано в начале документации по модулю sqlite3, но ведь документацию читают только лузеры. правда же?
    Ответ написан
    1 комментарий
  • Как можно скомпилировать файл конфигурации так, чтобы тело приложения загружало настройки?

    Vindicar
    @Vindicar
    RTFM!
    1. Определяешь формат файла конфигурации. Вариантов много:
    • простой ini-файл (модуль configparser) - удобен, если нужны мало-объемные данные, и не более двух уровней иерархии (т.е. группа-ключ со значением).
    • xml-файл (модуль xml) - громоздкий, но зато поддерживает много уровней вложенности и есть средства проверки корректности
    • json-файл (модуль json) - куда проще в плане синтаксиса, на выходе получаешь комбинацию из словарей и списков питона. Я бы посоветовал его.
    • Можно даже СУБД (типа sqlite3) прикрутить, при желании. Но это оправдано очень не всегда.

    2. Выбираешь место хранения конфига.
    • В папке программы? Будет одна конфигурация для всех пользователей на ПК. Не факт, что у тебя будут права на запись в эту папку. Зато легко копировать программу на другой комп.
    • В папке APPDATA пользователя? Далеко, пользователь вряд ли залезет, зато у разных пользователей на одном компе будут свои настройки. Сложнее перенести программу на другой комп - нужно будет еще найти и скопировать папку настроек. (Сложнее не в плане защиты от копирования, а в плане удобства распространения.)
    • В папке Мои документы пользователя? Не факт что это хорошая идея, но плюсы примерно те же что и выше.
    • Возможна комбинация предыдущих. Например, я делаю так: если в папке с исполняемым скриптом лежит файл с именем "portable", ищу конфиг тут же. Иначе ищу его в APPDATA.

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

    Vindicar
    @Vindicar
    RTFM!
    Почитай официальные примеры, там это есть.
    await bot.api.messages.send(
                peer_id=event.object.user_id, message="Спасибо за подписку!", random_id=0
            )

    Можно предположить, что peer_id - это id пользователя, которому нужно отправить сообщение.
    Ответ написан
  • Как перевести число в двочиную систему состоящую из 2 и 5?

    Vindicar
    @Vindicar
    RTFM!
    Перевод числа в строку с записью двоичной системе - это bin(). Единственное, первые два символа префикса 0b оторвать. Для более удобной замены нескольких символов за один раз лучше использовать .translate(). В итоге получаем:
    table = {ord('0'):'2',ord('1'):'5'}
    print(bin(N)[2:].translate(table))
    Ответ написан
  • Как добавить bash в автозагрузку от имени root?

    Vindicar
    @Vindicar
    RTFM!
    Если убунта новая - то сделай из него systemd модуль. Тебе нужен тип one-shot, т.е. который выполняется и завершается, а не работает постоянно. Вот приблизительный пример. Допустим, файл называется foo.service
    [Unit]
    #человекочитаемое описание
    Description=Setup foo
    
    [Service]
    Type=oneshot
    #это путь к скрипту, который будет выполняться разово при запуске сервиса
    ExecStart=/opt/foo/setup-foo.sh
    #если ExecStart отработал, сервис считается активным
    RemainAfterExit=true
    #это путь к скрипту, который будет выполняться разово при остановке сервиса
    ExecStop=/opt/foo/teardown-foo.sh
    StandardOutput=journal
    
    [Install]
    #когда запускать скрипт при загрузке - когда готовы выполняться от имени пользователей, или когда сеть есть, или ещё когда.
    WantedBy=multi-user.target


    Создав файл, не забудь сделать systemctl daemon-reload чтобы systemd подцепил изменения.
    А чтобы срабатывало при загрузке - systemctl enable foo.service. Если назвал файл иначе, поправь последний аргумент.
    Если твои скрипты не отмечены как испоняемые, или не имеют в первой строке #!/bin/bash, то тогда надо изменить строки ExecStart/ExecStop так:
    ExecStart=/bin/bash /opt/foo/setup-foo.sh
    Ответ написан
    Комментировать
  • Discord.py иерархия как сделать?

    Vindicar
    @Vindicar
    RTFM!
    Пишешь список ролей от наиболее авторитетных до наименее авторитетных.
    При выполнении команды кика/мьюта сравниваешь наиболее авторитетную роль отправителя с наиболее авторитетной ролью цели. Авторитетность тут меряется как индекс в списке ролей - чем меньше, тем лучше.
    Ну а дальше, выполняешь команду только если отправитель более авторитетен чем цель.
    Ответ написан
    Комментировать
  • Как открыть другой файл python и там в словарь перезаписать данные?

    Vindicar
    @Vindicar
    RTFM!
    mlt_melt, не городите велосипед, а используйте модуль json. Будет вам нормальное сохранение структурированных данных - до тех пор, пока их можно представить в виде набора часть-целое.
    А если связи более сложные, например, есть список юзеров и нужно хранить кто с кем в друзьях - то тут уже впору задуматься о реляционной БД.
    Ответ написан
    Комментировать
  • Как сделать так, чтобы числа из словаря после перебора и парсинга суммировались?

    Vindicar
    @Vindicar
    RTFM!
    cumma = 0
    cumma += searcher(i)

    Вот на кой огурец ты сбрасываешь сумму в 0 на каждой итерации цикла? Конечно 0 + x = x.
    Вынеси cumma = 0 за цикл, инвестор.
    Ответ написан
    1 комментарий
  • Взаимосвязь Python с программами?

    Vindicar
    @Vindicar
    RTFM!
    Под наивным "взаимосвязь" скрывается несколько совершенно различных технологий.
    Пакеты pyautogui и pywinauto занимаются вопросами имитации пользовательского ввода (и вообще взаимодействия с интерфейсом программы).
    Если тебе нужно лезть в чужую память - то тут уже нужно использовать win32 API функции ReadProcessMemory()/WriteProcessMemory(). Модуль ctypes в помощь.
    Если тебе нужно лезть в трафик чужого приложения, есть такая штука как dpkt.

    Фокус в том, что ни один из этих инструментов не тривиален в использовании. Нужно хорошо представлять устройство памяти процесса в windows, устройство оконного интерфейса в windows или устройство сетевых протоколов, в зависимости от задачи. А это дело не одного месяца.
    Ответ написан
    4 комментария
  • Как в Python вывести таблицу как в примере?

    Vindicar
    @Vindicar
    RTFM!
    Вывести в консоль?
    Ну я бы подходил к этому так.
    1. Преобразовать все выводимые данные в строки и разбить их по переносам строки.
    2. Определить наибольшую ширину каждого столбца с учётом переносов строки. Для каждой ячейки вычисляем наибольшую ширину строки, потом ищем максимум по столбцу. Можно добавить 1-2 символа как "поля", если надо.
    3. При выводе строки, выводим строки ячеек вместе, используя itertools.zip_longest(). Т.е. сначала первую строку в каждой ячейке, потом вторую, и т.д. Если получили вместо одной из строк None, значит в этой ячейке строки уже закончились - выводим пробелы.
    Ширину вывода каждой ячейки мы знаем из пункта 2, выровнять значение пробелами - тривиально.

    # -*- coding: utf-8 -*-
    import typing as t
    import itertools
    
    def print_table(headers: t.Dict[str, str], data: t.Iterable[t.Dict[str, str]]) -> None:
        keys: t.List[str] = list(headers.keys()) #список ключей в таблице - чтобы сохранять порядок столбцов
        split_data: t.List[t.Dict[str, t.List[str]]] = [] #ячейки, разбитые на строки
        max_widths: t.Dict[str, int] = { key:len(value) for key,value in headers.items() } #ширина каждого столбца в таблице
        for line in data:
            #разбиваем ячейки строки на текстовые строки по \n
            split_line: t.Dict[str, t.List[str]] = { key:value.splitlines() for key,value in line.items() }
            #обновляем ширину столбцов, если надо
            for key in keys:
                new_width = max(map(len, split_line.get(key, [''])))
                if new_width > max_widths[key]:
                    max_widths[key] = new_width
            split_data.append(split_line)
        #выводим заголовки
        for key in keys:
            print(f'{{0:<{max_widths[key]}}}'.format(headers[key]), end='|') #можно вместо | поставить пробел
        print()
        print( '+'.join('-'*v for v in max_widths.values()) + '|') #разделитель заголовка и тела таблицы
        #выводим строки таблицы
        for row in split_data:
            for parts in itertools.zip_longest(*(row[key] for key in keys)):
                #parts - кортеж, где каждый элемент либо строка в очередной ячейке, либо None
                for key,part in zip(keys, parts):
                    #None означает, что в этой ячейке строки текста уже кончились
                    print(f'{{0:<{max_widths[key]}}}'.format(part if part is not None else ''), end='|')
                print()
            print( '+'.join('-'*v for v in max_widths.values())  + '|') #разделитель строк, если надо
    
    data = [
        {'ip':'192.168.0.2', 'model':'DES-3200-26', 'uptime': '3d 12:03:05', 'uplink state': '25: up\n26:up', 'uplink err': '0\n11', 'uplink mcast': '24560\n113'},
        {'ip':'192.168.0.2', 'model':'DES-3200-52', 'uptime': '1d 04:00:15', 'uplink state': '49: up\n50:up\n51:down\n52:down', 'uplink err': '10\n1133\n0\n0', 'uplink mcast': '5497812\n3145\n0\n0'},
    ]
    headers = {'ip': 'IP address', 'model': 'Model', 'uptime': 'Uptime', 'uplink state': 'Uplink state', 'uplink err': 'Uplink errors', 'uplink mcast': 'Uplink M-cast'}
    print_table(headers, data)

    IP address |Model      |Uptime     |Uplink state|Uplink errors|Uplink M-cast|
    -----------+-----------+-----------+------------+-------------+-------------|
    192.168.0.2|DES-3200-26|3d 12:03:05|25: up      |0            |24560        |
               |           |           |26:up       |11           |113          |
    -----------+-----------+-----------+------------+-------------+-------------|
    192.168.0.2|DES-3200-52|1d 04:00:15|49: up      |10           |5497812      |
               |           |           |50:up       |1133         |3145         |
               |           |           |51:down     |0            |0            |
               |           |           |52:down     |0            |0            |
    -----------+-----------+-----------+------------+-------------+-------------|
    Ответ написан
    2 комментария
  • Почему Python такой, как им пользуются?

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

    1. Правильно, если нужен именно упакованный exe, используется PyInstaller, хотя это и не очень оптимально.
    2. Файлы с расширением .pyw запускаются без окна консоли (на Windows). На Linux системах есть свои средства подавления окна консоли.
    3. Чтобы запустить программу на .NET, нужно, чтобы была установлена правильная версия .NET Framework. Чтобы запустить программу, скомпилированную на C++ с помощью Visual Studio, под виндой обычно требуется MSVC Redistributable правильной версии. Они могут быть предустановлены, но это не факт. Так что вопрос зависимостей есть не только в питоне. Питон хотя бы имеет пакетный менеджер для таких вещей, и в большинстве случаев установка зависимостей сводится как pip install foo bar baz.
    А как им пользуются, запускают код, он "крутиться" что то там делает или вызывают питоновские скрипты из других языков.

    Как правило, самостоятельно, в виртуальном окружении типа venv или docker. Если скрипту не требуются специфичные зависимости, можно использовать интерпретатор питона, установленный прямо в системе.
    Но есть механизмы, позволяющие программе на C++ встраивать в себя интерпретатор питона - тогда можно использовать питон для написания скриптов для автоматизации этой программы, например. Это используется реже.
    Ответ написан
    Комментировать
  • Как результат каждого процесса записать в отдельный соответствующий файл (Multiprocessing, Python)?

    Vindicar
    @Vindicar
    RTFM!
    for i,item in enumerate(data_group):
        file_name = f"{i}.txt"
        #ну и далее по тексту

    Как-то так? Я серьёзно не вижу в чём затруднение.
    Ответ написан
    Комментировать
  • Как sys.stdin, который выглядит как словарь превратить в словарь?

    Vindicar
    @Vindicar
    RTFM!
    Ты пробовал вывести str(sys.stdin) на экран?
    >>> str(sys.stdin)
    "<_io.TextIOWrapper name='<stdin>' mode='r' encoding='utf-8'>"


    sys.stdin - это файл, открытый в текстовом режиме. Работай с ним как с файлом.
    Ответ написан
    1 комментарий
  • Как проверить, на какой сервер зашёл пользователь?

    Vindicar
    @Vindicar
    RTFM!
    Ну и в чём проблема-то? Иметь отдельную настройку под каждый сервер?
    БД в помощь, делаешь таблицу вида "id сервера - срок", при входе пользователя делаешь выборку из неё по id сервера. Если ничего не нашли, используем срок по умолчанию (я бы по умолчанию задал 0, чтобы функция работала только если админ её настроил).
    Ответ написан
  • Вход на сайт и парсинг данных, как реализовать?

    Vindicar
    @Vindicar
    RTFM!
    Какую библиотеку используешь? Смотришь, какой запрос к сайту выполняется при авторизации в браузере, имитируешь его, сохраняешь возвращённые сайтом куки, потом эти куки указываешь при последующих запросах.
    Ответ написан
    Комментировать
  • Как сделать tasks.loop автоматического разбана после истечения времени, используя SQLITE3?

    Vindicar
    @Vindicar
    RTFM!
    зачем вызов await client.wait_until_ready() в цикле for bans в функции ban_loop()? Это затормозит цикл чёрт знает насколько. Аналогично с вызовом того же в начале ban_loop() - у тебя же есть обработчик on_ready(), ты запускаешь ban_loop() там, это гарантирует, что цикл начнётся когда бот уже готов работать.

    Далее, зачем выбирать все баны и пролистывать их, когда можно настроить SELECT чтобы он выбирал только истёкшие баны?
    Ответ написан
    3 комментария
  • Как настроить блокировку только для некоторых потоков?

    Vindicar
    @Vindicar
    RTFM!
    Lock (он же мьютекс) такими вещами не занимается.
    Ты можешь скостылить конструкцию, при которой у каждого order есть свой Lock, но это будет или расточительно (если всегда создавать Lock) или утомительно (если создавать его при обращении к order).
    Асинхронный подход может помочь, но он потребует почти полной переделки кода. Не очень-то удобно.
    А вообще стоит задаться вопросом - этот Lock точно является узким местом?
    Ответ написан
    Комментировать
  • Как грамотно сформировать архитектуру чат бота?

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

    Vindicar
    @Vindicar
    RTFM!
    1. itertools.permutations(), itertools.products(), itertools.combinations_with_replacement(). Выбери, какое поведение тебе нужнее, они немного отличаются.
    2. таких комбинаций будет ОЧЕНЬ много - вплоть до 2^N, где N - длина исходной строки. Чтобы представил, 16 букв (именно букв) дадут 65536 комбинаций. Оно тебе точно надо?
    Ответ написан
    2 комментария