• Как найти чат, возвращающий ошибку "ApiError: 917" с помощью логирования?

    Vindicar
    @Vindicar
    RTFM!
    Заверни вызов метода в try - except, в ветке except пиши в журнал (хоть стандартынй модуль logging, хоть просто в файл) id чата, с которым пытался работать.
    Ответ написан
    Комментировать
  • Почему не работает cron?

    Vindicar
    @Vindicar
    RTFM!
    Попробуй просто
    cd /root/my_venv && /root/my_venv/bin/python /root/my_venv/app.py

    activate-скрипт не так уж много полезного делает.
    Ответ написан
    1 комментарий
  • Почему бот не реагирует на inline клавиатуру?

    Vindicar
    @Vindicar
    RTFM!
    Почему ru_bot() вообще отдекорирован как обработчик события, если ты эту функцию вызываешь вручную?
    И, самое главное, откуда в модуле ru берётся dp, и тот ли это dp, что и в main?

    Я подозреваю, что не тот, а свой собственный. Тогда не удивительно, что регистрация обработчиков в нём не имеет эффекта...

    Если это так

    Переделай импортируемые модули так, чтобы в них можно было передать объект dp из main. Например, так:
    # ru.py
    
    def setup(dp):
        @dp.message_handler()
        async def ru_bot(message: types.Message):  # да, эти функции описаны внутри setup()
            ...
    
        @dp.callback_query_handler()
        async def handle_callback_ru(callback_query: types.CallbackQuery):
            ...
    
    # main.py
    
    dp = ...  # создаёшь диспетчер бота
    import ru
    ru.setup(dp)  # регаешь обработчики из ru
    ...  # запускаешь бота


    Ответ написан
  • Что я сделал не так?

    Vindicar
    @Vindicar
    RTFM!
    В-нулевых, пиши симптомы ошибки.
    Во-первых, simpleDividers(n)[len(simpleDividers(n))+1]
    Тебе что, палец отрезают за каждую использованную локальную переменную?
    Зачем два раза вычислять simpleDividers(n)? Почему не закинуть результат в переменную?
    Во-вторых, ты пытаешься обратиться к элементу списка с номером, превышающим его длину (потому что +1).
    Т.е. если у числа три делителя, ты бы обратился к номеру 4. Как по-твоему, это получится сделать?
    В-третьих, ты не возвращаешь answer через return при возврате из simpleDividers(), а код ниже написна так, словно ты его возвращаешь.
    Ответ написан
    Комментировать
  • Почему python возвращает существующий объект, вместо создания нового?

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

    Ну и да, set() не является hashable(), а потому не может быть ключом в словаре.

    sets = [set() for _ in range(3)]
    for s in sets:
        print(id(s))

    Этот код выведет разные id(), потому что ссылки на объекты остаются в списке sets(), а значит, новые множества создаются не там же, где старые.
    Ответ написан
    Комментировать
  • Как запустить программу в одной консоле, но чтобы выполнение происходило в другой?

    Vindicar
    @Vindicar
    RTFM!
    Можно обойтись без промежуточного cmd.exe если использовать модуль subprocess, и передать при создании дочернего процесса флаг subprocess.CREATE_NEW_CONSOLE (доступен только на винде).
    Но тебе всё равно придётся вынести часть кода в дочерний процесс, так как один процесс может иметь только одно окно консоли.

    Лучше подумай, не стоит ли использовать GUI. Если очень хочется консольку, то можно создать подобие GUI в ней, используя стандартный модуль curses. Проблема в том, что curses - либа под unix, так что надо искать порт под винду.
    Например, этот пакет добавляет поддержку винды в стандартный модуль curses, делая программу более переносимой.
    Ответ написан
    Комментировать
  • Как создать зависящие от времени функции не останаливая работу программы на pygame?

    Vindicar
    @Vindicar
    RTFM!
    У тебя должна быть фиксированная частота обновления логики игры.
    Тогда ты сможешь любые задержки выражать в числе кадров, которое должно пройти, прежде чем можно выполнить следующее действие. Соответственно у каждого действия есть счётчик кадров, если он не 0 - действие на кулдауне и выполнять его нельзя. Каждый кадр уменьшаешь ненулевые счётчики на 1.

    Чуть более тонкий подход - хранить время, оставшееся до истечения кулдауна. На каждом кадре измерять, сколько времени прошло с прошлого кадра, и вычитать этот интервал. Точность всё равно будет порядка одного кадра, но хотя бы при тормозах кулдауны не будут замедляться.

    Заодно почитай, что такое автомат состояний. Пригодится.
    Ответ написан
    Комментировать
  • Как предотвратить двойные нажатия?

    Vindicar
    @Vindicar
    RTFM!
    Вопрос на засыпку: если объект-кнопка обработал событие, остальные объекты его тоже получат?
    Если да, то именно такое поведение и будет наблюдаться. Надо как-то пометить, что событие уже было обработано элементом интерфейса. Либо изъять событие из очереди, либо как-то дать знать новому экрану, что события обрабатывать не надо.

    Альтернативно, вызывай коллбэк только если элемент зафиксировал и нажатие и отпускание кнопки без выхода курсора за пределы элемента. Тогда "остаточного" события будет недостаточно для активации кнопки.
    Ответ написан
    Комментировать
  • Полезность моделей памяти которые отличный от linear?

    Vindicar
    @Vindicar
    RTFM!
    Ты придумал защищённый режим x86. Селектор+смещение, да, да.
    На практике ОС создавали два селектора размером со всё адресное пространство, а для реального управления использовали только страничный механизм, потому что размер таблицы селекторов был ограничен, да и просто муторная это штука. В итоге в длинном режиме (x64) остался только страничный механизм.
    Ответ написан
    Комментировать
  • Python, что правильнее использовать, запуск бота на прямую или крон?

    Vindicar
    @Vindicar
    RTFM!
    Ну если на то пошло, то systemd умеет делать задачи-таймеры по типу крона. Хотя крон, пожалуй, на большем числе систем из коробки есть.

    Я бы сказал так. Если у тебя интервалы запуска более-менее статичные - используй systemd или cron.
    А вот если у тебя время следующего запуска нужно вычислять согласно некоторой нетривиальной логике - тут уже лучше самому сделать планировщик.
    Ответ написан
  • Finite State Machine Python, как вызвать функцию с переменной state?

    Vindicar
    @Vindicar
    RTFM!
    У тебя проблема молотка.
    С 99% вероятностью тебе не нужно вызывать такие функции, они являются обработчиками событий и вызываются самим фреймворком aiogram. Если тебе нужно повторно использовать код в таком обработчике, вынеси его в отдельную функцию, которая не работает ни с состоянием, ни с событием.

    Допустим, у тебя есть код:
    @state_router.message(MyState.stateA)
    async def process_stateA(message: Message, state: FSMContext) -> None:
        data = await state.get_data()
        result = message.text + str(data['some_key'])  # это типа логика обработки
        await message.reply(result)

    Его надо будет отрефакторить так:

    def do_stuff(msgtext: str, some_value) -> str:
        return msgtext + str(some_value)
    
    @state_router.message(MyState.stateA)
    async def process_stateA(message: Message, state: FSMContext) -> None:
        data = await state.get_data()
        result = do_stuff(message.text, data['some_key'])
        await message.reply(result)

    И тогда ты сможешь при необходимости вызвать снова do_stuff(), не трогая process_stateA().
    Ответ написан
    1 комментарий
  • Как хранить данные для кастомного блока code?

    Vindicar
    @Vindicar
    RTFM!
    БД тут абсолютно ни причём. Она хранит текст в том виде, в каком ты его туда поместил, вплоть до байта.
    Это браузеры по умолчанию сокращает отступы в ходе рендеринга HTML. Но есть теги вроде <pre>, которые отступы сохраняют. Также можно использовать CSS-свойство white-space со значениями pre или pre-wrap.

    Ответ написан
    Комментировать
  • Как изменять сайт на питоне, аналогично javascript коду сайта?

    Vindicar
    @Vindicar
    RTFM!
    1) Как мне использовать питон код в javascript коде сайта

    Никак, большинство бразуеров поддерживает только JavaScript. Клиентский код придётся писать на нём.
    Зато ты можешь использовать любой язык на стороне сервера - если твоя программа поддерживает нужные протоколы (HTTP + websockets), браузеру будет всё равно, на чём она написана.
    2) Как я могу вносить изменения на работающую html страницу, аналогично работе javascript кода, написанного выше

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

    Vindicar
    @Vindicar
    RTFM!
    while True: вокруг участка, который нужно перезапускать заново.
    Можешь для надёжности завернуть участок в try: except Exception:.
    А вообще я подозреваю, что такую спамилку запросами забанят через час.
    Ответ написан
  • Как реализовать выход из программы или закрытие cmd консоли при вводе 'stop'?

    Vindicar
    @Vindicar
    RTFM!
    Грубое решение: настрой таймаут чтения, и при таймауте проверяй логическую переменную, которая хранит признак "пора остановиться". Тогда если ты эту переменную взведёшь, твои потоки-клиенты отвалятся, пусть и не сразу.
    Ответ написан
    Комментировать
  • Можно ли в python задать размеры окна другому приложению?

    Vindicar
    @Vindicar
    RTFM!
    Тебе нужна функция WinAPI SetWindowPos().
    Чтобы достучаться до винапи, используй стандартный модуль ctypes.
    Ответ написан
    Комментировать
  • Как можно распарсить текст на python?

    Vindicar
    @Vindicar
    RTFM!
    Модуль re в помощь. Если grep умеешь пользоваться, то и тут справишься.
    Ответ написан
  • Как сделать так чтобы бот понимал какой сегодня день недели?

    Vindicar
    @Vindicar
    RTFM!
    Учим стандартную библиотекц питона.
    Там это есть.
    import datetime
    day_of_week = datetime.datetime.now.weekday()
    Ответ написан
    3 комментария
  • При каких обстоятельствах запущен данный процесс python-программы?

    Vindicar
    @Vindicar
    RTFM!
    Я бы попробовал использовать аудит-хук.
    Многие функции питона генерят события аудита, на которые можно подписаться.
    Есть полная таблица событий для CPython, но тебя будут интересовать события типа subprocess.Popen, os.system, os.spawn, os.startfile, os.exec, os.fork и так далее.
    Внутри хука можешь попробовать вызвать traceback.format_stack() чтобы узнать текущий стек вызовов, и записать его в какой-нибудь журнал работы.
    import sys
    import traceback
    # хук который ловит событие импорта модуля
    def hook(event, args):
        if event != 'import':
            return
        name, filename = args[0], args[1]
        callstack = traceback.extract_stack(limit=None)
        print(event, name, filename)
        for item in traceback.format_list(callstack):
            print('    ', item.strip())
    
    sys.addaudithook(hook)
    
    import json
    
    print('Done')


    Это сработает только если процессы спавнятся средствами питона, а не каким-нибудь скомпилированным расширением.

    Также можешь поискать использование модуля multiprocessing, это тоже вероятный кандидат.
    Ответ написан
    1 комментарий
  • Почему в результате изменения второго списка меняется также и первый, если перед этим я приравнял второй список к первому?

    Vindicar
    @Vindicar
    RTFM!
    Читаем про изменяемые и неизменяемые объекты в питоне.
    Если коротко, когда ты делаешь a = b, ты не копируешь объект. Ты просто создаёшь новую ссылку на него.
    Достаточно проверить так:
    print(languages is new_list) # True
    Если объект изменяемый, то изменения будут видны по любой ссылке, что логично:
    a = [1, 2, 3]
    b = a  # b ссылается на тот же список
    b.append(4)  # список изменили

    Если объект неизменяемый, то это не так заметно, потому что ссылка заменяется на ссылку на новый объект:
    a = 5
    b = a  # b ссылается на 5
    a += 1  # a = a + 1 т.е. a = 6 - a теперь ссылается на новый объект 6, b - по прежнему на 5.


    Если нужна независимая копия списка, словаря или иного изменяемого объекта - делай её явно.
    Ответ написан
    1 комментарий