I have the following loop which prints a period after each iteration:
for i in range(3):
time.sleep(1)
print('.')
This runs exactly as expected: a period is printed to the terminal on a new line in 1 second increments
. # after 1 seconds
. # after 2 seconds
. # after 3 seconds
I want to change the output to print periods to the same line (so the output is more compact and easier to read). However, I have a problem when I change the code to the following:
for i in range(3):
time.sleep(1)
print('.', end='')
In this case, the single line of periods only print all at once when the for loop is complete:
... # all after 3 seconds
Am I doing something wrong here or there a limitation with the python print statement?
By default, terminal output won't appear until a newline is printed.
You can force partial lines to appear immediately by adding flush=True to the print call.
Here, this will help you:
import time
for i in range(3):
time.sleep(1)
print(".", end="", flush=True)
print("")
Edit
In case you are using python2, be sure to add
from __future__ import print_function
as the first statement to your script.
Related
So i am currently trying to make something that will print . and remove it then print ..
and also remove it then print ... When i tried using sys module to remove the prevous text this was the output: lol [Ktest so it basically adds a [K to the next line.
I also tried using another method so instead of removing the prevous text it would just add onto it like:
import time
print("lol",end="")
time.sleep(1)
print("test")
it did work in IDLE but when i tried to use it by opening the file in the command promt it waited for 1 second and then just gave loltest without any delay between them. So nothing i found in the internet worked for me.
You may print with the keyword argument end to append the special character '\r' to the end of the line.
E.g.
import time
print(".", end='\r')
time.sleep(2)
print("..", end='\r')
time.sleep(2)
print("...", end='\r')
time.sleep(2)
'\r' is carriage return and will return to the start of the line in some terminals, from where you can overwrite the text you just printed. Note that the behaviour might differ between terminals though.
To print over the prvious print, you can use end="\r.
import time
print("lol", end="\r")
time.sleep(1)
print("test")
for i in range(4):
print("."*i, end="\r")
time.sleep(1)
You can use the os module to execute shell commands.
To clear the terminal, command required in windows is cls and for unix its clear
import os
os.system('cls' if os.name == 'nt' else 'clear')
If you don't want to clear previous terminal outputs you can use flexibility of print function or the carriage return as others denoted.
for _ in range(3):
print('.', end='')
time.sleep(1)
If you specifically want to print . then .. then ..., you don't need to remove the existing text; you can just print additional dots.
To make the dots actually appear one by one, you'll need to flush the buffers, using flush=True
import time
for _ in range(3):
print('.', end='', flush=True)
time.sleep(1)
print()
This has the advantage that it will work much more generally; almost any output method can do that, whereas ANSI codes or tricks with \r or clearing the screen depend on your hardware, operating system and various other things.
You can do it with ANSI escape codes, like this:
import sys, time
clear_line = '\x1b[1K\r'
print("lol", end="")
sys.stdout.flush() # to force printing the text above
time.sleep(1)
print(clear_line+"test") # Now lol replaced with test
Please note that ANSI codes you should use depend on the environment where the program is executing (platform, terminal, etc.).
Update: you may want to see the built-in curses module.
So i have a code of a timer and When a person puts in the number i just want the timer to start and inputted number to not be visible.Code is something like
s=int(input("enter time in sec"))
countdown(s)
so the output is :
enter time in sec 5
0:4
0:3
0:2
0:1
0:0
time up
What i want is to first remove "enter time in sec 5" then when 0:4 prints i want to print 0:3 in its place not below it.
I tried Python deleting input line and copy pasted this on the code like so
s = int(input("enter time in sec "))
print ('\033[1A\033[K')
countdown(s)
and nothing seemed to happen, don't if im wrong in the implementation or it didn't work.
Edit:-
Tried both
os.system('cls')
and
print ('\033[1A\033[K')
neither seemed to work
my code,
def time_format(inp):
import os
m,s=divmod(inp,60)
#os.system('cls')
print ('\033[1A\033[K')
...code for printing time below...
Edit:- im on windows and am using Idle.
neither of the two work
You didn't specify what OS you use but if you target Linux it could
be:
#!/usr/bin/env python3
import time
def countdown(seconds):
for i in range(seconds, -1, -1):
# move to the beginning of the line and remove line
print("\r\033[K", end='', flush=True)
print(f"\r{i}", end='', flush=True)
time.sleep(1)
print("\nTime's up!")
s = int(input("enter time in sec: "))
# move one line up
print("\033[1A", end='', flush=True)
countdown(s)
It works like that:
See accepted answer of: How to clear the interpreter console?
os.system('cls') works on Windows, while
os.system('clear') works on Linux
Got a pop saying I shouldn't delete answered question therefore answering it myself.
I believe both the
print("\033[1A", end='', flush=True)
and
os.system('cls')
works. The issue is that there is no option/method to do it on IDLE. because i tried both the methods work if i double click and run the file as is but none work on IDLE
I am using the following line to print the time at the start of my code.
print (time.strftime("%H:%M:%S"))
I am also using the same command during long 'for' loops so that I can predict how long it will take my code to run. (I am doing heat flow modeling with a lot of time steps.)
The time at the start doesn't print until the first print time.strftime() command in the 'for' loop prints. Both are the correct times.
How can I get it to print when the code starts, rather than when the next print command seems to flush it out?
What you're trying to do is to flush out the print buffer, which looks like this in Python 2:
import sys
print(time.strftime("%H:%M:%S"))
sys.stdout.flush()
In Python 3, it's even easier:
print(time.strftime("%H:%M:%S"), flush=True)
I get different time in my for loop whenever i print time.strftime("%H:%M:%S") I am using python 3.5
import time
print ('Started at :' + time.strftime("%H:%M:%S"))
for x in range(5):
print (x)
time.sleep(1)
print ('Current time is:' + time.strftime("%H:%M:%S"))
print ('Script Ended at :' + time.strftime("%H:%M:%S"))
I want to make (for fun) python print out 'LOADING...' to console. The twist is that I want to print it out letter by letter with sleep time between them of 0.1 seconds (ish). So far I did this:
from time import sleep
print('L') ; sleep(0.1)
print('O') ; sleep(0.1)
print('A') ; sleep(0.1)
etc...
However that prints it to separate lines each.
Also I cant just type print('LOADING...') since it will print instantaneously, not letter by letter with sleep(0.1) in between.
The example is trivial but it raises a more general question: Is it possible to print multiple strings to one line with other function being executed in between the string prints?
In Python2, if you put a comma after the string, print does not add a new line. However, the output may be buffered, so to see the character printed slowly, you may also need to flush stdout:
from time import sleep
import sys
print 'L',
sys.stdout.flush()
sleep(0.1)
So to print some text slowly, you could use a for-loop like this:
from time import sleep
import sys
def print_slowly(text):
for c in text:
print c,
sys.stdout.flush()
sleep(0.5)
print_slowly('LOA')
In Python3, change
print c,
to
print(c, end='')
You can also simply try this
from time import sleep
loading = 'LOADING...'
for i in range(10):
print(loading[i], sep=' ', end=' ', flush=True); sleep(0.5)
from time import sleep
myList = ['Let this be the first line', 'Followed by a second line', 'and a third line']
for s in myList:
print(s) ; sleep(0.6)
If you've written a quite large program and want to add that feature, then overwrite the builtin function print
python_print = print
def print(txt):
text = str(txt)
for c in text:
python_print(c, end="", flush=True)
time.sleep(random.randint(2, 8)/100)
python_print()
This function ensures that
The output is flushed (no need of the sys module)
After one character was written, there is a delay of 0.02 to 0.08 seconds.
The actual behavior of the print function is kept (so you can make it print arrays and modules) - because of the str() call, though there are some exceptions.
What this function cannot do:
You can't call print like this anymore because it only takes one argument:
print("Hello", "World")
Feel free to add that feature or have a look at someone implemented that:
https://book.pythontips.com/en/latest/args_and_kwargs.html
Oh and if you haven't noticed yet - use python_print() if delayed text is inapropriate in some cases.
I wonder why python_print is not shallow-cloned. May anyone explain?
--
Someone implemented that :)
Someone has called my approach (I think especially the *args) cute and worked for at least 30 minutes to get something even better which is considerably larger (please, don't call it bloated though). I didn't test it, but it seems working well to my eyes.
So with that code you'll be able to use print like print("Hello", "World") again.
Credits to: #MarcinKonowalczyk =>
https://gist.github.com/MarcinKonowalczyk/48a08fe2492b88df184decf427fd2caf
Thank you for taking your time.
Now Run a Function While Loading
In order to run something (otherwise Loading would be useless anyway I guess) while it's printing, you can use the threading module.
So, without further ado, let's quickly get started.
import threading
def load():
# do I/O blocking stuff here
threading.Thread(target=load).start() # returns the thread object
# and runs start() to launch the function load() non-blocking.
print("LOADING...")
You may consider removing the random delay from my function which is untypical for a LOADING... screen.
If you don't need to wait until the LOADING... is done to close the program easily with ctrl-c, you can change the daemon attribute to True. Please note that, if the main thread finishes, your other thread will stop forcefully.
Here's an example to how you could to that:
loadingThread = Threading.thread(target=load)
loadingThread.daemon = True
loadingThread.start()
print("LOADING...")
loadingThread.join() # wait for the loadingThread to finish
With this, the program will exit just fine, however you may have to catch KeyboardInterrupt:
try:
loadingThread.join()
except KeyboardInterrupt:
# cleanup stuff here or just *pass*
finally: # optional, runs *always*
# cleanup stuff here
Updated to print all the letters on one line.
from time import sleep
import sys
sys.stdout.write ('L') ; sleep(0.1)
sys.stdout.write ('O') ; sleep(0.1)
sys.stdout.write ('A') ; sleep(0.1)
...
sys.stdout.write ('\n')
etc...
or even:
from time import sleep
import sys
output = 'LOA...'
for char in output:
sys.stdout.write ('%s' % char)
sleep (0.1)
sys.stdout.write ('\n')
To type a string one letter at a time all you've got to do is this:
import sys
import time
yourWords = "whatever you want to type letter by letter"
for char in yourWords:
sys.stdout.write(char)
time.sleep(0.1)
import time
import sys
def code(text, delay=0.07):
for c in text:
sys.stdout.write(c)
sys.stdout.flush()
time.sleep(delay)
print()
Instead of print type code
Most of questions related to this topics here in SO is as follows:
How to print some information on the same line without introducing a
new line
Q1 Q2.
Instead, my question is as follows:
I expect to see the following effect,
>> You have finished 10%
where the 10 keep increasing in the same time. I know how to do this in C++ but cannot
find a good solution in python.
import sys, time
for i in xrange(0, 101, 10):
print '\r>> You have finished %d%%' % i,
sys.stdout.flush()
time.sleep(2)
print
The \r is the carriage return. You need the comma at the end of the print statement to avoid automatic newline. Finally sys.stdout.flush() is needed to flush the buffer out to stdout.
For Python 3, you can use:
print("\r>> You have finished {}%".format(i), end='')
Python 3
You can use keyword arguments to print:
print('string', end='\r', flush=True)
end='\r' replaces the default end-of-line behavior with '\r'
flush=True flushes the buffer, making the printed text appear immediately.
Python 2
In 2.6+ you can use from __future__ import print_function at the start of the script to enable Python 3 behavior. Or use the old way:
Python's print puts a newline after each command, unless you suppress it with a trailing comma. So, the print command is:
print 'You have finished {0}%\r'.format(percentage),
Note the comma at the end.
Unfortunately, Python only sends the output to the terminal after a complete line. The above is not a complete line, so you need to flush it manually:
import sys
sys.stdout.flush()
On linux( and probably on windows) you can use curses module like this
import time
import curses
win = curses.initscr()
for i in range(100):
win.clear()
win.addstr("You have finished %d%%"%i)
win.refresh()
time.sleep(.1)
curses.endwin()
Benfit with curses as apposed to other simpler technique is that, you can draw on terminal like a graphics program, because curses provides moving to any x,y position e.g. below is a simple script which updates four views
import time
import curses
curses.initscr()
rows = 10
cols= 30
winlist = []
for r in range(2):
for c in range(2):
win = curses.newwin(rows, cols, r*rows, c*cols)
win.clear()
win.border()
winlist.append(win)
for i in range(100):
for win in winlist:
win.addstr(5,5,"You have finished - %d%%"%i)
win.refresh()
time.sleep(.05)
curses.endwin()
I had to combine a few answers above to make it work on Python 3.7 / Windows 10. The example runs on Spyder's console:
import sys, time
for i in range(0, 101, 5):
print("\r>> You have finished {}%".format(i), end='')
sys.stdout.flush()
time.sleep(.2)
The time.sleep(.2) is just used to simulates some time-consuming code.
using sys.stdout.write() instead of print works in both python 2 and 3 without any compromises.
The OP didn't specify Py2 or Py3. In Python 3 the 'import' of 'sys' and the 'sys.stdout' call can be replaced with 'flush=True':
import time
for i in range(0,101,25):
print("\r>>TESTING - {:0>3d}%".format(i), end='', flush=True)
time.sleep(.5)
print()
Thanks to Petr Viktorin for showing the "flush" parameter for Python 3 print(). I submit this because his Python 3 example doesn't include a 'format' specifier. It took me awhile to figure out that the additional parameters go after the 'format' specifier parentheses as shown in my example. I just picked an example format of 3 character integer 0 filled on the left. The best doc I found for Py3 format is: 6.1.3.1. Format Specification Mini-Language