эти функции тоже в порядок приведи чтоб с документацией
def get_last_message_from_sender_with_subject(sender_name, subject):
    """
    Выгрузить файл из последнего сообщения по теме и отправителю
    """
    # Создаем объект Outlook
    outlook = win32.Dispatch("Outlook.Application")
    namespace = outlook.GetNamespace("MAPI")

    # Получаем папку "Входящие"
    inbox = namespace.GetDefaultFolder(6)  # 6 - это код для папки "Входящие"

    # Получаем все сообщения в папке "Входящие" и сортируем их по времени получения
    messages = inbox.Items
    messages.Sort("[ReceivedTime]", True)  # Сортируем по времени получения (последние сообщения первыми)

    # Перебираем сообщения, пока не найдем нужное
    found_message = None
    for message in messages:
        if message.SenderName == sender_name and subject.lower() in message.Subject.lower():
            found_message = message
            break

    if found_message is not None:
        # Сообщение найдено, выводим информацию о нем
        print(f"Тема: {found_message.Subject}")
        print(f"От: {found_message.SenderName}")
        print(f"Дата: {found_message.ReceivedTime}")
        
        # Проверяем, есть ли вложения
        if found_message.Attachments.Count > 0:
            # Папка для сохранения вложений
            save_folder = 'C:\\Users\\22240938\\Desktop\\packages\\запросы'  # Укажите нужный путь
            
            # Создаем папку, если ее нет
            if not os.path.exists(save_folder):
                os.makedirs(save_folder)
                
            for attachment in found_message.Attachments:
                attachment_path = os.path.join(save_folder, attachment.FileName)
                attachment.SaveAsFile(attachment_path)  # Сохраняем вложение
                print(f"Сохранено: {attachment.FileName}")
        else:
            print("Вложений нет.")
    else:
        print(f"Не найдено сообщений от '{sender_name}' с темой '{subject}'.")

def send_email_with_attachments(attachments):
    """Отправляет письма через Outlook с указанными вложениями."""
    outlook = win32.Dispatch('outlook.application')
    for attachment in attachments:
        if os.path.getsize(attachment) < 30 * 1024 * 1024:
            mail = outlook.CreateItem(0)
            mail.To = 'IA@mail.ru'  # Измените на адрес получателя
            mail.Subject = f'{os.path.basename(attachment)}'
            mail.Body = ''
            mail.Attachments.Add(os.path.abspath(attachment))
            mail.Send()
            print(f'Письмо с {attachment} отправлено.')
        else: print(f'Письмо с {attachment} не отправлено. Превышен размер 30 мб!')
            
# очистка логов от джавы
def clear_folder(folder_path):
    # Проверяем, существует ли папка
    if not os.path.exists(folder_path):
        print(f"Папка {folder_path} не существует.")
        return
    
    # Перебираем все элементы в директории
    for filename in os.listdir(folder_path):
        file_path = os.path.join(folder_path, filename)

        try:
            # Если элемент — файл, удаляем его
            if os.path.isfile(file_path) or os.path.islink(file_path):
                os.unlink(file_path)
            # Если элемент — директория, удаляем её рекурсивно
            elif os.path.isdir(file_path):
                shutil.rmtree(file_path)
        except Exception as e:
            print(f'Не удалось удалить {file_path}. Причина: {e}')

# Ждем, пока от последнего выполнившегося запроса пройдет <minutes> мин. 
# если прошло, выполнение ячейки заканчивается и переходит к следующим
def check_last_execution(minutes, model="", strategy=""):
    '''Проверяем, не было ли расчетов <minutes> мин назад по модели или стратегии
    minutes - кол-во минут, model="", strategy=""'''
    current_time = datetime.now()
    minutes_ago = current_time - timedelta(minutes=minutes)
    
    current_time_str = current_time.strftime('%Y-%m-%d %H:%M:%S.{:03d}'.format(current_time.microsecond // 1000))
    minutes_ago_str = minutes_ago.strftime('%Y-%m-%d %H:%M:%S.{:03d}'.format(minutes_ago.microsecond // 1000))
  
    result = parse_df(model=model, strategy=strategy, start=minutes_ago_str, cols=['date_exec'],end=current_time_str)

    # Проверка результата
    if not result.empty:
        last_execution_time = result.iloc[-1][0]
        if last_execution_time < minutes_ago:
            return True
    else: return True

    return False

def wait_loop(minutes, model="", strategy=""):
    '''Ждем <minutes> мин, пока стенд загружен моделью или стратегией
    minutes - кол-во минут, model="", strategy=""'''
    while True:
        if check_last_execution(minutes, model, strategy):
            print("Задача выполнена! Останавливаем цикл.")
            break
        else:
            print(f"Ждем {minutes} мин перед повторной проверкой.")
            time.sleep(minutes * 60)  # Ждем