PythonMastery

Progress bar in Python

Draw a text progress bar with a percentage, and redraw it on one line in the terminal with a carriage return.

A text progress bar shows how much of a long task is done. This program builds the bar as a string first, so you can see each stage, and then shows how to redraw it on one line in a terminal.

The program

python
def progress_bar(done, total, width=30):
    fraction = done / total if total else 1
    filled = int(width * fraction)
    bar = "█" * filled + "-" * (width - filled)
    return f"[{bar}] {fraction:4.0%} ({done}/{total})"


for done in [0, 5, 10, 15, 20]:
    print(progress_bar(done, 20))
output
[------------------------------]   0% (0/20)
[███████-----------------------]  25% (5/20)
[███████████████---------------]  50% (10/20)
[██████████████████████--------]  75% (15/20)
[██████████████████████████████] 100% (20/20)

How it works

Updating one line in the terminal

To make the bar grow in place, print it with "\r" at the start and end="". The carriage return \r moves the cursor back to the start of the line, so the next bar is written over the old one:

python
import time


def progress_bar(done, total, width=30):
    fraction = done / total if total else 1
    filled = int(width * fraction)
    bar = "█" * filled + "-" * (width - filled)
    return f"[{bar}] {fraction:4.0%} ({done}/{total})"


total = 20
for done in range(total + 1):
    print("\r" + progress_bar(done, total), end="", flush=True)
    time.sleep(0.01)  # stands in for real work
print()

This block has no output shown: in a terminal you see one bar that fills up. The Run button on this page and other captured output show all 21 versions of the line. flush=True makes Python show each version at once instead of waiting until the line is finished. The final print() moves to a new line when the work is done.

Learn the idea: F-Strings: Modern String Formatting, Loops: for, while, and the Pythonic Patterns, Working with Strings