Spaces:
Sleeping
Sleeping
| import streamlit as st | |
| import pandas as pd | |
| from datetime import date, datetime | |
| import io | |
| # ------------------ Streamlit app ------------------ | |
| st.title("Attendance Management System") | |
| st.write("Upload an Excel file, mark attendance, and save updates directly.") | |
| # File uploader | |
| uploaded_file = st.file_uploader("Upload an Excel file:", type=["xlsx"]) | |
| if uploaded_file: | |
| # Ensure Roll Number column is read as string | |
| df = pd.read_excel(uploaded_file, dtype={"Roll Number": str}) | |
| st.write("**Uploaded Attendance Data:**") | |
| st.dataframe(df) | |
| if 'Roll Number' not in df.columns: | |
| st.error("The uploaded file must contain a 'Roll Number' column.") | |
| else: | |
| # Clean roll numbers (remove spaces, keep as string) | |
| df['Roll Number'] = df['Roll Number'].astype(str).str.strip() | |
| attendance_date = st.date_input("Select Attendance Date:", value=date.today()) | |
| attendance_date_str = attendance_date.strftime('%Y-%m-%d') | |
| if attendance_date_str not in df.columns: | |
| df[attendance_date_str] = 'A' # Default to 'A' (Absent) | |
| # Holiday or No Class option | |
| holiday = st.checkbox("Mark this date as a Holiday/No Class") | |
| if holiday: | |
| df[attendance_date_str] = 'H' # Mark as 'H' (Holiday) | |
| # Mark Attendance section | |
| st.write("### Mark Attendance:") | |
| roll_numbers = st.text_input( | |
| f"Enter roll numbers for {attendance_date_str} (comma-separated):" | |
| ) | |
| if st.button("Apply Attendance"): | |
| if not holiday and roll_numbers.strip(): | |
| present_rolls = [roll.strip() for roll in roll_numbers.split(",") if roll.strip()] | |
| df[attendance_date_str] = df['Roll Number'].apply( | |
| lambda x: 'P' if x in present_rolls else ('H' if holiday else 'A') | |
| ) | |
| # Calculate total attendance and percentage | |
| attendance_columns = [ | |
| col for col in df.columns if col not in ['Student Names', 'Full Roll Numbers', 'Roll Number', 'Total Attendance', 'Attendance %'] | |
| ] | |
| if attendance_columns: | |
| df['Total Attendance'] = df[attendance_columns].apply(lambda row: row.tolist().count('P'), axis=1) | |
| df['Attendance %'] = (df['Total Attendance'] / len(attendance_columns)) * 100 | |
| # Add/update summary row | |
| if 'Total' in df['Roll Number'].astype(str).values: | |
| summary_index = df[df['Roll Number'].astype(str) == 'Total'].index[0] | |
| for col in attendance_columns: | |
| df.at[summary_index, col] = df[col].tolist().count('P') | |
| else: | |
| total_row = {col: df[col].tolist().count('P') if col in attendance_columns else '' for col in df.columns} | |
| total_row['Roll Number'] = 'Total' | |
| df = pd.concat([df, pd.DataFrame([total_row])], ignore_index=True) | |
| # Reorder columns | |
| cols = [col for col in df.columns if col not in ['Total Attendance', 'Attendance %']] | |
| cols += ['Total Attendance', 'Attendance %'] | |
| df = df[cols] | |
| # Save updated file to memory buffer | |
| output = io.BytesIO() | |
| with pd.ExcelWriter(output, engine='xlsxwriter') as writer: | |
| df.to_excel(writer, index=False, sheet_name="Attendance") | |
| output.seek(0) | |
| st.write("**Updated Attendance Data:**") | |
| st.dataframe(df) | |
| # Download button for updated file | |
| current_date_str = datetime.now().strftime('%Y-%m-%d') | |
| download_file_name = f"{current_date_str}.xlsx" | |
| st.download_button( | |
| label="Download Updated File", | |
| data=output, | |
| file_name=download_file_name, | |
| mime="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" | |
| ) | |
| else: | |
| st.warning("Please enter at least one roll number or mark as a holiday.") | |
| else: | |
| st.info("Please upload an Excel file to proceed.") | |
| st.markdown("---") | |
| st.markdown( | |
| "<p style='text-align: center; font-size: 14px;'>Designed by: " | |
| "<b>Engr. Makhdoom Muhammad Naeem Hashmi</b></p>", | |
| unsafe_allow_html=True | |
| ) | |