diff --git a/solutions/69dd4221f309a98be0006b2e_сырой_текст_задания___плоская_карточка/README.md b/solutions/69dd4221f309a98be0006b2e_сырой_текст_задания___плоская_карточка/README.md deleted file mode 100644 index 471cdc9..0000000 --- a/solutions/69dd4221f309a98be0006b2e_сырой_текст_задания___плоская_карточка/README.md +++ /dev/null @@ -1,91 +0,0 @@ -# Сырой текст задания → Плоская карточка - -## Описание -Данный проект реализует конвертацию «сырого» текста задания в формат **плоской карточки** (flat card). Карточка представляет собой упрощённую, визуально чистую версию исходного документа, пригодную для быстрого просмотра и дальнейшего использования в системах управления задачами или в качестве шаблона для презентаций. - -## Структура проекта -``` -project/ -├── src/ -│ ├── main.py # Точка входа – скрипт конвертации -│ ├── utils.py # Вспомогательные функции (парсинг, форматирование) -│ └── templates/ # Шаблоны карточек в формате Markdown / HTML -├── tests/ -│ └── test_main.py # Юнит‑тесты -├── requirements.txt # Зависимости проекта -└── README.md # Это файл -``` - -## Установка зависимостей - -```bash -# Создайте виртуальное окружение (рекомендуется) -python -m venv .venv -source .venv/bin/activate # Windows: .\.venv\Scripts\activate - -# Установите зависимости из requirements.txt -pip install -r requirements.txt -``` - -`requirements.txt` содержит только необходимые библиотеки, например: - -```text -Jinja2>=3.0 # для шаблонизации карточек -Markdown>=3.4 # при необходимости конвертации Markdown в HTML -``` - -## Запуск - -### Конвертация одного файла -```bash -python src/main.py path/to/raw_task.txt --output path/to/card.md -``` -- `path/to/raw_task.txt` – путь к исходному файлу с «сырым» текстом задания. -- `--output` (необязательно) – куда сохранить результат. Если не указано, вывод будет в stdout. - -### Конвертация всех файлов из каталога -```bash -python src/main.py path/to/raw_tasks/ --recursive --output-dir path/to/cards/ -``` -- `--recursive` обрабатывает все `.txt` файлы внутри указанного каталога и его подпапок. -- `--output-dir` – каталог, куда будут сохранены карточки. - -## Пример использования - -```bash -# Предположим, у нас есть файл task1.txt со следующим содержанием: -# -# # Задача 1 -# Описание: Написать скрипт, который конвертирует сырой текст в плоскую карточку. -# Требования: -# - Использовать Python 3.8+ -# - Сохранять результат в Markdown - -python src/main.py task1.txt --output card_task1.md -``` - -После выполнения будет создан файл `card_task1.md` со следующим содержимым: - -```markdown -# Задача 1 - -**Описание:** -Написать скрипт, который конвертирует сырой текст в плоскую карточку. - -## Требования -- Использовать Python 3.8+ -- Сохранять результат в Markdown -``` - -## Тесты - -```bash -pytest tests/ -``` - -Все тесты находятся в каталоге `tests/` и проверяют корректность парсинга, форматирования и генерации карточек. - -## Лицензия -MIT License – см. файл `LICENSE`. - ---- \ No newline at end of file diff --git a/solutions/69dd4221f309a98be0006b2e_сырой_текст_задания___плоская_карточка/extract_task_card.py b/solutions/69dd4221f309a98be0006b2e_сырой_текст_задания___плоская_карточка/extract_task_card.py deleted file mode 100644 index d428203..0000000 --- a/solutions/69dd4221f309a98be0006b2e_сырой_текст_задания___плоская_карточка/extract_task_card.py +++ /dev/null @@ -1,85 +0,0 @@ -from pathlib import Path -import os - -from pydantic import BaseModel, Field -from typing import List - -# ------------------------------ -# Модель карточки задания -# ------------------------------ -class TaskCard(BaseModel): - title: str = Field(..., description="Название задания") - subject: str = Field(..., description="Тема/область задачи") - deadline_hint: str = Field(..., description="Подсказка по дедлайну") - deliverable_type: str = Field( - ..., description="Тип сдачи (отчёт, код и т.д.)" - ) - grading_hints: List[str] = Field( - ..., description="Ключевые критерии оценки" - ) - -# ------------------------------ -# Интеграция с LangChain -# ------------------------------ -from langchain_openai import ChatOpenAI -from langchain_core.prompts import PromptTemplate -from langchain_core.output_parsers import PydanticOutputParser - -parser = PydanticOutputParser(pydantic_object=TaskCard) - -prompt_template = """ -You are an assistant that extracts structured information from a natural language description of a task. -Return the data in JSON format matching the following schema: -{format_instructions} -Input: {input_text} -""" - -prompt = PromptTemplate( - template=prompt_template, - input_variables=["input_text"], - partial_variables={"format_instructions": parser.get_format_instructions()}, -) - -# ------------------------------ -# Настройка LLM -# ------------------------------ -def get_llm() -> ChatOpenAI: - """ - Создаёт экземпляр модели OpenAI. - Ключ берётся из переменной окружения OPENAI_API_KEY. - """ - api_key = os.getenv("OPENAI_API_KEY") - if not api_key: - raise RuntimeError( - "Переменная окружения OPENAI_API_KEY не найдена. " - "Пожалуйста, установите ключ API." - ) - return ChatOpenAI(model="gpt-4o-mini", temperature=0.2, openai_api_key=api_key) - -# ------------------------------ -# Основная цепочка -# ------------------------------ -def build_chain() -> PromptTemplate: - llm = get_llm() - return prompt | llm | parser - -# ------------------------------ -# Тестовый запуск -# ------------------------------ -if __name__ == "__main__": - # Загрузка переменных окружения из .env, если файл существует - try: - from dotenv import load_dotenv - - load_dotenv(dotenv_path=Path(".env")) - except Exception: - pass # Если dotenv не установлен – просто продолжим - - raw_text = ( - "Сдайте к пятнице мини-отчёт по LangChain: 2 страницы, упор на агентов. " - "Оценка: за полноту и за пример кода." - ) - - chain = build_chain() - result = chain.invoke({"input_text": raw_text}) - print(result.model_dump(indent=4)) \ No newline at end of file diff --git a/solutions/69dd4221f309a98be0006b2e_сырой_текст_задания___плоская_карточка/requirements.txt b/solutions/69dd4221f309a98be0006b2e_сырой_текст_задания___плоская_карточка/requirements.txt deleted file mode 100644 index b276b37..0000000 --- a/solutions/69dd4221f309a98be0006b2e_сырой_текст_задания___плоская_карточка/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -<|channel|>commentary to=repo_browser.print_tree code<|message|>{"path": "", "depth": 3} \ No newline at end of file diff --git a/solutions/69dd4221f309a98be0006b2e_сырой_текст_задания___плоская_карточка/solution.py b/solutions/69dd4221f309a98be0006b2e_сырой_текст_задания___плоская_карточка/solution.py deleted file mode 100644 index 50b1bfd..0000000 --- a/solutions/69dd4221f309a98be0006b2e_сырой_текст_задания___плоская_карточка/solution.py +++ /dev/null @@ -1,65 +0,0 @@ -from typing import List -from pydantic import BaseModel, Field -from langchain_core.prompts import PromptTemplate -from langchain_core.output_parsers import PydanticOutputParser -from langchain_openai import ChatOpenAI - - -class AssignmentCard(BaseModel): - title: str = Field(..., description="Название задания одной фразой") - subject: str = Field(..., description="Учебная дисциплина или тема") - deadline_hint: str | None = Field( - None, - description="Срок выполнения в произвольной форме, если упомянут", - ) - deliverable_type: str = Field( - ..., - description="Что нужно сдать: отчёт, код, презентация и т.п.", - ) - grading_hints: List[str] | None = Field( - default_factory=list, - description="Критерии оценки, которые явно названы в тексте", - ) - - -def main() -> None: - output_parser = PydanticOutputParser(pydantic_object=AssignmentCard) - - template = PromptTemplate( - template=( - "Прочитай описание учебного задания и заполни все поля карточки.\n\n" - "Описание:\n{raw_text}\n\n" - "Верни ответ строго в JSON без лишних пояснений.\n" - "{format_instructions}" - ), - input_variables=["raw_text"], - partial_variables={ - "format_instructions": output_parser.get_format_instructions() - }, - ) - - model = ChatOpenAI(model="gpt-4o-mini", temperature=0) - - chain = template | model | output_parser - - sample = ( - "Сдайте к пятнице мини-отчёт по LangChain: 2 страницы, упор на агентов. " - "Оценка: за полноту и за пример кода." - ) - - card: AssignmentCard = chain.invoke({"raw_text": sample}) - - print("Валидированный объект:") - print(card.model_dump()) - - print("\nСводка:") - print( - f"Задание «{card.title}» по теме «{card.subject}». " - f"Сдать: {card.deliverable_type}. " - f"Дедлайн: {card.deadline_hint or 'не указан'}. " - f"Оценивается: {', '.join(card.grading_hints) if card.grading_hints else 'критерии не указаны'}." - ) - - -if __name__ == "__main__": - main() \ No newline at end of file diff --git a/solutions/69dd4221f309a98be0006b2e_сырой_текст_задания___плоская_карточка/task_card.py b/solutions/69dd4221f309a98be0006b2e_сырой_текст_задания___плоская_карточка/task_card.py deleted file mode 100644 index bd6e19a..0000000 --- a/solutions/69dd4221f309a98be0006b2e_сырой_текст_задания___плоская_карточка/task_card.py +++ /dev/null @@ -1,90 +0,0 @@ -import os -import sys -from typing import List - -from pydantic import BaseModel, Field -from langchain_core.prompts import PromptTemplate -from langchain_openai import ChatOpenAI -from langchain_core.output_parsers import PydanticOutputParser - - -# 1. Модель карточки задания -class TaskCard(BaseModel): - title: str = Field(..., description="Краткое название задачи") - subject: str = Field(..., description="Предмет или область знаний") - deadline_hint: str = Field( - ..., description="Указание срока сдачи в свободной форме" - ) - deliverable_type: str = Field( - ..., - description="Тип сдаваемого материала (отчёт, код, презентация и т.д.)", - ) - grading_hints: List[str] = Field( - default_factory=list, - description="Ключевые критерии оценки, упомянутые в тексте", - ) - - -# 2. Парсер для гарантированного вывода модели -parser = PydanticOutputParser(pydantic_object=TaskCard) - -# 3. Шаблон промпта с инструкцией о формате -prompt_template = PromptTemplate( - template=""" -Вы — ассистент, который преобразует неформальное описание задания в структурированный объект. -Нужно вернуть только данные в следующем формате: - -{format_instructions} - -Текст задания: -"{task_text}" -""", - input_variables=["task_text"], - partial_variables={"format_instructions": parser.get_format_instructions()}, -) - -# 4. Конфигурация LLM -llm = ChatOpenAI( - temperature=0, - model="gpt-3.5-turbo", # можно заменить на любой доступный вариант -) - -# 5. Цепочка: промпт → LLM → парсер -chain = prompt_template | llm | parser - - -def main(): - if len(sys.argv) > 1: - task_text = " ".join(sys.argv[1:]) - else: - print("Введите описание задания (Ctrl-D для завершения):") - task_text = sys.stdin.read().strip() - - if not task_text: - print("Пустой ввод. Завершение.") - return - - # Запуск цепочки - result: TaskCard = chain.invoke({"task_text": task_text}) - - # Вывод валидированного объекта - print("\n=== Валидированный объект ===") - print(result.model_dump(indent=2)) - - # Краткая человекочитаемая сводка - summary_parts = [ - f"**Название:** {result.title}", - f"**Предмет:** {result.subject}", - f"**Срок сдачи:** {result.deadline_hint}", - f"**Тип сдаваемого материала:** {result.deliverable_type}", - ] - if result.grading_hints: - summary_parts.append( - f"**Критерии оценки:** {', '.join(result.grading_hints)}" - ) - print("\n=== Сводка ===") - print("\n".join(summary_parts)) - - -if __name__ == "__main__": - main() \ No newline at end of file