Skip to content

Commit

Permalink
add unit_pre and unit_prefixes
Browse files Browse the repository at this point in the history
- fixes #825 with `unit_pre=" "`
- fixes #953 with `unit_prefixes="bytes"` or `"IEEE1541"`
  • Loading branch information
casperdcl committed Oct 27, 2020
1 parent 4c1f17a commit 35ba023
Show file tree
Hide file tree
Showing 6 changed files with 122 additions and 73 deletions.
27 changes: 17 additions & 10 deletions README.rst
Expand Up @@ -407,15 +407,6 @@ Parameters
* disable : bool, optional
Whether to disable the entire progressbar wrapper
[default: False]. If set to None, disable on non-TTY.
* unit : str, optional
String that will be used to define the unit of each iteration
[default: it].
* unit_scale : bool or int or float, optional
If 1 or True, the number of iterations will be reduced/scaled
automatically and a metric prefix following the
International System of Units standard will be added
(kilo, mega, etc.) [default: False]. If any other non-zero
number, will scale ``total`` and ``n``.
* dynamic_ncols : bool, optional
If set, constantly alters ``ncols`` and ``nrows`` to the
environment (allowing for window resizes) [default: False].
Expand Down Expand Up @@ -447,8 +438,24 @@ Parameters
* postfix : dict or ``*``, optional
Specify additional stats to display at the end of the bar.
Calls ``set_postfix(**postfix)`` if possible (dict).
* unit : str, optional
String that will be used to define the unit of each iteration
[default: it].
* unit_scale : bool or int or float, optional
If 1 or True, the number of iterations will be reduced/scaled
automatically and a metric prefix following the
International System of Units standard will be added
(kilo, mega, etc.) [default: False]. If any other non-zero
number, will scale ``total`` and ``n``.
* unit_divisor : float, optional
[default: 1000], ignored unless ``unit_scale`` is True.
* unit_pre : str, optional
Pre-prefix [default: ''].
* unit_prefixes : list or str, optional
Prefixes (default: [''] + list('kMGTPEZY')).
Use ``"IEEE1541"`` or ``"bytes"`` as a shortcut to override:
unit='B', unit_scale=True, unit_divisor=1024, unit_pre=' ',
unit_prefixes=[''] + [i + 'i' for i in 'KMGTPEZY'].
* write_bytes : bool, optional
If (default: None) and ``file`` is unspecified,
bytes will be written in Python 2. If ``True`` will also write
Expand All @@ -474,7 +481,7 @@ Extra CLI Options
used when ``delim`` is specified.
* bytes : bool, optional
If true, will count bytes, ignore ``delim``, and default
``unit_scale`` to True, ``unit_divisor`` to 1024, and ``unit`` to 'B'.
``unit_prefixes`` to ``"IEEE1541"``.
* tee : bool, optional
If true, passes ``stdin`` to both ``stderr`` and ``stdout``.
* update : bool, optional
Expand Down
4 changes: 2 additions & 2 deletions setup.cfg
Expand Up @@ -2,8 +2,8 @@
universal = 1

[flake8]
ignore = W503,W504,E722
max_line_length = 80
ignore = W503,W504,E203,E722
max_line_length = 88
exclude = .asv,.tox,.ipynb_checkpoints,build,dist,.git,__pycache__

