Skip to content

Instantly share code, notes, and snippets.

@sud007
Last active July 13, 2024 08:34
Show Gist options
  • Save sud007/1ff53bfb9e231d2a7d3219e86ac7bc72 to your computer and use it in GitHub Desktop.
Save sud007/1ff53bfb9e231d2a7d3219e86ac7bc72 to your computer and use it in GitHub Desktop.
Electricity Bill Calculation for rental floors
/**
* You can edit, run, and share this code.
* play.kotlinlang.org
*/
fun calculateTotalUnits(unitsOld: Double, unitsNew: Double): Double {
return (unitsNew - unitsOld).roundToTwoDecimalPlaces()
}
fun calculatePerUnitPrice(amountTotal: Double, unitsTotal: Double): Double {
return (amountTotal / unitsTotal).roundToTwoDecimalPlaces()
}
fun calculateCommonBill(unitsTotal: Double, sumAllFloorUnits: Double, perUnitPrice: Double): Double {
val commonUnits = unitsTotal - sumAllFloorUnits
println("Common Meter Units: ${commonUnits.roundToTwoDecimalPlaces()}")
return (commonUnits * perUnitPrice).roundToTwoDecimalPlaces()
}
fun calculateBillPerFloor(totalUnits: Double, commonBillPerFloor: Double, perUnitPrice: Double): Double {
return ((totalUnits * perUnitPrice) + commonBillPerFloor).roundToTwoDecimalPlaces()
}
fun calculateBillError(billSumAllFloors: Double, amountTotal: Double): Double {
return (billSumAllFloors - amountTotal).roundToTwoDecimalPlaces()
}
fun calculateFinalBill(floorBill: Double, billDiff: Double): Double {
return (floorBill + billDiff).roundToTwoDecimalPlaces()
}
fun Double.roundToTwoDecimalPlaces(): Double {
return String.format("%.2f", this).toDouble()
}
val CURRENCY = "₹"
val FLOOR_NAME_1 = "Mr. Bhaskar"
val FLOOR_NAME_2 = "Mr. Pandey"
val FLOOR_NAME_3 = "Mr. Kandaswamy"
val FLOOR_NAME_4 = "Mrs. Singh"
fun main() {
// Input data
val year = "2024"
val cycleName = "Jun-Jul"
val unitsOld = 135725.7
val unitsNew = 138520.12
val amountTotal = 20146.0
val floor1UnitsOld = 33634.7
val floor1UnitsNew = 34192.9
val floor2UnitsOld = 264.0
val floor2UnitsNew = 697.4
val floor3UnitsOld = 50878.1
val floor3UnitsNew = 51824.5
val floor4UnitsOld = 1191.2
val floor4UnitsNew = 1965.1
println("Electricity Bill calculation for Cycle : $cycleName, $year")
// Calculate total units
val unitsTotal = calculateTotalUnits(unitsOld, unitsNew)
println("New Units: $unitsNew")
println("Old Units: $unitsOld")
println("Total Bill Amount: $amountTotal")
println("Total Unit in Cycle: $unitsTotal")
// Calculate per unit price
val perUnitPrice = calculatePerUnitPrice(amountTotal, unitsTotal)
println("Per UnitPrice: ₹$perUnitPrice")
println()
println("NOTE : Total bill in PDF is different than final Amount displayed by Biller (Amazon, Paytm, PhonePe).")
println()
// Calculate total units for each floor
val totalUnitsFloor1 = calculateTotalUnits(floor1UnitsOld, floor1UnitsNew)
val totalUnitsFloor2 = calculateTotalUnits(floor2UnitsOld, floor2UnitsNew)
val totalUnitsFloor3 = calculateTotalUnits(floor3UnitsOld, floor3UnitsNew)
val totalUnitsFloor4 = calculateTotalUnits(floor4UnitsOld, floor4UnitsNew)
println("Floor 1 Units: $totalUnitsFloor1")
println("Floor 2 Units: $totalUnitsFloor2")
println("Floor 3 Units: $totalUnitsFloor3")
println("Floor 4 Units: $totalUnitsFloor4")
println()
// Calculate sum of all floor units
val sumAllFloorUnits = totalUnitsFloor1 + totalUnitsFloor2 + totalUnitsFloor3 + totalUnitsFloor4
println("All floor Units: $sumAllFloorUnits")
println()
// Calculate common bill
val commonBill = calculateCommonBill(unitsTotal, sumAllFloorUnits, perUnitPrice)
val commonBillPerFloor = (commonBill / 4).roundToTwoDecimalPlaces()
println("Common Bill For Each Floor: $CURRENCY $commonBillPerFloor")
println()
// Calculate bill for each floor
val floor1Bill = calculateBillPerFloor(totalUnitsFloor1, commonBillPerFloor, perUnitPrice)
val floor2Bill = calculateBillPerFloor(totalUnitsFloor2, commonBillPerFloor, perUnitPrice)
val floor3Bill = calculateBillPerFloor(totalUnitsFloor3, commonBillPerFloor, perUnitPrice)
val floor4Bill = calculateBillPerFloor(totalUnitsFloor4, commonBillPerFloor, perUnitPrice)
println("Floor 1 Bill with Common Units: $CURRENCY $floor1Bill")
println("Floor 2 Bill with Common Units: $CURRENCY $floor2Bill")
println("Floor 3 Bill with Common Units: $CURRENCY $floor3Bill")
println("Floor 4 Bill with Common Units: $CURRENCY $floor4Bill")
println()
// Calculate total bill for all floors
val billSumAllFloors = floor1Bill + floor2Bill + floor3Bill + floor4Bill
println("All Floor Sum: $CURRENCY $billSumAllFloors")
println()
// Calculate bill Error
val billError = calculateBillError(billSumAllFloors, amountTotal)
val billErrorPerFloor = (billError/4).roundToTwoDecimalPlaces()
println("All Floor Sum Error: $CURRENCY $billError")
println("Per floor adjustment of Error: $CURRENCY $billErrorPerFloor")
println()
// Calculate final bill for each floor
val floor1BillFinal = calculateFinalBill(floor1Bill, billErrorPerFloor)
val floor2BillFinal = calculateFinalBill(floor2Bill, billErrorPerFloor)
val floor3BillFinal = calculateFinalBill(floor3Bill, billErrorPerFloor)
val floor4BillFinal = calculateFinalBill(floor4Bill, billErrorPerFloor)
// Print final bills for each floor
println("$FLOOR_NAME_1 Final Bill: $CURRENCY $floor1BillFinal")
println("$FLOOR_NAME_2 Final Bill: $CURRENCY $floor2BillFinal")
println("$FLOOR_NAME_3 Final Bill: $CURRENCY $floor3BillFinal")
println("$FLOOR_NAME_4 Final Bill: $CURRENCY $floor4BillFinal")
}
@sud007
Copy link
Author

