• Как запустить shell-комманду в новом процессе без блокировки потока?

    Vindicar
    @Vindicar
    RTFM!
    communicate() как раз и ждёт. Вместо этого ты можешь попробовать просто читать из proc.stdout.
    С асинхронностью сложнее, но ты можешь попробовать запустить функцию в потоке через loop.run_in_executor(). Это позволит завернуть поток в асинхронную задачу. Так как поток будет висеть в ожидании ввода-вывода, он не должен сильно влиять на GIL и мешать другим потокам.
    Ответ написан
    2 комментария
  • Бот на Telebot падает, когда отправляешь второй одинаковый запрос в БД sqllite. Как исправить?

    Vindicar
    @Vindicar
    RTFM!
    Если ты хочешь при любом действии пользователя убедиться, что он в базе, то тебе нужен не просто INSERT, а INSERT ON CONFLICT IGNORE или INSERT ON CONFLICT UPDATE. Если тебе требуется что-то обновлять (например, хранить для пользователя момент последнего обращения к боту), то нужен второй. Если не требуется, то лучше первый.
    Ответ написан
    Комментировать
  • Только начал свое знакомство с Python. Вроде бы код верный, но высвечивается ошибка. В чем может быть проблема?

    Vindicar
    @Vindicar
    RTFM!
    Во-первых, это неверно. map() принимает два аргумента: функцию, которую нужно применить, и коллекцию, к которой её применяем. Ты, к тому же, скобку не закрыл.
    a,b,n=map(float(input().split())
    Надо так:
    a,b,n=map(float, input().split() )

    Во-вторых, по-моему, у тебя кривой расчёт. ИМХО, проще всего рассчитать цену книги в копейках, а потом уже отталкиваться от этого.
    price_kop = 100 * a + b
    total_kop = price * n
    total_gr, total_kop = divmod(total_kop, 100)
    print(total_gr, total_kop)
    Ответ написан
    Комментировать
  • Как обработать закрытие консоли?

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

    Vindicar
    @Vindicar
    RTFM!
    Гуглить пробовал? На первой странице выдачи этот ответ на StackOverflow.
    Если коротко:

    Зависит от установленных на компе голосовых движков. Проверь доступные движки так:
    import pyttsx3
    
    engine = pyttsx3.init()
    for voice in engine.getProperty('voices'):
        print(voice)

    Ищи голоса, у которых упомянут русский язык. Если нет - гугли, как их ставить.

    Определившись с голосом, пропиши его id в скрипте, например
    # тут id голоса, который ты выбрал
    voice_id = "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech\Voices\Tokens\MSTTS_V110_trTR_Tolga"
    engine = pyttsx3.init()
    engine.setProperty('voice', voice_id)
    Ответ написан
    Комментировать
  • Как отправлять много запросов get (python) чтобы не забанили на сайте?

    Vindicar
    @Vindicar
    RTFM!
    1. ХЗ. 100% зависит от сайта.
    2. Стараться обходиться минимумом запросов, отправлять их пореже, стараться лучше косить под обычного пользователя.
    Ответ написан
  • Нужно ли закрывать сессию при requests?

    Vindicar
    @Vindicar
    RTFM!
    1. Чем не устраивают обозначенные варианты? Если токен должен переживать перезапуск, храни его в конфигурации. Если не должен, храни его только в памяти - в глобальной переменной или в атрибуте класса.
    2. Конечно стоит. Просто для того, чтобы при истечении токена на полпути его можно было перезапросить прозрачно для клиентского кода. Например, декоратор вида:
    def requires_token(func):
        @functools.wraps(func)
        def wrapper(self, *args, **kwargs):  #оборачиваем метод, а не функцию
            try:
                result = func(self, *args, **kwargs)  # пробуем вызвать метод как есть
            except InvalidToken:  # кастомное исключение, которое должны выбрасывать методы
                self._acquire_new_token()  # получаем новый токен
                result = func(self, *args, **kwargs)  # пробуем еще раз
            return result
    
        return wrapper

    Тогда любой декорированный метод, который выбрасывает исключение InvalidToken, спровоцирует автоматический запрос нового токена и одну повторную попытку выполнения операции.
    Но можно делать это и явно, в каждом методе.
    3. Под закрытием сессии ты понимаешь инвалидацию токена, т.е. невозможность его дальнейшего использования? Ну так это тебя нужно спрашивать, нужно ли закрывать сессию и требует ли используемое API явного закрытия сессии. Планируешь ли ты выполнять дальнейшие операции в рамках этой сессии? Если точно нет, можешь закрывать - например, при выходе из скрипта. Заодно снимется вопрос о хранении токена. Если не хочешь дёргать получение токена понапрасну, тогда храни токен, но не закрывай.
    Делать это в КАЖДОМ методе точно бессмысленно.
    Ответ написан
    5 комментариев
  • Как визуализовать результат работы кластеризации?

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

    Vindicar
    @Vindicar
    RTFM!
    list(zip(sess, tasks)) должно сгенерить список пар "сессия, задача". Дальше уже с каждой парой работаешь.
    Ответ написан
  • NoneType: 'NoneType' object is not subscriptable. Как быть, где допустил ошибку?

    Vindicar
    @Vindicar
    RTFM!
    msg = event.object.message
    user_id = msg['from_id']

    Значит, msg - это None.
    1. Читай документацию на используемую библиотеку, в каких случаях это может быть
    2. Выполняй операции только если if msg is not None:
    Ответ написан
    Комментировать
  • Как заставить дискорд бота запустить песню?

    Vindicar
    @Vindicar
    RTFM!
    Ну тебе бот пишет прямым текстом где он ищет библиотеку:
    OSError: dlopen(opus, 0x0006): tried: 'opus' (no such file), '/usr/local/lib/opus' (no such file), '/usr/lib/opus' (no such file), '/Users/similization/Programming/python/discord_bot/opus' (no such file)

    Найди, куда именно установился опус, и создай символическую ссылку на библиотеку по одному из указанных путей. Лучше всего по последнему, я полагаю.
    Ответ написан
  • Почему пул запускает тг бота хотя этого нет в def?

    Vindicar
    @Vindicar
    RTFM!
    Без полного кода ответить затруднительно, но...
    Проверь, завёрнуто ли у тебя тело бота в if __name__ == '__main__':
    Ответ написан
    2 комментария
  • Как отслеживать изменение даты файла с сайта?

    Vindicar
    @Vindicar
    RTFM!
    Если искомый файл доступен по ссылке, можно попробовать делать HEAD-запрос к нему и анализировать заголовок ответа Last-Modified. Если сервер его отдаёт, этот заголовок будет содержать дату и время последнего изменения файла.
    Альтернативно, можно добавить к обычному GET-запросу заголовок If-Modified-Since. В этом случае сервер даст разные ответы, если файл был модифицирован после указанного в заголовке момента времени, и если он не был. Опять же, нужно проверять на конкретном сервере, настройки могут отличаться.
    Ответ написан
    Комментировать
  • Как настроить локальный Django сервер если есть проблемы с электричеством?

    Vindicar
    @Vindicar
    RTFM!
    1. Многие модели материнских плат имеют в BIOS/UEFI настройку "Power On State", т.е. что делать, когда пропало а потом восстановилось электропитание. Типичные опции "Off" (остаться выключенной), "Restore" (включиться, если на момент пропадания питания была включенной), "On" (включиться всегда). Лезь в биос своей материнки и смотри, есть ли она.
    2. Настрой автозапуск для Django-сервера, в зависимости от того, какая ОС. Для линуксов это будет systemd модуль или init-v скрипт. Для винды можно использовать планировщик задач или утилиту NSSM, чтобы превратить скрипт в службу (это если у тебя django работает на своём встроенном сервере). Если же у тебя Django-скрипт выполняется как WSGI-приложение к обычному серверу (скажем, Apache), то утсановщик апача обычно об автозапуске заботится сам.
    Ответ написан
    Комментировать
  • Помощь с кодом. (discord.py/python), Упоминания в эмбеде?

    Vindicar
    @Vindicar
    RTFM!
    description='Администратор:{message.author.name}\nИгрок:{user.mention}\nВыданная роль:{role}'

    Это не f-строка, это обычная строка, в ней подстановка не выполняется. Ты f забыл в начале.
    Ответ написан
    Комментировать
  • Как решить такую задачу на python?

    Vindicar
    @Vindicar
    RTFM!
    Для каждого символа c в строке построй список вида [c.upper(), c.lower()], если это буква. Если не буква, список должен содержать один элемент.
    Построй общий список из таких списков (назовём его patterns). Для твоего примера он будет выглядеть так:
    [['a', 'A'], ['.'], ['b', 'B'], ['c', 'C'], ['@'], ['d', 'D']]

    А дальше вызываешь itertools.product(*patterns) и итерируешься по тому, что оно вернёт.
    Ответ написан
    1 комментарий
  • Как вывести в чат боте входные данные в сообщении?

    Vindicar
    @Vindicar
    RTFM!
    Ну смотри внимательно на структуру.
    Сделаем переменную all_lessons = [], куда будем складывать результат.
    Верхняя структура данных - кортеж (tuple). Элементы кортежа - уроки (идут по вертикали).
    Т.е. циклом вида for lesson in data: можно будет перебрать уроки.

    Теперь смотрим отдельный урок:
    [
      [['6']], # индекс 0 - номер урока (почему-то в двух списках)
      [], #индекс 1 - понедельник
      [['Физкультура'], ['Храпов О.Е.'], ['12:05 - 12:45'], ['216']], #индекс 2 - вторник
      [['Иностранный ...'], ['Севостьянова Е....'], ['12:05 - 12:45'], ['047']], #индекс 3 - среда
      [['Физкультура'], ['Храпов О.Е.'], ['12:05 - 12:45'], ['216']], #индекс 4 - четверг
      [], #индекс 5 - пятница
      [], #индекс 6 - суббота?
      [], #индекс 7 - ?
      []  #индекс 8 - ?
    ],


    Отсюда можно сделать вывод, что номер урока можно достать так: lesson[0][0].
    Далее, идёт цикл по дням недели
    for day_number in range(1, 7): #1 - понедельник
        lesson_per_day = lesson[day_number]


    Теперь рассмотрим, что попадёт в lesson_per_day. Тут есть три варианта:
    1. пустой список, урока нет
    2. В списке 4 элемента, один и тот же урок
    3. В списке 8 элементов, это или мигающее занятие (по неделям), или занятие по подгруппам (тебе виднее).
    [
       ['Технология'], #0 - что
       ['Бирюкова Е.Н.'], # 1 - кто
       ['16:15 - 16:55'], # 2 - когда
       ['133'], # 3 - где
       ['Технология'],  #4 - что (альтернатива)
       ['Горбунова Е.П.'], # 5 - кто (альтернатива)
       ['16:15 - 16:55'], # 6 - когда (альтернатива)
       ['048'] # 7 - где (альтернатива)
    ]

    Отсюда:
    if len(lesson_per_day) == 4: # есть одно занятие?
        all_lessons.append({
            'number': int(lesson[0][0]),
            'day': day_number,
            'subject': lesson_per_day[0],
            'teacher': lesson_per_day[1],
            'time': lesson_per_day[2],
            'room': lesson_per_day[3],
            'type': ''  # занятие не над/под чертой
        })
    elif len(lesson_per_day) == 8: # есть два занятия?
        all_lessons.append({
            'number': int(lesson[0][0]),
            'day': day_number,
            'subject': lesson_per_day[0],
            'teacher': lesson_per_day[1],
            'time': lesson_per_day[2],
            'room': lesson_per_day[3],
            'type': 'над чертой'
        })
        all_lessons.append({
            'number': int(lesson[0][0]),
            'day': day_number,
            'subject': lesson_per_day[4],
            'teacher': lesson_per_day[5],
            'time': lesson_per_day[6],
            'room': lesson_per_day[7],
            'type': 'под чертой'
        })

    Собери это вместе и в итоге получишь список словарей вида:
    [
        {'number': 6, 'daynumber': 1, 'subject': 'Физкультура', 'teacher': 'Храпов О.Е.', 'time': '12:05 - 12:45', 'room': '216', type: ''},
        {..................},
        .....................
    ]

    С этим списком уже делай что тебе надо: в базу сохраняй, отсеивай по number/daynumber, выводи... С ним будет проще работать.
    Ответ написан
  • SyntaxError: Non-UTF-8 code starting как исправить ошибку?

    Vindicar
    @Vindicar
    RTFM!
    Файл .py должен быть либо в кодировке ASCII (читай - никакой кириллицы и прочих национальных алфавитов), либо в кодировке UTF-8.
    Если у тебя кодировка не такая (а я подозреваю, у тебя стандартная виндовая ANSI, она же Windows-1251), то нужно явно указать кодировку в начале файла. Что-то типа
    # -*- coding: windows-1251 -*-
    Но я бы посоветовал взять нормальный текстовый редактор и сохранить файл в UTF-8. Меньше проблем.

    Ну собственно я готов спорить, что после "see" шла ссылка, которую ты не открыл.
    Ответ написан
    1 комментарий
  • Как определить размер объекта на фото при помощи python?

    Vindicar
    @Vindicar
    RTFM!
    Смотри в сторону OpenCV. Какой конкретно метод - зависит от искомого объекта: один ли он в кадре, насколько он контрастен по отношению к фону, насколько много на нём контрастных деталей, и т.д.
    Есть template matching для случаев, когда видимый размер и ориентация известны. Работает для нескольких объектов.
    Есть feature matching, для случаев, когда объект только один и имеет контрастные, узнаваемые элементы, но может быть разного размера и ориентации.
    Есть каскады Хаара (или тут) для поиска множества объектов известной ориентации, но с варьируемым размером.
    Есть backprojection, если объектов несколько, но они имеют характерный, узнаваемый набор цветов.
    Копай, разбирайся, выбирай.

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

    Vindicar
    @Vindicar
    RTFM!
    С учётом контекста твоих предыдущих вопросов - ты пытаешься реализовать мой совет, но получается плохо.
    Смотри.

    #сначала реализуем механизм, который позволяет получать объект дневник для пользователя
    import typing
    from functools import lru_cache
    # говорим, что результаты вызова функции должны кэшироваться,
    # но храниться в кэше должно не более 50 экземпляров класса Dnevnik
    # при появлении новых экземпляров, самые старые будут выкинуты
    @lru_cache(maxsize=50)
    # принимаем ID пользователя Telegram, возвращаем или объект Dnevnik, или None
    def get_user_dnevnik(user_id) -> typing.Optional[Dnevnik]:
        # получаешь новый курсор для своего соединения с БД
        # я фз как у тебя называется глобальная переменная, хранящая соединение, 
        # так что назвал её db_conn. Поправишь
        cursor = db_conn.cursor()
        # выбираем из таблицы логинов/паролей пару, соответствующую указанному пользователю
        # имена таблицы и столбцов опять таки поправь, я не помню как они у тебя называются
        cursor.execute("SELECT loginD, passwordD FROM users WHERE id = ?", (user_id,))
        row = cursor.fetchone()
        if row is None: # нет такого пользователя, возвращаем None
            return None
        # в запросе порядок столбцов сначала логин, потом пароль, так что row = (логин, пароль)
        return Dnevnik(login=row[0], password=row[1]) # возвращаем объект Dnevnik


    Теперь, всякий раз, когда тебе требуется объект Dnevnik для пользователя с известным id, вызываешь функцию
    get_user_dnevnik(), передав ей в параметрах этот id.
    Поскольку мы указали для функции lru_cache, фактически запрос к БД и конструирование объекта Dnevnik будет выполняться только если в кэше нет дневника для пользователя с этим id. А если он есть, то дневник будет быстренько возвращён из кэша.
    В то же время кэш будет расти не беспредельно, его размер мы явно задаём и можем подогнать под свои нужды, чтобы балансировать потребление кэшем памяти и потребление проца повторным созданием экземпляров Dnevnik.
    Ответ написан
    Комментировать