Contact
CoCalc Logo Icon
StoreFeaturesDocsShareSupport News AboutSign UpSign In
| Download
Path: tqdm / _tqdm.py
Views: 658
1
"""
2
Customisable progressbar decorator for iterators.
3
Includes a default (x)range iterator printing to stderr.
4
5
Usage:
6
>>> from tqdm import trange[, tqdm]
7
>>> for i in trange(10): #same as: for i in tqdm(xrange(10))
8
... ...
9
"""
10
from __future__ import absolute_import
11
# future division is important to divide integers and get as
12
# a result precise floating numbers (instead of truncated int)
13
from __future__ import division
14
# import compatibility functions and utilities
15
from ._utils import _supports_unicode, _environ_cols_wrapper, _range, _unich, \
16
_term_move_up, _unicode, WeakSet
17
import sys
18
from time import time
19
20
21
__author__ = {"github.com/": ["noamraph", "obiwanus", "kmike", "hadim",
22
"casperdcl", "lrq3000"]}
23
__all__ = ['tqdm', 'trange',
24
'TqdmTypeError', 'TqdmKeyError', 'TqdmDeprecationWarning']
25
26
27
class TqdmTypeError(TypeError):
28
pass
29
30
31
class TqdmKeyError(KeyError):
32
pass
33
34
35
class TqdmDeprecationWarning(Exception):
36
# not suppressed if raised
37
def __init__(self, msg, fp_write=None, *a, **k):
38
if fp_write is not None:
39
fp_write("\nTqdmDeprecationWarning: " + str(msg).rstrip() + '\n')
40
else:
41
super(TqdmDeprecationWarning, self).__init__(msg, *a, **k)
42
43
44
class tqdm(object):
45
"""
46
Decorate an iterable object, returning an iterator which acts exactly
47
like the original iterable, but prints a dynamically updating
48
progressbar every time a value is requested.
49
"""
50
@staticmethod
51
def format_sizeof(num, suffix=''):
52
"""
53
Formats a number (greater than unity) with SI Order of Magnitude
54
prefixes.
55
56
Parameters
57
----------
58
num : float
59
Number ( >= 1) to format.
60
suffix : str, optional
61
Post-postfix [default: ''].
62
63
Returns
64
-------
65
out : str
66
Number with Order of Magnitude SI unit postfix.
67
"""
68
for unit in ['', 'K', 'M', 'G', 'T', 'P', 'E', 'Z']:
69
if abs(num) < 999.95:
70
if abs(num) < 99.95:
71
if abs(num) < 9.995:
72
return '{0:1.2f}'.format(num) + unit + suffix
73
return '{0:2.1f}'.format(num) + unit + suffix
74
return '{0:3.0f}'.format(num) + unit + suffix
75
num /= 1000.0
76
return '{0:3.1f}Y'.format(num) + suffix
77
78
@staticmethod
79
def format_interval(t):
80
"""
81
Formats a number of seconds as a clock time, [H:]MM:SS
82
83
Parameters
84
----------
85
t : int
86
Number of seconds.
87
Returns
88
-------
89
out : str
90
[H:]MM:SS
91
"""
92
mins, s = divmod(int(t), 60)
93
h, m = divmod(mins, 60)
94
if h:
95
return '{0:d}:{1:02d}:{2:02d}'.format(h, m, s)
96
else:
97
return '{0:02d}:{1:02d}'.format(m, s)
98
99
@staticmethod
100
def status_printer(file):
101
"""
102
Manage the printing and in-place updating of a line of characters.
103
Note that if the string is longer than a line, then in-place
104
updating may not work (it will print a new line at each refresh).
105
"""
106
fp = file
107
fp_flush = getattr(fp, 'flush', lambda: None) # pragma: no cover
108
109
def fp_write(s):
110
fp.write(_unicode(s))
111
fp_flush()
112
113
last_len = [0]
114
115
def print_status(s):
116
len_s = len(s)
117
fp_write('\r' + s + (' ' * max(last_len[0] - len_s, 0)))
118
last_len[0] = len_s
119
return print_status
120
121
@staticmethod
122
def format_meter(n, total, elapsed, ncols=None, prefix='',
123
ascii=False, unit='it', unit_scale=False, rate=None,
124
bar_format=None):
125
"""
126
Return a string-based progress bar given some parameters
127
128
Parameters
129
----------
130
n : int
131
Number of finished iterations.
132
total : int
133
The expected total number of iterations. If meaningless (), only
134
basic progress statistics are displayed (no ETA).
135
elapsed : float
136
Number of seconds passed since start.
137
ncols : int, optional
138
The width of the entire output message. If specified,
139
dynamically resizes the progress meter to stay within this bound
140
[default: None]. The fallback meter width is 10 for the progress
141
bar + no limit for the iterations counter and statistics. If 0,
142
will not print any meter (only stats).
143
prefix : str, optional
144
Prefix message (included in total width) [default: ''].
145
ascii : bool, optional
146
If not set, use unicode (smooth blocks) to fill the meter
147
[default: False]. The fallback is to use ASCII characters
148
(1-9 #).
149
unit : str, optional
150
The iteration unit [default: 'it'].
151
unit_scale : bool, optional
152
If set, the number of iterations will printed with an
153
appropriate SI metric prefix (K = 10^3, M = 10^6, etc.)
154
[default: False].
155
rate : float, optional
156
Manual override for iteration rate.
157
If [default: None], uses n/elapsed.
158
bar_format : str, optional
159
Specify a custom bar string formatting. May impact performance.
160
[default: '{l_bar}{bar}{r_bar}'], where l_bar is
161
'{desc}{percentage:3.0f}%|' and r_bar is
162
'| {n_fmt}/{total_fmt} [{elapsed_str}<{remaining_str}, {rate_fmt}]'
163
Possible vars: bar, n, n_fmt, total, total_fmt, percentage,
164
rate, rate_fmt, elapsed, remaining, l_bar, r_bar, desc.
165
166
Returns
167
-------
168
out : Formatted meter and stats, ready to display.
169
"""
170
171
# sanity check: total
172
if total and n > total:
173
total = None
174
175
format_interval = tqdm.format_interval
176
elapsed_str = format_interval(elapsed)
177
178
# if unspecified, attempt to use rate = average speed
179
# (we allow manual override since predicting time is an arcane art)
180
if rate is None and elapsed:
181
rate = n / elapsed
182
inv_rate = 1 / rate if (rate and (rate < 1)) else None
183
format_sizeof = tqdm.format_sizeof
184
rate_fmt = ((format_sizeof(inv_rate if inv_rate else rate)
185
if unit_scale else
186
'{0:5.2f}'.format(inv_rate if inv_rate else rate))
187
if rate else '?') \
188
+ ('s' if inv_rate else unit) + '/' + (unit if inv_rate else 's')
189
190
if unit_scale:
191
n_fmt = format_sizeof(n)
192
total_fmt = format_sizeof(total) if total else None
193
else:
194
n_fmt = str(n)
195
total_fmt = str(total)
196
197
# total is known: we can predict some stats
198
if total:
199
# fractional and percentage progress
200
frac = n / total
201
percentage = frac * 100
202
203
remaining_str = format_interval((total - n) / rate) \
204
if rate else '?'
205
206
# format the stats displayed to the left and right sides of the bar
207
l_bar = (prefix if prefix else '') + \
208
'{0:3.0f}%|'.format(percentage)
209
r_bar = '| {0}/{1} [{2}<{3}, {4}]'.format(
210
n_fmt, total_fmt, elapsed_str, remaining_str, rate_fmt)
211
212
if ncols == 0:
213
return l_bar[:-1] + r_bar[1:]
214
215
if bar_format:
216
# Custom bar formatting
217
# Populate a dict with all available progress indicators
218
bar_args = {'n': n,
219
'n_fmt': n_fmt,
220
'total': total,
221
'total_fmt': total_fmt,
222
'percentage': percentage,
223
'rate': rate if inv_rate is None else inv_rate,
224
'rate_noinv': rate,
225
'rate_noinv_fmt': ((format_sizeof(rate)
226
if unit_scale else
227
'{0:5.2f}'.format(rate))
228
if rate else '?') + unit + '/s',
229
'rate_fmt': rate_fmt,
230
'elapsed': elapsed_str,
231
'remaining': remaining_str,
232
'l_bar': l_bar,
233
'r_bar': r_bar,
234
'desc': prefix if prefix else '',
235
# 'bar': full_bar # replaced by procedure below
236
}
237
238
# Interpolate supplied bar format with the dict
239
if '{bar}' in bar_format:
240
# Format left/right sides of the bar, and format the bar
241
# later in the remaining space (avoid breaking display)
242
l_bar_user, r_bar_user = bar_format.split('{bar}')
243
l_bar = l_bar_user.format(**bar_args)
244
r_bar = r_bar_user.format(**bar_args)
245
else:
246
# Else no progress bar, we can just format and return
247
return bar_format.format(**bar_args)
248
249
# Formatting progress bar
250
# space available for bar's display
251
N_BARS = max(1, ncols - len(l_bar) - len(r_bar)) if ncols \
252
else 10
253
254
# format bar depending on availability of unicode/ascii chars
255
if ascii:
256
bar_length, frac_bar_length = divmod(
257
int(frac * N_BARS * 10), 10)
258
259
bar = '#' * bar_length
260
frac_bar = chr(48 + frac_bar_length) if frac_bar_length \
261
else ' '
262
263
else:
264
bar_length, frac_bar_length = divmod(int(frac * N_BARS * 8), 8)
265
266
bar = _unich(0x2588) * bar_length
267
frac_bar = _unich(0x2590 - frac_bar_length) \
268
if frac_bar_length else ' '
269
270
# whitespace padding
271
if bar_length < N_BARS:
272
full_bar = bar + frac_bar + \
273
' ' * max(N_BARS - bar_length - 1, 0)
274
else:
275
full_bar = bar + \
276
' ' * max(N_BARS - bar_length, 0)
277
278
# Piece together the bar parts
279
return l_bar + full_bar + r_bar
280
281
# no total: no progressbar, ETA, just progress stats
282
else:
283
return (prefix if prefix else '') + '{0}{1} [{2}, {3}]'.format(
284
n_fmt, unit, elapsed_str, rate_fmt)
285
286
def __new__(cls, *args, **kwargs):
287
# Create a new instance
288
instance = object.__new__(cls)
289
# Add to the list of instances
290
if "_instances" not in cls.__dict__:
291
cls._instances = WeakSet()
292
cls._instances.add(instance)
293
# Return the instance
294
return instance
295
296
@classmethod
297
def _get_free_pos(cls, instance=None):
298
""" Skips specified instance """
299
try:
300
return max(inst.pos for inst in cls._instances
301
if inst is not instance) + 1
302
except ValueError as e:
303
if "arg is an empty sequence" in str(e):
304
return 0
305
raise # pragma: no cover
306
307
@classmethod
308
def _decr_instances(cls, instance):
309
"""
310
Remove from list and reposition other bars
311
so that newer bars won't overlap previous bars
312
"""
313
try: # in case instance was explicitly positioned, it won't be in set
314
cls._instances.remove(instance)
315
for inst in cls._instances:
316
if inst.pos > instance.pos:
317
inst.pos -= 1
318
except KeyError:
319
pass
320
321
@classmethod
322
def write(cls, s, file=sys.stdout, end="\n"):
323
"""
324
Print a message via tqdm (without overlap with bars)
325
"""
326
fp = file
327
328
# Clear all bars
329
inst_cleared = []
330
for inst in getattr(cls, '_instances', []):
331
# Clear instance if in the target output file
332
# or if write output + tqdm output are both either
333
# sys.stdout or sys.stderr (because both are mixed in terminal)
334
if inst.fp == fp or all(f in (sys.stdout, sys.stderr)
335
for f in (fp, inst.fp)):
336
inst.clear()
337
inst_cleared.append(inst)
338
# Write the message
339
fp.write(s)
340
fp.write(end)
341
# Force refresh display of bars we cleared
342
for inst in inst_cleared:
343
inst.refresh()
344
# TODO: make list of all instances incl. absolutely positioned ones?
345
346
@classmethod
347
def pandas(tclass, *targs, **tkwargs):
348
"""
349
Registers the given `tqdm` class with
350
pandas.core.
351
( frame.DataFrame
352
| series.Series
353
| groupby.DataFrameGroupBy
354
| groupby.SeriesGroupBy
355
).progress_apply
356
357
A new instance will be create every time `progress_apply` is called,
358
and each instance will automatically close() upon completion.
359
360
Parameters
361
----------
362
targs, tkwargs : arguments for the tqdm instance
363
364
Examples
365
--------
366
>>> import pandas as pd
367
>>> import numpy as np
368
>>> from tqdm import tqdm, tqdm_gui
369
>>>
370
>>> df = pd.DataFrame(np.random.randint(0, 100, (100000, 6)))
371
>>> tqdm.pandas(ncols=50) # can use tqdm_gui, optional kwargs, etc
372
>>> # Now you can use `progress_apply` instead of `apply`
373
>>> df.groupby(0).progress_apply(lambda x: x**2)
374
375
References
376
----------
377
https://stackoverflow.com/questions/18603270/
378
progress-indicator-during-pandas-operations-python
379
"""
380
from pandas.core.frame import DataFrame
381
from pandas.core.series import Series
382
from pandas.core.groupby import DataFrameGroupBy
383
from pandas.core.groupby import SeriesGroupBy
384
from pandas.core.groupby import GroupBy
385
from pandas.core.groupby import PanelGroupBy
386
from pandas import Panel
387
388
deprecated_t = [tkwargs.pop('deprecated_t', None)]
389
390
def inner_generator(df_function='apply'):
391
def inner(df, func, *args, **kwargs):
392
"""
393
Parameters
394
----------
395
df : (DataFrame|Series)[GroupBy]
396
Data (may be grouped).
397
func : function
398
To be applied on the (grouped) data.
399
*args, *kwargs : optional
400
Transmitted to `df.apply()`.
401
"""
402
# Precompute total iterations
403
total = getattr(df, 'ngroups', None)
404
if total is None: # not grouped
405
total = len(df) if isinstance(df, Series) \
406
else df.size // len(df)
407
else:
408
total += 1 # pandas calls update once too many
409
410
# Init bar
411
if deprecated_t[0] is not None:
412
t = deprecated_t[0]
413
deprecated_t[0] = None
414
else:
415
t = tclass(*targs, total=total, **tkwargs)
416
417
# Define bar updating wrapper
418
def wrapper(*args, **kwargs):
419
t.update()
420
return func(*args, **kwargs)
421
422
# Apply the provided function (in *args and **kwargs)
423
# on the df using our wrapper (which provides bar updating)
424
result = getattr(df, df_function)(wrapper, *args, **kwargs)
425
426
# Close bar and return pandas calculation result
427
t.close()
428
return result
429
return inner
430
431
# Monkeypatch pandas to provide easy methods
432
# Enable custom tqdm progress in pandas!
433
Series.progress_apply = inner_generator()
434
SeriesGroupBy.progress_apply = inner_generator()
435
Series.progress_map = inner_generator('map')
436
SeriesGroupBy.progress_map = inner_generator('map')
437
438
DataFrame.progress_apply = inner_generator()
439
DataFrameGroupBy.progress_apply = inner_generator()
440
DataFrame.progress_applymap = inner_generator('applymap')
441
442
Panel.progress_apply = inner_generator()
443
PanelGroupBy.progress_apply = inner_generator()
444
445
GroupBy.progress_apply = inner_generator()
446
GroupBy.progress_aggregate = inner_generator('aggregate')
447
GroupBy.progress_transform = inner_generator('transform')
448
449
def __init__(self, iterable=None, desc=None, total=None, leave=True,
450
file=sys.stderr, ncols=None, mininterval=0.1,
451
maxinterval=10.0, miniters=None, ascii=None, disable=False,
452
unit='it', unit_scale=False, dynamic_ncols=False,
453
smoothing=0.3, bar_format=None, initial=0, position=None,
454
gui=False, **kwargs):
455
"""
456
Parameters
457
----------
458
iterable : iterable, optional
459
Iterable to decorate with a progressbar.
460
Leave blank to manually manage the updates.
461
desc : str, optional
462
Prefix for the progressbar.
463
total : int, optional
464
The number of expected iterations. If unspecified,
465
len(iterable) is used if possible. As a last resort, only basic
466
progress statistics are displayed (no ETA, no progressbar).
467
If `gui` is True and this parameter needs subsequent updating,
468
specify an initial arbitrary large positive integer,
469
e.g. int(9e9).
470
leave : bool, optional
471
If [default: True], keeps all traces of the progressbar
472
upon termination of iteration.
473
file : `io.TextIOWrapper` or `io.StringIO`, optional
474
Specifies where to output the progress messages
475
[default: sys.stderr]. Uses `file.write(str)` and `file.flush()`
476
methods.
477
ncols : int, optional
478
The width of the entire output message. If specified,
479
dynamically resizes the progressbar to stay within this bound.
480
If unspecified, attempts to use environment width. The
481
fallback is a meter width of 10 and no limit for the counter and
482
statistics. If 0, will not print any meter (only stats).
483
mininterval : float, optional
484
Minimum progress update interval, in seconds [default: 0.1].
485
maxinterval : float, optional
486
Maximum progress update interval, in seconds [default: 10.0].
487
miniters : int, optional
488
Minimum progress update interval, in iterations.
489
If specified, will set `mininterval` to 0.
490
ascii : bool, optional
491
If unspecified or False, use unicode (smooth blocks) to fill
492
the meter. The fallback is to use ASCII characters `1-9 #`.
493
disable : bool, optional
494
Whether to disable the entire progressbar wrapper
495
[default: False].
496
unit : str, optional
497
String that will be used to define the unit of each iteration
498
[default: it].
499
unit_scale : bool, optional
500
If set, the number of iterations will be reduced/scaled
501
automatically and a metric prefix following the
502
International System of Units standard will be added
503
(kilo, mega, etc.) [default: False].
504
dynamic_ncols : bool, optional
505
If set, constantly alters `ncols` to the environment (allowing
506
for window resizes) [default: False].
507
smoothing : float, optional
508
Exponential moving average smoothing factor for speed estimates
509
(ignored in GUI mode). Ranges from 0 (average speed) to 1
510
(current/instantaneous speed) [default: 0.3].
511
bar_format : str, optional
512
Specify a custom bar string formatting. May impact performance.
513
If unspecified, will use '{l_bar}{bar}{r_bar}', where l_bar is
514
'{desc}{percentage:3.0f}%|' and r_bar is
515
'| {n_fmt}/{total_fmt} [{elapsed_str}<{remaining_str}, {rate_fmt}]'
516
Possible vars: bar, n, n_fmt, total, total_fmt, percentage,
517
rate, rate_fmt, elapsed, remaining, l_bar, r_bar, desc.
518
initial : int, optional
519
The initial counter value. Useful when restarting a progress
520
bar [default: 0].
521
position : int, optional
522
Specify the line offset to print this bar (starting from 0)
523
Automatic if unspecified.
524
Useful to manage multiple bars at once (eg, from threads).
525
gui : bool, optional
526
WARNING: internal parameter - do not use.
527
Use tqdm_gui(...) instead. If set, will attempt to use
528
matplotlib animations for a graphical output [default: False].
529
530
Returns
531
-------
532
out : decorated iterator.
533
"""
534
if disable:
535
self.iterable = iterable
536
self.disable = disable
537
self.pos = self._get_free_pos(self)
538
self._instances.remove(self)
539
return
540
541
if kwargs:
542
self.disable = True
543
self.pos = self._get_free_pos(self)
544
self._instances.remove(self)
545
raise (TqdmDeprecationWarning("""\
546
`nested` is deprecated and automated. Use position instead for manual control.
547
""", fp_write=getattr(file, 'write', sys.stderr.write))
548
if "nested" in kwargs else
549
TqdmKeyError("Unknown argument(s): " + str(kwargs)))
550
551
# Preprocess the arguments
552
if total is None and iterable is not None:
553
try:
554
total = len(iterable)
555
except (TypeError, AttributeError):
556
total = None
557
558
if ((ncols is None) and (file in (sys.stderr, sys.stdout))) or \
559
dynamic_ncols: # pragma: no cover
560
if dynamic_ncols:
561
dynamic_ncols = _environ_cols_wrapper()
562
ncols = dynamic_ncols(file)
563
else:
564
ncols = _environ_cols_wrapper()(file)
565
566
if miniters is None:
567
miniters = 0
568
dynamic_miniters = True
569
else:
570
dynamic_miniters = False
571
572
if mininterval is None:
573
mininterval = 0
574
575
if maxinterval is None:
576
maxinterval = 0
577
578
if ascii is None:
579
ascii = not _supports_unicode(file)
580
581
if bar_format and not ascii:
582
# Convert bar format into unicode since terminal uses unicode
583
bar_format = _unicode(bar_format)
584
585
if smoothing is None:
586
smoothing = 0
587
588
# Store the arguments
589
self.iterable = iterable
590
self.desc = desc + ': ' if desc else ''
591
self.total = total
592
self.leave = leave
593
self.fp = file
594
self.ncols = ncols
595
self.mininterval = mininterval
596
self.maxinterval = maxinterval
597
self.miniters = miniters
598
self.dynamic_miniters = dynamic_miniters
599
self.ascii = ascii
600
self.disable = disable
601
self.unit = unit
602
self.unit_scale = unit_scale
603
self.gui = gui
604
self.dynamic_ncols = dynamic_ncols
605
self.smoothing = smoothing
606
self.avg_time = None
607
self._time = time
608
self.bar_format = bar_format
609
610
# Init the iterations counters
611
self.last_print_n = initial
612
self.n = initial
613
614
# if nested, at initial sp() call we replace '\r' by '\n' to
615
# not overwrite the outer progress bar
616
self.pos = self._get_free_pos(self) if position is None else position
617
618
if not gui:
619
# Initialize the screen printer
620
self.sp = self.status_printer(self.fp)
621
if self.pos:
622
self.moveto(self.pos)
623
self.sp(self.format_meter(self.n, total, 0,
624
(dynamic_ncols(file) if dynamic_ncols else ncols),
625
self.desc, ascii, unit, unit_scale, None, bar_format))
626
if self.pos:
627
self.moveto(-self.pos)
628
629
# Init the time counter
630
self.start_t = self.last_print_t = self._time()
631
632
def __len__(self):
633
return (self.iterable.shape[0] if hasattr(self.iterable, 'shape')
634
else len(self.iterable)) if self.iterable is not None \
635
else self.total
636
637
def __enter__(self):
638
return self
639
640
def __exit__(self, *exc):
641
self.close()
642
return False
643
644
def __del__(self):
645
self.close()
646
647
def __repr__(self):
648
return self.format_meter(self.n, self.total,
649
time() - self.last_print_t,
650
self.ncols, self.desc, self.ascii, self.unit,
651
self.unit_scale, 1 / self.avg_time
652
if self.avg_time else None, self.bar_format)
653
654
def __lt__(self, other):
655
return self.pos < other.pos
656
657
def __le__(self, other):
658
return (self < other) or (self == other)
659
660
def __eq__(self, other):
661
return self.pos == other.pos
662
663
def __ne__(self, other):
664
return not (self == other)
665
666
def __gt__(self, other):
667
return not (self <= other)
668
669
def __ge__(self, other):
670
return not (self < other)
671
672
def __hash__(self):
673
return id(self)
674
675
def __iter__(self):
676
''' Backward-compatibility to use: for x in tqdm(iterable) '''
677
678
# Inlining instance variables as locals (speed optimisation)
679
iterable = self.iterable
680
681
# If the bar is disabled, then just walk the iterable
682
# (note: keep this check outside the loop for performance)
683
if self.disable:
684
for obj in iterable:
685
yield obj
686
else:
687
ncols = self.ncols
688
mininterval = self.mininterval
689
maxinterval = self.maxinterval
690
miniters = self.miniters
691
dynamic_miniters = self.dynamic_miniters
692
unit = self.unit
693
unit_scale = self.unit_scale
694
ascii = self.ascii
695
start_t = self.start_t
696
last_print_t = self.last_print_t
697
last_print_n = self.last_print_n
698
n = self.n
699
dynamic_ncols = self.dynamic_ncols
700
smoothing = self.smoothing
701
avg_time = self.avg_time
702
bar_format = self.bar_format
703
_time = self._time
704
format_meter = self.format_meter
705
706
try:
707
sp = self.sp
708
except AttributeError:
709
raise TqdmDeprecationWarning("""\
710
Please use `tqdm_gui(...)` instead of `tqdm(..., gui=True)`
711
""", fp_write=getattr(self.fp, 'write', sys.stderr.write))
712
713
for obj in iterable:
714
yield obj
715
# Update and print the progressbar.
716
# Note: does not call self.update(1) for speed optimisation.
717
n += 1
718
# check the counter first (avoid calls to time())
719
if n - last_print_n >= miniters:
720
delta_t = _time() - last_print_t
721
if delta_t >= mininterval:
722
cur_t = _time()
723
delta_it = n - last_print_n
724
elapsed = cur_t - start_t
725
# EMA (not just overall average)
726
if smoothing and delta_t:
727
avg_time = delta_t / delta_it \
728
if avg_time is None \
729
else smoothing * delta_t / delta_it + \
730
(1 - smoothing) * avg_time
731
732
if self.pos:
733
self.moveto(self.pos)
734
735
# Printing the bar's update
736
sp(format_meter(
737
n, self.total, elapsed,
738
(dynamic_ncols(self.fp) if dynamic_ncols
739
else ncols),
740
self.desc, ascii, unit, unit_scale,
741
1 / avg_time if avg_time else None, bar_format))
742
743
if self.pos:
744
self.moveto(-self.pos)
745
746
# If no `miniters` was specified, adjust automatically
747
# to the maximum iteration rate seen so far.
748
if dynamic_miniters:
749
if maxinterval and delta_t > maxinterval:
750
# Set miniters to correspond to maxinterval
751
miniters = delta_it * maxinterval / delta_t
752
elif mininterval and delta_t:
753
# EMA-weight miniters to converge
754
# towards the timeframe of mininterval
755
miniters = smoothing * delta_it * mininterval \
756
/ delta_t + (1 - smoothing) * miniters
757
else:
758
miniters = smoothing * delta_it + \
759
(1 - smoothing) * miniters
760
761
# Store old values for next call
762
self.n = self.last_print_n = last_print_n = n
763
self.last_print_t = last_print_t = cur_t
764
765
# Closing the progress bar.
766
# Update some internal variables for close().
767
self.last_print_n = last_print_n
768
self.n = n
769
self.close()
770
771
def update(self, n=1):
772
"""
773
Manually update the progress bar, useful for streams
774
such as reading files.
775
E.g.:
776
>>> t = tqdm(total=filesize) # Initialise
777
>>> for current_buffer in stream:
778
... ...
779
... t.update(len(current_buffer))
780
>>> t.close()
781
The last line is highly recommended, but possibly not necessary if
782
`t.update()` will be called in such a way that `filesize` will be
783
exactly reached and printed.
784
785
Parameters
786
----------
787
n : int
788
Increment to add to the internal counter of iterations
789
[default: 1].
790
"""
791
if self.disable:
792
return
793
794
if n < 0:
795
raise ValueError("n ({0}) cannot be negative".format(n))
796
self.n += n
797
798
if self.n - self.last_print_n >= self.miniters:
799
# We check the counter first, to reduce the overhead of time()
800
delta_t = self._time() - self.last_print_t
801
if delta_t >= self.mininterval:
802
cur_t = self._time()
803
delta_it = self.n - self.last_print_n # should be n?
804
elapsed = cur_t - self.start_t
805
# EMA (not just overall average)
806
if self.smoothing and delta_t:
807
self.avg_time = delta_t / delta_it \
808
if self.avg_time is None \
809
else self.smoothing * delta_t / delta_it + \
810
(1 - self.smoothing) * self.avg_time
811
812
if not hasattr(self, "sp"):
813
raise TqdmDeprecationWarning("""\
814
Please use `tqdm_gui(...)` instead of `tqdm(..., gui=True)`
815
""", fp_write=getattr(self.fp, 'write', sys.stderr.write))
816
817
if self.pos:
818
self.moveto(self.pos)
819
820
# Print bar's update
821
self.sp(self.format_meter(
822
self.n, self.total, elapsed,
823
(self.dynamic_ncols(self.fp) if self.dynamic_ncols
824
else self.ncols),
825
self.desc, self.ascii, self.unit, self.unit_scale,
826
1 / self.avg_time if self.avg_time else None,
827
self.bar_format))
828
829
if self.pos:
830
self.moveto(-self.pos)
831
832
# If no `miniters` was specified, adjust automatically to the
833
# maximum iteration rate seen so far.
834
# e.g.: After running `tqdm.update(5)`, subsequent
835
# calls to `tqdm.update()` will only cause an update after
836
# at least 5 more iterations.
837
if self.dynamic_miniters:
838
if self.maxinterval and delta_t > self.maxinterval:
839
self.miniters = self.miniters * self.maxinterval \
840
/ delta_t
841
elif self.mininterval and delta_t:
842
self.miniters = self.smoothing * delta_it \
843
* self.mininterval / delta_t + \
844
(1 - self.smoothing) * self.miniters
845
else:
846
self.miniters = self.smoothing * delta_it + \
847
(1 - self.smoothing) * self.miniters
848
849
# Store old values for next call
850
self.last_print_n = self.n
851
self.last_print_t = cur_t
852
853
def close(self):
854
"""
855
Cleanup and (if leave=False) close the progressbar.
856
"""
857
if self.disable:
858
return
859
860
# Prevent multiple closures
861
self.disable = True
862
863
# decrement instance pos and remove from internal set
864
pos = self.pos
865
self._decr_instances(self)
866
867
# GUI mode
868
if not hasattr(self, "sp"):
869
return
870
871
# annoyingly, _supports_unicode isn't good enough
872
def fp_write(s):
873
self.fp.write(_unicode(s))
874
875
try:
876
fp_write('')
877
except ValueError as e:
878
if 'closed' in str(e):
879
return
880
raise # pragma: no cover
881
882
if pos:
883
self.moveto(pos)
884
885
if self.leave:
886
if self.last_print_n < self.n:
887
cur_t = self._time()
888
# stats for overall rate (no weighted average)
889
self.sp(self.format_meter(
890
self.n, self.total, cur_t - self.start_t,
891
(self.dynamic_ncols(self.fp) if self.dynamic_ncols
892
else self.ncols),
893
self.desc, self.ascii, self.unit, self.unit_scale, None,
894
self.bar_format))
895
if pos:
896
self.moveto(-pos)
897
else:
898
fp_write('\n')
899
else:
900
self.sp('') # clear up last bar
901
if pos:
902
self.moveto(-pos)
903
else:
904
fp_write('\r')
905
906
def unpause(self):
907
"""
908
Restart tqdm timer from last print time.
909
"""
910
cur_t = self._time()
911
self.start_t += cur_t - self.last_print_t
912
self.last_print_t = cur_t
913
914
def set_description(self, desc=None):
915
"""
916
Set/modify description of the progress bar.
917
"""
918
self.desc = desc + ': ' if desc else ''
919
920
def moveto(self, n):
921
self.fp.write(_unicode('\n' * n + _term_move_up() * -n))
922
923
def clear(self, nomove=False):
924
"""
925
Clear current bar display
926
"""
927
if not nomove:
928
self.moveto(self.pos)
929
# clear up the bar (can't rely on sp(''))
930
self.fp.write('\r')
931
self.fp.write(' ' * (self.ncols if self.ncols else 10))
932
self.fp.write('\r') # place cursor back at the beginning of line
933
if not nomove:
934
self.moveto(-self.pos)
935
936
def refresh(self):
937
"""
938
Force refresh the display of this bar
939
"""
940
self.moveto(self.pos)
941
# clear up this line's content (whatever there was)
942
self.clear(nomove=True)
943
# Print current/last bar state
944
self.fp.write(self.__repr__())
945
self.moveto(-self.pos)
946
947
948
def trange(*args, **kwargs):
949
"""
950
A shortcut for tqdm(xrange(*args), **kwargs).
951
On Python3+ range is used instead of xrange.
952
"""
953
return tqdm(_range(*args), **kwargs)
954
955