• Как работают рекурсии?

    Vindicar
    @Vindicar
    RTFM!
    Raddzor788,
    Где хранятся все эти значение 1,2,3,4, ведь у моего 'x' нету же звездочки(*х), чтобы собрать столько аргументов.

    Твой x - это несколько разных x. Потому что есть такая вещь как области видимости. Обычно есть область видимости функции (локальная) и глобальная область видимости скрипта. Если функция не видит нужного имени в локальной области - она ищет в глобальной. Если не видит и там - ищет в __builtins__.
    0. По умолчанию есть глобальная область видимости скрипта.
    1. При вызове func(1) создаётся локальная область видимости (скажем, А), в ней создаётся имя x, указывающее на 1.
    2. Отработало условие 1 < 4.
    3. Вызывается func(2). При этом создаётся НОВАЯ локальная область видимости Б (потому что новый вызов функции), в ней создаётся имя x, указывающее на 2.
    4. Отрабатывает условие 2 < 4.
    5. Вызывается func(3). При этом создаётся локальная область видимости В, в ней создаётся имя x, указывающее на 3.
    6. Отрабатывает условие 3 < 4.
    7. Вызывается func(4). При этом создаётся локальная область видимости Г, в ней создаётся имя x, указывающее на 4.
    8. Условие 4 < 4 не отрабатывает. Происходит вызов print(x) - имя x находится в текущей локальной области Г, выводится ассоциированное с ним значение 4. Отрабатывает print(4), происходит возврат из функции, область видимости Г уничтожается.
    9. Происходит вызов print(x) в предыдущем "слое" рекурсии. Текущая локальная область видимости В - в ней имя x связано со значением 3. Отрабатывает print(3), происходит возврат из функции, область видимости В уничтожается.
    10. Происходит вызов print(x) в предыдущем "слое" рекурсии. Текущая локальная область видимости Б - в ней имя x связано со значением 2. Отрабатывает print(2), происходит возврат из функции, область видимости Б уничтожается.
    11. Происходит вызов print(x) в предыдущем "слое" рекурсии. Текущая локальная область видимости А - в ней имя x связано со значением 1. Отрабатывает print(1), происходит возврат из функции, область видимости А уничтожается.
    12. Мы вышли из всех слоёв рекурсии. Мы находимся в теле скрипта и работаем только с глобальной областью видимости.
    Ответ написан
    Комментировать
  • Можно ли и каким образом прописать команду telegram-боту обрабатывать только определенные изображения (скрины,документы), а остальные игнорировать?

    Vindicar
    @Vindicar
    RTFM!
    Простого способа нет. Метаданные могут кое-что подсказать - некоторые форматы изображений содержат комментарии, например, каким ПО файл был создан. Но метаданные могут отсутствовать или быть некорректными.
    Не говоря уже о том, что ваше определение "скриншоты, документы" - ОЧЕНЬ расплывчатое. Фотография экрана - это скриншот? А с точки зрения метаданных она будет неотличима от просто фотки. Фотография девушки с паспортом в руках - считается документом или нет?

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

    Vindicar
    @Vindicar
    RTFM!
    Автомат состояний. У тебя его зачаток написан в StateHandler(), хотя и немного корявый.
    Нужно так же иметь ввижу, что с персонажем могут быть ассоциированы несколько параллельно работающих автоматов состояний. Например, один связан с движением, другой - с атаками, третий - с абилками и т.д..

    Что касается рывка при спринте, просто сделай два состояния. При нажатии клавиши переходишь в состояние рывок, если по прошествию 2 секунд клавиша ещё не отпущена, то переводишь состояние в спринт. При отпускании в любом из двух состояний переходишь в ходьбу.
    Ответ написан
    3 комментария
  • Как увеличить паузу между отправкой запроса и получением результата?

    Vindicar
    @Vindicar
    RTFM!
    Время на формирования ответа сервера определяется самим сервером, ты на него повлиять не можешь.
    Если сервер тебе отправляет 10 результатов поиска вместо 30 - значит, либо ты сам запросил только 10, либо в базе есть только 10 подходящих элементов, либо действует какое-нибудь ограничение (для бесплатных пользователей. например?).

    В любом случае, без кода говорить не о чем.
    Ответ написан
  • Почему asyncio.current_task() не передается в функцию?

    Vindicar
    @Vindicar
    RTFM!
    Цитата из документации:
    Return the currently running Task instance, or None if no task is running.

    Как я это понимаю, если ты запланировал выполнение функции как задачи через asyncio.create_task(), то эта функция, и все, вызываемые в ней, смогут получить объект задачи, вызвав asyncio.current_task().
    Если же управление в текущую функции было передано без использования задач на любом из уровней, только через await вызовы, то current_task() вернёт None.

    Но вообще довольно странно. Эксперимент показывает, что хотя бы одна задача должна быть.
    Вот код

    import asyncio
    
    async def print_task():
        print(asyncio.current_task())
    
    
    async def foobar():
        await print_task()
    
    
    async def main():
        print('Direct call')
        await foobar()
        print('create_task')
        task = asyncio.create_task(foobar())
        await task
    
    # asyncio.run(main())  # даст такой же результат
    asyncio.get_event_loop().run_until_complete(main())

    На питоне 3.11 код выводит два объекта задачи, один создаётся run() или run_until_complete(), а другой - create_task(). Тогда получается, что получить None невозможно.
    Ответ написан
    Комментировать
  • Почему не срабатывает if? как это пофиксить?

    Vindicar
    @Vindicar
    RTFM!
    Учи основы работы с файлами в питоне и включай голову.
    Чтение и запись в файл производится по т.н. текущей позиции. При открытии файла текущая позиция стоит в начале файла, а при чтении/записи она смещается на длину прочитанного/записанного.
    А теперь смотри что ты делаешь. У тебя есть вызов fr = f.readlines(). Он построчно прочитает всё содержимое файла в список, и сохранит список в переменную fr. При этом текущая позиция окажется в конце файла - ты же прочитал всё содержимое.
    Как следствие, все дальнейшие вызовы read() и readlines() не смогут прочитать НИЧЕГО - ты уже в конце файла, дальше ничего нет. Они будут возвращать пустую строку или пустой список - а ты этого явно не ожидаешь.
    Раз уж ты читаешь весь файл в fr - то и дальше работай не с файлом, а со списком fr. Ну и проверка на chat_id у тебя кривая - что, если так совпадёт, что твой chat_id будет содержаться внутри второго значения (токен)? Такое может произойти, хоть это и маловероятно.

    Я бы посоветовал не выпендриваться со своим форматом данных в текстовике, а использовать модуль json. Он гораздо удобнее для хранения структурированной информации. А если указать правильные параметры при записи в файл, то полученный файл будет более-менее человеко-читаемым.
    Ответ написан
    2 комментария
  • Что я делаю не так Python?

    Vindicar
    @Vindicar
    RTFM!
    При установке питона обрати внимание на галочку py launcher.
    Ответ написан
    Комментировать
  • Как запустить два параллельных процесса бота: бесконечную функцию, проверяющую имеются ли обновления, и обработчики событий и сообщений?

    Vindicar
    @Vindicar
    RTFM!
    Надо хоть немножечко осознавать, как работает asyncio.
    create_task() возвращает объект класса Task, представляющий собой фоновую задачу. Эта задача уже запланирована к выполнению в рабочем цикле (loop) asyncio, и будет выполняться в фоне пока текущая корутина ожидает какой-нибудь другой операции.

    Но если тебе надо дождаться завершения работы задачи, ты можешь сделать await на этом объекте.
    Тогда текущая корутина приостановится, пока задача не завершится, и получит или возвращённое задачей значение, или выкинутое задачей исключение.
    А теперь посмотри на свой код:
    await asyncio.create_task(start_checking_price(1800))

    Ты создаёшь задачу - и тут же говоришь программе, что тебе надо дождаться её завершения!
    Ну как бы программа и делает в точности то, что ты от неё требуешь...
    Подчёркиваю красным: await asyncio.create_task(some_coro(...)) не имеет смысла практически никогда! Если тебе нужно запустить корутину и дождаться результата, делаешь просто await some_coro(...).
    А вот если тебе нужно запустить корутину параллельно текущей... Получится что-то типа такого:
    # ...
        check_task = asyncio.create_task(start_checking_price(1800))  # нету await, мы не ждём созданную задачу!
    
        try:
            await dp.start_polling()
        finally:
            check_task.cancel()  # отменяем корутину
            # внутри start_checking_price() текущий выполняемый await выкинет исключение CancelledError
            # это исключение всплывёт наружу, если мы сделаем await, и позволит отработать 
            # блокам finally, with и т.п. инструментам. Также можно явно поймать это исключение,
            # чтобы обработать отмену корутины. Но в твоём случае это не требуется.
            try:
                await check_task  # даём корутине отработать завершение
            except asyncio.CancelledError:  # ловим всплывшее CancelledError
                pass  # всё ок, никакие действия не требуются
            await my_bot.close()
    Ответ написан
    7 комментариев
  • Как получить экземпляр родителя из дочернего класса?

    Vindicar
    @Vindicar
    RTFM!
    Не надо так делать. Просто не надо.

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

    Vindicar
    @Vindicar
    RTFM!
    Прочитать все записи, разбить строку по разделителю, скормить всё в collections.Counter.
    С pandas не работал, вот пример для списков:
    from collections import Counter
    from itertools import chain
    data = [
      (1, 'old;white'),
      (2, 'old;green'),
      (3, 'old;brown'),
      (4, 'new;green'),
    ]
    # генерирует последовательность ['old', 'white'], ['old', 'green'], ...
    split_generator = (item[1].split(';') for item in data) 
    # генерирует последовательность 'old', 'white', 'old', 'green', ...
    property_generator = chain.from_iterable(split_generator)
    # исправляет регистр и удаляет пробелы - можно убрать, если не надо
    property_fixed_generator = (item.strip().lower() for item in property_generator)
    # поглощает данные из генераторов и считает вхождения
    count = Counter(property_fixed_generator)
    print(count)  # Counter({'old': 3, 'green': 2, 'white': 1, 'brown': 1, 'new': 1})
    Ответ написан
    Комментировать
  • Как указать когда нужна рекурсия а когда нет?

    Vindicar
    @Vindicar
    RTFM!
    JSON не предназначен для структур данных с циклическими ссылками. Вообще-то ты должен был словить исключение в этом случае, а не рекурсию. Очень странно, что этого не произошло.
    Тут есть две возможности:
    1. Задуматься о смысле жизни, а на кой тебе вообще обратные ссылки? Они тебе ТОЧНО необходимы? У тебя есть сценарий, когда у тебя есть ссылка на книгу, но нет необходимой ссылки на полку? Книга должна что-то знать о полке. на которой она стоит? Если без них можно обойтись, удали их. Проще жить будет. Подумай, например, что при перемещении книги с полки на полку ты должен не забыть сменить книге shelf.
    2. Посмотреть на параметр default в json.dump(). Это должна быть функция, которая принимает объект, и возвращает словарь. Ты можешь явно проверять, что объект - один из твоих датаклассов, и удалять из полученного словаря обратные ссылки. Аналогично, у json.load() есть object_hook, который позволяет задать свою логику превращения загруженных из JSON словарей в объекты. Но серьёзно, так ли нужны обратные ссылки?
    Ответ написан
  • Как реализовать Python-код, который будет распознавать речь, но будет реагировать только тогда, когда будет упомянуто определенное слово?

    Vindicar
    @Vindicar
    RTFM!
    Проверяй, содержит ли/начинается ли распознанный текст на определённое слово.
    Как - гуглится, это основы работы со строками в питоне. См. метод startswith() и оператор in. Заодно глянь методы перевода строки в другой регистр типа lower() - может помочь убрать чувствительность к регистру.
    Для начала должно хватить.
    Ответ написан
    Комментировать
  • Выполнение парсинга странцы?

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

    Vindicar
    @Vindicar
    RTFM!
    Не, ну ты можешь поиграться с AnythingLLM для реализации RAG и каким-нибудь ПО для собственно запуска языковой модели (Jan или что-нибудь ещё на базе Ollama).
    Но сразу скажу, у меня не вышло добиться толку.
    Ответ написан
    Комментировать
  • Как правильно написать многоуровневое меню для телеграмм бота в библиотеке telebot?

    Vindicar
    @Vindicar
    RTFM!
    Ну первое, что я замечу: в коде только call_start_menu() помечена как обработчик событий от кнопок, потому что только перед ней стоит декоратор callback_query_handler.
    Советую ознакомиться с документацией и примерами, чтобы понять, как регистрируются обработчики.
    А заодно (поскольку это будет ваш следующий вопрос) понять, что такое func= и для чего оно нужно.
    Ответ написан
    1 комментарий
  • Как SQL запрос переделать для sqlalchemy?

    Vindicar
    @Vindicar
    RTFM!
    По-моему, у тебя перепутаны скобки в stmt = ...
    stmt = select(Book).where(
      or_(
        Book.name.ilike(":message")
      ),   # тут or_ закончился
      (  # а тут уже фз что пошло...
        Book.author_name.ilike(":message"), 
        (
          Book.author_lastname.ilike(":message")
        )
      )
    )  # тут закончился where
    Ответ написан
  • Как сделать чтобы всё в windows 11 пропускалось через proxy?

    Vindicar
    @Vindicar
    RTFM!
    Только ставить клиент впн на комп, чтобы он завернул траффик на себя. Или использовать телефон как единственный источник инета, и завернуть весь раздаваемый трафик в впн.

    Есть, конечно, варианты типа proxify, но с ними нужно экспериментировать.
    Ответ написан
    Комментировать
  • Куда указывает ошибка AttributeError: 'Bot' object has no attribute 'row' (Pycord)?

    Vindicar
    @Vindicar
    RTFM!
    Да, ты чего-то не понимаешь. Почему у тебя не вызвал вопросов вот этот код?
    def __init__(self, bot):  # раз конструктор
        self.bot: commands.Bot = bot
    
    def __init__(self, *args, **kwargs):  # два конструктор ?!?!?!
        super().__init__(*args, **kwargs, title="Подача запроса")
    Ответ написан
  • Как исправить ошибку?

    Vindicar
    @Vindicar
    RTFM!
    Вариант 1: Ты уверен, что запускаешь свой скрипт, используя правильное окружение?
    Что, если запустить скрипт, явно используя питон из окружения? Например,
    /путь/к/твоему/проекту/venv/bin/python3 твой_скрипт.py

    Вариант 2: имя пакета и имя импортируемого модуля могут не совпадать.
    Ответ написан
    Комментировать