Update main.py
Browse files
main.py
CHANGED
|
@@ -1271,40 +1271,28 @@ def view_quizzes():
|
|
| 1271 |
|
| 1272 |
@app.route('/api/user/performance', methods=['GET'])
|
| 1273 |
def get_user_performance():
|
| 1274 |
-
"""Retrieves user's quiz performance
|
| 1275 |
try:
|
| 1276 |
-
# Authentication
|
| 1277 |
user, error = verify_token(request.headers.get('Authorization'))
|
| 1278 |
if error:
|
| 1279 |
return jsonify({'error': error['error']}), error['status']
|
| 1280 |
|
| 1281 |
-
#
|
| 1282 |
attempts_res = supabase.table('quiz_attempts') \
|
| 1283 |
-
.select(''
|
| 1284 |
-
id,
|
| 1285 |
-
quiz_id,
|
| 1286 |
-
score,
|
| 1287 |
-
submitted_at,
|
| 1288 |
-
quizzes(
|
| 1289 |
-
id,
|
| 1290 |
-
difficulty,
|
| 1291 |
-
created_at,
|
| 1292 |
-
notes!inner(
|
| 1293 |
-
id,
|
| 1294 |
-
study_materials!inner(title)
|
| 1295 |
-
)
|
| 1296 |
-
)
|
| 1297 |
-
''') \
|
| 1298 |
.eq('user_id', user.id) \
|
| 1299 |
.order('submitted_at', desc=True) \
|
| 1300 |
.execute()
|
| 1301 |
-
|
| 1302 |
-
if attempts_res.error:
|
| 1303 |
raise Exception(attempts_res.error.message)
|
|
|
|
|
|
|
| 1304 |
|
| 1305 |
-
# Group
|
| 1306 |
quizzes = {}
|
| 1307 |
-
for attempt in
|
| 1308 |
quiz_id = attempt['quizzes']['id']
|
| 1309 |
if quiz_id not in quizzes:
|
| 1310 |
quizzes[quiz_id] = {
|
|
@@ -1314,39 +1302,52 @@ def get_user_performance():
|
|
| 1314 |
'difficulty': attempt['quizzes']['difficulty'],
|
| 1315 |
'created_at': attempt['quizzes']['created_at']
|
| 1316 |
},
|
| 1317 |
-
'attempts': []
|
| 1318 |
-
'average_score': 0
|
| 1319 |
}
|
| 1320 |
quizzes[quiz_id]['attempts'].append(attempt)
|
| 1321 |
|
| 1322 |
-
# Calculate
|
| 1323 |
performance_data = []
|
| 1324 |
-
|
| 1325 |
-
|
| 1326 |
-
|
| 1327 |
-
|
| 1328 |
-
|
| 1329 |
-
|
| 1330 |
-
|
| 1331 |
-
|
| 1332 |
-
|
| 1333 |
-
|
| 1334 |
-
|
|
|
|
| 1335 |
|
| 1336 |
-
#
|
| 1337 |
-
|
| 1338 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1339 |
|
| 1340 |
return jsonify({
|
| 1341 |
'success': True,
|
| 1342 |
-
'average_score': round(
|
| 1343 |
-
'quizzes': performance_data,
|
| 1344 |
'suggestions': suggestions
|
| 1345 |
})
|
| 1346 |
|
| 1347 |
except Exception as e:
|
| 1348 |
-
logging.error(f"Performance error: {
|
| 1349 |
-
|
|
|
|
| 1350 |
|
| 1351 |
def generate_suggestions(quizzes, overall_avg):
|
| 1352 |
"""Generate personalized suggestions based on quiz performance"""
|
|
|
|
| 1271 |
|
| 1272 |
@app.route('/api/user/performance', methods=['GET'])
|
| 1273 |
def get_user_performance():
|
| 1274 |
+
"""Retrieves user's quiz performance and provides simple suggestions."""
|
| 1275 |
try:
|
| 1276 |
+
# --- Authentication ---
|
| 1277 |
user, error = verify_token(request.headers.get('Authorization'))
|
| 1278 |
if error:
|
| 1279 |
return jsonify({'error': error['error']}), error['status']
|
| 1280 |
|
| 1281 |
+
# --- Query Attempts with Proper Error Handling ---
|
| 1282 |
attempts_res = supabase.table('quiz_attempts') \
|
| 1283 |
+
.select('id, quiz_id, score, submitted_at, quizzes(id, difficulty, created_at, notes(study_materials(title)))') \
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1284 |
.eq('user_id', user.id) \
|
| 1285 |
.order('submitted_at', desc=True) \
|
| 1286 |
.execute()
|
| 1287 |
+
|
| 1288 |
+
if hasattr(attempts_res, 'error') and attempts_res.error:
|
| 1289 |
raise Exception(attempts_res.error.message)
|
| 1290 |
+
|
| 1291 |
+
attempts_data = attempts_res.data
|
| 1292 |
|
| 1293 |
+
# --- Group Attempts by Quiz ---
|
| 1294 |
quizzes = {}
|
| 1295 |
+
for attempt in attempts_data:
|
| 1296 |
quiz_id = attempt['quizzes']['id']
|
| 1297 |
if quiz_id not in quizzes:
|
| 1298 |
quizzes[quiz_id] = {
|
|
|
|
| 1302 |
'difficulty': attempt['quizzes']['difficulty'],
|
| 1303 |
'created_at': attempt['quizzes']['created_at']
|
| 1304 |
},
|
| 1305 |
+
'attempts': []
|
|
|
|
| 1306 |
}
|
| 1307 |
quizzes[quiz_id]['attempts'].append(attempt)
|
| 1308 |
|
| 1309 |
+
# --- Calculate Averages ---
|
| 1310 |
performance_data = []
|
| 1311 |
+
overall_scores = []
|
| 1312 |
+
|
| 1313 |
+
for quiz_id, quiz_data in quizzes.items():
|
| 1314 |
+
scores = [a['score'] for a in quiz_data['attempts']]
|
| 1315 |
+
avg_score = sum(scores) / len(scores) if scores else 0
|
| 1316 |
+
overall_scores.extend(scores)
|
| 1317 |
+
|
| 1318 |
+
performance_data.append({
|
| 1319 |
+
**quiz_data,
|
| 1320 |
+
'average_score': avg_score,
|
| 1321 |
+
'attempt_count': len(scores)
|
| 1322 |
+
})
|
| 1323 |
|
| 1324 |
+
# --- Calculate Overall Average ---
|
| 1325 |
+
average_score = sum(overall_scores) / len(overall_scores) if overall_scores else 0
|
| 1326 |
+
|
| 1327 |
+
# --- Generate Suggestions ---
|
| 1328 |
+
suggestions = []
|
| 1329 |
+
if performance_data:
|
| 1330 |
+
if average_score < 60:
|
| 1331 |
+
suggestions.append("Your average score is a bit low. Try reviewing the notes more thoroughly before taking quizzes.")
|
| 1332 |
+
# Find lowest scoring quiz
|
| 1333 |
+
weakest_quiz = min(performance_data, key=lambda x: x['average_score'])
|
| 1334 |
+
suggestions.append(f"Focus on: '{weakest_quiz['quiz_info']['title']}' (current average: {weakest_quiz['average_score']:.0f}%)")
|
| 1335 |
+
elif average_score > 85:
|
| 1336 |
+
suggestions.append("Great job! Try some 'hard' difficulty quizzes.")
|
| 1337 |
+
else:
|
| 1338 |
+
suggestions.append("You're making good progress! Keep practicing.")
|
| 1339 |
|
| 1340 |
return jsonify({
|
| 1341 |
'success': True,
|
| 1342 |
+
'average_score': round(average_score, 2),
|
| 1343 |
+
'quizzes': performance_data, # Changed from recent_attempts to quizzes
|
| 1344 |
'suggestions': suggestions
|
| 1345 |
})
|
| 1346 |
|
| 1347 |
except Exception as e:
|
| 1348 |
+
logging.error(f"Performance endpoint error: {str(e)}")
|
| 1349 |
+
logging.error(traceback.format_exc())
|
| 1350 |
+
return jsonify({'error': 'Internal server error'}), 500
|
| 1351 |
|
| 1352 |
def generate_suggestions(quizzes, overall_avg):
|
| 1353 |
"""Generate personalized suggestions based on quiz performance"""
|