Задать вопрос
Ответы пользователя по тегу Python
  • Как сделать вывод данных из базы данных в переменную 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")  # формируем абсолютный путь до файла базы

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

    Vindicar
    @Vindicar
    RTFM!
    Zakkaru, чтобы бот сохранял состояние переменной afk_users в json файл? Ну так бы и сказал.
    Ну тогда у тебя много ерунды написано... ну вот хотя бы тут.
    with open('afk_users.json', 'w', encoding='utf-8') as file:
        file.write(json.dumps(afk_users, indent=4, ensure_ascii=False))
        file.close()

    Во-первых, оператор with сам вызовет file.close() по окончанию.
    Во-вторых, можно было сделать проще - json.dump(afk_users, file, indent=4, ensure_ascii=False). Обрати внимание, не dumps(), а dump().
    with open('afk_users.json', 'w', encoding='utf-8') as file:
        json.dump(afk_users, file, indent=4, ensure_ascii=False))

    В-третьих, почему ты сохраняешь состояние переменной afk_users, а потом тут же её изменяешь? Может, всё-таки в обратном порядке?
    В-четвёртых, где у тебя загрузка состояния afk_users из файла? Она должна производиться при запуске бота, например внутри on_ready.
    Ответ написан
    Комментировать
  • Python Telegram bot: Как убить поток при любом исключении в основной части?

    Vindicar
    @Vindicar
    RTFM!
    Просто сделай поток демоном через параметр в threading.Thread.
    If not None, daemon parameter explicitly sets whether the thread is daemonic. If None (the default), the daemonic property is inherited from the current thread.

    Это поможет вот почему:

    daemon
    A boolean value indicating whether this thread is a daemon thread (True) or not (False). This must be set before start() is called, otherwise RuntimeError is raised. Its initial value is inherited from the creating thread; the main thread is not a daemon thread and therefore all threads created in the main thread default to daemon = False.
    The entire Python program exits when no alive non-daemon threads are left.

    Выделение моё.

    Ну а если у тебя есть неподконтрольные тебе недемонические потоки, то тогда придётся заворачивать основного бота в try catch. И да, то что "бот разбит на файлы с классами и методами" абсолютно ничего не меняет. Если бот синхронный, у него есть точка входа, где ты запускаешь его работу, и любое непойманное исключение в этом потоке всплывёт только там. Если бот асинхронный, то нужно реагировать на непойманные исключения в корутинах - читай доки на asyncio как это сделать.
    Ну и оптимальное решение - разобраться уже, где всплывает исключение, понять его причину, и исправить.
    Ответ написан
    Комментировать
  • Библиотека telebot Python?

    Vindicar
    @Vindicar
    RTFM!
    Их две. Одна так и называется, telebot.
    Другая называется pyTelegramBotAPI, но подключается как import telebot, и она куда популярнее.
    Ответ написан
    Комментировать
  • Возможно ли вызвать функцию, если есть только ее наименование в строковом виде?

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

    Если же эти функции все входят в один модуль, или являются методами одного объекта (обозначим владельца функций как obj), то можно сделать и так:
    func = getattr(obj, 'funcname')
    func()

    Наконец, и я бы посоветовал именно так, тебе никто не запрещает сделать самому словарь вида:
    accepted_funcs = { 'func1': func1, 'func2': func2 }
    Тогда ты просто вызываешь accepted_funcs['funcname'](). Этот способ позволяет гарантировать, что неожиданный внешний ввод не приведет к вызову какой-то неожиданной посторонней функции. Любое имя функции, не входящей в словарь, спровоцирует исключение.
    Ответ написан
    1 комментарий
  • Какие инструменты можно использовать для сравнения животных на картинках?

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

    Vindicar
    @Vindicar
    RTFM!
    Почитай про AJAX запросы.
    Проще всего будет написать JavaScript, который будет по завершению ввода строки (ну или по другому событию) делать маленький фоновый HTTP-запрос на сервер. Фоновый в том смысле что страница не будет перезагружаться, и пользователь сможет продолжить работу.
    А на сервере отдельный маршрут примет данные, запишет их куда надо, а скрипту ответит только получилось или нет.
    Ответ написан
    Комментировать
  • Как взять из массива все значения ключа?

    Vindicar
    @Vindicar
    RTFM!
    У тебя всегда в верхнем уровне массива один элемент?
    Ну так просто перебирай элементы в mas[0]['d']['x'].
    Если не всегда, то используй тот же цикл по z.
    Ответ написан
    Комментировать
  • Как переносить текст input() при ограничении количества букв?

    Vindicar
    @Vindicar
    RTFM!
    input() не предназначен для таких вещей.
    Тебе придётся или имитировать ввод вручную, или использовать модули для продвинутого консольного интерфейса типа curses (под винду нужно будет поставить пакет windows-curses).
    Ответ написан
    Комментировать
  • Как удалить символ из словаря?

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


    Теперь скажи, в контексте вышесказанного - что значит "удалить символ подчеркивания"? Удалить откуда?
    Я предполагаю, что из значений в словарях внутри списка в ключе data для каждого словаря в твоем списке?
    Ну вот собственно эту фразу достаточно перевести на питон (от конца к началу), чтобы получить ответ.
    # этот код изменит твой массив "на месте", а не создаст изменённую копию!
    for mas_item in mas: # для каждого словаря в твоем списке
        for data_dict in mas_item['data']: # для каждого словаря в списке по ключу data 
            # словари не любят, когда их модифицируют и проходятся по ним for'ом одновременно
            data_dict_keys = list(data_dict.keys()) # так что заранее составляем список ключей словаря
            for key in data_dict_keys: # проходимся по этим ключам
                data_dict[key] = data_dict[key].replace('_', '') # и обрабатываем значения по этим ключам

    Как-то так. Чем тебе это подчеркивание помешало, без понятия.
    Ответ написан
    1 комментарий
  • Как отследить пользователей телеграм бота, написанного на python и где взять их Id?

    Vindicar
    @Vindicar
    RTFM!
    Выше уже ответили, что нужно регистрировать пользователей самостоятельно. Я опишу один из способов, как это сделать.
    Я предполагаю, что используется СУБД Sqlite, хотя это можно адаптировать и к другим.
    Нам потребуется таблица пользователей примерно такого вида:
    import time
    import sqlite
    
    connection = sqlite3.connect('bot.db')
    cursor = connection.cursor()
    cursor.execute("""CREATE TABLE IF NOT EXISTS users ( -- всё что после -- комментарий SQL
        id TEXT PRIMARY KEY, -- идентификатор пользователя, он же первичный ключ таблицы
        first_use REAL, -- метка времени, когда пользователь впервые обратился к боту
        last_use REAL -- метка времени, когда пользователь последний раз обратился к боту
    )""")
    cursor.close()

    То, что мы сделали id первичным ключом, гарантирует, что одному пользователю будет соответствовать только одна строка таблицы.
    Тогда перед выполнением каждой команды нужно обновить эту таблицу - добавить строку, если её нет, или обновить поле last_use, если она есть. К счастью, существует синтаксис, позволяющий сделать это за один запрос.
    def ensure_user_stats(user_id):
        "Эта функция обновляет таблицу users, и должна вызываться в начале обработки каждой команды."
        global connection
        cursor = connection.cursor()
        now = time.time()
        # пытаемся добавить строку с указанным id, и фиксируем текущее время в полях first_use и last_use 
        # если возникает конфликт в поле id (такое id уже есть),
        # то мы обновляем в этой записи поле last_use на текущее время, а остальное не трогаем
        cursor.execute("""INSERT INTO users (id, first_use, last_use) VALUES (?, ?, ?)
        ON CONFLICT (id) DO UPDATE SET last_use = excluded.last_use""", (user_id, now, now))
        cursor.close()
    Ответ написан
    Комментировать