LambdaLabTM
Computer Science · Class 12 Project · Subject Code 083
Sample ProjectPython File Handling⏱️ 12 min read

Attendance Register for a Coaching Class

Mark daily attendance and get each student's monthly percentage with the shortfalls flagged.

1Introduction: the problem it solves

A small coaching class with forty students keeps attendance in a register. At the end of the month somebody has to count the P's in every row by hand to find who is below 75%, and by then it is too late to do anything about it.

The counting is mechanical, so the computer should do it — and it should do it any day of the month, not only at the end.

who would use it

A coaching centre, a school club, a sports coach, or any teacher who tracks daily attendance.

Why it is worth computerising

Marking attendance on paper is quick. Working out from that paper who has fallen below seventy-five per cent is not, and it is only done at the end of the month because of how long it takes. By then the student has already missed the classes, and nothing can be done about it.

The value of computerising this is not the marking, which was never the problem. It is that the percentage can be calculated on any day of the month, in a second, for the whole class. A shortage found on the tenth can still be fixed; the same shortage found on the thirtieth can only be recorded.

Objectives

  1. To record attendance for a whole class in one action rather than one entry at a time
  2. To store the register in a file that can never lose a day already written
  3. To count classes held and attended for every student without counting by hand
  4. To calculate the attendance percentage and flag anyone below the 75% requirement
  5. To make that report available on any day, not only at the end of the month

2How the job is done today

Before writing anything it is worth asking how the work is handled at present, and why each of those answers falls short. These were examined:

Paper attendance register

Universal, and the reason this project exists. Marking is quick; the counting at month end is not, and a shortage is discovered too late to be fixed.

School ERP attendance modules

Excellent where a school has one. They are priced per student per year, which puts them out of reach of a small coaching class.

Spreadsheet with one column per day

Works for a month. The sheet grows sideways until it is unreadable, and adding a student mid-term means editing every row.

3Functionalities

  • Marks a whole day's attendance in one call, writing P or A for every student on the roll
  • Appends to the file rather than rewriting it, so no earlier day can be lost
  • Counts classes held and classes attended for every student
  • Works out the percentage and flags anyone below 75%
  • Runs on any day, so a warning can be given while it still helps

The functions that provide them

FunctionArgumentsWhat it does
mark()roll_list, day, present_rollsAppend one day's attendance: P for present, A for absent.
report()Work out each student's attendance percentage.

4Technical details

LanguagePython 3
StoragePlain text and CSV files
Modules used
  • csv — attendance is naturally rows of (date, roll, status)
  • Text file handling in append mode — the register only ever grows

5How the data is stored

One file, `attendance.csv`, holding one row per student per day: the date, the roll number, and P or A. Append mode is the whole design — a register you can only add to cannot lose yesterday.

attendance.csv — one row per student per day

FieldTypeDescription
datetextThe day, written as DD-MM
rolltextRoll number of the student
statustextP if present, A if absent

What the report works out

FieldTypeDescription
heldintegerHow many days that roll number appears — classes held
presentintegerHow many of those rows say P
percentdecimalpresent / held x 100, flagged when below 75

6How it works, step by step

1
Mark

mark() takes the roll list and the list of who turned up, and writes P or A for every student on the roll.

2
Append

The file is opened in 'a' mode, so each day is added below the last one.

3
Count

report() reads the whole file once, counting classes held and classes attended per roll number.

4
Flag

Anything under 75% is printed with a marker, which is the number a student is actually judged on.

7Source code

attendance.py
# ---------------------------------------------------------------------------
# attendance.py
#
# A month's attendance register for a small coaching class. Attendance is
# marked a day at a time and written to a CSV file; the report reads that file
# back and works out each student's percentage.
#
# The file is only ever APPENDED to. That is the central decision of this
# program: a register you can only add to is a register that cannot silently
# lose a day that was already marked.
# ---------------------------------------------------------------------------

import csv

FILE = "attendance.csv"        # one row per student per day


def mark(roll_list, day, present_rolls):
    """Append one day's attendance: P for present, A for absent."""
    # "a" is append mode. Opening with "w" here would wipe every earlier day,
    # which is exactly the accident this program is written to prevent.
    with open(FILE, "a", newline="") as f:
        writer = csv.writer(f)

        # Walk the whole roll, not just the students who turned up — an absence
        # has to be recorded as firmly as a presence, or it cannot be counted.
        for roll in roll_list:
            status = "P" if roll in present_rolls else "A"
            writer.writerow([day, roll, status])


def report():
    """Work out each student's attendance percentage."""
    days = {}                  # roll -> how many classes were held for them
    present = {}               # roll -> how many of those they attended

    with open(FILE, "r", newline="") as f:
        # Each row was written as three values, so it can be unpacked into three
        # names in one step.
        for day, roll, status in csv.reader(f):
            # Every row means a class was held, whoever attended it.
            days[roll] = days.get(roll, 0) + 1

            if status == "P":
                present[roll] = present.get(roll, 0) + 1

    print("LAMBDALAB COACHING CLASSES — ATTENDANCE, AUGUST")
    print("{:<8}{:>8}{:>10}{:>10}".format("ROLL", "HELD", "PRESENT", "PERCENT"))

    # sorted() so the roll numbers come out in order rather than in the order
    # the dictionary happens to hold them.
    for roll in sorted(days):
        held = days[roll]
        came = present.get(roll, 0)        # .get() because a student who was
                                           # never present has no entry at all
        percent = came / held * 100

        # 75% is the figure a student is actually judged on, so it is marked
        # rather than left for the reader to work out.
        flag = "  <-- short" if percent < 75 else ""

        print("{:<8}{:>8}{:>10}{:>9.1f}%{}".format(roll, held, came, percent, flag))


