Задать вопрос
  • Как отправлять много запросов 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.
    Ответ написан
    Комментировать
  • Вопросик вселенского масштаба. Как добавить данные в БД Django?

    Vindicar
    @Vindicar
    RTFM!
    Сделай так, чтобы по нажатию на Добавить генерировался фоновый запрос через JS, передающий id книги.
    На бэкэнде сделай роут для этого запроса, и в нём уже выполняешь нужные действия.
    Ответ написан
  • Чем можно находить незакрытый html тэг?

    Vindicar
    @Vindicar
    RTFM!
    from html.parser import HTMLParser
    
    bufer = '''<p>
        <div>hi!
    </p>'''
    
    class MyHTMLParser(HTMLParser):
        def __init__(self):
            super().__init__()
            self.open_tags = []
        
        def handle_starttag(self, tag, attrs):
            print("Start tag:", tag)
            self.open_tags.append((tag, self.getpos()))
        
        def handle_endtag(self, tag):
            print("End tag  :", tag)
            unclosed_tags = []
            # ищем, когда был открыт нужный тег
            for i in range(len(self.open_tags)-1, -1, -1):
                if self.open_tags[i][0] != tag:
                    unclosed_tags.append(self.open_tags[i])
                else:
                    break
            if len(unclosed_tags) == len(self.open_tags): # тег никогда и не был открыт
                print(f"Closing tag {tag} has no matching opening tag!")
            elif unclosed_tags: # тег был открыт, но он не последний
                print("Following tags are not closed properly:\n", '\n'.join(f'    {t} at line {line} pos {col+1}' for t,(line, col) in unclosed_tags))
                del self.open_tags[-len(unclosed_tags)+1:] # сбрасываем незакрытые теги
            else: # тег был открыт, и он последний - всё в порядке
                del self.open_tags[-1]
        
        def close(self):
            super().close()
            print('Processing done')
    
    parser = MyHTMLParser()
    parser.feed(bufer)
    parser.close()


    Вместо вывода текста можешь сразу выкидывать исключения, или накапливать сведения об ошибках, чтобы выкинуть одно исключение с полной информацией в методе close().
    Ответ написан
    2 комментария
  • Почему ошибка UnboundLocalError: local variable 'loginD' referenced before assignment?

    Vindicar
    @Vindicar
    RTFM!
    Вообще-то да, эту ошибку тут часто спрашивают, хотя она очень простая.
    for row in records:
            loginD = row[2]
            passwordD = row[3]
    d = Dnevnik(login=loginD, password=passwordD)

    У тебя d создаётся после цикла, только для последнего значения loginD и passwordD.
    Вопрос: что будет, если в records ничего нет?
    Тело цикла не выполнится ни разу, переменные loginD и passwordD не будут определены. А ты дальше пытаешься их использовать, о чём питон и предупреждает.

    Ну и да, код - какой-то бред.
    1. Ты сначала делаешь records = cursor.fetchall(). Тем самым ты выбираешь все строки, возвращённые последним запросом, выполненным через cursor. При следующем вызове функции homeworkss() cursor уже не будет содержать строк (ты их все выбрал в прошлый раз). А следующий вызов может настать в любой момент, так как homeworkss() - обработчик события. Почему ты выполняешь запрос вне homeworkss()?
    2. Зачем вообще перебирать строки таким циклом, который создаёт дневник только для последней строки? Если тебе нужна конкретная строка, то почему не выбрать запросом только её? Если тебе нужны все строки, почему ты создаёшь дневник только для одной?
    Ответ написан
    Комментировать
  • Как мне продолжить изучение языков программирования?

    Vindicar
    @Vindicar
    RTFM!
    Я бы не советовал начинать с питона или с php, разве что программирование нужно выучить срочно, "ещё неделю назад, но вчера тоже сойдёт".
    Языки с динамической типизацией имеют свои преимущества, они удобны, но ИМХО они подразумевают, что программист умеет оперировать типами данных сам. Более строгие языки типа Java или C# всё-таки приучают думать о таких вещах самостоятельно. Самые основы (алгоритмы и структуры данных) лучше осваивать на них, а потом уже с этим базисом переползать на другие языки.
    Ответ написан
    3 комментария
  • Как получить названия всех ярлыков в папке?

    Vindicar
    @Vindicar
    RTFM!
    Ярлыки имеют расширение *.lnk.
    Для поиска файлов по расширению используй метод glob() класса pathlib.Path, ну или функцию glob.glob().
    Ответ написан
    Комментировать