52

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.

Community
  • 1
  • 1
Salvador Dali
  • 214,103
  • 147
  • 703
  • 753
  • this could be a solution: http://stackoverflow.com/questions/24816237/ipython-notebook-clear-cell-output-in-code – cel Jul 23 '16 at 10:47

2 Answers2

68

@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
DangerousDave
  • 781
  • 1
  • 6
  • 7
  • 2
    A good answer! The name of the module should be `IPython`, I think. – Cnly Dec 02 '17 at 07:09
  • 8
    For fast-iterating loops, I suggest clear_output(wait=True). When set to true, wait causes delays the clear until a new input is received. – Joseph Cottam Feb 20 '18 at 23:34
38

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='')
Community
  • 1
  • 1
chapelo
  • 2,519
  • 13
  • 19
  • 2
    On macOS this does not seem to produce any output in notebook. – cel Jul 23 '16 at 20:27
  • 2
    @cel, after installing and trying with jupyter, it does not work on Linux either. It's not the OS, has to be some change made by jupyter. – chapelo Jul 23 '16 at 22:59
  • @chapelo sorry, I forgot to reply to you. Sadly your solution didn't work for me. Python complains that this syntax `print('\r', 'something', end='')` is not valid (end =''). – Salvador Dali Jul 31 '16 at 21:01
  • Are you using Python 2.x? Have you tried `from __future__ import print_statement`? The print "function" should accept an `end` argument. – chapelo Jul 31 '16 at 21:10
  • I was able to do it in Python2.x using just `print "\rsomething",` and to me this seems to be the simplest solution for my version of Python. – jonathanking Nov 16 '17 at 17:36
  • Note that print('\r', 'Iteration', i, 'Score:', uniform(0, 1), end='') does not clear the line, but only overwrites it (at least in Jupyter with Python 3). Therefore, if your outputted strings are of different lengths, parts of the longer string will still be displayed. For example, if you print 'hamster', and then 'cat', the final output will be 'catster'. Code: `print('\rhamster', end='')`, `print('\rcat', end='')`. Therefore the solution proposed by @DangerousDave is preferred (with `clear_output(wait=True)`). – Fabian Ying Apr 18 '18 at 11:21