Issue
In a jupyter notebook I would like to define a function in python, which, when called, does the following:
- Gives out an alert to the user
- Restarts the notebook kernel
- Marks the executed cell as done (i.e. without a star,
[ ]
) - Focus is on the next cell
Or as an alternative:
- Gives out an alert to the user
- Restarts the notebook kernel
- Clears all the output of the entire notebook
- Focus is on the first cell again (like a F5 reload of the browser tab).
I have tried the following code
from IPython.display import display, HTML
def reload():
display(HTML(
'''
<script>
alert('This notebook needs to be restarted!');
IPython.notebook.kernel.restart();
IPython.display.clear_output();
window.location.reload();
</script>
'''
))
reload()
but it gives an error
AttributeError: 'function' object has no attribute 'clear_output'
despite this documentation.
When I remove the line
IPython.display.clear_output();
then the kernel is restarted, but I get 2(!) alerts and it looks like that the execution of the next cell is performed. Also, the cells are not cleared , the current cell still does have the star in the brackets ([*]
).
How to do it correctly?
Solution
This code does what you described as the alternative option, with the addition of saving a checkpoint before reloading so the output stays cleared:
from IPython.display import Javascript, display
def reload():
display(
Javascript('''
// clear all output (based on: https://stackoverflow.com/a/47315713/9504155)
// save a reference to the cell we're currently executing inside of,
// to avoid clearing it later (which would remove this js)
var this_cell = $(element).closest('.cell').data('cell');
function clear_other_cells () {
Jupyter.notebook.get_cells().forEach(function (cell) {
if (cell.cell_type === 'code' && cell !== this_cell) {
cell.clear_output();
}
Jupyter.notebook.set_dirty(true);
});
}
if (Jupyter.notebook._fully_loaded) {
// notebook has already been fully loaded, so clear now
clear_other_cells();
}
// save checkpoint so output stays cleared after reload
IPython.notebook.save_checkpoint();
IPython.notebook.kernel.restart();
alert('This notebook needs to be restarted!');
window.location.reload(false);
'''))
reload()
If you prefer the first option (without reloading the page, focusing on the next cell instead) just remove the lines for saving a checkpoint and reloading and use the IPython.display.clear_output()
function after the JavaScript part to clear the current cell's output as well:
from IPython.display import Javascript, clear_output, display
def reload():
display(
Javascript('''
// clear all output (based on: https://stackoverflow.com/a/47315713/9504155)
// save a reference to the cell we're currently executing inside of,
// to avoid clearing it later (which would remove this js)
var this_cell = $(element).closest('.cell').data('cell');
function clear_other_cells () {
Jupyter.notebook.get_cells().forEach(function (cell) {
if (cell.cell_type === 'code' && cell !== this_cell) {
cell.clear_output();
}
Jupyter.notebook.set_dirty(true);
});
}
if (Jupyter.notebook._fully_loaded) {
// notebook has already been fully loaded, so clear now
clear_other_cells();
}
IPython.notebook.kernel.restart();
alert('Notebook output cleared!');
'''))
clear_output()
IPython.display.clear_output();
was not working in your code because it was called in the HTML <script>
tag as JavaScript code instead of in Python.
Answered By - Jonathan Feenstra
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.