рекомендации по улучшению скрипта:

    Использование правильного API (Anthropic Claude):
        Проблема: В вашем ТЗ указано, что необходимо отправлять запросы в Claude. Однако текущий скрипт использует OpenAI API для генерации контента.
        Решение: Замените использование OpenAI API на Anthropic API для взаимодействия с моделью Claude. Это потребует изменения в функции generate_content и настройки аутентификации.

    # Импортируем необходимый клиент Anthropic
    from anthropic import Anthropic, HUMAN_PROMPT, AI_PROMPT

    def generate_content(api_key: str, prompt: str, max_tokens: int = 1000, temperature: float = 0.7) -> str:
        try:
            client = Anthropic(api_key=api_key)
            response = client.completions.create(
                model="claude-2",
                max_tokens_to_sample=max_tokens,
                prompt=f"{HUMAN_PROMPT} {prompt}{AI_PROMPT}",
                temperature=temperature,
            )
            logger.debug("Контент успешно сгенерирован.")
            return response.completion.strip()
        except Exception as e:
            logger.error(f"Ошибка при генерации контента: {e}")
            return ""

Чтение и обработка "Плана курса":

    Проблема: Скрипт не учитывает структуру курса из "Плана курса", которая содержит модули и лекции.
    Решение: Добавьте функцию для чтения и парсинга файлов "План курса" и извлечения структуры модулей и лекций. Предполагая, что "План курса" хранится в формате DOCX с таблицей или структурированным текстом, вы можете использовать библиотеку python-docx для парсинга.

def parse_course_plan(plan_file: Path) -> List[Dict]:
    try:
        document = Document(plan_file)
        course_structure = []
        current_module = None
        for para in document.paragraphs:
            text = para.text.strip()
            if text.startswith("Модуль"):
                current_module = {'name': text, 'lectures': []}
                course_structure.append(current_module)
            elif text.startswith("Лекция") and current_module:
                current_module['lectures'].append(text)
        logger.info(f"План курса из '{plan_file}' успешно прочитан.")
        return course_structure
    except Exception as e:
        logger.error(f"Ошибка при парсинге плана курса '{plan_file}': {e}")
        return []

Организация лекций по модулям:

    Проблема: Лекции не сохраняются в папки, названные по названиям модулей из плана.
    Решение: При сохранении лекций используйте структуру модулей из плана курса для определения пути сохранения.

# Внутри основного цикла по модулям и лекциям
module_dir = output_dir / module_name
module_dir.mkdir(parents=True, exist_ok=True)
lecture_file = module_dir / f"{lecture_title}.docx"
save_docx(generated_content, lecture_file)

Обработка незаконченных лекций:

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

def is_incomplete(response) -> bool:
    return response.get('stop_reason') == 'max_tokens'

# Внутри функции generate_content
# Проверьте, является ли лекция незаконченной, и при необходимости продолжите генерацию

Генерация тестов после модулей и итогового теста:

    Проблема: Скрипт не генерирует тесты после завершения всех лекций модуля и курса.
    Решение: После завершения генерации лекций в модуле добавьте код для генерации теста, используя "Запрос на написание теста". Аналогично поступите после генерации всех лекций курса для итогового теста.

# После цикла генерации лекций в модуле
test_prompt = read_docx(test_request_file)  # Файл "Запрос на написание теста"
test_content = generate_content(api_key, test_prompt)
test_file = module_dir / "Тест.docx"
save_docx(test_content, test_file)

Добавление инструкций и корректного написания формул в контекст:

    Проблема: Скрипт может не включать инструкции из файлов "Инструкции" и "Корректное написание формул" в контекст для генерации.
    Решение: Объедините содержимое этих файлов и добавьте их в начало или конец контекста.

# Чтение инструкций
instructions_dir = base_dir / "Инструкции"
instruction_files = get_all_docx_files(instructions_dir)
instructions_text = ""
for inst_file in instruction_files:
    inst_content = read_docx(inst_file)
    instructions_text += f"\n{inst_content}"

Улучшение логики формирования запроса (prompt):

    Решение: Составьте более структурированный prompt, включающий контекст, инструкции и само задание.

prompt = f"{instructions_text}\n{context_text}\n\nЗадание:\n{task_text}\n\nПожалуйста, выполните задание выше согласно предоставленным инструкциям."

    Обработка нескольких "Планов курса" и обновление пути к файлам:
        Решение: Если планов курса несколько, обрабатывайте каждый в отдельности, обновляя пути к соответствующим файлам заданий и контекста.

    Обработка исключений и ошибок:
        Решение: Добавьте более подробную обработку исключений, особенно при работе с файловой системой и API.

    Оптимизация количества токенов и температуры:
        Решение: Настройте параметры max_tokens и temperature в зависимости от требований к длине лекций и стилю изложения.

    Логирование прогресса и результатов:
        Решение: Улучшите логирование, добавив информацию о текущем модуле и лекции, статусе генерации и сохранения файлов.

    Рефакторинг кода для улучшения читаемости и поддержки:
        Решение: Разбейте код на более мелкие функции и модули, используйте объектно-ориентированный подход при необходимости.

Пример обновленного основного цикла в функции main:

def main():
    # Инициализация и загрузка конфигураций
    # ...

    # Чтение планов курса
    plan_dir = base_dir / "План курса"
    plan_files = get_all_docx_files(plan_dir)
    if not plan_files:
        logger.warning(f"В папке '{plan_dir}' не найдено файлов плана курса.")
        sys.exit(1)

    for plan_file in plan_files:
        course_structure = parse_course_plan(plan_file)
        for module in course_structure:
            module_name = module['name']
            module_dir = output_dir / module_name
            module_dir.mkdir(parents=True, exist_ok=True)

            for lecture_title in module['lectures']:
                # Проверка наличия задания для лекции
                # ...

                # Формирование prompt и генерация контента
                # ...

                # Обработка незаконченных лекций
                # ...

                # Сохранение лекции
                # ...

            # Генерация теста для модуля
            # ...

    # Генерация итогового теста
    # ...

    logger.info("Автоматизация завершена успешно.") внеси правки вкод: import os
import sys
import logging
import configparser
from pathlib import Path
from typing import List
from docx import Document
from openai import OpenAI

# Настройка логирования
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s [%(levelname)s] %(message)s',
    handlers=[
        logging.StreamHandler(sys.stdout),
        logging.FileHandler("automation.log", encoding='utf-8')
    ]
)
logger = logging.getLogger(__name__)

def load_config(config_path: str) -> str:
    config = configparser.ConfigParser()
    if not os.path.exists(config_path):
        logger.critical(f"Файл конфигурации '{config_path}' не найден.")
        sys.exit(1)
    config.read(config_path, encoding='utf-8')
    try:
        api_key = config['API']['openrouter_api_key']
        if not api_key:
            raise ValueError
        logger.info("API-ключ успешно загружен из конфигурации.")
        return api_key
    except (KeyError, ValueError):
        logger.critical("API-ключ не найден в файле конфигурации.")
        sys.exit(1)

def read_docx(file_path: Path) -> str:
    try:
        document = Document(file_path)
        text = "\n".join([para.text for para in document.paragraphs])
        logger.debug(f"Файл '{file_path}' успешно прочитан.")
        return text
    except Exception as e:
        logger.error(f"Ошибка при чтении файла '{file_path}': {e}")
        return ""

def get_all_docx_files(directory: Path) -> List[Path]:
    return list(directory.rglob("*.docx"))

def generate_content(api_key: str, prompt: str, max_tokens: int = 1000, temperature: float = 0.7) -> str:
    try:
        client = OpenAI(
            base_url="https://openrouter.ai/api/v1",
            api_key=api_key,
        )
        completion = client.chat.completions.create(
            model="openai/gpt-3.5-turbo",
            messages=[
                {
                    "role": "user",
                    "content": prompt
                }
            ],
            max_tokens=max_tokens,
            temperature=temperature
        )
        logger.debug("Контент успешно сгенерирован.")
        return completion.choices[0].message.content
    except Exception as e:
        logger.error(f"Ошибка при генерации контента: {e}")
        return ""

def save_docx(content: str, file_path: Path) -> None:
    try:
        document = Document()
        for line in content.split('\n'):
            document.add_paragraph(line)
        document.save(file_path)
        logger.info(f"Сохранено: '{file_path}'")
    except Exception as e:
        logger.error(f"Ошибка при сохранении файла '{file_path}': {e}")

def main():
    base_dir = Path(__file__).parent.resolve()
    assignment_dir = base_dir / "Задание"
    context_dir = base_dir / "База с контекстом"
    output_dir = base_dir / "Папка с готовыми лекциями"
    config_path = base_dir / "config.ini"

    api_key = load_config(str(config_path))

    assignment_files = get_all_docx_files(assignment_dir)
    context_files = get_all_docx_files(context_dir)

    if not assignment_files:
        logger.warning(f"В папке '{assignment_dir}' не найдено файлов .docx для заданий.")
    if not context_files:
        logger.warning(f"В папке '{context_dir}' не найдено файлов .docx для контекста.")

    context_text = ""
    for ctx_file in context_files:
        ctx_content = read_docx(ctx_file)
        context_text += f"\n{ctx_content}"

    for assignment_file in assignment_files:
        logger.info(f"Обработка задания: '{assignment_file}'")
        task_text = read_docx(assignment_file)
        if not task_text.strip():
            logger.warning(f"Задание в файле '{assignment_file}' пустое. Пропуск.")
            continue

        prompt = f"{context_text}\n\nЗадание:\n{task_text}\n\nПожалуйста, выполните задание выше согласно предоставленным инструкциям."

        generated_content = generate_content(api_key, prompt)

        if not generated_content:
            logger.warning(f"Не удалось сгенерировать контент для задания '{assignment_file}'. Пропуск.")
            continue

        relative_path = assignment_file.relative_to(assignment_dir).with_suffix('.docx')
        output_file = output_dir / relative_path

        output_file.parent.mkdir(parents=True, exist_ok=True)

        save_docx(generated_content, output_file)

    logger.info("Автоматизация завершена успешно.")

if __name__ == "__main__":
    main()

print("Код выполнен успешно.")