OUAREDAEK commited on
Commit
f6b3e37
·
verified ·
1 Parent(s): c8b7c8b

Upload app.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. app.py +145 -6
app.py CHANGED
@@ -63,9 +63,29 @@ LEARNER_STATE = load_json_file(LEARNER_STATE_FILE, {
63
  "success_rate": 0.0
64
  })
65
 
66
- # Intervalles SM-2 simplifiés
67
  SM2_INTERVALS = [1, 3, 7, 14, 30, 60]
68
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
69
  # ======================================================
70
  # ROUTES PRINCIPALES
71
  # ======================================================
@@ -79,6 +99,25 @@ def home():
79
  def get_competences():
80
  return jsonify(COMPETENCES)
81
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
82
  @app.route('/api/planner/generate', methods=['POST'])
83
  def generate_planner():
84
  try:
@@ -87,28 +126,38 @@ def generate_planner():
87
  start_date = datetime.strptime(data.get('start_date', '2026-01-01'), '%Y-%m-%d')
88
  duration = int(data.get('session_duration', 20))
89
  repetitions = int(data.get('repetitions', 6))
 
 
 
 
90
 
91
  plan = []
92
  current_date = start_date
93
 
94
- for i in range(min(repetitions, len(SM2_INTERVALS))):
95
  plan.append({
96
  'date': current_date.strftime('%Y-%m-%d'),
97
  'jour': current_date.strftime('%A'),
98
  'competence': competence,
99
  'repetition': i + 1,
100
  'duree': f'{duration} minutes',
101
- 'intervalle': f'+{SM2_INTERVALS[i]} jours',
102
  'type': 'Apprentissage' if i == 0 else 'Révision espacée',
103
- 'strategie': 'Active Recall + Élaboration'
 
104
  })
105
- current_date += timedelta(days=SM2_INTERVALS[i])
106
 
107
  # Sauvegarder
108
  PLANNER.extend(plan)
109
  save_json_file(PLANNER_FILE, PLANNER)
110
 
111
- return jsonify({'success': True, 'plan': plan})
 
 
 
 
 
112
  except Exception as e:
113
  return jsonify({'success': False, 'error': str(e)})
114
 
@@ -139,6 +188,13 @@ def save_journal():
139
  except Exception as e:
140
  return jsonify({'success': False, 'error': str(e)})
141
 
 
 
 
 
 
 
 
142
  @app.route('/api/notifications')
143
  def get_notification():
144
  messages = [
@@ -156,6 +212,37 @@ def get_notification():
156
  'type': 'reminder'
157
  })
158
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
159
  @app.route('/api/stats')
160
  def get_stats():
161
  return jsonify({
@@ -166,17 +253,69 @@ def get_stats():
166
  'engagement': LEARNER_STATE.get('engagement', 'stable')
167
  })
168
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
169
  @app.route('/api/sm2/explain')
170
  def explain_sm2():
171
  return jsonify({
172
  'title': 'Algorithme SM-2',
173
  'description': 'Répétition espacée optimisée pour la rétention mémoire',
 
 
 
 
 
 
174
  'intervals': SM2_INTERVALS,
175
  'principles': [
176
  'Réviser juste avant d\'oublier',
177
  'Augmenter l\'intervalle progressivement',
178
  'Adapter selon la difficulté',
179
  'Être régulier dans la pratique'
 
 
 
 
 
 
180
  ]
181
  })
182
 
 
63
  "success_rate": 0.0
64
  })
65
 
66
+ # Intervalles SM-2 de base
67
  SM2_INTERVALS = [1, 3, 7, 14, 30, 60]
68
 
