• Как выполнить относительный импорт библиотеки в Python?

    @o5a
    Можно добавить путь верхнего уровня (project_catalog) к pythonpath, тогда можно будет использовать относительный импорт. Например так
    import os
    
    # выходим на верхний уровень
    parentdir = os.path.dirname(os.path.dirname(__file__))
    # и добавляем его к путям поиска
    os.sys.path.insert(0,parentdir)
    # после чего можем использовать импорт по вложенному пути
    import module_name.module.ModuleFileOne
    Ответ написан
    1 комментарий
  • Как вывести текст без ошибок в файл с помощью SpellChecker?

    @o5a
    Если все еще актуально, то можете сделать так.

    spell.candidates напрямую не предназначен для вывода текста, он возвращает только набор предполагаемых вариантов для каждого переданного на проверку слова, поэтому вывод его просто так в строку мало что даст.

    И spell.unknown возвращает только множество "некорректных" слов.
    Если цель вывести весь исправленный текст, то лучше использовать spell.correction, можно так:
    def save_file():
        filepath = filedialog.asksaveasfilename()
        if filepath != "":
            text = text_editor.get("1.0", END)
            with open(filepath, "w") as file:
                mistakes = spell.unknown(text.split())
                file.write("Ошибки: " + str(mistakes))
    
                # перебираем пословно и заменяем слово, если его считает некорректным
                result = []
                for word in text.split():
                    correct = spell.correction(word)
                    # берем просто изначальное слово, если корректор не нашел его в словаре
                    result.append(correct if correct else word)
    
                file.write("\n")
                file.write("Правильное написание: " + ' '.join(result))

    Если все-таки предполагалось выводить в файл не весь исправленный текст, а только ошибочные слова, то не сложно будет изменить, просто перебираете не по всему тексту, а по своему mistakes.
    Ответ написан
    Комментировать
  • Как хранить большие объёмы текста?

    @o5a
    База данных выглядит подходящим вариантом. Сможете хранить полностью свои тексты и обращаться к ним в любом нужном порядке. Даже простой встроенный в python sqlite подойдет, если не планируется совместный доступ к данным.

    В json тоже можно, но менее эффективно, т.к. каждый раз его придется полностью считывать, да и хранить большие объемы текста не совсем его предназначение.
    Ответ написан
  • Как создать правильно API запрос на Python?

    @o5a
    Ошибка в том, что вместо запятых в тексте должны быть &.
    Но лучше вообще вручную так строку не составлять. Для этого есть встроенная функция, которая сама конвертирует в строку, а заодно учтет и кодирование для спецсимволов и кириллицы.

    from urllib.parse import urlencode
    
    params = {
        "text":  'russia',
        "day": 1,
        "month": 1
    }
    
    param_str = urlencode(params)
    # формируем полную ссылку
    api_url = f'https://api.api-ninjas.com/v1/historicalevents?{param_str}'
    print(api_url) # https://api.api-ninjas.com/v1/historicalevents?text=russia&day=1&month=1
    Ответ написан
    3 комментария
  • Как сделать правильный цикл назначения одной сущности другой?

    @o5a
    Проблема в том, что строка с выгрузкой результата в файл, находится внутри цикла, поэтому в файл будут попадать данные каждой итерации цикла. Предполагалось видимо выгрузить только в конце, поэтому отступ изменить надо
    for book, user in zip(books, itertools.cycle(users)):
        user["books"].append(
            {
                "title": book["Title"],
                "author": book["Author"],
                "pages": book["Pages"],
                "genre": book["Genre"],
            }
        )
    json.dump(users, result_json, indent=4)
    Ответ написан
    Комментировать
  • Где у меня ошибка в sqlite3?

    @o5a
    order в SQL является ключевым словом. Поэтому лучше не использовать его в названиях таблиц, полей. На это и ругается.

    Если уж назвали, то заключайте в кавычки:
    return self.cursor.execute(f'INSERT INTO orders ("order", name, tg, number, amount, promo, date) VALUES (?, ?, ?, ?, ?, ?, ?)',
                                           [order, name, tg, number, amount, promo, date])
    Ответ написан
  • Как использовать команду через @?

    @o5a
    Можно без regexp обойтись, просто методами самого vkbottle.
    Вместо всего этого
    @bot.on.message(text=["Призми погладить", "Рп погладить", "[id{user_id}|Фурина]"])
    async def pat_user(message: Message):
        # Проверяем, было ли упоминание пользователя через @
        mentioned_user_id = None
        mentioned_users = re.findall(r'\[id(\d+)\|.*?\]', message.text)
        if mentioned_users:
            mentioned_user_id = mentioned_users[0]

    Просто напрямую прописать этот формат в хэндлере, и затем использовать найденные им значения в функции
    @bot.on.message(text=["Рп погладить [id<mentioned_user_id>|<mentioned_user_name>]", "Призми погладить", "Рп погладить"])
    async def pat_user(message: Message, mentioned_user_id=None, mentioned_user_name=None):
        mentioned_user_id ... # уже можно использовать напрямую
        # можно и само имя использовать, если вдруг пригодится mentioned_user_name

    Так должно работать для "Рп погладить [idxxx|кто-тотам]", для второго аналогично сделать.
    Ответ написан
    Комментировать
  • Как можно исправить код?

    @o5a
    Что именно значит "функцию не выполняет"? Вообще ничего не срабатывает (даже хэндлер), не добавляет бонус, неправильно добавляет бонус, не выводит сообщения, или не запускается именно функция timer_bonus_db? Вариантов же много, пишите конкретнее в вопросах.

    1. Лучше вообще никогда не использовать подстановку значений в запрос через форматирование, как сделано тут:
    sql.execute(f"SELECT timer_bonus FROM users WHERE telegram_id LIKE '%{telegram_id}%'")

    А всегда использовать через подстановку параметров (?), как Вы уже и делали в других местах
    cursor.execute('SELECT balance FROM users WHERE telegram_id = ?;', (telegram_id,))
    cursor.execute('UPDATE users SET balance = ? WHERE telegram_id = ?', (balance, telegram_id))


    2. После изменения данных (insert, update, delete) нужно делать commit. В основном коде вижу это делается, а вот в dp.py (timer_bonus_db) явно у вас не показано, возможно там забыли. Т.к. это отдельное соединение (судя по тому, что делаете через класс), то там и свой commit нужно не забывать делать. Если у вас в этом классе commit принудительно нигде не делается, то это скорее всего и есть причина неправильной работы вашей команды.

    3. Откуда взялось число 4356 в расчете?
    time_to_end /= 4356
    Время (текущее и из поля базы) у вас идет в секундах, затем для перевода в часы соответственно нужно делить на (60*60 = 3600).

    4. В timer_bonus_db достаете timer_bonus из запроса в виде кортежа и конвертируете в число:
    с = float(timer_bonus[0])
    Но затем при проверке все равно используете кортеж
    if timer_bonus != 0:
    Что неправильно, т.к. если даже вернет 0, то получится
    (0, ) != 0
    что тоже сработает
    Ответ написан
    Комментировать
  • Откуда эти 2 значения?

    @o5a
    В вопросе приводите все скрипты. В данном случае в коде не привели pop.py, который импортируете, не известно, что он у вас делает. Да и в целом приведенный код и результат вывода не соответствуют. Приводите как оно реально есть, чтобы не возникало недопониманий.

    Судя по результатам, pop.py возможно содержит что-то такое
    x = 101
    print(x)

    В таком случае результат был бы похож на приведенный.
    Соответственно первое значение 101 получается в момент вызова
    import pop
    при работе f2()
    т.к. импорт по сути запускает срабатывание всего, что написали в том скрипте, как если бы вы его запустили вручную. И результат 101 пришел из модуля

    А второе значение 100 уже получается как результат
    print(x)
    где x - глобальная переменная, которую выставили в это значение в f1.
    Ответ написан
  • Python requests.post игнорирует данные?

    @o5a
    Есть же документация к API, там четко написано, какие поля нужны
    https://payok.io/cabinet/documentation/doc_api_tra...
    Ответ написан
  • По какой причине excel ругается на файл с объединенными ячейками, сформированный с Python OpenPyXL?

    @o5a
    Проблема в этом:
    sheet.merge_cells(start_row=start_row_index + 1, start_column=1, end_row=row_index + 1, end_column=1)

    При каждом повторении текста в 1-й колонке (Подразделение) будет повторяться объединение ячеек от начальной (где начался повторяющийся текст) до каждой новой строки, т.е. куча наслаивающихся объединений A2:A3, A2:A4 и т.д.
    Это Excel и не нравится. Объединение ячеек должно быть одно на всю группу ячеек, т.е. скажем тут только A2:A14.

    Так что измените код, чтобы объединяло не по каждому совпадению, а по окончанию повторяющегося блока, одно объединение на каждый повторяющийся блок.

    Можете или свой вариант проверки повторения видоизменить (только чтобы объединяло не более 1 раза на каждый блок повторений), или же просто в самом конце уже после построения всех ячеек согласно повторяющимся данным применить объединения на каждую из групп, например так:
    from itertools import groupby
    
        # из текущего кода убираем все merge_cells, а затем уже после цикла for row_index in ...
        # проходимся по всем повторениям (используем группировку groupby)
        idx = 2
        for k, g in groupby(temp[1:], key = lambda x: x[0]):
            # количество повторяющихся значений
            cnt = len(list(g))
            if cnt > 1:
                sheet.merge_cells(start_row=idx, start_column=1, end_row=idx+cnt-1, end_column=1)
            idx += cnt
    Ответ написан
    1 комментарий
  • Создал код бота в дискорде с помощью ChatGPT почему бот не хочет отвечать на команду?

    @o5a
    Он вообще реагирует на эвент? Если даже не реагирует, значит все-таки не все права раздали.
    Если реагирует, но сообщение пустое, то это потому что
    intents.messages = True
    Чтобы читать сообщения не только в личке бота, но и любое на сервере, нужно вместо этого использовать
    intents.message_content = True
    и вместе с этим в настройке самого бота (в панели управления приложением-ботом в дискорде) проставить галку этой привилегии message content
    https://discord.com/developers/applications/id_при...
    Ответ написан
    Комментировать
  • Как правильно оформлять таблицы с переменным количеством строк в python docxtpl?

    @o5a
    В самом шаблоне docx можно использовать циклы. Внутри нарисованной таблицы добавить соответствующие тэги, начинается с {%tr/tc for ... %} и закрывается endfor (отдельно закрывается тэг строк и столбцов), тогда переданные данные будут множиться по строкам и столбцам:
    +---------------------------+---------+----------------+
    | {%tr for row in data %}   |         |                |
    +---------------------------+---------+----------------+
    | {%tc for col in row %}    | {{col}} | {%tc endfor %} |
    +---------------------------+---------+----------------+
    | {%tr endfor %}            |         |                |
    +---------------------------+---------+----------------+


    В псевдографике это только пример, в самом docx ее не нужно рисовать, нужно делать обычную таблицу.
    Ответ написан
    Комментировать
  • Ошибка json.decoder.JSONDecodeError: Extra data: line 6 column 3 (char 308), как её решить?

    @o5a
    Основная проблема здесь:
    with open('merged.json', 'a+', encoding='utf-8') as hml:
        d = json.load(hml)

    Пытаетесь открыть файл для добавления данных и одновременно считать из него.
    Когда файл открывается "a+", указатель помещается в самый конец файла. Поэтому при считывании из него последующим json.load(hml) данных просто не будет (даже если файл что-то и содержит, т.к. указатель в самом конце). Поэтому и возвращается эта ошибка, что json некорректный.
    Можно это поправить, если после открытия файла перемотать указатель в его начало, добавив перед json.load строку
    hml.seek(0)
    Но вообще в целом по структуре всего кода, лучше не пытаться с json файлами работать путем их дописывания.
    Лучше
    1. Сначала полностью считать исходный файл в свой список/словарь
    2. Сделать изменения/дополнения именно в этом списке
    3. В конце записать уже полные данные с нуля в файл .json
    Тогда и ошибок будет меньше, и не понадобится изобретать костыли в виде replace("]", "")
    Ответ написан
    1 комментарий
  • Почему openCV генерирует неоткрывающееся видео?

    @o5a
    with open("test.mp4", 'wb') as new_file:
        new_file.write(downloaded_file)
        send()

    У Вас send() вызывается внутри блока работы с файлом (with). Т.е. вы открыли файл на запись, записали в него информацию, но еще не закрыв, пытаетесь считать данные. Для send() этот файл еще пустой. Сначала закончите запись в файл, затем уже читайте из него:
    with open("test.mp4", 'wb') as new_file:
        new_file.write(downloaded_file)
    send()

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

    @o5a
    Если пытались исключить все символы из набора, то надо было их заключить в квадратные скобки.
    text = re.sub('[–—!"#$%&()*,-./:;<=>@[\\]^_`{|}~\t\n\xa0–\ufeff]', '', str(text))

    А в изначальном виде у вас написан не набор символов, а последовательный шаблон поиска.
    Лучше почитайте хотя бы основы регулярных выражений, поймете ошибку.
    Но помимо этого Вы что-то странное делаете: из списка формируете строку зачем-то str(text) и из нее удаляете символы. Вы не умеет работать со списками? Для чего это было нужно?
    Ответ написан
    Комментировать
  • Как временно хранить кэш в python?

    @o5a
    Больше похоже, что вам нужно использовать базу данных для хранения расчетов по каждому аккаунту.
    Кэш функций хорош тогда, когда используются повторные обращения с одинаковыми параметрами вызова. Насколько я понял по описанию, вам нужно другое.
    Ответ написан
    Комментировать
  • Как добавить изображение в DB Drowser SQLite и вывести через чат-бота?

    @o5a
    Для вставки данных напрямую почитайте про тип BLOB. Создаете таблицу с полем такого типа и напрямую можете писать в него двоичные данные из файла.

    Но ТГ может работать и со ссылками. Только для send_photo строкой может быть или id файла на серверах ТГ, или http-ссылка. Если же это строка с именем локального файла, то нужно его сначала прочитать (чтобы передать данные). Можно сделать так:
    # класс для загрузки файла
    from aiogram.types import InputFile
    ...
    # его и используем для загрузки нашего файла
    await bot.send_photo(message.chat.id, InputFile(text1))


    У библиотек есть подробная документация: https://docs.aiogram.dev/en/dev-3.x/api/methods/se...
    Ответ написан
    1 комментарий
  • Как загрузить данные в таблицу из csv в postgres с помощью python (psycopg2)?

    @o5a
    Как и написано в ошибке, 'copy' предназначено для чтения файла с сервера.
    Варианты:

    1. Закинуть этот файл CSV на сервер и запускать так.
    2. Использовать вместо этого '\copy', она позволяет читать локальный файл, но для этого на компьютере должен быть рабочий psql.exe. Т.е. вместо прямого коннекта через psycopg написать скрипт запуска \copy с использованием локального psql
    3. Просто самому читать этот CSV в скрипте и писать в таблицу напрямую, через execute/executemany
    Ответ написан
    Комментировать
  • Как работает это решение задачи с LeetCode?

    @o5a
    Я понимаю, как tail меняется и зачем это нужно, но как head становится без дублей - не понимаю.

    tail - последний обработанный (недублирующийся) узел
    current - текущий узел
    Когда переходим к новому узлу (присваивая его текущему), проверяем, а не совпадает ли он с предыдущим (по значению).
    Если совпадает, то текущий узел мы просто выкидываем из цепочки, как бы прицепляя выход предыдущего узла к входу последующего, в обход текущего, за счет:
    tail.next = current.next
    Таким образом после проверки 2-го узла (повтор значения 1) получится такая картина:
    63d8f2d68cb94688580440.png
    Надеюсь, так понятнее ;)

    P.S. а если вопрос именно в том, почему head при этом тоже изменился, то head это просто ссылка на сам список (список = его первый элемент). Мы действиями изменили линковку списка.
    Ответ написан
    Комментировать