lnbits-legend/lnbits/extensions/gerty/number_prefixer.py
2023-01-30 11:46:44 +00:00

66 lines
2.7 KiB
Python

import math
def si_classifier(val):
suffixes = {
24: {"long_suffix": "yotta", "short_suffix": "Y", "scalar": 10**24},
21: {"long_suffix": "zetta", "short_suffix": "Z", "scalar": 10**21},
18: {"long_suffix": "exa", "short_suffix": "E", "scalar": 10**18},
15: {"long_suffix": "peta", "short_suffix": "P", "scalar": 10**15},
12: {"long_suffix": "tera", "short_suffix": "T", "scalar": 10**12},
9: {"long_suffix": "giga", "short_suffix": "G", "scalar": 10**9},
6: {"long_suffix": "mega", "short_suffix": "M", "scalar": 10**6},
3: {"long_suffix": "kilo", "short_suffix": "k", "scalar": 10**3},
0: {"long_suffix": "", "short_suffix": "", "scalar": 10**0},
-3: {"long_suffix": "milli", "short_suffix": "m", "scalar": 10**-3},
-6: {"long_suffix": "micro", "short_suffix": "ยต", "scalar": 10**-6},
-9: {"long_suffix": "nano", "short_suffix": "n", "scalar": 10**-9},
-12: {"long_suffix": "pico", "short_suffix": "p", "scalar": 10**-12},
-15: {"long_suffix": "femto", "short_suffix": "f", "scalar": 10**-15},
-18: {"long_suffix": "atto", "short_suffix": "a", "scalar": 10**-18},
-21: {"long_suffix": "zepto", "short_suffix": "z", "scalar": 10**-21},
-24: {"long_suffix": "yocto", "short_suffix": "y", "scalar": 10**-24},
}
exponent = int(math.floor(math.log10(abs(val)) / 3.0) * 3)
return suffixes.get(exponent, None)
def si_formatter(value):
"""
Return a triple of scaled value, short suffix, long suffix, or None if
the value cannot be classified.
"""
classifier = si_classifier(value)
if classifier is None:
# Don't know how to classify this value
return None
scaled = value / classifier["scalar"]
return (scaled, classifier["short_suffix"], classifier["long_suffix"])
def si_format(value, precision=4, long_form=False, separator=""):
"""
"SI prefix" formatted string: return a string with the given precision
and an appropriate order-of-3-magnitudes suffix, e.g.:
si_format(1001.0) => '1.00K'
si_format(0.00000000123, long_form=True, separator=' ') => '1.230 nano'
"""
scaled, short_suffix, long_suffix = si_formatter(value)
if scaled is None:
# Don't know how to format this value
return value
suffix = long_suffix if long_form else short_suffix
if abs(scaled) < 10:
precision = precision - 1
elif abs(scaled) < 100:
precision = precision - 2
else:
precision = precision - 3
return "{scaled:.{precision}f}{separator}{suffix}".format(
scaled=scaled, precision=precision, separator=separator, suffix=suffix
)