sud007 commented Jul 13, 2024

Summary

This small gist is tested and is working to calculate the Electricity bills of row houses with more than 1 floor and tenants. It has a very specific usecase and considerations. I will add those here

  1. A meter for the Rowhouse.
  2. Bill is provided for current cycle of units for main meter.
  3. All floors have a submeter to calculate their consumption.
  4. Common units denote the residual units which are shared among each floor and are calculated by Main meter.

What each function does.

  1. calculateTotalUnits : Total bill units payble for current cycle
  2. calculatePerUnitPrice : Amount of each unit this cycle
  3. calculateCommonBill Total Common bill paybale by each floor
  4. calculateBillPerFloor : Bill payable by each floor.
  5. calculateBillError : Calculates the error in Amounts of all floor and total house bill amount
  6. calculateFinalBill : Final per floor bill with error correction.
  7. roundToTwoDecimalPlaces : Extension helper function to add rounding in all places.

Error Calculations

Errors have been carefully checked twice in this calculation process

  1. When you calculate the total units : commonBillPerFloor makes sure that unit diff is correctly calculated from Total House bill.
  2. When final bill is calculated, billErrorPerFloor is used to further do a correction for each floor by calculating error in amount calculation introduced by rounding to 2 decimals

Where to test this

play.kotlinlang.org

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment