Flush output in for loop in Jupyter notebook - python

I want to print out i in my iteration on Jupyter notebook and flush it out. After the next iteration, I'll print the next i. I tried solutions from this question and this question, however, it just print out 0123...9 without flushing the output for me. Here is my working code:
import sys
import time
for i in range(10):
sys.stdout.write(str(i)) # or print(i, flush=True) ?
time.sleep(0.5)
sys.stdout.flush()
these are my setup: ipython 5.1, python 3.6. Maybe, I missed something in the previous solution?

#Try this:
import sys
import time
for i in range (10):
sys.stdout.write('\r'+str(i))
time.sleep(0.5)
'\r' will print at the beginning of the line

The first answer is correct but you don't need sys package. You can use the end parameter of the print function. It specifies what to print at the end, and its default value is \n(newline) (docs1, docs2). Use \r(carriage return) instead.
import time
for i in range (10):
print(i, end="\r")
time.sleep(0.5) # This line is to see if it's working or not

Try this
for i in range (10):
print("\r", end=str(i))

Related

Update only two lines in print inside jupyter notebbok

I want to print only two lines in my cycles, I started with the following:
import time
for i in range(10):
time.sleep(0.5)
for j in range(10):
time.sleep(0.5)
print('Index1:', i)
print('Index2:', j)
I tried different combinations of \r, \n, flush=True etc. at the beginning and end of print, but wasn't successful((
What I'd like to see is as in the GIF of accepted answer here
I tried those code, but it didn't help, maybe because my OS is Windows or I use jupyter notebook, I have no idea((
For Jupyter import clear_output from IPython.display. On terminal you can use something like os.system('clear') for Linux or os.system('cls') for Windows.
import time
import os
from IPython.display import clear_output
for i in range(10):
for j in range(10):
print(f'Index1: {i}\nIndex2: {j}')
time.sleep(0.5)
# for terminal ('clear' for Linux, 'cls' for Windows)
# os.system('clear')
# for Jupyter
clear_output(wait=True)
In Jupyter Notebook, you can clear current cell output using IPython.display.clear_output(wait=True)
In terminal, similiar behaviour can be achieved using ANSI escape codes, as in the following snippet:
import time
n = 15
for i in range(n):
print(f"{i}s passed")
print(f"{n-i}s remaining")
time.sleep(1)
print("\u001b[2A", end="") #ANSI escape code for cursor up 2 lines
remember that you must use end inside print()
try this code:
import time
for i in range(10):
time.sleep(0.5)
for j in range(10):
time.sleep(0.5)
print(f'\rIndex1: {i}, Index2: {j}', flush=True, end='')

Is there a way to remove prevous prints?

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.

Printing on the same line on a jupyter notebook

In python 3, we can easily print on the same line using the following script. I use this to understand the progress of my loop (how much time will be left). However, in jupyter it doesnt work (it prints on different lines)
import time
for f in range(10):
print(f, end='\r', flush=True)
time.sleep(10)
It doesnt work to turn pretty print off %pprint, and I tried the same with sys.stdout.write() but also there I have this issue.
Found the solution to this a bit later (note that it does not work in pycharm jupyter, but only in the browser implementation). For me print works fine, but here display is advised, but it prints apostrophes around strings.
from time import sleep
from IPython.display import clear_output, display
for f in range(10):
clear_output(wait=True)
print(f) # use display(f) if you encounter performance issues
sleep(10)
Edit: Just wanted to add that TQDM is often also a good tool for this goal. It displays progress bars and allows you to write output below it or differ the description of each bar. See also this post.
import sys
from tqdm import tqdm
from time import sleep
values = range(3)
with tqdm(total=len(values), file=sys.stdout) as pbar:
for i in values:
pbar.set_description('processed: %d' % (1 + i))
pbar.update(1)
sleep(1)
And the notebook one with nice colours
from tqdm import tqdm, tqdm_notebook
from time import sleep
for i in tqdm_notebook(range(2), desc='1st loop'):
sleep(0.01)
tqdm.write(f"Done task {i}")
Prefix a \r and add an argument end="" to print, like so
print("\rThis will be printed on the same line", end="")
This works in the Jupyter notebook in Google Colab.
The part "\r" overwrites the line, if you leave that you append to the line. Your version print(f, end='', flush=False) could work but I've read under Python 3 you need to use sys.stdout.write() and best is if you add flush command too.
import sys
import time
for f in range(10):
#delete "\r" to append instead of overwrite
sys.stdout.write("\r" + str(f))
sys.stdout.flush()
time.sleep(10)
The stdout.flush is required on some systems or you won't get any output
In some cases, the issue could arise when multiple arguments are given to the print statement.
for i in range(3):
print(i, "-", i ** 2, end="\r")
The above snippet prints 2 - 0 - 1 - 4 in a jupyter notebook. However, passing a single argument to print will give the desired result of 2 - 4 i.e. 0 - 0 is overwritten by 1 - 2 which is in-turn overwritten by 2 - 4
for i in range(3):
print(f"{i} - {i ** 2}", end="\r")
Here are the package versions that I am using.
# Name Version
notebook 6.4.12
ipython 8.4.0
python 3.8.13
jupyter-client 7.3.4

run a basic digital clock in the python shell

I want to code simple digital clock in the python shell. I want to avoid using tkinter if possible. This is what I currently have;
import time
while True:
from datetime import datetime
now = datetime.now()
print ("%s/%s/%s %s:%s:%s" % (now.month,now.day,now.year,now.hour,now.minute,now.second))
time.sleep(1)
This produces a recurring print out, something like this;
06/29/16 23:08:32
06/29/16 23:08:33
06/29/16 23:08:34
I know this is crude, I'm still learning. I just want one line with a "ticking" digital clock in the shell. I'm using python 3.5.1 on idle and windows 10.
If this isn't possible, I'd very much like to know why.
Kindest thanks
If you're just printing out a fixed length output like this each time, you can use the carriage return character to rewind to the start of the line, as long as you don't print a newline. Example:
# Note trailing comma, that suppresses the newline in Python
print ("%s/%s/%s %s:%s:%s" % (now.month,now.day,now.year,now.hour,now.minute,now.second)),
# Now rewind back to the start of the line. Again, not trailing comma
print("\r"),
Now, you may also notice that nothing is ever printed to the screen. This is because standard out is buffered, so you can flush with this:
# At the top...
import sys
# In the loop, after the first print
sys.stdout.flush()
This all works as follows. Imagine that there is actually a cursor on screen. You first print out the time with the first print (and the flush), then you move the cursor back to the start of the line with print("\r"),. This doesn't actually remove any of the characters, it just moves the cursor. You then write the next time out again. Because it nicely happens to be the exact same length, the time gets written out again, replacing the old characters.
The resulting script is then as follows:
import time
import sys
while True:
from datetime import datetime
now = datetime.now()
print ("%s/%s/%s %s:%s:%s" % (now.month,now.day,now.year,now.hour,now.minute,now.second)),
sys.stdout.flush()
print("\r"),
time.sleep(1)
If you want finer grained control over what's going on, you can start using the curses library, but I imagine that's overkill for what you're trying to do here.
EDIT: As #PadraicCunningham mentioned in the comments, the correct syntax to suppress newline printing in Python 3 and force the contents to flush to the screen is the following:
print("hello", flush=True, end="")
Also, as #AlexHall mentions, the print statement does not actually print a fixed width statement; so to do this, we should use strftime() instead.
Therefore the correct program is:
import time
while True:
from datetime import strftime
print (strftime("%m/%d/%Y %H:%M:%S"), end="", flush=True)
print("\r", end="", flush=True)
time.sleep(1)
All you need is:
from time import strftime
while True:
print (strftime("%m/%d/%Y %H:%M:%S"), end="", flush=True)
print("\r", end="", flush=True)
time.sleep(1)
tried this in repl.it, this worked for me...( added commas & now.strftime )
import time
from datetime import datetime
while True:
now = datetime.now()
print (now.strftime("%m/%d/%Y %H:%M:%S"), end="", flush=True),
print("\r", end="", flush=True),
time.sleep(1)
The following code is working for me.
from time import sleep
from datetime import datetime
while True:
now = datetime.now()
stdout.write(now.strftime("\r%m/%d/%Y %H:%M:%S")),
stdout.flush()
sleep(1)
stdout.write("\n")
You could set end= " " to remove newlines and add a carriage return i.e.:
'\r'
Therefore the correct program which should work for you is:
from datetime import datetime
import time
while True:
now = datetime.now()
print("\r%s/%s/%s %s:%s:%s" % (now.month, now.day, now.year, now.hour, now.minute, now.second), end='')
time.sleep(1)
print('')
A slight improvement on the above answers (removing the trailing comma; and changing end from "" to "\r" to do the carriage return as part of a single print statement.
import time
from datetime import datetime
while True:
now = datetime.now()
print (now.strftime("%m/%d/%Y %H:%M:%S"), end="\r", flush=True)
time.sleep(1)
ImportError: cannot import name 'strftime' from 'datetime' (/usr/lib/python3.7/datetime.py) So, use the following code:
import time, sys
while True:
from datetime import datetime
now = datetime.now()
showClock =" %s:%s:%s" % (now.hour,now.minute,now.second)
print(showClock, end="\r")

How to rewrite output in terminal

I have a Python script and I want to make it display a increasing number from 0 to 100% in the terminal. I know how to print the numbers on the terminal but how can I "rewrite" them so 0 turns into 1, 1 into 2, and so on until 100?
Printing a carriage return (\r) without a newline resets the cursor to the beginning of the line, making the next print overwriting what's already printed:
import time
import sys
for i in range(100):
print i,
sys.stdout.flush()
time.sleep(1)
print "\r",
This doesn't clear the line, so if you try to, say, print decreasing numbers using this methods, you'll see leftover text from previous prints. You can work around this by padding out your output with spaces, or using some of the control codes in the other answers.
This recipe here should prove useful. Using that module as tc, the following code does what you want:
from tc import TerminalController
from time import sleep
import sys
term = TerminalController()
for i in range(10):
sys.stdout.write("%3d" % i)
sys.stdout.flush()
sleep(2)
sys.stdout.write(term.BOL + term.CLEAR_EOL)
The recipe uses terminfo to get information about the terminal and works in Linux and OS X for a number of terminals. It does not work on Windows, though. (Thanks to piquadrat for testing, as per the comment below).
Edit: The recipe also gives capabilities for using colours and rewriting part of the line. It also has a ready made text progress bar.
Using the blessings package - clear your screen (clear/cls) and enter:
import sys
from blessings import Terminal
from time import sleep # <- boy, does this sound tempting a.t.m.
term = Terminal()
for i in range(6):
with term.location(term.width - 3, term.height - 3):
print('{}'.format(i))
sleep(2)
if (i == 3):
print('what was I doing, again?')
print('done')
To install it from CheeseShop, just...
pip install blessings
Based on this answer, but without the terminal controller:
import time
import sys
for i in range(100):
sys.stdout.write("Downloading ... %s%%\r" % (i))
sys.stdout.flush()
time.sleep(1)
Tested on GNOME terminal (Linux) and Windows console.
Tip: Don't run this example in IDLE editor.

Categories