A Fast, Extensible Progress Bar for Python and CLI
Go to file
Stephen L 6a9e080792 better unit test for nested + fix coverage
Signed-off-by: Stephen L. <lrq3000@gmail.com>
2015-12-02 19:16:08 +01:00
examples pandas examples 2015-11-30 23:27:38 +00:00
tqdm better unit test for nested + fix coverage 2015-12-02 19:16:08 +01:00
.coveragerc Move tqdm_gui into its own file, exclude from coverage 2015-11-11 19:45:40 +00:00
.gitignore cleanup 2015-06-08 03:06:41 +05:00
.mailmap mailmap to merge duplicate auth entries 2015-06-19 12:04:55 +01:00
.travis.yml separate performance tests without coverage to increase speed, Makefile jobserver support 2015-11-12 09:38:32 +00:00
CONTRIBUTE setup.py flake8 tests and compliance, minor typos and rewording 2015-11-01 16:04:02 +00:00
LICENSE Initial commit 2013-10-26 11:50:04 -07:00
MANIFEST.in Makefile: cleaner build + remove tqdm.gif in builds 2015-11-07 23:05:58 +01:00
Makefile tox nose-timer as suggested in #52 2015-11-28 18:36:09 +00:00
README.rst update README.rst 2015-12-01 21:11:07 +01:00
RELEASE setup.py flake8 tests and compliance, minor typos and rewording 2015-11-01 16:04:02 +00:00
logo.png Add logo to tqdm 2015-06-06 16:12:49 +02:00
setup.cfg cleanup 2015-06-08 03:06:41 +05:00
setup.py separate performance tests without coverage to increase speed, Makefile jobserver support 2015-11-12 09:38:32 +00:00
tox.ini remove pandas, numpy from tox (too slow), revert manual creation of tqdm 2015-11-29 18:01:01 +00:00
tqdm.gif optimized tqdm.gif (smaller size, fixed frame delay) 2015-11-07 23:05:25 +01:00

README.rst

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

|Logo|

tqdm
====

|PyPi Status| |PyPi Downloads|
|Build Status| |Coverage Status| |Branch Coverage Status|

``tqdm`` (read taqadum, تقدّم) means "progress" in arabic.

Instantly make your loops show a progress meter - just wrap any
iterable with "tqdm(iterable)", and you're done!

.. code:: python

    from tqdm import tqdm
    for i in tqdm(range(9)):
        ...

Here's what the output looks like:

76%\|████████████████████\             \| 7641/10000 [00:34<00:10,
222.22 it/s]

``trange(N)`` can be also used as a convenient shortcut for
``tqdm(xrange(N))``.

|Screenshot|

Overhead is low -- about 60ns per iteration (80ns with ``gui=True``).
By comparison, the well established
`ProgressBar <https://code.google.com/p/python-progressbar/>`__ has
an 800ns/iter overhead. It's a matter of taste, but we also like to think our
version is much more visually appealing.

``tqdm`` works on any platform (Linux/Windows/Mac), in any console or in a
GUI, and is also friendly with IPython/Jupyter notebooks.

``tqdm`` does not require any library nor curses to run, just a Python
interpreter.


Installation
------------

Latest pypi stable release
~~~~~~~~~~~~~~~~~~~~~~~~~~

.. code:: sh

    pip install tqdm

Latest development release on github
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Pull and install in the current directory:

.. code:: sh

    pip install -e git+https://github.com/tqdm/tqdm.git@master#egg=tqdm


Documentation
-------------

.. code:: python

    class tqdm(object):
      """
      Decorate an iterable object, returning an iterator which acts exactly
      like the orignal iterable, but prints a dynamically updating
      progressbar every time a value is requested.
      """

      def __init__(self, iterable=None, desc=None, total=None, leave=False,
                   file=sys.stderr, ncols=None, mininterval=0.1,
                   maxinterval=10.0, miniters=None, ascii=None, disable=False,
                   unit='it', unit_scale=False, dynamic_ncols=False,
                   smoothing=0.3, gui=False):

Parameters
~~~~~~~~~~

* iterable  : iterable, optional  
    Iterable to decorate with a progressbar.
    Leave blank [default: None] to manually manage the updates.
* desc  : str, optional  
    Prefix for the progressbar [default: None].
* total  : int, optional  
    The number of expected iterations. If not given, len(iterable)
    is used if possible. As a last resort, only basic progress
    statistics are displayed (no ETA, no progressbar). If `gui` is
    True and this parameter needs subsequent updating, specify an
    initial arbitrary large positive integer, e.g. int(9e9).
* leave  : bool, optional  
    If [default: False], removes all traces of the progressbar
    upon termination of iteration.
* file  : `io.TextIOWrapper` or `io.StringIO`, optional  
    Specifies where to output the progress messages
    [default: sys.stderr]. Uses `file.write(str)` and `file.flush()`
    methods.
* ncols  : int, optional  
    The width of the entire output message. If specified,
    dynamically resizes the progressbar to stay within this bound.
    If [default: None], attempts to use environment width. The
    fallback is a meter width of 10 and no limit for the counter and
    statistics. If 0, will not print any meter (only stats).
* mininterval  : float, optional  
    Minimum progress update interval, in seconds [default: 0.1].
* maxinterval  : float, optional
    Maximum progress update interval, in seconds [default: 10.0].
* miniters  : int, optional  
    Minimum progress update interval, in iterations [default: None].
    If specified, will set `mininterval` to 0.
* ascii  : bool, optional  
    If [default: None] or false, use unicode (smooth blocks) to fill
    the meter. The fallback is to use ASCII characters `1-9 #`.
* disable : bool  
    Whether to disable the entire progressbar wrapper
    [default: False].
* unit  : str, optional  
    String that will be used to define the unit of each iteration
    [default: 'it'].
* unit_scale  : bool, optional  
    If set, the number of iterations will be reduced/scaled
    automatically and a metric prefix following the
    International System of Units standard will be added
    (kilo, mega, etc.) [default: False].
* dynamic_ncols  : bool, optional  
    If set, constantly alters `ncols` to the environment (allowing
    for window resizes) [default: False].
* smoothing  : float  
    Exponential moving average smoothing factor for speed estimates
    (ignored in GUI mode). Ranges from 0 (average speed) to 1
    (current/instantaneous speed) [default: 0.3].
* nested  : bool, optional
    Set this to True if your progress bar is in an inner loop.
    Allows to display multiple, nested progress bars.

Returns
~~~~~~~

* out  : decorated iterator.

.. code:: python

      def update(self, n=1):
          """
          Manually update the progress bar, useful for streams
          such as reading files.
          E.g.:
          >>> t = tqdm(total=filesize) # Initialise
          >>> for current_buffer in stream:
          ...    ...
          ...    t.update(len(current_buffer))
          >>> t.close()
          The last line is highly recommended, but possibly not necessary if
          `t.update()` will be called in such a way that `filesize` will be
          exactly reached and printed.

          Parameters
          ----------
          n  : int
              Increment to add to the internal counter of iterations
              [default: 1].
          """

      def close(self):
          """
          Cleanup and (if leave=False) close the progressbar.
          """

    def trange(*args, **kwargs):
        """
        A shortcut for tqdm(xrange(*args), **kwargs).
        On Python3+ range is used instead of xrange.
        """

    class tqdm_gui(tqdm):
        """
        Experimental GUI version of tqdm!
        """

    def tgrange(*args, **kwargs):
        """
        Experimental GUI version of trange!
        """

Examples and Advanced Usage
---------------------------

See the `examples <https://github.com/tqdm/tqdm/tree/master/examples>`__ folder or
import the module and run ``help()``.

Hooks and callbacks
~~~~~~~~~~~~~~~~~~~

``tqdm`` can easily support callbacks/hooks and manual updates.
Here's an example with ``urllib``:

**urllib.urlretrieve documentation**

    | [...]
    | If present, the hook function will be called once
    | on establishment of the network connection and once after each
      block read
    | thereafter. The hook will be passed three arguments; a count of
      blocks
    | transferred so far, a block size in bytes, and the total size of
      the file.
    | [...]

