Skip to content

Instantly share code, notes, and snippets.

@muhiminulhasan
Created December 20, 2024 15:03
Show Gist options
  • Select an option

  • Save muhiminulhasan/9a03503c5401570bedc466452aeb811b to your computer and use it in GitHub Desktop.

Select an option

Save muhiminulhasan/9a03503c5401570bedc466452aeb811b to your computer and use it in GitHub Desktop.
Tariff-Based Electricity Bill Calculator for West Zone Power Distribution Company.
import typer
from rich.console import Console
from rich.table import Table
from rich.panel import Panel
from rich.text import Text
import math # Added for ceiling function
# Initialize typer app and rich console
app = typer.Typer()
console = Console()
def calculate_bill(units_consumed: float) -> tuple:
"""
Calculate electricity bill based on units consumed with tariff breakdown
Args:
units_consumed (float): Number of units (kWh) consumed
Returns:
tuple: (total_bill, breakdown_dict)
"""
# Tariff rates in Taka
tariff_rates = {
"0-50": 4.63,
"0-75": 5.26,
"76-200": 7.20,
"201-300": 7.59,
"301-400": 8.02,
"401-600": 12.67,
"600+": 14.61
}
# Fixed demand charge in BDT
DEMAND_CHARGE = 126.00
# VAT rate (5%)
VAT_RATE = 0.05
breakdown = {}
total_bill = 0
# Calculate bill based on consumption slabs
if units_consumed <= 50:
amount = units_consumed * tariff_rates["0-50"]
breakdown["0-50"] = math.ceil(amount)
total_bill = breakdown["0-50"]
elif units_consumed <= 75:
amount = units_consumed * tariff_rates["0-75"]
breakdown["0-75"] = math.ceil(amount)
total_bill = breakdown["0-75"]
elif units_consumed <= 200:
breakdown["0-75"] = math.ceil(75 * tariff_rates["0-75"])
breakdown["76-200"] = math.ceil((units_consumed - 75) * tariff_rates["76-200"])
total_bill = sum(breakdown.values())
elif units_consumed <= 300:
breakdown["0-75"] = math.ceil(75 * tariff_rates["0-75"])
breakdown["76-200"] = math.ceil(125 * tariff_rates["76-200"])
breakdown["201-300"] = math.ceil((units_consumed - 200) * tariff_rates["201-300"])
total_bill = sum(breakdown.values())
elif units_consumed <= 400:
breakdown["0-75"] = math.ceil(75 * tariff_rates["0-75"])
breakdown["76-200"] = math.ceil(125 * tariff_rates["76-200"])
breakdown["201-300"] = math.ceil(100 * tariff_rates["201-300"])
breakdown["301-400"] = math.ceil((units_consumed - 300) * tariff_rates["301-400"])
total_bill = sum(breakdown.values())
elif units_consumed <= 600:
breakdown["0-75"] = math.ceil(75 * tariff_rates["0-75"])
breakdown["76-200"] = math.ceil(125 * tariff_rates["76-200"])
breakdown["201-300"] = math.ceil(100 * tariff_rates["201-300"])
breakdown["301-400"] = math.ceil(100 * tariff_rates["301-400"])
breakdown["401-600"] = math.ceil((units_consumed - 400) * tariff_rates["401-600"])
total_bill = sum(breakdown.values())
else: # More than 600 units
breakdown["0-75"] = math.ceil(75 * tariff_rates["0-75"])
breakdown["76-200"] = math.ceil(125 * tariff_rates["76-200"])
breakdown["201-300"] = math.ceil(100 * tariff_rates["201-300"])
breakdown["301-400"] = math.ceil(100 * tariff_rates["301-400"])
breakdown["401-600"] = math.ceil(200 * tariff_rates["401-600"])
breakdown["600+"] = math.ceil((units_consumed - 600) * tariff_rates["600+"])
total_bill = sum(breakdown.values())
# Add demand charge (rounded up)
breakdown["Demand Charge"] = math.ceil(DEMAND_CHARGE)
total_bill += breakdown["Demand Charge"]
# Calculate VAT (rounded up)
vat_amount = total_bill * VAT_RATE
breakdown["VAT (5%)"] = math.ceil(vat_amount)
total_bill += breakdown["VAT (5%)"]
return total_bill, breakdown
def display_bill_rich(units_consumed: float):
"""
Display the electricity bill with breakdown using rich formatting
Args:
units_consumed (float): Number of units consumed
"""
total_bill, breakdown = calculate_bill(units_consumed)
# Create title
title = Text("Electricity Bill Breakdown", style="bold magenta")
console.print(Panel(title, style="bold blue"))
# Create units consumed info
console.print(f"\nUnits Consumed: [bold cyan]{units_consumed:.2f}[/bold cyan]")
# Create table for breakdown
table = Table(show_header=True, header_style="bold green")
table.add_column("Slab", style="dim")
table.add_column("Amount (Taka)", justify="right", style="green")
# Add rows to table
for slab, amount in breakdown.items():
if slab == "VAT (5%)":
table.add_row(slab, f"{amount}", style="bold yellow") # Removed .2f as amounts are now integers
else:
table.add_row(slab, f"{amount}") # Removed .2f as amounts are now integers
# Add total
table.add_row("Total Bill", f"{total_bill}", style="bold red") # Removed .2f as amount is now integer
# Print table
console.print(table)
@app.command()
def calculate(units: float = typer.Option(..., prompt="Enter units consumed", help="Number of units consumed")):
"""
Calculate and display electricity bill for given units
"""
try:
if units < 0:
console.print("[bold red]Error: Units consumed cannot be negative![/bold red]")
raise typer.Exit(1)
display_bill_rich(units)
except ValueError as e:
console.print(f"[bold red]Error: {str(e)}[/bold red]")
raise typer.Exit(1)
if __name__ == "__main__":
app()
rich==13.7.0
typer[all]==0.9.0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment