Skip to content

Instantly share code, notes, and snippets.

@sud007
Last active November 23, 2024 14:28
Show Gist options
  • Select an option

  • Save sud007/1ff53bfb9e231d2a7d3219e86ac7bc72 to your computer and use it in GitHub Desktop.

Select an option

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 (amountTotal - billSumAllFloors).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_G = "Mrs. Singh"
val isPaid = false
val lastDate = "26"
val prevMonth = "Oct"
val currentMonth = "Nov"
fun main() {
// Input data
val year = "2024"
val cycleName = "$prevMonth-$currentMonth"
val unitsOld = 145051.93
val unitsNew = 146194.80
val amountTotal = 11809.00
val floorGUnitsOld = 4132.9
val floorGUnitsNew = 4420.3
val floor1UnitsOld = 54019.5
val floor1UnitsNew = 54667.40
val floor2UnitsOld = 1738.1
val floor2UnitsNew = 1956.40
val floor3UnitsOld = 35064.6
val floor3UnitsNew = 35153.0
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 totalUnitsFloor3 = calculateTotalUnits(floor3UnitsOld, floor3UnitsNew)
val totalUnitsFloor2 = calculateTotalUnits(floor2UnitsOld, floor2UnitsNew)
val totalUnitsFloor1 = calculateTotalUnits(floor1UnitsOld, floor1UnitsNew)
val totalUnitsFloorG = calculateTotalUnits(floorGUnitsOld, floorGUnitsNew)
println("Floor 3 Units:\n$floor3UnitsNew-$floor3UnitsOld= $totalUnitsFloor3")
println("Floor 2 Units:\n$floor2UnitsNew-$floor2UnitsOld= $totalUnitsFloor2")
println("Floor 1 Units:\n$floor1UnitsNew-$floor1UnitsOld= $totalUnitsFloor1")
println("Floor G Units:\n$floorGUnitsNew-$floorGUnitsOld= $totalUnitsFloorG")
println()
// Calculate sum of all floor units
val sumAllFloorUnits = (totalUnitsFloor1 + totalUnitsFloor2 + totalUnitsFloor3 + totalUnitsFloorG).roundToTwoDecimalPlaces()
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 floor3Bill = calculateBillPerFloor(totalUnitsFloor3, commonBillPerFloor, perUnitPrice)
val floor2Bill = calculateBillPerFloor(totalUnitsFloor2, commonBillPerFloor, perUnitPrice)
val floor1Bill = calculateBillPerFloor(totalUnitsFloor1, commonBillPerFloor, perUnitPrice)
val floorGBill = calculateBillPerFloor(totalUnitsFloorG, commonBillPerFloor, perUnitPrice)
println("Floor 3 Bill with Common Units: $CURRENCY $floor3Bill")
println("Floor 2 Bill with Common Units: $CURRENCY $floor2Bill")
println("Floor 1 Bill with Common Units: $CURRENCY $floor1Bill")
println("Floor Ground Bill with Common Units: $CURRENCY $floorGBill")
println()
// Calculate total bill for all floors
val billSumAllFloors = floor1Bill + floor2Bill + floor3Bill + floorGBill
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 floorGBillFinal = calculateFinalBill(floorGBill, billErrorPerFloor)
// Print final bills for each floor
println("Final Bill to pay:")
println("$FLOOR_NAME_3 : $CURRENCY $floor3BillFinal")
println("$FLOOR_NAME_2 : $CURRENCY $floor2BillFinal")
println("$FLOOR_NAME_1 : $CURRENCY $floor1BillFinal")
println("$FLOOR_NAME_G : $CURRENCY $floorGBillFinal")
println()
if (isPaid) println("Bill has been paid already!") else println("Please pay your bill amount before *$lastDate $currentMonth*")
println("*Please pay to me*")
}
/**
* 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
Copy Markdown
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