programming
coding-tutorial
status-bar
progress-bar
code-examples

How to print out status bar and percentage?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

A console progress bar is usually just one line that gets rewritten as work advances. The basic technique is simple: compute a percentage, draw a fixed-width bar from that percentage, and print it with a carriage return so the next update overwrites the same line instead of adding a new one.

The Core Idea

Three pieces are involved:

  • the current progress value
  • the total amount of work
  • one console line that you redraw repeatedly

The carriage return character \r moves the cursor back to the start of the current line. That is what makes the output appear animated in place.

A Simple Python Example

python
1import sys
2import time
3
4def render_progress(current, total, width=30):
5    percent = current / total
6    filled = int(width * percent)
7    bar = "#" * filled + "-" * (width - filled)
8    sys.stdout.write(f"\r[{bar}] {percent * 100:6.2f}%")
9    sys.stdout.flush()
10
11
12total = 100
13for i in range(total + 1):
14    render_progress(i, total)
15    time.sleep(0.02)
16
17print()

This prints one bar that grows from left to right and ends with a newline after the loop finishes.

Why flush() Matters

Console output is often buffered. Without flush(), updates may appear in bursts instead of immediately. That makes the progress bar look broken even when the math is correct.

So the normal loop is:

  1. calculate percentage
  2. print with \r
  3. flush output

A Reusable C# Version

The same technique works in C#:

csharp
1using System;
2using System.Threading;
3
4class Program
5{
6    static void DrawProgress(int current, int total, int width = 30)
7    {
8        double percent = (double)current / total;
9        int filled = (int)(percent * width);
10        string bar = new string('#', filled) + new string('-', width - filled);
11
12        Console.Write($"\r[{bar}] {percent * 100,6:F2}%");
13    }
14
15    static void Main()
16    {
17        const int total = 100;
18
19        for (int i = 0; i <= total; i++)
20        {
21            DrawProgress(i, total);
22            Thread.Sleep(20);
23        }
24
25        Console.WriteLine();
26    }
27}

The console line is rewritten in place, so the screen stays clean instead of printing one hundred separate lines.

Add Task Labels or Counts

Real programs often include more context than a bare percentage:

python
def render_progress(current, total, label):
    percent = current / total
    print(f"\r{label}: {current}/{total} ({percent * 100:5.1f}%)", end="", flush=True)

That is useful for file uploads, batch processing, downloads, or migration tools where users want both the fraction and the description of what is happening.

Handle Unknown Totals Differently

If you do not know the total amount of work, a percentage is meaningless. In that case, use a spinner or a counter instead of pretending to show exact completion.

Example spinner idea:

python
1import itertools
2import sys
3import time
4
5for ch in itertools.cycle("|/-\\"):
6    sys.stdout.write(f"\rWorking {ch}")
7    sys.stdout.flush()
8    time.sleep(0.1)

That communicates activity honestly when the total work size is not known.

Avoid Over-Updating

Printing too often can become expensive. If a loop runs millions of times, updating the console every iteration may hurt performance more than the bar helps.

A common optimization is to redraw only when the visible percentage changes or every fixed number of items:

python
if i % 1000 == 0:
    render_progress(i, total)

This keeps output responsive without turning the console into the bottleneck.

Common Pitfalls

The most common mistake is forgetting the carriage return or flush, which causes a new line on every update or delayed output.

Another issue is dividing integers incorrectly or not guarding against total = 0. Developers also often show a fake percentage for tasks whose total work is unknown. A spinner is usually more honest in that case.

Summary

  • Use \r to redraw one console line in place.
  • Compute the filled width from current / total.
  • Flush the output so users see each update immediately.
  • Add labels or counts when users need more context than a bare percentage.
  • If the total is unknown, use a spinner or activity indicator instead of a percentage bar.

Course illustration
Course illustration

All Rights Reserved.