• Почему ошибка 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().
    Ответ написан
    Комментировать
  • ImportError: cannot import name 'enter_client' from partially initialized module 'handlers' Что я сделал не так?

    Vindicar
    @Vindicar
    RTFM!
    Если я комментирую импорт "from handlers import enter_client", в файле админа, то всё запускается, но естественно, функция работать не будет
    Если я комментирую импорт "from handlers import enter_admin", в файле клиент, то не работает, ссылаясь на ошибку (ImportError: cannot import name 'enter_client' from partially initialized module 'handlers')


    Циклический импорт, с чем тебя и поздравляю. Так делать нельзя.

    Определись уже с зависимостями, кто кому нужен? Зачем enter_client() ссылаться на контент из admin.py?
    Ответ написан
  • Не будет ли этот код блокировать асинхронный код?

    Vindicar
    @Vindicar
    RTFM!
    Проблема в том, что в Питоне потоки немножко увечные (ключевое слово GIL), а потому реально работают только в двух случаях:
    1. Исполняемый длительный код написан не на питоне, а принадлежит одному из бинарных модулей
    2. Исполняемый код большую часть времени ждёт (например, операции ввода/вывода).
    В случае с многопроцессностью проблем меньше, но появляетя проблема обмена данными между процессами.

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

    Vindicar
    @Vindicar
    RTFM!
    Это называется "поленился погуглить". Вопрос уже задавали много раз, в т.ч. тут.
    Вот мой недавний ответ на тот же вопрос.
    Сейчас далеко не 90е, и на большинстве страниц полно JS-скриптов. Они, в том числе, могут делать фоновые (без перезагрузки страницы) запросы по ходу работы сайта. Так, например, реализуется "бесконечная лента" - по достижению низа страницы делается фоновый запрос, и новый контент подставляется вниз.
    Некоторые сайты на этом вообще целиком построены - отдают основным запросом только болванку, а содержимое туда подсовывают фоновыми запросами. Как следствие, то, что ты выкачиваешь через requests, и то, что увидит пользователь в браузере - две большие разницы.
    Соответственно, тут нужно:
    1. Идентифицировать, какие фоновые запросы делает сайт. Инструменты разработчика в браузере в помощь.
    2. Определить, какие из этих запросов подгружают нужную тебе информацию, и в каком виде она представлена. Нередко там не HTML-разметка, а формат JSON, с которым куда проще работать.
    3. Определить, что нужно для выполнения этих запросов: какие URL дёргать, какие параметры подставлять, и т.д.
    4. Попробовать имитировать только эти запросы.
    Успех зависит от сайта, многие пытаются защищаться от такого, кто во что горазд.

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

    Vindicar
    @Vindicar
    RTFM!
    Можно дёргать функции WinAPI через ctypes, но pymem удобнее.
    Ответ написан
    Комментировать
  • Почему .append() добавляет неизмененные данные?

    Vindicar
    @Vindicar
    RTFM!
    nun[1]+=i
    possible.append(nun)
    nun[1]-=i

    Это не будет работать, так как append() добавляет ссылку на список, а не его копию.
    Попробуй выполнить вот такой код в отдельном файле и убедись
    b = []
    a = [1, 2, 3]
    b.append(a)
    b.append(a.copy())
    a.append(5)
    print(b)  # выведет [[1, 2, 3, 5], [1, 2, 3]]
    print(b[0] is a)  # выведет True, так как 0 элемент b - ссылка на a
    print(b[1] is a)  # выведет False, так как 1 элемент b - ссылка на отдельный список
    Ответ написан
    Комментировать
  • HTML-страницы в Python (pycharm) с использованием разных библиотек не весь по сравнению если смотреть в самом браузере?

    Vindicar
    @Vindicar
    RTFM!
    Наверняка основной запрос отдаёт болванку, а часть контента подтягивается отдельно яваскриптом и уже в эту болванку вставляется. Поищи по этому сайту, уже спрашивали как парсить динамический сайт.
    Ответ написан
  • Как передать апдейт телеграм боту о том что парсер обновил БД?

    Vindicar
    @Vindicar
    RTFM!
    Вариантов много. Самый простой - храни в БД время обновления (например, время, когда была добавлена запись), и пусть его бот периодически проверяет. Хорошо работает в том плане, что БД может обновляться разными источниками, бот о них знать не обязан. Но вносит лаг между обновлением данных и реакцией бота. Да и бот базу понапрасну дергает.

    Так как в тегах postgre, почитай про команду NOTIFY. Она вроде примерно про то же самое.

    Также есть вариант с сокетом - бот слушает UDP-сокет, парсер на него посылает пакет с оповещением. Плюс в том, что оповещать может любая программа, которая может до этого сокета достучаться.
    Ответ написан
    1 комментарий
  • Ошибка TypeError: marks_message() missing 1 required positional argument: 'marks' почему?

    Vindicar
    @Vindicar
    RTFM!
    @bot.message_handler(content_types=['text'])
    def marks_message(message, marks):


    marks_message(message, marks)
    Плохая идея. Ты уже решай - или функция является обработчиком события от бота, и тогда её параметры определяются библиотекой, или функция вызывается тобой.
    Ответ написан
    7 комментариев
  • Почему приложение Flask не работает в классе?

    Vindicar
    @Vindicar
    RTFM!
    Чтобы понять, нужно понимать три вещи про питон.
    Во-первых, в нём всё - оператор. Да-да.
    def - это оператор объявления функции.
    class - оператор объявления класса.
    Тебе никто не запрещает сделать
    if condition:
        def foo():
            pass
    else:
        def bar():
            pass


    Во-вторых, все методы класса существуют на уровне класса. Явная передача self на это намекает.
    Иными словами:
    class Foo:
        def bar(self, baz):
            print(self, baz)
    
    foo = Foo()
    # вот этот вызов
    foo.bar('hallo!')
    # полностью эквивалентен вот этому
    Foo.bar(foo, 'hallo!')

    А когда ты обращаешься к foo.bar, Питон конструирует специальный временный объект-обёртку, который ссылается на Foo.bar(), но в то же время подставляет туда первым параметром тот объект foo, к которому произошло обращение. Так что если Foo.bar() принимает два параметра (self и baz), то foo.bar() принимает уже один (baz), так как правильный self будет подставлен этой обёрткой самостоятельно.

    В-третьих, декоратор - это просто синтаксический сахар для вызова функции. Иными словами:
    @app.route('/') 
    def index(self):
        return render_template('index.html')

    будет эквивалентно вот такому коду:
    def index(self):
        return render_template('index.html')
    
    _decorator = app.route('/')
    index = _decorator(index)

    Причем это будет работать одинаково и вне класса, и внутри класса.
    Как это относится к твоему вопросу? А вот как.
    class Web:
        app = Flask(__name__) 
    
        @app.route('/') 
        def index(self):
            return render_template('index.html')

    Последовательность действий тут такова:
    1. Создаётся пространство имён для нового класса, пока что безымянного.
    2. В этом пространстве имён создаётся переменная app, её выражение вычисляется немедленно
    3. В этом пространстве имён создаётся функция index()
    4. Отрабатывает декоратор @app.route(), и регистрирует эту функцию index() как обработчик запроса. Обрати внимание, ни функция index(), ни @app.route понятия не имеют, что index() находится внутри класса! Поэтому app.route не ожидает, что index() будет первым параметром принимать какой-то там self. Как следствие, вместо self функция index() получит то, что передал первым параметром Flask. В данному случае - ничего, так как у тебя роут без параметров.
    5. Ну и в итоге отрабатывает создание класса, с учётом указанных предков (у тебя это неявно указанный object), наполнения пространства имён, и пр. Этот класс потом присваивается переменной Web в вышележащем пространстве имён.

    Ну и как теперь жить?
    А очень просто. Если тебе вот позарезу нужны обработчики роутов в виде методов класса, можно сделать так:
    class Web:
        def __init__(self):
            self.app = Flask(__name__) 
            # получаем обёртку для метода, привязанную к нашему self, см. пункт 2
            self_index = self.index
            # вызываем декоратор вручную, см. пункт 3.
            decorator = self.app.route('/')
            decorator(self_index)
            # ну или то же самое в одну строку:
            self.app.route('/')(self.index)
    
        def index(self):
            return render_template('index.html')

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

    Vindicar
    @Vindicar
    RTFM!
    Очень просто. Смотри на первый пример:
    product('ABCD', 'xy') --> Ax Ay Bx By Cx Cy Dx Dy
    Генерятся комбинации из двух символов (так как два параметра). Причем первый параметр кодирует возможные первые символы, а второй - возможные вторые.

    Нам нужно только обобщить это.

    Идешь циклом по строке-маске и формируешь список, где каждый элемент - список подставляемых знаков, соответствующих текущему символу строки-маски. (Назовём этот список списков parts).
    А дальше просто делаешь цикл for combo in product(*parts):
    Ответ написан
    1 комментарий
  • Как обработать исключение в генераторе функции filter?

    Vindicar
    @Vindicar
    RTFM!
    А чем не устроило:
    text_lower = text.lower() # зачем сто раз преобразовывать?
    for x in list_words:
        if x.lower() in text:
            finder = x
    else:  # else относится к for, а не к if
        finder = None
    Ответ написан
  • Как вызвать функцию aiogram?

    Vindicar
    @Vindicar
    RTFM!
    Ну у тебя тут сразу три проблемы.
    1. Искомая функция - обработчик событий в боте. Она ожидает, что на момент её вызова вся нутрянка бота будет в рабочем состоянии. Я сомневаюсь, что твой код это обеспечивает.
    2. Функция ожидает первым параметром объект класса types.Message. Обычно такие объекты создаёт сама библиотека aiogram, на основании приходящих боту сообщений. Программа их создавать не должна.
    3. Вызываемая функция асинхронная (async), а вызывающий её код - синхронный. Вызвать её будет не так просто, особенно с учётом пункта 1. Вдвойне так, если ты не в курсе, в чём разница между синхронным и асинхронным кодом.

    Так что вывод: ты творишь полную фигню. Сформулируй, какую задачу ты пытаешься решить, тогда может, тебе подскажут, как это сделать.
    Ответ написан
    Комментировать
  • Как запарсить div class (mamba)?

    Vindicar
    @Vindicar
    RTFM!
    pphhpphh, поучи немножко, как веб работает, перед тем как парсеры писать. Сэкономишь кучу времени потом.
    Сейчас далеко не 90е, и на большинстве страниц полно JS-скриптов. Они, в том числе, могут делать фоновые (без перезагрузки страницы) запросы по ходу работы сайта. Так, например, реализуется "бесконечная лента" - по достижению низа страницы делается фоновый запрос, и новый контент подставляется вниз.
    Некоторые сайты на этом вообще целиком построены - отдают основным запросом только болванку, а содержимое туда подсовывают фоновыми запросами. Как следствие, то, что ты выкачиваешь через requests, и то, что увидит пользователь в браузере - две большие разницы.
    Соответственно, тут нужно:
    1. Идентифицировать, какие фоновые запросы делает сайт. Инструменты разработчика в браузере в помощь.
    2. Определить, какие из этих запросов подгружают нужную тебе информацию, и в каком виде она представлена. Нередко там не HTML-разметка, а формат JSON, с которым куда проще работать.
    3. Определить, что нужно для выполнения этих запросов: какие URL дёргать, какие параметры подставлять, и т.д.
    4. Попробовать имитировать только эти запросы.
    Успех зависит от сайта, многие пытаются защищаться от такого, кто во что горазд.

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

    Vindicar
    @Vindicar
    RTFM!
    text=(int)
    Это не будет работать.
    Учи, как пользоваться реализацией FSM (finite state machine) в aiogram.
    Ответ написан
    Комментировать
  • Как остановить поток python?

    Vindicar
    @Vindicar
    RTFM!
    Метод join() приостанавливает тот поток, в котором он вызван до момента завершения указанного потока. Он никак не сигнализирует указанному потоку, что пора завершаться, это твоя задача.
    Я не вижу, чтобы ты присваивал True переменной schedule_stop.
    Ответ написан
    2 комментария
  • Как обойти бинарное дерево?

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

    Vindicar
    @Vindicar
    RTFM!
    человек вводил команду(/start например), после этого бот просил написать что нибудь, человек писал какой то текст и бот что то делал с ним

    Тебе нужны Finite State Machines (автоматы состояний). Стоит почитать, что это вообще такое.
    Проблема в том, что в pyTelegramBotAPI их реализации из коробки вроде нет. Есть сторонние библиотеки, которые нужно искать. Ну или реализовывать самому.

    Идея, в общем-то, простая: тебе нужно для каждого пользователя хранить его текущее состояние (например, ввёл он команду /start или нет). Тогда в обработчике сообщения ты сможешь узнать состояние этого пользователя, и решить, что делать с этим сообщением.
    Сложности будут, когда тебе потребуется хранить какие-то ещё данные вместе с сообщением.
    Ответ написан
    Комментировать