subprocess-util/src/subprocess_util/data_units.py

70 lines
1.9 KiB
Python
Raw Normal View History

2023-01-11 20:02:36 +01:00
from enum import Enum
def test():
for num_bytes in [0, 1, 128, 512, 1024, 4096, 75 * 1000, 750 * 1000, 850 * 1000, 1111 * 1000]:
print(f'{num_bytes} bytes = {DataUnitConverter.to_unit_auto_str(num_bytes)}')
class DataUnitConverter:
"""
A class to convert between data units.
Example: 1.000.000 B == 1 MB
The main purpose is to convert a number with many digits
to a "larger" unit so that the number is shorter
and more readable.
"""
2023-01-11 20:02:36 +01:00
class DataUnit(Enum):
B = 'B'
KB = 'KB'
MB = 'MB'
GB = 'GB'
TB = 'TB'
# Units sorted from small to large.
_unit_dict: dict[DataUnit, int] = {
DataUnit.B: 1,
DataUnit.KB: 1024,
DataUnit.MB: 1024 * 1024,
DataUnit.GB: 1024 * 1024 * 1024,
DataUnit.TB: 1024 * 1024 * 1024 * 1024,
}
@classmethod
def to_bytes(cls, num: int, unit: DataUnit) -> int:
return num * cls._unit_dict[unit]
@classmethod
def to_unit(cls, num_bytes: int, unit: DataUnit = DataUnit.GB) -> float:
return round(num_bytes / cls._unit_dict[unit], 3)
2023-03-29 17:48:51 +02:00
@classmethod
def to_unit_str(cls, num_bytes: int, unit: DataUnit = DataUnit.GB) -> str:
value = round(num_bytes / cls._unit_dict[unit], 3)
return cls.to_str(value, unit)
2023-01-11 20:02:36 +01:00
@classmethod
2023-01-12 16:28:18 +01:00
def to_unit_auto(cls, num_bytes: int) -> tuple[float, DataUnit]:
2023-01-11 20:02:36 +01:00
for unit, factor in cls._unit_dict.items():
converted = cls.to_unit(num_bytes, unit)
if converted <= 999:
return converted, unit
return num_bytes, cls.DataUnit.B
@classmethod
def to_unit_auto_str(cls, num_bytes: int) -> str:
value, unit = cls.to_unit_auto(num_bytes)
2023-03-29 17:48:51 +02:00
return cls.to_str(value, unit)
@classmethod
def to_str(cls, value: float, unit: DataUnit):
2023-01-11 20:02:36 +01:00
return f'{value} {unit.value}'
if __name__ == '__main__':
test()