EnglishStudyHelper / study_plan.py
amauricunha's picture
Upload 5 files
be3ddee verified
Raw
History Blame
9.12 kB
import logging
import os
try:
from groq import Groq
except ImportError:
Groq = None
try:
import google.generativeai as genai
except ImportError:
genai = None
logger = logging.getLogger(__name__)
groq_client = None
genai_client = None
try:
GROQ_API_KEY = os.environ.get("GROQ_API_KEY")
if GROQ_API_KEY and Groq:
groq_client = Groq(api_key=GROQ_API_KEY)
except Exception as e:
logger.warning(f"Groq client not available: {e}")
try:
GEMINI_API_KEY = os.environ.get("GEMINI_API_KEY")
if GEMINI_API_KEY and genai:
genai.configure(api_key=GEMINI_API_KEY)
genai_client = genai
except Exception as e:
logger.warning(f"Gemini client not available: {e}")
def generate_study_plan(user_data):
"""Gera um plano de estudos estruturado a partir dos dados do usuΓ‘rio (sem IA)."""
from datetime import timedelta
current_level = user_data.get('english_level', 'B1')
target_level = user_data.get('target_level', 'B2')
weekly_hours = user_data.get('weekly_hours', 5)
interests = user_data.get('interests', {})
context_focus = user_data.get('context_focus', 'General/Social')
study_goals = user_data.get('study_goals', [])
# ProgressΓ£o de nΓ­veis
level_progression = {
'A1': {'next': 'A2', 'weeks': 12},
'A2': {'next': 'B1', 'weeks': 16},
'B1': {'next': 'B2', 'weeks': 20},
'B2': {'next': 'C1', 'weeks': 24},
'C1': {'next': 'C2', 'weeks': 28},
'C2': {'next': 'C2', 'weeks': 32}
}
# Timeline
base_weeks = level_progression.get(current_level, level_progression['B1'])['weeks']
hour_multiplier = 5 / max(weekly_hours, 1)
adjusted_weeks = int(base_weeks * hour_multiplier)
from datetime import datetime
completion_date = (datetime.now() + timedelta(weeks=adjusted_weeks)).date().isoformat()
# Estrutura semanal
distributions = {
'A1': {'reading': 0.25, 'flashcards': 0.30, 'conversation': 0.20, 'writing': 0.15, 'grammar': 0.10},
'A2': {'reading': 0.30, 'flashcards': 0.25, 'conversation': 0.20, 'writing': 0.15, 'grammar': 0.10},
'B1': {'reading': 0.30, 'flashcards': 0.20, 'conversation': 0.25, 'writing': 0.20, 'listening': 0.05},
'B2': {'reading': 0.25, 'flashcards': 0.15, 'conversation': 0.25, 'writing': 0.25, 'listening': 0.10},
'C1': {'reading': 0.30, 'flashcards': 0.10, 'conversation': 0.25, 'writing': 0.25, 'listening': 0.10},
'C2': {'reading': 0.35, 'flashcards': 0.05, 'conversation': 0.25, 'writing': 0.25, 'listening': 0.10}
}
base_dist = distributions.get(current_level, distributions['B1'])
total_minutes = weekly_hours * 60
weekly_structure = {}
for activity, percentage in base_dist.items():
minutes = int(total_minutes * percentage)
if minutes >= 10:
weekly_structure[activity] = {
'minutes_per_week': minutes,
'sessions_per_week': max(1, minutes // 30),
'minutes_per_session': minutes // max(1, minutes // 30)
}
# Dicas de estudo (IA se disponΓ­vel)
def get_default_tips(level):
tips_by_level = {
'A1': [
"πŸ“š Start with basic vocabulary - 10 new words daily",
"🎯 Focus on present tense in daily conversations",
"πŸ’‘ Use picture dictionaries for visual learning",
"⭐ Practice pronunciation with simple audio materials",
"πŸš€ Don't worry about mistakes - communication is key!"
],
'A2': [
"πŸ“š Read simple news articles and stories",
"🎯 Practice past and future tenses regularly",
"πŸ’‘ Join basic English conversation groups",
"⭐ Use language learning apps for daily practice",
"πŸš€ Watch movies with subtitles in your language"
],
'B1': [
"πŸ“š Read intermediate articles on topics you enjoy",
"🎯 Practice expressing opinions and preferences",
"πŸ’‘ Start writing short paragraphs daily",
"⭐ Listen to podcasts at normal speed",
"πŸš€ Try to think in English for simple tasks"
],
'B2': [
"πŸ“š Read longer articles and opinion pieces",
"🎯 Practice formal and informal writing styles",
"πŸ’‘ Engage in debates and discussions",
"⭐ Watch news programs without subtitles",
"πŸš€ Set specific goals for each study session"
],
'C1': [
"πŸ“š Read academic and professional texts",
"🎯 Practice nuanced expressions and idioms",
"πŸ’‘ Write formal reports and presentations",
"⭐ Listen to academic lectures and conferences",
"πŸš€ Focus on specialized vocabulary for your field"
],
'C2': [
"πŸ“š Read literature and complex analytical texts",
"🎯 Master subtle language differences",
"πŸ’‘ Write with stylistic sophistication",
"⭐ Engage with native speakers in professional contexts",
"πŸš€ Aim for native-like fluency in all skills"
]
}
return tips_by_level.get(level, tips_by_level['B1'])
def generate_ai_tips(user_data):
prompt = f"""
Generate 5 personalized English study tips for a user with these characteristics:
- Current Level: {user_data.get('english_level', 'B1')}
- Target Level: {user_data.get('target_level', 'B2')}
- Weekly Study Time: {user_data.get('weekly_hours', 5)} hours
- Context Focus: {user_data.get('context_focus', 'General/Social')}
- Interests: {', '.join(user_data.get('interests', {}).keys())}
Provide practical, actionable tips that are specific to their level and interests. Format as a simple list of tips, each starting with an emoji.
"""
try:
if groq_client:
response = groq_client.chat.completions.create(
model="llama-3.1-8b-instant",
messages=[{"role": "user", "content": prompt}],
temperature=0.7
)
response_text = response.choices[0].message.content
elif genai_client:
model = genai_client.GenerativeModel('gemini-2.5-flash-latest')
response = model.generate_content(prompt)
response_text = response.text
else:
return get_default_tips(user_data.get('english_level', 'B1'))
tips = [line.strip() for line in response_text.split('\n') if line.strip() and any(e in line for e in ['πŸ“š','πŸ’‘','🎯','⭐','πŸš€'])]
return tips[:5] if tips else get_default_tips(user_data.get('english_level', 'B1'))
except Exception as e:
logger.warning(f"AI study tips error: {e}")
return get_default_tips(user_data.get('english_level', 'B1'))
study_tips = generate_ai_tips(user_data)
# Milestones
milestones = []
milestone_intervals = max(2, adjusted_weeks // 4)
for i in range(1, 5):
week = milestone_intervals * i
if week <= adjusted_weeks:
milestones.append({
'week': week,
'title': f"Milestone {i}",
'description': f"Progress checkpoint {i}",
'target_date': (datetime.now() + timedelta(weeks=week)).date().isoformat(),
'completed': False
})
plan = {
'id': f"plan_{datetime.now().strftime('%Y%m%d_%H%M%S')}",
'created_at': datetime.now().isoformat(),
'current_level': current_level,
'target_level': target_level,
'weekly_hours': weekly_hours,
'estimated_weeks': adjusted_weeks,
'completion_date': completion_date,
'weekly_structure': weekly_structure,
'study_tips': study_tips,
'milestones': milestones,
'interests': interests,
'context_focus': context_focus,
'study_goals': study_goals
}
return plan
import json
from datetime import datetime
# In-memory study plan storage (testing only)
_MEM_STUDY_PLAN = None
def save_study_plan(plan_data):
"""Store the study plan in memory (no disk IO)."""
global _MEM_STUDY_PLAN
try:
if isinstance(plan_data, dict):
plan_data = dict(plan_data)
plan_data['saved_at'] = datetime.now().isoformat()
_MEM_STUDY_PLAN = plan_data
return True
except Exception as e:
logger.warning(f"Failed to save study plan in-memory: {e}")
return False
def load_study_plan():
"""Load the study plan from in-memory storage."""
return _MEM_STUDY_PLAN