Daniel Engel Daniel Engel - 3 months ago 8
Python Question

My program is not updating its output

I'm trying to make a kind of simple progress bar, when each half a second the percentage is going up; The output is constantly updating itself. For this I tried to use the '\r' argument, but the code just ignores it and prints the progress bar over and over until it gets to 100 percent.

Here is the code:

import time
def progressBar(value, endvalue, bar_length=20):
while value <= endvalue:
percent = float(value) / endvalue
arrow = '-' * int(round(percent * bar_length)-1) + '>'
spaces = ' ' * (bar_length - len(arrow))
print("\rPercent: [{0}] {1}%".format(arrow + spaces, int(round(percent * 100))))
value+=1
time.sleep(0.5)

progressBar(1, 100)


output:

Percent: [> ] 1%

Percent: [> ] 2%

Percent: [> ] 3%

Percent: [> ] 4%

Percent: [> ] 5%

Percent: [> ] 6%

Percent: [> ] 7%

Percent: [-> ] 8%

Percent: [-> ] 9%

Percent: [-> ] 10%

Percent: [-> ] 11%


And so on and on.

Can someone tell me what is the problem here?

Answer

You need to tell print() not to print a newline:

print("\rPercent: [{0}] {1}%".format(arrow + spaces, int(round(percent * 100))),
      end="")

Setting end to an empty string replaces the default \n written.

You probably want to add a print() after the while loop is complete to add an explicit newline.

Demo with just end="":

GIF video of progress bar

You may want to add flush=True to ensure that there isn't a buffer problem (some terminal buffers wait for a newline before flushing):

print("\rPercent: [{0}] {1}%".format(arrow + spaces, int(round(percent * 100))),
      end="", flush=True)

Alternatively, use sys.stdout.write() and sys.stdout.flush():

sys.stdout.write("\rPercent: [{0}] {1}%".format(arrow + spaces, int(round(percent * 100))))
sys.stdout.flush()

but print produces the exact same calls to sys.stdout.write() anyway.

Comments