A percentage should lead to an actionable answer
A coordinator needs more than attended/conducted values. The system must update every student consistently when a class occurs, identify students below 75%, calculate how many consecutive future classes they must attend, and tell eligible students how many future absences they can currently tolerate.
Roster
Maintain unique student IDs and names.
Class event
Increase conducted for everyone and attended for present IDs.
Advice
Convert percentages into recovery or safety counts.
Attendance is a coordinated state change
- Student ID is non-empty and unique.
- Name is non-empty.
0 ≤ attended ≤ conducted.- Recording one class increments
conductedfor every enrolled student exactly once. - Only known present IDs receive an attended increment.
- Unknown IDs reject the complete class update rather than creating partial data.
The last rule makes the operation atomic at the application level: either the full roster is updated consistently or no attendance count changes.
Computed properties keep derived state fresh
StudentAttendance(student_id, name, attended, conducted) percentage = attended × 100 / conducted status = Eligible when percentage ≥ 75
Percentage and status are properties, not stored columns. Storing them would create redundant values that could disagree after an update. The raw counts remain the source of truth.
The report sorts by percentage ascending and then ID, placing the students needing attention first while producing deterministic ties.
Solve inequalities, then round in the correct direction
Classes needed to recover
If a student attends every next class, find smallest integer x such that:
(attended + x)/(conducted + x) ≥ r x ≥ (r×conducted − attended)/(1−r)
Use ceiling because a fraction of a class cannot be attended and the requirement is a minimum.
Currently safe absences
Find largest whole x such that attended/(conducted+x) ≥ r. Rearrangement gives x ≤ attended/r − conducted; use floor. This is a snapshot, not permission to ignore later policy changes.
Write the whole coordinated update safely
A class changes many rows, so simple append is unsuitable. The program writes a complete temporary CSV and then replaces the original. This prevents a normal mid-write failure from leaving a half-written destination, though stronger durability still requires database transactions and filesystem-specific guarantees.
Runnable Python program
Loading source…Run locally for persistent CSV behavior. The program uses only Python’s standard library and validates stored counts before building objects.
Trace one class event
- Read and validate roster.
- Validate the complete set before mutation.
- Record that one class occurred.
- Apply presence.
- Preserve 0≤attended≤conducted.
- Create replacement data.
- Commit the class event.
- Generate shortage advice.
- Show priority order.
Press Next to begin.
Protect boundaries and coordinated updates
Threshold equality
Zero classes
Recovery formula
Unknown present ID
Duplicate roster ID
Damaged CSV row
Each class update scans the roster
| Operation | Time | Space |
|---|---|---|
| Load n students | O(n) | O(n) |
| Validate present set | O(n+p) | O(n+p) |
| Record class/save | O(n) | O(n) |
| Sorted report | O(n log n) | O(n) |
The model stores cumulative counts, not a date-wise audit trail. A production system needs session records, course/subject separation, authentication, correction history and role-based approval.
Check the formulas
Why does recovery use ceiling?
Why not store percentage in CSV?
Extensions
- Add subject-wise sessions and date-wise history.
- Support authorized corrections with an audit log.
- Generate weekly shortage alerts without exposing records publicly.
- Import a roster and detect duplicate IDs.
- Move coordinated writes to SQLite transactions.
Explain derived data and atomicity
Why use properties?
Percentage and status always reflect current counts and cannot become stale stored fields.
Why validate all IDs first?
Discovering an unknown ID after partial mutation would leave students updated inconsistently.
Why temporary-file replacement?
A multi-row update should not overwrite the original until a complete replacement has been written.
What does this model not audit?
It lacks individual session dates and presence history, so it cannot prove which specific classes were attended.
An analyzer should explain the next action
Python properties, sets, CSV, exceptions and file replacement support the system, while inequality solving turns a raw percentage into useful recovery guidance. Correctness depends on updating the whole roster as one event.
