Created
December 20, 2024 15:03
-
-
Save muhiminulhasan/9a03503c5401570bedc466452aeb811b to your computer and use it in GitHub Desktop.
Tariff-Based Electricity Bill Calculator for West Zone Power Distribution Company.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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