{"id":18598779,"url":"https://github.com/crazypython/tqdm-review","last_synced_at":"2025-05-16T14:12:43.786Z","repository":{"id":148713611,"uuid":"66092126","full_name":"CrazyPython/tqdm-review","owner":"CrazyPython","description":"Code review for tqdm","archived":false,"fork":false,"pushed_at":"2017-01-02T17:14:21.000Z","size":786,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-17T23:49:03.385Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/CrazyPython.png","metadata":{"files":{"readme":"README.rst","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-08-19T15:24:22.000Z","updated_at":"2017-01-02T17:11:50.000Z","dependencies_parsed_at":null,"dependency_job_id":"feb009c1-77ef-48ac-aee0-bbeee6ea5242","html_url":"https://github.com/CrazyPython/tqdm-review","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CrazyPython%2Ftqdm-review","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CrazyPython%2Ftqdm-review/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CrazyPython%2Ftqdm-review/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CrazyPython%2Ftqdm-review/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/CrazyPython","download_url":"https://codeload.github.com/CrazyPython/tqdm-review/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254544158,"owners_count":22088808,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-07T01:34:25.412Z","updated_at":"2025-05-16T14:12:43.767Z","avatar_url":"https://github.com/CrazyPython.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"|Logo|\n\ntqdm\n====\n\n|PyPI-Status| |PyPI-Versions| |Conda-Forge-Status|\n\n|Build-Status| |Coverage-Status| |Branch-Coverage-Status| |Codacy-Grade|\n\n|DOI-URI| |LICENCE|\n\n\n``tqdm`` means \"progress\" in Arabic (taqadum, تقدّم)\nand an abbreviation for \"I love you so much\" in Spanish (te quiero demasiado).\n\nInstantly make your loops show a smart progress meter - just wrap any\niterable with ``tqdm(iterable)``, and you're done!\n\n.. code:: python\n\n    from tqdm import tqdm\n    for i in tqdm(range(10000)):\n        ...\n\n``76%|████████████████████████████         | 7568/10000 [00:33\u003c00:10, 229.00it/s]``\n\n``trange(N)`` can be also used as a convenient shortcut for\n``tqdm(xrange(N))``.\n\n|Screenshot|\n    REPL: `ptpython \u003chttps://github.com/jonathanslenders/ptpython\u003e`__\n\nIt can also be executed as a module with pipes:\n\n.. code:: sh\n\n    $ seq 9999999 | tqdm --unit_scale | wc -l\n    10.0Mit [00:02, 3.58Mit/s]\n    9999999\n    $ 7z a -bd -r backup.7z docs/ | grep Compressing | \\\n        tqdm --total $(find docs/ -type f | wc -l) --unit files \u003e\u003e backup.log\n    100%|███████████████████████████████▉| 8014/8014 [01:37\u003c00:00, 82.29files/s]\n\nOverhead is low -- about 60ns per iteration (80ns with ``tqdm_gui``), and is\nunit tested against performance regression.\nBy comparison, the well established\n`ProgressBar \u003chttps://github.com/niltonvolpato/python-progressbar\u003e`__ has\nan 800ns/iter overhead.\n\nIn addition to its low overhead, ``tqdm`` uses smart algorithms to predict\nthe remaining time and to skip unnecessary iteration displays, which allows\nfor a negligible overhead in most cases.\n\n``tqdm`` works on any platform (Linux, Windows, Mac, FreeBSD, Solaris/SunOS),\nin any console or in a GUI, and is also friendly with IPython/Jupyter notebooks.\n\n``tqdm`` does not require any library (not even curses!) to run, just a\nvanilla Python interpreter will do and an environment supporting ``carriage\nreturn \\r`` and ``line feed \\n`` control characters.\n\n------------------------------------------\n\n.. contents:: Table of contents\n   :backlinks: top\n   :local:\n\n\nInstallation\n------------\n\nLatest PyPI stable release\n~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n|PyPI-Status|\n\n.. code:: sh\n\n    pip install tqdm\n\nLatest development release on github\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n|GitHub-Status| |GitHub-Stars| |GitHub-Forks|\n\nPull and install in the current directory:\n\n.. code:: sh\n\n    pip install -e git+https://github.com/tqdm/tqdm.git@master#egg=tqdm\n\nLatest Conda release\n~~~~~~~~~~~~~~~~~~~~\n\n|Conda-Forge-Status|\n\n.. code:: sh\n\n    conda install -c conda-forge tqdm\n\n\nChangelog\n---------\n\nThe list of all changes is available either on GitHub's Releases:\n|GitHub-Status| or on crawlers such as\n`allmychanges.com \u003chttps://allmychanges.com/p/python/tqdm/\u003e`_.\n\n\nUsage\n-----\n\n``tqdm`` is very versatile and can be used in a number of ways.\nThe three main ones are given below.\n\nIterable-based\n~~~~~~~~~~~~~~\n\nWrap ``tqdm()`` around any iterable:\n\n.. code:: python\n\n    text = \"\"\n    for char in tqdm([\"a\", \"b\", \"c\", \"d\"]):\n        text = text + char\n\n``trange(i)`` is a special optimised instance of ``tqdm(range(i))``:\n\n.. code:: python\n\n    for i in trange(100):\n        pass\n\nInstantiation outside of the loop allows for manual control over ``tqdm()``:\n\n.. code:: python\n\n    pbar = tqdm([\"a\", \"b\", \"c\", \"d\"])\n    for char in pbar:\n        pbar.set_description(\"Processing %s\" % char)\n\nManual\n~~~~~~\n\nManual control on ``tqdm()`` updates by using a ``with`` statement:\n\n.. code:: python\n\n    with tqdm(total=100) as pbar:\n        for i in range(10):\n            pbar.update(10)\n\nIf the optional variable ``total`` (or an iterable with ``len()``) is\nprovided, predictive stats are displayed.\n\n``with`` is also optional (you can just assign ``tqdm()`` to a variable,\nbut in this case don't forget to ``del`` or ``close()`` at the end:\n\n.. code:: python\n\n    pbar = tqdm(total=100)\n    for i in range(10):\n        pbar.update(10)\n    pbar.close()\n\nModule\n~~~~~~\n\nPerhaps the most wonderful use of ``tqdm`` is in a script or on the command\nline. Simply inserting ``tqdm`` (or ``python -m tqdm``) between pipes will pass\nthrough all ``stdin`` to ``stdout`` while printing progress to ``stderr``.\n\nThe example below demonstrated counting the number of lines in all python files\nin the current directory, with timing information included.\n\n.. code:: sh\n\n    $ time find . -name '*.py' -exec cat \\{} \\; | wc -l\n    857365\n\n    real    0m3.458s\n    user    0m0.274s\n    sys     0m3.325s\n\n    $ time find . -name '*.py' -exec cat \\{} \\; | tqdm | wc -l\n    857366it [00:03, 246471.31it/s]\n    857365\n\n    real    0m3.585s\n    user    0m0.862s\n    sys     0m3.358s\n\nNote that the usual arguments for ``tqdm`` can also be specified.\n\n.. code:: sh\n\n    $ find . -name '*.py' -exec cat \\{} \\; |\n        tqdm --unit loc --unit_scale --total 857366 \u003e\u003e /dev/null\n    100%|███████████████████████████████████| 857K/857K [00:04\u003c00:00, 246Kloc/s]\n\nBacking up a large directory?\n\n.. code:: sh\n\n    $ 7z a -bd -r backup.7z docs/ | grep Compressing |\n        tqdm --total $(find docs/ -type f | wc -l) --unit files \u003e\u003e backup.log\n    100%|███████████████████████████████▉| 8014/8014 [01:37\u003c00:00, 82.29files/s]\n\n\nHelp!\n-----\n\nThe most common issues relate to excessive output on multiple lines, instead\nof a neat one-line progress bar.\n\n- Consoles in general: require support for carriage return (``CR``, ``\\r``).\n- Nested progress bars:\n    * Consoles in general: require support for moving cursors up to the\n      previous line. For example, `IDLE won't work \u003chttps://github.com/tqdm/tqdm/issues/191#issuecomment-230168030\u003e`__.\n    * Windows: additionally may require the python module ``colorama``.\n- Wrapping enumerated iterables: use ``enumerate(tqdm(...))`` instead of\n  ``tqdm(enumerate(...))``. The same applies to ``numpy.ndenumerate``.\n  This is because enumerate functions tend to hide the length of iterables.\n  ``tqdm`` does not.\n\nIf you come across any other difficulties, browse/open issues\n`here \u003chttps://github.com/tqdm/tqdm/issues?q=is%3Aissue\u003e`__.\n\nDocumentation\n-------------\n\n|PyPI-Versions| |README-Hits| (Since 19 May 2016)\n\n.. code:: python\n\n    class tqdm(object):\n      \"\"\"\n      Decorate an iterable object, returning an iterator which acts exactly\n      like the original iterable, but prints a dynamically updating\n      progressbar every time a value is requested.\n      \"\"\"\n\n      def __init__(self, iterable=None, desc=None, total=None, leave=True,\n                   file=sys.stderr, ncols=None, mininterval=0.1,\n                   maxinterval=10.0, miniters=None, ascii=None, disable=False,\n                   unit='it', unit_scale=False, dynamic_ncols=False,\n                   smoothing=0.3, bar_format=None, initial=0, position=None):\n\nParameters\n~~~~~~~~~~\n\n* iterable  : iterable, optional  \n    Iterable to decorate with a progressbar.\n    Leave blank to manually manage the updates.\n* desc  : str, optional  \n    Prefix for the progressbar.\n* total  : int, optional  \n    The number of expected iterations. If (default: None),\n    len(iterable) is used if possible. As a last resort, only basic\n    progress statistics are displayed (no ETA, no progressbar).\n    If ``gui`` is True and this parameter needs subsequent updating,\n    specify an initial arbitrary large positive integer,\n    e.g. int(9e9).\n* leave  : bool, optional  \n    If [default: True], keeps all traces of the progressbar\n    upon termination of iteration.\n* file  : ``io.TextIOWrapper`` or ``io.StringIO``, optional  \n    Specifies where to output the progress messages\n    [default: sys.stderr]. Uses ``file.write(str)`` and ``file.flush()``\n    methods.\n* ncols  : int, optional  \n    The width of the entire output message. If specified,\n    dynamically resizes the progressbar to stay within this bound.\n    If unspecified, attempts to use environment width. The\n    fallback is a meter width of 10 and no limit for the counter and\n    statistics. If 0, will not print any meter (only stats).\n* mininterval  : float, optional  \n    Minimum progress display update interval, in seconds [default: 0.1].\n* maxinterval  : float, optional  \n    Maximum progress display update interval, in seconds [default: 10].\n    Automatically adjusts ``miniters`` to correspond to ``mininterval``\n    after long display update lag. Only works if ``dynamic_miniters``\n    or monitor thread is enabled.\n* miniters  : int, optional  \n    Minimum progress display update interval, in iterations.\n    If 0 and ``dynamic_miniters``, will automatically adjust to equal\n    ``mininterval`` (more CPU efficient, good for tight loops).\n    If \u003e 0, will skip display of specified number of iterations.\n    Tweak this and ``mininterval`` to get very efficient loops.\n    If your progress is erratic with both fast and slow iterations\n    (network, skipping items, etc) you should set miniters=1.\n* ascii  : bool, optional  \n    If unspecified or False, use unicode (smooth blocks) to fill\n    the meter. The fallback is to use ASCII characters ``1-9 #``.\n* disable  : bool, optional  \n    Whether to disable the entire progressbar wrapper\n    [default: False].\n* unit  : str, optional  \n    String that will be used to define the unit of each iteration\n    [default: it].\n* unit_scale  : bool, optional  \n    If set, the number of iterations will be reduced/scaled\n    automatically and a metric prefix following the\n    International System of Units standard will be added\n    (kilo, mega, etc.) [default: False].\n* dynamic_ncols  : bool, optional  \n    If set, constantly alters ``ncols`` to the environment (allowing\n    for window resizes) [default: False].\n* smoothing  : float, optional  \n    Exponential moving average smoothing factor for speed estimates\n    (ignored in GUI mode). Ranges from 0 (average speed) to 1\n    (current/instantaneous speed) [default: 0.3].\n* bar_format  : str, optional  \n    Specify a custom bar string formatting. May impact performance.\n    If unspecified, will use '{l_bar}{bar}{r_bar}', where l_bar is\n    '{desc}{percentage:3.0f}%|' and r_bar is\n    '| {n_fmt}/{total_fmt} [{elapsed}\u003c{remaining}, {rate_fmt}]'\n    Possible vars: bar, n, n_fmt, total, total_fmt, percentage,\n    rate, rate_fmt, elapsed, remaining, l_bar, r_bar, desc.\n* initial  : int, optional  \n    The initial counter value. Useful when restarting a progress\n    bar [default: 0].\n* position  : int, optional  \n    Specify the line offset to print this bar (starting from 0)\n    Automatic if unspecified.\n    Useful to manage multiple bars at once (eg, from threads).\n\nExtra CLI Options\n~~~~~~~~~~~~~~~~~\n\n* delim  : chr, optional  \n    Delimiting character [default: '\\n']. Use '\\0' for null.\n    N.B.: on Windows systems, Python converts '\\n' to '\\r\\n'.\n* buf_size  : int, optional  \n    String buffer size in bytes [default: 256]\n    used when ``delim`` is specified.\n* bytes  : bool, optional  \n    If true, will count bytes and ignore ``delim``.\n\nReturns\n~~~~~~~\n\n* out  : decorated iterator.\n\n.. code:: python\n\n      def update(self, n=1):\n          \"\"\"\n          Manually update the progress bar, useful for streams\n          such as reading files.\n          E.g.:\n          \u003e\u003e\u003e t = tqdm(total=filesize) # Initialise\n          \u003e\u003e\u003e for current_buffer in stream:\n          ...    ...\n          ...    t.update(len(current_buffer))\n          \u003e\u003e\u003e t.close()\n          The last line is highly recommended, but possibly not necessary if\n          ``t.update()`` will be called in such a way that ``filesize`` will be\n          exactly reached and printed.\n\n          Parameters\n          ----------\n          n  : int\n              Increment to add to the internal counter of iterations\n              [default: 1].\n          \"\"\"\n\n      def close(self):\n          \"\"\"\n          Cleanup and (if leave=False) close the progressbar.\n          \"\"\"\n\n      def clear(self):\n          \"\"\"\n          Clear current bar display\n          \"\"\"\n\n      def refresh(self):\n          \"\"\"\n          Force refresh the display of this bar\n          \"\"\"\n\n      def write(cls, s, file=sys.stdout, end=\"\\n\"):\n          \"\"\"\n          Print a message via tqdm (without overlap with bars)\n          \"\"\"\n\n    def trange(*args, **kwargs):\n        \"\"\"\n        A shortcut for tqdm(xrange(*args), **kwargs).\n        On Python3+ range is used instead of xrange.\n        \"\"\"\n\n    class tqdm_gui(tqdm):\n        \"\"\"\n        Experimental GUI version of tqdm!\n        \"\"\"\n\n    def tgrange(*args, **kwargs):\n        \"\"\"\n        Experimental GUI version of trange!\n        \"\"\"\n\n    class tqdm_notebook(tqdm):\n        \"\"\"\n        Experimental IPython/Jupyter Notebook widget using tqdm!\n        \"\"\"\n\n    def tnrange(*args, **kwargs):\n        \"\"\"\n        Experimental IPython/Jupyter Notebook widget using tqdm!\n        \"\"\"\n\n\nExamples and Advanced Usage\n---------------------------\n\n- See the `examples \u003chttps://github.com/tqdm/tqdm/tree/master/examples\u003e`__\n  folder;\n- import the module and run ``help()``, or\n- consult the `wiki \u003chttps://github.com/tqdm/tqdm/wiki\u003e`__.\n    - this has an `excellent article \u003chttps://github.com/tqdm/tqdm/wiki/How-to-make-a-great-Progress-Bar\u003e`__ on how to make a **great** progressbar.\n\nNested progress bars\n~~~~~~~~~~~~~~~~~~~~\n\n``tqdm`` supports nested progress bars. Here's an example:\n\n.. code:: python\n\n    from tqdm import trange\n    from time import sleep\n\n    for i in trange(10, desc='1st loop'):\n        for j in trange(5, desc='2nd loop', leave=False):\n            for k in trange(100, desc='3nd loop'):\n                sleep(0.01)\n\nOn Windows `colorama \u003chttps://github.com/tartley/colorama\u003e`__ will be used if\navailable to produce a beautiful nested display.\n\nFor manual control over positioning (e.g. for multi-threaded use),\nyou may specify `position=n` where `n=0` for the outermost bar,\n`n=1` for the next, and so on.\n\nHooks and callbacks\n~~~~~~~~~~~~~~~~~~~\n\n``tqdm`` can easily support callbacks/hooks and manual updates.\nHere's an example with ``urllib``:\n\n**urllib.urlretrieve documentation**\n\n    | [...]\n    | If present, the hook function will be called once\n    | on establishment of the network connection and once after each\n      block read\n    | thereafter. The hook will be passed three arguments; a count of\n      blocks\n    | transferred so far, a block size in bytes, and the total size of\n      the file.\n    | [...]\n\n.. code:: python\n\n    import urllib\n    from tqdm import tqdm\n\n    def my_hook(t):\n      \"\"\"\n      Wraps tqdm instance. Don't forget to close() or __exit__()\n      the tqdm instance once you're done with it (easiest using `with` syntax).\n\n      Example\n      -------\n\n      \u003e\u003e\u003e with tqdm(...) as t:\n      ...     reporthook = my_hook(t)\n      ...     urllib.urlretrieve(..., reporthook=reporthook)\n\n      \"\"\"\n      last_b = [0]\n\n      def inner(b=1, bsize=1, tsize=None):\n        \"\"\"\n        b  : int, optional\n            Number of blocks just transferred [default: 1].\n        bsize  : int, optional\n            Size of each block (in tqdm units) [default: 1].\n        tsize  : int, optional\n            Total size (in tqdm units). If [default: None] remains unchanged.\n        \"\"\"\n        if tsize is not None:\n            t.total = tsize\n        t.update((b - last_b[0]) * bsize)\n        last_b[0] = b\n      return inner\n\n    eg_link = 'http://www.doc.ic.ac.uk/~cod11/matryoshka.zip'\n    with tqdm(unit='B', unit_scale=True, miniters=1,\n              desc=eg_link.split('/')[-1]) as t:  # all optional kwargs\n        urllib.urlretrieve(eg_link, filename='/dev/null',\n                           reporthook=my_hook(t), data=None)\n\nIt is recommend to use ``miniters=1`` whenever there is potentially\nlarge differences in iteration speed (e.g. downloading a file over\na patchy connection).\n\nPandas Integration\n~~~~~~~~~~~~~~~~~~\n\nDue to popular demand we've added support for ``pandas`` -- here's an example\nfor ``DataFrame.progress_apply`` and ``DataFrameGroupBy.progress_apply``:\n\n.. code:: python\n\n    import pandas as pd\n    import numpy as np\n    from tqdm import tqdm\n\n    df = pd.DataFrame(np.random.randint(0, 100, (100000, 6)))\n\n    # Register `pandas.progress_apply` and `pandas.Series.map_apply` with `tqdm`\n    # (can use `tqdm_gui`, `tqdm_notebook`, optional kwargs, etc.)\n    tqdm.pandas(desc=\"my bar!\")\n\n    # Now you can use `progress_apply` instead of `apply`\n    # and `progress_map` instead of `map`\n    df.progress_apply(lambda x: x**2)\n    # can also groupby:\n    # df.groupby(0).progress_apply(lambda x: x**2)\n\nIn case you're interested in how this works (and how to modify it for your\nown callbacks), see the\n`examples \u003chttps://github.com/tqdm/tqdm/tree/master/examples\u003e`__\nfolder or import the module and run ``help()``.\n\nIPython/Jupyter Integration\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nIPython/Jupyter is supported via the `tqdm_notebook` submodule:\n\n.. code:: python\n\n    from tqdm import tnrange, tqdm_notebook\n    from time import sleep\n\n    for i in tnrange(10, desc='1st loop'):\n        for j in tqdm_notebook(xrange(100), desc='2nd loop'):\n            sleep(0.01)\n\nIn addition to `tqdm` features, the submodule provides a native Jupyter\nwidget (compatible with IPython v1-v4 and Jupyter), fully working nested bars\nand color hints (blue: normal, green: completed, red: error/interrupt,\nlight blue: no ETA); as demonstrated below.\n\n|Screenshot-Jupyter1|\n|Screenshot-Jupyter2|\n|Screenshot-Jupyter3|\n\nWriting messages\n~~~~~~~~~~~~~~~~\n\nSince ``tqdm`` uses a simple printing mechanism to display progress bars,\nyou should not write any message in the terminal using ``print()``.\n\nTo write messages in the terminal without any collision with ``tqdm`` bar\ndisplay, a ``.write()`` method is provided:\n\n.. code:: python\n\n    from tqdm import tqdm, trange\n    from time import sleep\n\n    bar = trange(10)\n    for i in bar:\n        # Print using tqdm class method .write()\n        sleep(0.1)\n        if not (i % 3):\n            tqdm.write(\"Done task %i\" % i)\n        # Can also use bar.write()\n\nBy default, this will print to standard output ``sys.stdout``. but you can\nspecify any file-like object using the ``file`` argument. For example, this\ncan be used to redirect the messages writing to a log file or class.\n\nRedirecting writing\n~~~~~~~~~~~~~~~~~~~\n\nIf using a library that can print messages to the console, editing the library\nby  replacing ``print()`` with ``tqdm.write()`` may not be desirable.\nIn that case, redirecting ``sys.stdout`` to ``tqdm.write()`` is an option.\n\nTo redirect ``sys.stdout``, create a file-like class that will write\nany input string to ``tqdm.write()``, and supply the arguments\n``file=sys.stdout, dynamic_ncols=True``.\n\nA reusable canonical example is given below:\n\n.. code:: python\n\n    from time import sleep\n\n    import contextlib\n    import sys\n\n    from tqdm import tqdm\n\n    class DummyTqdmFile(object):\n        \"\"\"Dummy file-like that will write to tqdm\"\"\"\n        file = None\n        def __init__(self, file):\n            self.file = file\n\n        def write(self, x):\n            # Avoid print() second call (useless \\n)\n            if len(x.rstrip()) \u003e 0:\n                tqdm.write(x, file=self.file)\n\n    @contextlib.contextmanager\n    def stdout_redirect_to_tqdm():\n        save_stdout = sys.stdout\n        try:\n            sys.stdout = DummyTqdmFile(sys.stdout)\n            yield save_stdout\n        # Relay exceptions\n        except Exception as exc:\n            raise exc\n        # Always restore sys.stdout if necessary\n        finally:\n            sys.stdout = save_stdout\n\n    def blabla():\n        print(\"Foo blabla\")\n\n    # Redirect stdout to tqdm.write() (don't forget the `as save_stdout`)\n    with stdout_redirect_to_tqdm() as save_stdout:\n        # tqdm call need to specify sys.stdout, not sys.stderr (default)\n        # and dynamic_ncols=True to autodetect console width\n        for _ in tqdm(range(3), file=save_stdout, dynamic_ncols=True):\n            blabla()\n            sleep(.5)\n\n    # After the `with`, printing is restored\n    print('Done!')\n\nMonitoring thread, intervals and miniters\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n``tqdm`` implements a few tricks to to increase efficiency and reduce overhead.\n\n1. Avoid unnecessary frequent bar refreshing: ``mininterval`` defines how long\n   to wait between each refresh. ``tqdm`` always gets updated in the background,\n   but it will diplay only every ``mininterval``.\n2. Reduce number of calls to check system clock/time.\n3. ``mininterval`` is more intuitive to configure than ``miniters``.\n   A clever adjustment system ``dynamic_miniters`` will automatically adjust\n   ``miniters`` to the amount of iterations that fit into time ``mininterval``.\n   Essentially, ``tqdm`` will check if it's time to print without actually\n   checking time. This behavior can be still be bypassed by manually setting\n   ``miniters``.\n\nHowever, consider a case with a combination of fast and slow iterations.\nAfter a few fast iterations, ``dynamic_miniters`` will set ``miniters`` to a\nlarge number. When interation rate subsequently slows, ``miniters`` will\nremain large and thus reduce display update frequency. To address this:\n\n4. ``maxinterval`` defines the maximum time between display refreshes.\n   A concurrent monitoring thread checks for overdue updates and forces one\n   where necessary.\n\nThe monitoring thread should not have a noticeable overhead, and guarantees\nupdates at least every 10 seconds by default.\nThis value can be directly changed by setting the ``monitor_interval`` of\nany ``tqdm`` instance (i.e. ``t = tqdm.tqdm(...); t.monitor_interval = 2``).\nThe monitor thread may be disabled application-wide by setting\n``tqdm.tqdm.monitor_interval = 0`` before instantiatiation of any ``tqdm`` bar.\n\n\nContributions\n-------------\n\nAll source code is hosted on `GitHub \u003chttps://github.com/tqdm/tqdm\u003e`__.\nContributions are welcome.\n\nSee the\n`CONTRIBUTE \u003chttps://raw.githubusercontent.com/tqdm/tqdm/master/CONTRIBUTE\u003e`__\nfile for more information.\n\n\nLICENCE\n-------\n\nOpen Source (OSI approved): |LICENCE|\n\nCitation information: |DOI-URI|\n\n\nAuthors\n-------\n\nRanked by contributions.\n\n-  Casper da Costa-Luis (casperdcl)\n-  Stephen Larroque (lrq3000)\n-  Hadrien Mary (hadim)\n-  Noam Yorav-Raphael (noamraph)*\n-  Ivan Ivanov (obiwanus)\n-  Mikhail Korobov (kmike)\n\n`*` Original author\n\n|README-Hits| (Since 19 May 2016)\n\n.. |Logo| image:: https://raw.githubusercontent.com/tqdm/tqdm/master/images/logo.gif\n.. |Screenshot| image:: https://raw.githubusercontent.com/tqdm/tqdm/master/images/tqdm.gif\n.. |Build-Status| image:: https://travis-ci.org/tqdm/tqdm.svg?branch=master\n   :target: https://travis-ci.org/tqdm/tqdm\n.. |Coverage-Status| image:: https://coveralls.io/repos/tqdm/tqdm/badge.svg\n   :target: https://coveralls.io/r/tqdm/tqdm\n.. |Branch-Coverage-Status| image:: https://codecov.io/github/tqdm/tqdm/coverage.svg?branch=master\n   :target: https://codecov.io/github/tqdm/tqdm?branch=master\n.. |Codacy-Grade| image:: https://api.codacy.com/project/badge/Grade/3f965571598f44549c7818f29cdcf177\n   :target: https://www.codacy.com/app/tqdm/tqdm?utm_source=github.com\u0026amp;utm_medium=referral\u0026amp;utm_content=tqdm/tqdm\u0026amp;utm_campaign=Badge_Grade\n.. |GitHub-Status| image:: https://img.shields.io/github/tag/tqdm/tqdm.svg?maxAge=2592000\n   :target: https://github.com/tqdm/tqdm/releases\n.. |GitHub-Forks| image:: https://img.shields.io/github/forks/tqdm/tqdm.svg\n   :target: https://github.com/tqdm/tqdm/network\n.. |GitHub-Stars| image:: https://img.shields.io/github/stars/tqdm/tqdm.svg\n   :target: https://github.com/tqdm/tqdm/stargazers\n.. |PyPI-Status| image:: https://img.shields.io/pypi/v/tqdm.svg\n   :target: https://pypi.python.org/pypi/tqdm\n.. |PyPI-Downloads| image:: https://img.shields.io/pypi/dm/tqdm.svg\n   :target: https://pypi.python.org/pypi/tqdm\n.. |PyPI-Versions| image:: https://img.shields.io/pypi/pyversions/tqdm.svg\n   :target: https://pypi.python.org/pypi/tqdm\n.. |Conda-Forge-Status| image:: https://anaconda.org/conda-forge/tqdm/badges/version.svg\n   :target: https://anaconda.org/conda-forge/tqdm\n.. |LICENCE| image:: https://img.shields.io/pypi/l/tqdm.svg\n   :target: https://raw.githubusercontent.com/tqdm/tqdm/master/LICENCE\n.. |DOI-URI| image:: https://zenodo.org/badge/21637/tqdm/tqdm.svg\n   :target: https://zenodo.org/badge/latestdoi/21637/tqdm/tqdm\n.. |Screenshot-Jupyter1| image:: https://raw.githubusercontent.com/tqdm/tqdm/master/images/tqdm-jupyter-1.gif\n.. |Screenshot-Jupyter2| image:: https://raw.githubusercontent.com/tqdm/tqdm/master/images/tqdm-jupyter-2.gif\n.. |Screenshot-Jupyter3| image:: https://raw.githubusercontent.com/tqdm/tqdm/master/images/tqdm-jupyter-3.gif\n.. |README-Hits| image:: http://caspersci.uk.to/cgi-bin/hits.cgi?q=tqdm\u0026colorA=FFC107\u0026colorB=2196F3\n   :target: http://caspersci.uk.to/cgi-bin/hits.cgi?q=tqdm\u0026a=plot\u0026r=https://github.com/tqdm/tqdm\u0026l=https://raw.githubusercontent.com/tqdm/tqdm/master/images/logo.gif\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcrazypython%2Ftqdm-review","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcrazypython%2Ftqdm-review","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcrazypython%2Ftqdm-review/lists"}