DEV Community

jmau111⚡⚡⚡
jmau111⚡⚡⚡

Posted on

Python: build a progress bar for your CLI

Disclaimer

There are third-party packages for that. For example, tdqm or progress

Here, well build our own script, but bear in mind that many issues you may encounter have already been solved by some open-source projects.

The goals

We want to build some utility to display a progress bar for our tasks.

The inputs

Our tool requires, at least, the following:

  • total size or length of the task(s)
  • current state of the task (percent)
  • a char to display the bars

The code

import sys
import os
import time
import shutil

def pb(done, total, char="|"):
    total = float(total)
    columns = shutil.get_terminal_size().columns
    width = int(columns * 0.5)
    completed = int(round(width * done / total))
    diff = width - completed
    progress = char * completed + " " * diff
    percent = round(100 * done / total, 1)
    sys.stdout.write(f" {progress} {percent}% \r")
    sys.stdout.flush()

if __name__ == "__main__":
    # testing code
    for i in range(1000):
        time.sleep(.23)
        pb(i + 1, 1000)

    pb()
Enter fullscreen mode Exit fullscreen mode

In the above code, shutil.get_terminal_size().columns helps determining the number of columns according to the size of the window.

Then, we make some calculation to represent what is completed and what is remaining.

The use of sys.stdout.write and sys.stdout.flush to display the progress is essential here. If you use a basic print instead, you may not see the output until the task is completed (buffer).

The result

You will get something like the following:

||||||||||||||||||||||||||||||||||||||||||||||||||||| 100.0%

Cons

It clearly reinvents the wheel and possibly misses some edge cases third-party packages already address.

The char used here to display the progress is not the best you can find, so do not hesitate to use another one.

Pros

Our utility can be used in various loops and different contexts.

It's very simple and can be modified easily.

It's 100% built-in, no additional package is required.

Top comments (0)