• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..03-May-2022-

examples/H20-Sep-2021-1,057853

tests/H20-Sep-2021-3,6642,797

tqdm/H20-Sep-2021-4,7253,858

tqdm.egg-info/H03-May-2022-1,5801,214

.pre-commit-config.yamlH A D20-Sep-20211.4 KiB6362

.zenodo.jsonH A D20-Sep-2021478 1211

CODE_OF_CONDUCT.mdH A D20-Sep-20211.4 KiB2721

CONTRIBUTING.mdH A D20-Sep-202111.9 KiB370264

DEMO.ipynbH A D20-Sep-202128.3 KiB891890

LICENCEH A D20-Sep-20212 KiB5037

MakefileH A D20-Sep-20215.1 KiB192150

PKG-INFOH A D20-Sep-202155.4 KiB1,5801,214

README.rstH A D20-Sep-202152.1 KiB1,5021,139

environment.ymlH A D20-Sep-2021771 4039

pyproject.tomlH A D20-Sep-2021227 86

setup.cfgH A D20-Sep-20214.1 KiB155138

setup.pyH A D20-Sep-2021439 1710

tests_notebook.ipynbH A D20-Sep-202111.9 KiB513512

tox.iniH A D20-Sep-20212 KiB8576

README.rst

1|Logo|
2
3tqdm
4====
5
6|Py-Versions| |Versions| |Conda-Forge-Status| |Docker| |Snapcraft|
7
8|Build-Status| |Coverage-Status| |Branch-Coverage-Status| |Codacy-Grade| |Libraries-Rank| |PyPI-Downloads|
9
10|LICENCE| |OpenHub-Status| |binder-demo| |awesome-python|
11
12``tqdm`` derives from the Arabic word *taqaddum* (تقدّم) which can mean "progress,"
13and is an abbreviation for "I love you so much" in Spanish (*te quiero demasiado*).
14
15Instantly make your loops show a smart progress meter - just wrap any
16iterable with ``tqdm(iterable)``, and you're done!
17
18.. code:: python
19
20    from tqdm import tqdm
21    for i in tqdm(range(10000)):
22        ...
23
24``76%|████████████████████████        | 7568/10000 [00:33<00:10, 229.00it/s]``
25
26``trange(N)`` can be also used as a convenient shortcut for
27``tqdm(range(N))``.
28
29|Screenshot|
30    |Video| |Slides| |Merch|
31
32It can also be executed as a module with pipes:
33
34.. code:: sh
35
36    $ seq 9999999 | tqdm --bytes | wc -l
37    75.2MB [00:00, 217MB/s]
38    9999999
39
40    $ tar -zcf - docs/ | tqdm --bytes --total `du -sb docs/ | cut -f1` \
41        > backup.tgz
42     32%|██████████▍                      | 8.89G/27.9G [00:42<01:31, 223MB/s]
43
44Overhead is low -- about 60ns per iteration (80ns with ``tqdm.gui``), and is
45unit tested against performance regression.
46By comparison, the well-established
47`ProgressBar <https://github.com/niltonvolpato/python-progressbar>`__ has
48an 800ns/iter overhead.
49
50In addition to its low overhead, ``tqdm`` uses smart algorithms to predict
51the remaining time and to skip unnecessary iteration displays, which allows
52for a negligible overhead in most cases.
53
54``tqdm`` works on any platform
55(Linux, Windows, Mac, FreeBSD, NetBSD, Solaris/SunOS),
56in any console or in a GUI, and is also friendly with IPython/Jupyter notebooks.
57
58``tqdm`` does not require any dependencies (not even ``curses``!), just
59Python and an environment supporting ``carriage return \r`` and
60``line feed \n`` control characters.
61
62------------------------------------------
63
64.. contents:: Table of contents
65   :backlinks: top
66   :local:
67
68
69Installation
70------------
71
72Latest PyPI stable release
73~~~~~~~~~~~~~~~~~~~~~~~~~~
74
75|Versions| |PyPI-Downloads| |Libraries-Dependents|
76
77.. code:: sh
78
79    pip install tqdm
80
81Latest development release on GitHub
82~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
83
84|GitHub-Status| |GitHub-Stars| |GitHub-Commits| |GitHub-Forks| |GitHub-Updated|
85
86Pull and install pre-release ``devel`` branch:
87
88.. code:: sh
89
90    pip install "git+https://github.com/tqdm/tqdm.git@devel#egg=tqdm"
91
92Latest Conda release
93~~~~~~~~~~~~~~~~~~~~
94
95|Conda-Forge-Status|
96
97.. code:: sh
98
99    conda install -c conda-forge tqdm
100
101Latest Snapcraft release
102~~~~~~~~~~~~~~~~~~~~~~~~
103
104|Snapcraft|
105
106There are 3 channels to choose from:
107
108.. code:: sh
109
110    snap install tqdm  # implies --stable, i.e. latest tagged release
111    snap install tqdm  --candidate  # master branch
112    snap install tqdm  --edge  # devel branch
113
114Note that ``snap`` binaries are purely for CLI use (not ``import``-able), and
115automatically set up ``bash`` tab-completion.
116
117Latest Docker release
118~~~~~~~~~~~~~~~~~~~~~
119
120|Docker|
121
122.. code:: sh
123
124    docker pull tqdm/tqdm
125    docker run -i --rm tqdm/tqdm --help
126
127Other
128~~~~~
129
130There are other (unofficial) places where ``tqdm`` may be downloaded, particularly for CLI use:
131
132|Repology|
133
134.. |Repology| image:: https://repology.org/badge/tiny-repos/python:tqdm.svg
135   :target: https://repology.org/project/python:tqdm/versions
136
137Changelog
138---------
139
140The list of all changes is available either on GitHub's Releases:
141|GitHub-Status|, on the
142`wiki <https://github.com/tqdm/tqdm/wiki/Releases>`__, or on the
143`website <https://tqdm.github.io/releases>`__.
144
145
146Usage
147-----
148
149``tqdm`` is very versatile and can be used in a number of ways.
150The three main ones are given below.
151
152Iterable-based
153~~~~~~~~~~~~~~
154
155Wrap ``tqdm()`` around any iterable:
156
157.. code:: python
158
159    from tqdm import tqdm
160    from time import sleep
161
162    text = ""
163    for char in tqdm(["a", "b", "c", "d"]):
164        sleep(0.25)
165        text = text + char
166
167``trange(i)`` is a special optimised instance of ``tqdm(range(i))``:
168
169.. code:: python
170
171    from tqdm import trange
172
173    for i in trange(100):
174        sleep(0.01)
175
176Instantiation outside of the loop allows for manual control over ``tqdm()``:
177
178.. code:: python
179
180    pbar = tqdm(["a", "b", "c", "d"])
181    for char in pbar:
182        sleep(0.25)
183        pbar.set_description("Processing %s" % char)
184
185Manual
186~~~~~~
187
188Manual control of ``tqdm()`` updates using a ``with`` statement:
189
190.. code:: python
191
192    with tqdm(total=100) as pbar:
193        for i in range(10):
194            sleep(0.1)
195            pbar.update(10)
196
197If the optional variable ``total`` (or an iterable with ``len()``) is
198provided, predictive stats are displayed.
199
200``with`` is also optional (you can just assign ``tqdm()`` to a variable,
201but in this case don't forget to ``del`` or ``close()`` at the end:
202
203.. code:: python
204
205    pbar = tqdm(total=100)
206    for i in range(10):
207        sleep(0.1)
208        pbar.update(10)
209    pbar.close()
210
211Module
212~~~~~~
213
214Perhaps the most wonderful use of ``tqdm`` is in a script or on the command
215line. Simply inserting ``tqdm`` (or ``python -m tqdm``) between pipes will pass
216through all ``stdin`` to ``stdout`` while printing progress to ``stderr``.
217
218The example below demonstrate counting the number of lines in all Python files
219in the current directory, with timing information included.
220
221.. code:: sh
222
223    $ time find . -name '*.py' -type f -exec cat \{} \; | wc -l
224    857365
225
226    real    0m3.458s
227    user    0m0.274s
228    sys     0m3.325s
229
230    $ time find . -name '*.py' -type f -exec cat \{} \; | tqdm | wc -l
231    857366it [00:03, 246471.31it/s]
232    857365
233
234    real    0m3.585s
235    user    0m0.862s
236    sys     0m3.358s
237
238Note that the usual arguments for ``tqdm`` can also be specified.
239
240.. code:: sh
241
242    $ find . -name '*.py' -type f -exec cat \{} \; |
243        tqdm --unit loc --unit_scale --total 857366 >> /dev/null
244    100%|█████████████████████████████████| 857K/857K [00:04<00:00, 246Kloc/s]
245
246Backing up a large directory?
247
248.. code:: sh
249
250    $ tar -zcf - docs/ | tqdm --bytes --total `du -sb docs/ | cut -f1` \
251      > backup.tgz
252     44%|██████████████▊                   | 153M/352M [00:14<00:18, 11.0MB/s]
253
254This can be beautified further:
255
256.. code:: sh
257
258    $ BYTES="$(du -sb docs/ | cut -f1)"
259    $ tar -cf - docs/ \
260      | tqdm --bytes --total "$BYTES" --desc Processing | gzip \
261      | tqdm --bytes --total "$BYTES" --desc Compressed --position 1 \
262      > ~/backup.tgz
263    Processing: 100%|██████████████████████| 352M/352M [00:14<00:00, 30.2MB/s]
264    Compressed:  42%|█████████▎            | 148M/352M [00:14<00:19, 10.9MB/s]
265
266Or done on a file level using 7-zip:
267
268.. code:: sh
269
270    $ 7z a -bd -r backup.7z docs/ | grep Compressing \
271      | tqdm --total $(find docs/ -type f | wc -l) --unit files \
272      | grep -v Compressing
273    100%|██████████████████████████▉| 15327/15327 [01:00<00:00, 712.96files/s]
274
275Pre-existing CLI programs already outputting basic progress information will
276benefit from ``tqdm``'s ``--update`` and ``--update_to`` flags:
277
278.. code:: sh
279
280    $ seq 3 0.1 5 | tqdm --total 5 --update_to --null
281    100%|████████████████████████████████████| 5.0/5 [00:00<00:00, 9673.21it/s]
282    $ seq 10 | tqdm --update --null  # 1 + 2 + ... + 10 = 55 iterations
283    55it [00:00, 90006.52it/s]
284
285FAQ and Known Issues
286--------------------
287
288|GitHub-Issues|
289
290The most common issues relate to excessive output on multiple lines, instead
291of a neat one-line progress bar.
292
293- Consoles in general: require support for carriage return (``CR``, ``\r``).
294- Nested progress bars:
295
296  * Consoles in general: require support for moving cursors up to the
297    previous line. For example,
298    `IDLE <https://github.com/tqdm/tqdm/issues/191#issuecomment-230168030>`__,
299    `ConEmu <https://github.com/tqdm/tqdm/issues/254>`__ and
300    `PyCharm <https://github.com/tqdm/tqdm/issues/203>`__ (also
301    `here <https://github.com/tqdm/tqdm/issues/208>`__,
302    `here <https://github.com/tqdm/tqdm/issues/307>`__, and
303    `here <https://github.com/tqdm/tqdm/issues/454#issuecomment-335416815>`__)
304    lack full support.
305  * Windows: additionally may require the Python module ``colorama``
306    to ensure nested bars stay within their respective lines.
307
308- Unicode:
309
310  * Environments which report that they support unicode will have solid smooth
311    progressbars. The fallback is an ``ascii``-only bar.
312  * Windows consoles often only partially support unicode and thus
313    `often require explicit ascii=True <https://github.com/tqdm/tqdm/issues/454#issuecomment-335416815>`__
314    (also `here <https://github.com/tqdm/tqdm/issues/499>`__). This is due to
315    either normal-width unicode characters being incorrectly displayed as
316    "wide", or some unicode characters not rendering.
317
318- Wrapping generators:
319
320  * Generator wrapper functions tend to hide the length of iterables.
321    ``tqdm`` does not.
322  * Replace ``tqdm(enumerate(...))`` with ``enumerate(tqdm(...))`` or
323    ``tqdm(enumerate(x), total=len(x), ...)``.
324    The same applies to ``numpy.ndenumerate``.
325  * Replace ``tqdm(zip(a, b))`` with ``zip(tqdm(a), b)`` or even
326    ``zip(tqdm(a), tqdm(b))``.
327  * The same applies to ``itertools``.
328  * Some useful convenience functions can be found under ``tqdm.contrib``.
329
330- `Hanging pipes in python2 <https://github.com/tqdm/tqdm/issues/359>`__:
331  when using ``tqdm`` on the CLI, you may need to use Python 3.5+ for correct
332  buffering.
333- `No intermediate output in docker-compose <https://github.com/tqdm/tqdm/issues/771>`__:
334  use ``docker-compose run`` instead of ``docker-compose up`` and ``tty: true``.
335
336If you come across any other difficulties, browse and file |GitHub-Issues|.
337
338Documentation
339-------------
340
341|Py-Versions| |README-Hits| (Since 19 May 2016)
342
343.. code:: python
344
345    class tqdm():
346      """
347      Decorate an iterable object, returning an iterator which acts exactly
348      like the original iterable, but prints a dynamically updating
349      progressbar every time a value is requested.
350      """
351
352      def __init__(self, iterable=None, desc=None, total=None, leave=True,
353                   file=None, ncols=None, mininterval=0.1,
354                   maxinterval=10.0, miniters=None, ascii=None, disable=False,
355                   unit='it', unit_scale=False, dynamic_ncols=False,
356                   smoothing=0.3, bar_format=None, initial=0, position=None,
357                   postfix=None, unit_divisor=1000):
358
359Parameters
360~~~~~~~~~~
361
362* iterable  : iterable, optional
363    Iterable to decorate with a progressbar.
364    Leave blank to manually manage the updates.
365* desc  : str, optional
366    Prefix for the progressbar.
367* total  : int or float, optional
368    The number of expected iterations. If unspecified,
369    len(iterable) is used if possible. If float("inf") or as a last
370    resort, only basic progress statistics are displayed
371    (no ETA, no progressbar).
372    If ``gui`` is True and this parameter needs subsequent updating,
373    specify an initial arbitrary large positive number,
374    e.g. 9e9.
375* leave  : bool, optional
376    If [default: True], keeps all traces of the progressbar
377    upon termination of iteration.
378    If ``None``, will leave only if ``position`` is ``0``.
379* file  : ``io.TextIOWrapper`` or ``io.StringIO``, optional
380    Specifies where to output the progress messages
381    (default: sys.stderr). Uses ``file.write(str)`` and ``file.flush()``
382    methods.  For encoding, see ``write_bytes``.
383* ncols  : int, optional
384    The width of the entire output message. If specified,
385    dynamically resizes the progressbar to stay within this bound.
386    If unspecified, attempts to use environment width. The
387    fallback is a meter width of 10 and no limit for the counter and
388    statistics. If 0, will not print any meter (only stats).
389* mininterval  : float, optional
390    Minimum progress display update interval [default: 0.1] seconds.
391* maxinterval  : float, optional
392    Maximum progress display update interval [default: 10] seconds.
393    Automatically adjusts ``miniters`` to correspond to ``mininterval``
394    after long display update lag. Only works if ``dynamic_miniters``
395    or monitor thread is enabled.
396* miniters  : int or float, optional
397    Minimum progress display update interval, in iterations.
398    If 0 and ``dynamic_miniters``, will automatically adjust to equal
399    ``mininterval`` (more CPU efficient, good for tight loops).
400    If > 0, will skip display of specified number of iterations.
401    Tweak this and ``mininterval`` to get very efficient loops.
402    If your progress is erratic with both fast and slow iterations
403    (network, skipping items, etc) you should set miniters=1.
404* ascii  : bool or str, optional
405    If unspecified or False, use unicode (smooth blocks) to fill
406    the meter. The fallback is to use ASCII characters " 123456789#".
407* disable  : bool, optional
408    Whether to disable the entire progressbar wrapper
409    [default: False]. If set to None, disable on non-TTY.
410* unit  : str, optional
411    String that will be used to define the unit of each iteration
412    [default: it].
413* unit_scale  : bool or int or float, optional
414    If 1 or True, the number of iterations will be reduced/scaled
415    automatically and a metric prefix following the
416    International System of Units standard will be added
417    (kilo, mega, etc.) [default: False]. If any other non-zero
418    number, will scale ``total`` and ``n``.
419* dynamic_ncols  : bool, optional
420    If set, constantly alters ``ncols`` and ``nrows`` to the
421    environment (allowing for window resizes) [default: False].
422* smoothing  : float, optional
423    Exponential moving average smoothing factor for speed estimates
424    (ignored in GUI mode). Ranges from 0 (average speed) to 1
425    (current/instantaneous speed) [default: 0.3].
426* bar_format  : str, optional
427    Specify a custom bar string formatting. May impact performance.
428    [default: '{l_bar}{bar}{r_bar}'], where
429    l_bar='{desc}: {percentage:3.0f}%|' and
430    r_bar='| {n_fmt}/{total_fmt} [{elapsed}<{remaining}, '
431    '{rate_fmt}{postfix}]'
432    Possible vars: l_bar, bar, r_bar, n, n_fmt, total, total_fmt,
433    percentage, elapsed, elapsed_s, ncols, nrows, desc, unit,
434    rate, rate_fmt, rate_noinv, rate_noinv_fmt,
435    rate_inv, rate_inv_fmt, postfix, unit_divisor,
436    remaining, remaining_s, eta.
437    Note that a trailing ": " is automatically removed after {desc}
438    if the latter is empty.
439* initial  : int or float, optional
440    The initial counter value. Useful when restarting a progress
441    bar [default: 0]. If using float, consider specifying ``{n:.3f}``
442    or similar in ``bar_format``, or specifying ``unit_scale``.
443* position  : int, optional
444    Specify the line offset to print this bar (starting from 0)
445    Automatic if unspecified.
446    Useful to manage multiple bars at once (eg, from threads).
447* postfix  : dict or ``*``, optional
448    Specify additional stats to display at the end of the bar.
449    Calls ``set_postfix(**postfix)`` if possible (dict).
450* unit_divisor  : float, optional
451    [default: 1000], ignored unless ``unit_scale`` is True.
452* write_bytes  : bool, optional
453    If (default: None) and ``file`` is unspecified,
454    bytes will be written in Python 2. If ``True`` will also write
455    bytes. In all other cases will default to unicode.
456* lock_args  : tuple, optional
457    Passed to ``refresh`` for intermediate output
458    (initialisation, iterating, and updating).
459* nrows  : int, optional
460    The screen height. If specified, hides nested bars outside this
461    bound. If unspecified, attempts to use environment height.
462    The fallback is 20.
463* colour  : str, optional
464    Bar colour (e.g. 'green', '#00ff00').
465* delay  : float, optional
466    Don't display until [default: 0] seconds have elapsed.
467
468Extra CLI Options
469~~~~~~~~~~~~~~~~~
470
471* delim  : chr, optional
472    Delimiting character [default: '\n']. Use '\0' for null.
473    N.B.: on Windows systems, Python converts '\n' to '\r\n'.
474* buf_size  : int, optional
475    String buffer size in bytes [default: 256]
476    used when ``delim`` is specified.
477* bytes  : bool, optional
478    If true, will count bytes, ignore ``delim``, and default
479    ``unit_scale`` to True, ``unit_divisor`` to 1024, and ``unit`` to 'B'.
480* tee  : bool, optional
481    If true, passes ``stdin`` to both ``stderr`` and ``stdout``.
482* update  : bool, optional
483    If true, will treat input as newly elapsed iterations,
484    i.e. numbers to pass to ``update()``. Note that this is slow
485    (~2e5 it/s) since every input must be decoded as a number.
486* update_to  : bool, optional
487    If true, will treat input as total elapsed iterations,
488    i.e. numbers to assign to ``self.n``. Note that this is slow
489    (~2e5 it/s) since every input must be decoded as a number.
490* null  : bool, optional
491    If true, will discard input (no stdout).
492* manpath  : str, optional
493    Directory in which to install tqdm man pages.
494* comppath  : str, optional
495    Directory in which to place tqdm completion.
496* log  : str, optional
497    CRITICAL|FATAL|ERROR|WARN(ING)|[default: 'INFO']|DEBUG|NOTSET.
498
499Returns
500~~~~~~~
501
502* out  : decorated iterator.
503
504.. code:: python
505
506    class tqdm():
507      def update(self, n=1):
508          """
509          Manually update the progress bar, useful for streams
510          such as reading files.
511          E.g.:
512          >>> t = tqdm(total=filesize) # Initialise
513          >>> for current_buffer in stream:
514          ...    ...
515          ...    t.update(len(current_buffer))
516          >>> t.close()
517          The last line is highly recommended, but possibly not necessary if
518          ``t.update()`` will be called in such a way that ``filesize`` will be
519          exactly reached and printed.
520
521          Parameters
522          ----------
523          n  : int or float, optional
524              Increment to add to the internal counter of iterations
525              [default: 1]. If using float, consider specifying ``{n:.3f}``
526              or similar in ``bar_format``, or specifying ``unit_scale``.
527
528          Returns
529          -------
530          out  : bool or None
531              True if a ``display()`` was triggered.
532          """
533
534      def close(self):
535          """Cleanup and (if leave=False) close the progressbar."""
536
537      def clear(self, nomove=False):
538          """Clear current bar display."""
539
540      def refresh(self):
541          """
542          Force refresh the display of this bar.
543
544          Parameters
545          ----------
546          nolock  : bool, optional
547              If ``True``, does not lock.
548              If [default: ``False``]: calls ``acquire()`` on internal lock.
549          lock_args  : tuple, optional
550              Passed to internal lock's ``acquire()``.
551              If specified, will only ``display()`` if ``acquire()`` returns ``True``.
552          """
553
554      def unpause(self):
555          """Restart tqdm timer from last print time."""
556
557      def reset(self, total=None):
558          """
559          Resets to 0 iterations for repeated use.
560
561          Consider combining with ``leave=True``.
562
563          Parameters
564          ----------
565          total  : int or float, optional. Total to use for the new bar.
566          """
567
568      def set_description(self, desc=None, refresh=True):
569          """
570          Set/modify description of the progress bar.
571
572          Parameters
573          ----------
574          desc  : str, optional
575          refresh  : bool, optional
576              Forces refresh [default: True].
577          """
578
579      def set_postfix(self, ordered_dict=None, refresh=True, **tqdm_kwargs):
580          """
581          Set/modify postfix (additional stats)
582          with automatic formatting based on datatype.
583
584          Parameters
585          ----------
586          ordered_dict  : dict or OrderedDict, optional
587          refresh  : bool, optional
588              Forces refresh [default: True].
589          kwargs  : dict, optional
590          """
591
592      @classmethod
593      def write(cls, s, file=sys.stdout, end="\n"):
594          """Print a message via tqdm (without overlap with bars)."""
595
596      @property
597      def format_dict(self):
598          """Public API for read-only member access."""
599
600      def display(self, msg=None, pos=None):
601          """
602          Use ``self.sp`` to display ``msg`` in the specified ``pos``.
603
604          Consider overloading this function when inheriting to use e.g.:
605          ``self.some_frontend(**self.format_dict)`` instead of ``self.sp``.
606
607          Parameters
608          ----------
609          msg  : str, optional. What to display (default: ``repr(self)``).
610          pos  : int, optional. Position to ``moveto``
611            (default: ``abs(self.pos)``).
612          """
613
614      @classmethod
615      @contextmanager
616      def wrapattr(cls, stream, method, total=None, bytes=True, **tqdm_kwargs):
617          """
618          stream  : file-like object.
619          method  : str, "read" or "write". The result of ``read()`` and
620              the first argument of ``write()`` should have a ``len()``.
621
622          >>> with tqdm.wrapattr(file_obj, "read", total=file_obj.size) as fobj:
623          ...     while True:
624          ...         chunk = fobj.read(chunk_size)
625          ...         if not chunk:
626          ...             break
627          """
628
629      @classmethod
630      def pandas(cls, *targs, **tqdm_kwargs):
631          """Registers the current `tqdm` class with `pandas`."""
632
633    def trange(*args, **tqdm_kwargs):
634        """
635        A shortcut for `tqdm(xrange(*args), **tqdm_kwargs)`.
636        On Python3+, `range` is used instead of `xrange`.
637        """
638
639Convenience Functions
640~~~~~~~~~~~~~~~~~~~~~
641
642.. code:: python
643
644    def tqdm.contrib.tenumerate(iterable, start=0, total=None,
645                                tqdm_class=tqdm.auto.tqdm, **tqdm_kwargs):
646        """Equivalent of `numpy.ndenumerate` or builtin `enumerate`."""
647
648    def tqdm.contrib.tzip(iter1, *iter2plus, **tqdm_kwargs):
649        """Equivalent of builtin `zip`."""
650
651    def tqdm.contrib.tmap(function, *sequences, **tqdm_kwargs):
652        """Equivalent of builtin `map`."""
653
654Submodules
655~~~~~~~~~~
656
657.. code:: python
658
659    class tqdm.notebook.tqdm(tqdm.tqdm):
660        """IPython/Jupyter Notebook widget."""
661
662    class tqdm.auto.tqdm(tqdm.tqdm):
663        """Automatically chooses beween `tqdm.notebook` and `tqdm.tqdm`."""
664
665    class tqdm.asyncio.tqdm(tqdm.tqdm):
666      """Asynchronous version."""
667      @classmethod
668      def as_completed(cls, fs, *, loop=None, timeout=None, total=None,
669                       **tqdm_kwargs):
670          """Wrapper for `asyncio.as_completed`."""
671
672    class tqdm.gui.tqdm(tqdm.tqdm):
673        """Matplotlib GUI version."""
674
675    class tqdm.tk.tqdm(tqdm.tqdm):
676        """Tkinter GUI version."""
677
678    class tqdm.rich.tqdm(tqdm.tqdm):
679        """`rich.progress` version."""
680
681    class tqdm.keras.TqdmCallback(keras.callbacks.Callback):
682        """Keras callback for epoch and batch progress."""
683
684    class tqdm.dask.TqdmCallback(dask.callbacks.Callback):
685        """Dask callback for task progress."""
686
687
688``contrib``
689+++++++++++
690
691The ``tqdm.contrib`` package also contains experimental modules:
692
693- ``tqdm.contrib.itertools``: Thin wrappers around ``itertools``
694- ``tqdm.contrib.concurrent``: Thin wrappers around ``concurrent.futures``
695- ``tqdm.contrib.discord``: Posts to `Discord <https://discord.com>`__ bots
696- ``tqdm.contrib.telegram``: Posts to `Telegram <https://telegram.org>`__ bots
697- ``tqdm.contrib.bells``: Automagically enables all optional features
698
699  * ``auto``, ``pandas``, ``discord``, ``telegram``
700
701Examples and Advanced Usage
702---------------------------
703
704- See the `examples <https://github.com/tqdm/tqdm/tree/master/examples>`__
705  folder;
706- import the module and run ``help()``;
707- consult the `wiki <https://github.com/tqdm/tqdm/wiki>`__;
708
709  * this has an
710    `excellent article <https://github.com/tqdm/tqdm/wiki/How-to-make-a-great-Progress-Bar>`__
711    on how to make a **great** progressbar;
712
713- check out the `slides from PyData London <https://tqdm.github.io/PyData2019/slides.html>`__, or
714- run the |binder-demo|.
715
716Description and additional stats
717~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
718
719Custom information can be displayed and updated dynamically on ``tqdm`` bars
720with the ``desc`` and ``postfix`` arguments:
721
722.. code:: python
723
724    from tqdm import tqdm, trange
725    from random import random, randint
726    from time import sleep
727
728    with trange(10) as t:
729        for i in t:
730            # Description will be displayed on the left
731            t.set_description('GEN %i' % i)
732            # Postfix will be displayed on the right,
733            # formatted automatically based on argument's datatype
734            t.set_postfix(loss=random(), gen=randint(1,999), str='h',
735                          lst=[1, 2])
736            sleep(0.1)
737
738    with tqdm(total=10, bar_format="{postfix[0]} {postfix[1][value]:>8.2g}",
739              postfix=["Batch", dict(value=0)]) as t:
740        for i in range(10):
741            sleep(0.1)
742            t.postfix[1]["value"] = i / 2
743            t.update()
744
745Points to remember when using ``{postfix[...]}`` in the ``bar_format`` string:
746
747- ``postfix`` also needs to be passed as an initial argument in a compatible
748  format, and
749- ``postfix`` will be auto-converted to a string if it is a ``dict``-like
750  object. To prevent this behaviour, insert an extra item into the dictionary
751  where the key is not a string.
752
753Additional ``bar_format`` parameters may also be defined by overriding
754``format_dict``, and the bar itself may be modified using ``ascii``:
755
756.. code:: python
757
758    from tqdm import tqdm
759    class TqdmExtraFormat(tqdm):
760        """Provides a `total_time` format parameter"""
761        @property
762        def format_dict(self):
763            d = super(TqdmExtraFormat, self).format_dict
764            total_time = d["elapsed"] * (d["total"] or 0) / max(d["n"], 1)
765            d.update(total_time=self.format_interval(total_time) + " in total")
766            return d
767
768    for i in TqdmExtraFormat(
769          range(9), ascii=" .oO0",
770          bar_format="{total_time}: {percentage:.0f}%|{bar}{r_bar}"):
771        if i == 4:
772            break
773
774.. code::
775
776    00:00 in total: 44%|0000.     | 4/9 [00:00<00:00, 962.93it/s]
777
778Note that ``{bar}`` also supports a format specifier ``[width][type]``.
779
780- ``width``
781
782  * unspecified (default): automatic to fill ``ncols``
783  * ``int >= 0``: fixed width overriding ``ncols`` logic
784  * ``int < 0``: subtract from the automatic default
785
786- ``type``
787
788  * ``a``: ascii (``ascii=True`` override)
789  * ``u``: unicode (``ascii=False`` override)
790  * ``b``: blank (``ascii="  "`` override)
791
792This means a fixed bar with right-justified text may be created by using:
793``bar_format="{l_bar}{bar:10}|{bar:-10b}right-justified"``
794
795Nested progress bars
796~~~~~~~~~~~~~~~~~~~~
797
798``tqdm`` supports nested progress bars. Here's an example:
799
800.. code:: python
801
802    from tqdm.auto import trange
803    from time import sleep
804
805    for i in trange(4, desc='1st loop'):
806        for j in trange(5, desc='2nd loop'):
807            for k in trange(50, desc='3rd loop', leave=False):
808                sleep(0.01)
809
810For manual control over positioning (e.g. for multi-processing use),
811you may specify ``position=n`` where ``n=0`` for the outermost bar,
812``n=1`` for the next, and so on.
813However, it's best to check if ``tqdm`` can work without manual ``position``
814first.
815
816.. code:: python
817
818    from time import sleep
819    from tqdm import trange, tqdm
820    from multiprocessing import Pool, RLock, freeze_support
821
822    L = list(range(9))
823
824    def progresser(n):
825        interval = 0.001 / (n + 2)
826        total = 5000
827        text = "#{}, est. {:<04.2}s".format(n, interval * total)
828        for _ in trange(total, desc=text, position=n):
829            sleep(interval)
830
831    if __name__ == '__main__':
832        freeze_support()  # for Windows support
833        tqdm.set_lock(RLock())  # for managing output contention
834        p = Pool(initializer=tqdm.set_lock, initargs=(tqdm.get_lock(),))
835        p.map(progresser, L)
836
837Note that in Python 3, ``tqdm.write`` is thread-safe:
838
839.. code:: python
840
841    from time import sleep
842    from tqdm import tqdm, trange
843    from concurrent.futures import ThreadPoolExecutor
844
845    L = list(range(9))
846
847    def progresser(n):
848        interval = 0.001 / (n + 2)
849        total = 5000
850        text = "#{}, est. {:<04.2}s".format(n, interval * total)
851        for _ in trange(total, desc=text):
852            sleep(interval)
853        if n == 6:
854            tqdm.write("n == 6 completed.")
855            tqdm.write("`tqdm.write()` is thread-safe in py3!")
856
857    if __name__ == '__main__':
858        with ThreadPoolExecutor() as p:
859            p.map(progresser, L)
860
861Hooks and callbacks
862~~~~~~~~~~~~~~~~~~~
863
864``tqdm`` can easily support callbacks/hooks and manual updates.
865Here's an example with ``urllib``:
866
867**``urllib.urlretrieve`` documentation**
868
869    | [...]
870    | If present, the hook function will be called once
871    | on establishment of the network connection and once after each block read
872    | thereafter. The hook will be passed three arguments; a count of blocks
873    | transferred so far, a block size in bytes, and the total size of the file.
874    | [...]
875
876.. code:: python
877
878    import urllib, os
879    from tqdm import tqdm
880    urllib = getattr(urllib, 'request', urllib)
881
882    class TqdmUpTo(tqdm):
883        """Provides `update_to(n)` which uses `tqdm.update(delta_n)`."""
884        def update_to(self, b=1, bsize=1, tsize=None):
885            """
886            b  : int, optional
887                Number of blocks transferred so far [default: 1].
888            bsize  : int, optional
889                Size of each block (in tqdm units) [default: 1].
890            tsize  : int, optional
891                Total size (in tqdm units). If [default: None] remains unchanged.
892            """
893            if tsize is not None:
894                self.total = tsize
895            return self.update(b * bsize - self.n)  # also sets self.n = b * bsize
896
897    eg_link = "https://caspersci.uk.to/matryoshka.zip"
898    with TqdmUpTo(unit='B', unit_scale=True, unit_divisor=1024, miniters=1,
899                  desc=eg_link.split('/')[-1]) as t:  # all optional kwargs
900        urllib.urlretrieve(eg_link, filename=os.devnull,
901                           reporthook=t.update_to, data=None)
902        t.total = t.n
903
904Inspired by `twine#242 <https://github.com/pypa/twine/pull/242>`__.
905Functional alternative in
906`examples/tqdm_wget.py <https://github.com/tqdm/tqdm/blob/master/examples/tqdm_wget.py>`__.
907
908It is recommend to use ``miniters=1`` whenever there is potentially
909large differences in iteration speed (e.g. downloading a file over
910a patchy connection).
911
912**Wrapping read/write methods**
913
914To measure throughput through a file-like object's ``read`` or ``write``
915methods, use ``CallbackIOWrapper``:
916
917.. code:: python
918
919    from tqdm.auto import tqdm
920    from tqdm.utils import CallbackIOWrapper
921
922    with tqdm(total=file_obj.size,
923              unit='B', unit_scale=True, unit_divisor=1024) as t:
924        fobj = CallbackIOWrapper(t.update, file_obj, "read")
925        while True:
926            chunk = fobj.read(chunk_size)
927            if not chunk:
928                break
929        t.reset()
930        # ... continue to use `t` for something else
931
932Alternatively, use the even simpler ``wrapattr`` convenience function,
933which would condense both the ``urllib`` and ``CallbackIOWrapper`` examples
934down to:
935
936.. code:: python
937
938    import urllib, os
939    from tqdm import tqdm
940
941    eg_link = "https://caspersci.uk.to/matryoshka.zip"
942    response = getattr(urllib, 'request', urllib).urlopen(eg_link)
943    with tqdm.wrapattr(open(os.devnull, "wb"), "write",
944                       miniters=1, desc=eg_link.split('/')[-1],
945                       total=getattr(response, 'length', None)) as fout:
946        for chunk in response:
947            fout.write(chunk)
948
949The ``requests`` equivalent is nearly identical:
950
951.. code:: python
952
953    import requests, os
954    from tqdm import tqdm
955
956    eg_link = "https://caspersci.uk.to/matryoshka.zip"
957    response = requests.get(eg_link, stream=True)
958    with tqdm.wrapattr(open(os.devnull, "wb"), "write",
959                       miniters=1, desc=eg_link.split('/')[-1],
960                       total=int(response.headers.get('content-length', 0))) as fout:
961        for chunk in response.iter_content(chunk_size=4096):
962            fout.write(chunk)
963
964**Custom callback**
965
966``tqdm`` is known for intelligently skipping unnecessary displays. To make a
967custom callback take advantage of this, simply use the return value of
968``update()``. This is set to ``True`` if a ``display()`` was triggered.
969
970.. code:: python
971
972    from tqdm.auto import tqdm as std_tqdm
973
974    def external_callback(*args, **kwargs):
975        ...
976
977    class TqdmExt(std_tqdm):
978        def update(self, n=1):
979            displayed = super(TqdmExt, self).update(n):
980            if displayed:
981                external_callback(**self.format_dict)
982            return displayed
983
984``asyncio``
985~~~~~~~~~~~
986
987Note that ``break`` isn't currently caught by asynchronous iterators.
988This means that ``tqdm`` cannot clean up after itself in this case:
989
990.. code:: python
991
992    from tqdm.asyncio import tqdm
993
994    async for i in tqdm(range(9)):
995        if i == 2:
996            break
997
998Instead, either call ``pbar.close()`` manually or use the context manager syntax:
999
1000.. code:: python
1001
1002    from tqdm.asyncio import tqdm
1003
1004    with tqdm(range(9)) as pbar:
1005        async for i in pbar:
1006            if i == 2:
1007                break
1008
1009Pandas Integration
1010~~~~~~~~~~~~~~~~~~
1011
1012Due to popular demand we've added support for ``pandas`` -- here's an example
1013for ``DataFrame.progress_apply`` and ``DataFrameGroupBy.progress_apply``:
1014
1015.. code:: python
1016
1017    import pandas as pd
1018    import numpy as np
1019    from tqdm import tqdm
1020
1021    df = pd.DataFrame(np.random.randint(0, 100, (100000, 6)))
1022
1023    # Register `pandas.progress_apply` and `pandas.Series.map_apply` with `tqdm`
1024    # (can use `tqdm.gui.tqdm`, `tqdm.notebook.tqdm`, optional kwargs, etc.)
1025    tqdm.pandas(desc="my bar!")
1026
1027    # Now you can use `progress_apply` instead of `apply`
1028    # and `progress_map` instead of `map`
1029    df.progress_apply(lambda x: x**2)
1030    # can also groupby:
1031    # df.groupby(0).progress_apply(lambda x: x**2)
1032
1033In case you're interested in how this works (and how to modify it for your
1034own callbacks), see the
1035`examples <https://github.com/tqdm/tqdm/tree/master/examples>`__
1036folder or import the module and run ``help()``.
1037
1038Keras Integration
1039~~~~~~~~~~~~~~~~~
1040
1041A ``keras`` callback is also available:
1042
1043.. code:: python
1044
1045    from tqdm.keras import TqdmCallback
1046
1047    ...
1048
1049    model.fit(..., verbose=0, callbacks=[TqdmCallback()])
1050
1051Dask Integration
1052~~~~~~~~~~~~~~~~
1053
1054A ``dask`` callback is also available:
1055
1056.. code:: python
1057
1058    from tqdm.dask import TqdmCallback
1059
1060    with TqdmCallback(desc="compute"):
1061        ...
1062        arr.compute()
1063
1064    # or use callback globally
1065    cb = TqdmCallback(desc="global")
1066    cb.register()
1067    arr.compute()
1068
1069IPython/Jupyter Integration
1070~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1071
1072IPython/Jupyter is supported via the ``tqdm.notebook`` submodule:
1073
1074.. code:: python
1075
1076    from tqdm.notebook import trange, tqdm
1077    from time import sleep
1078
1079    for i in trange(3, desc='1st loop'):
1080        for j in tqdm(range(100), desc='2nd loop'):
1081            sleep(0.01)
1082
1083In addition to ``tqdm`` features, the submodule provides a native Jupyter
1084widget (compatible with IPython v1-v4 and Jupyter), fully working nested bars
1085and colour hints (blue: normal, green: completed, red: error/interrupt,
1086light blue: no ETA); as demonstrated below.
1087
1088|Screenshot-Jupyter1|
1089|Screenshot-Jupyter2|
1090|Screenshot-Jupyter3|
1091
1092The ``notebook`` version supports percentage or pixels for overall width
1093(e.g.: ``ncols='100%'`` or ``ncols='480px'``).
1094
1095It is also possible to let ``tqdm`` automatically choose between
1096console or notebook versions by using the ``autonotebook`` submodule:
1097
1098.. code:: python
1099
1100    from tqdm.autonotebook import tqdm
1101    tqdm.pandas()
1102
1103Note that this will issue a ``TqdmExperimentalWarning`` if run in a notebook
1104since it is not meant to be possible to distinguish between ``jupyter notebook``
1105and ``jupyter console``. Use ``auto`` instead of ``autonotebook`` to suppress
1106this warning.
1107
1108Note that notebooks will display the bar in the cell where it was created.
1109This may be a different cell from the one where it is used.
1110If this is not desired, either
1111
1112- delay the creation of the bar to the cell where it must be displayed, or
1113- create the bar with ``display=False``, and in a later cell call
1114  ``display(bar.container)``:
1115
1116.. code:: python
1117
1118    from tqdm.notebook import tqdm
1119    pbar = tqdm(..., display=False)
1120
1121.. code:: python
1122
1123    # different cell
1124    display(pbar.container)
1125
1126The ``keras`` callback has a ``display()`` method which can be used likewise:
1127
1128.. code:: python
1129
1130    from tqdm.keras import TqdmCallback
1131    cbk = TqdmCallback(display=False)
1132
1133.. code:: python
1134
1135    # different cell
1136    cbk.display()
1137    model.fit(..., verbose=0, callbacks=[cbk])
1138
1139Another possibility is to have a single bar (near the top of the notebook)
1140which is constantly re-used (using ``reset()`` rather than ``close()``).
1141For this reason, the notebook version (unlike the CLI version) does not
1142automatically call ``close()`` upon ``Exception``.
1143
1144.. code:: python
1145
1146    from tqdm.notebook import tqdm
1147    pbar = tqdm()
1148
1149.. code:: python
1150
1151    # different cell
1152    iterable = range(100)
1153    pbar.reset(total=len(iterable))  # initialise with new `total`
1154    for i in iterable:
1155        pbar.update()
1156    pbar.refresh()  # force print final status but don't `close()`
1157
1158Custom Integration
1159~~~~~~~~~~~~~~~~~~
1160
1161To change the default arguments (such as making ``dynamic_ncols=True``),
1162simply use built-in Python magic:
1163
1164.. code:: python
1165
1166    from functools import partial
1167    from tqdm import tqdm as std_tqdm
1168    tqdm = partial(std_tqdm, dynamic_ncols=True)
1169
1170For further customisation,
1171``tqdm`` may be inherited from to create custom callbacks (as with the
1172``TqdmUpTo`` example `above <#hooks-and-callbacks>`__) or for custom frontends
1173(e.g. GUIs such as notebook or plotting packages). In the latter case:
1174
11751. ``def __init__()`` to call ``super().__init__(..., gui=True)`` to disable
1176   terminal ``status_printer`` creation.
11772. Redefine: ``close()``, ``clear()``, ``display()``.
1178
1179Consider overloading ``display()`` to use e.g.
1180``self.frontend(**self.format_dict)`` instead of ``self.sp(repr(self))``.
1181
1182Some submodule examples of inheritance:
1183
1184- `tqdm/notebook.py <https://github.com/tqdm/tqdm/blob/master/tqdm/notebook.py>`__
1185- `tqdm/gui.py <https://github.com/tqdm/tqdm/blob/master/tqdm/gui.py>`__
1186- `tqdm/tk.py <https://github.com/tqdm/tqdm/blob/master/tqdm/tk.py>`__
1187- `tqdm/contrib/telegram.py <https://github.com/tqdm/tqdm/blob/master/tqdm/contrib/telegram.py>`__
1188- `tqdm/contrib/discord.py <https://github.com/tqdm/tqdm/blob/master/tqdm/contrib/discord.py>`__
1189
1190Dynamic Monitor/Meter
1191~~~~~~~~~~~~~~~~~~~~~
1192
1193You can use a ``tqdm`` as a meter which is not monotonically increasing.
1194This could be because ``n`` decreases (e.g. a CPU usage monitor) or ``total``
1195changes.
1196
1197One example would be recursively searching for files. The ``total`` is the
1198number of objects found so far, while ``n`` is the number of those objects which
1199are files (rather than folders):
1200
1201.. code:: python
1202
1203    from tqdm import tqdm
1204    import os.path
1205
1206    def find_files_recursively(path, show_progress=True):
1207        files = []
1208        # total=1 assumes `path` is a file
1209        t = tqdm(total=1, unit="file", disable=not show_progress)
1210        if not os.path.exists(path):
1211            raise IOError("Cannot find:" + path)
1212
1213        def append_found_file(f):
1214            files.append(f)
1215            t.update()
1216
1217        def list_found_dir(path):
1218            """returns os.listdir(path) assuming os.path.isdir(path)"""
1219            listing = os.listdir(path)
1220            # subtract 1 since a "file" we found was actually this directory
1221            t.total += len(listing) - 1
1222            # fancy way to give info without forcing a refresh
1223            t.set_postfix(dir=path[-10:], refresh=False)
1224            t.update(0)  # may trigger a refresh
1225            return listing
1226
1227        def recursively_search(path):
1228            if os.path.isdir(path):
1229                for f in list_found_dir(path):
1230                    recursively_search(os.path.join(path, f))
1231            else:
1232                append_found_file(path)
1233
1234        recursively_search(path)
1235        t.set_postfix(dir=path)
1236        t.close()
1237        return files
1238
1239Using ``update(0)`` is a handy way to let ``tqdm`` decide when to trigger a
1240display refresh to avoid console spamming.
1241
1242Writing messages
1243~~~~~~~~~~~~~~~~
1244
1245This is a work in progress (see
1246`#737 <https://github.com/tqdm/tqdm/issues/737>`__).
1247
1248Since ``tqdm`` uses a simple printing mechanism to display progress bars,
1249you should not write any message in the terminal using ``print()`` while
1250a progressbar is open.
1251
1252To write messages in the terminal without any collision with ``tqdm`` bar
1253display, a ``.write()`` method is provided:
1254
1255.. code:: python
1256
1257    from tqdm.auto import tqdm, trange
1258    from time import sleep
1259
1260    bar = trange(10)
1261    for i in bar:
1262        # Print using tqdm class method .write()
1263        sleep(0.1)
1264        if not (i % 3):
1265            tqdm.write("Done task %i" % i)
1266        # Can also use bar.write()
1267
1268By default, this will print to standard output ``sys.stdout``. but you can
1269specify any file-like object using the ``file`` argument. For example, this
1270can be used to redirect the messages writing to a log file or class.
1271
1272Redirecting writing
1273~~~~~~~~~~~~~~~~~~~
1274
1275If using a library that can print messages to the console, editing the library
1276by  replacing ``print()`` with ``tqdm.write()`` may not be desirable.
1277In that case, redirecting ``sys.stdout`` to ``tqdm.write()`` is an option.
1278
1279To redirect ``sys.stdout``, create a file-like class that will write
1280any input string to ``tqdm.write()``, and supply the arguments
1281``file=sys.stdout, dynamic_ncols=True``.
1282
1283A reusable canonical example is given below:
1284
1285.. code:: python
1286
1287    from time import sleep
1288    import contextlib
1289    import sys
1290    from tqdm import tqdm
1291    from tqdm.contrib import DummyTqdmFile
1292
1293
1294    @contextlib.contextmanager
1295    def std_out_err_redirect_tqdm():
1296        orig_out_err = sys.stdout, sys.stderr
1297        try:
1298            sys.stdout, sys.stderr = map(DummyTqdmFile, orig_out_err)
1299            yield orig_out_err[0]
1300        # Relay exceptions
1301        except Exception as exc:
1302            raise exc
1303        # Always restore sys.stdout/err if necessary
1304        finally:
1305            sys.stdout, sys.stderr = orig_out_err
1306
1307    def some_fun(i):
1308        print("Fee, fi, fo,".split()[i])
1309
1310    # Redirect stdout to tqdm.write() (don't forget the `as save_stdout`)
1311    with std_out_err_redirect_tqdm() as orig_stdout:
1312        # tqdm needs the original stdout
1313        # and dynamic_ncols=True to autodetect console width
1314        for i in tqdm(range(3), file=orig_stdout, dynamic_ncols=True):
1315            sleep(.5)
1316            some_fun(i)
1317
1318    # After the `with`, printing is restored
1319    print("Done!")
1320
1321Redirecting ``logging``
1322~~~~~~~~~~~~~~~~~~~~~~~
1323
1324Similar to ``sys.stdout``/``sys.stderr`` as detailed above, console ``logging``
1325may also be redirected to ``tqdm.write()``.
1326
1327Warning: if also redirecting ``sys.stdout``/``sys.stderr``, make sure to
1328redirect ``logging`` first if needed.
1329
1330Helper methods are available in ``tqdm.contrib.logging``. For example:
1331
1332.. code:: python
1333
1334    import logging
1335    from tqdm import trange
1336    from tqdm.contrib.logging import logging_redirect_tqdm
1337
1338    LOG = logging.getLogger(__name__)
1339
1340    if __name__ == '__main__':
1341        logging.basicConfig(level=logging.INFO)
1342        with logging_redirect_tqdm():
1343            for i in trange(9):
1344                if i == 4:
1345                    LOG.info("console logging redirected to `tqdm.write()`")
1346        # logging restored
1347
1348Monitoring thread, intervals and miniters
1349~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1350
1351``tqdm`` implements a few tricks to increase efficiency and reduce overhead.
1352
1353- Avoid unnecessary frequent bar refreshing: ``mininterval`` defines how long
1354  to wait between each refresh. ``tqdm`` always gets updated in the background,
1355  but it will display only every ``mininterval``.
1356- Reduce number of calls to check system clock/time.
1357- ``mininterval`` is more intuitive to configure than ``miniters``.
1358  A clever adjustment system ``dynamic_miniters`` will automatically adjust
1359  ``miniters`` to the amount of iterations that fit into time ``mininterval``.
1360  Essentially, ``tqdm`` will check if it's time to print without actually
1361  checking time. This behaviour can be still be bypassed by manually setting
1362  ``miniters``.
1363
1364However, consider a case with a combination of fast and slow iterations.
1365After a few fast iterations, ``dynamic_miniters`` will set ``miniters`` to a
1366large number. When iteration rate subsequently slows, ``miniters`` will
1367remain large and thus reduce display update frequency. To address this:
1368
1369- ``maxinterval`` defines the maximum time between display refreshes.
1370  A concurrent monitoring thread checks for overdue updates and forces one
1371  where necessary.
1372
1373The monitoring thread should not have a noticeable overhead, and guarantees
1374updates at least every 10 seconds by default.
1375This value can be directly changed by setting the ``monitor_interval`` of
1376any ``tqdm`` instance (i.e. ``t = tqdm.tqdm(...); t.monitor_interval = 2``).
1377The monitor thread may be disabled application-wide by setting
1378``tqdm.tqdm.monitor_interval = 0`` before instantiation of any ``tqdm`` bar.
1379
1380
1381Merch
1382-----
1383
1384You can buy `tqdm branded merch <https://tqdm.github.io/merch>`__ now!
1385
1386Contributions
1387-------------
1388
1389|GitHub-Commits| |GitHub-Issues| |GitHub-PRs| |OpenHub-Status| |GitHub-Contributions| |CII Best Practices|
1390
1391All source code is hosted on `GitHub <https://github.com/tqdm/tqdm>`__.
1392Contributions are welcome.
1393
1394See the
1395`CONTRIBUTING <https://github.com/tqdm/tqdm/blob/master/CONTRIBUTING.md>`__
1396file for more information.
1397
1398Developers who have made significant contributions, ranked by *SLoC*
1399(surviving lines of code,
1400`git fame <https://github.com/casperdcl/git-fame>`__ ``-wMC --excl '\.(png|gif|jpg)$'``),
1401are:
1402
1403==================== ======================================================== ==== ================================
1404Name                 ID                                                       SLoC Notes
1405==================== ======================================================== ==== ================================
1406Casper da Costa-Luis `casperdcl <https://github.com/casperdcl>`__             ~78% primary maintainer |Gift-Casper|
1407Stephen Larroque     `lrq3000 <https://github.com/lrq3000>`__                 ~10% team member
1408Martin Zugnoni       `martinzugnoni <https://github.com/martinzugnoni>`__     ~4%
1409Daniel Ecer          `de-code <https://github.com/de-code>`__                 ~2%
1410Richard Sheridan     `richardsheridan <https://github.com/richardsheridan>`__ ~1%
1411Guangshuo Chen       `chengs <https://github.com/chengs>`__                   ~1%
1412Kyle Altendorf       `altendky <https://github.com/altendky>`__               <1%
1413Matthew Stevens      `mjstevens777 <https://github.com/mjstevens777>`__       <1%
1414Hadrien Mary         `hadim <https://github.com/hadim>`__                     <1%  team member
1415Noam Yorav-Raphael   `noamraph <https://github.com/noamraph>`__               <1%  original author
1416Mikhail Korobov      `kmike <https://github.com/kmike>`__                     <1%  team member
1417==================== ======================================================== ==== ================================
1418
1419Ports to Other Languages
1420~~~~~~~~~~~~~~~~~~~~~~~~
1421
1422A list is available on
1423`this wiki page <https://github.com/tqdm/tqdm/wiki/tqdm-ports>`__.
1424
1425
1426LICENCE
1427-------
1428
1429Open Source (OSI approved): |LICENCE|
1430
1431Citation information: |DOI|
1432
1433|README-Hits| (Since 19 May 2016)
1434
1435.. |Logo| image:: https://img.tqdm.ml/logo.gif
1436.. |Screenshot| image:: https://img.tqdm.ml/tqdm.gif
1437.. |Video| image:: https://img.tqdm.ml/video.jpg
1438   :target: https://tqdm.github.io/video
1439.. |Slides| image:: https://img.tqdm.ml/slides.jpg
1440   :target: https://tqdm.github.io/PyData2019/slides.html
1441.. |Merch| image:: https://img.tqdm.ml/merch.jpg
1442   :target: https://tqdm.github.io/merch
1443.. |Build-Status| image:: https://img.shields.io/github/workflow/status/tqdm/tqdm/Test/master?logo=GitHub
1444   :target: https://github.com/tqdm/tqdm/actions?query=workflow%3ATest
1445.. |Coverage-Status| image:: https://img.shields.io/coveralls/github/tqdm/tqdm/master?logo=coveralls
1446   :target: https://coveralls.io/github/tqdm/tqdm
1447.. |Branch-Coverage-Status| image:: https://codecov.io/gh/tqdm/tqdm/branch/master/graph/badge.svg
1448   :target: https://codecov.io/gh/tqdm/tqdm
1449.. |Codacy-Grade| image:: https://app.codacy.com/project/badge/Grade/3f965571598f44549c7818f29cdcf177
1450   :target: https://www.codacy.com/gh/tqdm/tqdm/dashboard
1451.. |CII Best Practices| image:: https://bestpractices.coreinfrastructure.org/projects/3264/badge
1452   :target: https://bestpractices.coreinfrastructure.org/projects/3264
1453.. |GitHub-Status| image:: https://img.shields.io/github/tag/tqdm/tqdm.svg?maxAge=86400&logo=github&logoColor=white
1454   :target: https://github.com/tqdm/tqdm/releases
1455.. |GitHub-Forks| image:: https://img.shields.io/github/forks/tqdm/tqdm.svg?logo=github&logoColor=white
1456   :target: https://github.com/tqdm/tqdm/network
1457.. |GitHub-Stars| image:: https://img.shields.io/github/stars/tqdm/tqdm.svg?logo=github&logoColor=white
1458   :target: https://github.com/tqdm/tqdm/stargazers
1459.. |GitHub-Commits| image:: https://img.shields.io/github/commit-activity/y/tqdm/tqdm.svg?logo=git&logoColor=white
1460   :target: https://github.com/tqdm/tqdm/graphs/commit-activity
1461.. |GitHub-Issues| image:: https://img.shields.io/github/issues-closed/tqdm/tqdm.svg?logo=github&logoColor=white
1462   :target: https://github.com/tqdm/tqdm/issues?q=
1463.. |GitHub-PRs| image:: https://img.shields.io/github/issues-pr-closed/tqdm/tqdm.svg?logo=github&logoColor=white
1464   :target: https://github.com/tqdm/tqdm/pulls
1465.. |GitHub-Contributions| image:: https://img.shields.io/github/contributors/tqdm/tqdm.svg?logo=github&logoColor=white
1466   :target: https://github.com/tqdm/tqdm/graphs/contributors
1467.. |GitHub-Updated| image:: https://img.shields.io/github/last-commit/tqdm/tqdm/master.svg?logo=github&logoColor=white&label=pushed
1468   :target: https://github.com/tqdm/tqdm/pulse
1469.. |Gift-Casper| image:: https://img.shields.io/badge/dynamic/json.svg?color=ff69b4&label=gifts%20received&prefix=%C2%A3&query=%24..sum&url=https%3A%2F%2Fcaspersci.uk.to%2Fgifts.json
1470   :target: https://cdcl.ml/sponsor
1471.. |Versions| image:: https://img.shields.io/pypi/v/tqdm.svg
1472   :target: https://tqdm.github.io/releases
1473.. |PyPI-Downloads| image:: https://img.shields.io/pypi/dm/tqdm.svg?label=pypi%20downloads&logo=PyPI&logoColor=white
1474   :target: https://pepy.tech/project/tqdm
1475.. |Py-Versions| image:: https://img.shields.io/pypi/pyversions/tqdm.svg?logo=python&logoColor=white
1476   :target: https://pypi.org/project/tqdm
1477.. |Conda-Forge-Status| image:: https://img.shields.io/conda/v/conda-forge/tqdm.svg?label=conda-forge&logo=conda-forge
1478   :target: https://anaconda.org/conda-forge/tqdm
1479.. |Snapcraft| image:: https://img.shields.io/badge/snap-install-82BEA0.svg?logo=snapcraft
1480   :target: https://snapcraft.io/tqdm
1481.. |Docker| image:: https://img.shields.io/badge/docker-pull-blue.svg?logo=docker&logoColor=white
1482   :target: https://hub.docker.com/r/tqdm/tqdm
1483.. |Libraries-Rank| image:: https://img.shields.io/librariesio/sourcerank/pypi/tqdm.svg?logo=koding&logoColor=white
1484   :target: https://libraries.io/pypi/tqdm
1485.. |Libraries-Dependents| image:: https://img.shields.io/librariesio/dependent-repos/pypi/tqdm.svg?logo=koding&logoColor=white
1486    :target: https://github.com/tqdm/tqdm/network/dependents
1487.. |OpenHub-Status| image:: https://www.openhub.net/p/tqdm/widgets/project_thin_badge?format=gif
1488   :target: https://www.openhub.net/p/tqdm?ref=Thin+badge
1489.. |awesome-python| image:: https://awesome.re/mentioned-badge.svg
1490   :target: https://github.com/vinta/awesome-python
1491.. |LICENCE| image:: https://img.shields.io/pypi/l/tqdm.svg
1492   :target: https://raw.githubusercontent.com/tqdm/tqdm/master/LICENCE
1493.. |DOI| image:: https://img.shields.io/badge/DOI-10.5281/zenodo.595120-blue.svg
1494   :target: https://doi.org/10.5281/zenodo.595120
1495.. |binder-demo| image:: https://mybinder.org/badge_logo.svg
1496   :target: https://mybinder.org/v2/gh/tqdm/tqdm/master?filepath=DEMO.ipynb
1497.. |Screenshot-Jupyter1| image:: https://img.tqdm.ml/jupyter-1.gif
1498.. |Screenshot-Jupyter2| image:: https://img.tqdm.ml/jupyter-2.gif
1499.. |Screenshot-Jupyter3| image:: https://img.tqdm.ml/jupyter-3.gif
1500.. |README-Hits| image:: https://caspersci.uk.to/cgi-bin/hits.cgi?q=tqdm&style=social&r=https://github.com/tqdm/tqdm&l=https://img.tqdm.ml/favicon.png&f=https://img.tqdm.ml/logo.gif
1501   :target: https://caspersci.uk.to/cgi-bin/hits.cgi?q=tqdm&a=plot&r=https://github.com/tqdm/tqdm&l=https://img.tqdm.ml/favicon.png&f=https://img.tqdm.ml/logo.gif&style=social
1502