[CODER] [CODER] [CODER] Write the temperature conversion function #23
157
generated_code.py
Normal file
157
generated_code.py
Normal file
@ -0,0 +1,157 @@
|
||||
"""Temperature conversion utilities for SNS Network Solutions."""
|
||||
|
||||
from enum import Enum
|
||||
|
||||
|
||||
class TemperatureUnit(str, Enum):
|
||||
"""Supported temperature units."""
|
||||
|
||||
CELSIUS = "Celsius"
|
||||
FAHRENHEIT = "Fahrenheit"
|
||||
KELVIN = "Kelvin"
|
||||
|
||||
|
||||
# Absolute zero in Celsius — used for Kelvin validation
|
||||
_ABSOLUTE_ZERO_CELSIUS = -273.15
|
||||
_ABSOLUTE_ZERO_FAHRENHEIT = -459.67
|
||||
|
||||
|
||||
def convert_temperature(
|
||||
value: float,
|
||||
from_unit: str,
|
||||
to_unit: str,
|
||||
) -> float:
|
||||
"""Convert a temperature value between Celsius, Fahrenheit, and Kelvin.
|
||||
|
||||
Validates that the input value is physically possible (i.e., not below
|
||||
absolute zero for the given unit) and that both unit strings are
|
||||
recognised before performing the conversion.
|
||||
|
||||
Args:
|
||||
value: The numeric temperature to convert.
|
||||
from_unit: The unit of the supplied value. Must be one of
|
||||
``'Celsius'``, ``'Fahrenheit'``, or ``'Kelvin'``.
|
||||
to_unit: The target unit for the result. Same allowed values as
|
||||
*from_unit*.
|
||||
|
||||
Returns:
|
||||
The converted temperature as a ``float``, rounded to six decimal
|
||||
places to avoid floating-point noise.
|
||||
|
||||
Raises:
|
||||
TypeError: If *value* is not an ``int`` or ``float``.
|
||||
ValueError: If either unit string is not recognised, or if *value*
|
||||
is below absolute zero for the given *from_unit*.
|
||||
|
||||
Examples:
|
||||
>>> convert_temperature(100, 'Celsius', 'Fahrenheit')
|
||||
212.0
|
||||
>>> convert_temperature(32, 'Fahrenheit', 'Celsius')
|
||||
0.0
|
||||
>>> convert_temperature(0, 'Kelvin', 'Celsius')
|
||||
-273.15
|
||||
>>> convert_temperature(300, 'Kelvin', 'Fahrenheit')
|
||||
80.33
|
||||
"""
|
||||
# --- type guard ---
|
||||
if not isinstance(value, (int, float)):
|
||||
raise TypeError(
|
||||
f"'value' must be a numeric type (int or float), got {type(value).__name__!r}."
|
||||
)
|
||||
|
||||
# --- unit validation (guard clauses) ---
|
||||
valid_units = {u.value for u in TemperatureUnit}
|
||||
|
||||
if from_unit not in valid_units:
|
||||
raise ValueError(
|
||||
f"Unrecognised from_unit {from_unit!r}. "
|
||||
f"Allowed values: {sorted(valid_units)}."
|
||||
)
|
||||
if to_unit not in valid_units:
|
||||
raise ValueError(
|
||||
f"Unrecognised to_unit {to_unit!r}. "
|
||||
f"Allowed values: {sorted(valid_units)}."
|
||||
)
|
||||
|
||||
# --- physical validity guard ---
|
||||
_validate_above_absolute_zero(value, from_unit)
|
||||
|
||||
# --- trivial case ---
|
||||
if from_unit == to_unit:
|
||||
return float(value)
|
||||
|
||||
# --- convert to Celsius as the common intermediate ---
|
||||
celsius = _to_celsius(value, from_unit)
|
||||
|
||||
# --- convert from Celsius to the target unit ---
|
||||
result = _from_celsius(celsius, to_unit)
|
||||
|
||||
return round(result, 6)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Private helpers
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def _validate_above_absolute_zero(value: float, unit: str) -> None:
|
||||
"""Raise ValueError if *value* is below absolute zero for *unit*.
|
||||
|
||||
Args:
|
||||
value: The temperature value to check.
|
||||
unit: The unit string (already validated as a recognised unit).
|
||||
|
||||
Raises:
|
||||
ValueError: When *value* is physically impossible.
|
||||
"""
|
||||
if unit == TemperatureUnit.CELSIUS and value < _ABSOLUTE_ZERO_CELSIUS:
|
||||
raise ValueError(
|
||||
f"Temperature {value} °C is below absolute zero "
|
||||
f"({_ABSOLUTE_ZERO_CELSIUS} °C)."
|
||||
)
|
||||
if unit == TemperatureUnit.FAHRENHEIT and value < _ABSOLUTE_ZERO_FAHRENHEIT:
|
||||
raise ValueError(
|
||||
f"Temperature {value} °F is below absolute zero "
|
||||
f"({_ABSOLUTE_ZERO_FAHRENHEIT} °F)."
|
||||
)
|
||||
if unit == TemperatureUnit.KELVIN and value < 0:
|
||||
raise ValueError(
|
||||
f"Temperature {value} K is below absolute zero (0 K)."
|
||||
)
|
||||
|
||||
|
||||
def _to_celsius(value: float, from_unit: str) -> float:
|
||||
"""Convert *value* (in *from_unit*) to degrees Celsius.
|
||||
|
||||
Args:
|
||||
value: Source temperature.
|
||||
from_unit: Source unit (pre-validated).
|
||||
|
||||
Returns:
|
||||
Equivalent temperature in Celsius.
|
||||
"""
|
||||
if from_unit == TemperatureUnit.CELSIUS:
|
||||
return float(value)
|
||||
if from_unit == TemperatureUnit.FAHRENHEIT:
|
||||
# °C = (°F − 32) × 5/9
|
||||
return (value - 32) * 5 / 9
|
||||
# Kelvin → °C = K − 273.15
|
||||
return value - 273.15
|
||||
|
||||
|
||||
def _from_celsius(celsius: float, to_unit: str) -> float:
|
||||
"""Convert a Celsius value to *to_unit*.
|
||||
|
||||
Args:
|
||||
celsius: Temperature in degrees Celsius.
|
||||
to_unit: Target unit (pre-validated).
|
||||
|
||||
Returns:
|
||||
Equivalent temperature in *to_unit*.
|
||||
"""
|
||||
if to_unit == TemperatureUnit.CELSIUS:
|
||||
return celsius
|
||||
if to_unit == TemperatureUnit.FAHRENHEIT:
|
||||
# °F = °C × 9/5 + 32
|
||||
return celsius * 9 / 5 + 32
|
||||
# °C → K = °C + 273.15
|
||||
return celsius + 273.15
|
||||
Loading…
Reference in New Issue
Block a user