221k views
22 votes
Make a Python script that converts Gigabytes to Kilobytes, Megabytes, Terabyte, & Petabyte.

User Kamilla
by
4.7k points

1 Answer

11 votes

Coding:

def humanbytes(B):

"""Return the given bytes as a human friendly KB, MB, GB, or TB string."""

B = float(B)

KB = float(1024)

MB = float(KB ** 2) # 1,048,576

GB = float(KB ** 3) # 1,073,741,824

TB = float(KB ** 4) # 1,099,511,627,776

if B < KB:

return '{0} {1}'.format(B,'Bytes' if 0 == B > 1 else 'Byte')

elif KB <= B < MB:

return '{0:.2f} KB'.format(B / KB)

elif MB <= B < GB:

return '{0:.2f} MB'.format(B / MB)

elif GB <= B < TB:

return '{0:.2f} GB'.format(B / GB)

elif TB <= B:

return '{0:.2f} TB'.format(B / TB)

tests = [1, 1024, 500000, 1048576, 50000000, 1073741824, 5000000000, 1099511627776, 5000000000000]

for t in tests: print("{0} == {1}".format(t,humanbytes(t)))

Step-by-step explanation:

By the way, the hardcoded PRECISION_OFFSETS is created that way for maximum performance. We could have programmatically calculated the offsets using the formula unit_step_thresh = unit_step - (0.5/(10**precision)) to support arbitrary precisions. But it really makes NO sense to format filesizes with massive 4+ trailing decimal numbers. That's why my function supports exactly what people use: 0, 1, 2 or 3 decimals. Thus we avoid a bunch of pow and division math. This decision is one of many small attention-to-detail choices that make this function FAST. Another example of performance choices was the decision to use a string-based if unit != last_label check to detect the end of the List, rather than iterating by indices and seeing if we've reached the final List-index. Generating indices via range() or tuples via enumerate() is slower than just doing an address comparison of Python's immutable string objects stored in the _LABELS lists, which is what this code does instead!

User Trinitrotoluene
by
5.1k points