I am trying to write an application to convert bytes to kb to mb to gb to tb. Here\'s what I have so far:
def size_format(b):
if b < 1000:
r
I think this is a short and succinct. The idea is based on some graph scaling code I wrote many years ago. The code snippet round(log2(size)*4)/40 does the magic here, calculating the boundaries with an increment with the power of 2**10. The "correct" implementation would be: trunc(log2(size)/10, however then you would get strange behavior when the size is close to a new boundary. For instance datasize(2**20-1) would return (1024.00, 'KiB'). By using round and scaling the log2result you get a nice cutof when approaching a new boundary.
from math import log2
def datasize(size):
"""
Calculate the size of a code in B/KB/MB.../
Return a tuple of (value, unit)
"""
assert size>0, "Size must be a positive number"
units = ("B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB")
scaling = round(log2(size)*4)//40
scaling = min(len(units)-1, scaling)
return size/(2**(10*scaling)), units[scaling]
for size in [2**10-1, 2**10-10, 2**10-100, 2**20-10000, 2**20-2**18, 2**20, 2**82-2**72, 2**80-2**76]:
print(size, "bytes= %.3f %s" % datasize(size))
1023 bytes= 0.999 KiB
1014 bytes= 0.990 KiB
924 bytes= 924.000 B
1038576 bytes= 0.990 MiB
786432 bytes= 768.000 KiB
1048576 bytes= 1.000 MiB
4830980911975647053611008 bytes= 3.996 YiB
1133367955888714851287040 bytes= 0.938 YiB