Рассмотрим функцию, которая преобразует количество байтов в удобочитаемую строку:
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)
Я ищу функцию, которая, учитывая читаемую человеком строку, вернет границы этого размера (мин, макс) в байтах, составляя 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
Но это решение дает только приблизительные значения
@Barmar получил таблицу в БД, в которой хранятся размеры файлов в байтах. Нужно, чтобы пользователи моего приложения отфильтровали эту таблицу с такими вещами, как «размер файла равен 10,5 МБ», «размер файла меньше 9 КиБ»
Перевод 10,5 МБ в определенный диапазон кажется плохим пользовательским интерфейсом. Я бы просто дал им два поля, чтобы указать конечные точки диапазона. Но это, вероятно, лучшее обсуждение для Пользовательский опыт.






Вы можете использовать двоичный поиск: начните с приблизительного значения, сделайте его диапазоном на основе множителя и выполните поиск в этом диапазоне на основе того, как значение преобразуется в удобочитаемую форму.
Поскольку вы предполагаете, что во входных данных используется только 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)
Это кажется странным, что нужно делать, зачем вам это нужно? Может быть, есть лучший способ решить настоящую проблему.