""" Convert International System of Units (SI) and Binary prefixes """ from __future__ import annotations from enum import Enum class SIUnit(Enum): yotta = 24 zetta = 21 exa = 18 peta = 15 tera = 12 giga = 9 mega = 6 kilo = 3 hecto = 2 deca = 1 deci = -1 centi = -2 milli = -3 micro = -6 nano = -9 pico = -12 femto = -15 atto = -18 zepto = -21 yocto = -24 class BinaryUnit(Enum): yotta = 8 zetta = 7 exa = 6 peta = 5 tera = 4 giga = 3 mega = 2 kilo = 1 def convert_si_prefix( known_amount: float, known_prefix: str | SIUnit, unknown_prefix: str | SIUnit, ) -> float: """ Wikipedia reference: https://en.wikipedia.org/wiki/Binary_prefix Wikipedia reference: https://en.wikipedia.org/wiki/International_System_of_Units >>> convert_si_prefix(1, SIUnit.giga, SIUnit.mega) 1000 >>> convert_si_prefix(1, SIUnit.mega, SIUnit.giga) 0.001 >>> convert_si_prefix(1, SIUnit.kilo, SIUnit.kilo) 1 >>> convert_si_prefix(1, 'giga', 'mega') 1000 >>> convert_si_prefix(1, 'gIGa', 'mEGa') 1000 """ if isinstance(known_prefix, str): known_prefix = SIUnit[known_prefix.lower()] if isinstance(unknown_prefix, str): unknown_prefix = SIUnit[unknown_prefix.lower()] unknown_amount: float = known_amount * ( 10 ** (known_prefix.value - unknown_prefix.value) ) return unknown_amount def convert_binary_prefix( known_amount: float, known_prefix: str | BinaryUnit, unknown_prefix: str | BinaryUnit, ) -> float: """ Wikipedia reference: https://en.wikipedia.org/wiki/Metric_prefix >>> convert_binary_prefix(1, BinaryUnit.giga, BinaryUnit.mega) 1024 >>> convert_binary_prefix(1, BinaryUnit.mega, BinaryUnit.giga) 0.0009765625 >>> convert_binary_prefix(1, BinaryUnit.kilo, BinaryUnit.kilo) 1 >>> convert_binary_prefix(1, 'giga', 'mega') 1024 >>> convert_binary_prefix(1, 'gIGa', 'mEGa') 1024 """ if isinstance(known_prefix, str): known_prefix = BinaryUnit[known_prefix.lower()] if isinstance(unknown_prefix, str): unknown_prefix = BinaryUnit[unknown_prefix.lower()] unknown_amount: float = known_amount * ( 2 ** ((known_prefix.value - unknown_prefix.value) * 10) ) return unknown_amount if __name__ == "__main__": import doctest doctest.testmod()