Spaces:
Running
Running
github-actions[bot] commited on
Commit ·
57fbb45
1
Parent(s): b60040e
🚀 Auto-deploy backend from GitHub (8ef6f40)
Browse files- analytics.py +18 -23
- main.py +2 -10
- routes/diagnostic.py +0 -1
- services/user_provisioning_service.py +0 -1
analytics.py
CHANGED
|
@@ -232,7 +232,6 @@ class EnhancedRiskRequest(BaseModel):
|
|
| 232 |
avgQuizScore: float = Field(..., ge=0, le=100)
|
| 233 |
attendance: float = Field(..., ge=0, le=100)
|
| 234 |
assignmentCompletion: float = Field(..., ge=0, le=100)
|
| 235 |
-
streak: Optional[int] = 0
|
| 236 |
xpGrowthRate: Optional[float] = 0.0
|
| 237 |
timeOnPlatform: Optional[float] = 0.0 # hours
|
| 238 |
# Optional trend data
|
|
@@ -810,7 +809,7 @@ def _build_risk_features(data: EnhancedRiskRequest) -> np.ndarray:
|
|
| 810 |
data.avgQuizScore,
|
| 811 |
data.attendance,
|
| 812 |
data.assignmentCompletion,
|
| 813 |
-
|
| 814 |
data.xpGrowthRate or 0.0,
|
| 815 |
data.timeOnPlatform or 0.0,
|
| 816 |
data.engagementTrend7d or 0.0,
|
|
@@ -871,12 +870,8 @@ def _rule_based_risk(data: EnhancedRiskRequest) -> EnhancedRiskPrediction:
|
|
| 871 |
score -= 10
|
| 872 |
if (data.daysSinceLastActivity or 0) >= 7:
|
| 873 |
score -= 10
|
| 874 |
-
if (data.streak or 0) == 0:
|
| 875 |
-
score -= 5
|
| 876 |
|
| 877 |
# Bonuses
|
| 878 |
-
if (data.streak or 0) >= 7:
|
| 879 |
-
score += 5
|
| 880 |
if (data.engagementTrend7d or 0) > 0:
|
| 881 |
score += 5
|
| 882 |
|
|
@@ -1151,19 +1146,19 @@ async def train_risk_model(force_retrain: bool = False) -> RiskTrainResponse:
|
|
| 1151 |
if not data:
|
| 1152 |
continue
|
| 1153 |
|
| 1154 |
-
|
| 1155 |
-
|
| 1156 |
-
|
| 1157 |
-
|
| 1158 |
-
|
| 1159 |
-
|
| 1160 |
-
|
| 1161 |
-
|
| 1162 |
-
|
| 1163 |
-
|
| 1164 |
-
|
| 1165 |
-
|
| 1166 |
-
|
| 1167 |
X_data.append(features)
|
| 1168 |
|
| 1169 |
# Determine label from existing riskLevel or compute it
|
|
@@ -1260,7 +1255,7 @@ def _generate_synthetic_risk_data(n: int) -> Tuple[np.ndarray, np.ndarray]:
|
|
| 1260 |
quiz = np.random.normal(35, 12)
|
| 1261 |
attendance = np.random.normal(50, 15)
|
| 1262 |
completion = np.random.normal(35, 15)
|
| 1263 |
-
streak
|
| 1264 |
xp_growth = np.random.normal(-0.5, 0.3)
|
| 1265 |
time_platform = np.random.normal(2, 1)
|
| 1266 |
trend = np.random.normal(-10, 5)
|
|
@@ -1272,7 +1267,7 @@ def _generate_synthetic_risk_data(n: int) -> Tuple[np.ndarray, np.ndarray]:
|
|
| 1272 |
quiz = np.random.normal(60, 10)
|
| 1273 |
attendance = np.random.normal(72, 10)
|
| 1274 |
completion = np.random.normal(60, 12)
|
| 1275 |
-
streak
|
| 1276 |
xp_growth = np.random.normal(0.2, 0.3)
|
| 1277 |
time_platform = np.random.normal(5, 2)
|
| 1278 |
trend = np.random.normal(0, 8)
|
|
@@ -1284,7 +1279,7 @@ def _generate_synthetic_risk_data(n: int) -> Tuple[np.ndarray, np.ndarray]:
|
|
| 1284 |
quiz = np.random.normal(85, 8)
|
| 1285 |
attendance = np.random.normal(93, 5)
|
| 1286 |
completion = np.random.normal(88, 8)
|
| 1287 |
-
streak
|
| 1288 |
xp_growth = np.random.normal(1.0, 0.4)
|
| 1289 |
time_platform = np.random.normal(10, 3)
|
| 1290 |
trend = np.random.normal(5, 5)
|
|
@@ -1297,7 +1292,7 @@ def _generate_synthetic_risk_data(n: int) -> Tuple[np.ndarray, np.ndarray]:
|
|
| 1297 |
max(0, min(100, quiz)),
|
| 1298 |
max(0, min(100, attendance)),
|
| 1299 |
max(0, min(100, completion)),
|
| 1300 |
-
|
| 1301 |
xp_growth,
|
| 1302 |
max(0, time_platform),
|
| 1303 |
trend,
|
|
|
|
| 232 |
avgQuizScore: float = Field(..., ge=0, le=100)
|
| 233 |
attendance: float = Field(..., ge=0, le=100)
|
| 234 |
assignmentCompletion: float = Field(..., ge=0, le=100)
|
|
|
|
| 235 |
xpGrowthRate: Optional[float] = 0.0
|
| 236 |
timeOnPlatform: Optional[float] = 0.0 # hours
|
| 237 |
# Optional trend data
|
|
|
|
| 809 |
data.avgQuizScore,
|
| 810 |
data.attendance,
|
| 811 |
data.assignmentCompletion,
|
| 812 |
+
0, # streak removed
|
| 813 |
data.xpGrowthRate or 0.0,
|
| 814 |
data.timeOnPlatform or 0.0,
|
| 815 |
data.engagementTrend7d or 0.0,
|
|
|
|
| 870 |
score -= 10
|
| 871 |
if (data.daysSinceLastActivity or 0) >= 7:
|
| 872 |
score -= 10
|
|
|
|
|
|
|
| 873 |
|
| 874 |
# Bonuses
|
|
|
|
|
|
|
| 875 |
if (data.engagementTrend7d or 0) > 0:
|
| 876 |
score += 5
|
| 877 |
|
|
|
|
| 1146 |
if not data:
|
| 1147 |
continue
|
| 1148 |
|
| 1149 |
+
features = [
|
| 1150 |
+
data.get("engagementScore", 50),
|
| 1151 |
+
data.get("avgQuizScore", 50),
|
| 1152 |
+
data.get("attendance", 80),
|
| 1153 |
+
data.get("assignmentCompletion", 60),
|
| 1154 |
+
0, # streak removed
|
| 1155 |
+
data.get("xpGrowthRate", 0),
|
| 1156 |
+
data.get("timeOnPlatform", 0),
|
| 1157 |
+
0.0, # engagementTrend7d
|
| 1158 |
+
0.0, # quizScoreVariance
|
| 1159 |
+
data.get("consecutiveAbsences", 0),
|
| 1160 |
+
data.get("daysSinceLastActivity", 0),
|
| 1161 |
+
]
|
| 1162 |
X_data.append(features)
|
| 1163 |
|
| 1164 |
# Determine label from existing riskLevel or compute it
|
|
|
|
| 1255 |
quiz = np.random.normal(35, 12)
|
| 1256 |
attendance = np.random.normal(50, 15)
|
| 1257 |
completion = np.random.normal(35, 15)
|
| 1258 |
+
# streak removed
|
| 1259 |
xp_growth = np.random.normal(-0.5, 0.3)
|
| 1260 |
time_platform = np.random.normal(2, 1)
|
| 1261 |
trend = np.random.normal(-10, 5)
|
|
|
|
| 1267 |
quiz = np.random.normal(60, 10)
|
| 1268 |
attendance = np.random.normal(72, 10)
|
| 1269 |
completion = np.random.normal(60, 12)
|
| 1270 |
+
# streak removed
|
| 1271 |
xp_growth = np.random.normal(0.2, 0.3)
|
| 1272 |
time_platform = np.random.normal(5, 2)
|
| 1273 |
trend = np.random.normal(0, 8)
|
|
|
|
| 1279 |
quiz = np.random.normal(85, 8)
|
| 1280 |
attendance = np.random.normal(93, 5)
|
| 1281 |
completion = np.random.normal(88, 8)
|
| 1282 |
+
# streak removed
|
| 1283 |
xp_growth = np.random.normal(1.0, 0.4)
|
| 1284 |
time_platform = np.random.normal(10, 3)
|
| 1285 |
trend = np.random.normal(5, 5)
|
|
|
|
| 1292 |
max(0, min(100, quiz)),
|
| 1293 |
max(0, min(100, attendance)),
|
| 1294 |
max(0, min(100, completion)),
|
| 1295 |
+
0, # streak removed
|
| 1296 |
xp_growth,
|
| 1297 |
max(0, time_platform),
|
| 1298 |
trend,
|
main.py
CHANGED
|
@@ -2956,7 +2956,6 @@ async def _generate_risk_recommendations_llm(data: EnhancedRiskRequest, result:
|
|
| 2956 |
f"engagementScore: {data.engagementScore:.1f}\n"
|
| 2957 |
f"avgQuizScore: {data.avgQuizScore:.1f}\n"
|
| 2958 |
f"assignmentCompletion: {data.assignmentCompletion:.1f}\n"
|
| 2959 |
-
f"streak: {int(data.streak or 0)}\n"
|
| 2960 |
f"daysSinceLastActivity: {int(data.daysSinceLastActivity or 0)}\n"
|
| 2961 |
f"top_factors: {', '.join(result.top_factors)}"
|
| 2962 |
)
|
|
@@ -11380,8 +11379,6 @@ def _reset_student_testing_data_admin(
|
|
| 11380 |
"level": 1,
|
| 11381 |
"currentXP": 0,
|
| 11382 |
"totalXP": 0,
|
| 11383 |
-
"streak": 0,
|
| 11384 |
-
"streakHistory": [],
|
| 11385 |
"atRiskSubjects": [],
|
| 11386 |
"hasTakenDiagnostic": False,
|
| 11387 |
"iarAssessmentState": "not_started",
|
|
@@ -12783,7 +12780,6 @@ class ProgressEvaluateRequest(BaseModel):
|
|
| 12783 |
mastery_level_before: str
|
| 12784 |
items: List[Dict[str, Any]]
|
| 12785 |
previous_attempts: int = Field(default=0)
|
| 12786 |
-
current_streak_days: int = Field(default=0)
|
| 12787 |
|
| 12788 |
|
| 12789 |
class ProgressEvaluateResponse(BaseModel):
|
|
@@ -12833,7 +12829,6 @@ async def evaluate_progress(request: ProgressEvaluateRequest):
|
|
| 12833 |
mastery_changed = True
|
| 12834 |
|
| 12835 |
xp_base = 0
|
| 12836 |
-
xp_streak = 0
|
| 12837 |
xp_mastery = 0
|
| 12838 |
xp_other = 0
|
| 12839 |
|
|
@@ -12847,8 +12842,6 @@ async def evaluate_progress(request: ProgressEvaluateRequest):
|
|
| 12847 |
elif diff == "hard":
|
| 12848 |
xp_base += 20
|
| 12849 |
|
| 12850 |
-
xp_streak = min(30, 5 * request.current_streak_days)
|
| 12851 |
-
|
| 12852 |
if mastery_changed:
|
| 12853 |
xp_mastery = 50
|
| 12854 |
|
|
@@ -12858,7 +12851,7 @@ async def evaluate_progress(request: ProgressEvaluateRequest):
|
|
| 12858 |
if request.previous_attempts >= 1 and score_percent > 60:
|
| 12859 |
xp_other += 15
|
| 12860 |
|
| 12861 |
-
xp_total = xp_base +
|
| 12862 |
|
| 12863 |
error_analysis = []
|
| 12864 |
for item in request.items:
|
|
@@ -12915,7 +12908,6 @@ async def evaluate_progress(request: ProgressEvaluateRequest):
|
|
| 12915 |
stats_ref = db.collection("studentProgress").document(request.student_id).collection("stats").document("summary")
|
| 12916 |
stats_ref.set({
|
| 12917 |
"total_xp": firebase_firestore.Increment(xp_total),
|
| 12918 |
-
"current_streak_days": request.current_streak_days,
|
| 12919 |
"topics_mastered": firebase_firestore.Increment(1) if mastery_changed else firebase_firestore.Increment(0),
|
| 12920 |
}, merge=True)
|
| 12921 |
except Exception as fs_err:
|
|
@@ -12926,7 +12918,7 @@ async def evaluate_progress(request: ProgressEvaluateRequest):
|
|
| 12926 |
mastery_changed=mastery_changed,
|
| 12927 |
score_percent=round(score_percent, 1),
|
| 12928 |
xp_earned=xp_total,
|
| 12929 |
-
xp_breakdown={"base": xp_base, "mastery_bonus": xp_mastery, "
|
| 12930 |
badges_unlocked=[],
|
| 12931 |
performance_feedback=f"You got {correct_count}/{total_items} correct.",
|
| 12932 |
error_analysis=error_analysis,
|
|
|
|
| 2956 |
f"engagementScore: {data.engagementScore:.1f}\n"
|
| 2957 |
f"avgQuizScore: {data.avgQuizScore:.1f}\n"
|
| 2958 |
f"assignmentCompletion: {data.assignmentCompletion:.1f}\n"
|
|
|
|
| 2959 |
f"daysSinceLastActivity: {int(data.daysSinceLastActivity or 0)}\n"
|
| 2960 |
f"top_factors: {', '.join(result.top_factors)}"
|
| 2961 |
)
|
|
|
|
| 11379 |
"level": 1,
|
| 11380 |
"currentXP": 0,
|
| 11381 |
"totalXP": 0,
|
|
|
|
|
|
|
| 11382 |
"atRiskSubjects": [],
|
| 11383 |
"hasTakenDiagnostic": False,
|
| 11384 |
"iarAssessmentState": "not_started",
|
|
|
|
| 12780 |
mastery_level_before: str
|
| 12781 |
items: List[Dict[str, Any]]
|
| 12782 |
previous_attempts: int = Field(default=0)
|
|
|
|
| 12783 |
|
| 12784 |
|
| 12785 |
class ProgressEvaluateResponse(BaseModel):
|
|
|
|
| 12829 |
mastery_changed = True
|
| 12830 |
|
| 12831 |
xp_base = 0
|
|
|
|
| 12832 |
xp_mastery = 0
|
| 12833 |
xp_other = 0
|
| 12834 |
|
|
|
|
| 12842 |
elif diff == "hard":
|
| 12843 |
xp_base += 20
|
| 12844 |
|
|
|
|
|
|
|
| 12845 |
if mastery_changed:
|
| 12846 |
xp_mastery = 50
|
| 12847 |
|
|
|
|
| 12851 |
if request.previous_attempts >= 1 and score_percent > 60:
|
| 12852 |
xp_other += 15
|
| 12853 |
|
| 12854 |
+
xp_total = xp_base + xp_mastery + xp_other
|
| 12855 |
|
| 12856 |
error_analysis = []
|
| 12857 |
for item in request.items:
|
|
|
|
| 12908 |
stats_ref = db.collection("studentProgress").document(request.student_id).collection("stats").document("summary")
|
| 12909 |
stats_ref.set({
|
| 12910 |
"total_xp": firebase_firestore.Increment(xp_total),
|
|
|
|
| 12911 |
"topics_mastered": firebase_firestore.Increment(1) if mastery_changed else firebase_firestore.Increment(0),
|
| 12912 |
}, merge=True)
|
| 12913 |
except Exception as fs_err:
|
|
|
|
| 12918 |
mastery_changed=mastery_changed,
|
| 12919 |
score_percent=round(score_percent, 1),
|
| 12920 |
xp_earned=xp_total,
|
| 12921 |
+
xp_breakdown={"base": xp_base, "mastery_bonus": xp_mastery, "other": xp_other},
|
| 12922 |
badges_unlocked=[],
|
| 12923 |
performance_feedback=f"You got {correct_count}/{total_items} correct.",
|
| 12924 |
error_analysis=error_analysis,
|
routes/diagnostic.py
CHANGED
|
@@ -717,7 +717,6 @@ async def _save_results(
|
|
| 717 |
"learning_path": risk_profile.get("suggested_learning_path", []),
|
| 718 |
"current_topic_index": 0,
|
| 719 |
"total_xp": fs.Increment(50 + mastered_count * 10),
|
| 720 |
-
"current_streak_days": 1,
|
| 721 |
"badges": fs.ArrayUnion(["first_assessment"]),
|
| 722 |
"topics_mastered": mastered_count,
|
| 723 |
"diagnostic_completed": True,
|
|
|
|
| 717 |
"learning_path": risk_profile.get("suggested_learning_path", []),
|
| 718 |
"current_topic_index": 0,
|
| 719 |
"total_xp": fs.Increment(50 + mastered_count * 10),
|
|
|
|
| 720 |
"badges": fs.ArrayUnion(["first_assessment"]),
|
| 721 |
"topics_mastered": mastered_count,
|
| 722 |
"diagnostic_completed": True,
|
services/user_provisioning_service.py
CHANGED
|
@@ -185,7 +185,6 @@ class UserProvisioningService:
|
|
| 185 |
"level": 1,
|
| 186 |
"currentXP": 0,
|
| 187 |
"totalXP": 0,
|
| 188 |
-
"streak": 0,
|
| 189 |
"atRiskSubjects": [],
|
| 190 |
"hasTakenDiagnostic": False,
|
| 191 |
}
|
|
|
|
| 185 |
"level": 1,
|
| 186 |
"currentXP": 0,
|
| 187 |
"totalXP": 0,
|
|
|
|
| 188 |
"atRiskSubjects": [],
|
| 189 |
"hasTakenDiagnostic": False,
|
| 190 |
}
|