Overwrite previous output in jupyter notebook

Let's assume I have a part of code that runs for some specific amount of time and each 1 second outputs something like this: iteration X, score Y. I will substitute this function with my black box function:

from random import uniform
import time

def black_box():
    i = 1
    while True:
        print 'Iteration', i, 'Score:', uniform(0, 1)
        time.sleep(1)
        i += 1

Now when I run it in Jupyter notebook, it output a new line after each second:

Iteration 1 Score: 0.664167449844
Iteration 2 Score: 0.514757592404
...

Yes, after when the output becomes too big, the html becomes scrollable, but the thing is that I do not need any of these lines except of currently the last one. So instead of having n lines after n seconds, I want to have only 1 line (the last one) shown.

I have not found anything like this in documentation or looking through magic. A question with almost the same title but irrelevant.


Solution 1:

@cel is right: ipython notebook clear cell output in code

Using the clear_output() gives makes your Notebook have the jitters, though. I recommend using the display() function as well, like this (Python 2.7):

from random import uniform
import time
from IPython.display import display, clear_output

def black_box():
i = 1
while True:
    clear_output(wait=True)
    display('Iteration '+str(i)+' Score: '+str(uniform(0, 1)))
    time.sleep(1)
    i += 1

Solution 2:

The usual (documented) way to do what you describe (that only works with Python 3) is:

print('Iteration', i, 'Score:', uniform(0, 1), end='\r')

In Python 2 we have to sys.stdout.flush() after the print, as it shows in this answer:

print('Iteration', i, 'Score:', uniform(0, 1), end='\r')
sys.stdout.flush()

Using IPython notebook I had to concatenate the string to make it work:

print('Iteration ' + str(i) + ', Score: ' + str(uniform(0, 1)), end='\r')

And finally, to make it work with Jupyter, I used this:

print('\r', 'Iteration', i, 'Score:', uniform(0, 1), end='')

Or you could split the prints before and after the time.sleep if it makes more sense, or you need to be more explicit:

print('Iteration', i, 'Score:', uniform(0, 1), end='')
time.sleep(1)
print('', end='\r') # or even print('\r', end='')