Задать вопрос
Ответы пользователя по тегу Python
  • Как реализовать систему добавления в список: смотрю, буду смотреть и т.д зарегистрированным пользователем?

    Vindicar
    @Vindicar
    RTFM!
    С точки зрения БД, просто связная таблица или несколько. Это же классическое отношение "многие ко многим".
    Есть таблица "Пользователи" с каким-то первичным ключом.
    Есть таблица "Аниме" с каким-то первичным ключом.
    Если делаешь отдельную связную таблицу на каждый тип списка (т.е. одна для "просмотрел" и одна для "буду смотреть"), то они будут иметь вид "ID пользователя, ID аниме", и эти же два поля будут составным первичным ключом. Наличие строки в таблице будет означать, что указанный пользователь внёс указанное аниме в список, соответствующий таблице.

    Либо можно сделать общую таблицу "Списки", тогда её вид будет немного иным - "ID пользователя, ID аниме, Тип списка". Если пользователь может поместить одно аниме только в один список, то ключ будет как выше, а если в несколько одновременно, то ключ будет все три поля.

    А уж как это сделать с точки зрения моделей, читай документацию. Это одна из самых базовых вещей, если что.
    Ответ написан
    4 комментария
  • Как сделать что бы хандлер срабатывал каждые 10 секунд, aiogram, python?

    Vindicar
    @Vindicar
    RTFM!
    Ну как-то так, только имей ввиду, что контроль над тем, кто может выполнять команды, остаётся на тебе.
    Бот либо опрашивает новости, либо нет, и сделать это индивидуально для разных пользователей будет сложнее.
    stop_polling_site = None  # контролирует, продолжаем мы проверять новости или нет
    
    async def get_news(message: types.Message):
      "Эта функция только проверяет и отправляет новости, она не является обработчиком событий"
      fresh_news = chek_news_update() # ты выполняешь сетевую операцию синхронно. Зачем?!
    
      if len(fresh_news) >= 1:
        for k, v in sorted(fresh_news.items()):
          news = f'{hcode(v["dates_id_print"])}\n' \
               f'{hlink(v["aubl_title"], v["aubl_url_split_print"])}'
          await message.answer(news)  # <<< не лучший способ отправлять сообщения в канал, но это твое дело.
          print('ok news')
      else:
        print('no')
    
    @dp.message_handler(commands='startnews')
    async def start_polling_news(message: types.Message):
      "Эта функция обрабатывает команду для начала опроса и реализует цикл опроса."
      global stop_polling_site
      if stop_polling_site is not None:
        await message.answer("Мы уже проверяем новости.")
        return
      stop_polling_site = asyncio.Event()
      while True:  # цикл опроса новостей
        try:
            # реализуем ожидание без остановки остального бота. Таймаут - сколько ждем в секундах.
            # такой подход используется вместо asyncio.sleep(), 
            # чтобы можно было в любой момент остановить опрос новостей.
            await asyncio.wait_for(stop_polling_site.wait(), timeout=600)
        except asyncio.TimeoutError:
            # дождались таймаута - работаем.
            try:
              await get_news(message)
            except:
              pass # была ошибка при получении новостей, думай сам что тут делать
        else:
            # таймаута не было - значит, поступила команда на остановку цикла
            break
      stop_polling_site = None
    
    @dp.message_handler(commands='stopnews')
    async def stop_polling_news(message: types.Message):
      "Эта функция обрабатывает команду для окончания опроса."
      global stop_polling_site
      if stop_polling_site is None:
        # цикл и так не работает
        await message.answer("Мы и так не проверяем новости.")
      else:
        # говорим остановить цикл
        stop_polling_site.set()
    Ответ написан
  • Загрузка файла с облачного хранилища?

    Vindicar
    @Vindicar
    RTFM!
    egor_u, ну вот и ответ. Если немножечко почитать документацию, то увидим, что метод .write() возвращает количество прочитанных байт.
    Я не знаю, что ты ожидал получить в переменной wb перед выполнением wb = openpyxl.load_workbook(wb), но это явно не оно.
    И вообще, load_workbook() ожидает получить на вход путь и имя открываемого файла.
    Ответ написан
    Комментировать
  • Актуально ли сейчас делать и продавать телеграмм ботов, написанных на Python?

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

    Vindicar
    @Vindicar
    RTFM!
    Ну самый лобовой способ - изменить файл-шаблон так (сокращено):
    class MainApp(App):
        def build(self):
            main_layout = FloatLayout()
            # INSERT CODE HERE
            return main_layout
     
    if __name__ == '__main__':
        app = MainApp()
        app.run()

    Тогда можно будет сделать просто
    with open('file.py', 'rt', encoding='utf-8') as src:
        data = src.read()
    with open('file2.py', 'wt', encoding='utf-8') as dest:
        dest.write(data.replace('# INSERT CODE HERE', 'тут твой код'))

    Разумеется, строка # INSERT CODE HERE не должна встречаться в других местах файла-шаблона.
    Также подразумевается, что файл-шаблон сам по себе, и не изменяется программно - вместо этого результат записывается в другой файл, который уже используется.
    Ответ написан
    6 комментариев
  • Как перенести бекс без \n в pdf?

    Vindicar
    @Vindicar
    RTFM!
    for i in range(0, len(text), 22):
        line = text[i:i+22]

    Ну и далее по тексту.
    Ответ написан
    1 комментарий
  • Как сделать что бы бот ожидал пока пользователь прикрепит файл, а потом сохранит его в discord.py?

    Vindicar
    @Vindicar
    RTFM!
    Отправленный файл - это ведь тоже сообщение, просто с прикреплённым аттачем. Почему бы не обрабатывать сообщения от пользователей и смотреть аттачи? Строго говоря, файл и команда могут вообще быть в одном сообщении, хотя это несколько менее удобно.
    А вообще ты встретился с необходимостью в машине состояний. В discord.py её вроде нет "из коробки", придётся самому реализовывать. Это не так сложно, просто нужно вести список или словарь пользователей, от которых мы ждём файл. При поступлении сообщения с файлом смотрим, есть ли отправитель в этом списке. Если есть, обрабатываем файл и убираем его оттуда, если нет - игнорируем сообщение.
    С таймаутом сложнее, но можно в списке хранить не id пользователя, а пары id-метка времени. Тогда можно будет понять, когда был послан запрос, и периодически удалять "старые" записи из списка.
    Ответ написан
  • Почему не обновляется текстовый виджет Tkinter?

    Vindicar
    @Vindicar
    RTFM!
    fan_gpu_info.after(1000, fan_gpu_info)
    Может, имелось ввиду это?
    fan_gpu_info.after(1000, fans_gpu)
    Ответ написан
    2 комментария
  • Как настроить голосование в боте дискорд?

    Vindicar
    @Vindicar
    RTFM!
    1. Оформи код как положено (</>)
    2. resactions = [reaction for reaction in message.reactions if reaction.emoji in ['✅', '❌']]

    Что тебе мешает адаптировать эту строку, чтобы считать реации отдельно?
    А то и проще, используй collections.Counter:
    from collections import Counter
    
    counts = Counter(reaction.emoji for reaction in message.reactions)
    if counts['✅'] > counts['❌']:
        KABOOM()
    Ответ написан
  • Как сделать вывод данных из базы данных в переменную python?

    Vindicar
    @Vindicar
    RTFM!
    В дополнение к написанному выше @Dr. Bacon, можно сделать так
    connect.row_factory = sqlite3.Row
    Тогда вместо простых кортежей будут возвращаться объекты, похожие на словари, и можно будет обращаться к полям по имени.
    cursor.execute("""SELECT OrderNumber FROM orders ORDER BY OrderNumber DESC LIMIT 1;""")
    row = cursor.fetchone()
    ID = row['OrderNumber']

    Единственное, смена row_factory затронет только курсоры, созданные позднее. Созданные ранее курсоры будут использовать предыдущую фабрику строк. Так что если хочешь это сделать, менять row_factory лучше сразу после открытия соединения.
    Ответ написан
    Комментировать
  • Какой вариант построения условий производительнее?

    Vindicar
    @Vindicar
    RTFM!
    Если у тебя не миллионы элементов в коллекции - разница вряд ли будет.
    А если так, то достаточно создать коллекцию один раз и переиспользовать её, а не делать это внутри if - и разницы не будет.
    Ответ написан
    Комментировать
  • Как вернуть результат работы декоратора?

    Vindicar
    @Vindicar
    RTFM!
    Ну для начала, что ты понимаешь под "результатом работы декоратора"?
    Результат работы декоратора - это функция, если что!
    Т.е. код
    @app.on_message(filters.text)
    def message(client, message):
        msg = message.text

    Практически эквивалентен коду
    decorator = app.on_message(filters.text)
    
    def message(client, message):
        msg = message.text
    # функция заменяется на результат работы декоратора - на ту же самую или другую функцию
    message = decorator(message)

    А уж что возвращает декоратор, а также что еще он делает с функцией - это его дело.

    Более того, в твоем случае я сильно подозреваю что функция message() не должна ничего возвращать. Если тебе нужно сохранить введённое сообщение, используй глобальные переменные.
    Ответ написан
    Комментировать
  • Как поставить таймер на функцию в дискорд боте?

    Vindicar
    @Vindicar
    RTFM!
    1. В документации есть пример.
    2. Тебе не нужен контекст (ctx), ты можешь получить объект канала просто по его ID. Через него же можно получить и приватный канал с юзером. Получив объект канала, можешь писать просто в него.
    Ответ написан
  • Как перебрать объекты и найти максимальное значение свойства у одного из объектов?

    Vindicar
    @Vindicar
    RTFM!
    winner = max(player1, player2, key=lambda p: p.scores)

    Параметр key задаёт функцию-ключ. Эта функция должна для каждого сравниваемого объекта вернуть его "вес", и max() тогда вернёт целый объект с наивысшим "весом".
    Но вообще твое решение тоже норм.
    Ответ написан
    1 комментарий
  • Непонятная ошибка KeyError, как исправить?

    Vindicar
    @Vindicar
    RTFM!
    queue_len = len(self.song_queue[ctx.guild.id])
    KeyError: 902227097647468664

    Число выглядит как id в дискорде. KeyError обычно случается, когда пытаешься обратиться к несуществующему ключу в словаре. В указанной строке кода есть кусочек, который выглядит как обращение к словарю: self.song_queue[ctx.guild.id]
    Вывод: в словаре self.song_queue нет ключа для того сервера (ctx.guild) с которого пришла команда боту. А вот почему его там нет, и почему нет логики, предусматривающей этот сценарий - это уже вопрос к вам.
    Ответ написан
    Комментировать
  • Как остановить зацикленную функцию телеграм бота(telebot)?

    Vindicar
    @Vindicar
    RTFM!
    В указанном виде - никак, бот, насколько я могу судить, однопоточный, и этот один поток будет занят циклом while True.
    Ответ написан
    Комментировать
  • Чем отличается результат отображения переменной через функцию print() от обрадения к ней напрямую?

    Vindicar
    @Vindicar
    RTFM!
    Некоторые среды разработки позволяют вывести содержимое переменной. Например, Jupyter или интерактивный интерпретатор питон. Но это не фича питона, это фича среды разработки. Упрощая, для каждого выражения среда выполняет примерно такой код:
    result = введённое_тобой_выражение
    if result is not None:
        print(repr(result))

    А вот способов преобразовать объект в строку в питоне и впрямь 2.
    str(some_object) должно давать человеко-читаемое представление.
    repr(some_object) должно (если можно) давать такое представление, которое описывает этот объект в синтаксисе питона.
    Наглядный пример - строки.
    print(str("foo\nbar")) напечатает
    foo
    bar

    Тогда как print(repr("foo\nbar")) напечатает
    "foo\nbar"

    Но для многих объектов нет ни толкового str(), ни толкового repr(), так что оба представления совпадают.
    Ответ написан
  • Питон не видит таблицу Sqlite, что делать?

    Vindicar
    @Vindicar
    RTFM!
    по видеоуроку ХаудиХо

    Ну собственно проблема уже в этом. Эти видяшки почти ничего не объясняют, а просто "делай как я". Нужно как следует учить язык, боты - не самая тривиальная вещь.

    А вообще galaxy выше прав. Вы указываете базу данных вот так: sqlite3.connect("Database.db")
    Если не помните, это то, что называется "относительный путь", который отсчитывается относительно текущего рабочего каталога. Проблема в том, что текущий рабочий каталог при запуске скрипта может быть разным - это совершенно необязательно каталог, где лежит скрипт (хотя часто может им быть). Факторов, влияющих на текущий рабочий каталог, очень много, и лучше на него не полагаться.
    Надежнее узнать полный путь до каталога скрипта, и использовать его для построения пути до рабочих файлов скрипта. Например, так:
    import sys
    import pathlib
    script_path = pathlib.Path(sys.argv[0]).parent  # абсолютный путь до каталога, где лежит скрипт
    conn = sqlite3.connect(script_path / "Database.db")  # формируем абсолютный путь до файла базы

    Вот после этого можно быть уверенным, к какой базе обращается бот.
    Ответ написан