convert international system of units si and binary prefixes wikipedia reference https en wikipedia orgwikibinaryprefix wikipedia reference https en wikipedia orgwikiinternationalsystemofunits convertsiprefix1 siunit giga siunit mega 1000 convertsiprefix1 siunit mega siunit giga 0 001 convertsiprefix1 siunit kilo siunit kilo 1 convertsiprefix1 giga mega 1000 convertsiprefix1 giga mega 1000 wikipedia reference https en wikipedia orgwikimetricprefix convertbinaryprefix1 binaryunit giga binaryunit mega 1024 convertbinaryprefix1 binaryunit mega binaryunit giga 0 0009765625 convertbinaryprefix1 binaryunit kilo binaryunit kilo 1 convertbinaryprefix1 giga mega 1024 convertbinaryprefix1 giga mega 1024 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 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
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:
    
    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:
    
    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()