import random from datetime import datetime from typing import List, Dict, Optional from sqlalchemy import select from sqlalchemy.ext.asyncio import AsyncSession from database.models import Task, Vocabulary class TaskService: """Сервис для работы с заданиями""" @staticmethod async def generate_translation_tasks( session: AsyncSession, user_id: int, count: int = 5 ) -> List[Dict]: """ Генерация заданий на перевод слов Args: session: Сессия базы данных user_id: ID пользователя count: Количество заданий Returns: Список заданий """ # Получаем слова пользователя result = await session.execute( select(Vocabulary) .where(Vocabulary.user_id == user_id) .order_by(Vocabulary.last_reviewed.asc().nullsfirst()) .limit(count * 2) # Берем больше, чтобы было из чего выбрать ) words = list(result.scalars().all()) if not words: return [] # Выбираем случайные слова selected_words = random.sample(words, min(count, len(words))) tasks = [] for word in selected_words: # Случайно выбираем направление перевода direction = random.choice(['en_to_ru', 'ru_to_en']) if direction == 'en_to_ru': task = { 'type': 'translate_to_ru', 'word_id': word.id, 'question': f"Переведи слово: {word.word_original}", 'word': word.word_original, 'correct_answer': word.word_translation, 'transcription': word.transcription } else: task = { 'type': 'translate_to_en', 'word_id': word.id, 'question': f"Переведи слово: {word.word_translation}", 'word': word.word_translation, 'correct_answer': word.word_original, 'transcription': word.transcription } tasks.append(task) return tasks @staticmethod async def save_task_result( session: AsyncSession, user_id: int, task_type: str, content: Dict, user_answer: str, correct_answer: str, is_correct: bool, ai_feedback: Optional[str] = None ) -> Task: """ Сохранение результата выполнения задания Args: session: Сессия базы данных user_id: ID пользователя task_type: Тип задания content: Содержимое задания user_answer: Ответ пользователя correct_answer: Правильный ответ is_correct: Правильность ответа ai_feedback: Обратная связь от AI Returns: Сохраненное задание """ task = Task( user_id=user_id, task_type=task_type, content=content, user_answer=user_answer, correct_answer=correct_answer, is_correct=is_correct, ai_feedback=ai_feedback, completed_at=datetime.utcnow() ) session.add(task) await session.commit() await session.refresh(task) return task @staticmethod async def update_word_statistics( session: AsyncSession, word_id: int, is_correct: bool ): """ Обновление статистики слова Args: session: Сессия базы данных word_id: ID слова is_correct: Правильность ответа """ result = await session.execute( select(Vocabulary).where(Vocabulary.id == word_id) ) word = result.scalar_one_or_none() if word: word.times_reviewed += 1 if is_correct: word.correct_answers += 1 word.last_reviewed = datetime.utcnow() await session.commit() @staticmethod async def get_user_stats(session: AsyncSession, user_id: int) -> Dict: """ Получение статистики пользователя Args: session: Сессия базы данных user_id: ID пользователя Returns: Статистика пользователя """ # Количество слов words_result = await session.execute( select(Vocabulary).where(Vocabulary.user_id == user_id) ) words = list(words_result.scalars().all()) total_words = len(words) # Количество выполненных заданий tasks_result = await session.execute( select(Task).where(Task.user_id == user_id) ) tasks = list(tasks_result.scalars().all()) total_tasks = len(tasks) # Правильные ответы correct_tasks = len([t for t in tasks if t.is_correct]) accuracy = int((correct_tasks / total_tasks * 100)) if total_tasks > 0 else 0 # Слова с повторениями reviewed_words = len([w for w in words if w.times_reviewed > 0]) return { 'total_words': total_words, 'reviewed_words': reviewed_words, 'total_tasks': total_tasks, 'correct_tasks': correct_tasks, 'accuracy': accuracy }