Реализованы задания и статистика (/task, /stats)
Создано: - services/task_service.py - сервис для работы с заданиями - bot/handlers/tasks.py - обработчики команд /task и /stats Реализовано: ✅ /task - генерация заданий на перевод слов - 5 случайных слов из словаря пользователя - Два направления: EN→RU и RU→EN - Показ транскрипции - Проверка ответов через AI - Детальная обратная связь - Сохранение результатов в БД ✅ /stats - статистика обучения - Количество слов в словаре - Количество изученных слов - Выполненные задания - Процент правильных ответов Функции: - Умные повторения (слова с меньшим количеством повторений появляются чаще) - Обновление статистики слов после каждого задания - Прогресс-бар выполнения заданий - Эмодзи-реакции на результат 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
183
services/task_service.py
Normal file
183
services/task_service.py
Normal file
@@ -0,0 +1,183 @@
|
||||
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"Переведи слово: <b>{word.word_original}</b>",
|
||||
'word': word.word_original,
|
||||
'correct_answer': word.word_translation,
|
||||
'transcription': word.transcription
|
||||
}
|
||||
else:
|
||||
task = {
|
||||
'type': 'translate_to_en',
|
||||
'word_id': word.id,
|
||||
'question': f"Переведи слово: <b>{word.word_translation}</b>",
|
||||
'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
|
||||
}
|
||||
Reference in New Issue
Block a user