makhdoomnaeem's picture
Update app.py
2c8f5aa verified
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
)