Skip to content

Commit

Permalink
use metric prefixes K, M, ...
Browse files Browse the repository at this point in the history
  • Loading branch information
bernt-matthias committed Feb 21, 2024
1 parent 22f5073 commit 279c372
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 49 deletions.
2 changes: 1 addition & 1 deletion lib/galaxy/datatypes/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -1100,7 +1100,7 @@ def set_peek(self, dataset: DatasetProtocol, **kwd) -> None:
else:
est_lines = self.estimate_file_lines(dataset)
if est_lines is not None:
dataset.blurb = f"~{util.trailing_zeros_to_powerof10(util.roundify(est_lines))} {inflector.cond_plural(est_lines, self.line_class)}"
dataset.blurb = f"~{util.trailing_zeros_to_powerof10(est_lines)} {inflector.cond_plural(est_lines, self.line_class)}"
else:
dataset.blurb = "Error: Cannot estimate lines in dataset"
else:
Expand Down
103 changes: 55 additions & 48 deletions lib/galaxy/util/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,6 @@
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from hashlib import md5
from math import (
floor,
log10,
)
from os.path import relpath
from typing import (
Any,
Expand Down Expand Up @@ -1139,14 +1135,14 @@ def commaify(amount):
return commaify(new)


def trailing_zeros_to_powerof10(amount: int):
def trailing_zeros_to_powerof10(amount: int) -> str:
"""
>>> trailing_zeros_to_powerof10(23000)
'23000'
'23K'
>>> trailing_zeros_to_powerof10(2300000)
'23\u00d710^5'
'2.3M'
>>> trailing_zeros_to_powerof10(23000000)
'23\u00d710^6'
'23M'
>>> trailing_zeros_to_powerof10(1)
'1'
>>> trailing_zeros_to_powerof10(0)
Expand All @@ -1156,32 +1152,15 @@ def trailing_zeros_to_powerof10(amount: int):
>>> trailing_zeros_to_powerof10(-100)
'-100'
"""
amount = str(amount)
zeros = 0
i = len(amount) - 1
while i >= 0 and amount[i] == "0":
zeros += 1
i -= 1
if len(amount) < len(f"{amount[: i+1]}\u00d710^{zeros}"):
return amount

m, prefix = metric_prefix(amount, 1000)
m = int(m) if m.is_integer() else f"{m:.1f}"
# print(m, type(m), m.is_integer(), int(m), f"{int(m) if m.is_integer() else m:.1f}")
exp = f"{m}{prefix}"
if len(exp) <= len(str(amount)):
return exp
else:
return f"{amount[: i+1]}\u00d710^{zeros}"


def roundify(amount: int, sfs: int = 2):
"""
Take a number and round it to 'sfs' significant figures.
>>> roundify(99)
99
>>> roundify(-99)
-99
>>> roundify(1111)
1100
>>> roundify(1999)
2000
"""
return round(amount, -int(floor(log10(abs(amount)))) + sfs - 1)
return str(amount)


@overload
Expand Down Expand Up @@ -1509,7 +1488,43 @@ def docstring_trim(docstring):
return "\n".join(trimmed)


def nice_size(size):
def metric_prefix(number: Union[int, float], base: int, text: bool = True) -> Tuple[float, str]:
"""
>>> metric_prefix(100, 1000)
(100.0, '')
>>> metric_prefix(999, 1000)
(999.0, '')
>>> metric_prefix(1000, 1000)
(1.0, 'K')
>>> metric_prefix(999, 1000, False)
(999.0, '0')
>>> metric_prefix(1000, 1000, False)
(1.0, '3')
>>> metric_prefix(1001, 1000)
(1.001, 'K')
>>> metric_prefix(1000000, 1000)
(1.0, 'M')
>>> metric_prefix(1000**10, 1000)
(1.0, 'Q')
>>> metric_prefix(1000**11, 1000)
(1000.0, 'Q')
"""
prefixes = ["", "K", "M", "G", "T", "P", "E", "Z", "Y", "R", "Q"]
if number < 0:
number = abs(number)
sign = -1
else:
sign = 1

for i, prefix in enumerate(prefixes):
if number < base:
return sign * float(number), prefix if text else str(i*3)
number /= base
else:
return sign * float(number) * base, prefix if text else str(i*3)


def nice_size(size: Union[float, int ,str]) -> str:
"""
Returns a readably formatted string with the size
Expand All @@ -1522,23 +1537,15 @@ def nice_size(size):
>>> nice_size(100000000)
'95.4 MB'
"""
words = ["bytes", "KB", "MB", "GB", "TB", "PB", "EB"]
prefix = ""
try:
size = float(size)
if size < 0:
size = abs(size)
prefix = "-"
except Exception:
except ValueError:
return "??? bytes"
for ind, word in enumerate(words):
step = 1024 ** (ind + 1)
if step > size:
size = size / float(1024**ind)
if word == "bytes": # No decimals for bytes
return "%s%d bytes" % (prefix, size)
return f"{prefix}{size:.1f} {word}"
return "??? bytes"
size, prefix = metric_prefix(size, 1024)
if prefix == "":
return "%d bytes" % size
else:
return f"{size:.1f} {prefix}B"


def size_to_bytes(size):
Expand Down

0 comments on commit 279c372

Please sign in to comment.