Package: progiter
ProgIterProgIter lets you measure and print the progress of an iterative process. This
can be done either via an iterable interface or using the manual API. Using the
iterable interface is most common.Basic usage is:>>>fromprogiterimportProgIter>>>forninProgIter(range(1000)):>>>...# do some workThe basic ProgIter isunthreaded. This differentiates it fromtqdmandrich.progresswhich use athreadedimplementation.
The choice of implementation has different tradeoffs and neither is strictly
better than the other.
An unthreaded progress bar provides synchronous uncluttered logging, increased
stability, and — unintuitively —- speed (due to Python’s GIL).
Meanwhile threaded progress bars are more responsive, able to update multiple
stdout lines at a time, and can look prettier (unless you try to log stdout to
disk).ProgIter was originally developed independently oftqdm, but the newer
versions of this library have been designed to be compatible with tqdm-API.ProgIteris now a (mostly) drop-in alternative totqdm.
Thetqdmlibrary may be more appropriate in some cases.
The main advantage ofProgIteris that it does not use any python
threading, and therefore can be safer with code that makes heavy use of
multiprocessing.The reasonfor this is that threading before forking may cause locks to be duplicated
across processes, which may lead to deadlocks (although with tqdm this is very
unlikely).ProgIter is simpler than tqdm, which may be desirable for some applications.
However, this also means ProgIter is not as extensible as tqdm.
If you want a pretty bar or need something fancy, use tqdm (or rich);
if you want useful information  about your iteration by default, use progiter.New in Version 2.0,progiter.ProgressManager, which enables near-seemless
toggling between an unthreadedProgIterbackend and a threadedRichProgIterbackend. Basic usage is:fromprogiter.managerimportProgressManagerpman=ProgressManager()withpman:foriteminpman.progiter(range(1000)):...# do some workThe following gif illustrates this and more complex usage:Package level documentation can be found at:https://progiter.readthedocs.io/en/latest/ExampleThe basic usage of ProgIter is simple and intuitive: wrap a python iterable.
The following example wraps arangeiterable and reports progress to stdout
as the iterable is consumed. TheProgIterobject accepts various keyword
arguments to modify the details of how progress is measured and reported. See
API documentation of theProgIterclass here:https://progiter.readthedocs.io/en/latest/progiter.progiter.html#progiter.progiter.ProgIter>>>fromprogiterimportProgIter>>>defis_prime(n):...returnn>=2andnotany(n%i==0foriinrange(2,n))>>>forninProgIter(range(1000),verbose=2):>>># do some work>>>is_prime(n)0.00%0/1000...rate=0Hz,eta=?,total=0:00:000.60%6/1000...rate=76995.12Hz,eta=0:00:00,total=0:00:00100.00%1000/1000...rate=266488.22Hz,eta=0:00:00,total=0:00:00For more complex applications is may sometimes be desireable to manually use
the ProgIter API. This is done as follows:>>>fromprogiterimportProgIter>>>n=3>>>prog=ProgIter(desc='manual',total=n,verbose=3,time_thresh=0)>>>prog.begin()# Manually begin progress iteration>>>for_inrange(n):...prog.step(inc=1)# specify the number of steps to increment>>>prog.end()# Manually end progress iterationmanual0.00%0/3...rate=0Hz,eta=?,total=0:00:00manual33.33%1/3...rate=5422.82Hz,eta=0:00:00,total=0:00:00manual66.67%2/3...rate=8907.61Hz,eta=0:00:00,total=0:00:00manual100.00%3/3...rate=12248.15Hz,eta=0:00:00,total=0:00:00By defaultProgIteraims to write a line to stdout once every two seconds
to minimize its overhead and reduce clutter. Setting this to zero will force
it to print on every iteration.When working with ProgIter in either iterable or manual mode you can use theprog.ensure_newlinemethod to guarantee that the next call you make to stdout
will start on a new line. You can also use theprog.set_extramethod to
update a dynamic “extra” message that is shown in the formatted output. The
following example demonstrates this.>>>fromprogiterimportProgIter>>>defis_prime(n):...returnn>=2andnotany(n%i==0foriinrange(2,n))>>>_iter=range(1000)>>>prog=ProgIter(_iter,desc='check primes',verbose=2,time_thresh=1e-3)>>>forninprog:>>>ifn==97:>>>print('!!! Special print at n=97 !!!')>>>ifis_prime(n):>>>prog.set_extra('Biggest prime so far:{}'.format(n))>>>prog.ensure_newline()checkprimes0.00%0/1000...rate=0Hz,eta=?,total=0:00:00checkprimes0.60%6/1000...Biggestprimesofar:5rate=79329.39Hz,eta=0:00:00,total=0:00:00!!!Specialprintatn=97!!!checkprimes75.60%756/1000...Biggestprimesofar:751rate=272693.23Hz,eta=0:00:00,total=0:00:00checkprimes99.30%993/1000...Biggestprimesofar:991rate=245852.75Hz,eta=0:00:00,total=0:00:00checkprimes100.00%1000/1000...Biggestprimesofar:997rate=244317.84Hz,eta=0:00:00,total=0:00:00InstallationProgIter can be easily installed viapip.pipinstallprogiterAlternatively, theubeltlibrary ships with its own version of ProgIter.
Note that theubeltversion of progiter is distinct (i.e. ubelt actually
contains a copy of this library), but the two libraries are generally kept in
sync.