• Как сделать чтобы извлекался user_id пользователя, а не бота?

    Vindicar
    @Vindicar
    RTFM!
    Читаем доки telebot.
    https://docs.python-telegram-bot.org/en/stable/tel...
    message (telegram.MaybeInaccessibleMessage, optional) - Message sent by the bot with the callback button that originated the query

    Выделение моё. Теперь понятно, почему ты получаешь id самого бота?
    А если чуть выше глянуть, там ещё интереснее.
    from_user (telegram.User) – Sender.


    Привыкай находить и читать документацию, там много интересного.
    Ответ написан
    1 комментарий
  • Как работает Jinja?

    Vindicar
    @Vindicar
    RTFM!
    В рамках веб-стэка питон код не может выполняться на клиенте. Учи основы.
    Вся работа Jinja выполняется на бэкэнде. Проверить легко - открой исходник страницы (Ctrl-U по умолчанию), и ты увидишь, что пришло в браузер от сайта.
    Ответ написан
    Комментировать
  • Задание из практикума, не могу сделать уже целую неделю. Какие есть ошибки?

    Vindicar
    @Vindicar
    RTFM!
    У тебя как минимум один косяк в expire().
    for title, batches in items.items():
        for batch in batches:
            if batch['expiration_date'] and batch['expiration_date'] < today:
                expiring_items.append({'title': title, 'expiration_date': batch['expiration_date']})
                break  # <--- ???

    Ты находишь первую "протухшую" партию для товара, и сразу же переходишь к следующему товару. А если у одного товара несколько "протухших" партий?
    Ответ написан
    Комментировать
  • Появилась проблема при запуске приложения Python в Termux?

    Vindicar
    @Vindicar
    RTFM!
    Если нужен красивый визуал в командной строке под никсами, может, стоит использовать модуль curses?
    Ответ написан
  • Где и как в Pycharm можно проанализировать код на вызовы или использование не объявленных методов\полей?

    Vindicar
    @Vindicar
    RTFM!
    Ide подсвечивает такие опечатки, но реально на них можно напороться только при исполнение кода

    Про линтеры выше написали, а я добавлю: PyCharm позволяет просмотреть список всех наденных проблем (errors, warnings) в проекте. Если он не пустой - значит, надо чинить.
    Ответ написан
  • Бот на python/telebot не приветствует новых пользователей, что не так?

    Vindicar
    @Vindicar
    RTFM!
    А почему ты вызываешь bot.polling()? Это для асинхронных ботов, а твой синхронный. Используй infinity_polling().
    Вообще, читай официальные примеры, вроде вот этого, и сравнивай со своим кодом.
    Ответ написан
  • Как исключить ввод пустой строки?

    Vindicar
    @Vindicar
    RTFM!
    Тебе нужно повторять ввод аргументов, пока пользователь не введёт их правильно? Ну вот и повод почитать про циклы.
    while True:  # бесконечный цикл
      x_str = input('Введите x:')  # вводим число
      try:  # внутри блока try мы будем отлавливать ошибки - исключения
        x = float(x_str)  # пробуем преобразовать строку в число
      except ValueError:  # в случае чего float() выкинет исключение ValueError
        print(x_str, 'это не число. Попробуйте ещё раз.')  # сообщаем пользователю
      else:  # если ошибки не было
        break  #  то прерываем цикл, у нас в x лежит нужное значение
      # мы делаем break только в ветке else - значит, пока отрабатывает ветка except, цикл продолжится

    В принципе, если тебе нужна только одна попытка, ты можешь вытащить блок try-except из цикла, убрать ветку else, и заменить ветку except на что-то типа:
    except ValueError:
      print(x_str, 'это не число. У вас есть ещё одна попытка')  # сообщаем пользователю
      x_str = input('Введите x: ')
      x = float(x_str)

    Тогда получится обойтись без циклов.

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

    Vindicar
    @Vindicar
    RTFM!
    66a00bc093f98796053667.png
    У меня всё работает. Смотри настройки IDE, в частности, File->Settings->Editor->Inspections, ищешь "deprecate".
    Ответ написан
  • Питон,нейросеть, алгоритм выхода из лабиринта?

    Vindicar
    @Vindicar
    RTFM!
    Общая идея задачи. как я её понял: дрон с воздуха снимает лабиринт, затем алгоритм сшивает кадры в одно изображение, извлекает форму лабиринта и строит путь по нему. Так? Если так, это должно было быть в вопросе.

    У тебя три чётко видимых шага.
    1. Сборка карты лабиринта по видео с дрона. Я бы для начала использовал поиск локальных особенностей (SIFT, углы по Харрису, или что-то столь же простое).
    Вопрос 1
    Что использовать - сильно зависит от условий съёмки. Чем более контрастные элементы присутствуют на изображении, тем лучше.

    Они обычно не позволяют работать в реальном времени, но это для задачи и не требуется. Затем, зная позиции особенностей на каждом изображении, сравниваем их с "соседними" изображениями.
    Вопрос 2
    Тут будет большой вопрос, касающийся определения соседних изображений. Простой ответ: считаем соседними N последних кадров, но тут могут быть проблемы с длинной цепочкой кадров. Например, если дрон сделает круг, не факт, что на карте этот круг сомкнётся. Может потребоваться какая-то оценка позиции снимка.

    По итогам сравнения мы получим проективное преобразование, описывающее, как надо повернуть/наклонить/растянуть/etc один кадр, чтобы совпали общие с соседним кадром части. Подвергнув кадр такому преобразованию, мы сможем все кадры привести к одной плоскости.
    Вопрос 3
    Скорее всего, возможные преобразования будут на нескольких кадрах, так что придётся их как-то ранжировать, и "усреднять" несколько наилучших преобразований с ближайшими соседями

    Тогда постепенно построите одно изображение-карту, а уж дальше его можно будет обрабатывать обычными средствами. Там, пороговое преобразование или что для выделения "стен", определение границ лабиринта, и дальше уже тупой flood-fill для поиска пути.
    Ответ написан
    1 комментарий
  • Почему выводит ошибку Traceback (most recent call last) при сохранении json словаря в переменную?

    Vindicar
    @Vindicar
    RTFM!
    Читаем и осознаём текст ошибки. UnicodeDecodeError - ошибка декодирования строки байт в юникод-строку, т.е. косяк с кодировками. В списке traceback ищем последний элемент, который ссылается на твой код.
    File "C:\Users\Maks\PycharmProjects\pythonProject7\main.py", line 57, in check_news_update
        news_dict = json.load(file)

    Т.е. косяк при чтении json из файла. При вызове load() кодировку нельзя указать, так что проверяем, откуда приходит файл.
    with open('news_dict.json') as file:  # где encoding? где режим открытия?
            news_dict = json.load(file)

    Вот и ошибка - не указана кодировка (и я бы явно указал режим открытия 'rt'). Причём при сохранении не забыл ведь указать...
    with open("news_dict.json", "w",encoding="utf-8") as file:  # а тут всё правильно
                json.dump(news_dict, file, indent=4, ensure_ascii=False)
    Ответ написан
    Комментировать
  • Как сделать так, чтобы бот, написанный на модуле telebot, включал у пользователя режим ответа на cообщение?

    Vindicar
    @Vindicar
    RTFM!
    А доки на телебот читать пробовал? Нет? Ну так попробуй, там много интересного.

    send_message(...)
    reply_markup (telebot.types.InlineKeyboardMarkup or telebot.types.ReplyKeyboardMarkup or telebot.types.ReplyKeyboardRemove or telebot.types.ForceReply) – Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove reply keyboard or to force a reply from the user.

    Выделение моё.
    Т.е. вместо клавиатуры передаёшь специальный объект. А дальше тыкаешь по ссылке ForceReply и смотришь что это за объект и как его сконструировать.
    Ответ написан
  • Как запустить uvicorn не блокируя основной поток?

    Vindicar
    @Vindicar
    RTFM!
    Возможно, придётся заглянуть с другой стороны. uvicorn вроде позволяет запускать корутины при старте сервера? Оформи бота как корутину и используй этот механизм, чтобы uvicorn запускал бота, а не наоборот.
    Ответ написан
  • Создание переменных в тг боте аиограм?

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

    Vindicar
    @Vindicar
    RTFM!
    Во-первых, нужно чётко описать цепочку трафика. Вот первый вариант:
    [клиент] --> [решающий прокси] --> [реальный прокси] --> [целевой сайт]
                         \--> [другие сайты]

    Т.е. клиент всегда ходит через решающий прокси (тот, который принимает решение, как обращаться к сайту), а далее трафик идёт по одной из двух веток.
    Плюсы: у клиента фиксированная конфигурация, требуется только поддержка прокси, не требуется доп. ПО на кленте
    Минусы: решающий прокси тащит на себе весь трафик клиента.

    Если это недопустимо, т.е. тебе позарез нужно что-то такое:
    [клиент] --> [решающий прокси] --> [реальный прокси] --> [целевой сайт]
        \--> [другие сайты]

    То решение нужно принимать на стороне клиента. Тут есть два варианта.
    Вариант А: решающий прокси разворачивается на клиенте. Так работает nekoray, например.
    [клиент --> решающий прокси] --> [реальный прокси] --> [целевой сайт]
                         \--> [другие сайты]

    Плюсы: ПО на клиенте всё ещё требует только поддержку прокси, и всё.
    Минусы: на клиенте ставится доп. ПО, управление производится на машине клиента (неудобно если их несколько)

    Вариант Б, которым я сам пользуюсь: использовать PAC-файл. Он выполняется в контексте браузера и содержит логику на JS, которая определяет, как посылать каждый запрос. Разумеется, генератор и прокси могут быть на одном узле.
    [Генератор и хостинг для PAC-файла]
       ^
       |
    [клиентский браузер] --> [реальный прокси] --> [целевой сайт]
        \--> [другие сайты]

    Плюсы: на клиенте фиксированная конфигурация и нет доп. ПО. Все решения принимаются сервером, который периодиченки обновляет PAC-файл.
    Минусы: работает ТОЛЬКО с браузером, если прокси недоступен, браузер может начать пытаться слать запросы напрямую. Трудно повлиять на то, как часто клиент будет перезагружать PAC-файл.

    Вариант В: использовать маршрутизацию совместно VPN, чтобы завернуть все пакеты на целевые хосты в VPN, и только их.
    Плюсы: работает с любым ПО, даже если оно не умеет прокси.
    Минусы: Требует полноценный VPN с виртуальным сетевым адаптером, а не прокси. Определить подсети по имени сайта нетривиально, ибо CDN могут менять адреса без предупреждения. Раздавать 100500 маршрутов на клиенты тоже нетривиально.
    Ответ написан
    Комментировать
  • Бот перестает работать после определенного блока, как исправить?

    Vindicar
    @Vindicar
    RTFM!
    Ну так ты не озаботился изучением работы инлайн-кнопок, вот и результат.
    У тебя две функции отмечены декоратором
    @bot.callback_query_handler(func=lambda call: True)

    Эта проблема встречается регулярно, и на этом сайте уже есть несколько вопросов по ней.
    Вот один из них, с моим ответом.
    Ответ написан
    Комментировать
  • Как исправить ошибку "IndexError: list index out of range" для чат-бота телеграмм на библиотеке aiogram?

    Vindicar
    @Vindicar
    RTFM!
    А голову включить и код по шагам пройти не пробовал?
    dict_data_user = await state.get_data()
    list_data_user = []  # сначала список пуст
    for k, v in dict_data_user.items():  # начинаем цикл, первая итерация
        list_data_user.append(v)  # добавляем в список элемент. Длина списка равна 1.
        user_id = message.from_user.id
        id_product = list_data_user[0]  # читаем из списка элемент с индексом 0. ОК, он есть, мы его только что добавили
        full_name = list_data_user[1]  # откуда бы взяться элементу с индексом 1 в списке из одного элемента?!
        index_adress = list_data_user[2]
        number_phon = list_data_user[3]
        user_db.add_user(id_product=id_product, user_id=user_id, full_name=full_name,
                         index_adress=index_adress, number_phon=number_phon)
        await state.clear()

    Тут вопрос стоит, ты вообще понимаешь, что пишешь? Ты точно имел ввиду распаковку list_data_user, а не v или ещё чего-нибудь?
    Ответ написан
  • Как получать информацию о подарках в прямых эфирах TikTok?

    Vindicar
    @Vindicar
    RTFM!
    Вот трудно вбить в гугл "API tiktok gift"?
    Вторая же ссылка ведёт на гитхаб подходящей под описание библиотеки. А там и примеры есть...
    Вторая ссылка, Карл!
    Ответ написан
    1 комментарий
  • Как выводить значения row[0] в разные опции Select Menu?

    Vindicar
    @Vindicar
    RTFM!
    Ну так голову-то включи.
    for row in records:
        print("ник:", row[0])
        options=[
            discord.SelectOption(label=row[0])
         ]

    Ты options перезаписывашеь каждый раз, вместо того, чтобы создать этот список перед циклом, и добавлять в него элементы.
    Ответ написан
    Комментировать
  • Не могу решить задание ЕГЭ. Почему мой код не работает?

    Vindicar
    @Vindicar
    RTFM!
    Тебе выше правильно намекнули.
    Во-первых, нужно увидеть простую вещь: дописывание нуля в конец двоичного представления - это то же, что умножение на 2. Назовём это операция А. А дописывание единицы - то же, что умножение на 2 и прибавление 1. Назовём это операция Б. Таким образом, можно избавиться от двоичной системы в задании.

    Второе: операция А будет давать в результате только чётные числа, независимо от аргумента. Аналогично, операция Б будет давать только нечётные числа, независимо от аргумента.

    Третье: результат как операции А, так и операции Б всегда больше аргумента. Более того, больший аргумент даёт больший результат. Это легко показать.
    Пусть у нас есть число x. Результат операции A меньше, чем операции Б над тем же числом, поэтому мы должны проверить только один сценарий: когда к x применяется операция А, а к x - 1 - операция Б. Значит, x станет 2 * x, а x - 1 станет 2 * (x - 1) + 1 = 2 * x - 1. Т.е. для x - 1 результат меньше. Т.е. даже в таком, самом спорном случае, меньшее число даёт меньший результат

    Четвёртое: задачу можно решать задом наперёд. У нас есть целевые числа - значит, мы должны применить к ним алгоритм наоборот, чтобы получить исходные. Это и даст нам диапазон для поиска исходных чисел.

    Дальше уже проще. Смотрим на начало целевого диапазона, число 876 544. Оно чётное, значит, оно могло быть создано только операцией А. Значит, чтобы получить исходное число, нужно поделить его на 2. 876 544 / 2 = 438 272. Это число тоже чётное, оно тоже могло быть создано только операцией А. 438 272/ 2 = 219 136. Оно тоже чётное. Значит, третий раз применяем операцию А наоборот: 219 136 / 2 = 109 568. Исходя из пункта 3, можем сказать, что числа, меньше 109 568, не могут дать результат, больший или равный 876 544.

    Аналогично анализируем верхнюю границу целевого диапазона.
    1 234 567 899 = 2 * 617 283 949 + 1 (операция Б)
    617 283 949 = 2 * 308 641 974 + 1 (операция Б)
    308 641 974 = 2 * 154 320 987 (операция А)
    Значит, исходное число должно быть не более 154 320 987. Вот тебе и диапазон для поиска.
    А поскольку большие аргументы дают большие результаты, то это означает, что ни одно число меньше 154 320 987 не даст результат, который выйдет за верхнюю границу диапазона (1 234 567 899). Т.е. искомые числа - это весь диапазон от 109 568 до 154 320 987. Посчитать, сколько чисел в диапазоне, тривиально.
    Ответ написан
    Комментировать
  • Как организовать клиент-клиент соединение на python через socket?

    Vindicar
    @Vindicar
    RTFM!
    Почитай про разницу между потоковыми и датаграммными сокетами.
    В потоковых сокетах всегда есть клиент, устанавливающий подключение, и есть сервер, ожидающий подключение.
    Датаграммные сокеты в этом плане более одноранговы, хотя и там обычно есть узел, который первым проявляет инициативую.
    В любом случае, проблемы у тебя возникнут, когда оба узла находятся в разных сетях, за несколькими слоями NAT каждый. Имея публично доступный сервер, эту проблему решить куда проще.
    Ответ написан
    Комментировать