544

How do I use a progress bar when my script is doing some task that is likely to take time?

For example, a function which takes some time to complete and returns True when done. How can I display a progress bar during the time the function is being executed?

Note that I need this to be in real time, so I can't figure out what to do about it. Do I need a thread for this? I have no idea.

Right now I am not printing anything while the function is being executed, however a progress bar would be nice. Also I am more interested in how this can be done from a code point of view.

smci
  • 32,567
  • 20
  • 113
  • 146
user225312
  • 126,773
  • 69
  • 172
  • 181
  • Are you using a GUI toolkit or CLI only? – Bobby Jul 01 '10 at 18:41
  • CLI. But I can use a third party library, that is no issue. With GUI I can do this, but I was interested in the CLI part. – user225312 Jul 01 '10 at 18:42
  • 4
    Possible duplicate of [Text Progress Bar in the Console](http://stackoverflow.com/questions/3173320/text-progress-bar-in-the-console) Note that while this question was posted three days earlier, the linked question is more frequently viewed. – Greenstick Aug 13 '16 at 00:03
  • Here is a solution for within a Jupyter Notebook: https://mikulskibartosz.name/how-to-display-a-progress-bar-in-jupyter-notebook-47bd4c2944bf – Steven C. Howell Apr 12 '19 at 15:51
  • I've published a new kind of progress bar, which you can print, see throughput and eta, even pause it, besides the very cool animations! Please take a look: https://github.com/rsalmei/alive-progress ![alive-progress](https://raw.githubusercontent.com/rsalmei/alive-progress/master/img/main.gif) – rsalmei Aug 23 '19 at 06:43
  • I don't have a loop, it's a single write command. In that case is it possible? ` with open(path2file, 'wb+') as f: # with open(path2file, 'w+') as f: f.write(data.read())` – Charlie Parker Nov 12 '22 at 02:29

47 Answers47

720

With tqdm (conda install tqdm or pip install tqdm) you can add a progress meter to your loops in a second:

from time import sleep
from tqdm import tqdm
for i in tqdm(range(10)):
    sleep(3)

 60%|██████    | 6/10 [00:18<00:12,  0.33 it/s]

Also, there is a notebook version:

from tqdm.notebook import tqdm
for i in tqdm(range(100)):
    sleep(3)

You can use tqdm.auto instead of tqdm.notebook to work in both a terminal and notebooks.

tqdm.contrib contains some helper functions to do things like enumerate, map, and zip. There are concurrent maps in tqdm.contrib.concurrent.

You can even get progress sent to your phone after disconnecting from a jupyter notebook using tqdm.contrib.telegram or tqdm.contrib.discord.

GIF showing an example of the output of using tqdm.contrib.telegram to display progress bar in Telegram mobile app

Gangula
  • 5,193
  • 4
  • 30
  • 59
scls
  • 16,591
  • 10
  • 44
  • 55
  • 17
    This is the only solution I found to work with terminal, qtconsole and notebook – Ivelin Jun 01 '15 at 01:17
  • 3
    Does it work with any iterable? I've had trouble getting it to work with a list of strings. – Josh Usre Jan 12 '16 at 21:47
  • @AnotherParker It works but it cannot reprint on the same line because [IDLE does not support](http://stackoverflow.com/questions/35895864/what-is-the-difference-between-cmd-and-idle-when-using-tqdm/35900117#35900117) the `\r` carriage return character. So it also affects all progress bars. – gaborous May 15 '16 at 01:50
  • 3
    @JoshUsre Yes it should work with any iterable, for the moment I didn't see any iterable it choked on. However, the display of the ETA (remaining time) requires the iterable to have a ```__len__``` property or the user must supply the `total` argument to `tqdm`. Else, the bar will work but with no ETA. – gaborous May 30 '16 at 11:23
  • 9
    @gaborous: How come this isn't the top voted answer? This simple solution works both in terminal and in Jupyter notebook unlike the top answer. – Ébe Isaac Jun 03 '16 at 08:04
  • Not necessary to `import *`, just do `from tqdm import tqdm` – ZN13 Dec 04 '17 at 20:26
  • why not just ```import tqdm```? is there a specific reason for importing a specific asset from the package? – Garrett Gaddy Dec 23 '17 at 04:29
  • If you do `import tqdm` you will need to do `tqdm.tqdm(...)` which is not very convenient. – scls Dec 24 '17 at 07:52
  • 6
    for running in a jupyter notebook use `from tqdm import tqdm_notebook as tqdm`. Otherwise doesn't write it on one line. – Jacques MALAPRADE Oct 24 '18 at 09:52
  • I have a bunch of concurrent processes writing to multiple files, which implement a tqdm progress bar but the bars overwrite themselves. Is there a way to have an explicit progress bar for each process? – GRoutar Jun 19 '19 at 15:34
  • To only ignore `TqdmExperimentalWarning: GUI is experimental/alpha` and not other warnings, do `from tqdm import TqdmExperimentalWarning` and then `warnings.simplefilter('ignore', TqdmExperimentalWarning)` – hzahnuwen Jul 08 '20 at 08:52
  • 1
    The FizzBuzzEnterpriseEdition of progress bars, my god I love it! – Nick Brady Oct 15 '21 at 18:30
  • +1, when using `tqdm` with enumerate, it goes inside the enumerate function, like this `enumerate(tqdm(list_name))`. This also works with dataloaders from pytorch! – mikey Nov 18 '21 at 14:02
  • This also works for creating progress bars with dataloaders from pytorch: `enumerate(tqdm(data_loader))`. Awesome! – mikey Nov 18 '21 at 14:08
  • I don't have a loop, it's a single write command. In that case is it possible? ` with open(path2file, 'wb+') as f: # with open(path2file, 'w+') as f: f.write(data.read())` – Charlie Parker Nov 12 '22 at 02:29
244

Use alive-progress, the coolest progress bar ever! Just pip install alive-progress and you're good to go!

GIF showing an example of alive-progress

To use any progress bar effectively, i.e. gaining both a percentage of completion and an ETA, you need to be able to tell it the total number of items. Then alive-progress will keep track of where your processing currently is, and how long it will take!
Don't worry if you can't estimate the total, alive-progress will still work.

To use it, you can either drive alive-progress' bar directly:

def compute():
    with alive_bar(1000) as bar:  # your expected total
        for item in items:        # the original loop
            print(item)           # your actual processing here
            bar()                 # call `bar()` at the end


compute()

Or, if you prefer to keep the codes isolated, just insert a yield in your processing code (to mark when an item has been processed), then drive the alive-progress' bar like this:

def compute():
    for item in items:
        print(item)
        yield                  # simply insert this :)


with alive_bar(1000) as bar:
    for i in compute():
        bar()

Either way, you'll get an awesome and animated progress bar!

|█████████████▎                      | ▅▃▁ 321/1000 [32%] in 8s (40.1/s, eta: 16s)

And it supports a LOT of advanced options right out of the box!! some advanced options

Disclosure: I'm the proud author of alive-progress, which has 4.6K+ ⭐️ on github!
Read the documentation at https://github.com/rsalmei/alive-progress to get to know all the advanced features.

Behold some more animations it can do in both spinner and bar widgets: GIF showing various styles of alive-progress

It also works on Jupyter Notebooks! GIF showing alive-progress on Jupyter Notebooks

You can even design your own animations!! GIF showing animation designer

rsalmei
  • 3,085
  • 1
  • 14
  • 15
  • 7
    Love it! How's it going with jupyter notebook support? – blupp Dec 19 '20 at 11:55
  • didn't solve my problem, i use yield with threads and queue – Jawad May 02 '22 at 15:48
  • Open an issue in the project, I can help you there. – rsalmei May 03 '22 at 16:19
  • I don't have a loop, it's a single write command. In that case is it possible? ` with open(path2file, 'wb+') as f: # with open(path2file, 'w+') as f: f.write(data.read())` – Charlie Parker Nov 12 '22 at 02:29
  • Yes @CharlieParker, you could use it as well! You don't have a loop but have a lot of bytes, all it takes are multiple operations... I'd suggest you divide the work into chunks of perhaps 1KB, 8KB, or even 1MB depending on the total size, and use the write of each chunk to drive the bar! – rsalmei Nov 14 '22 at 20:21
  • Very nice! as a personal note, I couldn't find how to emulate a download progress bar, because it advances only one by one and I need to advance by something like bytes per item. – ruloweb May 01 '23 at 18:32
  • 1
    Thanks, @ruloweb. You advance it by whatever quantity you want, just call `bar(size)` at the end of the iteration. – rsalmei May 02 '23 at 20:16
233

There are specific libraries (like this one here) but maybe something very simple would do:

import time
import sys

toolbar_width = 40

# setup toolbar
sys.stdout.write("[%s]" % (" " * toolbar_width))
sys.stdout.flush()
sys.stdout.write("\b" * (toolbar_width+1)) # return to start of line, after '['

for i in range(toolbar_width):
    time.sleep(0.1) # do real work here
    # update the bar
    sys.stdout.write("-")
    sys.stdout.flush()

sys.stdout.write("]\n") # this ends the progress bar

Note: progressbar2 is a fork of progressbar which hasn't been maintained in years.

Wolph
  • 78,177
  • 11
  • 137
  • 148
ChristopheD
  • 112,638
  • 29
  • 165
  • 179
168

No external packages. A ready-made piece of code.

You can customize bar progress symbol "#", bar size, text prefix etc.

Python 3.3+

import sys
def progressbar(it, prefix="", size=60, out=sys.stdout): # Python3.3+
    count = len(it)
    def show(j):
        x = int(size*j/count)
        print("{}[{}{}] {}/{}".format(prefix, "#"*x, "."*(size-x), j, count), 
                end='\r', file=out, flush=True)
    show(0)
    for i, item in enumerate(it):
        yield item
        show(i+1)
    print("\n", flush=True, file=out)

Usage:

import time    
for i in progressbar(range(15), "Computing: ", 40):
    time.sleep(0.1) # any code you need

To fill the whole character space use a unicode u"█" char replacing "#". With for i in progressbar(range(100)): ... you get :

enter image description here

  • Doesn't require a second thread. Some solutions/packages above require.

  • Works with any iterable it means anything that len() can be used on. A list, a dict of anything for example ['a', 'b', 'c' ... 'g']

  • Works with generators only have to wrap it with a list(). For example for i in progressbar(list(your_generator), "Computing: ", 40): Unless the work is done in the generator. In that case you need another solution (like tqdm).

You can also change output by changing out to sys.stderr for example.


Python 3.6+ (f-string)

def progressbar(it, prefix="", size=60, out=sys.stdout): # Python3.6+
    count = len(it)
    def show(j):
        x = int(size*j/count)
        print(f"{prefix}[{u'█'*x}{('.'*(size-x))}] {j}/{count}", end='\r', file=out, flush=True)
    show(0)
    for i, item in enumerate(it):
        yield item
        show(i+1)
    print("\n", flush=True, file=out)

Python 2 (old-code)

import sys
def progressbar(it, prefix="", size=60, out=sys.stdout):
    count = len(it)
    def show(j):
        x = int(size*j/count)
        out.write("%s[%s%s] %i/%i\r" % (prefix, u"#"*x, "."*(size-x), j, count))
        out.flush()        
    show(0)
    for i, item in enumerate(it):
        yield item
        show(i+1)
    out.write("\n")
    out.flush()
imbr
  • 6,226
  • 4
  • 53
  • 65
  • 2
    I like this solution, generators will throw the following error: `TypeError: object of type 'generator' has no len()` – jabellcu Dec 09 '19 at 17:35
  • @jabellcu in that case (`generators`) you have to wrap it with a `list()`. Like `for i in progressbar(list(your_generator), "Computing: ", 40):` – imbr Dec 09 '19 at 18:04
  • 3
    Should have seen this comment before, wasted time to figure out on making it work with generator. I must say converting to list might not be helpful with large objects as the point of generator is lost. (In my case, I am reading pages from a PDF and I don't want to load all pages into memory). I appreciate the simplicity over adding a library for progress bar – rainversion_3 Nov 19 '20 at 12:37
  • 3
    Wrapping a generator as a list seem to indeed miss the point. If all the work is done in the generator, then the progress bar wouldn't show the progress. (tqdm handles that for example by then not showing a percentage unless you tell it the total) The comment regarding the thread issue may not be 100% accurate. A second thread wouldn't be an issue with jupyter notebook. Writing to two separate outputs is (stdout and stderr). – de1 Jan 27 '21 at 13:22
  • 2
    I made a "better" version which replaces the `#` character with a unicode character that fills a whole character space - `█`. This is a gist I made: https://gist.github.com/ChesterChowWOV/2b35c551b339adbf459363322aac5b4b – ChesterWOV Oct 24 '21 at 10:07
  • I don't have a loop, it's a single write command. In that case is it possible? ` with open(path2file, 'wb+') as f: # with open(path2file, 'w+') as f: f.write(data.read())` – Charlie Parker Nov 12 '22 at 02:30
  • @CharlieParker you need to turn in loop and read by chunks. – imbr Nov 12 '22 at 13:11
  • @imbr how do I do that? how do I google that? – Charlie Parker Nov 12 '22 at 22:03
  • 1
    I prefer these characters: █ and ▒ – SurveyLoophole Jan 18 '23 at 21:49
  • This answer would be perfect if it also printed a little estimate of time remaining – Connor Jul 19 '23 at 15:58
  • @Connor that is easy to implement using `time` and a linear or another order of estimation. Feel free to contribute. Adding this in here would make it uncessary complex. – imbr Jul 19 '23 at 20:31
105

The above suggestions are pretty good, but I think most people just want a ready made solution, with no dependencies on external packages, but is also reusable.

I got the best points of all the above, and made it into a function, along with a test cases.

To use it, just copy the lines under "def update_progress(progress)" but not the test script. Don't forget to import sys. Call this whenever you need to display or update the progress bar.

This works by directly sending the "\r" symbol to console to move cursor back to the start. "print" in python does not recongise the above symbol for this purpose, hence we need 'sys'

import time, sys

# update_progress() : Displays or updates a console progress bar
## Accepts a float between 0 and 1. Any int will be converted to a float.
## A value under 0 represents a 'halt'.
## A value at 1 or bigger represents 100%
def update_progress(progress):
    barLength = 10 # Modify this to change the length of the progress bar
    status = ""
    if isinstance(progress, int):
        progress = float(progress)
    if not isinstance(progress, float):
        progress = 0
        status = "error: progress var must be float\r\n"
    if progress < 0:
        progress = 0
        status = "Halt...\r\n"
    if progress >= 1:
        progress = 1
        status = "Done...\r\n"
    block = int(round(barLength*progress))
    text = "\rPercent: [{0}] {1}% {2}".format( "#"*block + "-"*(barLength-block), progress*100, status)
    sys.stdout.write(text)
    sys.stdout.flush()


# update_progress test script
print "progress : 'hello'"
update_progress("hello")
time.sleep(1)

print "progress : 3"
update_progress(3)
time.sleep(1)

print "progress : [23]"
update_progress([23])
time.sleep(1)

print ""
print "progress : -10"
update_progress(-10)
time.sleep(2)

print ""
print "progress : 10"
update_progress(10)
time.sleep(2)

print ""
print "progress : 0->1"
for i in range(101):
    time.sleep(0.1)
    update_progress(i/100.0)

print ""
print "Test completed"
time.sleep(10)

This is what the result of the test script shows (The last progress bar animates):

progress : 'hello'
Percent: [----------] 0% error: progress var must be float
progress : 3
Percent: [##########] 100% Done...
progress : [23]
Percent: [----------] 0% error: progress var must be float

progress : -10
Percent: [----------] 0% Halt...

progress : 10
Percent: [##########] 100% Done...

progress : 0->1
Percent: [##########] 100% Done...
Test completed
rayryeng
  • 102,964
  • 22
  • 184
  • 193
Brian Khuu
  • 1,167
  • 1
  • 9
  • 5
  • 10
    The animated test (last one) should say `in range(101)` not 100, the progress stops at 99% and never displays done. – Nick Humrich Nov 17 '14 at 22:47
  • This is a great answer! Two suggestions: 1) you can use `print(..., end='')` instead of calling `stdout.write()` + `stdout.flush()`. 2) if you put `\r` at the end of the string instead of the beginning, it plays much nicer with other console output. – Tim Sparkles Dec 11 '20 at 21:43
  • how do you make the progress bar overwrite each time it updates, instead of appending new lines to the console each time? – user5359531 Feb 05 '21 at 15:37
  • @user5359531 try bellow answer – imbr Mar 27 '21 at 16:06
  • I changed the format of the progress to 2 decimal places like: `text = "\rPercent: [{0}] {1:.2f}% {2}".format( "#"*block + "-"*(barLength-block), progress*100, status)` – Kory Gill Apr 23 '22 at 20:58
31

Try progress from https://pypi.python.org/pypi/progress.

from progress.bar import Bar

bar = Bar('Processing', max=20)
for i in range(20):
    # Do some work
    bar.next()
bar.finish()

The result will be a bar like the following:

Processing |#############                   | 42/100
Vladislav
  • 1,318
  • 16
  • 15
  • Just tried this. VERY easy to use. Took me like 2 minutes (including pip install progress) to have a status bar up and running. – perelin Nov 17 '17 at 22:36
  • `progress` makes nice bars, but it fails if other software is manipulating `stderr`. sorry, but I've not investigated the exact problem. – Arthur Aug 30 '19 at 14:59
  • It prints one line for each progress in my ubuntu console, for example, if max=20, it prints 20 lines...How do I make it prints only one line? – L's World May 28 '20 at 01:17
26

for a similar application (keeping track of the progress in a loop) I simply used the python-progressbar:

Their example goes something like this,

from progressbar import *               # just a simple progress bar


widgets = ['Test: ', Percentage(), ' ', Bar(marker='0',left='[',right=']'),
           ' ', ETA(), ' ', FileTransferSpeed()] #see docs for other options

pbar = ProgressBar(widgets=widgets, maxval=500)
pbar.start()

for i in range(100,500+1,50):
    # here do something long at each iteration
    pbar.update(i) #this adds a little symbol at each iteration
pbar.finish()
print
Massagran
  • 1,781
  • 1
  • 20
  • 29
21

I've just made a simple progress class for my needs after searching here for a equivalent solution. I thought I might a well post it.

from __future__ import print_function
import sys
import re


class ProgressBar(object):
    DEFAULT = 'Progress: %(bar)s %(percent)3d%%'
    FULL = '%(bar)s %(current)d/%(total)d (%(percent)3d%%) %(remaining)d to go'

    def __init__(self, total, width=40, fmt=DEFAULT, symbol='=',
                 output=sys.stderr):
        assert len(symbol) == 1

        self.total = total
        self.width = width
        self.symbol = symbol
        self.output = output
        self.fmt = re.sub(r'(?P<name>%\(.+?\))d',
            r'\g<name>%dd' % len(str(total)), fmt)

        self.current = 0

    def __call__(self):
        percent = self.current / float(self.total)
        size = int(self.width * percent)
        remaining = self.total - self.current
        bar = '[' + self.symbol * size + ' ' * (self.width - size) + ']'

        args = {
            'total': self.total,
            'bar': bar,
            'current': self.current,
            'percent': percent * 100,
            'remaining': remaining
        }
        print('\r' + self.fmt % args, file=self.output, end='')

    def done(self):
        self.current = self.total
        self()
        print('', file=self.output)

Example :

from time import sleep

progress = ProgressBar(80, fmt=ProgressBar.FULL)

for x in xrange(progress.total):
    progress.current += 1
    progress()
    sleep(0.1)
progress.done()

Will print the following:

[======== ] 17/80 ( 21%) 63 to go

C8H10N4O2
  • 18,312
  • 8
  • 98
  • 134
Romuald Brunet
  • 5,595
  • 4
  • 38
  • 34
  • 3
    Awesome, thank you for this. BTW, you can add the `progress.current` incrementing in the end of `__call__` to limit the interaction with the object from the main code even more. – npit Aug 13 '17 at 23:25
  • This code is simple, concise and useful! Thank you! – Ian Rehwinkel May 06 '19 at 10:16
21

I like Brian Khuu's answer for its simplicity and not needing external packages. I changed it a bit so I'm adding my version here:

import sys
import time


def updt(total, progress):
    """
    Displays or updates a console progress bar.

    Original source: https://stackoverflow.com/a/15860757/1391441
    """
    barLength, status = 20, ""
    progress = float(progress) / float(total)
    if progress >= 1.:
        progress, status = 1, "\r\n"
    block = int(round(barLength * progress))
    text = "\r[{}] {:.0f}% {}".format(
        "#" * block + "-" * (barLength - block), round(progress * 100, 0),
        status)
    sys.stdout.write(text)
    sys.stdout.flush()


runs = 300
for run_num in range(runs):
    time.sleep(.1)
    updt(runs, run_num + 1)

It takes the total number of runs (total) and the number of runs processed so far (progress) assuming total >= progress. The result looks like this:

[#####---------------] 27%
Gabriel
  • 40,504
  • 73
  • 230
  • 404
20

You can use tqdm:

from tqdm import tqdm

with tqdm(total=100, desc="Adding Users", bar_format="{l_bar}{bar} [ time left: {remaining} ]") as pbar:
    for i in range(100):
        time.sleep(3)
        pbar.update(1)

In this example the progress bar is running for 5 minutes and it is shown like that:

Adding Users:   3%|█████▊                                     [ time left: 04:51 ]                                                                                                        

You can change it and customize it as you like.

double-beep
  • 5,031
  • 17
  • 33
  • 41
Eyal.D
  • 550
  • 3
  • 18
11

I really like the python-progressbar, as it is very simple to use.

For the most simple case, it is just:

import progressbar
import time

progress = progressbar.ProgressBar()
for i in progress(range(80)):
    time.sleep(0.01)

The appearance can be customized and it can display the estimated remaining time. For an example use the same code as above but with:

progress = progressbar.ProgressBar(widgets=[progressbar.Bar('=', '[', ']'), ' ',
                                            progressbar.Percentage(), ' ',
                                            progressbar.ETA()])
luator
  • 4,769
  • 3
  • 30
  • 51
8

A simple oneliner:

K = 628318
for k in range(K):
    # your stuff
    print(end="\r|%-80s|" % ("="*(80*(k+1)//K)))
|=====================================================================       |

80 is the length of the bar. Eventually you want a final print().

It can be also put into a convencience function. Along with yield, one can emulate the behaviour of tqdm:

def progbar(iterobj):
    K = len(iterobj)
    for k, obj in enumerate(iterobj):
        print(end="\r|%-80s|" % ("="*(80*(k+1)//K)))
        yield obj
    print()
    raise StopIteration

for k in progbar(range(628318)):
    # your stuff
    pass

And not to forget the digital progress indicator:

K = 628318
for k in range(K):
    # your stuff
    print(end=f"\r{(k+1)/K*100:6.2f} %")
 94.53 %

It is not to difficult to combine both, if needed.

The keys are the "Carriage Return" \r and the suppression of the default end="\n" in print.

7

Use this library: fish (GitHub).

Usage:

>>> import fish
>>> while churning:
...     churn_churn()
...     fish.animate()

Have fun!

kenorb
  • 155,785
  • 88
  • 678
  • 743
Etienne
  • 12,440
  • 5
  • 44
  • 50
7

If it is a big loop with a fixed amount of iterations that is taking a lot of time you can use this function I made. Each iteration of loop adds progress. Where count is the current iteration of the loop, total is the value you are looping to and size(int) is how big you want the bar in increments of 10 i.e. (size 1 =10 chars, size 2 =20 chars)

import sys
def loadingBar(count,total,size):
    percent = float(count)/float(total)*100
    sys.stdout.write("\r" + str(int(count)).rjust(3,'0')+"/"+str(int(total)).rjust(3,'0') + ' [' + '='*int(percent/10)*size + ' '*(10-int(percent/10))*size + ']')

example:

for i in range(0,100):
     loadingBar(i,100,2)
     #do some code 

output:

i = 50
>> 050/100 [==========          ]
jelde015
  • 554
  • 6
  • 7
6

When running in jupyter notebooks use of normal tqdm doesn't work, as it writes output on multiple lines. Use this instead:

import time
from tqdm.notebook import tqdm

for i in tqdm(range(100)):
    time.sleep(0.5)

enter image description here

Jacques MALAPRADE
  • 963
  • 4
  • 13
  • 28
6

pip install progressbar2

Progressbar Progressbar Progressbar Progressbar Progressbar

import os
import time
import progressbar 

os.environ['PYCHARM_HOSTED'] = '1' # https://github.com/WoLpH/python-progressbar/issues/237

class COLOR: # https://stackoverflow.com/a/287944/11465149
    YELLOW    = '\033[93m'
    GREEN     = '\033[92m'
    RED       = '\033[91m'
    BOLD      = '\033[1m'
    ENDC      = '\033[0m'

widgets=[
    'FILE.JSON ',
    COLOR.YELLOW          , progressbar.Percentage()                        , COLOR.ENDC,
    COLOR.RED + COLOR.BOLD, progressbar.Bar(left=' ', marker='━', right=' '), COLOR.ENDC,
    COLOR.YELLOW          , progressbar.Timer()                             , COLOR.ENDC
]

for i in progressbar.progressbar(range(100), widgets=widgets):
    time.sleep(0.01)
    if i == 99:
        widgets[4] = COLOR.GREEN

Use enumerate(...progressbar(max_value=...) + this in case you want to use it as a download progressbar

Giorgos Xou
  • 1,461
  • 1
  • 13
  • 32
5

The code below is a quite general solution and also has a time elapsed and time remaining estimate. You can use any iterable with it. The progress bar has a fixed size of 25 characters but it can show updates in 1% steps using full, half, and quarter block characters. The output looks like this:

 18% |████▌                    | \ [0:00:01, 0:00:06]

Code with example:

import sys, time
from numpy import linspace

def ProgressBar(iterObj):
  def SecToStr(sec):
    m, s = divmod(sec, 60)
    h, m = divmod(m, 60)
    return u'%d:%02d:%02d'%(h, m, s)
  L = len(iterObj)
  steps = {int(x):y for x,y in zip(linspace(0, L, min(100,L), endpoint=False),
                                   linspace(0, 100, min(100,L), endpoint=False))}
  qSteps = ['', u'\u258E', u'\u258C', u'\u258A'] # quarter and half block chars
  startT = time.time()
  timeStr = '   [0:00:00, -:--:--]'
  activity = [' -',' \\',' |',' /']
  for nn,item in enumerate(iterObj):
    if nn in steps:
      done = u'\u2588'*int(steps[nn]/4.0)+qSteps[int(steps[nn]%4)]
      todo = ' '*(25-len(done))
      barStr = u'%4d%% |%s%s|'%(steps[nn], done, todo)
    if nn>0:
      endT = time.time()
      timeStr = ' [%s, %s]'%(SecToStr(endT-startT),
                             SecToStr((endT-startT)*(L/float(nn)-1)))
    sys.stdout.write('\r'+barStr+activity[nn%4]+timeStr); sys.stdout.flush()
    yield item
  barStr = u'%4d%% |%s|'%(100, u'\u2588'*25)
  timeStr = '   [%s, 0:00:00]\n'%(SecToStr(time.time()-startT))
  sys.stdout.write('\r'+barStr+timeStr); sys.stdout.flush()

# Example
s = ''
for c in ProgressBar(list('Disassemble and reassemble this string')):
  time.sleep(0.2)
  s += c
print(s)

Suggestions for improvements or other comments are appreciated. Cheers!

Niko
  • 89
  • 1
  • 5
4

It is quite straightforward in Python3:

   import time
   import math

    def show_progress_bar(bar_length, completed, total):
        bar_length_unit_value = (total / bar_length)
        completed_bar_part = math.ceil(completed / bar_length_unit_value)
        progress = "*" * completed_bar_part
        remaining = " " * (bar_length - completed_bar_part)
        percent_done = "%.2f" % ((completed / total) * 100)
        print(f'[{progress}{remaining}] {percent_done}%', end='\r')

    bar_length = 30
    total = 100
    for i in range(0, total + 1):
        show_progress_bar(bar_length, i, total)
        time.sleep(0.1)

    print('\n')
4

2022 Answer for simple progress bar without external library

import time, sys

def progress(size):
    for item in range(size):
        if(item==0):
            print("[",end="")

        elif(item==size-1):
            print("]",end="\n")

        else:
            #main work goes here
            time.sleep(0.1)
            print("%",end="")
            sys.stdout.flush()

progress(50)

3

I like this page.

Starts with simple example and moves onto a multi-threaded version. Works out of the box. No 3rd party packages required.

The code will look something like this:

import time
import sys

def do_task():
    time.sleep(1)

def example_1(n):
    for i in range(n):
        do_task()
        print '\b.',
        sys.stdout.flush()
    print ' Done!'

print 'Starting ',
example_1(10)

Or here is example to use threads in order to run the spinning loading bar while the program is running:

import sys
import time
import threading

class progress_bar_loading(threading.Thread):

    def run(self):
            global stop
            global kill
            print 'Loading....  ',
            sys.stdout.flush()
            i = 0
            while stop != True:
                    if (i%4) == 0: 
                        sys.stdout.write('\b/')
                    elif (i%4) == 1: 
                        sys.stdout.write('\b-')
                    elif (i%4) == 2: 
                        sys.stdout.write('\b\\')
                    elif (i%4) == 3: 
                        sys.stdout.write('\b|')

                    sys.stdout.flush()
                    time.sleep(0.2)
                    i+=1

            if kill == True: 
                print '\b\b\b\b ABORT!',
            else: 
                print '\b\b done!',


kill = False      
stop = False
p = progress_bar_loading()
p.start()

try:
    #anything you want to run. 
    time.sleep(1)
    stop = True
except KeyboardInterrupt or EOFError:
         kill = True
         stop = True
kenorb
  • 155,785
  • 88
  • 678
  • 743
3

Here's a short solution that builds the loading bar programmatically (you must decide how long you want it).

import time

n = 33  # or however many loading slots you want to have
load = 0.01  # artificial loading time!
loading = '.' * n  # for strings, * is the repeat operator

for i in range(n+1):
    # this loop replaces each dot with a hash!
    print('\r%s Loading at %3d percent!' % (loading, i*100/n), end='')
    loading = loading[:i] + '#' + loading[i+1:]
    time.sleep(load)
    if i==n: print()
étale-cohomology
  • 2,098
  • 2
  • 28
  • 33
3

I used format() method to make a load bar. Here is my solution:

import time

loadbarwidth = 23

for i in range(1, loadbarwidth + 1):
    time.sleep(0.1) 

    strbarwidth = '[{}{}] - {}\r'.format(
        (i * '#'),
        ((loadbarwidth - i) * '-'),
        (('{:0.2f}'.format(((i) * (100/loadbarwidth))) + '%'))
    )

    print(strbarwidth ,end = '')

print()

Output:

[#######################] - 100.00%
2

If your work can't be broken down into measurable chunks, you could call your function in a new thread and time how long it takes:

import thread
import time
import sys

def work():
    time.sleep( 5 )

def locked_call( func, lock ):
    lock.acquire()
    func()
    lock.release()

lock = thread.allocate_lock()
thread.start_new_thread( locked_call, ( work, lock, ) )

# This part is icky...
while( not lock.locked() ):
    time.sleep( 0.1 )

while( lock.locked() ):
    sys.stdout.write( "*" )
    sys.stdout.flush()
    time.sleep( 1 )
print "\nWork Done"

You can obviously increase the timing precision as required.

bvanvugt
  • 1,212
  • 1
  • 8
  • 15
2

I like Gabriel answer, but i changed it to be flexible. You can send bar-length to the function and get your progress bar with any length that you want. And you can't have a progress bar with zero or negative length. Also, you can use this function like Gabriel answer (Look at the Example #2).

import sys
import time

def ProgressBar(Total, Progress, BarLength=20, ProgressIcon="#", BarIcon="-"):
    try:
        # You can't have a progress bar with zero or negative length.
        if BarLength <1:
            BarLength = 20
        # Use status variable for going to the next line after progress completion.
        Status = ""
        # Calcuting progress between 0 and 1 for percentage.
        Progress = float(Progress) / float(Total)
        # Doing this conditions at final progressing.
        if Progress >= 1.:
            Progress = 1
            Status = "\r\n"    # Going to the next line
        # Calculating how many places should be filled
        Block = int(round(BarLength * Progress))
        # Show this
        Bar = "[{}] {:.0f}% {}".format(ProgressIcon * Block + BarIcon * (BarLength - Block), round(Progress * 100, 0), Status)
        return Bar
    except:
        return "ERROR"

def ShowBar(Bar):
    sys.stdout.write(Bar)
    sys.stdout.flush()

if __name__ == '__main__':
    print("This is a simple progress bar.\n")

    # Example #1:
    print('Example #1')
    Runs = 10
    for i in range(Runs + 1):
        progressBar = "\rProgress: " + ProgressBar(10, i, Runs)
        ShowBar(progressBar)
        time.sleep(1)

    # Example #2:
    print('\nExample #2')
    Runs = 10
    for i in range(Runs + 1):
        progressBar = "\rProgress: " + ProgressBar(10, i, 20, '|', '.')
        ShowBar(progressBar)
        time.sleep(1)

    print('\nDone.')

# Example #2:
Runs = 10
for i in range(Runs + 1):
    ProgressBar(10, i)
    time.sleep(1)

Result:

This is a simple progress bar.

Example #1

Progress: [###-------] 30%

Example #2

Progress: [||||||||||||........] 60%

Done.

2

Guess i'm a little late but this should work for people working with the current versions of python 3, since this uses "f-strings", as introduced in Python 3.6 PEP 498:

Code

from numpy import interp

class Progress:
    def __init__(self, value, end, title='Downloading',buffer=20):
        self.title = title
        #when calling in a for loop it doesn't include the last number
        self.end = end -1
        self.buffer = buffer
        self.value = value
        self.progress()

    def progress(self):
        maped = int(interp(self.value, [0, self.end], [0, self.buffer]))
        print(f'{self.title}: [{"#"*maped}{"-"*(self.buffer - maped)}]{self.value}/{self.end} {((self.value/self.end)*100):.2f}%', end='\r')

Example

#some loop that does perfroms a task
for x in range(21)  #set to 21 to include until 20
    Progress(x, 21)

Output

Downloading: [########------------] 8/20 40.00%
Gustavo Barros
  • 150
  • 2
  • 7
2

Use the progress library!

pip install progress

Here is a custom subclass I wrote to format the ETA/Elapsed times into a better readable format:

import datetime
from progress.bar import IncrementalBar


class ProgressBar(IncrementalBar):
    '''
    My custom progress bar that:
       - Show %, count, elapsed, eta
       - Time is shown in H:M:S format
    '''

    message = 'Progress'
    suffix  = '%(percent).1f%% (%(index)d/%(max)d) -- %(elapsed_min)s (eta: %(eta_min)s)'

    def formatTime(self, seconds):
        return str(datetime.timedelta(seconds=seconds))

    @property
    def elapsed_min(self):
        return self.formatTime(self.elapsed)

    @property
    def eta_min(self):
        return self.formatTime(self.eta)

if __name__=='__main__':
    counter = 120
    bar     = ProgressBar('Processing', max=counter)

    for i in range(counter):
        bar.next()
        time.sleep(1)

    bar.finish()
kakhkAtion
  • 2,264
  • 22
  • 23
2

This is my simple solution:

import time

def progress(_cur, _max):
    p = round(100*_cur/_max)
    b = f"Progress: {p}% - ["+"."*int(p/5)+" "*(20-int(p/5))+"]"
    print(b, end="\r")

# USAGE:
for i in range(0,101):
    time.sleep(0.1) 
    progress(i,100)

print("..."*5, end="\r")
print("Done")
dododo
  • 21
  • 2
2

A very simple approach:

def progbar(count: int) -> None:
    for i in range(count):
        print(f"[{i*'#'}{(count-1-i)*' '}] - {i+1}/{count}", end="\r")
        yield i
    print('\n')

And the usage:

from time import sleep

for i in progbar(10):
    sleep(0.2) #whatever task you need to do
  • This is a great solution for modern python with type hinting, f-strings & no imports (in actual usage). My favorite! – ranvel Feb 13 '21 at 14:10
2

There are a lot of amazing answers already still I would like to share my solution to the progress bar.

from time import sleep

def progress_bar(progress: float, total: float, width: int = 25):
    percent = width * ((progress + 1) / total)
    bar = chr(9608) * int(percent) + "-" * (width - int(percent))
    print(f"\r|{bar}| {(100/width)*percent:.2f}%", end="\r")

numbers = range(0, 1000)
numbersLen = len(numbers)
for i in numbers:
    sleep(0.01) # Do something usefull here
    progress_bar(i, numbersLen)

EDIT:

If you are looking for a bar that adjusts it's with based on the terminal's width and a possibility for messages at the end then this works too. Note that the message will disappear if the Terminal gets too narrow as the bar will break if it's too wide for 1 line.

def progressBar(progress: float, total: float, message: str = ""):
    terminalWidth = get_terminal_size().columns
    width = int(terminalWidth / 4)
    percent = width * ((progress + 1) / total)
    bar = chr(9608) * int(percent) + "-" * (width - int(percent))
    if terminalWidth <= 40:
        message = ""
    else:
        message = message + (" " * (int(terminalWidth / 2) - len(message)))
    print(f"\r|{bar}| {(100/width)*percent:.2f}% " + message, end="\r")
HandyGold75
  • 53
  • 1
  • 5
  • Thanks @Handygold75, this is pretty close to what i needed, modified a little your answer to make it callable under a context. posting it below. – Bravhek Jul 06 '22 at 00:27
1

Try PyProg. PyProg is an open-source library for Python to create super customizable progress indicators & bars.

It is currently at version 1.0.2; it is hosted on Github and available on PyPI (Links down below). It is compatible with Python 3 & 2 and it can also be used with Qt Console.

It is really easy to use. The following code:

import pyprog
from time import sleep

# Create Object
prog = pyprog.ProgressBar(" ", "", 34)
# Update Progress Bar
prog.update()

for i in range(34):
    # Do something
    sleep(0.1)
    # Set current status
    prog.set_stat(i + 1)
    # Update Progress Bar again
    prog.update()

# Make the Progress Bar final
prog.end()

will produce:

Initial State:
Progress: 0% --------------------------------------------------

When half done:
Progress: 50% #########################-------------------------

Final State:
Progress: 100% ##################################################

I actually made PyProg because I needed a simple but super customizable progress bar library. You can easily install it with: pip install pyprog.

PyProg Github: https://github.com/Bill13579/pyprog
PyPI: https://pypi.python.org/pypi/pyprog/

Bill Kudo
  • 21
  • 1
1

You can also use enlighten. The main advantage is you can log at the same time without overwriting your progress bar.

import time
import enlighten

manager = enlighten.Manager()
pbar = manager.counter(total=100)

for num in range(1, 101):
    time.sleep(0.05)
    print('Step %d complete' % num)
    pbar.update()

It also handles multiple progress bars.

import time
import enlighten

manager = enlighten.Manager()
odds = manager.counter(total=50)
evens = manager.counter(total=50)

for num in range(1, 101):
    time.sleep(0.05)
    if num % 2:
        odds.update()
    else:
        evens.update()
aviso
  • 2,371
  • 1
  • 14
  • 15
1

a little more generic answer of jelde015 (credit to him of course)

for updating the loading bar manually will be:

import sys
from math import *


def loadingBar(i, N, size):
    percent = float(i) / float(N)
    sys.stdout.write("\r"
                     + str(int(i)).rjust(3, '0')
                     +"/"
                     +str(int(N)).rjust(3, '0')
                     + ' ['
                     + '='*ceil(percent*size)
                     + ' '*floor((1-percent)*size)
                     + ']')

and calling it by:

loadingBar(7, 220, 40)

will result:

007/220 [=                                       ]  

just call it whenever you want with the current i value.

set the size as the number of chars the bar should be

Yarden Cohen
  • 584
  • 2
  • 4
  • 19
1

I use wget, you have to install the module tho in cmd prompt in windows or terminal if on mac or linux

pip install wget

It's pretty straight forward, just use the download() function

import wget
url = input("Enter Url to download: ")
wget.download(url)

tqdm is also an option, u have to download the module, too.

pip install tqdm

now make sure to import the module, set the range and pass

from tqdm import tqdm
for i in tqdm(range(int(9e7))):
    pass
1409aram
  • 11
  • 1
1

There's a lot of good ansers already, but adding this specidfic based upon @HandyGold75 answer, I wanted it to be callabe under a specific context, with an initial msg, plus a timing feedback in seconds at the end.

from time import sleep, time


class ProgressBar:
    def __init__(self, total: float, width: int = 50, msg: str = ""):
    self.total = total
    self.width = width
    self.start: float = time()
    if msg:
        print(f"{msg}")

    def progress(self, progress: float):
        percent = self.width * ((progress) / self.total)
        bar = chr(9608) * int(percent) + "-" * (self.width - int(percent))
        print(
            f"\r|{bar}| {(100/self.width)*percent:.2f}% "
            f"[{progress} of {self.total}]",
            end="\r",
        )

    def __enter__(self):
        return self.progress

    def __exit__(self, type, value, traceback):
        end: float = time()
        print(f"\nFinished after {end - self.start: .3f} seconds.")


# USAGE
total_loops = 150
with ProgressBar(total=total_loops) as progress:
    for i in range(total_loops):
        sleep(0.01)  # Do something usefull here
        progress(i + 1)
Bravhek
  • 327
  • 3
  • 10
0

@Massagran: It works well in my programs. Furthermore, we need to add a counter to indicate the loop times. This counter plays as the argument of the method update. For example: read all lines of a test file and treat them on something. Suppose that the function dosth() do not concern in the variable i.

lines = open(sys.argv[1]).readlines()
i = 0
widgets=[Percentage(), Bar()]
pbar = ProgressBar(widgets=widgets,maxval=len(lines)).start()
pbar.start()
for line in lines:<pre>
    dosth();
    i += 1
    pbar.update(i)</pre>
pbar.finish()

The variable i controls the status of pbar via the method update

Tung
  • 1,579
  • 4
  • 15
  • 32
0

You should link the progress bar to the task at hand (so that it measures the progress :D). For example, if you are FTPing a file, you can tell ftplib to grab a certain size buffer, let's say 128K, and then you add to your progress bar whatever percentage of the filesize 128k represents. If you are using the CLI, and your progress meter is 20 characters long, you would add one character when 1/20th of the file had transferred.

johncip
  • 2,087
  • 18
  • 24
  • In my case I am using a API and it provides no facility for the getting specific chunks. Thanks for the idea though, it is nice. – user225312 Jul 01 '10 at 19:17
0

use the os_sys lib:

i use it for many types of bars, example:

from os_sys.progress import bar as Bar
bar = Bar('progresing: ', max=20)
for i in range(20):
    #do somthing
    bar.next()
bar.finish()

your output will be:

procesing:  |######                          | 2/10

read more in the discription of os_sys

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
Matthijs990
  • 637
  • 3
  • 26
0

This is a simple way to create a progressbar

import time,sys
toolbar_width = 50
# setting up toolbar [-------------------------------------]
sys.stdout.write("[%s]"%(("-")*toolbar_width))
sys.stdout.flush()
# each hash represents 2 % of the progress
for i in range(toolbar_width):
    sys.stdout.write("\r") # return to start of line
    sys.stdout.flush()
    sys.stdout.write("[")#Overwrite over the existing text from the start 
    sys.stdout.write("#"*(i+1))# number of # denotes the progress completed 
    sys.stdout.flush()
    time.sleep(0.1)
0

This progress bar shows points of each 2 percent complete and numbers for each 10 percent complete.

import sys

def ProgressBar (num, total, nextPercent, nextPoint):
    num = float (num)
    total = float (total) - 1
    if not nextPoint:
        nextPoint = 0.0
    if not nextPercent:
        nextPoint += 2.0
        sys.stdout.write ("[0%")
        nextPercent = 10
    elif num == total:
        sys.stdout.write ("100%]\n")
        nextPercent += 10
    elif not nextPoint:
        nextPoint = 0.0
    elif num / total * 100 >= nextPercent:
        sys.stdout.write (str(int (nextPercent)) + "%")
        nextPercent += 10
    elif num / total * 100 >= nextPoint:
        sys.stdout.write (":")
        nextPoint += 2
    return (nextPercent, nextPoint)

nextPercent, nextPoint = 0, 0
total = 1000

for num in range (total):
    nextPercent, nextPoint = ProgressBar (num, total, nextPercent, nextPoint)

Results:

>>> 
[0%::::10%:::::20%:::::30%:::::40%:::::50%:::::60%:::::70%:::::80%:::::90%:::::100%]
>>> 
Emil Brundage
  • 213
  • 3
  • 12
0

A simple solution here !

void = '-'
fill = '#'
count = 100/length
increaseCount = 0
for i in range(length):
    print('['+(fill*i)+(void*(length-i))+'] '+str(int(increaseCount))+'%',end='\r')
    increaseCount += count
    time.sleep(0.1)
print('['+(fill*(i+1))+(void*(length-(i+1)))+'] '+str(int(increaseCount))+'%',end='\n')

Note : You can modify the fill and the "void" character if you want.

The loading bar (picture)

Community
  • 1
  • 1
0

Progressbar for iterrows. Adaptation of @eusoubrasileiro code for displaying progress when looping through rows of a dataframe. Additionally shows percentage, ith/count, elapsed seconds, iters/sec, remaining seconds. Allows specifying an nth updating count (per).

import time
import sys
def progressbar_iterrows(df, prefix="", size=60, file=sys.stdout, per=1000):
    count = len(df)
    t = 0
    def show(j,elapsed):
        avg = 0 if elapsed == 0 else j/elapsed
        remaining = 0 if avg == 0 else (count-j)/avg
        x = int(size*j/count)
        file.write("%s[%s%s] %i%% %i/%i elapsed:%i %i/sec remaining:%i\r" % (prefix, "#"*x, "."*(size-x), j/count, j, count, elapsed, avg, remaining))
        file.flush()
    file.write("Initializing ...\r")
    file.flush()
    for i, item in df.iterrows():
        yield i,item
        if t == 0:
            t = time.time()
        if i % per == 0:
            show(i,time.time()-t)
    file.write("\n")
    file.flush()

Usage:

    for n,r in progressbar_iterrows(br_b_sections_df, "Processed: "):
        # do something

Output:

Processed: [........................] 0% 5000/28751240 elapsed:12 413/sec remaining:55054
BSalita
  • 8,420
  • 10
  • 51
  • 68
0
from IPython.display import clear_output
progress_bar=u"\u001b[7m Loading: "
for i in range(100):
    clear_output(wait=True)
    progress_bar+=u"\u001b[7m "
    print(progress_bar+str(i+1)+"%")
    time.sleep(0.03) #you can change the speed

output

0
#doesnt affect actual execution
#based on events and consumption in background
#may be that actual process completes a bit earlier than progress shows 99%
#make an instance with number of elements in a loop
#in each iteration call the method current_progress

import time
from math import ceil
import os
import sys
from threading import Thread
class progress_bar(object):
 def __init__(self,total_elements,length_bar=25):
  self.length_bar=length_bar
  self.total_elements=total_elements
  self.singleweight=(float(1)/float(total_elements))*100
  self.done=0
  self.qt=[0]
  self.call_count=0
  t=Thread(target=self.display_progress)
  t.start()
 def current_progress(self):
  self.done+=1
  self.qt=[self.done]+self.qt
 def display_progress(self):
  while True:
   try:
    done=self.qt.pop()
   except:
    continue
   else:
    self.call_count+=1
    self.progress=self.singleweight*done
    fill=ceil(self.progress)
    bar=int((fill*self.length_bar)/100)*"|"
    bar="["+bar+str(fill)+"%"
    barp=bar
    for i in range(0,self.length_bar+3-(len(bar))):
     barp=barp+"_"
    barp=barp+"]"
    if self.progress <= 100:
     os.system("clear")
     print("Progress:",barp, sep=' ', end='\n', file=sys.stdout, flush=True)
    if self.call_count == self.total_elements:
     break
  else:
   pass
0

Inspired by many of the answers with no package dependency, I am sharing my implementation here. The function to be used in any loop expects the current iteration number, the total number of iterations, and the initial time.

import time    
def simple_progress_bar(i: int, n: int, init_time: float):
    avg_time = (time.time()-init_time)/(i+1)
    percent = ((i+1)/(n))*100
    print(
        end=f"\r|{'='*(int(percent))+'>'+'.'*int(100-int(percent))}|| " + \
        f"||Completion: {percent : 4.3f}% || \t "+ \
        f"||Time elapsed: {avg_time*(i+1):4.3f} seconds || \t " + \
        f"||Remaining time: {(avg_time*(n-(i+1))): 4.3f} seconds."
    )
    return



N = 325
t0 = time.time()
for k in range(N):
    # stuff goes here #
    time.sleep(0.0001)
    # stuff goes here #
    
    simple_progress_bar(k, N, t0)
Rajesh Nakka
  • 123
  • 1
  • 7
0

You can use the rich library, wich has really good terminal styling, including progress bars. First run the followng command: pip install rich

Example from docs:

import time
from rich.progress import track

for i in track(range(20), description="Processing..."):
    time.sleep(1)  # Simulate work being done
Taitep
  • 1
  • 3
0

With quo (pip install quo) you can add a progress meter to your loops in a second:enter image description here Check the documentation here

-2

Here is a very simple version, in case you have a loop and just want to get an idea of progression of iterations, such as a dot for every, say, 5000 iterations.

my_list = range(0,100000)

counter = 0
for x in my_list:
    #your code here

    counter = counter + 1
    if counter % 5000 == 0:
        print(".", end="") # end="" avoids a newline, keeps dots together

print() #this makes sure whatever you print next is in a new line

my_list is not part of the scheme. Use your own iterable, whatever you are looping over. This version doesn't tell you ahead of time how many total iterations.

Rabi
  • 1
  • 1