# --- the program itself ----------------------------------------------------

rolls = ["A01", "A02", "A03", "A04"]       # the class list

open(FILE, "w").close()                    # start a fresh register for the demo;
                                           # a real term would keep the old file

# Four days of attendance. In use, each of these lines would be run on its own
# day, with the list of who actually attended.
mark(rolls, "01-08", ["A01", "A02", "A03"])
mark(rolls, "02-08", ["A01", "A03", "A04"])
mark(rolls, "03-08", ["A01", "A02", "A03", "A04"])
mark(rolls, "04-08", ["A01", "A03"])

report()
⬇️ Take it with you

The full report as a PDF — cover page, certificate, index, code, output, future scope and references, ready to print and fill in. Or the code on its own as a zip.

or one file:

8Sample output

This is a real run, not a mock-up — the transcript below is what the program actually printed.

Command Prompt
C:\LambdaLab\Projects\Attendance> python attendance.py
LAMBDALAB COACHING CLASSES — ATTENDANCE, AUGUST
ROLL        HELD   PRESENT   PERCENT
A01            4         4    100.0%
A02            4         2     50.0%  <-- short
A03            4         4    100.0%
A04            4         2     50.0%  <-- short

Running it also wrote attendance.csv. This is what that file held afterwards:

attendance.csv
01-08,A01,P
01-08,A02,P
01-08,A03,P
01-08,A04,A
02-08,A01,P
02-08,A02,A
02-08,A03,P
02-08,A04,P
03-08,A01,P
03-08,A02,P
03-08,A03,P
03-08,A04,P
04-08,A01,P
04-08,A02,A
04-08,A03,P
04-08,A04,A

9Testing

Every case below was actually run and the result recorded as it appeared — including the ones expected to fail.

Test caseExpectedActual
Four days marked for four studentsA02 at 50%, flagged as shortA02 4 2 50.0% <-- short
A student on exactly 75%75.0% and NOT flagged - the boundaryA04 4 3 75.0%
A day on which nobody attendedThe day still counts as held for allA01 4 3 75.0%
A class of one studentOne row, 100%A01 4 4 100.0%

Two kinds of case are in there on purpose. The boundary cases test the edge of a rule, where a program is most often wrong by one. The failure cases check that it refuses cleanly and says why, instead of quietly producing a wrong answer.

10Advantages

Set against the ways the job is done today:

  • A shortage is visible while there is still time to fix it
  • No day can be lost, because the file is only ever added to
  • The percentage is calculated the same way for every student
  • One command produces a report for the whole class
  • The file opens in any spreadsheet if it has to be checked by hand

11Future scope

What this version does not do

A report should be honest about its own limits, and each of these is the reason for one of the additions below:

  • The roll list lives in the program, so a student joining mid-term needs a code change
  • Attendance is a whole-day mark; separate periods are not recorded
  • There is no correction facility — a wrong entry must be fixed in the file by hand
  • Nothing is sent to a parent; the shortfall is only shown on screen

Proposed enhancements

This is also where you make the project yours. Pick one or two of these, or something nobody here thought of:

  • Send an SMS or email to a parent as soon as a student drops below 75%
  • A monthly chart of attendance with matplotlib
  • Mark attendance from a phone by scanning a QR code on each student's card
  • Separate the roll list into its own file so students can join mid-term
  • Warn about a student absent three days running

12What you may have to teach yourself

CBSE expects some self-learning in a project, and says so. For this one, that means:

  • dict.get(key, 0), which is what makes the counting loop short
  • Why append mode matters here, and what 'w' would have destroyed
  • Optional: matplotlib, for the attendance chart

13Conclusion

The register now answers, on any day of the month, the one question it was always being asked at the end of it. Marking takes no longer than it did on paper; the counting takes no time at all.

The choice of append mode turned out to matter more than anything clever in the program. A register that can only be added to is a register that cannot quietly lose a day.

14References

Every report needs a bibliography. This one used:

  • Computer Science with Python, Class XII — the NCERT / CBSE prescribed textbook, for the chapters on file handling and working with text and CSV files
  • Computer Science with Python, Class XI — for functions, lists, dictionaries and string handling
  • Python 3 documentation — https://docs.python.org/3/
  • CBSE Senior School Curriculum, Computer Science (Subject Code 083) — the project guidelines this report follows
  • LambdaLab — https://www.lambdalab.in
Key Takeaway
The PDF above is the whole report. Cover page, certificate, acknowledgement, index, everything on this page, and the references — in the order CBSE marks them, ready to print. The cover page, certificate and acknowledgement arrive with blank rules where names go, because a certificate with somebody else's name printed on it is not a template. Fill those in, get the certificate signed, and replace the problem with one you have looked into yourself.