8

How can I print the status of a Jupyter notebook on the previous line? I think I'm looking for something like clear_output(), but for only a single line.

Sample code:

from IPython.display import clear_output
import time
print('This is important info!')
for i in range(100):
    print('Processing BIG data file {}'.format(i))
    time.sleep(0.1)
    clear_output(wait=True)
    if i == 50:
        print('Something bad happened on run {}.  This needs to be visible at the end!'.format(i))
print('Done.')

When this runs it gives the behavior of over-writing the previous status line, but both of the lines marked as important (with exclamation points and everything!) are lost. When this is finished the display just says:

Done. 

What it should say is:

This is important info!
Something bad happened on run 50.  This needs to be visible at the end!
Done.

This post suggests using clear_output() and then reprinting everything. This seems impractical because the amount of data I really tend to display is big (lots of graphs, dataframes, ...).

Here's two SO links about clear_output().

Is there a way to make this work that doesn't involve reprinting everything?

Casey
  • 475
  • 6
  • 19

3 Answers3

7

I got it woking using the update function of the display handle:

from IPython.display import display
from time import sleep

print('Test 1')
dh = display('Test2',display_id=True)
sleep(1)
dh.update('Test3')
Jan-Philipp
  • 71
  • 1
  • 2
3

This simple escape sequence trick can do the job most of the time. \n and \r can do a lot if used properly.

\r: (Carriage Return) (CR) returns the cursor to the beginning of the new line without moving to a new line.
\n:(Line Feed) (LF) moves the cursor to the next line.

import time
print('This is important info!')
for i in range(100):
    print("\r"+'Processing BIG data file {}'.format(i),end="")
    time.sleep(0.1)
    if i == 50:
        print("\r"+'Something bad happened on run {}.  This needs to be visible at the end!'.format(i))
print("\r"+'Done.')
Tarun Kumar
  • 346
  • 3
  • 8
2

This will do it:

import IPython

IPython.display.display_javascript(r'''
    var el = document.querySelector('.output_text:last-of-type > pre');
    el.innerHTML = el.innerHTML.replace(/(\n.*$)/gm,""); ''', raw=True)
Artem
  • 21
  • 3
  • A bit of explaining would have helped, so I'll do it for you: you take the notebook's first output block (`pre`) and replace its HTML (our 2 lines of output) using a regexp that matches the second line of output to just keep the first one. You issue this command when necessary in code using the `display.display_javascript` method of the `IPython` class. – Redoman Jul 02 '22 at 13:11