Skip to content

Commit

Permalink
Merge pull request #1 from Erotemic/dev/morechunk
Browse files Browse the repository at this point in the history
display now reports chunksize
  • Loading branch information
Erotemic committed Sep 5, 2018
2 parents bf29dc5 + 7465a4e commit 295cd8e
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 27 deletions.
75 changes: 48 additions & 27 deletions progiter/progiter.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@
unicode_literals)
import sys
import time
import datetime
import collections
from math import log10, floor
import six
from collections import OrderedDict
import numbers
from collections import OrderedDict
from datetime import timedelta
from math import log10, floor

__all__ = [
'ProgIter',
Expand Down Expand Up @@ -84,8 +84,10 @@ def _infer_length(iterable):


class _TQDMCompat(object):
"""
Base class for ProgIter that implements a restricted TQDM Compatibility API
"""

# TQDM Compatibility API
@classmethod
def write(cls, s, file=None, end='\n', nolock=False):
""" simply writes to stdout """
Expand Down Expand Up @@ -174,6 +176,11 @@ def set_postfix_str(self, s='', refresh=True):


class _BackwardsCompat(object):
"""
Base class for ProgIter that maintains backwards compatibility with older
versions of the ProgIter API.
"""

# Backwards Compatibility API
@property
def length(self):
Expand All @@ -190,17 +197,6 @@ class ProgIter(_TQDMCompat, _BackwardsCompat):
"""
Prints progress as an iterator progresses
Note:
USE `tqdm` INSTEAD. The main difference between `ProgIter` and `tqdm`
is that ProgIter does not use threading where as `tqdm` does.
`ProgIter` is simpler than `tqdm` and thus more stable in certain
circumstances. However, `tqdm` is recommended for the majority of use
cases.
Note:
The API on `ProgIter` will change to become inter-compatible with
`tqdm`.
Attributes:
iterable (iterable): An iterable iterable
desc (str): description label to show with progress
Expand All @@ -217,23 +213,35 @@ class ProgIter(_TQDMCompat, _BackwardsCompat):
initial (int): starting index offset (defaults to 0)
stream (file): defaults to sys.stdout
enabled (bool): if False nothing happens.
chunksize (int): indicates that each iteration processes a batch of
this size. Iteration rate is displayed in terms of single-items.
verbose (int): verbosity mode
0 - no verbosity,
1 - verbosity with clearline=True and adjust=True
2 - verbosity without clearline=False and adjust=True
3 - verbosity without clearline=False and adjust=False
Note:
Either use ProgIter in a with statement or call prog.end() at the end
of the computation if there is a possibility that the entire iterable
may not be exhausted.
Note:
ProgIter is an alternative to `tqdm`. The main difference between
`ProgIter` and `tqdm` is that ProgIter does not use threading where as
`tqdm` does. `ProgIter` is simpler than `tqdm` and thus more stable in
certain circumstances. However, `tqdm` is recommended for the majority
of use cases.
Note:
The `ProgIter` API will change to become inter-compatible with `tqdm`.
SeeAlso:
tqdm - https://pypi.python.org/pypi/tqdm
Reference:
http://datagenetics.com/blog/february12017/index.html
Notes:
Either use ProgIter in a with statement or call prog.end() at the end
of the computation if there is a possibility that the entire iterable
may not be exhausted.
Example:
>>> # doctest: +SKIP
>>> import ubelt as ub
Expand Down Expand Up @@ -265,6 +273,9 @@ def __init__(self, iterable=None, desc=None, total=None, freq=1,
elif verbose >= 3: # nocover
enabled, clearline, adjust = 1, 0, 0

# Potential new additions to the API
self._microseconds = kwargs.pop('microseconds', False)

# --- Accept the tqdm api ---
if kwargs:
stream = kwargs.pop('file', stream)
Expand All @@ -284,7 +295,7 @@ def __init__(self, iterable=None, desc=None, total=None, freq=1,
initial = kwargs.pop('start', initial)
if kwargs:
raise ValueError('ProgIter given unknown kwargs {}'.format(kwargs))
# ----------------------------
# ----------------------------

if stream is None:
stream = sys.stdout
Expand All @@ -305,6 +316,7 @@ def __init__(self, iterable=None, desc=None, total=None, freq=1,
self.extra = ''
self.started = False
self.finished = False

self._reset_internals()

def __call__(self, iterable):
Expand Down Expand Up @@ -340,7 +352,10 @@ def __iter__(self):
def set_extra(self, extra):
"""
specify a custom info appended to the end of the next message
TODO: come up with a better name and rename
TODO:
- [ ] extra is a bad name; come up with something better and rename
Example:
>>> import ubelt as ub
Expand Down Expand Up @@ -558,7 +573,7 @@ def _build_message_template(self):
if self.chunksize and not length_unknown:
msg_body = [
('{desc}'),
(' {percent:03.2f}% of '),
(' {percent:03.2f}% of ' + str(self.chunksize) + 'x'),
('?' if length_unknown else six.text_type(self.total)),
('...'),
]
Expand Down Expand Up @@ -608,10 +623,16 @@ def format_message(self):
if self._est_seconds_left is None:
eta = '?'
else:
eta = six.text_type(datetime.timedelta(
seconds=int(self._est_seconds_left)))
total = six.text_type(datetime.timedelta(
seconds=int(self._total_seconds)))
if self._microseconds:
eta = six.text_type(timedelta(seconds=self._est_seconds_left))
else:
eta = six.text_type(timedelta(seconds=int(self._est_seconds_left)))

if self._microseconds:
total = six.text_type(timedelta(seconds=self._total_seconds))
else:
total = six.text_type(timedelta(seconds=int(self._total_seconds)))

# similar to tqdm.format_meter
if self.chunksize and self.total:
msg = self._msg_fmtstr.format(
Expand Down
7 changes: 7 additions & 0 deletions whatsnew.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Version: 0.0.3
--------------
* Can now inform ProgIter of chunksize to get Hz in items per second instead of chunks per second.

Version: 0.0.1
--------------
* Initial version ported from ubelt

0 comments on commit 295cd8e

Please sign in to comment.