69
+ # ======================================================
70
+ # FONCTIONS UTILITAIRES
71
+ # ======================================================
72
+
73
+ def get_reminder_for_quality(quality_level):
74
+ """Retourne un rappel adapté au niveau de qualité"""
75
+ reminders = [
76
+ "🧠 Révision fréquente conseillée pour renforcer la mémoire",
77
+ "📚 Répétition espacée standard recommandée",
78
+ "🚀 Excellente progression, continuez ainsi !",
79
+ "🏆 Niveau expert, rétention à long terme optimale"
80
+ ]
81
+ return reminders[min(quality_level, 3)]
82
+
83
+ def get_intervals_for_quality(quality_level):
84
+ """Retourne les intervalles adaptés au niveau de qualité"""
85
+ quality_multipliers = [0.7, 1.0, 1.5, 2.0]
86
+ multiplier = quality_multipliers[min(quality_level, 3)]
87
+ return [int(interval * multiplier) for interval in SM2_INTERVALS]
88
+
89
  # ======================================================
90
  # ROUTES PRINCIPALES
91
  # ======================================================
 
99
  def get_competences():
100
  return jsonify(COMPETENCES)
101
 
102
+ @app.route('/api/planner/visualize')
103
+ def visualize_planner():
104
+ """Génère les données de visualisation pour la courbe SM-2"""
105
+ try:
106
+ competence = request.args.get('competence', 'Compétence')
107
+ quality = int(request.args.get('quality', 1))
108
+
109
+ intervals = get_intervals_for_quality(quality)
110
+
111
+ return jsonify({
112
+ 'success': True,
113
+ 'intervals': intervals,
114
+ 'competence': competence,
115
+ 'quality_level': quality,
116
+ 'description': f'Courbe SM-2 adaptée (Niveau {quality})'
117
+ })
118
+ except Exception as e:
119
+ return jsonify({'success': False, 'error': str(e)})
120
+
121
  @app.route('/api/planner/generate', methods=['POST'])
122
  def generate_planner():
123
  try:
 
126
  start_date = datetime.strptime(data.get('start_date', '2026-01-01'), '%Y-%m-%d')
127
  duration = int(data.get('session_duration', 20))
128
  repetitions = int(data.get('repetitions', 6))
129
+ quality_level = int(data.get('quality_level', 1))
130
+
131
+ # Obtenir les intervalles adaptés
132
+ adjusted_intervals = get_intervals_for_quality(quality_level)
133
 
134
  plan = []
135
  current_date = start_date
136
 
137
+ for i in range(min(repetitions, len(adjusted_intervals))):
138
  plan.append({
139
  'date': current_date.strftime('%Y-%m-%d'),
140
  'jour': current_date.strftime('%A'),
141
  'competence': competence,
142
  'repetition': i + 1,
143
  'duree': f'{duration} minutes',
144
+ 'intervalle': f'+{adjusted_intervals[i]} jours',
145
  'type': 'Apprentissage' if i == 0 else 'Révision espacée',
146
+ 'strategie': 'Active Recall + Élaboration',
147
+ 'reminder': get_reminder_for_quality(quality_level)
148
  })
149
+ current_date += timedelta(days=adjusted_intervals[i])
150
 
151
  # Sauvegarder
152
  PLANNER.extend(plan)
153
  save_json_file(PLANNER_FILE, PLANNER)
154
 
155
+ return jsonify({
156
+ 'success': True,
157
+ 'plan': plan,
158
+ 'intervals': adjusted_intervals,
159
+ 'quality_level': quality_level
160
+ })
161
  except Exception as e:
162
  return jsonify({'success': False, 'error': str(e)})
163
 
 
188
  except Exception as e:
189
  return jsonify({'success': False, 'error': str(e)})
190
 
191
+ @app.route('/api/journal/entries')
192
+ def get_journal_entries():
193
+ """Récupère les dernières entrées du journal"""
194
+ limit = int(request.args.get('limit', 5))
195
+ entries = JOURNAL[-limit:] if len(JOURNAL) > limit else JOURNAL
196
+ return jsonify(entries)
197
+
198
  @app.route('/api/notifications')
199
  def get_notification():
200
  messages = [
 
212
  'type': 'reminder'
213
  })
214
 
