import streamlit as st import pandas as pd import plotly.express as px from io import BytesIO import base64 import os import os os.environ["STREAMLIT_RUNTIME_DIR"] = "/tmp" os.environ["STREAMLIT_CACHE_DIR"] = "/tmp" # PAGE CONFIGURATION st.set_page_config(page_title="Telangana Minorities Residential Educational Institutions Society", layout="wide") # Custom CSS for UI st.markdown(""" """, unsafe_allow_html=True) # DATA UPLOAD st.title("Telangana Minorities Residential Educational Institutions Society Analysis Dashboard") uploaded_file = st.file_uploader("Upload your dataset (Excel or CSV)", type=["xlsx", "csv"]) if uploaded_file: # ✅ Save uploaded file to /tmp to avoid permission error save_path = os.path.join("/tmp", uploaded_file.name) with open(save_path, "wb") as f: f.write(uploaded_file.getbuffer()) # Read dataset if save_path.endswith(".xlsx"): df = pd.read_excel(save_path) else: df = pd.read_csv(save_path) st.success("Dataset uploaded successfully!") # Standardize column names df.columns = df.columns.str.strip().str.lower().str.replace(" ", "_") df.fillna(0, inplace=True) # DYNAMIC COLUMN DETECTION def find_column(keyword): for col in df.columns: if keyword in col: return col return None columns = { "v_minority": { "sanctioned": find_column("vth_class_minority_sanction"), "admitted": find_column("vth_class_minority_admitted"), "vacancy": find_column("vth_class_minority_vacancies"), "attendance": find_column("total_school_attendance"), }, "v_non_minority": { "sanctioned": find_column("vth_class_non_minority_sanction"), "admitted": find_column("vth_class_non_minority_admitted"), "vacancy": find_column("vth_class_non_minority_vacancies"), "attendance": find_column("total_school_attendance"), }, "inter_minority": { "sanctioned": find_column("1st_year_minority_sanction"), "admitted": find_column("1st_year_minority_admitted"), "vacancy": find_column("1st_year_minority_vacancies"), "attendance": find_column("total_intermediate_attendance"), }, "inter_non_minority": { "sanctioned": find_column("1st_year_non_minority_sanction"), "admitted": find_column("1st_year_non_minority_admitted"), "vacancy": find_column("1st_year_non_minority_vacancies"), "attendance": find_column("total_intermediate_attendance"), }, "absentees": find_column("total_absentees"), } # FILTERS st.sidebar.header("Filters") level_filter = st.sidebar.radio("Select Level", ["V (School)", "Inter 1st Year"]) category_filter = st.sidebar.radio("Select Category", ["Minority", "Non-Minority"]) districts = st.sidebar.multiselect("Select District(s)", options=df["district"].unique(), default=df["district"].unique()) search_college = st.sidebar.text_input("Search College Name (Optional)") df = df[df["district"].isin(districts)] if search_college: df = df[df["college_name"].str.contains(search_college, case=False, na=False)] # Map columns dynamically if level_filter == "V (School)": key = "v_minority" if category_filter == "Minority" else "v_non_minority" else: key = "inter_minority" if category_filter == "Minority" else "inter_non_minority" sanctioned_col = columns[key]["sanctioned"] admitted_col = columns[key]["admitted"] vacant_col = columns[key]["vacancy"] attendance_col = columns[key]["attendance"] absentees_col = columns["absentees"] # KPI CALCULATIONS total_sanctioned = df[sanctioned_col].sum() total_admitted = df[admitted_col].sum() total_vacant = df[vacant_col].sum() total_attendance = df[attendance_col].sum() total_absentees = df[absentees_col].sum() attendance_pct = round((total_attendance / (total_attendance + total_absentees)) * 100, 2) if (total_attendance + total_absentees) > 0 else 0 # KPI DISPLAY col1, col2, col3, col4, col5, col6 = st.columns(6) col1.markdown(f"