Skip to content

Commit d731e79

Browse files
committed
clean up progress bar
1 parent 1c7b78d commit d731e79

File tree

2 files changed

+95
-63
lines changed

2 files changed

+95
-63
lines changed

pymc/progressbar.py

Lines changed: 90 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -9,70 +9,104 @@
99
import uuid
1010
try:
1111
from IPython.core.display import HTML, Javascript, display
12-
13-
have_ipython = True
1412
except ImportError:
15-
have_ipython = False
13+
pass
1614

17-
class ProgressBar:
18-
def __init__(self, iterations):
19-
self.iterations = iterations
20-
self.prog_bar = '[]'
21-
self.fill_char = '*'
22-
self.width = 40
23-
self.__update_amount(0)
15+
__all__ = ['progress_bar']
2416

17+
class ProgressBar(object):
18+
def __init__(self, iterations, animation_interval = .5):
19+
self.iterations = iterations
2520
self.start = time.time()
2621
self.last = 0
27-
if have_ipython:
28-
self.animate = self.animate_ipython
29-
self.divid = str(uuid.uuid4())
30-
self.sec_id = str(uuid.uuid4())
31-
32-
pb = HTML(
33-
"""
34-
<div style="float: left; border: 1px solid black; width:500px">
35-
<div id="%s" style="background-color:blue; width:0%%">&nbsp;</div>
36-
</div>
37-
<label id="%s" style="padding-left: 10px;" text = ""/>
38-
""" % (self.divid,self.sec_id))
39-
display(pb)
40-
else:
41-
self.animate = self.animate_noipython
42-
43-
def animate_noipython(self, iter):
44-
if sys.platform.lower().startswith('win'):
45-
print(self, '\r', end='')
46-
else:
47-
print(self)
48-
self.update_iteration(iter)
49-
50-
def animate_ipython(self, iter):
51-
elapsed = time.time() - self.start
52-
iter = iter + 1
53-
if elapsed - self.last > .5 or iter == self.iterations:
54-
self.last = elapsed
22+
self.animation_interval = animation_interval
5523

56-
self.update_iteration(iter)
57-
fraction = int(100*iter/float(self.iterations))
24+
def percentage(self, i):
25+
return 100*i/float(self.iterations)
5826

59-
display(Javascript("$('div#%s').width('%i%%')" % (self.divid, fraction)))
60-
display(Javascript("$('label#%s').text('%i%% in %.1f sec')" % (self.sec_id, fraction, round(elapsed, 1))))
27+
def update(self, i):
28+
elapsed = time.time() - self.start
29+
i = i + 1
30+
31+
if elapsed - self.last > self.animation_interval or i == self.iterations:
32+
self.animate(i+1, elapsed)
33+
self.last = elapsed
34+
35+
class TextProgressBar(ProgressBar):
36+
def __init__(self, iterations, printer):
37+
self.fill_char = '-'
38+
self.width = 40
39+
self.printer = printer
6140

62-
def update_iteration(self, elapsed_iter):
63-
self.__update_amount((elapsed_iter / float(self.iterations)) * 100.0)
64-
self.prog_bar += ' %d of %s complete' % (elapsed_iter, self.iterations)
41+
ProgressBar.__init__(self, iterations)
42+
self.update(0)
6543

44+
def animate(self, i, elapsed):
45+
self.printer(self.progbar(i, elapsed))
6646

67-
def __update_amount(self, new_amount):
68-
percent_done = int(round((new_amount / 100.0) * 100.0))
47+
48+
def progbar(self,i, elapsed):
49+
bar = self.bar(self.percentage(i))
50+
return "[%s] %i of %i complete in %.1f sec" % (bar, i, self.iterations, round(elapsed,1))
51+
52+
def bar(self, percent):
6953
all_full = self.width - 2
70-
num_hashes = int(round((percent_done / 100.0) * all_full))
71-
self.prog_bar = '[' + self.fill_char * num_hashes + ' ' * (all_full - num_hashes) + ']'
72-
pct_place = (len(self.prog_bar) / 2) - len(str(percent_done))
73-
pct_string = '%d%%' % percent_done
74-
self.prog_bar = self.prog_bar[0:pct_place] + \
75-
(pct_string + self.prog_bar[pct_place + len(pct_string):])
76-
77-
def __str__(self):
78-
return str(self.prog_bar)
54+
num_hashes = int(percent/100 * all_full)
55+
56+
bar = self.fill_char * num_hashes + ' ' * (all_full - num_hashes)
57+
58+
info = '%d%%' % percent
59+
loc = ( len(bar) - len(info) )/2
60+
return replace_at(bar, info, loc, loc + len(info))
61+
62+
63+
def replace_at(str, new, start, stop):
64+
return str[:start] + new + str[stop:]
65+
66+
def consoleprint(s):
67+
if sys.platform.lower().startswith('win'):
68+
print(s, '\r', end='')
69+
else:
70+
print(s)
71+
72+
def ipythonprint(s):
73+
print('\r', s, end='')
74+
sys.stdout.flush()
75+
76+
class IPythonNotebookPB(ProgressBar):
77+
def __init__(self, iterations):
78+
self.divid = str(uuid.uuid4())
79+
self.sec_id = str(uuid.uuid4())
80+
81+
pb = HTML(
82+
"""
83+
<div style="float: left; border: 1px solid black; width:500px">
84+
<div id="%s" style="background-color:blue; width:0%%">&nbsp;</div>
85+
</div>
86+
<label id="%s" style="padding-left: 10px;" text = ""/>
87+
""" % (self.divid,self.sec_id))
88+
display(pb)
89+
90+
ProgressBar.__init__(self, iterations)
91+
92+
def animate(self, i, elapsed):
93+
percentage = int(self.fraction(i))
94+
95+
display(Javascript("$('div#%s').width('%i%%')" % (self.divid, percentage)))
96+
display(Javascript("$('label#%s').text('%i%% in %.1f sec')" % (self.sec_id, fraction, round(elapsed, 1))))
97+
98+
def run_from_ipython():
99+
try:
100+
__IPYTHON__
101+
return True
102+
except NameError:
103+
return False
104+
105+
def progress_bar(iters):
106+
if run_from_ipython():
107+
if in_notebook():
108+
return NotebookProgressBar(iters)
109+
else:
110+
return IPythonConsolePB(iters, ipythonprint)
111+
else:
112+
return TextProgressBar(iters, consoleprint)

pymc/sample.py

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@
44
from time import time
55
from core import *
66
import step_methods
7-
from progressbar import ProgressBar
7+
from progressbar import progress_bar
88

99
__all__ = ['sample', 'psample']
1010

1111
@withmodel
12-
def sample(model, draws, step, start = None, trace = None, progress_bar = True):
12+
def sample(model, draws, step, start = None, trace = None, track_progress = True):
1313
"""
1414
Draw a number of samples using the given step method.
1515
Multiple step methods supported via compound step method
@@ -51,15 +51,13 @@ def sample(model, draws, step, start = None, trace = None, progress_bar = True):
5151
except TypeError:
5252
pass
5353

54-
55-
56-
progress = ProgressBar(draws)
54+
progress = progress_bar(draws)
5755

5856
for i in xrange(draws):
5957
point = step.step(point)
6058
trace = trace.record(point)
61-
if progress_bar:
62-
progress.animate(i)
59+
if track_progress:
60+
progress.update(i)
6361

6462
return trace
6563

0 commit comments

Comments
 (0)