class Battery:
    def __init__(
        self, power_density, specific_energy, max_discharge, safety_coefficient
    ):
        """
        Initializes the Battery.

        Parameters
        ----------
        power_density : float
            The power density of the battery in Watts per kilogram (W/kg).
        specific_energy : float
            The specific energy of the battery in Watt-hours per kilogram (Wh/kg).
        """
        self.power_density = power_density
        self.specific_energy = specific_energy
        self.max_discharge = max_discharge
        self.safety_coefficient = safety_coefficient

    def calculate_total_weight(self, required_capacity, required_max_power):
        """
        Calculates the total weight of a battery system.

        Parameters
        ----------
        required_capacity : float
            The required energy capacity of the battery in Watt-hours (Wh).
        required_max_power : float
            The required maximum power output of the battery in Watts (W).

        Returns
        -------
        total_weight: float
            The total weight of the battery, in kilograms.

        Raises
        ------
        ValueError
            If any of the input parameters are invalid.
        """
        # Input Validation
        if any(
            param < 0
            for param in [
                self.power_density,
                self.specific_energy,
                required_capacity,
                required_max_power,
            ]
        ):
            raise ValueError("Input parameters must be greater than 0.")
        required_power = (
            required_max_power * self.safety_coefficient / (1 - self.max_discharge)
        )
        required_capacity = (
            required_capacity * self.safety_coefficient / (1 - self.max_discharge)
        )
        # Calculate the weight based on capacity and power requirements
        capacity_weight = required_capacity / self.specific_energy
        power_weight = required_power / self.power_density

        # Determine the more demanding parameter
        self.weight = max(capacity_weight, power_weight)
        self.power = self.weight * self.power_density
        self.capacity = self.weight * self.specific_energy
        return self.weight