215
+ @app.route('/api/notifications/intelligent')
216
+ def get_intelligent_notification():
217
+ """Notifications plus élaborées"""
218
+ notifications = [
219
+ {
220
+ 'message': "🌱 5 minutes aujourd'hui renforcent durablement votre mémoire.",
221
+ 'type': 'motivation',
222
+ 'effectiveness_score': 0.85
223
+ },
224
+ {
225
+ 'message': "⏰ Une courte révision maintenant évite l'oubli.",
226
+ 'type': 'rappel_court',
227
+ 'effectiveness_score': 0.92
228
+ },
229
+ {
230
+ 'message': "💪 Votre régularité montre une vraie progression.",
231
+ 'type': 'encouragement',
232
+ 'effectiveness_score': 0.78
233
+ },
234
+ {
235
+ 'message': "🤔 Quelle stratégie vous aide le plus aujourd'hui ?",
236
+ 'type': 'metacognition',
237
+ 'effectiveness_score': 0.88
238
+ }
239
+ ]
240
+
241
+ notification = np.random.choice(notifications)
242
+ notification['timestamp'] = datetime.now().isoformat()
243
+
244
+ return jsonify(notification)
245
+
246
  @app.route('/api/stats')
247
  def get_stats():
248
  return jsonify({
 
253
  'engagement': LEARNER_STATE.get('engagement', 'stable')
254
  })
255
 
256
+ @app.route('/api/learner/stats')
257
+ def get_learner_stats():
258
+ """Statistiques détaillées de l'apprenant"""
259
+ retention_data = LEARNER_STATE.get('retention', {})
260
+
261
+ # Calculer le niveau d'engagement
262
+ total_sessions = LEARNER_STATE.get('total_sessions', 0)
263
+ if total_sessions > 20:
264
+ engagement = 'high'
265
+ elif total_sessions > 10:
266
+ engagement = 'medium'
267
+ else:
268
+ engagement = 'low'
269
+
270
+ # Calculer le niveau de risque
271
+ days_inactive = LEARNER_STATE.get('days_inactive', 0)
272
+ if days_inactive > 7:
273
+ risk = 'high'
274
+ elif days_inactive > 3:
275
+ risk = 'medium'
276
+ else:
277
+ risk = 'low'
278
+
279
+ return jsonify({
280
+ 'total_sessions': total_sessions,
281
+ 'success_rate': round(LEARNER_STATE.get('success_rate', 0), 2),
282
+ 'journal_entries': len(JOURNAL),
283
+ 'planned_sessions': len(PLANNER),
284
+ 'engagement_level': engagement,
285
+ 'risk_level': risk,
286
+ 'days_inactive': days_inactive,
287
+ 'retention_rates': retention_data,
288
+ 'notification_effectiveness': {
289
+ 'motivation': 0.85,
290
+ 'rappel_court': 0.92,
291
+ 'encouragement': 0.78,
292
+ 'metacognition': 0.88
293
+ }
294
+ })
295
+
296
  @app.route('/api/sm2/explain')
297
  def explain_sm2():
298
  return jsonify({
299
  'title': 'Algorithme SM-2',
300
  'description': 'Répétition espacée optimisée pour la rétention mémoire',
301
+ 'quality_levels': {
302
+ '0': 'Difficulté - Révisions fréquentes nécessaires',
303
+ '1': 'Moyen - Intervalles standard',
304
+ '2': 'Bon - Consolidation progressive',
305
+ '3': 'Excellent - Rétention long terme'
306
+ },
307
  'intervals': SM2_INTERVALS,
308
  'principles': [
309
  'Réviser juste avant d\'oublier',
310
  'Augmenter l\'intervalle progressivement',
311
  'Adapter selon la difficulté',
312
  'Être régulier dans la pratique'
313
+ ],
314
+ 'recommendations': [
315
+ 'Commencez avec des sessions courtes (10-20 minutes)',
316
+ 'Augmentez la durée progressivement',
317
+ 'Notez votre niveau de confiance après chaque session',
318
+ 'Ajustez les intervalles selon vos résultats'
319
  ]
320
  })
321