summaryrefslogtreecommitdiff
path: root/conversion_utils.py
blob: bab27e1215dc0a67389e2353ba77b9b53c4ff7a1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#!/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")