Last active
July 23, 2022 17:15
-
-
Save Stefan-Code/6cbcde79eff1e78d51e6e9a8b971e1a7 to your computer and use it in GitHub Desktop.
Format numbers with the appropriate SI prefix
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def si_format(number, unit=''): | |
""" | |
Formats a number with the appropriate SI prefix. | |
Example: | |
>>> si_format(500000, unit='B') | |
'500 KB' | |
>>> si_format(2000000, unit='B') | |
'2 MB' | |
>>> si_format(1e-6, unit='m') | |
'1 μm' | |
""" | |
si_prefixes = ['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y', 'y', 'z', 'a', 'f', 'p', 'n', 'μ', 'm'] | |
try: | |
# max(min(...)) to clip list indices to the valid range. | |
# floor() yields *max.* 3 places before the decimal separator | |
# each SI prefixes increases by a factor of 1000 = 10^3 | |
# scaling factors for numbers < 1 are achieved with Python's fancy negative indexing | |
scaling_index = max(min(math.floor(math.log10(abs(number)) / 3), 8), -8) | |
except ValueError: | |
# log10(0) is undefined | |
scaling_index = 0 | |
# Formatting 4g = 4 *valid* digits (before or after the decimal separator) | |
return f'{number / (1000 ** scaling_index):.4g} {si_prefixes[scaling_index]}{unit}'.rstrip() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment