Print to the same line and not a new line?

Question:

Basically I want to do the opposite of what this guy did… hehe.

Python Script: Print new line each time to shell rather than update existing line

I have a program that is telling me how far along it is.

for i in some_list:
    #do a bunch of stuff.
    print i/len(some_list)*100," percent complete"

So if len(some_list) was 50, I’d get that last line printed 50 times over. I want to print one line and keep updating that line. I know I know this is probably the lamest question you’ll read all day. I just can’t figure out the four words I need to put into google to get the answer.

Update! I tried mvds’ suggestion which SEEMED right. The new code

print percent_complete,"           r",

Percent complete is just a string (I was abstracting the first time now I an trying to be literal). The result now is that it runs the program, doesn’t print ANYTHING until after the program is over, and then prints “100 percent complete” on one and only one line.

Without the carriage return (but with the comma, half of mvds’ suggestion) it prints nothing until the end. And then prints:

0 percent complete     2 percent complete     3 percent complete     4 percent complete    

And so on. So now the new issue is that with the comma it doesn’t print until the program is finished.

With the carriage return and no comma it behaves the exact same as with neither.

Asked By: chriscauley

||

Answers:

It’s called the carriage return, or r

Use

print i/len(some_list)*100," percent complete         r",

The comma prevents print from adding a newline. (and the spaces will keep the line clear from prior output)

Also, don’t forget to terminate with a print "" to get at least a finalizing newline!

Answered By: mvds

Try it like this:

for i in some_list:
    #do a bunch of stuff.
    print i/len(some_list)*100," percent complete",

(With a comma at the end.)

Answered By: chryss

This works for me, hacked it once to see if it is possible, but never actually used in my program (GUI is so much nicer):

import time
f = '%4i %%'
len_to_clear = len(f)+1
clear = 'x08'* len_to_clear
print 'Progress in percent:'+' '*(len_to_clear),
for i in range(123):
    print clear+f % (i*100//123),
    time.sleep(0.4)
raw_input('nDone')
Answered By: Tony Veijalainen

From python 3.x you can do:

print('bla bla', end='')

(which can also be used in Python 2.6 or 2.7 by putting from __future__ import print_function at the top of your script/module)

Python console progressbar example:

import time

# status generator
def range_with_status(total):
    """ iterate from 0 to total and show progress in console """
    n=0
    while n<total:
        done = '#'*(n+1)
        todo = '-'*(total-n-1)
        s = '<{0}>'.format(done+todo)
        if not todo:
            s+='n'        
        if n>0:
            s = 'r'+s
        print(s, end='')
        yield n
        n+=1

# example for use of status generator
for i in range_with_status(10):
    time.sleep(0.1)
Answered By: Remi

for Console you’ll probably need

sys.stdout.flush()

to force update. I think using , in print will block stdout from flushing and somehow it won’t update

Answered By: siriusd

For me, what worked was a combo of Remi’s and siriusd’s answers:

from __future__ import print_function
import sys

print(str, end='r')
sys.stdout.flush()
Answered By: dlchambers
import time
import sys


def update_pct(w_str):
    w_str = str(w_str)
    sys.stdout.write("b" * len(w_str))
    sys.stdout.write(" " * len(w_str))
    sys.stdout.write("b" * len(w_str))
    sys.stdout.write(w_str)
    sys.stdout.flush()

for pct in range(0, 101):
    update_pct("{n}%".format(n=str(pct)))
    time.sleep(0.1)

b will move the location of the cursor back one space
So we move it back all the way to the beginning of the line
We then write spaces to clear the current line – as we write spaces the cursor moves forward/right by one
So then we have to move the cursor back at the beginning of the line before we write our new data

Tested on Windows cmd using Python 2.7

Answered By: Robert

Based on Remi answer for Python 2.7+ use this:

from __future__ import print_function
import time

# status generator
def range_with_status(total):
    """ iterate from 0 to total and show progress in console """
    import sys
    n = 0
    while n < total:
        done = '#' * (n + 1)
        todo = '-' * (total - n - 1)
        s = '<{0}>'.format(done + todo)
        if not todo:
            s += 'n'
        if n > 0:
            s = 'r' + s
        print(s, end='r')
        sys.stdout.flush()
        yield n
        n += 1


# example for use of status generator
for i in range_with_status(50):
    time.sleep(0.2)
Answered By: Francisco Costa

In Python 3.3+ you don’t need sys.stdout.flush(). print(string, end='', flush=True) works.

So

print('foo', end='')
print('rbar', end='', flush=True)

will overwrite ‘foo’ with ‘bar’.

Answered By: LeopardShark

For Python 3.6+ and for any list rather than just ints, as well as using the entire width of your console window and not crossing over to a new line, you could use the following:

note: please be informed, that the function get_console_with() will work only on Linux based systems, and as such you have to rewrite it to work on Windows.

import os
import time

def get_console_width():
    """Returns the width of console.

    NOTE: The below implementation works only on Linux-based operating systems.
    If you wish to use it on another OS, please make sure to modify it appropriately.
    """
    return int(os.popen('stty size', 'r').read().split()[1])


def range_with_progress(list_of_elements):
    """Iterate through list with a progress bar shown in console."""

    # Get the total number of elements of the given list.
    total = len(list_of_elements)
    # Get the width of currently used console. Subtract 2 from the value for the
    # edge characters "[" and "]"
    max_width = get_console_width() - 2
    # Start iterating over the list.
    for index, element in enumerate(list_of_elements):
        # Compute how many characters should be printed as "done". It is simply
        # a percentage of work done multiplied by the width of the console. That
        # is: if we're on element 50 out of 100, that means we're 50% done, or
        # 0.5, and we should mark half of the entire console as "done".
        done = int(index / total * max_width)
        # Whatever is left, should be printed as "unfinished"
        remaining = max_width - done
        # Print to the console.
        print(f'[{done * "#"}{remaining * "."}]', end='r')
        # yield the element to work with it
        yield element
    # Finally, print the full line. If you wish, you can also print whitespace
    # so that the progress bar disappears once you are done. In that case do not
    # forget to add the "end" parameter to print function.
    print(f'[{max_width * "#"}]')


if __name__ == '__main__':
    list_of_elements = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
    for e in range_with_progress(list_of_elements):
        time.sleep(0.2)

Answered By: tamaroth

Late to the game – but since the none of the answers worked for me (I didn’t try them all) and I’ve come upon this answer more than once in my search … In python 3, this solution is pretty elegant and I believe does exactly what the author is looking for, it updates a single statement on the same line. Note, you may have to do something special if the line shrinks instead of grows (like perhaps make the string a fixed length with padded spaces at the end)

if __name__ == '__main__':
    for i in range(100):
        print("", end=f"rPercentComplete: {i} %")
        time.sleep(0.2)
Answered By: SteveJ

If you are using Python 3
then this is for you and it really works.

print(value , sep='',end ='', file = sys.stdout , flush = False)
Answered By: Azaz-ul- Haque

If you are using Spyder, the lines just print continuously with all the previous solutions. A way to avoid that is using:

for i in range(1000):
    print('r' + str(round(i/len(df)*100,1)) + '% complete', end='')
    sys.stdout.flush()
Answered By: bfree67

For Python 3+

for i in range(5):
    print(str(i) + 'r', sep='', end ='', file = sys.stdout , flush = False)
Answered By: maximusdooku

Just figured this out on my own for showing a countdown but it would also work for a percentage.

import time
#Number of seconds to wait
i=15
#Until seconds has reached zero
while i > -1:
    #Ensure string overwrites the previous line by adding spaces at end
    print("r{} seconds left.   ".format(i),end='')
        time.sleep(1)
        i-=1
    print("") #Adds newline after it's done

As long as whatever comes after ‘/r’ is the same length or longer (including spaces) than the previous string, it will overwrite it on the same line. Just make sure you include the end=” otherwise it will print to a newline. Hope that helps!

Answered By: ReconGator

for object "pega" that provides StartRunning(), StopRunning(),
boolean getIsRunning() and integer getProgress100() returning
value in range of 0 to 100, this provides text progress bar
while running…

now = time.time()
timeout = now + 30.0
last_progress = -1

pega.StartRunning()

while now < timeout and pega.getIsRunning():
    time.sleep(0.5)
    now = time.time()

    progress = pega.getTubProgress100()
    if progress != last_progress:
        print('r'+'='*progress+'-'*(100-progress)+' ' + str(progress) + "% ", end='', flush=True)
        last_progress = progress

pega.StopRunning()

progress = pega.getTubProgress100()
print('r'+'='*progress+'-'*(100-progress)+' ' + str(progress) + "% ", flush=True)
Answered By: jwasch

As of end of 2020 and Python 3.8.5 on linux console for me only this works:

print('some string', end='r')

Credit goes to: This post

Answered By: parrott

As of 2021, for Python 3.9.0 the following solution worked for me in Windows 10, Pycharm.

print('r some string ', end='', flush=True)

Answered By: Rujuta Vaze

In those cases, with python 3.x, I’m using the following code:

for ii in range(100):
    print(f"rPercent: {ii+1} %", end=" "*20)

The problem with some other answers is that if your printed string goes shorter at one step, the last characters from the previous string won’t be overwrited.

So I use end=" "*20 in order to overwrite the previous line with whitespace. Just make sure that 20 is longer than the length of your longest string.

Answered By: obchardon
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.