[tool:pytest]
Expand Down
6 changes: 2 additions & 4 deletions tqdm/cli.py
Expand Up @@ -139,7 +139,7 @@ def posix_pipe(fin, fout, delim=b'\\n', buf_size=256,
used when `delim` is specified.
bytes : bool, optional
If true, will count bytes, ignore `delim`, and default
`unit_scale` to True, `unit_divisor` to 1024, and `unit` to 'B'.
`unit_prefixes` to `"IEEE1541"`.
tee : bool, optional
If true, passes `stdin` to both `stderr` and `stdout`.
update : bool, optional
Expand Down Expand Up @@ -289,9 +289,7 @@ def write(x):
fp_write(x)
stdout_write(x)
if delim_per_char:
tqdm_args.setdefault('unit', 'B')
tqdm_args.setdefault('unit_scale', True)
tqdm_args.setdefault('unit_divisor', 1024)
tqdm_args.setdefault('unit_prefixes', 'IEEE1541')
log.debug(tqdm_args)
with tqdm(**tqdm_args) as t:
posix_pipe(stdin, stdout, '', buf_size, t.update)
Expand Down
4 changes: 2 additions & 2 deletions tqdm/completion.sh
Expand Up @@ -5,14 +5,14 @@ _tqdm(){
prv="${COMP_WORDS[COMP_CWORD - 1]}"

case ${prv} in
--bar_format|--buf_size|--colour|--comppath|--delim|--desc|--initial|--lock_args|--manpath|--maxinterval|--mininterval|--miniters|--ncols|--nrows|--position|--postfix|--smoothing|--total|--unit|--unit_divisor)
--bar_format|--buf_size|--colour|--comppath|--delim|--desc|--initial|--lock_args|--manpath|--maxinterval|--mininterval|--miniters|--ncols|--nrows|--position|--postfix|--smoothing|--total|--unit|--unit_divisor|--unit_pre)
# await user input
;;
"--log")
COMPREPLY=($(compgen -W 'CRITICAL FATAL ERROR WARN WARNING INFO DEBUG NOTSET' -- ${cur}))
;;
*)
COMPREPLY=($(compgen -W '--ascii --bar_format --buf_size --bytes --colour --comppath --delim --desc --disable --dynamic_ncols --help --initial --leave --lock_args --log --manpath --maxinterval --mininterval --miniters --ncols --nrows --null --position --postfix --smoothing --tee --total --unit --unit_divisor --unit_scale --update --update_to --version --write_bytes -h -v' -- ${cur}))
COMPREPLY=($(compgen -W '--ascii --bar_format --buf_size --bytes --colour --comppath --delim --desc --disable --dynamic_ncols --help --initial --leave --lock_args --log --manpath --maxinterval --mininterval --miniters --ncols --nrows --null --position --postfix --smoothing --tee --total --unit --unit_divisor --unit_pre --unit_prefixes --unit_scale --update --update_to --version --write_bytes -h -v' -- ${cur}))
;;
esac
}
Expand Down
103 changes: 66 additions & 37 deletions tqdm/std.py
Expand Up @@ -17,6 +17,7 @@
# native libraries
from contextlib import contextmanager
from datetime import datetime, timedelta
from functools import partial
from numbers import Number
from time import time
from warnings import warn
Expand Down Expand Up @@ -226,7 +227,7 @@ class tqdm(Comparable):
monitor = None

@staticmethod
def format_sizeof(num, suffix='', divisor=1000):
def format_sizeof(num, divisor=1000, pre='', prefixes=None):
"""
Formats a number (greater than unity) with SI Order of Magnitude
prefixes.
Expand All @@ -235,25 +236,30 @@ def format_sizeof(num, suffix='', divisor=1000):
----------
num : float
Number ( >= 1) to format.
suffix : str, optional
Post-postfix [default: ''].
divisor : float, optional
Divisor between prefixes [default: 1000].
Divisor between postfixes [default: 1000].
pre : str, optional
Pre-prefix [default: ''].
prefixes : list, optional
Prefixes (default: [''] + list('kMGTPEZY')).
Returns
-------
out : str
Number with Order of Magnitude SI unit postfix.
"""
for unit in ['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z']:
prefixes = prefixes or [''] + list('kMGTPEZY')
p = ''
for unit in prefixes[:-1]:
if abs(num) < 999.5:
if abs(num) < 99.95:
if abs(num) < 9.995:
return '{0:1.2f}'.format(num) + unit + suffix
return '{0:2.1f}'.format(num) + unit + suffix
return '{0:3.0f}'.format(num) + unit + suffix
return '{0:1.2f}'.format(num) + p + unit
return '{0:2.1f}'.format(num) + p + unit
return '{0:3.0f}'.format(num) + p + unit
num /= divisor
return '{0:3.1f}Y'.format(num) + suffix
p = pre
return '{0:3.1f}'.format(num) + pre + prefixes[-1]

