Skip to content

Instantly share code, notes, and snippets.

@agmezr
Created September 1, 2020 19:46
Show Gist options
  • Save agmezr/ddc1213c4c3dbbdc95e85f64091bc7ed to your computer and use it in GitHub Desktop.
Save agmezr/ddc1213c4c3dbbdc95e85f64091bc7ed to your computer and use it in GitHub Desktop.
Human friendly format without using math libraries
"""
Write a function in Python called ‘humanSize’ that takes a non-negative number
of bytes and returns a string with the equivalent number of ‘kB’, ‘MB’, ‘GB’,
‘TB’, ‘PB’, ‘EB’, ‘ZB’, or ‘YB’,between [0, 1000), with at most 1 digit of
precision after the decimal.
If the number of bytes is >= 1000 YB, return this number of YB, for example 5120 YB.
"""
from collections import OrderedDict
# using ordered dict to make sure it evaluates first the biggest one.
SIZE_BYTES = OrderedDict({
"YB": 1e24,
"ZB": 1e21,
"EB": 1e18,
"PB": 1e15,
"TB": 1e12,
"GB": 1e9,
"MB": 1e6,
"KB": 1e3,
})
def humanSize(total_bytes):
"""Returns the total number of bytes in human friendly format."""
if total_bytes < 0 :
raise ValueError("Number should be positive")
if total_bytes >= SIZE_BYTES["YB"]:
total = int(total_bytes // SIZE_BYTES["YB"])
return f"{total} YB"
for size, value in SIZE_BYTES.items():
if total_bytes // value > 0:
result = _format_number(total_bytes/value)
return f"{result} {size}"
return f"{total_bytes} bytes"
def _format_number(n):
"""Returns the decimal number truncated to 1 position.
Can't use format(".1f") because it will round it up.
"""
num = str(n).split(".")
if len(num) == 1:
return n
integer, decimal = num
return ".".join((integer, decimal[:1]))
if __name__ == "__main__":
# assert base cases
assert humanSize(10) == "10 bytes"
assert humanSize(1e3) == "1.0 KB"
assert humanSize(1e6) == "1.0 MB"
assert humanSize(1e9) == "1.0 GB"
assert humanSize(1e12) == "1.0 TB"
assert humanSize(1e15) == "1.0 PB"
assert humanSize(1e18) == "1.0 EB"
assert humanSize(1e21) == "1.0 ZB"
assert humanSize(1e24) == "1 YB"
# assert not round
assert humanSize(9990) == "9.9 KB"
assert humanSize(9999990) == "9.9 MB"
assert humanSize(9.9e18) == "9.9 EB"
assert humanSize(9.9e21) == "9.9 ZB"
# some big numbers
assert humanSize(21367329234) == "21.3 GB"
assert humanSize(2136732923453884) == "2.1 PB"
assert humanSize(657892349896458698) == "657.8 PB"
assert humanSize(6578923498964586980) == "6.5 EB"
assert humanSize(657892349896458649646849359) == "657 YB"
assert humanSize(578923498964586496468499) == "578.9 ZB"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment