Skip to content

Commit 2360e45

Browse files
committed
add custom bar symbols formatting
Signed-off-by: Stephen L. <[email protected]>
1 parent 50fc2d8 commit 2360e45

1 file changed

Lines changed: 64 additions & 2 deletions

File tree

tqdm/_tqdm.py

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,27 @@ def format_meter(n, total, elapsed, ncols=None, prefix='',
167167
-------
168168
out : Formatted meter and stats, ready to display.
169169
"""
170+
171+
def extract_symbols(s, start_tag, end_tag):
172+
"""
173+
Extract custom symbols enclosed by tags, with the first character being the separator.
174+
Eg, extract_symbols('before{start},1,2,3,4,#{end}after', '{start}', '{end}')
175+
176+
Returns
177+
-------
178+
out, out2 : list of symbols, input string without tagged part
179+
"""
180+
start = s.find(start_tag)
181+
start_content = start+len(start_tag)
182+
end_content = s.find(end_tag)
183+
end = end_content+len(end_tag)
184+
185+
sep = s[start_content:start_content+1]
186+
return s[start_content+1:end_content].split(sep), s[:start] + s[end:]
187+
188+
# Custom symbols variables
189+
c_symbols = None
190+
looping = False
170191

171192
# sanity check: total
172193
if total and n > total:
@@ -235,6 +256,22 @@ def format_meter(n, total, elapsed, ncols=None, prefix='',
235256
# 'bar': full_bar # replaced by procedure below
236257
}
237258

259+
# Custom symbols extraction
260+
for tag in ['bar_symbols', 'bar_symbols_ascii', 'bar_symbols_loop', 'bar_symbols_loop_ascii']:
261+
start_tag = '{' + tag + '}'
262+
end_tag = '{/' + tag + '}'
263+
# Check if tag is found in the template
264+
if start_tag in bar_format and end_tag in bar_format:
265+
# Get ascii symbols if ascii env, else unicode
266+
if (ascii and 'ascii' in tag) or (not ascii and not 'ascii' in tag):
267+
c_symbols, bar_format = extract_symbols(bar_format, start_tag, end_tag)
268+
# Looping symbol?
269+
if 'loop' in tag:
270+
looping = True
271+
# Need to clean all tags from template
272+
else:
273+
_, bar_format = extract_symbols(bar_format, start_tag, end_tag)
274+
238275
# Interpolate supplied bar format with the dict
239276
if '{bar}' in bar_format:
240277
# Format left/right sides of the bar, and format the bar
@@ -251,15 +288,40 @@ def format_meter(n, total, elapsed, ncols=None, prefix='',
251288
N_BARS = max(1, ncols - len(l_bar) - len(r_bar)) if ncols \
252289
else 10
253290

254-
# format bar depending on availability of unicode/ascii chars
255-
if ascii:
291+
# custom symbols format
292+
# need to provide both ascii and unicode versions of custom symbols,
293+
# eg, if ascii env but user provided only unicode symbols, then
294+
# will revert to default ascii bar.
295+
if c_symbols:
296+
# looping symbols: just update the symbol animation at each iteration
297+
if looping:
298+
# increment one step in the animation at each step
299+
bar = c_symbols[divmod(n, len(c_symbols))[1]]
300+
frac_bar = ''
301+
302+
bar_length = N_BARS # avoid the filling
303+
frac_bar_length = len(frac_bar)
304+
# normal progress symbols
305+
else:
306+
bar_length, frac_bar_length = divmod(
307+
int(frac * N_BARS * len(c_symbols)), len(c_symbols))
308+
309+
bar = c_symbols[-1] * bar_length # last symbol is always the filler
310+
frac_bar = c_symbols[frac_bar_length] if frac_bar_length \
311+
else ' '
312+
313+
# ascii format
314+
elif ascii:
315+
# get the remainder of the division of current fraction with number of symbols
316+
# this will tell us which symbol we should pick
256317
bar_length, frac_bar_length = divmod(
257318
int(frac * N_BARS * 10), 10)
258319

259320
bar = '#' * bar_length
260321
frac_bar = chr(48 + frac_bar_length) if frac_bar_length \
261322
else ' '
262323

324+
# unicode format (if available)
263325
else:
264326
bar_length, frac_bar_length = divmod(int(frac * N_BARS * 8), 8)
265327

0 commit comments

Comments
 (0)