Implementing Progress Bars in Python for Long-Running Scripts

Introduction

When working with long-running scripts or operations in Python, providing real-time feedback to users via a progress bar can significantly enhance user experience. A progress bar visually indicates the completion status of a task, helping users understand how much longer they might need to wait. This tutorial explores various methods for implementing progress bars in Python using both built-in techniques and third-party libraries.

Understanding Progress Bars

A progress bar typically consists of a visual indicator that fills up as the operation progresses. It can be accompanied by additional information such as percentage completed, estimated time remaining, and a label or prefix describing the task.

Built-In Solutions

For simple scenarios where external dependencies are undesirable, Python’s standard library can be utilized to create basic progress bars. Here’s an example of how you can implement a custom progress bar using sys.stdout:

import sys
import time

def simple_progress_bar(total_iterations, prefix="", size=40):
    """Displays a simple text-based progress bar."""
    count = 0
    start_time = time.time()
    
    while count < total_iterations:
        count += 1
        elapsed_time = time.time() - start_time
        percentage = (count / total_iterations) * 100
        
        # Calculate remaining time
        estimated_total_time = elapsed_time / (count / 100)
        remaining_time = estimated_total_time - elapsed_time
        
        filled_length = int(size * count // total_iterations)
        bar = '#' * filled_length + '-' * (size - filled_length)

        sys.stdout.write(f"\r{prefix}[{bar}] {int(percentage)}% Complete")
        
        # Display the estimated remaining time
        mins, sec = divmod(remaining_time, 60)
        if count == total_iterations:
            sys.stdout.write(" - Completed!\n")
        else:
            sys.stdout.write(f" - Remaining: {int(mins):02}:{sec:05.2f}")
        
        sys.stdout.flush()
        time.sleep(0.1) # Simulate work by sleeping for a short period

# Usage
total_iterations = 50
simple_progress_bar(total_iterations, prefix="Processing:", size=40)

This function uses sys.stdout.write to update the progress bar in place with carriage return (\r) to overwrite the current line. It calculates and displays both percentage completion and estimated remaining time.

Using Third-Party Libraries

For more advanced functionality and ease of use, several third-party libraries are available that offer customizable progress bars:

TQDM

TQDM is a popular library for adding progress bars in Python scripts. It supports various styles and formats, making it suitable for both console applications and Jupyter notebooks.

To install TQDM, run:

pip install tqdm

Here’s how you can use TQDM to create a progress bar:

from tqdm import tqdm
import time

# Simulate a long-running process
for _ in tqdm(range(100), desc="Processing items"):
    time.sleep(0.1)

TQDM automatically handles the formatting and updating of the progress bar, providing a simple interface for looping over iterable objects.

Custom Progress Bar Function

If you prefer to write your own reusable function without external dependencies, consider this approach:

import sys
import time

def update_progress(progress):
    """Displays or updates a console progress bar."""
    bar_length = 10
    if not isinstance(progress, float):
        progress = 0.0
        status = "Error: Progress must be a float between 0 and 1"
    elif progress < 0:
        progress = 0.0
        status = "Halt..."
    elif progress >= 1:
        progress = 1.0
        status = "Done..."

    block = int(round(bar_length * progress))
    text = f"\rPercent: [{'#' * block + '-' * (bar_length - block)}] {progress*100:.2f}% {status}"
    sys.stdout.write(text)
    sys.stdout.flush()

# Usage example
for i in range(101):
    time.sleep(0.1)
    update_progress(i / 100.0)

print("\nProcess completed.")

This function is flexible, allowing progress to be updated incrementally and displaying both percentage completion and status messages.

Conclusion

Choosing the right method for implementing a progress bar depends on your specific needs and constraints. For straightforward tasks or when avoiding dependencies, custom-built solutions using Python’s standard library are sufficient. However, for more complex requirements or ease of integration with existing codebases, third-party libraries like TQDM offer robust and flexible options.

By understanding these methods, you can effectively implement progress bars in your Python scripts to improve user experience during long-running operations.

Leave a Reply

Your email address will not be published. Required fields are marked *