Remove and Replace Printed items [duplicate] - python

This question already has answers here:
Print in one line dynamically [duplicate]
(22 answers)
Closed 9 years ago.
The community reviewed whether to reopen this question 4 months ago and left it closed:
Original close reason(s) were not resolved
I was wondering if it was possible to remove items you have printed in Python - not from the Python GUI, but from the command prompt.
e.g.
a = 0
for x in range (0,3):
a = a + 1
b = ("Loading" + "." * a)
print (a)
so it prints
>>>Loading
>>>Loading.
>>>Loading..
>>>Loading...
But, my problem is I want this all on one line, and for it it remove it self when something else comes along. So instead of printing "Loading", "Loading.", "Loading... I want it to print "Loading.", then it removes what is on the line and replaces it with "Loading.." and then removes "Loading.." and replaces it (on the same line) with "Loading...". It's kind of hard to describe.
p.s I have tried to use the Backspace character but it doesn't seem to work ("\b")

Just use CR to go to beginning of the line.
import time
for x in range (0,5):
b = "Loading" + "." * x
print (b, end="\r")
time.sleep(1)

One way is to use ANSI escape sequences:
import sys
import time
for i in range(10):
print("Loading" + "." * i)
sys.stdout.write("\033[F") # Cursor up one line
time.sleep(1)
Also sometimes useful (for example if you print something shorter than before):
sys.stdout.write("\033[K") # Clear to the end of line

import sys
import time
a = 0
for x in range (0,3):
a = a + 1
b = ("Loading" + "." * a)
# \r prints a carriage return first, so `b` is printed on top of the previous line.
sys.stdout.write('\r'+b)
time.sleep(0.5)
print (a)
Note that you might have to run sys.stdout.flush() right after sys.stdout.write('\r'+b) depending on which console you are doing the printing to have the results printed when requested without any buffering.

Related

Why must print()'s end argument be empty in order to facilitate proper "per-coordinate" character printing with the blessed python library? [duplicate]

This question already has answers here:
Getting SyntaxError for print with keyword argument end=' '
(17 answers)
Closed 8 years ago.
This is the function for printing all values in a nested list (taken from Head first with Python).
def printall(the_list, level):
for x in the_list:
if isinstance(x, list):
printall(x, level=level + 1)
else:
for tab_stop in range(level):
print("\t", end='')
print(x)
The function is working properly.
The function basically prints the values in a list and if there is a nested list then it print it by a tab space.
Just for a better understanding, what does end=' ' do?
I am using Python 3.3.5
For 2.7
f = fi.input( files = 'test2.py', inplace = True, backup = '.bak')
for line in f:
if fi.lineno() == 4:
print line + '\n'
print 'extra line'
else:
print line + '\n'
as of 2.6 fileinput does not support with.
This code appends 3 more lines and prints the appended text on the 3rd new line. and then appends a further 16 empty lines.
The default value of end is \n meaning that after the print statement it will print a new line. So simply stated end is what you want to be printed after the print statement has been executed
Eg: - print ("hello",end=" +") will print hello +
See the documentation for the print function: print()
The content of end is printed after the thing you want to print. By default it contains a newline ("\n") but it can be changed to something else, like an empty string.

python delayed loop without new line waits until loop is finished to display text [duplicate]

This question already has answers here:
python print function in real time
(3 answers)
Closed 6 years ago.
I have a loop in python that is sleeping 0.1 seconds every iteration. It is sequentially printing out a string to the console. I want it to add a character every iteration, But the problem is that it waits until the loop is finished to display the text. This only happens when I have the ", end='' " bit at the end of the print call.
import time
def speak(text):
i = 0
for i in range(0, len(text) + 1):
print(text[i], end='')
i += 1
time.sleep(0.1)
speak("Test 123. Can you see me?")
As the comments say, you need flush=True in your call to print(...).
Also, your loop goes one character off the end of the string (causing an exception), and it would be nice to print a newline at the end of the text. Here's a fixed up version that works on my machine:
import time
def speak(text):
for c in text + '\n':
print(c, end='', flush=True)
time.sleep(0.1)
speak("Test 123. Can you see me?")

Python print to stay on same line [duplicate]

This question already has answers here:
How to overwrite the previous print to stdout?
(18 answers)
Closed last month.
import os
import time
h = 0
s = 0
m = 0
while s <= 60:
os.system('clear')
print h, "hours", m, 'minutes', s, 'seconds'
time.sleep(1)
s += 1
if s == 60:
m += 1
s = 0
elif m == 60:
h += 1
m = 0
s = 0
I have this code above. It all works fine and does what it is meant to do, but I want to make it so that it prints all the statements in the same line. For example, it should print out 0 hours 0 minutes 0 seconds and then on the same line should print out 0 hours 0 minutes 1 second, with the second variable the only thing that is changing. How do I do this? I have already tried using the os.system('clear') command but it does not work. Im running this on Mac OSX 10.7.
You should use what your terminal provides. In most cases you need to use '\r' (carriage return, return to first column in that line); but depending on the operating system this might be interpreted such that it also appends a line feed. I feel I remember that OSX might do this.
Also you need to avoid the automatic newline print will always append. You could use a trailing comma for this, but this has issues (stray space, no flushing). So I propose to use sys.stdout.write() instead and because without a newline typically no flushing will be done, you should use sys.stdout.flush() explicitly as well.
Then, returning to the first column will not delete the old output, so it only gets overwritten by the next line. If that is shorter than the one before, you will have trailing junk. To avoid this, again use what your terminal provides (very often '\x1b[K' erases everything till the end of the line without moving the cursor, but if this does not work for you, just print some spaces or make sure your output is formatted always to the same width).
EL = '\x1b[K' # clear to end of line
CR = '\r' # carriage return
sys.stdout.write(("%d hours %d minutes %s seconds" + EL + CR) % (h, m, s))
sys.stdout.flush()
A more decent approach (besides this shortcut by using literal sequences) is to use the official curses library.
import curses
curses.setupterm()
EL = curses.tigetstr('el')
CR = curses.tigetstr('cr')
And if CR really does not work on OSX as we want it to, then there might be goto in your termcaps to go to a specific position (e. g. first column) or you can use save_cursor (SC) and restore_cursor (RC) to restore an earlier saved position:
sys.stdout.write(SC + "%d hours %d minutes %s seconds" + EL + RC % (h, m, s))
Try this:
print h, "hours", m, 'minutes', s, 'seconds', '\r'
and you should also look at Alfe's answer :-)
In Python 3 you could use this kind of code:
print("{} hours, {} minutes, {} seconds".format(h, m, s), end = "\r")

How can I print multiple things on the same line, one at a time?

I want to run a script, which basically shows an output like this:
Installing XXX... [DONE]
Currently, I print Installing XXX... first and then I print [DONE].
How can I instead print Installing xxx... and [DONE] on the same line?
For the specific problem of writing a new message on the same line, replacing what was there before, please see How to overwrite the previous print to stdout?. Most answers here interpreted the question as being about writing new text at the end of the current line.
For the problem of using a single print to output multiple things at once, see How can I print multiple things (fixed text and/or variable values) on the same line, all at once?.
Python 3 Solution
The print() function accepts an end parameter which defaults to \n (new line). Setting it to an empty string prevents it from issuing a new line at the end of the line.
def install_xxx():
print("Installing XXX... ", end="", flush=True)
install_xxx()
print("[DONE]")
Python 2 Solution
Putting a comma on the end of the print() line prevents print() from issuing a new line (you should note that there will be an extra space at the end of the output).
def install_xxx():
print "Installing XXX... ",
install_xxx()
print "[DONE]"
You can simply use this:
print 'something',
...
print ' else',
and the output will be
something else
no need to overkill by import sys. Pay attention to comma symbol at the end.
Python 3+
print("some string", end=""); to remove the newline insert at the end. Read more by help(print);
You should use backspace '\r' or ('\x08') char to go back on previous position in console output
Python 2+:
import time
import sys
def backspace(n):
sys.stdout.write((b'\x08' * n).decode()) # use \x08 char to go back
for i in range(101): # for 0 to 100
s = str(i) + '%' # string for output
sys.stdout.write(s) # just print
sys.stdout.flush() # needed for flush when using \x08
backspace(len(s)) # back n chars
time.sleep(0.2) # sleep for 200ms
Python 3:
import time
def backline():
print('\r', end='') # use '\r' to go back
for i in range(101): # for 0 to 100
s = str(i) + '%' # string for output
print(s, end='') # just print and flush
backline() # back to the beginning of line
time.sleep(0.2) # sleep for 200ms
This code will count from 0% to 100% on one line. Final value will be:
> python test.py
100%
Additional info about flush in this case here: Why do python print statements that contain 'end=' arguments behave differently in while-loops?
Use sys.stdout.write('Installing XXX... ') and sys.stdout.write('Done'). In this way, you have to add the new line by hand with "\n" if you want to recreate the print functionality. I think that it might be unnecessary to use curses just for this.
Most simple:
Python 3
print('\r' + 'something to be override', end='')
It means it will back the cursor to beginning, than will print something and will end in the same line. If in a loop it will start printing in the same place it starts.
None of the answers worked for me since they all paused until a new line was encountered. I wrote a simple helper:
def print_no_newline(string):
import sys
sys.stdout.write(string)
sys.stdout.flush()
To test it:
import time
print_no_newline('hello ')
# Simulate a long task
time.sleep(2)
print('world')
"hello " will first print out and flush to the screen before the sleep. After that you can use standard print.
sys.stdout.write will print without return carriage
import sys
sys.stdout.write("installing xxx")
sys.stdout.write(".")
http://en.wikibooks.org/wiki/Python_Programming/Input_and_output#printing_without_commas_or_newlines
Python appends newline as an end to print. Use end=' ' for python3 for print method to append a space instead of a newline. for python2 use comma at end of print statement.
print('Foo', end=' ')
print('Bar')
This simple example will print 1-10 on the same line.
for i in range(1,11):
print (i, end=" ")
Print has an optional end argument, it is what printed in the end.
The default is a newline, but you can change it to empty string. e.g. print("hello world!", end="")
If you want to overwrite the previous line (rather than continually adding to it), you can combine \r with print(), at the end of the print statement. For example,
from time import sleep
for i in xrange(0, 10):
print("\r{0}".format(i)),
sleep(.5)
print("...DONE!")
will count 0 to 9, replacing the old number in the console. The "...DONE!" will print on the same line as the last counter, 9.
In your case for the OP, this would allow the console to display percent complete of the install as a "progress bar", where you can define a begin and end character position, and update the markers in between.
print("Installing |XXXXXX | 30%"),
Here a 2.7-compatible version derived from the 3.0 version by #Vadim-Zin4uk:
Python 2
import time
for i in range(101): # for 0 to 100
s = str(i) + '%' # string for output
print '{0}\r'.format(s), # just print and flush
time.sleep(0.2)
For that matter, the 3.0 solution provided looks a little bloated. For example, the backspace method doesn't make use of the integer argument and could probably be done away with altogether.
Python 3
import time
for i in range(101): # for 0 to 100
s = str(i) + '%' # string for output
print('{0}\r'.format(s), end='') # just print and flush
time.sleep(0.2) # sleep for 200ms
Both have been tested and work.
This is a very old thread, but here's a very thorough answer and sample code.
\r is the string representation of Carriage Return from the ASCII character set. It's the same as octal 015 [chr(0o15)] or hexidecimal 0d [chr(0x0d)] or decimal 13 [chr(13)]. See man ascii for a boring read. It (\r) is a pretty portable representation and is easy enough for people to read. It very simply means to move the carriage on the typewriter all the way back to the start without advancing the paper. It's the CR part of CRLF which means Carriage Return and Line Feed.
print() is a function in Python 3. In Python 2 (any version that you'd be interested in using), print can be forced into a function by importing its definition from the __future__ module. The benefit of the print function is that you can specify what to print at the end, overriding the default behavior of \n to print a newline at the end of every print() call.
sys.stdout.flush tells Python to flush the output of standard output, which is where you send output with print() unless you specify otherwise. You can also get the same behavior by running with python -u or setting environment variable PYTHONUNBUFFERED=1, thereby skipping the import sys and sys.stdout.flush() calls. The amount you gain by doing that is almost exactly zero and isn't very easy to debug if you conveniently forget that you have to do that step before your application behaves properly.
And a sample. Note that this runs perfectly in Python 2 or 3.
from __future__ import print_function
import sys
import time
ANS = 42
FACTORS = {n for n in range(1, ANS + 1) if ANS % n == 0}
for i in range(1, ANS + 1):
if i in FACTORS:
print('\r{0:d}'.format(i), end='')
sys.stdout.flush()
time.sleep(ANS / 100.0)
else:
print()
This solution in Python 3.X specific:
When I need to do this, I'll generally just use
end=' '
For example:
# end='' ends the output with a <space>
print("Welcome to" , end = ' ')
print("stackoverflow", end = ' ')
This outputs as:
Welcome to stackoverflow
The space in end= can be replaced with any character. For example,
print("Welcome to" , end = '...')
print("stackoverflow", end = '!')
Which outputs as:
Welcome to...stackoverflow!
print() has a built in parameter "end" that is by default set to "\n"
Calling print("This is America") is actually calling print("This is America", end = "\n").
An easy way to do is to call print("This is America", end ="")
Just in case you have pre-stored the values in an array, you can call them in the following format:
for i in range(0,n):
print arr[i],
Found this Quora post, with this example which worked for me (python 3),
which was closer to what I needed it for (i.e. erasing the whole previous line).
The example they provide:
def clock():
while True:
print(datetime.now().strftime("%H:%M:%S"), end="\r")
For printing the on the same line, as others have suggested, just use end=""
I found this solution, and it's working on Python 2.7
# Working on Python 2.7 Linux
import time
import sys
def backspace(n):
print('\r', end='') # use '\r' to go back
for i in range(101): # for 0 to 100
s = str(i) + '%' # string for output
sys.stdout.write(string)
backspace(len(s)) # back for n chars
sys.stdout.flush()
time.sleep(0.2) # sleep for 200ms

Print to the same line and not a new line? [duplicate]

This question already has answers here:
How to overwrite the previous print to stdout?
(18 answers)
Why doesn't print output show up immediately in the terminal when there is no newline at the end?
(1 answer)
Closed last month.
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.
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!
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)
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()
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’.
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
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)
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
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()
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')
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)
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
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.)
For Python 3+
for i in range(5):
print(str(i) + '\r', sep='', end ='', file = sys.stdout , flush = False)
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.
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)
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)
If you are using Python 3
then this is for you and it really works.
print(value , sep='',end ='', file = sys.stdout , flush = False)
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!
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)

Categories

Resources