Merge pull request #103 from jric/master

Ability to update progress bar in non-linear fashion.
This commit is contained in:
Jason Piper
2014-03-14 11:26:30 +00:00
4 changed files with 80 additions and 31 deletions
+6
View File
@@ -1,5 +1,11 @@
.idea
.project
.settings
.pydevproject
MANIFEST
*.pyc
.tox
build/
clint.egg-info/
dist/
+1
View File
@@ -29,3 +29,4 @@ Patches and Suggestions
- Justin Barber <barber.justin (at) gmail>
- Dmitry Medvinsky
- Eric Anderson
- Joshua Richardson
+66 -31
View File
@@ -33,43 +33,78 @@ ETA_INTERVAL = 1
#How many intervals (excluding the current one) to calculate the simple moving average
ETA_SMA_WINDOW = 9
def bar(it, label='', width=32, hide=HIDE_DEFAULT, empty_char=BAR_EMPTY_CHAR, filled_char=BAR_FILLED_CHAR, expected_size=None, every=1):
"""Progress iterator. Wrap your iterables with it."""
def _show(_i):
if (time.time() - bar.etadelta) > ETA_INTERVAL:
bar.etadelta = time.time()
bar.ittimes = bar.ittimes[-ETA_SMA_WINDOW:]+[-(bar.start-time.time())/(_i+1)]
bar.eta = sum(bar.ittimes)/float(len(bar.ittimes)) * (count-_i)
bar.etadisp = time.strftime('%H:%M:%S', time.gmtime(bar.eta))
x = int(width*_i/count)
if not hide:
if ((_i % every)==0 or # True every "every" updates
(_i == count)): # And when we're done
class Bar(object):
def __enter__(self):
return self
def __exit__(self, exc_type, exc_val, exc_tb):
self.done()
return False # we're not surpressing exceptions
def __init__(self, label='', width=32, hide=None, empty_char=BAR_EMPTY_CHAR,
filled_char=BAR_FILLED_CHAR, expected_size=None, every=1):
self.label = label
self.width = width
self.hide = hide
if hide is None:
try:
self.hide = not STREAM.isatty()
except AttributeError: # output does not support isatty()
self.hide = True
self.empty_char = empty_char
self.filled_char = filled_char
self.expected_size = expected_size
self.every = every
self.start = time.time()
self.ittimes = []
self.eta = 0
self.etadelta = time.time()
self.etadisp = time.strftime('%H:%M:%S', time.gmtime(self.eta))
if (self.expected_size):
self.show(0)
def show(self, progress, count=None):
if count is not None:
self.expected_size = count
if self.expected_size is None:
raise Exception("expected_size not initialized")
if (time.time() - self.etadelta) > ETA_INTERVAL:
self.etadelta = time.time()
self.ittimes = \
self.ittimes[-ETA_SMA_WINDOW:]+\
[-(self.start-time.time())/(progress+1)]
self.eta = \
sum(self.ittimes)/float(len(self.ittimes)) * \
(self.expected_size-progress)
self.etadisp = time.strftime('%H:%M:%S', time.gmtime(self.eta))
x = int(self.width*progress/self.expected_size)
if not self.hide:
if ((progress % self.every)==0 or # True every "every" updates
(progress == self.expected_size)): # And when we're done
STREAM.write(BAR_TEMPLATE % (
label, filled_char*x, empty_char*(width-x), _i, count, bar.etadisp))
self.label, self.filled_char*x,
self.empty_char*(self.width-x), progress,
self.expected_size, self.etadisp))
STREAM.flush()
count = len(it) if expected_size is None else expected_size
bar.start = time.time()
bar.ittimes = []
bar.eta = 0
bar.etadelta = time.time()
bar.etadisp = time.strftime('%H:%M:%S', time.gmtime(bar.eta))
if count:
_show(0)
for i, item in enumerate(it):
yield item
_show(i+1)
if not hide:
def done(self):
if not self.hide:
STREAM.write('\n')
STREAM.flush()
def bar(it, label='', width=32, hide=HIDE_DEFAULT, empty_char=BAR_EMPTY_CHAR, filled_char=BAR_FILLED_CHAR, expected_size=None, every=1):
"""Progress iterator. Wrap your iterables with it."""
count = len(it) if expected_size is None else expected_size
with Bar(label=label, width=width, hide=hide, empty_char=BAR_EMPTY_CHAR,
filled_char=BAR_FILLED_CHAR, expected_size=count, every=every) \
as bar:
for i, item in enumerate(it):
yield item
bar.show(i+1)
def dots(it, label='', hide=HIDE_DEFAULT, every=1):
"""Progress iterator. Prints a dot for each item being iterated"""
+7
View File
@@ -14,6 +14,13 @@ from clint.textui import progress
if __name__ == '__main__':
for i in progress.bar(range(100)):
sleep(random() * 0.2)
with progress.Bar(label="nonlinear", expected_size=10) as bar:
last_val = 0
for val in (1,2,3,9,10):
sleep(2 * (val - last_val))
bar.show(val)
last_val = val
for i in progress.dots(range(100)):
sleep(random() * 0.2)