• Почему проходят первые тесты, но не проходят вторые на Codewars?

    Vindicar
    @Vindicar
    RTFM!
    Тормозит, потому что ты брутфорсишь перебор простых чисел. Используй решето Эратосфена.
    Иными словами, тебе не нужно перебирать все числа меньшие N, чтобы найти делители - достаточно проверить все простые числа, меньшие или равные N/2. А так как ты находишь простые числа по возрастанию, то все эти числа ты уже знаешь.
    До кучи, 2 всегда простое, а вот другие чётные числа - нет. Можешь добавить 2 в список заранее, а цикл по i делать от 3 с шагом 2.

    Ну и да, не называй переменную list. Это сбивает с толку.
    Ответ написан
    Комментировать
  • Как из текстового файла достать строки в определённом диапазоне?

    Vindicar
    @Vindicar
    RTFM!
    Пропустить нужное число строк, прочитать нужное число строк.
    def read_lines_in_range(f, ifrom: int, ito: int) -> list[str]:
        f.seek(0)
        for i in range(ifrom):
            f.readline()
        return [f.readline() for i in range(ito-ifrom)]

    Единственное, позиция чтения в файле должна быть в начале файла. Так что файл надо либо закрыть и открыть, либо сделать f.seek(0).
    Ответ написан
    Комментировать
  • Как найти ближайшее меньшее к моему числу из заданных чисел?

    Vindicar
    @Vindicar
    RTFM!
    Так как у тебя степени двойки, то можно рассчитать математически.
    import math 
    z = float(input('Z = '))  # например, 10
    logz = math.log(z, 2)  # 10 находится между 2**3 и 2**4, так что logz будет 3 с копейками (но меньше 4)
    pwr = int(logz)  # отбрасываем дробную часть, получаем 3
    value = 2 ** pwr  # ближайшее меньшее значение - 2 ** 3

    Но для произвольных чисел это не сработает.
    Ответ написан
    Комментировать
  • Как сделать так, чтобы бот отвечал на команду start?

    Vindicar
    @Vindicar
    RTFM!
    Что за @bot.send_message? Здесь декоратору не место, тут нужен просто вызов функции.
    Ответ написан
    7 комментариев
  • Как распарсить строку (python)?

    Vindicar
    @Vindicar
    RTFM!
    shlex.split(), например?
    Ответ написан
    Комментировать
  • Как скачать музыку с Vk с помощю Python?

    Vindicar
    @Vindicar
    RTFM!
    youtube-dl?
    Оно не только YouTube умеет, а ещё много какие сайты. Есть командная строка, вроде был и питоновский интерфейс. Хотя можно тупо через subprocess запустить.
    Ответ написан
    Комментировать
  • Как убрать двойные кавычки при чтении CSV файла?

    Vindicar
    @Vindicar
    RTFM!
    Читаем доку.
    quoting: optional constant from csv module
    Defaults to csv.QUOTE_MINIMAL. If you have set a float_format then floats are converted to strings and thus csv.QUOTE_NONNUMERIC will treat them as non-numeric.

    Константы, которые можно использовать для контроля кавычек, описаны в доках на csv.
    Тот же параметр quoting есть и у read_csv()
    Ответ написан
    Комментировать
  • Как записать файл в папке?

    Vindicar
    @Vindicar
    RTFM!
    Ну тебе тут и насоветовали... Читай что такое относительный и абсолютный пути.
    C:\папка\user_file - это абсолютный путь.
    \папка\user_file - это относительный путь от корня текущего диска.
    папка\user_file - это относительный путь от текущей директории.
    Текущая директория (равно как и диск) может быть разной при запуске скрипта, может быть изменена в ходе работы скрипта, и не обязательно совпадает с директорией скрипта.
    Если тебя это устраивает, например, если ты пишешь программу для командной строки, которая принимает путь как параметр - то можешь использовать относительный путь.
    Если же ты хочешь обратиться к какому-то файлу с данными в каталоге скрипта - лучше сконструировать абсолютный путь. Не указать его явно (тогда придётся менять при перемещении скрипта в другую папку), а сконструировать. Например, так:
    import pathlib  # стандартный модуль питона. Очень советую его освоить!
    import sys
    # путь к папке скрипта, например, C:\myscript
    script_dir = pathlib.Path(sys.argv[0]).parent  
    # путь к файлу собирается из частей вот так
    user_file = script_dir / "some_folder" / "user_file"  # C:\myscript\some_folder\user_file
    # обрати внимание, мы не паримся по поводу того, что 
    # под виндой разделитель каталогов \, а под линуксом /
    # это уже забота pathlib
    with user_file.open('w+') as f:
        pass  # делаешь что тебе нужно с файлом
    # через функцию open() тоже сработает, метод open() просто для удобства
    with open(user_file, 'w+') as f:
        pass  # делаешь что тебе нужно с файлом

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

    Vindicar
    @Vindicar
    RTFM!
    Регулярное выражение вида
    GotoIfTime\((?P<from>\d+:\d+)-(?P<to>\d+:\d+),(?P<days>[a-z-]+),\*,\*\?open,s,1\)
    извлечёт из строки нужные части. Их можно будет вытащить так:
    regexp = re.compile(r'GotoIfTime\((?P<from>\d+:\d+)-(?P<to>\d+:\d+),(?P<days>[a-z-]+),\*,\*\?open,s,1\)', re.I)
    m = regexp.match('GotoIfTime(09:00-17:59,mon-fri,*,*?open,s,1)')
    if m:
        print(m.group('days'), m.group('from'), m.group('to'))

    Для работы с датами datetime ну и просто работа со строками. C днём недели можно будет справиться как-то так:
    now = datetime.datetime.now()
    weekday = now.weekday()
    days = m.group('days').lower()
    days_of_week = ['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun']  # datetime.datetime.weekday()
    if '-' in days:  # диапазон
        dfrom, _, dto = days.partition('-')
        dfrom, dto = days_of_week.index(dfrom), days_of_week.index(dto)
        if dfrom <= dto:  # обычный кейс, вроде mon-fri
            day_is_good = dfrom <= weekday <= dto
        else:  # на случае если нужно зацикливание вида fri-tue
            day_is_good = (weekday >= dfrom) or (weekday <= dto)
    else:  # один день, не диапазон
        dow = days_of_week.index(days)
        day_is_good = weekday == dow
    print(day_is_good)  # True или False


    С временем тоже несложно, разбиваешь через partition() по двоеточию, преобразуешь в целое, потом делаешь datetime.datetime.now().replace(hour=h, minute=m) и получаешь указанное время в текущий день.

    Таким образом у тебя будет два момента времени, один на базе from другой на базе to. Их можно просто сравнить с текущим: if from <= now <= to:
    Ответ написан
  • Как добавить кнопки в бота, через телеграм в Aiogram?

    Vindicar
    @Vindicar
    RTFM!
    Гипотетически можно, но практически тяжело. Объясню почему.

    Если ты хочешь добавить в бота новую функциональность, то это возможно при выполнении одного из двух условий:
    1. Новая функциональность по сути совпадает со старой, но работает с другими параметрами. Например, раньше парсили один сайт, теперь два. Пробелма в том, что для этого нужно заранее проектировать старую функциональность так, чтобы она была гибкой. Иными словами, если у тебя в коде намертво прописан путь, по которому нужно вытаскивать с сайта информацию, то без правки кода не получится ничего изменить. И даже если ты это предусмотришь, всё равно будут пределы этой гибкости.

    2. Ты можешь загрузить в бота код, реализующий новую функциональность. Для этого нужно будет:
    - разбить бота на изолированные компоненты, по типу Cogs из библиотеки discord.py.
    - предусмотреть механизм подгрузки файла с компонентом в бота "на ходу".
    - предусмотреть механизм выгрузки компонента из бота "на ходу", что намного сложнее. Это потребуется, если ты захочешь заменить компонент обновлённой версией, не перезапуская бота.
    - предусмотреть механизм, позволяющий тебе отдать боту файл с кодом, чтобы тот поместил этот файл к остальным компонентам.
    Это всё нетривиальные задачи, которые требуют очень хорошего понимания как Питона, так и устройства библиотеки aiogram. Собственно, беглый взгляд на доки показывает, что aiogram вообще не предусматривает удаления обработчиков событий. А это значит что единственный способ выгрузить функциональность из бота - это его перезапуск.
    Ответ написан
    Комментировать
  • Как сделать вывод определённого количества столбцов?

    Vindicar
    @Vindicar
    RTFM!
    Читай про операторы LIMIT и OFFSET у SQL-запроса.
    Если размер страницы N записей, то для выдачи страницы i тебе нужно будет задать OFFSET (i - 1) * N LIMIT N.
    Разумеется, нужно также задать порядок сортировки записей через ORDER BY.
    Ответ написан
    Комментировать
  • Как сделать чтобы программа ждала завершения bat-файла?

    Vindicar
    @Vindicar
    RTFM!
    Если дело в батнике, то можно запускать программу через start /wait program.exe
    Ответ написан
    Комментировать
  • Как создать клавиши с названиями из списка?

    Vindicar
    @Vindicar
    RTFM!
    async def choice_cat(message):
        CATs = cur.execute(f'SELECT name FROM cathlete WHERE id = "{message.from_user.id}"').fetchall()
        for fds in range(len(CATs)):
            astt = ReplyKeyboardMarkup(resize_keyboard=True).add(KeyboardButton(f"CATs[{fds}]"))


    Код, конечно, жесть. По пунктам:
    1. НИКОГДА не генерируй SQL запрос через форматирование строк. Легко словить ошибку, а если очень не повезёт - SQL-инъекцию. Используй подстановку параметров (ссылка для sqlite, если у тебя другая БД - ищи доки на неё).
    2. Как насчёт проверить, а вернула ли БД хоть что-то? Это не гарантируется. Всегда ожидай подставы.
    3. Зачем итерироваться по индексу списка, если ты индекс не используешь? Почему не итерироваться по самому списку? И да, это абсолютные основы питона, которые НАДО знать задолго до того, как браться за ботов.
    4. Зачем ты создаёшь новую клавиатуру на каждой итерации цикла? Тут уже даже не знания языка, тут простая логика. Создал клавиатуру, добавил кнопку - на следующей итерации выбросил старую клавиатуру, создал новую добавил другую кнопку. Ну бессмыслица же! Создай клавиатуру один раз, до цикла, и добавляй кнопки к ней.
    5. Ну тот факт, что ты не посылаешь сообщение, к которому будет прикреплена клавиатура (а сама по себе она не бывает!), это уже мелочи. Видимо, не дошёл ещё до этого этапа.

    kbd = ReplyKeyboardMarkup(resize_keyboard=True)
    btns = cur.execute(f'SELECT name FROM cathlete WHERE id = ?', (message.from_user.id,)).fetchall()
    # btns - список списков. 
    if not btns:
        # кнопки не предусмотрены, как-то даём пользователю знать об этом
        return  # если это фатально, останавливаемся тут
        # иначе создаём какое-то значение btns по умолчанию и  продолжаем
        # тут уж сам решай
    # делаем клавиатуру
    for btn in btns:
        kbd.add(KeyboardButton(btn[0]))
    # ну и отправляем её вместе с сообщением
    Ответ написан
    7 комментариев
  • Как сделать ограничения в бд?

    Vindicar
    @Vindicar
    RTFM!
    Если БД позволяет, можно сделать триггер на вставку записи, который не даёт вставить более 5.
    Но в твоём случае решение кодом будет понятнее, а потому предпочтительнее.
    Ответ написан
    Комментировать
  • Как сплитовать с aiohttp?

    Vindicar
    @Vindicar
    RTFM!
    1. Прочитать ответ из объекта ClientResponse, а не пытаться использовать его как есть.
    2. Для разбора URL на кусочки есть стандартный модуль urllib.parse
    Ответ написан
    Комментировать
  • Нужно спарсить номера телефонов, но они появляются полсе нажатии на кнопку, как их спарсить?

    Vindicar
    @Vindicar
    RTFM!
    а) разобраться, как сайт получает номер телефона, и повторить. Если номер подгружается отдельным запросом, выяснить каким, попробовать сделать запрос самому. Если номер спрятан в теле страницы, выяснить где, как он зашифрован, извлечь. расшифровать. Муторно, но требует меньше ресурсов.
    б) вместо requests использовать безголовый браузер (selenium), имитировать клик на кнопку, пусть сайт сам всё за нас сделает. Легче, но такие вещи прожорливы по памяти и CPU.
    Ответ написан
    1 комментарий
  • Как получить значение из словаря, не зная имени ключа?

    Vindicar
    @Vindicar
    RTFM!
    1. Сформулируй, по какому критерию определять нужное значение
    2. Перебирай значения в словаре, пока не найдешь соответствующее критерию
    Ответ написан
  • Как упростить мой код?

    Vindicar
    @Vindicar
    RTFM!
    Циклы. Помещай изображения и их высоты в отдельные списки, в конце итерируйся по этим спискам, чтобы собрать результат.
    Ответ написан
    2 комментария
  • Как автоматически запускать баш скрипт при включении пк?

    Vindicar
    @Vindicar
    RTFM!
    а) написать systemd unit
    б) написать init.d скрипт
    в) вроде крон умеет делать запуск с условием @reboot, но тут есть баги
    г) если включение = логин пользователя, то профиль-скрипт этого пользователя тоже подойдёт
    Ответ написан
    Комментировать
  • Как можно решить ошибку?

    Vindicar
    @Vindicar
    RTFM!
    Я же тебе уже говорил: если нет ответа на сообщение, то message.reply_to_message будет иметь значение None, и взять у него атрибут from_user не получится (о чём и говорит ошибка).
    Проверяй, что message.reply_to_message не None, если это не так, то думай - или подставляй какое-то другое значение, или просто сообщай об ошибке.
    Ответ написан