Удобочитаемый размер в диапазоне байтов - PullRequest
0 голосов
/ 18 марта 2019

Рассмотрим функцию, которая преобразует количество байтов в читаемую человеком строку:

def sizeof_fmt(num, suffix='B'):
    for unit in ['','Ki','Mi','Gi','Ti','Pi','Ei','Zi']:
        if abs(num) < 1024.0:
            return "%3.1f %s%s" % (num, unit, suffix)
        num /= 1024.0
    return "%.1f %s%s" % (num, 'Yi', suffix)

Я ищу функцию, которая, учитывая читаемую человеком строку, вернула бы границы этого размера (min, max) в байтах, что составляет 1 число после десятичной точки. Например:

human_readable_to_range('1 KiB') => 1024, 1075 1 КиБ останавливается на 1075, потому что 1076 - это 1,1 КиБ

human_readable_to_range('1.3 KiB') => 1281, 1382

human_readable_to_range('9.7 MiB') => 10118759, 10223615

Я пытался решить это следующим образом:

def human_readable_to_range(size):
  MULTIPLIERS = {
    'KiB': 2**10,
    'MiB': 2**20
  }
  number, unit = size.split(' ')
  multiplier = MULTIPLIERS[unit]
  rough_value = float(number) * multiplier
  min_ = rough_value - multiplier * 0.5
  max_ = rough_value + multiplier * 0.5

Но это решение дает только приблизительные значения

Ответы [ 2 ]

0 голосов
/ 18 марта 2019

Поскольку вы принимаете только 1 десятичную цифру на входе, добавьте и вычтите 0.05 к данному числу и используйте его как максимальное и минимальное количество, которое затем умножаете на единицу.

def human_readable_to_range(size):
  MULTIPLIERS = {
    'KiB': 2**10,
    'MiB': 2**20
  }
  number, unit = size.split(' ')
  minnum = float(number) - 0.05
  maxnum = float(number) + 0.05
  multiplier = MULTIPLIERS[unit]
  return round(minnum * multiplier), round(maxnum * multiplier)
0 голосов
/ 18 марта 2019

Вы можете использовать бинарный поиск: начать с приблизительного значения, сделать его диапазоном на основе множителя и искать этот диапазон на основе того, как значение преобразуется в его удобочитаемую форму.

...