Задать вопрос
  • Не добавляется столбец в sqlite3, что делать(срочно, пожалуйста)?

    Vindicar
    @Vindicar
    RTFM!
    Что лежит в переменной channel_id? Это строка? Если это строка, она точно содержит только символы, допустимые для имени столбца? Ты это проверил, или понадеялся на авось?

    А вообще, если ты вынужден делать ALTER TABLE на ходу, у тебя большие проблемы с архитектурой БД. Дальше будет только хуже.
    Лучше опиши задачу, которую пытаешься решить (хотя я догадываюсь, что это очередной чудо-бот).
    Ответ написан
  • Как решить пример в Python, который находится как string в переменной?

    Vindicar
    @Vindicar
    RTFM!
    Тупой способ: использовать eval(), но это очень рискованно! Если данные приходят извни, атакующий может вписать туда почти любой питоновский код. Потом не плачь, что тебя не предупреждали.

    Умный способ, на примере (-5 * 3) - 2:
    1. Разбить строку на осмысленные токены : число, оператор и т.п. Для каждого токена хранить его тип и значение. Получим список в духе:
    [('parenthesis', '('), ('operator', '-'), ('number', '5'), ('operator', '*'), ('number', '3'), ('parenthesis', ')'), ('operator', '-'), ('number', '2') ]

    Тут ушли все пробелы.
    2. Подправить унарные операторы. Операторы "+" и "-", следующие за началом строки, открывающей скобкой или другим оператором, являются унарными (с одним аргументом), а не бинарными (с двумя). Их стоит обозначить по другому, чтобы не путать. Получим такое (смотри на второй токен):
    [('parenthesis', '('), ('operator', 'unary-'), ('number', '5'), ('operator', '*'), ('number', '3'), ('parenthesis', ')'), ('operator', '-'), ('number', '2') ]

    3. Преобразовать из инфиксной нотации (2 + 3) в постфиксную (2 3 +). Для этого есть железнодорожный алгоритм Дейкстры, он гуглится. В постфиксной нотации всё решается куда проще, так как ей не нужны скобки. Наш пример запишется как 5 unary- 3 * 2 -
    [('number', '5'), ('operator', 'unary-'), ('number', '3'), ('operator', '*'),  ('number', '2'), ('operator', '-')]

    4. Решить пример. Алгоритм очень простой. У нас есть список аргументов, поначалу он пуст. Идём по списку токенов (в постфиксной нотации):
    а. Если токен - число, поместить его в конец списка аргументов, перейти к следующему токену.
    б. Если токен - унарный оператор, взять и удалить последний элемент из списка, применить к этому элементу оператор, результат добавить в конец списка.
    в. Если токен - бинарный оператор, взять и удалить последние 2 элемента из списка, применить к ним оператор (не перепутай порядок аргументов!), результат добавить в конец списка.
    Всё! Когда токены кончатся, у тебя в списке аргументов должно быть ровно одно число - это и будет ответ.
    На нашем примере:
    [('number', '5'), ('operator', 'unary-'), ('number', '3'), ('operator', '*'),  ('number', '2'), ('operator', '-')]

    1. Число "5": список аргументов [ 5 ]
    2. Унарный минус: берем 5 из списка, применяем оператор, кладем результат назад. Список аргументов [ -5 ]
    3. Число "3": список аргументов [ -5, 3 ]
    4. Оператор *: берем -5 и 3 из списка, применяем оператор, кладём результат назад. Список аргументов [ -15 ]
    5. Число "2": список аргументов [ -15, 2 ]
    6. Бинарный минус: берем -15 и 2 из списка, применяем оператор, кладём результат назад. Список аргументов [ -17 ]
    Токены закончились, в списке одно число -17. Это ответ.
    Ответ написан
    Комментировать
  • Почему при использовании with open не добавляются в сравнение отрицательные числа?

    Vindicar
    @Vindicar
    RTFM!
    Ну во-первых, почему вначале read(1)? Это читает один символ, а не одну строку, так что если у тебя более 10 чисел в файле, работать будет некорректно.
    Во-вторых, isdigit() проверяет, что строка содержит только цифры. Знак "-" цифрой не является. Поэтому твой код такие строки игнорирует.
    Ответ написан
    3 комментария
  • Как сделать такой перебор через itertools на Python?

    Vindicar
    @Vindicar
    RTFM!
    Никак. Я бы решил по-другому.
    Рассматривай твою строку как число в N-рной системе счисления.
    Например, если среди символов строки могут быть только цифры 0-9 - это будут десятичные числа.
    Если будут a-z - то получим систему счисления с основанием 26.

    Тогда каждой строке можно будет соспоставить число - номер этой строки в списке всех возможных строк. В твоём случае "1111111111" соотвествует номер 0, "1111111112" - номер 1, и так далее.

    Соответственно, перебор строк будет сводиться к перебору всех чисел от 0 до числа возможных строк, с последующим переводом в выбранную "систему счисления". А остановка и возобновление перебора - сведётся к запоминанию текущего числа и выбору другой начальной позиции в следующий раз.

    Хотя можно и попытаться пропустить N первых строк в выхлопе product(), но это будет медленно, если нужно начать где-то в конце.
    Ответ написан
    Комментировать
  • Как получить другой элемент Literal?

    Vindicar
    @Vindicar
    RTFM!
    Литерал означает, что данная переменная/параметр всегда имеет одно из перечисленных значений. Так что...
    other_player_mark = 'cross' if mark == 'zero' else 'zero'

    Не, ты, конечно можешь извратиться...
    import typing as t
    
    Mark = t.Literal['cross', 'zero']
    
    class TicTacToePlayer:
        def __init__(self,
                     mark: Mark,
                     field: TicTacToeField
                     ):
            self.cells = []
            self.mark = mark
            self.field = field
        
        def opposite(self, mark: Mark) -> Mark:
            values = t.get_args(Mark)
            idx = values.index(mark)
            next_idx = int(not idx)
            return t.cast(Mark, values[next_idx])

    но лучше не надо!
    Ответ написан
  • Как разбить файл на несколько по буквам?

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

    Vindicar
    @Vindicar
    RTFM!
    recieved = await reader.read(2048)
    Ты читаешь 2КБ. И всё.
    Проблема в том, что размер пакета при передаче по сети ограничен. Хоть гигабайт отправь, приходить будет порциями. И вообще, отправитель (или промежуточное сетевое оборудование) может данные хоть по байту нарезать, ты это не контролируешь.
    Поэтому обязательно надо предусматривать какой-то способ определить конце передачи, и повторять чтение в цикле, поке конец не достигнут. Основных способов два.
    1. Передавать сначала размер данных в байтах (фиксированным размером - например, как 4байтовое целое), потом сами данные. Читаешь размер, разбираешь его в целое число, читаешь данные, пока не накопится желаемое число байт.
    2. После переданных данных передавать условную последовательность "конец передачи". Тогда читаешь данные, пока эта последовательность не встретится.
    У тебя данные бинарные, первый способ сработает лучше.
    Ответ написан
  • Как убрать скобки?

    Vindicar
    @Vindicar
    RTFM!
    1. Убрать list(). Обратиться по индексу 0 - bd[0].
    2. Почитать про списки и кортежи.
    Ответ написан
    Комментировать
  • Не запускается дискорд бот, что делать?

    Vindicar
    @Vindicar
    RTFM!
    Ну для начала неплохо бы прочитать документацию!
    client = discord.Client(intents=discord.Intents.default())
    bot = commands.Bot(command_prefix='/', intents=intents)

    Вот на кой тебе сразу и экземпляр Client, и экземпляр Bot, если Bot умеет всё, что умеет Client?
    При этом что ты запускаешь? Сразу же client.run(config.TOKEN)
    Т.е. до всего, что после этой строки выполнение вообще не доходит, так как run() уходит в вечный цикл работы бота.

    Убери всё, что связано с client. Если тебе так надо on_ready() - декорируй его через @bot.event.

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

    Vindicar
    @Vindicar
    RTFM!
    Технически - да, во втором быстрее.
    Но разница будет микросекундная. Обращение к словарю - быстрая операция, по сравнению даже с парсингом JSON, а он, в свою очередь - быстр по сравнению с сетью.
    Ответ написан
    2 комментария
  • Как запустить shell-комманду в новом процессе без блокировки потока?

    Vindicar
    @Vindicar
    RTFM!
    communicate() как раз и ждёт. Вместо этого ты можешь попробовать просто читать из proc.stdout.
    С асинхронностью сложнее, но ты можешь попробовать запустить функцию в потоке через loop.run_in_executor(). Это позволит завернуть поток в асинхронную задачу. Так как поток будет висеть в ожидании ввода-вывода, он не должен сильно влиять на GIL и мешать другим потокам.
    Ответ написан
    2 комментария
  • Бот на Telebot падает, когда отправляешь второй одинаковый запрос в БД sqllite. Как исправить?

    Vindicar
    @Vindicar
    RTFM!
    Если ты хочешь при любом действии пользователя убедиться, что он в базе, то тебе нужен не просто INSERT, а INSERT ON CONFLICT IGNORE или INSERT ON CONFLICT UPDATE. Если тебе требуется что-то обновлять (например, хранить для пользователя момент последнего обращения к боту), то нужен второй. Если не требуется, то лучше первый.
    Ответ написан
    Комментировать
  • Только начал свое знакомство с Python. Вроде бы код верный, но высвечивается ошибка. В чем может быть проблема?

    Vindicar
    @Vindicar
    RTFM!
    Во-первых, это неверно. map() принимает два аргумента: функцию, которую нужно применить, и коллекцию, к которой её применяем. Ты, к тому же, скобку не закрыл.
    a,b,n=map(float(input().split())
    Надо так:
    a,b,n=map(float, input().split() )

    Во-вторых, по-моему, у тебя кривой расчёт. ИМХО, проще всего рассчитать цену книги в копейках, а потом уже отталкиваться от этого.
    price_kop = 100 * a + b
    total_kop = price * n
    total_gr, total_kop = divmod(total_kop, 100)
    print(total_gr, total_kop)
    Ответ написан
    Комментировать
  • Как обработать закрытие консоли?

    Vindicar
    @Vindicar
    RTFM!
    Я также попробовал через signal.
    Видимо, на практике нереально. Спасибо винде.
    Ответ написан
    Комментировать
  • Как сменить язык речи в голосовом ассистенте?

    Vindicar
    @Vindicar
    RTFM!
    Гуглить пробовал? На первой странице выдачи этот ответ на StackOverflow.
    Если коротко:

    Зависит от установленных на компе голосовых движков. Проверь доступные движки так:
    import pyttsx3
    
    engine = pyttsx3.init()
    for voice in engine.getProperty('voices'):
        print(voice)

    Ищи голоса, у которых упомянут русский язык. Если нет - гугли, как их ставить.

    Определившись с голосом, пропиши его id в скрипте, например
    # тут id голоса, который ты выбрал
    voice_id = "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech\Voices\Tokens\MSTTS_V110_trTR_Tolga"
    engine = pyttsx3.init()
    engine.setProperty('voice', voice_id)
    Ответ написан
    Комментировать
  • Как отправлять много запросов get (python) чтобы не забанили на сайте?

    Vindicar
    @Vindicar
    RTFM!
    1. ХЗ. 100% зависит от сайта.
    2. Стараться обходиться минимумом запросов, отправлять их пореже, стараться лучше косить под обычного пользователя.
    Ответ написан
  • Нужно ли закрывать сессию при requests?

    Vindicar
    @Vindicar
    RTFM!
    1. Чем не устраивают обозначенные варианты? Если токен должен переживать перезапуск, храни его в конфигурации. Если не должен, храни его только в памяти - в глобальной переменной или в атрибуте класса.
    2. Конечно стоит. Просто для того, чтобы при истечении токена на полпути его можно было перезапросить прозрачно для клиентского кода. Например, декоратор вида:
    def requires_token(func):
        @functools.wraps(func)
        def wrapper(self, *args, **kwargs):  #оборачиваем метод, а не функцию
            try:
                result = func(self, *args, **kwargs)  # пробуем вызвать метод как есть
            except InvalidToken:  # кастомное исключение, которое должны выбрасывать методы
                self._acquire_new_token()  # получаем новый токен
                result = func(self, *args, **kwargs)  # пробуем еще раз
            return result
    
        return wrapper

    Тогда любой декорированный метод, который выбрасывает исключение InvalidToken, спровоцирует автоматический запрос нового токена и одну повторную попытку выполнения операции.
    Но можно делать это и явно, в каждом методе.
    3. Под закрытием сессии ты понимаешь инвалидацию токена, т.е. невозможность его дальнейшего использования? Ну так это тебя нужно спрашивать, нужно ли закрывать сессию и требует ли используемое API явного закрытия сессии. Планируешь ли ты выполнять дальнейшие операции в рамках этой сессии? Если точно нет, можешь закрывать - например, при выходе из скрипта. Заодно снимется вопрос о хранении токена. Если не хочешь дёргать получение токена понапрасну, тогда храни токен, но не закрывай.
    Делать это в КАЖДОМ методе точно бессмысленно.
    Ответ написан
    5 комментариев
  • Как визуализовать результат работы кластеризации?

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

    Vindicar
    @Vindicar
    RTFM!
    list(zip(sess, tasks)) должно сгенерить список пар "сессия, задача". Дальше уже с каждой парой работаешь.
    Ответ написан
  • NoneType: 'NoneType' object is not subscriptable. Как быть, где допустил ошибку?

    Vindicar
    @Vindicar
    RTFM!
    msg = event.object.message
    user_id = msg['from_id']

    Значит, msg - это None.
    1. Читай документацию на используемую библиотеку, в каких случаях это может быть
    2. Выполняй операции только если if msg is not None:
    Ответ написан
    Комментировать