• Как лучше обзавестись self-hosted почтой?

    Vindicar
    @Vindicar
    RTFM!
    Голый почтовый сервер, умеющий только SMTP - не проблема, протокол-то текстовый, как HTTP. Насчёт IMAP не знаю.
    Проблема - сделать так, чтобы письма с твоего сервера не летели в /dev/spam автоматом у всех получателей.
    Вот для этого потребуется конкретно обмазать это всё всякими подписями, сертификатами, и так далее.
    Я даже точный список привести затрудняюсь...
    Ответ написан
    2 комментария
  • Как правильно настроить работу процессов и как можно оптимизировать код?

    Vindicar
    @Vindicar
    RTFM!
    from multiprocessing import Pool
    
    def concatenate(video1: str, video2: str, output: str) -> bool:
        """Склеивает два видео и пишет результат в файл output.
        Не стоит использовать глобальные объекты. 
        Стоит принимать как параметры и возвращать только базовые типы данных 
        (булевы, числа, строки, кортежи, списки, словари)."""
        ...   # верни True при успехе, False при неудаче. Лови все исключения.
    
    if __name__ == '__main__':
        videos_to_process = [  # этот список формируешь по своей логике.
            ('18_05_video1.avi', '18_05_video2.avi', r'output\18_05.avi'),  # порядок как у аргументов concatenate()
            ('17_05_video1.avi', '17_05_video2.avi', r'output\17_05.avi'),
        ]
        with Pool() as pool:  # по умолчанию пул создаст по одному процессу на ядро
            results = pool.starmap(concatenate, videos_to_process)
        if not all(results):  # хотя одна функция вернула False?
            for (v1, v2, vr), success in zip(videos_to_process, results):
                if not success:  # выясняем, которая
                    print(f'Video merge failed: {v1} + {v2} -> {vr}')
        else:
            print('All videos merged successfully.')
    Ответ написан
    Комментировать
  • Почему возникает ошибка в Python?

    Vindicar
    @Vindicar
    RTFM!
    Как выше правильно заметили, предупреждение просто сообщает, что утилита pip для установки пакетов имеет не самую новую версию. Чаще всего это не проблема.

    Косяк в основной программе, потому что ты потерял подчеркивания вокруг __name__. Неплохо бы знать, что это и зачем это нужно - тогда не будете совершать таких ошибок.

    Ну и да: боты - это ни разу не просто. Очень не советую начинать с этого.
    Ответ написан
    Комментировать
  • Selenium постоянно крашит из за того что якобы нету таких координат в видомости браузера?

    Vindicar
    @Vindicar
    RTFM!
    Окно открыто у меня на максимум(1920,1080).


    actions.move_by_offset(1088, 1205).perform()
    Ответ написан
  • Как устранить ошибку на библиотеке disnake?

    Vindicar
    @Vindicar
    RTFM!
    bot={  # <<< bot? 
    "yes": "Да",
    "no": "Нет"}

    Как обычно, ответ - включить голову и посмотреть на код внимательно.
    У тебя был объект бота в переменной bot - но ты его переопределил на словарь. Разумеется, после этого у тебя bot содержит словарь, и методы бота больше недоступны.
    Придумай переменной другое, незанятое имя, чтобы не было таких ситуаций.
    Ответ написан
    Комментировать
  • Как отправить сообщение в указанное время с помощью isoweekday из библиотеки datetime?

    Vindicar
    @Vindicar
    RTFM!
    dt_string = now.strftime("%d/%m/%Y %H:%M:%S")   # метка времени вида дд/мм/гггг чч:мм:сс
    if (dt_string == "19:04:00") and x == 6:  # ВНЕЗАПНО метка времени вида чч:мм:сс, дата куда-то пропала

    Что ты ожидал-то? =)

    А вообще, aioschedule в помощь, если у тебя будет несколько таких напоминашек.
    Там достаточно один раз наладить запуск рабочего цикла aioschedule, и дальше просто планировать что делать.
    Ответ написан
    7 комментариев
  • Pycord. Выдаёт ошибку при просьбе вывода всех забаненных участников, как исправить?

    Vindicar
    @Vindicar
    RTFM!
    Если осилить документацию, станет видно, что bans() возвращает не обычный, а асинхронный итератор. А потому перебирать его надо не через for, а через async for. Тащем-та, в документации по ссылке и пример есть, как это делается.
    Ответ написан
    Комментировать
  • Почему возникает ошибка TypeError: 'Item' object is not iterable?

    Vindicar
    @Vindicar
    RTFM!
    У тебя get_category_item() возвращает только один предмет из категории, а ты думаешь, что она возвращает коллекцию предметов. Хотя ты сам делаешь scalar.
    Ответ написан
    Комментировать
  • Телеграм бот перестает работать, пишет ошибка в базе данных. Где ошибка?

    Vindicar
    @Vindicar
    RTFM!
    Включи голову и подумай.
    Судя по ошибке, у тебя в таблице users ID пользователя - уникальный ключ.
    Запрос на создание таблицы у тебя не содержит указания ключа, что, к слову, нехорошо. Я полагаю, ты убрал запись о ключе в какой-то момент, но не пересоздал таблицу.
    Ты записываешь в эту таблицу данные о пользователе всякий раз, когда получаешь команду /start.
    Внимание, вопрос: что произойдёт, если пользователь введёт /start ещё раз?
    Прааааавильно, бот попытается создать ещё одну запись для этого пользователя. Что запрещено наличием первичного ключа.

    Для начала ответь себе на вопрос: что тебе нужно сделать в базе, если пользователь ввёл /start ещё раз?
    Ничего? Читай про форму INSERT OR IGNORE, она как раз позволяет молча пропустить запись, если такой первичный ключ уже есть.
    Сообщить пользователю? Тогда сначала проверь в базе наличие записи для этого пользователя, и если она есть - сообщай, если её нет, то вноси в базу.
    Ответ написан
    Комментировать
  • Распознавание капчи на python, как улучшить результат?

    Vindicar
    @Vindicar
    RTFM!
    Ну так ты хреначишь BGR2GRAY+пороговое преобразование с фиксированным порогом, и думаешь что оно само сработает? Волшебную кнопку ждёшь?
    Попробуй перегнать в HSV и поэкспериментируй с каналами, посмотри, какой наиболее информативный. Используй алгоритм Otsu для определения порога.
    Попробуй разбить текст на символы, например, через connected components with stats. Если символы не касаются друг друга, должно сработать. Если касаются, то будет сложнее - нужно будет как-то разделять их ДО порогового преобразования.
    Потом уже пробуй распознать каждый символ. Если шрифт всегда один и тот же, то может и pytesseract не понадобится, просто собери образцы символов и ищи их через generalized Hough-Guil.
    Ответ написан
    Комментировать
  • Вылезает ошибка discord.ext.commands.errors.CommandInvokeError: Command raised an exception: KeyError: 1189988964807999659?

    Vindicar
    @Vindicar
    RTFM!
    if user_balances.get(author.id, initial_balance) < amount:
        await ctx.send('Insufficient funds.')
    else:
        user_balances[author.id] -= amount

    Ты не рассматриваешь ситуацию, когда пользователь не имеет сохранённого баланса (для него нет записи в user_balances), и но при этом amount <= initial_balance.
    В этом случае :
    1. get() вернёт initial_balance, так как записи о пользователе нет
    2. условие в if не выполнится, так как initial_balance >= amount
    3. управление перейдёт в else
    4. обращение user_balances[author.id] провалится, так как записи о пользователе нет.

    Рекомендую ознакомиться с методом словаря setdefault(), который добавляет ключ в словарь, если его там не было.
    Но я бы не заморачивался, а использовать вместо простого словаря класс collections.defaultdict. Он при попытке прочитать несуществующий ключ добавляет его, вызывая указанную функцию для получения значения.
    Например:
    from collections import defaultdict
    
    balance = defaultdict(lambda: 100)  # по умолчанию значение 100
    print(balance)  # выведет defaultdict(..., {}) - в словаре пока ничего нет
    print(balance["Вася"])  # выведет 100 - ключ "Вася" добавится автоматически
    print(balance)  # выведет defaultdict(..., {'Вася': 100}) - ключ сохранился в словаре
    balance['Петя'] += 50  # создаст ключ "Петя" со значением 100, потом добавит к нему 50
    print(balance)  # выведет defaultdict(..., {'Вася': 100, 'Петя': 150})

    Для своего бота код приспособь сам. Я не знаю, как ты сохраняешь/загружаешь баналс пользователей между запусками бота, но тебе может потребоваться сделать из defaultdict обычный словарь при сохранении, и наоборот - при загрузке.
    Вообще я бы не советовал начинать изучения Питона с ботов - это НЕ простая тема.
    Ответ написан
    Комментировать
  • Почему datetime выдает не верное текущее время?

    Vindicar
    @Vindicar
    RTFM!
    Ты документацию название функции читал?
    utcnow()
    Она возвращает universal coordinated time, т.е., считай, время по гринвичу. Если тебе нужно время в локальном часовом поясе, используй просто now().
    Ответ написан
  • Как сделать, чтобы мой дискорд бот мог общаться с пользователями?

    Vindicar
    @Vindicar
    RTFM!
    Ну я нечто подобное делал для своего IRC бота. Идея-то простая. У тебя есть набор пар, вроде словаря: регулярное выражение, чтобы отлавливать простые фразы, и список возможных ответов. Прогоняем регулярки по входящему сообщению, ищем первую сработавшую, получаем соответствующий её список. Из списка выбираем вариант с помощью random.choice() и отправляем.

    Проблемы с этим подходом две:
    1. язык - штука очень гибкая, все варианты не перечислить в регулярке.
    2. болтливый бот быстро надоедает, поэтому лучше отвечать только на прямое обращение.
    Ответ написан
  • Какие есть способы скомпилировать Python программу в исполняемый файл?

    Vindicar
    @Vindicar
    RTFM!
    Чтобы код остался питоном - никак. Питон по природе язык с виртуальной машиной, известные мне реализации питона не делают полноценную трансляцию в машинный код. Максимум JIT.
    Но можно поискать транспиляторы, вроде cython. На главной странице репозитория есть любопытный набор ссылок.
    Ответ написан
    1 комментарий
  • Пытался написать телеграмм бота с Chat GPT. В чем ошибка?

    Vindicar
    @Vindicar
    RTFM!
    ModuleNotFoundError: No module named 'urllib3.contrib.appengine'

    Stackoverflow говорит, что это косяк в последней версии requests. Создай отдельный файл и сделай в нём только import requests - отработает или нет?

    Если нет, поставь более старую версию. Если ставил через pip, то можно указать версию явно: pip install requests==x.yy.zz. Список версий можно посмотреть на pypi.
    Ответ написан
    Комментировать
  • Async, js модули, в браузере как правильно сделать синхронизацию?

    Vindicar
    @Vindicar
    RTFM!
    Это плохая идея, я тебе скажу. Асинхронный код не от хорошей жизни асинхронный - длительные операции вешают страницу, спасибо однопоточному браузерному JS.
    Так что если нужно что-то большое грузить при старте - лучше делать асинхронно, дальше использовать через callbackи, раз уж async-await не хочешь делать.
    Ответ написан
  • Как мне вывести список с экземплярами класса?

    Vindicar
    @Vindicar
    RTFM!
    В питоне есть два метода преобразования в строку: __str__() и __repr__().
    Первый преобразует объект в какую-то человекочитаемую строку. Он вызывается, если передать объект в функцию str().
    Второй обычно даёт более "техническое" представление объекта - в идеале, он показывает питоновский код, который нужно выполнить, чтобы этот объект получить. Но это требование не строгое, и никто не запрещает в __repr__() показывать что-то другое. Метод вызывается, если передать объект в функцию repr().

    Если у объекта нет __str__(), то питон попробует вызвать __repr__(). А __repr__() есть у всех объектов - он наследуется от базового object.

    Ты выводишь список целиком. У списка (list) нет метода __str__(), он использует __repr__() - и поэтому пытается вызывать repr() на твоих объектах, а repr() даже не пытается вызвать __str__(), она сразу идёт к __repr__().

    Я бы посоветовал переписать метод Deck.__str__() так:
    def __str__(self):
            return '[' + (', '.join(str(card) for card in self.mydeck)) + ']'

    Тперь он явно вызывает str() на каждой карте, а потому будет использоваться метод Card.__str__().
    Ответ написан
  • Как соединить рандомные точки на координатной плоскости в многоугольник?

    Vindicar
    @Vindicar
    RTFM!
    Твоя задача называется выпуклая оболочка - convex hull.
    Попробуй поискать по этим терминам.
    Ответ написан
    Комментировать
  • Какой командой запустить код заново в python?

    Vindicar
    @Vindicar
    RTFM!
    Почитай про цикл while и оператор break.
    Также, на будущее - не забывай оформлять код кнопкой </>.
    Чем более читаем твой вопрос и твой код, тем больше шансов получить ответ.
    Ответ написан
    Комментировать
  • Tkinter. Какой метод позиционирование лучше выбрать .pack / .place / .grid?

    Vindicar
    @Vindicar
    RTFM!
    Помести кнопки в Frame, Frame прикрути через pack(). Кнопки внутри фрейма - можно тоже через pack, можно еще как.
    Единственное, при добавлении новых элементов нужно будет сообразить, как указать, чтобы они паковались ДО фрейма с кнопками.

    EDIT: Заверни панель кнопок в ещё один Frame, и помести эту панель внутри внешнего Frame через pack(side='top', anchor='center'). Но учитывая, что у тебя в окне и так уже используется pack(side='top'), то можно обойтись без внешнего Frame - просто убери expand/fill с панели кнопок и запакуй её наверх.
    Пример кода с внешней панелью:
    import tkinter as tk
    
    
    root = tk.Tk()
    root.geometry('200x100')
    frame_outer = tk.Frame(root, bg='blue')
    frame_outer.pack(expand=True, fill='both')
    
    frame = tk.Frame(frame_outer, bg='green')
    btn1 = tk.Button(frame, text='Button1')
    btn2 = tk.Button(frame, text='Button2')
    btn1.pack(side='left', padx=5, pady=5)
    btn2.pack(side='left', padx=5, pady=5)
    frame.pack(side='top', anchor='center')
    
    root.mainloop()
    Ответ написан
    3 комментария