import base64 from csv import DictWriter import os.path as os_path from plotly.graph_objects import Figure import gradio as gr from pandas import read_csv, DataFrame import emission_calculator.calculator as ec DATA_PATH = "./reports/historic_data.csv" def compute_history() -> Figure: if not os_path.exists(DATA_PATH): f = open(DATA_PATH, "xt") f.write("Name,Energy Usage,Waste Generated,Business Travel") f.close() df = DataFrame.from_dict({}) else: df = read_csv(DATA_PATH) return ec.draw_historic_figure(df) def validate_input( company_name: str, avg_electric_bill: float, avg_gas_bill: float, avg_transport_cost: float, monthly_waste_generated: float, recycled_waste_percent: float, annual_travel_kms: float, fuel_efficiency: float, ) -> None: """ Comprehensive validation for input parameters with non-zero requirements """ # Company Name Validation if not company_name or company_name.isspace(): raise gr.Error("Company name cannot be empty or just whitespace!") if len(company_name) > 100: raise gr.Error("Company name is too long (maximum 100 characters)!") # Non-Zero Input Validation non_zero_fields = [ ("Electricity Bill", avg_electric_bill), ("Gas Bill", avg_gas_bill), ("Transport Cost", avg_transport_cost), ("Monthly Waste", monthly_waste_generated), ("Annual Travel Distance", annual_travel_kms), ("Fuel Efficiency", fuel_efficiency), ] for name, value in non_zero_fields: try: float_val = float(value) except (TypeError, ValueError): raise gr.Error(f"{name} must be a valid number!") if float_val <= 0: raise gr.Error(f"{name} must be a positive number greater than zero!") # Additional realistic range checks if name == "Electricity Bill" and float_val > 10000: raise gr.Error( "Electricity bill seems unrealistically high. Please check the amount!" ) if name == "Monthly Waste" and float_val > 1000: raise gr.Error( "Monthly waste generation seems extremely high. Please verify!" ) if name == "Fuel Efficiency" : if float_val < 5: raise gr.Error( "Fuel efficiency seems unrealistically low. Please verify!" ) if float_val > 15: raise gr.Error( "Fuel efficiency is very high. Please verify!" ) # Percentage-specific validation try: recycled_percent = float(recycled_waste_percent) except (TypeError, ValueError): raise gr.Error("Recycled waste percentage must be a valid number!") if recycled_percent < 0 or recycled_percent > 100: raise gr.Error("Recycled waste percentage must be between 1 and 100!") def compute( company_name: str, avg_electric_bill: float, avg_gas_bill: float, avg_transport_cost: float, monthly_waste_generated: float, recycled_waste_percent: float, annual_travel_kms: float, fuel_efficiency: float, ) -> tuple[str, gr.Button]: """ Compute carbon footprint with comprehensive input validation Returns: result (tuple) of summary HTML (str) and download_report button (Button) """ # Validate inputs first validate_input( company_name, avg_electric_bill, avg_gas_bill, avg_transport_cost, monthly_waste_generated, recycled_waste_percent, annual_travel_kms, fuel_efficiency, ) # Proceed with calculation if validation passes df = ec.make_dataframe( company_name=company_name, avg_electric_bill=avg_electric_bill, avg_gas_bill=avg_gas_bill, avg_transport_bill=avg_transport_cost, monthly_waste_generated=monthly_waste_generated, recycled_waste_percent=recycled_waste_percent, annual_travel_kms=annual_travel_kms, fuel_efficiency=fuel_efficiency, ) try: df_dump = ec.dataframe_to_dict(df=df) with open(DATA_PATH, mode="a") as f: w = DictWriter(f, fieldnames=df_dump.keys()) if not os_path.exists(DATA_PATH): w.writeheader() w.writerow(df_dump) print("Saving is successful") except Exception as e: print(e) plot = ec.draw_report_figure(df) # Convert plot to base64 image img_data = base64.b64encode( plot.to_image(width=1400, height=800, format="png") ).decode("utf-8") # convert plot to pdf for downloading report file_path = f"./reports/{company_name.lower().replace(' ', '_')[:10]}_report.pdf" plot.write_image(file_path, width=1400, height=800) # Generate a summary HTML with embedded image summary = f"""