Python format size application (converting B to KB, MB, GB, TB)

前端 未结 15 1642
轮回少年
轮回少年 2021-02-01 16:13

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         


        
相关标签:
15条回答
  • 2021-02-01 16:39

    Here is to convert bytes to kilo, mega, tera.

    #From bytes to kilo, mega, tera
    def  get_(size):
    
        #2**10 = 1024
        power = 2**10
        n = 1
        Dic_powerN = {1:'kilobytes', 2:'megabytes', 3:'gigabytes', 4:'Terabytes'}
    
        if size <= power**2 :
            size /=  power
            return size, Dic_powerN[n]
    
        else: 
            while size   >  power :
                n  += 1
                size /=  power**n
    
            return size, Dic_powerN[n]
    
    0 讨论(0)
  • 2021-02-01 16:40

    I have improved, in my opininion, @whereisalext answer to have a somewhat more generic function which does not require one to add more if statements once more units are going to be added:

    AVAILABLE_UNITS = ['bytes', 'KB', 'MB', 'GB', 'TB']
    
    def get_amount_and_unit(byte_amount):
        for index, unit in enumerate(AVAILABLE_UNITS):
            lower_threshold = 0 if index == 0 else 1024 ** (index - 1)
            upper_threshold = 1024 ** index
            if lower_threshold <= byte_amount < upper_threshold:
                if lower_threshold == 0:
                    return byte_amount, unit
                else:
                    return byte_amount / lower_threshold, AVAILABLE_UNITS[index - 1]
        # Default to the maximum
        max_index = len(AVAILABLE_UNITS) - 1
        return byte_amount / (1024 ** max_index), AVAILABLE_UNITS[max_index]
    

    Do note that this differs slightly frrom @whereisalext's algo:

    • This returns a tuple containing the converted amount at the first index and the unit at the second index
    • This does not try to differ between a singular and multiple bytes (1 bytes is therefore an output of this approach)
    0 讨论(0)
  • 2021-02-01 16:44

    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
    
    0 讨论(0)
  • 2021-02-01 16:47

    I have quite readable function to convert bytes into greater units:

    def bytes_2_human_readable(number_of_bytes):
        if number_of_bytes < 0:
            raise ValueError("!!! number_of_bytes can't be smaller than 0 !!!")
    
        step_to_greater_unit = 1024.
    
        number_of_bytes = float(number_of_bytes)
        unit = 'bytes'
    
        if (number_of_bytes / step_to_greater_unit) >= 1:
            number_of_bytes /= step_to_greater_unit
            unit = 'KB'
    
        if (number_of_bytes / step_to_greater_unit) >= 1:
            number_of_bytes /= step_to_greater_unit
            unit = 'MB'
    
        if (number_of_bytes / step_to_greater_unit) >= 1:
            number_of_bytes /= step_to_greater_unit
            unit = 'GB'
    
        if (number_of_bytes / step_to_greater_unit) >= 1:
            number_of_bytes /= step_to_greater_unit
            unit = 'TB'
    
        precision = 1
        number_of_bytes = round(number_of_bytes, precision)
    
        return str(number_of_bytes) + ' ' + unit
    
    0 讨论(0)
  • 2021-02-01 16:47

    A very simple solution would be:

    SIZE_UNITS = ['B', 'KB', 'MB', 'GB', 'TB', 'PB']
    
    def get_readable_file_size(size_in_bytes):
        index = 0
        while size_in_bytes >= 1024:
            size_in_bytes /= 1024
            index += 1
        try:
            return f'{size_in_bytes} {SIZE_UNITS[index]}'
        except IndexError:
            return 'File too large'
    
    0 讨论(0)
  • 2021-02-01 16:48

    good idea for me:

    def convert_bytes(num):
        """
        this function will convert bytes to MB.... GB... etc
        """
        step_unit = 1000.0 #1024 bad the size
    
        for x in ['bytes', 'KB', 'MB', 'GB', 'TB']:
            if num < step_unit:
                return "%3.1f %s" % (num, x)
            num /= step_unit
    
    0 讨论(0)
提交回复
热议问题