Задать вопрос
Ответы пользователя по тегу Python
  • Каким образом изменяется id объектов внутри изменяемых типов данных?

    Vindicar
    @Vindicar
    RTFM!
    Первый сценарий: элемент списка хранил ссылку на одно число (экземпляр типа int), потом стал хранить ссылку на другое. Сам список при этом располагается по тому же адресу, что и раньше.
    Второй сценарий: то же самое, но с элементом словаря.
    Ответ написан
    Комментировать
  • Как перенести код с консольного питона на aiogram?

    Vindicar
    @Vindicar
    RTFM!
    1. Поучи, как работают асинхронная программа, и почему цикл вида
    while True:
        schedule.run_pending()

    парализует её работу.
    2. Портируй код с использованием асинхронного aioschedule.
    Ответ написан
    8 комментариев
  • Как ускорить функцию на пайтоне?

    Vindicar
    @Vindicar
    RTFM!
    while Adj[x,rand] != 1:
        rand = np.random.randint(0,nodes_length)


    Ну проблема вот в этом, ты скакать по массиву так можешь очень долго. Почему бы не составить список индексов r для который Adj[x, r] != r, а потом сделать random.choice() из него?
    Ну и далее, numpy массивы не предназначены для изменения своей длины, вот это твое chrom = np.append(chrom,rand) чётко показывает, что тебе нужен список. Если очень надо, преврати его в массив перед возвратом.
    Ответ написан
    Комментировать
  • Как создать алгоритм синтаксического анализа списка токенов?

    Vindicar
    @Vindicar
    RTFM!
    Ну для начала, ты неправильно ставишь цель. После синтаксического разбора у тебя будет не список, а древовидная структура данных, а итоговый код будет результатом обхода этой структуры в глубину.
    Так что читай про восходящий алгоритм. Идея у него простая. У тебя должен быть набор правил твоей грамматики, например:
    ЦИКЛ_WHILE = 'while' '(' ВЫРАЖЕНИЕ ')' ОПЕРАТОР
    Заглавными я записал нетерминальные символы - что-то, что раскрывается далее в последовательность токенов.
    Остальное - терминальные символы, т.е. токены.
    Итак, у тебя есть цепочка символов - терминальных или нетерминальных. Нетерминальные хранят в себе кусочек дерева программы, терминальные хранят в себе один токен.
    1. Перебираешь правила, ищешь правило, соответствующее текущей позиции в цепочке. Для начала цепочки это будет правило "программа в целом".
    2. Строишь узел дерева, соответствующий найденному правилу.
    3. Помещаешь в этот узел терминальные символы, входящие в правило. В примере выше это будут 'while' и '('. Сдвигаешь позицию в цепочке.
    4. Если в правиле дальше идёт нетерминальный символ, рекурсивно обрабатываешь цепочку по правилу для этого символа, начиная с текущей позиции. Когда обработка закончится, у тебя позиция в цепочке сместится на конец последовательности символов для этого нетерминала, и можно будет продолжить для следующего символа в правиле.
    5. Когда правило закончилось - возвращаешь полученное мини-дерево, чтобы вышележащий код его встроил в свой узел дерева.
    6. Если есть альтернативы, сохраняешь текущую позицию в цепочке и пробуешь альтернативы по очереди. Если альтернатива не сработала (правило тут не подходит), то возвращаешься к сохранённой позиции и пробуешь уже с другой альтернативой.
    7. Если в какой-то момент ни одно правило не подошло, или если мы получили неожиданный терминал, есть синтаксическая ошибка в коде.

    Это сравнительно легко реализуется через косвенную рекурсию. Т.е. у тебя в парсере будет много методов nfrjuj вида (псевдокод!):
    def parse_while_node(tokens: List[Token], pos: int) -> TreeNode, int:
        """Принимает список токенов и позицию в нём, возвращает мини-дерево и новую позицию в списке."""
        node = WhileNode() # узел дерева разбора, соответствующий циклу while
        assert tokens[pos].type == 'while'  # проверяем фиксированный токен, выкидываешь исключение если это не он
        pos += 1
        assert tokens[pos].type == '('
        pos += 1
        # обращаемся к другому правилу для разбора нетерминального символа ВЫРАЖЕНИЕ
        # сохраняем мини-дерево для выражения условия и обновляем позицию
        node.condition, pos = parse_expression_node(tokens, pos)
        assert tokens[pos].type == ')'
        pos += 1
        # аналогично парсим нетерминал ОПЕРАТОР
        node.body, pos = parse_operator_node(tokens, pos)
        # возвращаем вызвавшему нас коду наше минидерево с узлом while на вершине,
        # а также позицию где мы остановились
        return node, pos

    А для реализации правила вида
    ОПЕРАТОР = ПРИСВАИВАНИЕ | ВЕТВЛЕНИЕ | ЦИКЛ_WHILE
    можно будет сделать так:
    def parse_operator_node(tokens: List[Token], pos: int) -> TreeNode, int:
        variants = [parse_assignment_node, parse_if_node, parse_while_node]
        for variant in variants:
            try: # пробуем вариант из ветвления
                node, pos = variant(tokens, pos)
            except:
                pass # вариант не подошёл - пробуем другой
            else: # вариант подошёл
                return node, pos
        else: # ни один вариант не подошёл
            raise Exception()
    Ответ написан
    1 комментарий
  • Откуда цифра в конце вывода stdout?

    Vindicar
    @Vindicar
    RTFM!
    write() возвращает количество записанных символов/байт.
    В консоли питона, если введённое выражение вычислилось не в None, то полученный результат выводится.
    У тебя сначала выводится строка от вызова write(), а потом в консоли выводится возвращённое write() значение. Так как ты не вывел символ перевода строки, она сливается с выведенной строкой.
    Запиши код в файл и выполни его, и увидишь что цифра не появляется - потому что это поведение есть только интерактивной консоли.
    Ответ написан
    Комментировать
  • Что делать если при попытке выдачи роли через бота дискорд появляется ошибка?

    Vindicar
    @Vindicar
    RTFM!
    Что делать? Открыть глаза, прочитать ошибку, понять ошибку. Мыслить логически.
    await req(guild_id, user_id, role.id, reason=reason)
    AttributeError: 'NoneType' object has no attribute 'id'

    "У None нет атрибута id". Т.е. вместо некоего объекта с атрибутом id передали None.
    Смотрим на строку кода и ищем обращение к атрибуту id. Это role.id, т.е. вместо параметра роли в метод передали None.
    Смотрим выше, пока не найдём ссылку на строку не из discord.py.
    await author.add_roles(role)
    Т.е. твоя переменная role имеет значение None.
    Ищем эту строку в коде, потом смотрим выше откуда взялось role.
    role = guild.get_role(940997266100064316)
    Смотрим документацию на get_role().
    Returns the role or None if not found.

    Т.е. role может содержать None, если переданный id не соответствует роли в этом сервере.
    Вот тебе и ответ. Перепроверь id, который ты передаёшь в get_role().
    Ответ написан
    Комментировать
  • Как исправить ошибку с выдачей роли в дискорд боте пайтон?

    Vindicar
    @Vindicar
    RTFM!
    что еще за self.get_guild(), и почему нельзя взять guild из ctx?
    Сейчас discord.py ожидает, что self будет передана как параметр при вызвое команды пользователем.
    Ответ написан
    Комментировать
  • Как боту дискорд подсчитать слова в сообщении Python?

    Vindicar
    @Vindicar
    RTFM!
    Почитай про параметры команд в discord.py, она уже реализует и разбиение на слова, и отключение этой механики.
    Если хочешь разбивать на слова сам, то строковый метод split() тебе в помощь. Получишь список слов.
    Ну а количество... как длину списка найти, знаешь, я надеюсь?
    Ответ написан
    Комментировать
  • Как дать понять питону, что если строка является 'null', то ее пробивать нельзя?

    Vindicar
    @Vindicar
    RTFM!
    До чего изобретателен может быть человек, не понимающий что он делает!
    Ключевое слово: кортеж.
    await cur.execute(sql, (id))
    (id) - это то же самое, что id.
    А вот (id,) - это уже кортеж из одного элемента.
    execute() как раз и ожидает вторым параметром кортеж, или иную коллекцию, где один элемент - это одно подставляемое значение.

    Этот метод необходим для удаления скобок, которые ставит pymysql при обычном fetchone

    "Скобки", как ты выразился - это потому что fetchone() возвращает кортеж, по одному элементу на значение в строке (ну или None если очередной строки нет). Т.е. для каждого пункта между SELECT и FROM будет один элемент в кортеже, в том же порядке. Ты запрашиваешь только teleid, поэтому получаешь кортеж из одного элемента.
    Получить этот элемент можно, обратившись по индексу 0.
    row = await cur.fetchone()
    if row is not None: #есть хоть одна строка?
        teleid = row[0]
        # дальше делаешь что хочешь с teleid
    else: # нет такой строки
        print('Беда')

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

    Vindicar
    @Vindicar
    RTFM!
    Проверить, что name не содержит символ перевода строки.
    Ответ написан
  • Aiogram: Как сохранить введенные данные пользователя?

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

    А вот где хранить данные - вопрос реализации. Можно сделать словарь вида "ID пользователя - набор данных", можно сделать БД. Принцип это не меняет.
    Ответ написан
    Комментировать
  • Где перечислено это, что используется в хендлере?

    Vindicar
    @Vindicar
    RTFM!
    1. По приведённой ссылке описывается API запросов Телеграма, а не API для питон кода. Используй одну из библиотек, вроде pyTelegramBotAPI или aiogram. У первого доки получше, вроде.
    2. Если используешь aiogram, то в асинхронность вникать придётся. pyTelegramBotAPI использует синхронный код. В чём-то это будет проще, в чём-то - сложнее.
    Ответ написан
  • Как вычесть результат функции из результата другой функции?

    Vindicar
    @Vindicar
    RTFM!
    Ну во-первых тебе стоит поучить питон на более простых вещах, а потом уже браться за GUI.
    Во-вторых, пусть твои функции помещают результат своего расчёта в глобальную переменную, каждая в свою. Сейчас они записывают его текстом в интерфейс, а как число не сохраняют нигде.
    Ответ написан
    Комментировать
  • Нужна помощь с sqlite3, discord.py?

    Vindicar
    @Vindicar
    RTFM!
    В коде неправильного больше чем правильного...
    1. У тебя написано, что команда должна получить два параметра - text и id. Если id она должна найти сама, то его нужно убрать из параметров купить(). id нужно получить из ctx.author.id.
    2. Ты вообще пробовал обращаться к своей базе? Смотрел, что тебе возвращает fetchone()?
    По твоему запросу она вернёт либо кортеж с одним значением, либо None, если не было найдено ни одной подходящей строки.
    Ни то ни другое сравнивать непосредственно нельзя!
    Вытащи результат в переменные, проверь на None, а потом уже сравнивай нулевые элементы.
    3. Убери токен бота из тела вопроса.
    4. Советую cursor создавать внутри обработчика, во избежание заморочек с одновременным использованием.
    5. Советую указывать типы параметров в описании команды! discord.py обращает на них внимание, и пытается конвертировать входную строку.
    async def купить(ctx, text: str):
    6. Как уже было написано, execute() принимает вторым параметром КОРТЕЖ, пусть даже из одного элемента. А кортеж из одного элемента пишется как (item,).
    Ответ написан
  • Как заменить определенную строку на другую в файле формата .docx?

    Vindicar
    @Vindicar
    RTFM!
    В незнании питона, разумеется.
    В Питоне переменная - это не более чем ссылка на объект. Соответственно, если ты присвоил переменной ссылку на другой объект - от этого первый объект не изменится.
    for para in paras: # имя para указывает на объект - элемент списка doc.paragraphs
            para = para.text.split(' ') # имя para указывает на список строк, старая ссылка потеряна.
            for word in para: # имя word указывает на элемент из списка - строку
                //'NAME,' - строка в исходном файле
                if word == 'NAME,':
                    word = name + ',' # имя word теперь указывает на другую строку. Список от этого не изменился.
            para = ' '.join(para) # имя para теперь указывает на строку, ссылка на список потеряна
            # а список doc.paragraphs от присваивания выше тоже никак не изменится,
            # так как он ничего не знает об операциях с para.text

    Попробуй присвоить что-нибудь para.text, для начала. И не переиспользуй имена переменных, тебя что, платить заставляют за каждое имя?
    Ну и не приведён код, который сохранит изменённый документ в файл.
    Ответ написан
  • Почему не работает Schedule python?

    Vindicar
    @Vindicar
    RTFM!
    schedule.every(4).hours.do(First_script())
    Вызвать подпрограмму First_script() НЕМЕДЛЕННО, её возвращаемое значение интерпретировать как адрес функции, вызываемой каждые 4 часа.

    schedule.every(4).hours.do(First_script)
    Взять адрес подпрограммы First_script() и запланировать её вызов каждые 4 часа.
    Ответ написан
    Комментировать
  • Как исправить ошибку с одновременными запросами в aiogram?

    Vindicar
    @Vindicar
    RTFM!
    1. Первый пользователь посылает сообщение. Запускается копия search_vk() и выполняет синхронный запрос:
    user_data = vk_parser.get_user_data(user_id)
    Пока запрос выполняется, бот стоит, так как код синхронный.
    2. get_user_data() деляет глупости вида
    with open("FIO.txt", "w") as file: #открываем один и тот же файл для любого запроса

    или
    global bio # используем одну и ту же переменную для любого запроса

    Ну и прочие медиа-файлы тоже одни и те же для разных запросов.
    3. Обработчик сообщения первого пользователя доходит до строки
    loading = await message.answer('<b>Идёт поиск</b>')

    Так как это await-вызов, планируется вызов корутины, и асинхронная программа переходит к следующей доступной операции, пока выполняется отправка сообщения. Собранные данные лежат в файлах.
    4. Второй пользователь посылает сообщение. Запускается ещё одна копия search_vk() и тоже выполняет синхронный запрос get_user_data(). Второй вызов get_user_data() перезаписывает данные в файлах.
    5. Обработчик сообщения второго пользователя доходит до строки
    loading = await message.answer('<b>Идёт поиск</b>')

    и засыпает, пока сообщение отправляется.
    6. Тем временем сообщение первого пользователя отправилось. Обработчик получает управление, и отправляет содержимое файлов - которое было перезаписано, заодно закрывая их.
    7. Сообщение второго пользователя отправилось. Его копия search_vk() пытается отправить файлы, но первый обработчик их уже закрыл.
    Дело ещё осложняется сетевым лагом, так что трудно сказать, кто в итоге будет первым.

    Если по прочтению ты ещё не понял, в чём дело, скажу прямо: не используй глобальные объекты, будь то файлы или переменные, в конкурентной среде! Убедись, что каждая копия обработчика запроса имеет свои хранилища для данных! Локальные переменные безопасны, они создаются каждый раз заново. Если не можешь обойтись без файлов на диске, либо используй модуль tempfile, либо привяжи их имена к ID отправителя сообщения, чтобы хотя бы разные пользователи не сталкивались лбами.
    Ответ написан
    Комментировать
  • IndexError: list index out of range.Как решить?

    Vindicar
    @Vindicar
    RTFM!
    В файле есть строка, в которой нет символа ":". Например, пустая строка (возможно в конце файла).
    Ответ написан
  • Не могу понять суть ошибки: TypeError: on_startup() missing 1 required positional argument: 'message'?

    Vindicar
    @Vindicar
    RTFM!
    on_startup(_)
    Ты говоришь, что функция on_startup() ожидает 1 параметр (по имени _).
    Очевидно, она вызывается без параметров.
    Или в какой момент возникает ошибка? Есть ли декораторы на этой функции?
    Ответ написан