Repository: home-assistant/core
File: homeassistant/util/unit_conversion.py (Python)

Code before:

    @classmethod
    @lru_cache
    def get_unit_floored_log_ratio(
        cls, from_unit: str | None, to_unit: str | None
    ) -> float:
        """Get floored base10 log ratio between units of measurement."""
        ratio = cls.get_unit_ratio(from_unit, to_unit)
        return floor(max(0, log10(ratio)))

    @classmethod
    @lru_cache
    def _are_unit_inverses(cls, from_unit: str | None, to_unit: str | None) -> bool:
        """Return true if one unit is an inverse but not the other."""
        return (from_unit in cls._UNIT_INVERSES) != (to_unit in cls._UNIT_INVERSES)


class CarbonMonoxideConcentrationConverter(BaseUnitConverter):
    """Convert carbon monoxide ratio to mass per volume.

    Using ambient temperature of 20°C and pressure of 1 ATM.
    """

    UNIT_CLASS = "carbon_monoxide"
    _UNIT_CONVERSION: dict[str | None, float] = {
        CONCENTRATION_PARTS_PER_BILLION: 1e3,
        CONCENTRATION_PARTS_PER_MILLION: 1e6,
        CONCENTRATION_MILLIGRAMS_PER_CUBIC_METER: (
            _CARBON_MONOXIDE_MOLAR_MASS / _AMBIENT_IDEAL_GAS_MOLAR_VOLUME * 1e3
        ),
        CONCENTRATION_MICROGRAMS_PER_CUBIC_METER: (
            _CARBON_MONOXIDE_MOLAR_MASS / _AMBIENT_IDEAL_GAS_MOLAR_VOLUME * 1e6
        ),
    }
    VALID_UNITS = {
        CONCENTRATION_PARTS_PER_BILLION,
        CONCENTRATION_PARTS_PER_MILLION,
        CONCENTRATION_MILLIGRAMS_PER_CUBIC_METER,
        CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
    }


class DataRateConverter(BaseUnitConverter):
    """Utility to convert data rate values."""

    UNIT_CLASS = "data_rate"
    # Units in terms of bits
    _UNIT_CONVERSION: dict[str | None, float] = {
        UnitOfDataRate.BITS_PER_SECOND: 1,
        UnitOfDataRate.KILOBITS_PER_SECOND: 1 / 1e3,
        UnitOfDataRate.MEGABITS_PER_SECOND: 1 / 1e6,

Review comment (bug):
This should be `1e9` in my opinion. Tests pass because your last commit made the test wrong.

Code after:
    def get_unit_ratio(cls, from_unit: str | None, to_unit: str | None) -> float:
        """Get unit ratio between units of measurement."""
        from_ratio, to_ratio = cls._get_from_to_ratio(from_unit, to_unit)
        return from_ratio / to_ratio

    @classmethod
    @lru_cache
    def get_unit_floored_log_ratio(
        cls, from_unit: str | None, to_unit: str | None
    ) -> float:
        """Get floored base10 log ratio between units of measurement."""
        ratio = cls.get_unit_ratio(from_unit, to_unit)
        return floor(max(0, log10(ratio)))

    @classmethod
    @lru_cache
    def _are_unit_inverses(cls, from_unit: str | None, to_unit: str | None) -> bool:
        """Return true if one unit is an inverse but not the other."""
        return (from_unit in cls._UNIT_INVERSES) != (to_unit in cls._UNIT_INVERSES)


class CarbonMonoxideConcentrationConverter(BaseUnitConverter):
    """Convert carbon monoxide ratio to mass per volume.

    Using ambient temperature of 20°C and pressure of 1 ATM.
    """

    UNIT_CLASS = "carbon_monoxide"
    _UNIT_CONVERSION: dict[str | None, float] = {
        CONCENTRATION_PARTS_PER_BILLION: 1e9,
        CONCENTRATION_PARTS_PER_MILLION: 1e6,
        CONCENTRATION_MILLIGRAMS_PER_CUBIC_METER: (
            _CARBON_MONOXIDE_MOLAR_MASS / _AMBIENT_IDEAL_GAS_MOLAR_VOLUME * 1e3
        ),
        CONCENTRATION_MICROGRAMS_PER_CUBIC_METER: (
            _CARBON_MONOXIDE_MOLAR_MASS / _AMBIENT_IDEAL_GAS_MOLAR_VOLUME * 1e6
        ),
    }
    VALID_UNITS = {
        CONCENTRATION_PARTS_PER_BILLION,
        CONCENTRATION_PARTS_PER_MILLION,
        CONCENTRATION_MILLIGRAMS_PER_CUBIC_METER,
        CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
    }


class DataRateConverter(BaseUnitConverter):
    """Utility to convert data rate values."""

    UNIT_CLASS = "data_rate"
    # Units in terms of bits