#!/usr/bin/env python3 from numbers import Number from typing import Callable class Converter(object): def __init__(self, name: str, category: str, to_canonical: Callable, from_canonical: Callable, unit: str) -> None: self.name = name self.category = category self.to_canonical = to_canonical self.from_canonical = from_canonical self.unit = unit def to_canonical(self, n: Number) -> Number: return self.to_canonical(n) def from_canonical(self, n: Number) -> Number: return self.from_canonical(n) def unit_suffix(self) -> str: return self.unit conversion_catalog = { "Fahrenheit": Converter("Fahrenheit", "temperature", lambda f: (f - 32.0) * 0.55555555, lambda c: c * 1.8 + 32.0, "°F"), "Celsius": Converter("Celsius", "temperature", lambda c: c, lambda c: c, "°C"), "Kelvin": Converter("Kelvin", "temperature", lambda k: k - 273.15, lambda c: c + 273.15, "°K"), } def convert(magnitude: Number, from_thing: str, to_thing: str) -> Number: src = conversion_catalog.get(from_thing, None) dst = conversion_catalog.get(to_thing, None) if src is None or dst is None: raise ValueError("No known conversion") return _convert(magnitude, src, dst) def _convert(magnitude: Number, from_unit: Converter, to_unit: Converter) -> Number: canonical = from_unit.to_canonical(magnitude) converted = to_unit.from_canonical(canonical) return converted def f_to_c(temp_f: float) -> float: """Fahrenheit to Celsius.""" return convert(temp_f, "Fahrenheit", "Celsius") def c_to_f(temp_c: float) -> float: """Celsius to Fahrenheit.""" return convert(temp_c, "Celsius", "Fahrenheit")