Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Python: printProgressBar function with autoresize option
# This version of the printProgressBar function implements an optional autoresize argument.
# It has been updated from a previous version to use the shutil Python module to determine
# the terminal size. This update should allow it to work on most operating systems and does
# speed up the autosize feature quite a bit – though it still slows things down quite a bit.
# For more robust features, it's recommended you use a progress bar library like tdqm (see: https://github.com/tqdm/tqdm)
def printProgressBar (iteration, total, prefix = '', suffix = '', decimals = 1, length = 100, fill = '█', autosize = False):
"""
Call in a loop to create terminal progress bar
@params:
iteration - Required : current iteration (Int)
total - Required : total iterations (Int)
prefix - Optional : prefix string (Str)
suffix - Optional : suffix string (Str)
decimals - Optional : positive number of decimals in percent complete (Int)
length - Optional : character length of bar (Int)
fill - Optional : bar fill character (Str)
autosize - Optional : automatically resize the length of the progress bar to the terminal window (Bool)
"""
percent = ("{0:." + str(decimals) + "f}").format(100 * (iteration / float(total)))
styling = '%s |%s| %s%% %s' % (prefix, fill, percent, suffix)
if autosize:
cols, _ = shutil.get_terminal_size(fallback = (length, 1))
length = cols - len(styling)
filledLength = int(length * iteration // total)
bar = fill * filledLength + '-' * (length - filledLength)
print('\r%s' % styling.replace(fill, bar), end = '\r')
# Print New Line on Complete
if iteration == total:
print()
# Sample Usage
import shutil, time
# A List of Items
items = list(range(0, 57))
l = len(items)
# Initial call to print 0% progress
printProgressBar(0, l, prefix = 'Progress:', suffix = 'Complete', autosize = True)
for i, item in enumerate(items):
# Do stuff...
time.sleep(0.1)
# Update Progress Bar
printProgressBar(i + 1, l, prefix = 'Progress:', suffix = 'Complete', autosize = True)
@ahmed4end

This comment has been minimized.

Copy link

@ahmed4end ahmed4end commented Jul 25, 2019

'tput' is not recognized as an internal or external command,
operable program or batch file.

@greenstick

This comment has been minimized.

Copy link
Owner Author

@greenstick greenstick commented Jul 25, 2019

What OS are you using?

@fishnexj

This comment has been minimized.

Copy link

@fishnexj fishnexj commented Jul 31, 2019

Same error for me too:

'tput' is not recognized as an internal or external command,
operable program or batch file.
Traceback (most recent call last):
  File "<...>", line 43, in <module>
    printProgressBar(0, l, prefix = 'Progress:', suffix = 'Complete', autosize = True)
  File "<...>", line 27, in printProgressBar
    length = int(columns) - len(styling)
ValueError: invalid literal for int() with base 10: b''
[Finished in 0.5s with exit code 1]

My OS:
image

@greenstick

This comment has been minimized.

Copy link
Owner Author

@greenstick greenstick commented Aug 1, 2019

Unfortunately I've made the decision to not actively support this Gist and have left it available for historical reference. The function itself if highly inefficient – to allow the progress bar to dynamically resize with the terminal it must open a subprocess and call a terminal command (in this case, tput) to get the window size on each iteration. While there may be some way around this problem, I just developed it as a test case in response to a comment on the question posted here.

If you really do want to get this working, I'd recommend searching for a terminal command / CLI tool on Windows (or whatever OS you intend to use it with) that is capable of detecting the width of the terminal window. All you'll need to do is update line 26 with the appropriate command. For reference, tput is part of the Linux ncurses package, which is available in most Linux distributions. Hope this helps.

@shakeyourbunny

This comment has been minimized.

Copy link

@shakeyourbunny shakeyourbunny commented Aug 24, 2019

to make this work on Windows, use this gist:
https://gist.github.com/shakeyourbunny/303b000168edc2705262ce40381034a3

TLDR: instead of playing around with a subprocess or something, just use shutil.get_terminal_size()

@greenstick

This comment has been minimized.

Copy link
Owner Author

@greenstick greenstick commented Aug 25, 2019

Hadn't thought of shutil – nice idea, definitely would speed things up a bit. I'll update it.

@ezequias

This comment has been minimized.

Copy link

@ezequias ezequias commented Sep 26, 2019

Not working for me.

image

@ezequias

This comment has been minimized.

Copy link

@ezequias ezequias commented Sep 26, 2019

shutil.get_terminal_size()

Not working too

image

@shakeyourbunny

This comment has been minimized.

Copy link

@shakeyourbunny shakeyourbunny commented Sep 26, 2019

The magic sauce is that you have to add some other stuff to, see my version:
https://gist.github.com/shakeyourbunny/303b000168edc2705262ce40381034a3

@greenstick

This comment has been minimized.

Copy link
Owner Author

@greenstick greenstick commented Oct 7, 2019

@ezequias As I understand it, this issue has to do with the return character for the printProgressBar function. It's set to \r but you should be able to set it to \r\n or \n to make it work. The upshot is that your IDE handles the return and newline characters differently than the terminal the function was developed in.

@ezequias

This comment has been minimized.

Copy link

@ezequias ezequias commented Oct 7, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment