Functory
functory.
4 min read
Functory

Compute attendance rate from LMS student progress CSVs in Python and publish a sharable URL with Functory

This article explains how to compute an accreditation-ready attendance rate from LMS student progress CSVs (enrollments, progress percent, last_activity) and expose the result as a shareable URL using Functory. It's targeted at founders and small teams that need automated, repeatable reporting without running servers or building a dashboard.

Precise function description

Input: student_progress.csv (columns: student_email, course_code, term, enroll_date, progress_pct, last_activity (ISO8601), status). Processing: filter enrolled students (status==active), determine presence as last_activity within term date range or progress_pct >= 5%, and then compute attendance rate per course. Output: CSV attendance_summary.csv and JSON metrics for API consumers.

Concrete input schema

  • student_progress.csv example row: alice@example.com,CS201,2024-Spring,2024-01-10T00:00:00Z,12.5,2024-02-12T09:21:00Z,active
  • course_dates.json (optional): maps course_code to term start and end dates; used to interpret last_activity windows (e.g., CS201: {start:'2024-01-08', end:'2024-05-12'}).

Output example

attendance_summary.csv (example):

course_code,term,enrolled_count,present_count,attendance_rate_pct
CS201,2024-Spring,95,81,85.26
MATH101,2024-Spring,120,102,85.00

attendance_details.json contains per-student last_activity and a boolean present flag for downstream auditing.

Real-world scenario

Startup example: A product team with 4 instructors needs weekly attendance updates shared with a non-technical COO. Data: student_progress.csv with 5,000 rows (covering 20 courses). Specific problem: accuracy—progress_pct is noisy (system records 0.1% for auto-saves). The function treats a student as present if progress_pct >= 5% OR last_activity inside term range to reduce false negatives.

Example dataset and problem

Dataset: 5,000 rows, columns listed above. Problem solved: automatic weekly generation of attendance_summary.csv, which is then published via Functory as an endpoint the COO can bookmark. The function handles timezone normalization, ignores audit-only auto-saves (filter progress_pct < 1%), and enforces term window checks to avoid counting pre-enrollment activity.

Workflow (end-to-end)

  1. Export student_progress.csv from LMS weekly or point the function at an S3 URL.
  2. Call the Functory function via the web UI or HTTP API; upload CSV or pass a URL string to the file parameter.
  3. Function returns attendance_summary.csv path; Functory exposes a downloadable link that can be shared with the team.
  4. Optional: chain with a Functory function that emails the CSV to stakeholders on completion.

Algorithm summary

  1. Load student_progress.csv; parse last_activity as UTC datetime.
  2. Filter to status==active and progress_pct >= 1% (noise filter).
  3. Define present if (progress_pct >= 5%) OR (last_activity between term_start and term_end).
  4. Aggregate present by course_code and term; compute attendance_rate_pct.

Python snippet

import pandas as pd
from pathlib import Path

def main(progress_csv: str, course_dates_json: str | None = None, out_dir: str = '.') -> str:
    df = pd.read_csv(progress_csv, parse_dates=['enroll_date','last_activity'])
    df['student_email'] = df['student_email'].str.lower().str.strip()
    # noise filter
    df = df[df['status'].eq('active') & (df['progress_pct'].fillna(0) >= 1.0)]
    # optional course dates
    if course_dates_json:
        import json
        cd = json.loads(Path(course_dates_json).read_text())
    else:
        cd = {}
    def is_present(row):
        if row.get('progress_pct',0) >= 5.0:
            return True
        dates = cd.get(row['course_code'], None)
        if dates:
            return dates['start'] <= row['last_activity'].date().isoformat() <= dates['end']
        return not pd.isna(row['last_activity'])
    df['present'] = df.apply(is_present, axis=1)
    summary = df.groupby(['course_code','term']).agg(enrolled_count=('student_email','nunique'), present_count=('present','sum')).reset_index()
    summary['attendance_rate_pct'] = (summary['present_count']/summary['enrolled_count']*100).round(2)
    out = Path(out_dir); out.mkdir(exist_ok=True)
    summary.to_csv(out/'attendance_summary.csv', index=False)
    return str(out/'attendance_summary.csv')

Comparison to other approaches

Teams often solve this with: spreadsheets shared on Google Drive (manual), scheduled SQL queries in a data warehouse (requires infra and data syncing), or ad-hoc scripts in a notebook (hard to expose as a URL). Publishing this single-file function on Functory gives the advantages of a hosted API without managing servers—shareable URL, parameterized inputs, and a consistent runtime environment.

Business or productivity benefit

Concrete benefit: replacing a weekly manual export+email workflow with an automated Functory endpoint saves 2–3 staff-hours per week, or ~104–156 hours per year—a measurable productivity gain for a small team. It also reduces reporting latency from 2 days to immediate.

Industry stat: A 2023 EdTech adoption study found 58% of small training providers increased automation in reporting in the prior year (EdTech Insights, 2023).

How Functory Makes It Easy

Wrap the core logic in main(progress_csv: str, course_dates_json: str | None = None) and choose an exact Python version such as 3.11.11. In requirements.txt pin dependencies: pandas==2.2.3. Functory will surface progress_csv as an upload field or URL input and return a path to attendance_summary.csv which becomes a downloadable link. No CLI: Functory calls main directly. Benefits include autoscaling, built-in logs via print(), CPU/GPU tier choice for heavier analysis, and pay-per-use billing. Chain this function with other Functory functions (for emailing or pushing to Slack) to create a full reporting automation without managing servers.

Conclusion: This pattern turns weekly LMS progress exports into a shareable attendance report with minimal engineering. Next steps: add automated scheduling, integrate course date management, or add an audit CSV for regulators. Deploy on Functory and give your stakeholders a single URL to always fetch the latest metric.

Thanks for reading.