Spaces:
Sleeping
Sleeping
| # app.py — paste into your Hugging Face Space (Python Gradio runtime) | |
| import os, json, html, random | |
| from datetime import datetime | |
| import gradio as gr | |
| import plotly.graph_objects as go | |
| # ---------------- Files ---------------- | |
| LEADERBOARD_FILE = "road2success_leaderboard.json" | |
| PROGRESS_FILE = "student_progress.json" | |
| OPPORTUNITIES_FILE = "student_opportunities.json" | |
| # Default data factories | |
| def default_progress_data(): | |
| return { | |
| "current_level": "Class 10", | |
| "quizzes_completed": {}, | |
| "study_sessions_completed": {}, | |
| "total_hours_studied": 0, | |
| "last_study_date": datetime.now().isoformat(), | |
| "daily_goals": {}, | |
| "achievements": [], | |
| "code_snippets_completed": {} | |
| } | |
| def default_opportunities_data(): | |
| return { | |
| "hackathons": [], | |
| "internships": [], | |
| "scholarships": [], | |
| "reminders": [] | |
| } | |
| # Initialize files if missing | |
| if not os.path.exists(PROGRESS_FILE): | |
| with open(PROGRESS_FILE, "w") as f: | |
| json.dump(default_progress_data(), f, indent=2) | |
| if not os.path.exists(OPPORTUNITIES_FILE): | |
| with open(OPPORTUNITIES_FILE, "w") as f: | |
| json.dump(default_opportunities_data(), f, indent=2) | |
| if not os.path.exists(LEADERBOARD_FILE): | |
| with open(LEADERBOARD_FILE, "w") as f: | |
| json.dump({"scores": []}, f, indent=2) | |
| def load_progress(): | |
| try: | |
| with open(PROGRESS_FILE, "r") as f: | |
| return json.load(f) | |
| except: | |
| return default_progress_data() | |
| def save_progress(p): | |
| with open(PROGRESS_FILE, "w") as f: | |
| json.dump(p, f, indent=2) | |
| def load_opportunities(): | |
| try: | |
| with open(OPPORTUNITIES_FILE, "r") as f: | |
| return json.load(f) | |
| except: | |
| return default_opportunities_data() | |
| def save_opportunities(d): | |
| with open(OPPORTUNITIES_FILE, "w") as f: | |
| json.dump(d, f, indent=2) | |
| def reset_leaderboard(): | |
| with open(LEADERBOARD_FILE, "w") as f: | |
| json.dump({"scores": []}, f, indent=2) | |
| # ---------------- Roadmaps & Data ---------------- | |
| ROADMAPS = { | |
| "Class 6": { | |
| "objective": "Build curiosity, logical thinking, basic problem-solving and gentle programming.", | |
| "subjects": ["Fractions, Decimals, Basic Geometry", "Basics of Physics, Chemistry, Biology", "Scratch / Python Turtle basics"], | |
| "study_sessions": [ | |
| {"title": "Basic Mathematics Fundamentals", "duration": "2 hours", "topics": ["Number System", "Basic Operations", "Fractions"]}, | |
| {"title": "Introduction to Science", "duration": "1.5 hours", "topics": ["Living Organisms", "Matter", "Energy"]}, | |
| {"title": "Scratch Programming Basics", "duration": "2 hours", "topics": ["Blocks", "Sprites", "Simple Games"]} | |
| ], | |
| "projects": ["Simple games in Scratch", "Science fair volcano or plant growth"], | |
| "weekly_hours": 18, | |
| "difficulty": "Beginner" | |
| }, | |
| "Class 7": { | |
| "objective": "Strengthen reasoning, begin structured coding and deeper science.", | |
| "subjects": ["Integers, Fractions, Probability", "Forces, Motion, Biology", "Python basics - loops & conditionals"], | |
| "study_sessions": [ | |
| {"title": "Algebra Fundamentals", "duration": "2.5 hours", "topics": ["Variables", "Equations", "Expressions"]}, | |
| {"title": "Physics Basics", "duration": "2 hours", "topics": ["Motion", "Forces", "Energy"]}, | |
| {"title": "Python Introduction", "duration": "3 hours", "topics": ["Syntax", "Variables", "Basic Programs"]} | |
| ], | |
| "projects": ["Python guessing game", "Science experiments logbook"], | |
| "weekly_hours": 20, | |
| "difficulty": "Beginner" | |
| }, | |
| "Class 8": { | |
| "objective": "Structured thinking, algebra foundation, and applied coding.", | |
| "subjects": ["Algebra, Linear equations, Geometry", "Electricity basics, Chemistry", "Python lists & functions"], | |
| "study_sessions": [ | |
| {"title": "Algebra and Equations", "duration": "3 hours", "topics": ["Linear Equations", "Polynomials", "Factorization"]}, | |
| {"title": "Science Concepts", "duration": "2.5 hours", "topics": ["Electricity", "Chemical Reactions", "Light"]}, | |
| {"title": "Python Functions", "duration": "3 hours", "topics": ["Functions", "Lists", "Basic Algorithms"]} | |
| ], | |
| "projects": ["Calculator in Python", "Science project presentation"], | |
| "weekly_hours": 22, | |
| "difficulty": "Intermediate" | |
| }, | |
| "Class 9": { | |
| "objective": "Prepare foundations for high-school STEM and beginner coding competitions.", | |
| "subjects": ["Geometry, Trigonometry basics, Probability", "Motion, Energy, Chemistry basics", "Python data structures"], | |
| "study_sessions": [ | |
| {"title": "Geometry and Trigonometry", "duration": "3 hours", "topics": ["Triangles", "Circles", "Trigonometric Ratios"]}, | |
| {"title": "Physics Fundamentals", "duration": "3 hours", "topics": ["Motion", "Force", "Energy", "Work"]}, | |
| {"title": "Python Data Structures", "duration": "3 hours", "topics": ["Lists", "Dictionaries", "Tuples", "Sets"]} | |
| ], | |
| "projects": ["Math problem solver", "Physics simulation"], | |
| "weekly_hours": 25, | |
| "difficulty": "Intermediate" | |
| }, | |
| "Class 10": { | |
| "objective": "Prepare for board exams and build strong coding fundamentals.", | |
| "subjects": ["Algebra, Quadratics, Coordinate Geometry", "Physics/Chem/Biology fundamentals", "Python algorithms"], | |
| "study_sessions": [ | |
| {"title": "Advanced Mathematics", "duration": "4 hours", "topics": ["Quadratic Equations", "Arithmetic Progressions", "Coordinate Geometry"]}, | |
| {"title": "Science Comprehensive", "duration": "4 hours", "topics": ["Light", "Electricity", "Chemical Reactions", "Life Processes"]}, | |
| {"title": "Python Algorithms", "duration": "3 hours", "topics": ["Sorting", "Searching", "Problem Solving"]} | |
| ], | |
| "projects": ["Board exam preparation", "Mini coding projects"], | |
| "weekly_hours": 30, | |
| "difficulty": "Intermediate" | |
| }, | |
| "JEE Main": { | |
| "objective": "Crack JEE Main with focused PCM practice and time management.", | |
| "subjects": ["Physics: Mechanics, Optics, Modern Physics", "Chemistry: Physical, Organic, Inorganic", "Mathematics: Algebra, Calculus, Coordinate Geometry"], | |
| "study_sessions": [ | |
| {"title": "Physics Advanced", "duration": "5 hours", "topics": ["Mechanics", "Optics", "Electromagnetism", "Modern Physics"]}, | |
| {"title": "Chemistry Comprehensive", "duration": "5 hours", "topics": ["Physical Chemistry", "Organic Chemistry", "Inorganic Chemistry"]}, | |
| {"title": "Mathematics Intensive", "duration": "5 hours", "topics": ["Calculus", "Algebra", "Coordinate Geometry", "Probability"]} | |
| ], | |
| "projects": ["Mock test series", "Previous year papers"], | |
| "weekly_hours": 45, | |
| "difficulty": "Advanced" | |
| }, | |
| "NEET": { | |
| "objective": "Crack NEET with strong Biology focus and NCERT mastery.", | |
| "subjects": ["Biology: Botany, Zoology", "Chemistry: Physical, Organic, Inorganic", "Physics: Basics for Medical"], | |
| "study_sessions": [ | |
| {"title": "Biology Intensive", "duration": "6 hours", "topics": ["Human Physiology", "Genetics", "Plant Physiology", "Ecology"]}, | |
| {"title": "Chemistry for NEET", "duration": "4 hours", "topics": ["Organic Chemistry", "Physical Chemistry", "Inorganic Chemistry"]}, | |
| {"title": "Physics Medical", "duration": "4 hours", "topics": ["Mechanics", "Optics", "Thermodynamics", "Modern Physics"]} | |
| ], | |
| "projects": ["NCERT revision", "Medical entrance mock tests"], | |
| "weekly_hours": 48, | |
| "difficulty": "Advanced" | |
| }, | |
| "B.Tech 1st Year": { | |
| "objective": "Build strong foundation in programming, mathematics, and basic engineering.", | |
| "subjects": ["Programming Fundamentals", "Engineering Mathematics", "Physics & Chemistry", "Basic Electronics"], | |
| "study_sessions": [ | |
| {"title": "C Programming", "duration": "4 hours", "topics": ["Data Types", "Control Structures", "Functions", "Arrays"]}, | |
| {"title": "Engineering Mathematics", "duration": "4 hours", "topics": ["Calculus", "Matrices", "Differential Equations"]}, | |
| {"title": "Engineering Physics", "duration": "3 hours", "topics": ["Mechanics", "Waves", "Optics", "Thermodynamics"]} | |
| ], | |
| "projects": ["Simple Calculator", "Basic Circuit Design"], | |
| "weekly_hours": 35, | |
| "difficulty": "Intermediate" | |
| }, | |
| "B.Tech 2nd Year": { | |
| "objective": "Develop core engineering skills and branch specialization.", | |
| "subjects": ["Data Structures", "Object-Oriented Programming", "Database Management", "Discrete Mathematics"], | |
| "study_sessions": [ | |
| {"title": "Data Structures", "duration": "5 hours", "topics": ["Arrays", "Linked Lists", "Stacks", "Queues", "Trees"]}, | |
| {"title": "OOP Concepts", "duration": "4 hours", "topics": ["Classes", "Inheritance", "Polymorphism", "Abstraction"]}, | |
| {"title": "Database Systems", "duration": "4 hours", "topics": ["SQL", "Normalization", "ER Diagrams"]} | |
| ], | |
| "projects": ["Library Management System", "Student Database"], | |
| "weekly_hours": 38, | |
| "difficulty": "Intermediate" | |
| }, | |
| "B.Tech 3rd Year": { | |
| "objective": "Advanced specialization and industry-ready skills development.", | |
| "subjects": ["Operating Systems", "Computer Networks", "Software Engineering", "Machine Learning"], | |
| "study_sessions": [ | |
| {"title": "Operating Systems", "duration": "5 hours", "topics": ["Process Management", "Memory Management", "File Systems"]}, | |
| {"title": "Computer Networks", "duration": "5 hours", "topics": ["TCP/IP", "Routing", "Network Security"]}, | |
| {"title": "Machine Learning", "duration": "5 hours", "topics": ["Supervised Learning", "Unsupervised Learning", "Neural Networks"]} | |
| ], | |
| "projects": ["Web Application", "ML Project", "Network Simulation"], | |
| "weekly_hours": 42, | |
| "difficulty": "Advanced" | |
| }, | |
| "B.Tech Final Year": { | |
| "objective": "Capstone projects, placement preparation, and research orientation.", | |
| "subjects": ["System Design", "Cloud Computing", "Big Data Analytics", "AI & Deep Learning"], | |
| "study_sessions": [ | |
| {"title": "System Design", "duration": "6 hours", "topics": ["Microservices", "Load Balancing", "Scalability"]}, | |
| {"title": "Cloud Computing", "duration": "5 hours", "topics": ["AWS/Azure", "Virtualization", "Containerization"]}, | |
| {"title": "AI & Deep Learning", "duration": "6 hours", "topics": ["CNN", "RNN", "Transformers", "Computer Vision"]} | |
| ], | |
| "projects": ["Major Project", "Research Paper", "Portfolio Website"], | |
| "weekly_hours": 45, | |
| "difficulty": "Expert" | |
| } | |
| } | |
| # ---------------- Code Snippets for B.Tech Students ---------------- | |
| CODE_SNIPPETS = { | |
| "B.Tech 1st Year": [ | |
| { | |
| "title": "Factorial Calculator", | |
| "problem": "Write a C program to calculate factorial of a number using recursion", | |
| "code": """#include <stdio.h> | |
| long factorial(int n) { | |
| if (n == 0 || n == 1) | |
| return 1; | |
| else | |
| return n * factorial(n - 1); | |
| } | |
| int main() { | |
| int num; | |
| printf("Enter a positive integer: "); | |
| scanf("%d", &num); | |
| if (num < 0) | |
| printf("Factorial is not defined for negative numbers.\\n"); | |
| else | |
| printf("Factorial of %d = %ld\\n", num, factorial(num)); | |
| return 0; | |
| }""", | |
| "explanation": "This program uses recursion to calculate factorial. The base case is when n=0 or n=1, returning 1. Otherwise, it calls itself with n-1.", | |
| "video_url": "https://www.youtube.com/embed/4agL-MQq05E" | |
| }, | |
| { | |
| "title": "Matrix Multiplication", | |
| "problem": "Write a C program for matrix multiplication", | |
| "code": """#include <stdio.h> | |
| int main() { | |
| int a[10][10], b[10][10], result[10][10]; | |
| int r1, c1, r2, c2; | |
| printf("Enter rows and columns for first matrix: "); | |
| scanf("%d %d", &r1, &c1); | |
| printf("Enter rows and columns for second matrix: "); | |
| scanf("%d %d", &r2, &c2); | |
| if (c1 != r2) { | |
| printf("Matrix multiplication not possible!\\n"); | |
| return 0; | |
| } | |
| printf("Enter elements of matrix 1:\\n"); | |
| for(int i=0; i<r1; i++) | |
| for(int j=0; j<c1; j++) | |
| scanf("%d", &a[i][j]); | |
| printf("Enter elements of matrix 2:\\n"); | |
| for(int i=0; i<r2; i++) | |
| for(int j=0; j<c2; j++) | |
| scanf("%d", &b[i][j]); | |
| // Multiply matrices | |
| for(int i=0; i<r1; i++) { | |
| for(int j=0; j<c2; j++) { | |
| result[i][j] = 0; | |
| for(int k=0; k<c1; k++) | |
| result[i][j] += a[i][k] * b[k][j]; | |
| } | |
| } | |
| printf("Result matrix:\\n"); | |
| for(int i=0; i<r1; i++) { | |
| for(int j=0; j<c2; j++) | |
| printf("%d\\t", result[i][j]); | |
| printf("\\n"); | |
| } | |
| return 0; | |
| }""", | |
| "explanation": "Matrix multiplication requires that columns of first matrix equal rows of second matrix. Uses triple nested loops for calculation.", | |
| "video_url": "https://www.youtube.com/embed/jzdQ-5hry98" | |
| } | |
| ], | |
| "B.Tech 2nd Year": [ | |
| { | |
| "title": "Linked List Implementation", | |
| "problem": "Implement a singly linked list with insert, delete and display operations", | |
| "code": """#include <stdio.h> | |
| #include <stdlib.h> | |
| struct Node { | |
| int data; | |
| struct Node* next; | |
| }; | |
| struct Node* createNode(int data) { | |
| struct Node* newNode = (struct Node*)malloc(sizeof(struct Node)); | |
| newNode->data = data; | |
| newNode->next = NULL; | |
| return newNode; | |
| } | |
| void insertAtEnd(struct Node** head, int data) { | |
| struct Node* newNode = createNode(data); | |
| if (*head == NULL) { | |
| *head = newNode; | |
| return; | |
| } | |
| struct Node* temp = *head; | |
| while (temp->next != NULL) | |
| temp = temp->next; | |
| temp->next = newNode; | |
| } | |
| void deleteNode(struct Node** head, int key) { | |
| struct Node *temp = *head, *prev = NULL; | |
| if (temp != NULL && temp->data == key) { | |
| *head = temp->next; | |
| free(temp); | |
| return; | |
| } | |
| while (temp != NULL && temp->data != key) { | |
| prev = temp; | |
| temp = temp->next; | |
| } | |
| if (temp == NULL) return; | |
| prev->next = temp->next; | |
| free(temp); | |
| } | |
| void displayList(struct Node* head) { | |
| struct Node* temp = head; | |
| while (temp != NULL) { | |
| printf("%d -> ", temp->data); | |
| temp = temp->next; | |
| } | |
| printf("NULL\\n"); | |
| } | |
| int main() { | |
| struct Node* head = NULL; | |
| insertAtEnd(&head, 10); | |
| insertAtEnd(&head, 20); | |
| insertAtEnd(&head, 30); | |
| printf("Linked list: "); | |
| displayList(head); | |
| deleteNode(&head, 20); | |
| printf("After deleting 20: "); | |
| displayList(head); | |
| return 0; | |
| }""", | |
| "explanation": "Singly linked list implementation with dynamic memory allocation. Includes node creation, insertion at end, deletion by value, and display functions.", | |
| "video_url": "https://www.youtube.com/embed/dq3F3e9o2DM" | |
| } | |
| ] | |
| } | |
| # ---------------- Opportunities (H/I/S) ---------------- | |
| HACKATHONS = [ | |
| {"name":"Smart India Hackathon 2025","deadline":"2025-09-30","eligibility":"College Students (All Years)","prizes":"₹5 Lakhs + Incubation","skills":["Programming","Problem Solving"],"url":"https://sih.gov.in","category":"National","level":"B.Tech All Years"}, | |
| {"name":"NASA Space Apps Challenge","deadline":"2025-10-01","eligibility":"All Students","prizes":"NASA Recognition + Prizes","skills":["Data Science","Space Tech"],"url":"https://www.spaceappschallenge.org","category":"International","level":"All Levels"} | |
| ] | |
| INTERNSHIPS = [ | |
| {"name":"Software Engineering Intern","deadline":"2025-10-30","duration":"12 weeks","stipend":"₹30,000/month","skills":["Python"],"url":"https://jobs.careers.microsoft.com/us/en/job/1880847/Software-Engineering-Intern","type":"B.Tech","level":"Class 11-12"}, | |
| {"name":"Software Application Development Apprenticeship, March 2026","deadline":"2025-10-10","duration":"12 weeks","stipend":"50000k","skills":["Open Source"],"url":"https://www.geekscodes.com/2025/08/google-software-development.html","type":"Open Source","level":"B.Tech 2nd-4th Year"} | |
| ] | |
| SCHOLARSHIPS = [ | |
| {"name":"Reliance Foundation Scholarships","deadline":"2026-01-15","amount":"₹10000/month","eligibility":"Secondary,Undergraduate,Postgraduate","url":"https://www.scholarships.reliancefoundation.org/","type":"Merit-based","level":"Secondary,Undergraduate,Postgraduate"} | |
| ] | |
| # ---------------- AI Mentor (lightweight) ---------------- | |
| def ai_mentor_query(prompt, short_answer=True, eli5=False): | |
| if not prompt or not prompt.strip(): | |
| return "Ask a clear question about study plans, hackathons, or projects." | |
| fallback_responses = [ | |
| "Try splitting study into focused 25-minute sessions with 5-minute breaks.", | |
| "For hackathons, build the smallest working prototype first, then polish.", | |
| "Practice coding by building small projects; review and refactor them.", | |
| "Create a weekly schedule and stick to short daily study blocks for steady progress." | |
| ] | |
| return random.choice(fallback_responses) | |
| # ---------------- Dashboard helpers ---------------- | |
| def create_progress_chart(level, sessions_completed, total_sessions): | |
| progress = 0 | |
| if total_sessions > 0: | |
| progress = min((sessions_completed / total_sessions) * 100, 100) | |
| fig = go.Figure(go.Indicator(mode="gauge+number", value=progress, domain={'x':[0,1],'y':[0,1]}, title={'text':f"Study Progress - {level}"}, gauge={'axis':{'range':[None,100]}})) | |
| return fig | |
| def get_study_materials_interface(level): | |
| sessions = ROADMAPS.get(level, {}).get("study_sessions", []) | |
| progress_data = load_progress() | |
| materials_html = "<div style='max-height:520px;overflow-y:auto;'>" | |
| materials_html += "<h3>📚 Study Sessions</h3>" | |
| for i, session in enumerate(sessions): | |
| session_key = f"{level}_{session['title']}" | |
| is_completed = progress_data.get("study_sessions_completed", {}).get(session_key, False) | |
| status_icon = "✅" if is_completed else "⏳" | |
| status_color = "#28a745" if is_completed else "#007bff" | |
| materials_html += f""" | |
| <div style='padding:12px;margin:8px 0;background:{'#d4edda' if is_completed else '#f8f9fa'};border-radius:8px;border-left:4px solid {status_color};'> | |
| <h4 style="color:#0b3d91">{status_icon} Session {i+1}: {html.escape(session['title'])}</h4> | |
| <p>⏰ {session['duration']}</p> | |
| <p>📚 {', '.join(session['topics'])}</p> | |
| </div> | |
| """ | |
| materials_html += "</div>" | |
| return materials_html | |
| def mark_session_completed(level, session_title): | |
| if not level or not session_title: | |
| return "❌ Level and session required." | |
| p = load_progress() | |
| key = f"{level}_{session_title}" | |
| p.setdefault("study_sessions_completed", {}) | |
| current = p["study_sessions_completed"].get(key, False) | |
| p["study_sessions_completed"][key] = not current | |
| # update hours | |
| s = next((x for x in ROADMAPS.get(level, {}).get("study_sessions", []) if x['title'] == session_title), None) | |
| if s: | |
| try: | |
| hours = float(s['duration'].split()[0]) | |
| except: | |
| hours = 0.0 | |
| if not current: | |
| p["total_hours_studied"] = p.get("total_hours_studied", 0) + hours | |
| else: | |
| p["total_hours_studied"] = max(0, p.get("total_hours_studied", 0) - hours) | |
| p["last_study_date"] = datetime.now().isoformat() | |
| save_progress(p) | |
| action = "completed" if not current else "unmarked" | |
| return f"✅ Session '{session_title}' {action}! Progress updated." | |
| def create_dashboard_stats(level): | |
| p = load_progress() | |
| sessions = ROADMAPS.get(level, {}).get("study_sessions", []) | |
| completed_sessions = sum(1 for s in sessions if p.get("study_sessions_completed", {}).get(f"{level}_{s['title']}", False)) | |
| total_sessions = len(sessions) | |
| percent = (completed_sessions / total_sessions * 100) if total_sessions > 0 else 0 | |
| last = p.get("last_study_date", datetime.now().isoformat())[:10] | |
| html_block = f""" | |
| <div style='background:linear-gradient(135deg,#dbeafe,#bde4ff);color:#0b3d91;padding:16px;border-radius:10px;'> | |
| <h3>🎯 {level} Learning Dashboard</h3> | |
| <div style='display:flex;justify-content:space-around;flex-wrap:wrap;margin-top:10px;'> | |
| <div><h4>📚 {completed_sessions}/{total_sessions}</h4><small>Sessions</small></div> | |
| <div><h4>⏰ {p.get('total_hours_studied',0):.1f}</h4><small>Total Hours</small></div> | |
| <div><h4>📅 {last}</h4><small>Last Study</small></div> | |
| </div> | |
| <p style='margin-top:12px;'>Overall Progress: <strong>{percent:.1f}%</strong></p> | |
| <div style='background:#ddd;border-radius:8px;height:10px;'><div style='background:#28a745;height:100%;width:{percent}%;border-radius:8px;'></div></div> | |
| </div> | |
| """ | |
| return html_block | |
| def get_code_snippets_interface(level): | |
| if level not in CODE_SNIPPETS: | |
| return "<div style='text-align:center;padding:20px;'><h4>No code snippets available for this level</h4></div>" | |
| snippets = CODE_SNIPPETS[level] | |
| progress_data = load_progress() | |
| snippets_html = "<div style='max-height:520px;overflow-y:auto;'>" | |
| snippets_html += "<h3>💻 Code Snippets & Practice Problems</h3>" | |
| for i, snippet in enumerate(snippets): | |
| snippet_key = f"{level}_{snippet['title']}" | |
| is_completed = progress_data.get("code_snippets_completed", {}).get(snippet_key, False) | |
| status_icon = "✅" if is_completed else "💻" | |
| status_color = "#28a745" if is_completed else "#007bff" | |
| snippets_html += f""" | |
| <div style='padding:12px;margin:8px 0;background:{'#d4edda' if is_completed else '#f8f9fa'};border-radius:8px;border-left:4px solid {status_color};'> | |
| <h4 style="color:#0b3d91">{status_icon} {html.escape(snippet['title'])}</h4> | |
| <p><strong>Problem:</strong> {html.escape(snippet['problem'])}</p> | |
| <details> | |
| <summary><strong>View Code Solution</strong></summary> | |
| <pre style='background:#f5f5f5;padding:10px;border-radius:5px;overflow-x:auto;'>{html.escape(snippet['code'])}</pre> | |
| </details> | |
| <p><strong>Explanation:</strong> {html.escape(snippet['explanation'])}</p> | |
| <div style='margin-top:10px;'> | |
| <iframe width="100%" height="200" src="{snippet['video_url']}" frameborder="0" allowfullscreen></iframe> | |
| </div> | |
| </div> | |
| """ | |
| snippets_html += "</div>" | |
| return snippets_html | |
| def mark_code_snippet_completed(level, snippet_title): | |
| if not level or not snippet_title: | |
| return "❌ Level and snippet title required." | |
| p = load_progress() | |
| key = f"{level}_{snippet_title}" | |
| p.setdefault("code_snippets_completed", {}) | |
| current = p["code_snippets_completed"].get(key, False) | |
| p["code_snippets_completed"][key] = not current | |
| save_progress(p) | |
| action = "completed" if not current else "unmarked" | |
| return f"✅ Code snippet '{snippet_title}' {action}!" | |
| # ---------------- Opportunities & Reminders ---------------- | |
| def get_upcoming_deadlines_html(): | |
| today = datetime.now().date() | |
| items = HACKATHONS + INTERNSHIPS + SCHOLARSHIPS | |
| deadlines = [] | |
| for it in items: | |
| dl = it.get("deadline") | |
| try: | |
| d = datetime.strptime(dl, "%Y-%m-%d").date() | |
| days = (d - today).days | |
| except: | |
| days = None | |
| deadlines.append({"name":it.get("name"), "deadline":dl, "days_left":days, "url":it.get("url","#")}) | |
| deadlines = sorted([d for d in deadlines if d['days_left'] is None or d['days_left']>=0], key=lambda x: (x['days_left'] if x['days_left'] is not None else 999)) | |
| if not deadlines: | |
| return "<div style='padding:12px;text-align:center;'><h4>No upcoming deadlines</h4></div>" | |
| html_block = "<div style='max-height:420px;overflow-y:auto;'>" | |
| for d in deadlines[:12]: | |
| left = f"{d['days_left']} days left" if d['days_left'] is not None else "N/A" | |
| html_block += f"<div style='padding:10px;margin:8px 0;background:white;border-radius:8px;'><h4>{html.escape(d['name'])}</h4><p>📅 {d['deadline']} | {left}</p><a href='{d['url']}' target='_blank'>More</a></div>" | |
| html_block += "</div>" | |
| return html_block | |
| def create_hackathon_interface_html(): | |
| html_block = "<div style='max-height:420px;overflow-y:auto;'>" | |
| for h in HACKATHONS: | |
| try: | |
| days = (datetime.strptime(h['deadline'],'%Y-%m-%d').date() - datetime.now().date()).days | |
| except: | |
| days = "N/A" | |
| html_block += f"<div style='padding:12px;margin:8px 0;background:linear-gradient(135deg,#dbeafe,#bde4ff);color:#0b3d91;border-radius:8px;'><h4>🏆 {h['name']}</h4><p>📅 {h['deadline']} | {days} days left</p><p>Eligibility: {h['eligibility']}</p><a href='{h['url']}' style='color:#0b3d91' target='_blank'>Apply</a></div>" | |
| html_block += "</div>" | |
| return html_block | |
| def create_internship_interface_html(): | |
| html_block = "<div style='max-height:420px;overflow-y:auto;'>" | |
| for it in INTERNSHIPS: | |
| try: | |
| days = (datetime.strptime(it['deadline'],'%Y-%m-%d').date() - datetime.now().date()).days | |
| except: | |
| days = "N/A" | |
| html_block += f"<div style='padding:12px;margin:8px 0;background:linear-gradient(135deg,#e6f4ff,#cfeeff);color:#0b3d91;border-radius:8px;'><h4>💼 {it['name']}</h4><p>📅 {it['deadline']} | {days} days left</p><p>Duration: {it.get('duration')}</p><a href='{it['url']}' style='color:#0b3d91' target='_blank'>Apply</a></div>" | |
| html_block += "</div>" | |
| return html_block | |
| def create_scholarship_interface_html(): | |
| html_block = "<div style='max-height:420px;overflow-y:auto;'>" | |
| for s in SCHOLARSHIPS: | |
| try: | |
| days = (datetime.strptime(s['deadline'],'%Y-%m-%d').date() - datetime.now().date()).days | |
| except: | |
| days = "N/A" | |
| html_block += f"<div style='padding:12px;margin:8px 0;background:linear-gradient(135deg,#e0f7ff,#cdeeff);color:#0b3d91;border-radius:8px;'><h4>🎓 {s['name']}</h4><p>📅 {s['deadline']} | {days} days left</p><p>Amount: {s.get('amount')}</p><a href='{s['url']}' style='color:#0b3d91' target='_blank'>Apply</a></div>" | |
| html_block += "</div>" | |
| return html_block | |
| def set_custom_reminder(reminder_type, reminder_name, reminder_date, reminder_notes): | |
| if not reminder_name or not reminder_date: | |
| return "❌ Name and date required." | |
| try: | |
| datetime.strptime(reminder_date, "%Y-%m-%d") | |
| except ValueError: | |
| return "❌ Invalid date format. Use YYYY-MM-DD." | |
| data = load_opportunities() | |
| data.setdefault("reminders", []) | |
| new = { | |
| "type": reminder_type or "Personal", | |
| "name": reminder_name, | |
| "date": reminder_date, | |
| "notes": reminder_notes or "", | |
| "set_date": datetime.now().isoformat(), | |
| "completed": False | |
| } | |
| data["reminders"].append(new) | |
| save_opportunities(data) | |
| return f"✅ Reminder set for {reminder_date}: {reminder_name}" | |
| def get_custom_reminders_html(): | |
| data = load_opportunities() | |
| rems = data.get("reminders", []) | |
| if not rems: | |
| return "<div style='text-align:center;padding:12px;'><h4>No custom reminders.</h4></div>" | |
| html_block = "<div style='max-height:420px;overflow-y:auto;'>" | |
| for idx, r in enumerate(rems): | |
| try: | |
| d = datetime.strptime(r['date'], "%Y-%m-%d").date() | |
| days_left = (d - datetime.now().date()).days | |
| left_text = f"{days_left} days left" | |
| except: | |
| left_text = "N/A" | |
| color = "#28a745" if r.get("completed") else "#ff6b6b" | |
| status = "✅" if r.get("completed") else "⏳" | |
| html_block += f""" | |
| <div style='padding:10px;margin:8px 0;background:white;border-left:6px solid {color};border-radius:8px;'> | |
| <h4>{status} [{idx}] {html.escape(r['type'])}: {html.escape(r['name'])}</h4> | |
| <p>📅 {r['date']} | {left_text}</p> | |
| <p>📝 {html.escape(r.get('notes',''))}</p> | |
| <p style='font-size:12px;color:#666;'>Set on: {r['set_date'][:10]}</p> | |
| </div> | |
| """ | |
| html_block += "</div>" | |
| return html_block | |
| def mark_reminder_completed(index): | |
| data = load_opportunities() | |
| rems = data.get("reminders", []) | |
| try: | |
| idx = int(index) | |
| if idx < 0 or idx >= len(rems): | |
| return "❌ Invalid index" | |
| except: | |
| return "❌ Invalid index" | |
| rems[idx]['completed'] = True | |
| save_opportunities(data) | |
| return "✅ Reminder marked completed." | |
| def delete_reminder(index): | |
| data = load_opportunities() | |
| rems = data.get("reminders", []) | |
| try: | |
| idx = int(index) | |
| if idx < 0 or idx >= len(rems): | |
| return "❌ Invalid index" | |
| except: | |
| return "❌ Invalid index" | |
| name = rems[idx].get("name","") | |
| rems.pop(idx) | |
| save_opportunities(data) | |
| return f"🗑️ Reminder '{name}' deleted." | |
| # ---------------- GRADIO UI ---------------- | |
| custom_css = """ | |
| .gradio-container { | |
| background: linear-gradient(135deg, #eaf6ff 0%, #d5efff 100%); | |
| min-height: 100vh; | |
| padding: 24px; | |
| color: #0b3d91; | |
| } | |
| .gradio-container .container { | |
| background: rgba(255,255,255,0.04); | |
| border-radius: 12px; | |
| padding: 16px; | |
| } | |
| """ | |
| with gr.Blocks(title="Road2Success — Learning Dashboard", theme=gr.themes.Soft(), css=custom_css) as app: | |
| gr.Markdown("# 🚀 Road2Success — Learning Dashboard") | |
| gr.Markdown("*Professional roadmap, AI mentor, hackathon prep & leaderboard*") | |
| with gr.Tabs(): | |
| # Learning Dashboard | |
| with gr.TabItem("🏠 Learning Dashboard"): | |
| with gr.Row(): | |
| with gr.Column(scale=2): | |
| gr.Markdown("### Select Level") | |
| level_choice = gr.Radio(choices=list(ROADMAPS.keys()), value=list(ROADMAPS.keys())[0], label="Level") | |
| refresh_btn = gr.Button("🔄 Refresh") | |
| stats_display = gr.HTML() | |
| with gr.Column(scale=3): | |
| progress_plot = gr.Plot() | |
| with gr.Row(): | |
| with gr.Column(scale=2): | |
| gr.Markdown("### Study Materials") | |
| materials_html = gr.HTML() | |
| with gr.Column(scale=1): | |
| gr.Markdown("### Quick Actions") | |
| session_dropdown = gr.Dropdown(label="Session", choices=[]) | |
| mark_session_btn = gr.Button("Mark Session Complete") | |
| action_status = gr.Textbox(interactive=False, label="Action status") | |
| gr.Markdown("### Code Snippets") | |
| code_snippets_html = gr.HTML() | |
| snippet_dropdown = gr.Dropdown(label="Code Snippet", choices=[]) | |
| mark_snippet_btn = gr.Button("Mark Snippet Complete") | |
| snippet_status = gr.Textbox(interactive=False, label="Snippet status") | |
| reset_btn = gr.Button("⚠️ Reset Dashboard", variant="danger") | |
| reset_status = gr.Textbox(interactive=False, label="Reset status") | |
| # Study Roadmaps | |
| with gr.TabItem("📚 Study Roadmaps"): | |
| gr.Markdown("## 🗺️ Study Roadmaps") | |
| roadmap_level = gr.Dropdown(choices=list(ROADMAPS.keys()), value=list(ROADMAPS.keys())[0], label="Select Level") | |
| show_roadmap_btn = gr.Button("Show Roadmap") | |
| roadmap_html = gr.HTML() | |
| # Opportunities & Reminders | |
| with gr.TabItem("🚀 Opportunities & Reminders"): | |
| gr.Markdown("## 🌟 Opportunities Hub") | |
| with gr.Row(): | |
| with gr.Column(scale=2): | |
| opp_overview = gr.HTML() | |
| gr.Markdown("### Hackathons") | |
| hack_html = gr.HTML() | |
| gr.Markdown("### Internships") | |
| intern_html = gr.HTML() | |
| gr.Markdown("### Scholarships") | |
| schol_html = gr.HTML() | |
| with gr.Column(scale=1): | |
| gr.Markdown("### Set Custom Reminder") | |
| r_type = gr.Dropdown(["Hackathon","Internship","Scholarship","Exam","Project","Personal"], label="Type") | |
| r_name = gr.Textbox(label="Name") | |
| r_date = gr.Textbox(label="Date (YYYY-MM-DD)") | |
| r_notes = gr.Textbox(label="Notes", lines=2) | |
| set_reminder_btn = gr.Button("Set Reminder") | |
| set_out = gr.Textbox(interactive=False, label="Set status") | |
| gr.Markdown("### Your Reminders (0-based index shown)") | |
| reminders_html = gr.HTML() | |
| rem_index = gr.Textbox(label="Reminder index (0-based)") | |
| mark_done_btn = gr.Button("Mark Done") | |
| del_btn = gr.Button("Delete Reminder") | |
| rem_action_status = gr.Textbox(interactive=False, label="Reminder action status") | |
| # AI Mentor | |
| with gr.TabItem("🤖 AI Mentor"): | |
| gr.Markdown("## 💬 AI Mentor (simple fallback)") | |
| prompt = gr.Textbox(label="Ask a question", lines=3) | |
| short_toggle = gr.Checkbox(label="Short answer", value=True) | |
| eli5_toggle = gr.Checkbox(label="Explain simply", value=False) | |
| ask_btn = gr.Button("Ask Mentor") | |
| mentor_out = gr.Textbox(lines=6, label="Mentor output") | |
| # -- Core update function | |
| def update_dashboard(level): | |
| sessions = ROADMAPS.get(level, {}).get("study_sessions", []) | |
| session_titles = [s['title'] for s in sessions] | |
| # Get code snippets for the level | |
| snippet_titles = [] | |
| if level in CODE_SNIPPETS: | |
| snippet_titles = [s['title'] for s in CODE_SNIPPETS[level]] | |
| stats = create_dashboard_stats(level) | |
| completed_sessions = sum(1 for s in sessions if load_progress().get("study_sessions_completed", {}).get(f"{level}_{s['title']}", False)) | |
| fig = create_progress_chart(level, completed_sessions, len(sessions)) | |
| materials = get_study_materials_interface(level) | |
| code_snippets = get_code_snippets_interface(level) | |
| opps = get_upcoming_deadlines_html() | |
| return (gr.update(choices=session_titles, value=(session_titles[0] if session_titles else None)), | |
| gr.update(choices=snippet_titles, value=(snippet_titles[0] if snippet_titles else None)), | |
| stats, fig, materials, code_snippets, opps) | |
| def refresh_all(level): | |
| session_update, snippet_update, stats, fig, materials, code_snippets, opps = update_dashboard(level) | |
| reminders = get_custom_reminders_html() | |
| hack = create_hackathon_interface_html() | |
| intern = create_internship_interface_html() | |
| schol = create_scholarship_interface_html() | |
| return session_update, snippet_update, stats, fig, materials, code_snippets, opps, reminders, hack, intern, schol | |
| def reset_dashboard(): | |
| save_progress(default_progress_data()) | |
| save_opportunities(default_opportunities_data()) | |
| reset_leaderboard() | |
| return "✅ Dashboard reset to defaults." | |
| # Wire events | |
| level_choice.change(update_dashboard, inputs=[level_choice], | |
| outputs=[session_dropdown, snippet_dropdown, stats_display, progress_plot, materials_html, code_snippets_html, opp_overview]) | |
| refresh_btn.click(update_dashboard, inputs=[level_choice], | |
| outputs=[session_dropdown, snippet_dropdown, stats_display, progress_plot, materials_html, code_snippets_html, opp_overview]) | |
| mark_session_btn.click(mark_session_completed, inputs=[level_choice, session_dropdown], outputs=[action_status]).then( | |
| update_dashboard, inputs=[level_choice], | |
| outputs=[session_dropdown, snippet_dropdown, stats_display, progress_plot, materials_html, code_snippets_html, opp_overview] | |
| ) | |
| mark_snippet_btn.click(mark_code_snippet_completed, inputs=[level_choice, snippet_dropdown], outputs=[snippet_status]).then( | |
| update_dashboard, inputs=[level_choice], | |
| outputs=[session_dropdown, snippet_dropdown, stats_display, progress_plot, materials_html, code_snippets_html, opp_overview] | |
| ) | |
| reset_btn.click(reset_dashboard, outputs=[reset_status]).then( | |
| refresh_all, inputs=[level_choice], | |
| outputs=[session_dropdown, snippet_dropdown, stats_display, progress_plot, materials_html, code_snippets_html, opp_overview, reminders_html, hack_html, intern_html, schol_html] | |
| ) | |
| # Study roadmap | |
| def show_roadmap(level): | |
| r = ROADMAPS.get(level, {}) | |
| html_block = f"<div style='padding:16px;background:linear-gradient(135deg,#dbeafe,#bde4ff);color:#0b3d91;border-radius:10px;'><h2>{level} - Learning Path</h2>" | |
| html_block += f"<h4>Objective</h4><p>{r.get('objective','')}</p>" | |
| html_block += "<h4>Subjects</h4><ul>" | |
| for sub in r.get('subjects', []): | |
| html_block += f"<li>{sub}</li>" | |
| html_block += "</ul><h4>Projects</h4><ul>" | |
| for proj in r.get('projects', []): | |
| html_block += f"<li>{proj}</li>" | |
| html_block += "</ul>" | |
| html_block += f"<p><strong>Weekly hours:</strong> {r.get('weekly_hours','N/A')}</p></div>" | |
| return html_block | |
| show_roadmap_btn.click(show_roadmap, inputs=[roadmap_level], outputs=[roadmap_html]) | |
| # Opportunities and reminders | |
| app.load(lambda: get_upcoming_deadlines_html(), outputs=[opp_overview]) | |
| app.load(lambda: create_hackathon_interface_html(), outputs=[hack_html]) | |
| app.load(lambda: create_internship_interface_html(), outputs=[intern_html]) | |
| app.load(lambda: create_scholarship_interface_html(), outputs=[schol_html]) | |
| app.load(lambda: get_custom_reminders_html(), outputs=[reminders_html]) | |
| set_reminder_btn.click(set_custom_reminder, inputs=[r_type, r_name, r_date, r_notes], outputs=[set_out]).then( | |
| lambda: get_custom_reminders_html(), outputs=[reminders_html] | |
| ).then(lambda: get_upcoming_deadlines_html(), outputs=[opp_overview]) | |
| mark_done_btn.click(mark_reminder_completed, inputs=[rem_index], outputs=[rem_action_status]).then( | |
| lambda: get_custom_reminders_html(), outputs=[reminders_html] | |
| ).then(lambda: get_upcoming_deadlines_html(), outputs=[opp_overview]) | |
| del_btn.click(delete_reminder, inputs=[rem_index], outputs=[rem_action_status]).then( | |
| lambda: get_custom_reminders_html(), outputs=[reminders_html] | |
| ).then(lambda: get_upcoming_deadlines_html(), outputs=[opp_overview]) | |
| ask_btn.click(ai_mentor_query, inputs=[prompt, short_toggle, eli5_toggle], outputs=[mentor_out]) | |
| # Initial load | |
| app.load(lambda: update_dashboard(list(ROADMAPS.keys())[0]), | |
| outputs=[session_dropdown, snippet_dropdown, stats_display, progress_plot, materials_html, code_snippets_html, opp_overview]) | |
| # Launch Gradio app | |
| if __name__ == "__main__": | |
| app.launch(share=True) |