Spaces:
Sleeping
Sleeping
| 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(""" | |
| <style> | |
| /* Background */ | |
| .stApp { | |
| background: linear-gradient(to right, #e0f7fa, #e1bee7); | |
| } | |
| /* Headings */ | |
| h1, h2, h3 { | |
| color: #4b0082; | |
| text-align: center; | |
| } | |
| /* Buttons */ | |
| .stButton>button { | |
| background-color: #6c63ff; | |
| color: white; | |
| border-radius: 10px; | |
| height: 3em; | |
| width: 100%; | |
| font-size: 16px; | |
| font-weight: bold; | |
| } | |
| /* Dataframe */ | |
| .css-1d391kg { | |
| border-radius: 10px; | |
| } | |
| /* Input boxes */ | |
| input { | |
| border-radius: 8px !important; | |
| } | |
| </style> | |
| """, 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")) | |