Skip to content

Instantly share code, notes, and snippets.

@JonathonReinhart
Created March 29, 2019 01:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JonathonReinhart/6839e16a38258c6b8f25bc9046199ccb to your computer and use it in GitHub Desktop.
Save JonathonReinhart/6839e16a38258c6b8f25bc9046199ccb to your computer and use it in GitHub Desktop.
Python human file size
#!/usr/bin/env/python3
import math
def round_down(n, d=8):
# https://stackoverflow.com/a/43533589/119527
d = 10 ** d
return math.floor(n * d) / d
def human_size(n, decimal_places=2):
n = float(n)
suffixes = ['', 'Ki', 'Mi', 'Gi', 'Ti', 'Pi']
for suffix in suffixes:
if n < 1024:
break
n /= 1024
if n.is_integer():
size = str(int(n))
else:
size = '{0:.{1}f}'.format(round_down(n, decimal_places), decimal_places)
return '{} {}B'.format(size, suffix)
if __name__ == '__main__':
import unittest
class Test(unittest.TestCase):
def test_1(self):
self.assertEqual(human_size(1), '1 B')
def test_1000(self):
self.assertEqual(human_size(1000), '1000 B')
def test_1_K_minus_1(self):
self.assertEqual(human_size(1023), '1023 B')
def test_1_K(self):
self.assertEqual(human_size(1024), '1 KiB')
def test_1_K_plus_1(self):
# It's not exactly 1 KiB, so show two decimal places
self.assertEqual(human_size(1024+1), '1.00 KiB')
def test_2_K_minus_1(self):
# It's not quite 2 KiB, so show two decimal places
self.assertEqual(human_size(2048-1), '1.99 KiB')
unittest.main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment