amauricunha commited on
Commit
87f6e1c
·
verified ·
1 Parent(s): ab3c972

Delete study_planner.py

Browse files
Files changed (1) hide show
  1. study_planner.py +0 -460
study_planner.py DELETED
@@ -1,460 +0,0 @@
1
- # study_planner.py
2
- import json
3
- from datetime import datetime, timedelta, date
4
- from typing import Dict, List, Any
5
- import logging
6
- from groq import Groq
7
- import google.generativeai as genai
8
- import os
9
-
10
- logger = logging.getLogger(__name__)
11
-
12
- # Initialize AI clients (reuse from main app)
13
- groq_client = None
14
- genai_client = None
15
-
16
- try:
17
- GROQ_API_KEY = os.environ.get("GROQ_API_KEY")
18
- if GROQ_API_KEY:
19
- groq_client = Groq(api_key=GROQ_API_KEY)
20
- except Exception as e:
21
- logger.warning(f"Groq client not available: {e}")
22
-
23
- try:
24
- GEMINI_API_KEY = os.environ.get("GEMINI_API_KEY")
25
- if GEMINI_API_KEY:
26
- genai.configure(api_key=GEMINI_API_KEY)
27
- genai_client = genai
28
- except Exception as e:
29
- logger.warning(f"Gemini client not available: {e}")
30
-
31
- class StudyPlanner:
32
- def __init__(self):
33
- self.level_progression = {
34
- 'A1': {'next': 'A2', 'weeks': 12, 'focus': ['basic vocabulary', 'present tense', 'introductions']},
35
- 'A2': {'next': 'B1', 'weeks': 16, 'focus': ['past tense', 'future tense', 'everyday situations']},
36
- 'B1': {'next': 'B2', 'weeks': 20, 'focus': ['conditional', 'complex sentences', 'opinions']},
37
- 'B2': {'next': 'C1', 'weeks': 24, 'focus': ['subjunctive', 'formal writing', 'presentations']},
38
- 'C1': {'next': 'C2', 'weeks': 28, 'focus': ['nuanced expressions', 'academic writing', 'debates']},
39
- 'C2': {'next': 'C2', 'weeks': 32, 'focus': ['native-like fluency', 'specialized topics', 'literature']}
40
- }
41
-
42
- self.activity_types = {
43
- 'reading': {
44
- 'icon': '📚',
45
- 'min_duration': 20,
46
- 'max_duration': 45,
47
- 'difficulty_scaling': True,
48
- 'description': 'Read articles and texts'
49
- },
50
- 'flashcards': {
51
- 'icon': '🃏',
52
- 'min_duration': 10,
53
- 'max_duration': 25,
54
- 'difficulty_scaling': False,
55
- 'description': 'Review vocabulary flashcards'
56
- },
57
- 'conversation': {
58
- 'icon': '💬',
59
- 'min_duration': 15,
60
- 'max_duration': 30,
61
- 'difficulty_scaling': True,
62
- 'description': 'Practice speaking and conversation'
63
- },
64
- 'writing': {
65
- 'icon': '✍️',
66
- 'min_duration': 15,
67
- 'max_duration': 40,
68
- 'difficulty_scaling': True,
69
- 'description': 'Complete writing exercises'
70
- },
71
- 'listening': {
72
- 'icon': '🎧',
73
- 'min_duration': 15,
74
- 'max_duration': 30,
75
- 'difficulty_scaling': True,
76
- 'description': 'Listen to audio content'
77
- },
78
- 'grammar': {
79
- 'icon': '📝',
80
- 'min_duration': 10,
81
- 'max_duration': 25,
82
- 'difficulty_scaling': True,
83
- 'description': 'Study grammar rules and patterns'
84
- }
85
- }
86
-
87
- def generate_personalized_plan(self, user_data: Dict[str, Any]) -> Dict[str, Any]:
88
- """Generate a comprehensive study plan based on user data"""
89
- try:
90
- current_level = user_data.get('english_level', 'B1')
91
- target_level = user_data.get('target_level', 'B2')
92
- weekly_hours = user_data.get('weekly_hours', 5)
93
- interests = user_data.get('interests', {})
94
- context_focus = user_data.get('context_focus', 'General/Social')
95
- study_goals = user_data.get('study_goals', [])
96
-
97
- # Calculate timeline
98
- timeline = self._calculate_study_timeline(current_level, target_level, weekly_hours)
99
-
100
- # Generate weekly structure
101
- weekly_structure = self._create_weekly_structure(weekly_hours, current_level, context_focus)
102
-
103
- # Create specific activities
104
- activities = self._generate_weekly_activities(
105
- weekly_structure, interests, current_level, context_focus, study_goals
106
- )
107
-
108
- # Generate AI-powered study tips
109
- study_tips = self._generate_ai_study_tips(user_data)
110
-
111
- plan = {
112
- 'id': f"plan_{datetime.now().strftime('%Y%m%d_%H%M%S')}",
113
- 'created_at': datetime.now().isoformat(),
114
- 'current_level': current_level,
115
- 'target_level': target_level,
116
- 'weekly_hours': weekly_hours,
117
- 'estimated_weeks': timeline['weeks'],
118
- 'completion_date': timeline['completion_date'],
119
- 'weekly_structure': weekly_structure,
120
- 'activities': activities,
121
- 'study_tips': study_tips,
122
- 'milestones': self._create_milestones(current_level, target_level, timeline['weeks']),
123
- 'adaptations': self._suggest_adaptations(user_data)
124
- }
125
-
126
- return {'success': True, 'plan': plan}
127
-
128
- except Exception as e:
129
- logger.error(f"Error generating study plan: {e}")
130
- return {'success': False, 'error': str(e)}
131
-
132
- def _calculate_study_timeline(self, current_level: str, target_level: str, weekly_hours: int) -> Dict[str, Any]:
133
- """Calculate realistic timeline for reaching target level"""
134
- try:
135
- current_info = self.level_progression.get(current_level, self.level_progression['B1'])
136
- base_weeks = current_info['weeks']
137
-
138
- # Adjust based on weekly hours (baseline is 5 hours/week)
139
- hour_multiplier = 5 / max(weekly_hours, 1)
140
- adjusted_weeks = int(base_weeks * hour_multiplier)
141
-
142
- # If targeting multiple levels ahead, add additional time
143
- level_order = ['A1', 'A2', 'B1', 'B2', 'C1', 'C2']
144
- current_idx = level_order.index(current_level) if current_level in level_order else 2
145
- target_idx = level_order.index(target_level) if target_level in level_order else 3
146
-
147
- if target_idx > current_idx + 1:
148
- # Multiple levels - add 20% more time
149
- adjusted_weeks = int(adjusted_weeks * 1.2 * (target_idx - current_idx))
150
-
151
- completion_date = (datetime.now() + timedelta(weeks=adjusted_weeks)).date()
152
-
153
- return {
154
- 'weeks': adjusted_weeks,
155
- 'completion_date': completion_date.isoformat(),
156
- 'intensity': 'High' if weekly_hours > 7 else 'Medium' if weekly_hours > 4 else 'Light'
157
- }
158
-
159
- except Exception as e:
160
- logger.error(f"Error calculating timeline: {e}")
161
- return {'weeks': 16, 'completion_date': (datetime.now() + timedelta(weeks=16)).date().isoformat()}
162
-
163
- def _create_weekly_structure(self, weekly_hours: int, level: str, context: str) -> Dict[str, Any]:
164
- """Create optimal weekly study structure"""
165
- try:
166
- # Base distribution percentages
167
- distributions = {
168
- 'A1': {'reading': 0.25, 'flashcards': 0.30, 'conversation': 0.20, 'writing': 0.15, 'grammar': 0.10},
169
- 'A2': {'reading': 0.30, 'flashcards': 0.25, 'conversation': 0.20, 'writing': 0.15, 'grammar': 0.10},
170
- 'B1': {'reading': 0.30, 'flashcards': 0.20, 'conversation': 0.25, 'writing': 0.20, 'listening': 0.05},
171
- 'B2': {'reading': 0.25, 'flashcards': 0.15, 'conversation': 0.25, 'writing': 0.25, 'listening': 0.10},
172
- 'C1': {'reading': 0.30, 'flashcards': 0.10, 'conversation': 0.25, 'writing': 0.25, 'listening': 0.10},
173
- 'C2': {'reading': 0.35, 'flashcards': 0.05, 'conversation': 0.25, 'writing': 0.25, 'listening': 0.10}
174
- }
175
-
176
- base_dist = distributions.get(level, distributions['B1'])
177
-
178
- # Adjust based on context
179
- if context == 'Professional/Business':
180
- base_dist['writing'] = min(base_dist['writing'] + 0.10, 0.40)
181
- base_dist['reading'] = max(base_dist['reading'] - 0.05, 0.15)
182
- base_dist['conversation'] = max(base_dist['conversation'] - 0.05, 0.15)
183
- elif context == 'Technical/IT':
184
- base_dist['reading'] = min(base_dist['reading'] + 0.10, 0.45)
185
- base_dist['flashcards'] = min(base_dist['flashcards'] + 0.05, 0.35)
186
- base_dist['conversation'] = max(base_dist['conversation'] - 0.10, 0.15)
187
-
188
- # Convert to actual hours
189
- weekly_structure = {}
190
- total_minutes = weekly_hours * 60
191
-
192
- for activity, percentage in base_dist.items():
193
- minutes = int(total_minutes * percentage)
194
- if minutes >= self.activity_types[activity]['min_duration']:
195
- weekly_structure[activity] = {
196
- 'minutes_per_week': minutes,
197
- 'sessions_per_week': max(1, minutes // 30), # Aim for 30-min sessions
198
- 'minutes_per_session': minutes // max(1, minutes // 30)
199
- }
200
-
201
- return weekly_structure
202
-
203
- except Exception as e:
204
- logger.error(f"Error creating weekly structure: {e}")
205
- return {}
206
-
207
- def _generate_weekly_activities(self, structure: Dict, interests: Dict, level: str, context: str, goals: List) -> List[Dict]:
208
- """Generate specific weekly activities"""
209
- activities = []
210
-
211
- try:
212
- for activity_type, schedule in structure.items():
213
- activity_info = self.activity_types[activity_type]
214
-
215
- for session in range(schedule['sessions_per_week']):
216
- activity = {
217
- 'id': f"{activity_type}_{session + 1}",
218
- 'type': activity_type,
219
- 'icon': activity_info['icon'],
220
- 'title': f"{activity_info['description']}",
221
- 'duration_minutes': schedule['minutes_per_session'],
222
- 'difficulty': level,
223
- 'context': context,
224
- 'day_of_week': (session * 2) % 7, # Spread throughout week
225
- 'specific_tasks': self._generate_specific_tasks(activity_type, level, context, interests, goals)
226
- }
227
- activities.append(activity)
228
-
229
- # Sort by day of week
230
- activities.sort(key=lambda x: x['day_of_week'])
231
-
232
- return activities
233
-
234
- except Exception as e:
235
- logger.error(f"Error generating activities: {e}")
236
- return []
237
-
238
- def _generate_specific_tasks(self, activity_type: str, level: str, context: str, interests: Dict, goals: List) -> List[str]:
239
- """Generate specific tasks for each activity type"""
240
- tasks = []
241
-
242
- try:
243
- interest_topics = list(interests.keys())[:3] if interests else ['general topics']
244
-
245
- if activity_type == 'reading':
246
- tasks = [
247
- f"Read a {context.lower()} article about {topic}" for topic in interest_topics
248
- ] + [
249
- f"Practice reading comprehension with {level}-level texts",
250
- "Identify new vocabulary and create flashcards"
251
- ]
252
-
253
- elif activity_type == 'flashcards':
254
- tasks = [
255
- "Review previous day's vocabulary",
256
- "Practice new words from recent reading",
257
- f"Focus on {context.lower()} terminology"
258
- ]
259
-
260
- elif activity_type == 'conversation':
261
- tasks = [
262
- f"Discuss {topic} using {level}-level vocabulary" for topic in interest_topics[:2]
263
- ] + [
264
- "Practice pronunciation with AI feedback",
265
- f"Role-play {context.lower()} scenarios"
266
- ]
267
-
268
- elif activity_type == 'writing':
269
- tasks = [
270
- f"Write a short text about {topic}" for topic in interest_topics[:1]
271
- ] + [
272
- f"Practice {context.lower()} writing format s",
273
- "Get AI feedback on grammar and style"
274
- ]
275
-
276
- elif activity_type == 'listening':
277
- tasks = [
278
- f"Listen to content about {topic}" for topic in interest_topics[:2]
279
- ] + [
280
- "Practice with different accents",
281
- "Take notes while listening"
282
- ]
283
-
284
- elif activity_type == 'grammar':
285
- level_grammar = {
286
- 'A1': ['present tense', 'basic sentence structure', 'personal pronouns'],
287
- 'A2': ['past tense', 'future tense', 'comparatives'],
288
- 'B1': ['present perfect', 'conditional sentences', 'passive voice'],
289
- 'B2': ['subjunctive mood', 'complex sentences', 'reported speech'],
290
- 'C1': ['advanced tenses', 'nuanced expressions', 'formal structures'],
291
- 'C2': ['idiomatic expressions', 'stylistic variations', 'literary devices']
292
- }
293
-
294
- tasks = [f"Study {topic}" for topic in level_grammar.get(level, level_grammar['B1'])]
295
-
296
- return tasks[:3] # Limit to 3 tasks per activity
297
-
298
- except Exception as e:
299
- logger.error(f"Error generating specific tasks: {e}")
300
- return ["Complete activity as planned"]
301
-
302
- def _generate_ai_study_tips(self, user_data: Dict) -> List[str]:
303
- """Generate personalized study tips using AI"""
304
- try:
305
- if not groq_client and not genai_client:
306
- return self._get_default_tips(user_data.get('english_level', 'B1'))
307
-
308
- prompt = f"""
309
- Generate 5 personalized English study tips for a user with these characteristics:
310
- - Current Level: {user_data.get('english_level', 'B1')}
311
- - Target Level: {user_data.get('target_level', 'B2')}
312
- - Weekly Study Time: {user_data.get('weekly_hours', 5)} hours
313
- - Context Focus: {user_data.get('context_focus', 'General/Social')}
314
- - Interests: {', '.join(user_data.get('interests', {}).keys())}
315
-
316
- Provide practical, actionable tips that are specific to their level and interests.
317
- Format as a simple list of tips, each starting with an emoji.
318
- """
319
-
320
- response_text = None
321
- if groq_client:
322
- response = groq_client.chat.completions.create(
323
- model="llama-3.1-8b-instant",
324
- messages=[{"role": "user", "content": prompt}],
325
- temperature=0.7
326
- )
327
- response_text = response.choices[0].message.content
328
- elif genai_client:
329
- model = genai_client.GenerativeModel('gemini-2.5-flash-latest')
330
- response = model.generate_content(prompt)
331
- response_text = response.text
332
-
333
- if response_text:
334
- # Extract tips from response
335
- tips = [line.strip() for line in response_text.split('\n') if line.strip() and ('📚' in line or '💡' in line or '🎯' in line or '⭐' in line or '🚀' in line)]
336
- return tips[:5] if tips else self._get_default_tips(user_data.get('english_level', 'B1'))
337
-
338
- return self._get_default_tips(user_data.get('english_level', 'B1'))
339
-
340
- except Exception as e:
341
- logger.error(f"Error generating AI study tips: {e}")
342
- return self._get_default_tips(user_data.get('english_level', 'B1'))
343
-
344
- def _get_default_tips(self, level: str) -> List[str]:
345
- """Get default study tips based on level"""
346
- tips_by_level = {
347
- 'A1': [
348
- "📚 Start with basic vocabulary - 10 new words daily",
349
- "🎯 Focus on present tense in daily conversations",
350
- "💡 Use picture dictionaries for visual learning",
351
- "⭐ Practice pronunciation with simple audio materials",
352
- "🚀 Don't worry about mistakes - communication is key!"
353
- ],
354
- 'A2': [
355
- "📚 Read simple news articles and stories",
356
- "🎯 Practice past and future tenses regularly",
357
- "💡 Join basic English conversation groups",
358
- "⭐ Use language learning apps for daily practice",
359
- "🚀 Watch movies with subtitles in your language"
360
- ],
361
- 'B1': [
362
- "📚 Read intermediate articles on topics you enjoy",
363
- "🎯 Practice expressing opinions and preferences",
364
- "💡 Start writing short paragraphs daily",
365
- "⭐ Listen to podcasts at normal speed",
366
- "🚀 Try to think in English for simple tasks"
367
- ],
368
- 'B2': [
369
- "📚 Read longer articles and opinion pieces",
370
- "🎯 Practice formal and informal writing styles",
371
- "💡 Engage in debates and discussions",
372
- "⭐ Watch news programs without subtitles",
373
- "🚀 Set specific goals for each study session"
374
- ],
375
- 'C1': [
376
- "📚 Read academic and professional texts",
377
- "🎯 Practice nuanced expressions and idioms",
378
- "💡 Write formal reports and presentations",
379
- "⭐ Listen to academic lectures and conferences",
380
- "🚀 Focus on specialized vocabulary for your field"
381
- ],
382
- 'C2': [
383
- "📚 Read literature and complex analytical texts",
384
- "🎯 Master subtle language differences",
385
- "💡 Write with stylistic sophistication",
386
- "⭐ Engage with native speakers in professional contexts",
387
- "🚀 Aim for native-like fluency in all skills"
388
- ]
389
- }
390
-
391
- return tips_by_level.get(level, tips_by_level['B1'])
392
-
393
- def _create_milestones(self, current_level: str, target_level: str, weeks: int) -> List[Dict]:
394
- """Create progress milestones"""
395
- milestones = []
396
-
397
- try:
398
- milestone_intervals = max(2, weeks // 4) # Create 4 milestones
399
-
400
- for i in range(1, 5):
401
- week = milestone_intervals * i
402
- if week <= weeks:
403
- milestone = {
404
- 'week': week,
405
- 'title': f"Milestone {i}",
406
- 'description': self._get_milestone_description(i, current_level, target_level),
407
- 'target_date': (datetime.now() + timedelta(weeks=week)).date().isoformat(),
408
- 'completed': False
409
- }
410
- milestones.append(milestone)
411
-
412
- return milestones
413
-
414
- except Exception as e:
415
- logger.error(f"Error creating milestones: {e}")
416
- return []
417
-
418
- def _get_milestone_description(self, milestone_num: int, current_level: str, target_level: str) -> str:
419
- """Get description for milestone"""
420
- descriptions = {
421
- 1: f"Complete foundation review and establish study routine",
422
- 2: f"Reach intermediate proficiency between {current_level} and {target_level}",
423
- 3: f"Demonstrate advanced skills approaching {target_level} level",
424
- 4: f"Achieve {target_level} level proficiency in all skills"
425
- }
426
-
427
- return descriptions.get(milestone_num, f"Progress checkpoint {milestone_num}")
428
-
429
- def _suggest_adaptations(self, user_data: Dict) -> List[str]:
430
- """Suggest plan adaptations based on user data"""
431
- adaptations = []
432
-
433
- try:
434
- weekly_hours = user_data.get('weekly_hours', 5)
435
- context = user_data.get('context_focus', 'General/Social')
436
- level = user_data.get('english_level', 'B1')
437
-
438
- if weekly_hours < 4:
439
- adaptations.append("💡 Consider increasing study time to 4+ hours/week for faster progress")
440
-
441
- if weekly_hours > 8:
442
- adaptations.append("⚠️ Ensure you don't burn out - quality over quantity")
443
-
444
- if context == 'Professional/Business':
445
- adaptations.append("📊 Focus extra time on business writing and presentation skills")
446
-
447
- if context == 'Technical/IT':
448
- adaptations.append("💻 Include technical documentation reading in your routine")
449
-
450
- if level in ['C1', 'C2']:
451
- adaptations.append("🎯 Consider specialized courses or certification preparation")
452
-
453
- return adaptations[:3] # Limit to 3 adaptations
454
-
455
- except Exception as e:
456
- logger.error(f"Error suggesting adaptations: {e}")
457
- return []
458
-
459
- # Global instance
460
- study_planner = StudyPlanner()