syeda-Rija20's picture
Update app.py
3df8bf8 verified
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"))