feat: complete pragativeer v2 frontend and backend, docker setup, and cbt engine

This commit is contained in:
2026-07-06 17:08:13 +05:30
parent ce01795aa9
commit 426b98ddab
66 changed files with 7949 additions and 363 deletions

76
backend/predictor.py Normal file
View File

@@ -0,0 +1,76 @@
from sqlmodel import Session, select
from uuid import UUID
import models
def calculate_readiness_score(user_id: UUID, session: Session) -> dict:
"""
Calculates the Exam Readiness Score (0-100) based on PRD A-05 parameters.
Weights: Accuracy (40%), Speed (20%), Syllabus Coverage (20%),
Consistency (10%), Mistake Recovery (10%).
"""
user = session.get(models.User, user_id)
if not user:
return {}
attempts = session.exec(
select(models.Attempt).where(models.Attempt.user_id == user_id)
).all()
if not attempts:
return {"score": 0, "status": "Not enough data"}
# 1. Accuracy (40% Weight)
avg_accuracy = sum(a.accuracy for a in attempts) / len(attempts)
w_accuracy = (avg_accuracy / 100) * 40
# 2. Speed (20% Weight) - Assuming benchmark is 120s per question
time_per_q = [ (a.time_taken / a.total_questions) for a in attempts if a.total_questions > 0 and a.time_taken ]
avg_time = sum(time_per_q) / len(time_per_q) if time_per_q else 120
speed_factor = min(1.0, 120 / max(avg_time, 1)) # Cap at 1.0
w_speed = speed_factor * 20
# 3. Consistency (10% Weight)
streak = min(user.streak_count, 30) # Max consistency score hit at 30 days
w_consistency = (streak / 30) * 10
# 4. Mistake Recovery (10% Weight)
mistakes = session.exec(select(models.Mistake).where(models.Mistake.user_id == user_id)).all()
mastered_count = sum(1 for m in mistakes if m.is_mastered)
total_mistakes = max(len(mistakes), 1)
w_recovery = (mastered_count / total_mistakes) * 10
# 5. Syllabus Coverage (20% Weight)
# For local sandbox, we will estimate based on total questions attempted
total_q_attempted = sum(a.total_questions for a in attempts)
coverage_factor = min(total_q_attempted / 500, 1.0) # Assume 500 questions = decent baseline coverage
w_coverage = coverage_factor * 20
# Total Calculation
total_score = round(w_accuracy + w_speed + w_consistency + w_recovery + w_coverage)
# Calculate College Prediction based on PRD A-07
prediction = "Keep Practicing"
target_type = "State Level"
if total_score >= 85:
prediction = "IIT Bombay / IIT Delhi within reach!"
target_type = "Reach"
elif total_score >= 70:
prediction = "NIT Trichy / NIT Surathkal on track."
target_type = "Target"
elif total_score >= 50:
prediction = "Top GFTIs / State Engineering Colleges."
target_type = "Safety"
return {
"score": total_score,
"breakdown": {
"accuracy": round(w_accuracy, 1),
"speed": round(w_speed, 1),
"consistency": round(w_consistency, 1),
"recovery": round(w_recovery, 1),
"coverage": round(w_coverage, 1)
},
"college_prediction": prediction,
"prediction_category": target_type
}