.. code:: python

    import urllib
    from tqdm import tqdm

    def my_hook(t):
      """
      Wraps tqdm instance. Don't forget to close() or __exit__()
      the tqdm instance once you're done with it (easiest using `with` syntax).

      Example
      -------

      >>> with tqdm(...) as t:
      ...     reporthook = my_hook(t)
      ...     urllib.urlretrieve(..., reporthook=reporthook)

      """
      last_b = [0]

      def inner(b=1, bsize=1, tsize=None):
        """
        b  : int, optional
            Number of blocks just transferred [default: 1].
        bsize  : int, optional
            Size of each block (in tqdm units) [default: 1].
        tsize  : int, optional
            Total size (in tqdm units). If [default: None] remains unchanged.
        """
        if tsize is not None:
            t.total = tsize
        t.update((b - last_b[0]) * bsize)
        last_b[0] = b
      return inner

    eg_link = 'http://www.doc.ic.ac.uk/~cod11/matryoshka.zip'
    with tqdm(unit='B', unit_scale=True, leave=True, miniters=1,
              desc=eg_link.split('/')[-1]) as t:  # all optional kwargs
        urllib.urlretrieve(eg_link, filename='/dev/null',
                           reporthook=my_hook(t), data=None)

It is recommend to use ``miniters=1`` whenever there is potentially
large differences in iteration speed (e.g. downloading a file over
a patchy connection).

Pandas Integration
~~~~~~~~~~~~~~~~~~

Due to popular demand we've added support for ``pandas`` -- here's an example
for ``DataFrameGroupBy.progress_apply``:

.. code:: python

    import pandas as pd
    import numpy as np
    from tqdm import tqdm, tqdm_pandas

    df = pd.DataFrame(np.random.randint(0, 100, (100000, 6)))

    # Create and register a new `tqdm` instance with `pandas`
    # (can use tqdm_gui, optional kwargs, etc.)
    tqdm_pandas(tqdm())

    # Now you can use `progress_apply` instead of `apply`
    df.groupby(0).progress_apply(lambda x: x**2)

In case you're interested in how this works (and how to modify it for your
own callbacks), see the `examples <https://github.com/tqdm/tqdm/tree/master/examples>`__
folder or import the module and run ``help()``.

Nested progress bars
~~~~~~~~~~~~~~~~~~~~

``tqdm`` supports nested progress bars, you just need to specify the
`nested=True` argument for all tqdm instanciation except the most outer bar.
Here's an example:

.. code:: python

    from tqdm import trange
    from time import sleep

    for i in trange(10, desc='1st loop', leave=True):
        for j in trange(100, desc='2nd loop', nested=True):
            sleep(0.01)

Contributions
-------------

To run the testing suite please make sure tox (http://tox.testrun.org/)
is installed, then type ``tox`` from the command line.

Alternatively if you don't want to use ``tox``, a Makefile is provided
with the following commands:

.. code:: sh

    $ make flake8
    $ make test
    $ make coverage

See the `CONTRIBUTE <https://raw.githubusercontent.com/tqdm/tqdm/master/CONTRIBUTE>`__
file for more information.


License
-------

`MIT LICENSE <https://raw.githubusercontent.com/tqdm/tqdm/master/LICENSE>`__.


Authors
-------

-  Casper da Costa-Luis (casperdcl)
-  Stephen Larroque (lrq3000)
-  Hadrien Mary (hadim)
-  Noam Yorav-Raphael (noamraph)*
-  Ivan Ivanov (obiwanus)
-  Mikhail Korobov (kmike)

`*` Original author

.. |Logo| image:: https://raw.githubusercontent.com/tqdm/tqdm/master/logo.png
.. |Build Status| image:: https://travis-ci.org/tqdm/tqdm.svg?branch=master
   :target: https://travis-ci.org/tqdm/tqdm
.. |Coverage Status| image:: https://coveralls.io/repos/tqdm/tqdm/badge.svg
   :target: https://coveralls.io/r/tqdm/tqdm
.. |Branch Coverage Status| image:: https://codecov.io/github/tqdm/tqdm/coverage.svg?branch=master
   :target: https://codecov.io/github/tqdm/tqdm?branch=master
.. |PyPi Status| image:: https://img.shields.io/pypi/v/tqdm.svg
   :target: https://pypi.python.org/pypi/tqdm
.. |PyPi Downloads| image:: https://img.shields.io/pypi/dm/tqdm.svg
   :target: https://pypi.python.org/pypi/tqdm
.. |Screenshot| image:: https://raw.githubusercontent.com/tqdm/tqdm/master/tqdm.gif