Bring back size_str text helper
authorChristian Herdtweck <christian.herdtweck@intra2net.com>
Mon, 29 Oct 2018 08:56:27 +0000 (09:56 +0100)
committerChristian Herdtweck <christian.herdtweck@intra2net.com>
Mon, 5 Nov 2018 11:21:54 +0000 (12:21 +0100)
Had been removed since it was not needed any more. Is needed again, so may
be relevant after all

src/text_helpers.py

index 668dd8b..89f60a7 100644 (file)
@@ -18,7 +18,8 @@
 #
 # Copyright (c) 2016-2018 Intra2net AG <info@intra2net.com>
 
-""" Functions for printing colored text using ANSI escape sequences
+"""
+Functions for printing colored text using ANSI escape sequences
 
 Not sure whether to save this as text_helpers.py or a shell_helpers.py or some
 other. Let's see what else could be added to any of those.
@@ -30,6 +31,13 @@ Functions might cause trouble when combined, e.g.::
 will show the text "and green" not in bold. May have to try using specific
 end-of-color or end-of-style escape sequences instead of 0 (reset-everything).
 
+See also: python package colorclass, a more professional version of this.
+
+Color unrelated functions:
+- head_and_tail: shows the first few and last few elements of an iterable that
+                 could potentially be pretty long
+- size_str: textual representation of data size
+
 References:
 * http://stackoverflow.com/questions/287871/print-in-terminal-with-colors-using-python
 * https://en.wikipedia.org/wiki/ANSI_escape_code
@@ -106,6 +114,44 @@ def head_and_tail(iterable, n_head=20, n_tail=20, n_elems=None,
             yield elem
 
 
+def size_str(byte_number, is_diff=False):
+    """ round byte_number to something easily human-readable like '1.5 GB'
+
+    :param bool is_diff: set to True to include a '+' or '-' in output;
+                         default: False
+    """
+
+    # constants
+    units = '', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y'
+    factor = 1024
+    thresh_add_comma = 10.   # below this, return 1.2G, above this return 12G
+
+    # prepare
+    if byte_number < 0:
+        sign_str = '-'
+    elif is_diff:
+        sign_str = '+'
+    else:
+        sign_str = ''
+    curr_fac = 1
+    curr_num = abs(float(byte_number))
+
+    # loop
+    for unit in units:
+        if curr_num > factor:
+            curr_num /= factor
+            continue
+        elif curr_num < thresh_add_comma and unit != 'B':   # e.g. 1.2G
+            return '{2}{0:.1f} {1}B'.format(curr_num, unit, sign_str)
+        else:   # e.g. 12G or 1B
+            return '{2}{0:d} {1}B'.format(int(round(curr_num)), unit, sign_str)
+
+    # have an impossible amount of data.  (>1024**4 GB)
+    # undo last "/factor" and show thousand-separator
+    return '{2}{0:,d} {1}B'.format(int(round(curr_num*factor)), units[-1],
+                                 sign_str)
+
+
 ###############################################################################
 # TEXT FORMATTING/COLORING
 ###############################################################################