| """ |
| Progress management for SkillSync |
| """ |
|
|
| import json |
| import os |
| from datetime import datetime |
|
|
| class ProgressManager: |
| """Manages user progress and submissions""" |
| |
| def __init__(self): |
| self.progress_file = "data/user_data/progress.json" |
| self.progress = self.load_progress() |
| |
| def load_progress(self): |
| """Load progress from file""" |
| try: |
| if os.path.exists(self.progress_file): |
| with open(self.progress_file, 'r') as f: |
| return json.load(f) |
| except Exception as e: |
| print(f"Error loading progress: {e}") |
| |
| return { |
| "completed_lessons": {}, |
| "quiz_scores": {}, |
| "assignment_submissions": {}, |
| "capstone_submitted": False, |
| "capstone_details": {}, |
| "last_accessed": None |
| } |
| |
| def save_progress(self): |
| """Save progress to file""" |
| try: |
| os.makedirs(os.path.dirname(self.progress_file), exist_ok=True) |
| self.progress["last_accessed"] = datetime.now().strftime("%Y-%m-%d %H:%M:%S") |
| with open(self.progress_file, 'w') as f: |
| json.dump(self.progress, f, indent=2) |
| return True |
| except Exception as e: |
| print(f"Error saving progress: {e}") |
| return False |
| |
| def get_completed_lessons(self, module_id): |
| """Get list of completed lesson IDs for a module""" |
| return self.progress["completed_lessons"].get(str(module_id), []) |
| |
| def get_total_completed(self): |
| """Get total number of completed lessons""" |
| return sum(len(lessons) for lessons in self.progress["completed_lessons"].values()) |
| |
| def mark_lesson_complete(self, module_id, lesson_id): |
| """Mark a lesson as complete""" |
| module_key = str(module_id) |
| if module_key not in self.progress["completed_lessons"]: |
| self.progress["completed_lessons"][module_key] = [] |
| if lesson_id not in self.progress["completed_lessons"][module_key]: |
| self.progress["completed_lessons"][module_key].append(lesson_id) |
| self.save_progress() |
| return True |
| return False |
| |
| def save_quiz_score(self, module_id, score): |
| """Save quiz score for a module""" |
| self.progress["quiz_scores"][str(module_id)] = { |
| "score": score, |
| "date": datetime.now().strftime("%Y-%m-%d %H:%M:%S") |
| } |
| self.save_progress() |
| return True |
| |
| def get_quiz_score(self, module_id): |
| """Get quiz score for a module""" |
| score_data = self.progress["quiz_scores"].get(str(module_id), {}) |
| return score_data.get("score", 0) |
| |
| def get_quizzes_passed(self, passing_score=80): |
| """Get number of quizzes passed""" |
| return sum( |
| 1 for score_data in self.progress["quiz_scores"].values() |
| if score_data.get("score", 0) >= passing_score |
| ) |
| |
| def save_assignment_submission(self, module_id, submission_data): |
| """Save assignment submission""" |
| module_key = str(module_id) |
| if module_key not in self.progress["assignment_submissions"]: |
| self.progress["assignment_submissions"][module_key] = [] |
| submission_data["submitted_at"] = datetime.now().strftime("%Y-%m-%d %H:%M:%S") |
| self.progress["assignment_submissions"][module_key].append(submission_data) |
| self.save_progress() |
| return True |
| |
| def submit_capstone(self, title, description, url, file): |
| """Submit capstone project""" |
| if not title or not description: |
| return False, "Title and description are required" |
| self.progress["capstone_submitted"] = True |
| self.progress["capstone_details"] = { |
| "title": title, |
| "description": description, |
| "url": url or "", |
| "submitted_at": datetime.now().strftime("%Y-%m-%d %H:%M:%S") |
| } |
| self.save_progress() |
| return True, "Capstone submitted successfully" |
| |
| def get_overall_progress(self, total_lessons=25): |
| """Calculate overall course progress""" |
| completed = self.get_total_completed() |
| return { |
| "total_lessons": total_lessons, |
| "completed_lessons": completed, |
| "percentage": int((completed / total_lessons) * 100) if total_lessons > 0 else 0, |
| "quizzes_passed": self.get_quizzes_passed(), |
| "capstone_submitted": self.progress.get("capstone_submitted", False) |
| } |
|
|