CoolFace
Apppublic

amalmuthu/AdaptiveLearning

sourceHugging Faceupdated 2y agoView on Hugging Face
0likes
app.py765 linesDownload Raw Back to root
1from flask import Flask, render_template, request, jsonify
2import numpy as np
3import pandas as pd
4from sklearn.ensemble import RandomForestClassifier
5from sklearn.preprocessing import StandardScaler
6from tensorflow.keras.models import Sequential
7from tensorflow.keras.layers import Dense, Dropout, LSTM
8from collections import defaultdict
9import time
10from scipy.stats import percentileofscore
11
12app = Flask(__name__)
13
14class AIModel:
15    def __init__(self):
16        self.performance_predictor = self._create_lstm_predictor()
17        self.path_recommender = self._create_path_recommender()
18        self.scaler = StandardScaler()
19        self._train_models()
20        
21    def _create_lstm_predictor(self):
22       from tensorflow.keras.layers import Input
23       from tensorflow.keras.models import Model
24
25       inputs = Input(shape=(10, 5))
26       x = LSTM(64, return_sequences=True)(inputs)
27       x = Dropout(0.2)(x)
28       x = LSTM(32)(x)
29       x = Dense(16, activation='relu')(x)
30       x = Dropout(0.2)(x)
31       outputs = Dense(1, activation='sigmoid')(x)
32    
33       model = Model(inputs=inputs, outputs=outputs)
34       model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
35       return model
36
37
38    def _create_path_recommender(self):
39        return RandomForestClassifier(n_estimators=100, max_depth=10, random_state=42)
40    
41    def _train_models(self):
42        X_lstm, y_lstm, X_rf, y_rf = self._generate_training_data()
43        self.performance_predictor.fit(X_lstm, y_lstm, epochs=10, batch_size=32, verbose=0)
44        self.path_recommender.fit(X_rf, y_rf)
45
46    def _generate_training_data(self):
47        n_students = 100
48        n_timesteps = 10
49        n_features = 5
50        
51        X_lstm = []
52        y_lstm = []
53        X_rf = []
54        y_rf = []
55        
56        for _ in range(n_students):
57            student_sequence = []
58            for t in range(n_timesteps):
59                base_score = np.random.normal(75, 15)
60                improvement = t * 2
61                score = min(max(base_score + improvement, 0), 100)
62                
63                time_spent = np.random.normal(45, 15)
64                knowledge = min(0.1 * t + np.random.normal(0.5, 0.1), 1)
65                velocity = score / (time_spent / 60)
66                progress = t / n_timesteps
67                
68                student_sequence.append([
69                    score/100,
70                    time_spent/60,
71                    knowledge,
72                    velocity/100,
73                    progress
74                ])
75            
76            final_performance = np.mean([seq[0] for seq in student_sequence[-3:]])
77            X_lstm.append(student_sequence)
78            y_lstm.append(final_performance)
79        
80        topics = ['algebra', 'geometry', 'calculus', 'physics', 'chemistry']
81        difficulties = [0.7, 0.6, 0.9, 0.8, 0.7]
82        
83        for _ in range(n_students * len(topics)):
84            knowledge = np.random.uniform(0, 1)
85            topic_idx = np.random.randint(0, len(topics))
86            difficulty = difficulties[topic_idx]
87            prerequisites_met = np.random.uniform(0, 1)
88            past_performance = np.random.normal(0.75, 0.15)
89            study_time = np.random.uniform(0.5, 2.0)
90            
91            success = int(
92                knowledge > difficulty - 0.2 and
93                prerequisites_met > 0.7 and
94                past_performance > 0.6 and
95                study_time > 0.8
96            )
97            
98            X_rf.append([
99                knowledge,
100                difficulty,
101                prerequisites_met,
102                past_performance,
103                study_time
104            ])
105            y_rf.append(success)
106        
107        return np.array(X_lstm), np.array(y_lstm), np.array(X_rf), np.array(y_rf)
108
109
110    #Training LSTM with actual student data ( Not being used here)
111    def train_with_student_data(self, student):
112        # Prepare sequence data
113        X = []
114        y = []
115        
116        for subject, data in student.subjects.items():
117            scores = data['scores']
118            times = data['time_spent']
119            knowledge_states = list(student.knowledge_state.values())
120            
121            # Create sequences of 10 timesteps
122            for i in range(len(scores) - 10):
123                sequence = []
124                for j in range(10):
125                    sequence.append([
126                        scores[i+j]/100,  # Normalized score
127                        times[i+j]/3600,  # Time in hours
128                        knowledge_states[i+j],  # Knowledge state
129                        data['recent_velocity'][i+j],  # Learning velocity
130                        len(data['topics_completed'])/len(self.topics[subject])  # Progress
131                    ])
132                
133                # Target is the next score
134                target = scores[i+10]/100
135                
136                X.append(sequence)
137                y.append(target)
138        
139        X = np.array(X)
140        y = np.array(y)
141        
142        # Train the model
143        self.performance_predictor.fit(
144            X, y,
145            epochs=10,
146            batch_size=32,
147            validation_split=0.2,
148            verbose=1
149        )
150
151    #Update the model ( Not being used here )
152    def update_model(self, all_students):
153        X_all = []
154        y_all = []
155        
156        for student in all_students:
157            X_student, y_student = self.prepare_student_data(student)
158            X_all.extend(X_student)
159            y_all.extend(y_student)
160        
161        X_all = np.array(X_all)
162        y_all = np.array(y_all)
163        
164        # Retrain model with all accumulated data
165        self.performance_predictor.fit(
166            X_all, y_all,
167            epochs=10,
168            batch_size=32,
169            validation_split=0.2,
170            verbose=1
171        )
172
173    def _prepare_student_sequence(self, student):
174        sequence = np.zeros((10, 5))  # Pre-allocate fixed-size array
175        current_pos = 0
176        
177        for subject, data in student.subjects.items():
178            scores = data['scores'][-10:] if data['scores'] else []
179            if not scores:
180                continue
181                
182            times = [data['time_spent']/len(data['scores']) for _ in range(len(scores))]
183            knowledge = [student.knowledge_state.get(topic, 0) for topic in data['topics_completed']][-10:]
184            velocities = data['recent_velocity'][-10:] if data['recent_velocity'] else []
185            
186            max_velocity = max(velocities) if velocities and max(velocities) > 0 else 1
187            normalized_velocities = np.array(velocities) / max_velocity if velocities else []
188            
189            for i in range(min(len(scores), 10 - current_pos)):
190                sequence[current_pos + i] = [
191                    scores[i] / 100,
192                    times[i] / 3600,
193                    np.mean(knowledge) if knowledge else 0,
194                    normalized_velocities[i] if i < len(normalized_velocities) else 0,
195                    len(data['topics_completed']) / len(self.topics[subject])
196                ]
197            current_pos += min(len(scores), 10 - current_pos)
198            if current_pos >= 10:
199                break
200                
201        return np.array([sequence])
202
203
204    def predict_performance(self, student):
205        sequence = self._prepare_student_sequence(student)
206        prediction = self.performance_predictor.predict(sequence)
207        return float(prediction.item()) 
208
209    def _prepare_topic_features(self, student, topic_info):
210        features = []
211        for topic, info in topic_info.items():
212            knowledge_level = student.knowledge_state.get(topic, 0)
213            prerequisites_met = all(
214                student.knowledge_state.get(prereq, 0) >= 0.7 
215                for prereq in info['prerequisites']
216            )
217            
218            recent_scores = []
219            recent_times = []
220            for subject_data in student.subjects.values():
221                if subject_data['scores']:
222                    recent_scores.extend(subject_data['scores'][-5:])
223                    avg_time = subject_data['time_spent'] / len(subject_data['scores'])
224                    recent_times.append(avg_time)
225            
226            past_performance = np.mean(recent_scores)/100 if recent_scores else 0.5
227            avg_study_time = np.mean(recent_times)/3600 if recent_times else 0.5
228            
229            features.append([
230                knowledge_level,
231                info['difficulty'],
232                float(prerequisites_met),
233                past_performance,
234                avg_study_time
235            ])
236            
237        return np.array(features)
238    
239    def recommend_topics(self, student, topics):
240        recommendations = []
241        
242        # Process each subject and its topics
243        for subject, subject_topics in topics.items():
244            current_knowledge = {topic: student.knowledge_state.get(topic, 0) 
245                               for topic in subject_topics.keys()}
246            
247            for topic, topic_info in subject_topics.items():
248                # Skip already mastered topics (knowledge > 0.8)
249                if current_knowledge[topic] > 0.8:
250                    continue
251                    
252                # Check prerequisites
253                prereqs_met = True
254                prereq_knowledge = 0
255                if topic_info['prerequisites']:
256                    prereq_scores = [current_knowledge.get(prereq, 0) 
257                                   for prereq in topic_info['prerequisites']]
258                    prereq_knowledge = sum(prereq_scores) / len(prereq_scores)
259                    prereqs_met = prereq_knowledge >= 0.5
260                
261                # Calculate readiness score
262                base_readiness = 0.7 if prereqs_met else 0.3
263                knowledge_factor = current_knowledge.get(topic, 0)
264                prereq_factor = prereq_knowledge if topic_info['prerequisites'] else 1.0
265                
266                readiness = (base_readiness * 0.4 + 
267                           knowledge_factor * 0.3 + 
268                           prereq_factor * 0.3)
269                
270                # Add to recommendations with calculated readiness
271                recommendations.append({
272                    'topic': topic,
273                    'subject': subject,
274                    'readiness': round(readiness, 2),
275                    'difficulty': topic_info['difficulty'],
276                    'prerequisites': topic_info['prerequisites']
277                })
278        
279        # Sort by readiness and return top recommendations
280        sorted_recommendations = sorted(recommendations, 
281                                     key=lambda x: x['readiness'], 
282                                     reverse=True)
283        
284        # Return at least 3 recommendations if available
285        return sorted_recommendations[:5]
286
287    def set_topics(self, topics):
288       self.topics = topics
289
290    def evaluate_student_readiness(self, student, topic):
291      # Find subject containing the topic
292      subject_topic = None
293      for subject, topics in self.topics.items():
294        if topic in topics:
295            subject_topic = topics[topic]
296            break
297    
298        if not subject_topic:
299         return {'readiness_score': 0, 'prerequisites_met': False}
300
301        features = self._prepare_topic_features(student, {topic: subject_topic})
302        readiness_score = float(self.path_recommender.predict_proba(features)[0][1])
303    
304        return {
305         'readiness_score': readiness_score,
306         'prerequisites_met': all(
307            student.knowledge_state.get(prereq, 0) >= 0.7
308            for prereq in subject_topic['prerequisites']
309          )
310        }
311    
312class Student:
313    def __init__(self, student_id, name, grade):
314        self.student_id = student_id
315        self.name = name
316        self.grade = grade
317        self.performance_history = []
318        self.knowledge_state = defaultdict(float)
319        self.learning_path = []
320        self.subjects = defaultdict(lambda: {
321            'scores': [],
322            'time_spent': 0,
323            'topics_completed': set(),
324            'mastery_level': defaultdict(float),
325            'recent_velocity': []
326        })
327        self.last_update_time = time.time()
328
329    def update_knowledge(self, topic, score, time_spent):
330        current_knowledge = self.knowledge_state[topic]
331        performance_weight = score / 100
332        time_weight = min(time_spent / 3600, 1)
333        
334        new_knowledge = current_knowledge + (
335            performance_weight * 0.7 + 
336            time_weight * 0.3
337        ) * (1 - current_knowledge)
338        
339        self.knowledge_state[topic] = round(new_knowledge, 2)
340        self._update_learning_velocity(score, time_spent)
341
342    def _update_learning_velocity(self, score, time_spent):
343        current_time = time.time()
344        time_diff = current_time - self.last_update_time
345        
346        if time_diff > 0:
347            velocity = score / (time_spent / 3600)
348            self.performance_history.append({
349                'timestamp': current_time,
350                'score': score,
351                'velocity': velocity
352            })
353            
354            if len(self.performance_history) > 10:
355                self.performance_history = self.performance_history[-10:]
356        
357        self.last_update_time = current_time
358
359class Analytics:
360    def __init__(self, learning_system):
361        self.learning_system = learning_system
362
363    def get_student_analytics(self, student_id):
364        student = self.learning_system.students.get(student_id)
365        if not student:
366            return None
367
368        return {
369            'performance_trends': self._calculate_performance_trends(student),
370            'learning_patterns': self._analyze_learning_patterns(student),
371            'topic_mastery': self._analyze_topic_mastery(student),
372            'time_analytics': self._analyze_time_patterns(student),
373            'comparison_metrics': self._get_peer_comparison(student)
374        }
375
376    def _calculate_performance_trends(self, student):
377        trends = {}
378        for subject, data in student.subjects.items():
379            scores = data['scores']
380            if len(scores) >= 3:
381                trends[subject] = {
382                    'trend': np.polyfit(range(len(scores)), scores, 1)[0],
383                    'recent_avg': np.mean(scores[-3:]),
384                    'overall_avg': np.mean(scores),
385                    'improvement_rate': (np.mean(scores[-3:]) - np.mean(scores[:3])) 
386                                      / np.mean(scores[:3]) if len(scores) >= 6 else 0
387                }
388        return trends
389
390    def _analyze_learning_patterns(self, student):
391        patterns = {}
392        for subject, data in student.subjects.items():
393            if data['scores'] and data['time_spent']:
394                patterns[subject] = {
395                    'efficiency': np.mean(data['scores']) / (data['time_spent'] / 3600),
396                    'consistency': np.std(data['scores']),
397                    'engagement': len(data['topics_completed']) / len(self.learning_system.topics[subject])
398                }
399        return patterns
400
401    def _analyze_topic_mastery(self, student):
402        mastery = {}
403        for subject, topics in self.learning_system.topics.items():
404            for topic_name, topic_info in topics.items():
405                knowledge = student.knowledge_state.get(topic_name, 0)
406                prereq_knowledge = np.mean([
407                   student.knowledge_state.get(prereq, 0)
408                   for prereq in topic_info['prerequisites']
409                ]) if topic_info['prerequisites'] else 1.0
410
411                try:
412                   readiness = self.learning_system.ai_model.evaluate_student_readiness(student, topic_name)
413                   readiness_score = readiness['readiness_score'] if readiness else 0
414                except:
415                   readiness_score = 0
416
417                mastery[topic_name] = {
418                    'knowledge_level': knowledge,
419                    'prerequisite_mastery': prereq_knowledge,
420                    'readiness': readiness_score
421                }
422        return mastery
423
424    def _analyze_time_patterns(self, student):
425        time_analysis = {}
426        for subject, data in student.subjects.items():
427            if data['scores'] and data['time_spent']:
428                time_per_topic = data['time_spent'] / len(data['topics_completed']) \
429                                if data['topics_completed'] else 0
430                time_analysis[subject] = {
431                    'avg_time_per_topic': time_per_topic,
432                    'total_time': data['time_spent'],
433                    'efficiency_score': np.mean(data['scores']) / max(time_per_topic, 1)
434                }
435        return time_analysis
436
437    def _get_peer_comparison(self, student):
438        peer_metrics = defaultdict(list)
439        for peer_id, peer in self.learning_system.students.items():
440            if peer_id != student.student_id and peer.grade == student.grade:
441                for subject, data in peer.subjects.items():
442                    if data['scores']:
443                        peer_metrics[subject].append({
444                            'avg_score': np.mean(data['scores']),
445                            'topics_completed': len(data['topics_completed']),
446                            'time_spent': data['time_spent']
447                        })
448
449        comparison = {}
450        for subject, metrics in peer_metrics.items():
451            if metrics:
452                peer_avg_score = np.mean([m['avg_score'] for m in metrics])
453                peer_avg_topics = np.mean([m['topics_completed'] for m in metrics])
454                peer_avg_time = np.mean([m['time_spent'] for m in metrics])
455
456                student_data = student.subjects[subject]
457                student_avg_score = np.mean(student_data['scores']) if student_data['scores'] else 0
458
459                comparison[subject] = {
460                    'score_percentile': percentileofscore(
461                        [m['avg_score'] for m in metrics],
462                        student_avg_score
463                    ),
464                    'progress_percentile': percentileofscore(
465                        [m['topics_completed'] for m in metrics],
466                        len(student_data['topics_completed'])
467                    ),
468                    'efficiency_percentile': percentileofscore(
469                        [m['time_spent'] / m['topics_completed'] for m in metrics if m['topics_completed']],
470                        student_data['time_spent'] / len(student_data['topics_completed'])
471                        if student_data['topics_completed'] else 0
472                    )
473                }
474        return comparison
475
476class AdaptiveLearningSystem:
477    def __init__(self):
478        self._initialize_topics()  # Call this first
479        self.ai_model = AIModel()
480        self.ai_model.set_topics(self.topics)
481        self.students = {}
482        self._initialize_sample_data()
483        
484        
485    def _initialize_topics(self):
486        self.topics = {
487            'math': {
488                'algebra': {
489                    'difficulty': 0.7,
490                    'prerequisites': ['basic_math']
491                },
492                'geometry': {
493                    'difficulty': 0.6,
494                    'prerequisites': ['algebra']
495                },
496                'calculus': {
497                    'difficulty': 0.9,
498                    'prerequisites': ['algebra', 'geometry']
499                }
500            },
501            'science': {
502                'physics': {
503                    'difficulty': 0.8,
504                    'prerequisites': ['algebra']
505                },
506                'chemistry': {
507                    'difficulty': 0.7,
508                    'prerequisites': ['algebra']
509                },
510                'biology': {
511                    'difficulty': 0.6,
512                    'prerequisites': []
513                }
514            }
515        }
516
517    def _initialize_sample_data(self):
518        sample_students = [
519            ('S001', 'John Doe', 10),
520            ('S002', 'Jane Smith', 10),
521            ('S003', 'Mike Johnson', 11)
522        ]
523        
524        for student_id, name, grade in sample_students:
525
526            self.students[student_id] = Student(student_id, name, grade)
527            self._initialize_student_data(self.students[student_id])
528
529    def _initialize_student_data(self, student):
530        for subject in ['math', 'science']:
531            for topic in self.topics[subject]:
532                score = np.random.randint(70, 100)
533                time = np.random.randint(1800, 3600)
534                student.update_knowledge(topic, score, time)
535                student.subjects[subject]['scores'].append(score)
536                student.subjects[subject]['time_spent'] += time
537                if score >= 80:
538                    student.subjects[subject]['topics_completed'].add(topic)
539
540    def calculate_learning_velocity(self, student):
541        if not student.performance_history:
542          return 0
543        recent_velocities = [ph['velocity'] for ph in student.performance_history[-5:]]
544        return round(np.mean(recent_velocities), 2)
545
546    def update_student_progress(self, student_id, subject, topic, score, time_spent):
547        if student_id not in self.students:
548            return None
549        
550        student = self.students[student_id]
551        student.subjects[subject]['scores'].append(score)
552        student.subjects[subject]['time_spent'] += time_spent
553        
554        if score >= 80:
555            student.subjects[subject]['topics_completed'].add(topic)
556        
557        student.update_knowledge(topic, score, time_spent)
558        
559        velocity = score / (time_spent / 3600)
560        student.subjects[subject]['recent_velocity'].append(velocity)
561        if len(student.subjects[subject]['recent_velocity']) > 10:
562            student.subjects[subject]['recent_velocity'] = student.subjects[subject]['recent_velocity'][-10:]
563        
564        return self.get_student_data(student_id)
565
566
567    def get_student_data(self, student_id):
568        student = self.students.get(student_id)
569        if not student:
570            return None
571            
572        recommended_topics = self.ai_model.recommend_topics(student, self.topics)
573        
574        return {
575            'student_info': {
576                'id': student.student_id,
577                'name': student.name,
578                'grade': student.grade
579            },
580            'progress': {
581                'knowledge_state': dict(student.knowledge_state),
582                'performance_prediction': self.ai_model.predict_performance(student),
583                'recommended_topics': recommended_topics,
584                'learning_velocity': self._calculate_learning_velocity(student),
585                'subjects': {
586                    subject: {
587                        'average_score': round(np.mean(data['scores']) if data['scores'] else 0, 2),
588                        'time_spent': data['time_spent'],
589                        'completed_topics': list(data['topics_completed']),
590                        'scores': data['scores']
591                    }
592                    for subject, data in student.subjects.items()
593                }
594            }
595        }
596
597
598    def _calculate_learning_velocity(self, student):
599        if not student.performance_history:
600            return 0
601        recent_velocities = [ph['velocity'] for ph in student.performance_history[-5:]]
602        return round(np.mean(recent_velocities), 2)
603
604class PerformanceMonitor:
605    def __init__(self, learning_system):
606        self.learning_system = learning_system
607        self.thresholds = {
608            'low_performance': 60,
609            'high_performance': 85,
610            'time_warning': 7200,
611            'velocity_warning': 10
612        }
613
614    def check_student_status(self, student_id):
615        student = self.learning_system.students.get(student_id)
616        if not student:
617            return None
618
619        alerts = []
620        recommendations = []
621
622        for subject, data in student.subjects.items():
623            recent_scores = data['scores'][-3:] if data['scores'] else []
624            if recent_scores and np.mean(recent_scores) < self.thresholds['low_performance']:
625                alerts.append({
626                    'type': 'low_performance',
627                    'subject': subject,
628                    'message': f"Performance below threshold in {subject}"
629                })
630                recommendations.append(self._generate_improvement_plan(student, subject))
631
632        for subject, data in student.subjects.items():
633            if data['time_spent'] > self.thresholds['time_warning']:
634                alerts.append({
635                    'type': 'time_warning',
636                    'subject': subject,
637                    'message': f"Extended time spent on {subject}"
638                })
639
640        velocity = self.learning_system.calculate_learning_velocity(student)
641        if velocity < self.thresholds['velocity_warning']:
642            alerts.append({
643                'type': 'velocity_warning',
644                'message': "Learning velocity below expected rate"
645            })
646
647        return {
648            'alerts': alerts,
649            'recommendations': recommendations,
650            'status_summary': self._generate_status_summary(student)
651        }
652
653    def _generate_improvement_plan(self, student, subject):
654        weak_topics = [
655            topic for topic in self.learning_system.topics[subject]
656            if student.knowledge_state.get(topic, 0) < 0.6
657        ]
658
659        return {
660            'subject': subject,
661            'weak_topics': weak_topics,
662            'suggested_actions': [
663                {
664                    'action': 'review_prerequisites',
665                    'topics': self.learning_system.topics[subject][topic]['prerequisites']
666                }
667                for topic in weak_topics
668            ],
669            'estimated_improvement_time': len(weak_topics) * 3600
670        }
671
672    def _generate_status_summary(self, student):
673        return {
674            'overall_progress': np.mean([
675                len(data['topics_completed']) / len(self.learning_system.topics[subject])
676                for subject, data in student.subjects.items()
677            ]),
678            'average_performance': np.mean([
679                np.mean(data['scores']) if data['scores'] else 0
680                for data in student.subjects.values()
681            ]),
682            'learning_efficiency': np.mean([
683                np.mean(data['scores']) / (data['time_spent'] / 3600)
684                if data['scores'] and data['time_spent'] else 0
685                for data in student.subjects.values()
686            ])
687        }
688
689class DataProcessor:
690    @staticmethod
691    def process_student_submission(raw_data):
692        try:
693            processed_data = {
694                'student_id': str(raw_data['student_id']),
695                'subject': str(raw_data['subject']).lower(),
696                'topic': str(raw_data['topic']).lower(),
697                'score': float(raw_data['score']),
698                'time_spent': int(raw_data['time_spent'])
699            }
700
701            assert 0 <= processed_data['score'] <= 100, "Score must be between 0 and 100"
702            assert processed_data['time_spent'] > 0, "Time spent must be positive"
703
704            return processed_data
705        except (KeyError, ValueError, AssertionError) as e:
706            raise ValueError(f"Invalid submission data: {str(e)}")
707
708learning_system = AdaptiveLearningSystem()
709
710@app.route('/')
711def home():
712    return render_template('index.html')
713
714@app.route('/api/student/<student_id>')
715def get_student(student_id):
716    data = learning_system.get_student_data(student_id)
717    if not data:
718        return jsonify({'error': 'Student not found'}), 404
719    return jsonify(data)
720
721@app.route('/api/analytics/<student_id>')
722def get_analytics(student_id):
723    analytics = Analytics(learning_system)
724    data = analytics.get_student_analytics(student_id)
725    if not data:
726        return jsonify({'error': 'Student not found'}), 404
727    return jsonify(data)
728
729@app.route('/api/status/<student_id>')
730def get_status(student_id):
731    monitor = PerformanceMonitor(learning_system)
732    status = monitor.check_student_status(student_id)
733    if not status:
734        return jsonify({'error': 'Student not found'}), 404
735    return jsonify(status)
736
737@app.route('/api/update_progress', methods=['POST'])
738def update_progress():
739    try:
740        data = DataProcessor.process_student_submission(request.json)
741    except ValueError as e:
742        return jsonify({'error': str(e)}), 400
743
744    updated_data = learning_system.update_student_progress(
745        data['student_id'],
746        data['subject'],
747        data['topic'],
748        data['score'],
749        data['time_spent']
750    )
751    
752    if not updated_data:
753        return jsonify({'error': 'Student not found'}), 404
754    
755    monitor = PerformanceMonitor(learning_system)
756    status = monitor.check_student_status(data['student_id'])
757    
758    return jsonify({
759        'student_data': updated_data,
760        'status': status
761    })
762
763if __name__ == '__main__':
764    app.run(debug=True)
765