Spaces:
Sleeping
Sleeping
File size: 9,124 Bytes
0143084 be3ddee 0143084 be3ddee 0143084 be3ddee 0143084 be3ddee | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 | 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
|