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

Electricity Bills for a Housing Society

Slab-wise bills for every flat from a month's meter readings.

1Introduction: the problem it solves

A housing society secretary collects meter readings for forty flats and works out each bill on a calculator. Tariffs are slab-based — the first hundred units cost less than the next hundred — so every bill is four separate multiplications, and one slip means a resident is overcharged.

This is arithmetic with a rule book, which is the kind of job a program never gets wrong twice.

who would use it

A housing society, a paying-guest owner billing tenants, or a shop billing sub-meters.

Why it is worth computerising

A slab tariff is designed to be fair, and the cost of that fairness is arithmetic. Each bill is four separate multiplications and an addition, and a society secretary does that forty times over with a calculator every month. One slip is not caught by anybody except the resident who was overcharged.

The rules never change between one flat and the next, which is exactly the condition under which a computer should be doing the work. Putting the tariff in one place has a second benefit: when the board revises a rate, one line is edited and every subsequent bill is correct, instead of forty calculations being re-learnt.

Objectives

  1. To read a month's meter readings for every flat from one file
  2. To work out the units used from the previous and current readings
  3. To charge each slab at its own rate, the way a real tariff does
  4. To add the fixed monthly charge and produce a printable bill for every flat
  5. To hold the tariff in one place, so a revision by the board is a one-line edit

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:

Secretary with a calculator

What most societies do. Slab arithmetic done forty times over is where the errors come from, and a resident overcharged once stops trusting the whole exercise.

Society management software

Comprehensive, subscription-priced, and built around accounting rather than meters. Small societies rarely buy it for this one job.

Spreadsheet with nested IF formulas

Common and fragile. The slab formula is hard to read, harder to check, and quietly wrong when the board changes a rate.

3Functionalities

  • Reads previous and current readings for every flat from a CSV file
  • Charges each slab at its own rate, the way a real tariff works
  • Adds the fixed monthly charge
  • Writes all the bills into one printable file
  • Keeps the tariff in one list at the top, so a rate change is a one-line edit

The functions that provide them

FunctionArgumentsWhat it does
units_cost()unitsCharge each slab at its own rate, the way a real tariff works.
make_bills()reading_file, bill_fileRead every flat's readings and write out a bill for each.

4Technical details

LanguagePython 3
StoragePlain text and CSV files
Modules used
  • csv — the readings are naturally a table
  • Text file handling — the bills are written out for printing

5How the data is stored

`readings.csv` holds the flat, the resident's name, and the previous and current meter readings. `bills.txt` is the output. The tariff lives in the SLABS list, so when the board revises rates you edit one line rather than hunting through the code.

readings.csv — the input

FieldTypeDescription
flattextFlat number, as it appears on the door
nametextResident's name, printed on the bill
previousintegerMeter reading at the start of the month
currentintegerMeter reading at the end of the month

SLABS — the tariff held in the program

FieldTypeDescription
limitintegerUpper edge of the slab in units; None for the last one
ratedecimalRupees per unit charged inside that slab
FIXEDdecimalFixed monthly charge added to every bill

Sample contents of readings.csv

flatnamepreviouscurrent
A-101R Sharma45204608
A-102S Iyer33103585
B-201M Khan77888190
B-202D Rao12001850

6How it works, step by step

1
Read

Each row gives previous and current readings; units used is the difference.

2
Slab

units_cost() walks the slabs in order, charging each block at its own rate until the units run out.

3
Add

The fixed monthly charge is added to the slab cost.

4
Write

Every flat's line is written to bills.txt in aligned columns.

7Source code

electricity.py
# ---------------------------------------------------------------------------
# electricity.py
#
# Slab-wise electricity bills for a housing society. Meter readings for every
# flat are read from a CSV file; a bill for each is written to a text file.
#
# A slab tariff does not charge every unit at the same rate: the first hundred
# units cost less than the next hundred, and so on. Getting that right is the
# whole of this program.
# ---------------------------------------------------------------------------

import csv

# The tariff, as (upper edge of the slab, rate per unit inside it).
# None means "everything above the previous edge", so the last entry has no
# upper limit. Keeping the tariff here means a revision by the board is one
# line to edit.
SLABS = [(100, 3.50), (200, 4.75), (400, 6.20), (None, 7.90)]

FIXED = 75.0                   # fixed monthly charge, added to every bill


