import streamlit as st import numpy as np import pandas as pd # ------------------------------- # PAGE CONFIG # ------------------------------- st.set_page_config(page_title="Smart Study Planner", page_icon="📚", layout="centered") # ------------------------------- # CUSTOM CSS (UI DESIGN) # ------------------------------- st.markdown(""" """, unsafe_allow_html=True) st.title("📚 Smart Study Planner with Smart Prediction") st.markdown("Analyze your study habits and improve performance 🚀") # ------------------------------- # CLASSES (OOP) # ------------------------------- class Subject: def __init__(self, name, hours, marks): self.name = name self.hours = hours self.marks = marks class Student: def __init__(self, name): self.name = name self.subjects = [] def add_subject(self, subject): self.subjects.append(subject) def get_dataframe(self): return pd.DataFrame({ "Subject": [s.name for s in self.subjects], "Study Hours": [s.hours for s in self.subjects], "Marks": [s.marks for s in self.subjects] }) def calculate_average(self): marks = [s.marks for s in self.subjects] return np.mean(marks) if marks else 0 def get_max_min(self): marks = [s.marks for s in self.subjects] return np.max(marks), np.min(marks) # ------------------------------- # SAFE TREND CALCULATION # ------------------------------- def performance_trend(self): hours = np.array([s.hours for s in self.subjects]) marks = np.array([s.marks for s in self.subjects]) if len(hours) > 1: trend = np.corrcoef(hours, marks)[0][1] if np.isnan(trend): trend = 0 return np.clip(trend, -1, 1) return 0 # ------------------------------- # AI-STYLE SMART PREDICTION (FIXED) # ------------------------------- def predict_performance(self): hours = np.array([s.hours for s in self.subjects]) marks = np.array([s.marks for s in self.subjects]) if len(hours) == 0: return 0 avg_marks = np.mean(marks) avg_hours = np.mean(hours) trend = self.performance_trend() variance = np.var(marks) consistency = 1 / (1 + variance) predicted = avg_marks \ + (avg_hours * 1.5) \ + (trend * 10) \ + (consistency * 5) return float(min(predicted, 100)) def get_grade(self, marks): if marks >= 85: return "A" elif marks >= 70: return "B" elif marks >= 55: return "C" elif marks >= 40: return "D" return "F" def best_subject(self): return max(self.subjects, key=lambda x: x.marks).name def weak_subject(self): return min(self.subjects, key=lambda x: x.marks).name def suggest_improvement(self): return f"Focus more on {self.weak_subject()} and increase study time by 2 hours." # ------------------------------- # SESSION STATE (FIXED) # ------------------------------- if "student" not in st.session_state: st.session_state.student = None if "student_name" not in st.session_state: st.session_state.student_name = "" # ------------------------------- # INPUT SECTION # ------------------------------- st.subheader("👤 Student Information") name = st.text_input("Enter Student Name", value=st.session_state.student_name) # FIX: create new student when name changes if name != st.session_state.student_name: st.session_state.student_name = name st.session_state.student = Student(name) # ------------------------------- # ADD SUBJECT # ------------------------------- st.subheader("📘 Add Subject") col1, col2, col3 = st.columns(3) with col1: subject_name = st.text_input("Subject") with col2: hours = st.number_input("Study Hours", min_value=0.0, step=0.5) with col3: marks = st.number_input("Marks", min_value=0, max_value=100) if st.button("➕ Add Subject"): if not name: st.error("Please enter student name first!") elif not subject_name: st.error("Please enter subject name!") else: sub = Subject(subject_name, hours, marks) st.session_state.student.add_subject(sub) st.success(f"{subject_name} added successfully!") # ------------------------------- # ANALYSIS SECTION # ------------------------------- st.markdown("---") if st.button("📊 Analyze Performance"): student = st.session_state.student if student is None or len(student.subjects) == 0: st.error("Please add subjects first!") else: df = student.get_dataframe() st.subheader("📋 Performance Table") st.dataframe(df, use_container_width=True) avg = student.calculate_average() max_m, min_m = student.get_max_min() grade = student.get_grade(avg) predicted = student.predict_performance() predicted_grade = student.get_grade(predicted) # ---------------- METRICS ---------------- col1, col2, col3 = st.columns(3) col1.metric("Average Marks", f"{avg:.2f}") col2.metric("Highest Marks", max_m) col3.metric("Lowest Marks", min_m) # ---------------- PROGRESS BAR ---------------- st.subheader("📈 Performance Progress") st.progress(int(avg)) st.write(f"🎯 Current Grade: **{grade}**") # ---------------- PREDICTION ---------------- st.subheader("🔮 Smart Prediction") if np.isnan(predicted): st.error("Prediction error due to insufficient variation in data") else: st.success(f"Expected Marks: {predicted:.2f}") st.success(f"Predicted Grade: {predicted_grade}") # ---------------- INSIGHTS ---------------- st.subheader("📌 Insights") st.write(f"🏆 Best Subject: **{student.best_subject()}**") st.write(f"⚠ Weak Subject: **{student.weak_subject()}**") st.info(student.suggest_improvement()) # ---------------- CONSISTENCY ---------------- marks_list = [s.marks for s in student.subjects] consistency_score = 1 / (1 + np.var(marks_list)) st.write(f"📊 Consistency Score: {round(consistency_score, 2)}") # ---------------- CHART ---------------- st.subheader("📉 Study vs Performance Trend") st.line_chart(df.set_index("Subject"))