IPython - Run all cells below from a widget
Asked Answered
B

4

21

I'm trying use a multi select widget to enable users to select from a list of countries, and then have a widget button which, when clicked, runs all the cells below.

This displays the list.

from IPython.display import display
w = widgets.SelectMultiple(

    description="Select up to five countries",
    options=dfCountries['name'].tolist()   
)
display(w)

And I want something like this to run all cells below:

def run_all(button):
    get_ipython().run_cell()

button = widgets.Button(description="Create next input")
button.on_click(run_all)
display(button)

But I can't find the hook to 'run all cells below

Thanks

Blackheart answered 22/9, 2015 at 10:41 Comment(0)
D
25

If I understood correctly you could do that via js.

See the following code:

from IPython.display import Javascript
Javascript('IPython.notebook.execute_cells_below()')

Will execute all the cells below the active cell so for you button it could be something like:

from IPython.display import Javascript, display
from ipywidgets import widgets

def run_all(ev):
    display(Javascript('IPython.notebook.execute_cells_below()'))

button = widgets.Button(description="Create next input")
button.on_click(run_all)
display(button)

Let me know if this is what you need.

Disject answered 24/9, 2015 at 20:4 Comment(8)
That's just what I was looking for. Thanks :)Blackheart
This works well but now that I have tested it, when the button is clicked, the state of the multi-select box is lost and I can't capture the values. It seems like it re-executes the cell that has the multi-select and the button in it?Blackheart
Actually seems to be that the multi-select retains state between execution. Is there a way to clear it?Blackheart
Ok, got it. Clear the selection with w.selected_labels=(())Blackheart
I am having the same issue as @colser had - state of all other widgets are lost, since "execute_cells_below" re-executes the current cell. Basically, I am trying to build a form UI to present to the user with come inputs and "Calculate" button in the bottom. How did you fix it? Do you have a sample notebook?Angara
In my case, I just added the code in an isolated cell that only has the code of @DisjectLipp
@Disject I got this to work for executing all cells below, but what if i want to run just the cell directly below the button? this there an equivalent of this for "run next cell"?Quadruple
None of the solutions here are working for me. Javascript fails to execute anything with this code: Javascript('IPython.notebook.execute_cells_below()')Reasonable
K
16

To run all cells below the current cell without executing the cell that has this button:

from IPython.display import Javascript, display
from ipywidgets import widgets

def run_all(ev):
    display(Javascript('IPython.notebook.execute_cell_range(IPython.notebook.get_selected_index()+1, IPython.notebook.ncells())'))

button = widgets.Button(description="Run all below")
button.on_click(run_all)
display(button)

This allows the current cell to also prompt for other inputs and those input values to be preserved. IPython.notebook.execute_cells_below() will execute the current cell and if other inputs are also displayed in this cell they will get their default values.

Ka answered 31/7, 2017 at 21:58 Comment(2)
Hey Michael, is there a way to adapt this to only run the cell directly below instead of all the cells? I've been playing around with this and can't figure out how to make it just run the cell below.Quadruple
I have tried display(Javascript('IPython.notebook.execute_cell_range(IPython.notebook.get_selected_index()+1, IPython.notebook.get_selected_index()+2)')) but it will run multiple sells below for some reason and I'm not sure why.Quadruple
B
1

You've already received some excellent suggestions, but I'd just like to mention a pretty flexible option with HTML:

Code:

from IPython.core.display import HTML
HTML('''<script> </script> <form action="javascript:IPython.notebook.execute_cells_below()"><input type="submit" id="toggleButton" value="Refresh"></form>''')

This will produce a button for you that runs all cells below in the notebook

A bonus feature with this approach is that the layout of your button will follow a theme selection if you're using Jupyter Themes from Dunovank on github https://github.com/dunovank/jupyter-themes

I tried to attach a screenshot, but I can't do that yet.

Berghoff answered 20/2, 2019 at 12:51 Comment(0)
F
0

If you are looking to run just the cell below the button This will do the trick!

from IPython.display import Javascript, display
from ipywidgets import widgets

def run_all(ev):
    display(Javascript('IPython.notebook.execute_cell_range(IPython.notebook.get_selected_index()+1, IPython.notebook.get_selected_index()+2)'))

button = widgets.Button(description="Run The Next Cell")

button.on_click(run_all)
display(button)
Fiorin answered 17/2, 2022 at 10:48 Comment(1)
See "Explaining entirely code-based answers". While this might be technically correct it doesn't explain why it solves the problem or should be the selected answer. We should educate along with helping solve the problem.Ramtil

© 2022 - 2024 — McMap. All rights reserved.