def units_cost(units):
    """Charge each slab at its own rate, the way a real tariff works."""
    cost = 0                   # money charged so far
    used = 0                   # units accounted for so far

    for limit, rate in SLABS:
        if limit is None:
            # The last slab has no upper edge, so everything left falls in it.
            block = units - used
        else:
            # Otherwise take whichever is smaller: what is left to charge, or
            # what fits inside this slab. Without the min() a big reading would
            # be charged for more units than were actually used.
            block = min(units - used, limit - used)

        if block <= 0:
            break              # nothing falls in this slab, so nothing above it

        cost = cost + block * rate
        used = used + block

        if used >= units:
            break              # everything has been charged

    return cost


def make_bills(reading_file, bill_file):
    """Read every flat's readings and write out a bill for each."""
    # Both files are opened at once: one to read from, one to write to.
    with open(reading_file, newline="") as f, open(bill_file, "w") as out:
        out.write("LAMBDALAB RESIDENCY — ELECTRICITY BILLS\n\n")
        out.write("{:<8}{:<16}{:>8}{:>12}\n".format("FLAT", "NAME", "UNITS", "AMOUNT"))

        for row in csv.DictReader(f):
            # Units used is the difference between the two readings. int() is
            # needed because everything read from a file arrives as text.
            units = int(row["current"]) - int(row["previous"])

            amount = units_cost(units) + FIXED

            out.write("{:<8}{:<16}{:>8}{:>12.2f}\n".format(
                row["flat"], row["name"], units, amount))


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

make_bills("readings.csv", "bills.txt")

print(open("bills.txt").read())        # show the bills on screen as well
readings.csv
flat,name,previous,current
A-101,R Sharma,4520,4608
A-102,S Iyer,3310,3585
B-201,M Khan,7788,8190
B-202,D Rao,1200,1850
⬇️ 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\Electricity> python electricity.py
LAMBDALAB RESIDENCY — ELECTRICITY BILLS

FLAT    NAME               UNITS      AMOUNT
A-101   R Sharma              88      383.00
A-102   S Iyer               275     1365.00
B-201   M Khan               402     2155.80
B-202   D Rao                650     4115.00

Running it also wrote bills.txt. This is what that file held afterwards:

bills.txt
LAMBDALAB RESIDENCY — ELECTRICITY BILLS

FLAT    NAME               UNITS      AMOUNT
A-101   R Sharma              88      383.00
A-102   S Iyer               275     1365.00
B-201   M Khan               402     2155.80
B-202   D Rao                650     4115.00

9Testing

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

Test caseExpectedActual
Four flats across all four slabs650 units billed at Rs 4115.00B-202 D Rao 650 4115.00
A flat that used nothingOnly the fixed charge, Rs 75.00A-1 Test 0 75.00
Exactly 100 units, the first slab edge100 x 3.50 + 75 = Rs 425.00A-1 Test 100 425.00
101 units, one unit into the second slab425.00 + 4.75 = Rs 429.75A-1 Test 101 429.75
readings.csv missingFileNotFoundErrorFileNotFoundError: [Errno 2] No such file or directory: 'readings.csv'

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:

  • Every bill uses the same slab arithmetic, so none is wrong by accident
  • A tariff revision is one edit rather than forty re-learnt calculations
  • Readings are typed once and used for the whole society
  • The bills are produced in a printable form, ready to distribute
  • A resident's charge can be checked against the reading in seconds

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:

  • Arrears and previous balances are not carried forward
  • A meter that has been replaced and restarted at zero would give a negative reading
  • All flats are charged on the same tariff; commercial units are not separated
  • Bills are written into one file rather than one page per flat

Proposed enhancements

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

  • Carry forward arrears and show the previous balance on the bill
  • Print each bill on its own page ready to slip under a door
  • Chart a flat's usage over twelve months so a leak or a faulty meter shows up
  • Send the bill by email or WhatsApp instead of printing
  • Handle a meter that has been replaced and restarted at zero

12What you may have to teach yourself

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

  • How your own electricity board's slabs actually work — read a real bill
  • min() inside the slab loop, which is what stops a block over-counting
  • Optional: how to lay out a bill for printing on A5

13Conclusion

Forty bills that took an evening and a calculator are now produced from one file of readings, with every slab charged at its own rate and no possibility of a slip.

Keeping the tariff in a single list, rather than spread through the code, means the program will survive the next revision by the board. That is worth more than any feature in it.

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.