dreamzboy
dreamzboy

Reputation: 841

Python ProgressBar in CLI

I'm using Python 3.x and have downloaded the progressbar2 library; however, I'm struggling with how to use it in my program. Everything works fine when there's a specified range but how do I get the progressbar to update in real-time with my own code? I expect the progress bar to jump 20% at every iteration of the texts list with it being display first and refresh the progress as it prints out the results.

I've also found another question similar to mine on Stack but I'd prefer using the progressbar2 library since it's already there. Consider the following:

import time
import progressbar

texts = ['a', 'b', 'c', 'd', 'e']

def basic_widget_example (texts):

    widgets = [progressbar.Percentage (), progressbar.Bar ()]
    bar = progressbar.ProgressBar (widgets = widgets, max_value = len (texts)).start ()
    for i in range (len (texts)):
        print (texts [i])
        time.sleep (0.1)
        bar.update (i + 1)
    bar.finish ()

Results:

N/A%|                                                                                                               |a
 20%|######################                                                                                         |b
 40%|############################################                                                                   |c
 60%|##################################################################                                             |d
 80%|########################################################################################                       |e
 100%|###############################################################################################################|

I would like it to look like this:

100%|#############################################################|
a
b                                                                                                                    
c                                                                                                                    
d                                                                                                                    
e     

One solution is to create 2 for-loop but as you can see the progressbar display is no longer accurate or in sync with my tasks. The progressbar will show 100% in less than a second even though my tasks may take 2 minutes to complete. Any idea how to achieve this while being close to accurate as possible?

def basic_widget_example (texts):

    widgets = [progressbar.Percentage (), progressbar.Bar ()]
    bar = progressbar.ProgressBar (widgets = widgets, max_value = len (texts)).start ()
    for i in range (len (texts)):
        # Do something
        time.sleep (0.1)
        bar.update (i + 1)
    bar.finish ()

    for text in texts:
        print (text)

Upvotes: 2

Views: 1149

Answers (1)

dreamzboy
dreamzboy

Reputation: 841

I've misinterpreted the usage of the progress bar. The progress bar is meant to let user know that calculation is taking place where there isn't a need communicating to the user. It's useful in cases where some string manipulations or creating a list from a set of data is taking place behind the scene. Once results is achieved and ready to be output onto the screen, there wouldn't be a need for a progress bar at that point.

As an example, I created a list of integers from 1 - 50, added 1 to it (background process), and appended it to another list which will be used to simulate output.

lst = [i for i in range (50)]
basic_widget_example (lst)

def basic_widget_example (lst):

    newlist = []

    widgets = [progressbar.Percentage (), progressbar.Bar ()]
    bar = progressbar.ProgressBar (widgets = widgets, max_value = len (lst)).start ()
    for i in range (len (lst)):
        # Do something
        newlist = [x + 1 for x in lst]
        time.sleep (0.1)
        bar.update (i + 1)
    bar.finish ()

    print (newlist [:5])

Results:

100%|###############################################################################################################|
[1, 2, 3, 4, 5]

The progress bar is being incremented with the length of the list which is 50 specified by the "max_value". This will produce two '#' at every iteration.

It's also worth mentioning the time.sleep (value) correspond to the time it takes for the progress bar to complete. In my example, 50 iterations * 0.1 seconds = 5 seconds. This means the progressbar will be 100% completed in 5 seconds. This is not real-time. Further calculations is needed to come up with the sleep value if real-time. One idea is to calculate the time it takes for each iteration or take an average and use that as a value for the time.sleep.

Upvotes: 1

Related Questions