@staticmethod
def format_interval(t):
Expand Down Expand Up @@ -342,6 +348,7 @@ def print_status(s):
def format_meter(n, total, elapsed, ncols=None, prefix='', ascii=False,
unit='it', unit_scale=False, rate=None, bar_format=None,
postfix=None, unit_divisor=1000, initial=0, colour=None,
unit_pre='', unit_prefixes=None,
**extra_kwargs):
"""
Return a string-based progress bar given some parameters
Expand All @@ -367,13 +374,6 @@ def format_meter(n, total, elapsed, ncols=None, prefix='', ascii=False,
If not set, use unicode (smooth blocks) to fill the meter
[default: False]. The fallback is to use ASCII characters
" 123456789#".
unit : str, optional
The iteration unit [default: 'it'].
unit_scale : bool or int or float, optional
If 1 or True, the number of iterations will be printed with an
appropriate SI metric prefix (k = 10^3, M = 10^6, etc.)
[default: False]. If any other non-zero number, will scale
`total` and `n`.
rate : float, optional
Manual override for iteration rate.
If [default: None], uses n/elapsed.
Expand All @@ -396,12 +396,23 @@ def format_meter(n, total, elapsed, ncols=None, prefix='', ascii=False,
Note: postfix is usually a string (not a dict) for this method,
and will if possible be set to postfix = ', ' + postfix.
However other types are supported (#382).
unit_divisor : float, optional
[default: 1000], ignored unless `unit_scale` is True.
initial : int or float, optional
The initial counter value [default: 0].
colour : str, optional
Bar colour (e.g. 'green', '#00ff00').
unit : str, optional
The iteration unit [default: 'it'].
unit_scale : bool or int or float, optional
If 1 or True, the number of iterations will be printed with an
appropriate SI metric prefix (k = 10^3, M = 10^6, etc.)
[default: False]. If any other non-zero number, will scale
`total` and `n`.
unit_divisor : float, optional
[default: 1000], ignored unless `unit_scale` is True.
unit_pre : str, optional
Pre-prefix [default: ''].
unit_prefixes : list, optional
Prefixes (default: [''] + list('kMGTPEZY')).
Returns
-------
Expand All @@ -428,7 +439,8 @@ def format_meter(n, total, elapsed, ncols=None, prefix='', ascii=False,
if rate is None and elapsed:
rate = (n - initial) / elapsed
inv_rate = 1 / rate if rate else None
format_sizeof = tqdm.format_sizeof
format_sizeof = partial(tqdm.format_sizeof, divisor=unit_divisor,
pre=unit_pre, prefixes=unit_prefixes)
rate_noinv_fmt = ((format_sizeof(rate) if unit_scale else
'{0:5.2f}'.format(rate))
if rate else '?') + unit + '/s'
Expand All @@ -438,9 +450,8 @@ def format_meter(n, total, elapsed, ncols=None, prefix='', ascii=False,
rate_fmt = rate_inv_fmt if inv_rate and inv_rate > 1 else rate_noinv_fmt

if unit_scale:
n_fmt = format_sizeof(n, divisor=unit_divisor)
total_fmt = format_sizeof(total, divisor=unit_divisor) \
if total is not None else '?'
n_fmt = format_sizeof(n)
total_fmt = format_sizeof(total) if total is not None else '?'
else:
n_fmt = str(n)
total_fmt = str(total) if total is not None else '?'
Expand Down Expand Up @@ -475,7 +486,7 @@ def format_meter(n, total, elapsed, ncols=None, prefix='', ascii=False,
# slight extension of self.format_dict
n=n, n_fmt=n_fmt, total=total, total_fmt=total_fmt,
elapsed=elapsed_str, elapsed_s=elapsed,
ncols=ncols, desc=prefix or '', unit=unit,
ncols=ncols, desc=prefix or '', unit=unit, unit_pre=unit_pre,
rate=inv_rate if inv_rate and inv_rate > 1 else rate,
rate_fmt=rate_fmt, rate_noinv=rate,
rate_noinv_fmt=rate_noinv_fmt, rate_inv=inv_rate,
Expand Down Expand Up @@ -835,7 +846,7 @@ def __init__(self, iterable=None, desc=None, total=None, leave=True,
unit_scale=False, dynamic_ncols=False, smoothing=0.3,
bar_format=None, initial=0, position=None, postfix=None,
unit_divisor=1000, write_bytes=None, lock_args=None,
nrows=None, colour=None,
nrows=None, colour=None, unit_pre='', unit_prefixes=None,
gui=False, **kwargs):
"""
Parameters
Expand Down Expand Up @@ -888,15 +899,6 @@ def __init__(self, iterable=None, desc=None, total=None, leave=True,
disable : bool, optional
Whether to disable the entire progressbar wrapper
[default: False]. If set to None, disable on non-TTY.
unit : str, optional
String that will be used to define the unit of each iteration
[default: it].
unit_scale : bool or int or float, optional
If 1 or True, the number of iterations will be reduced/scaled
automatically and a metric prefix following the
International System of Units standard will be added
(kilo, mega, etc.) [default: False]. If any other non-zero
number, will scale `total` and `n`.
dynamic_ncols : bool, optional
If set, constantly alters `ncols` and `nrows` to the
environment (allowing for window resizes) [default: False].
Expand Down Expand Up @@ -928,8 +930,24 @@ def __init__(self, iterable=None, desc=None, total=None, leave=True,
postfix : dict or *, optional
Specify additional stats to display at the end of the bar.
Calls `set_postfix(**postfix)` if possible (dict).
unit : str, optional
String that will be used to define the unit of each iteration
[default: it].
unit_scale : bool or int or float, optional
If 1 or True, the number of iterations will be reduced/scaled
automatically and a metric prefix following the
International System of Units standard will be added
(kilo, mega, etc.) [default: False]. If any other non-zero
number, will scale `total` and `n`.
unit_divisor : float, optional
[default: 1000], ignored unless `unit_scale` is True.
unit_pre : str, optional
Pre-prefix [default: ''].
unit_prefixes : list or str, optional
Prefixes (default: [''] + list('kMGTPEZY')).
Use `"IEEE1541"` or `"bytes"` as a shortcut to override:
unit='B', unit_scale=True, unit_divisor=1024, unit_pre=' ',
unit_prefixes=[''] + [i + 'i' for i in 'KMGTPEZY'].
write_bytes : bool, optional
If (default: None) and `file` is unspecified,
bytes will be written in Python 2. If `True` will also write
Expand Down Expand Up @@ -1055,9 +1073,19 @@ def __init__(self, iterable=None, desc=None, total=None, leave=True,
self.dynamic_miniters = dynamic_miniters
self.ascii = ascii
self.disable = disable
self.unit = unit
self.unit_scale = unit_scale
self.unit_divisor = unit_divisor
if hasattr(unit_prefixes, "upper") and unit_prefixes.upper() in \
["BYTES", "IEEE1541"]:
self.unit = 'B'
self.unit_scale = True
self.unit_divisor = 1024
self.unit_pre = ' '
self.unit_prefixes = [''] + [i + 'i' for i in 'KMGTPEZY']
else:
self.unit = unit
self.unit_scale = unit_scale
self.unit_divisor = unit_divisor
self.unit_pre = unit_pre
self.unit_prefixes = unit_prefixes
self.initial = initial
self.lock_args = lock_args
self.gui = gui
Expand Down Expand Up @@ -1486,7 +1514,8 @@ def format_dict(self):
if hasattr(self, 'start_t') else 0,
ncols=ncols, nrows=nrows,
prefix=self.desc, ascii=self.ascii, unit=self.unit,
unit_scale=self.unit_scale,
unit_scale=self.unit_scale, unit_pre=self.unit_pre,
unit_prefixes=self.unit_prefixes,
rate=1 / self.avg_time if self.avg_time else None,
bar_format=self.bar_format, postfix=self.postfix,
unit_divisor=self.unit_divisor, initial=self.initial,
Expand Down
51 changes: 33 additions & 18 deletions tqdm/tqdm.1
Expand Up @@ -124,22 +124,6 @@ If set to None, disable on non\-TTY.
.RS
.RE
.TP
.B \-\-unit=\f[I]unit\f[]
str, optional.
String that will be used to define the unit of each iteration [default:
it].
.RS
.RE
.TP
.B \-\-unit\-scale=\f[I]unit_scale\f[]
bool or int or float, optional.
If 1 or True, the number of iterations will be reduced/scaled
automatically and a metric prefix following the International System of
Units standard will be added (kilo, mega, etc.) [default: False].
If any other non\-zero number, will scale \f[C]total\f[] and \f[C]n\f[].
.RS
.RE
.TP
.B \-\-dynamic\-ncols
bool, optional.
If set, constantly alters \f[C]ncols\f[] and \f[C]nrows\f[] to the
Expand Down Expand Up @@ -196,12 +180,44 @@ Calls \f[C]set_postfix(**postfix)\f[] if possible (dict).
.RS
.RE
.TP
.B \-\-unit=\f[I]unit\f[]
str, optional.
String that will be used to define the unit of each iteration [default:
it].
.RS
.RE
.TP
.B \-\-unit\-scale=\f[I]unit_scale\f[]
bool or int or float, optional.
If 1 or True, the number of iterations will be reduced/scaled
automatically and a metric prefix following the International System of
Units standard will be added (kilo, mega, etc.) [default: False].
If any other non\-zero number, will scale \f[C]total\f[] and \f[C]n\f[].
.RS
.RE
.TP
.B \-\-unit\-divisor=\f[I]unit_divisor\f[]
float, optional.
[default: 1000], ignored unless \f[C]unit_scale\f[] is True.
.RS
.RE
.TP
.B \-\-unit\-pre=\f[I]unit_pre\f[]
str, optional.
Pre\-prefix [default: \[aq]\[aq]].
.RS
.RE
.TP
.B \-\-unit\-prefixes=\f[I]unit_prefixes\f[]
list or str, optional.
Prefixes (default: [\[aq]\[aq]] + list(\[aq]kMGTPEZY\[aq])).
Use \f[C]"IEEE1541"\f[] or \f[C]"bytes"\f[] as a shortcut to override:
unit=\[aq]B\[aq], unit_scale=True, unit_divisor=1024, unit_pre=\[aq]
\[aq], unit_prefixes=[\[aq]\[aq]] + [i + \[aq]i\[aq] for i in
\[aq]KMGTPEZY\[aq]].
.RS
.RE
.TP
.B \-\-write\-bytes
bool, optional.
If (default: None) and \f[C]file\f[] is unspecified, bytes will be
Expand Down Expand Up @@ -253,8 +269,7 @@ specified.
.B \-\-bytes
bool, optional.
If true, will count bytes, ignore \f[C]delim\f[], and default
\f[C]unit_scale\f[] to True, \f[C]unit_divisor\f[] to 1024, and
\f[C]unit\f[] to \[aq]B\[aq].
\f[C]unit_prefixes\f[] to \f[C]"IEEE1541"\f[].
.RS
.RE
.TP
Expand Down

0 comments on commit 35ba023

Please sign in to comment.