本文介绍了Jupyter Notebook:发生崩溃时如何重新启动上面的所有单元格?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题 1:

我正在使用 jupyter 4 和 python,我需要我的脚本在发生崩溃时重新启动上面的所有单元.

这可能吗?

问题 2:

如果我需要重新启动所有的单元格,我可以让python根据一些单元格ID执行它们吗?然后,我可以创建一个单元格 id 列表,在捕获异常时必须重新执行这些单元格 ID...

解决方案

您始终可以使用 Cell > 重新启动活动单元格上方的所有单元格在上面运行.但是,当谈到以编程方式和可靠这样做时,我有好消息也有坏消息要告诉您.


让我们摆脱关于问题 2 的坏消息:NO


...至少不是很可靠,因为如果您插入或删除任何其他单元格,单元格的任何 ID 都会更改.

根据


难的部分

那么,当发生崩溃时,我们如何设置它来处理错误?我不是这方面的专家,但我想我已经能够做出适合您的设置.但这很可能取决于相关错误的类型以及您的其他工作流程.

以下示例基于两个不同的错误消息.第一个是 NameError 当您尝试为不存在的变量赋值时发生.这将非常有用,因为在出​​现错误后重新运行某些单元将需要一个迭代器,该迭代器仅在笔记本完全重新启动时重置,而不是在单元作为错误处理方法的一部分重新运行时重置.名称错误只会在重新启动笔记本后重新启动内核时发生.作为错误处理的一部分,值 0 被分配给 x1.当单元格仅重新运行时 x1 将增加 1.

第二个错误将作为您的错误的代理,并且是每次尝试

如果片段中的评论不清楚,我很乐意添加更多细节.但是,如果您通过单击 Run Again! 运行笔记本几次,同时查看单元格 3 的输出,您将很快了解整个事情是如何组合在一起的:

Question 1:

I am using jupyter 4 with python and I would need my script to do a relaunch all the cells above when a crash occurs.

Is this possible ?

Question 2:

If I need to relaunch all some cells, can I ask python to execute them according to some cell-id? I could then create a list of the cells id which have to be re-executed when catching an exception...

解决方案

You can always relaunch all cells above the active cell using Cell > Run All Above. But when it comes to doing so programmatically and reliably, I've got both good and bad news for you.


Let's get the bad news regarding question 2 out of the way: NO


...at least not very reliably, because any ID of a cell would change if you insert or remove any other cell.

According to Execute specific cells through widgets and conditions on github:

And further down on the same post:


And now to the good news about the first question: YES


...but it's not 100% certain that it will solve your error handling needs as per the details in your question. But we'll get to that in a bit. Because the good news is that the answer to the question as it stands in the title

is YES WE CAN!

The hard (maybe even impossible) part of this question is to implement it as a robust error handling method. If you're only interested in that, skip to the section The hard part at the end of my answer. For now, let's go on with the easy part that is to programmatically run the menu option Cell > Run All (as described in the answer by Nic Cottrell). You have two options:

Option 1 - Run all cells above by executing a cell:

If you insert the following snippet in a cell and run it, all cells above will be executed:

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

Option 2 - Run all cells above by clicking a button:

If you insert the following snippet in a cell and run it, all cells above will be executed when you click the appearing button:

Snippet:

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

Output:


THE HARD PART

So, how can we set this up to handle an error when a crash occurs? I'm not an expert on this, but I think I've been able to make a setup that will work for you. But it will most likely depend on the type of error in question and the rest of your work flow.

The following example builds on two different error messages. The first is a NameError that occurs when you try to assign a value to a variable that does not exist. And this will be useful since re-running some cells after an error will need an iterator that resets only when the notebook is restarted completely, and not when a cell is re-run as part of an error handling method. The name error will only occur when the kernel is restarted upon a fresh restart of your notebook. As part of the error handling, the value 0 is assigned to x1. When the cell is only re-run x1 will increase by 1.

The second error will serve as a proxy for your error, and is an AssignmentError that occurs each time you try to delete an element from a list that does not exist. And this leads us to the real challenge, since if your error handler re-runs all cells above every time the error is triggered, you'll quickly end up in a bad loop. But we'll handle that with a counter that exits the looping execution of cells after a few runs.

It's also a bit problematic that there does not seem to exist a functionality to rerun your existing cell, or the cell from where the run cells above functionality is initialized. But we'll handle that with another suggestion from the same github post as earlier:

Notebook with suggested work-flow:

Insert the four following snippets below in four cells. Click the menu option Cell > Run all once, and we're good to go!

Snippet 1 - Imports and setup

import sys
import os
from IPython.core.display import display, HTML
from IPython.display import Javascript
from random import randint

# Trigger to randomly raise en error in the next cell
ErrorTrigger = randint(0, 9)

# Assignment of variables at first run of the Norebook
try: x1
except NameError: x1 = None
if x1 is None:
    %qtconsole # opens a qtconsole (for variable inspection and debugging)
    x1 = 0 # counter for NameError
    x2 = 0 # counter for assignment error (used in cells below)
    mr = 0 # counter for manual relaunch by button

    ErrorTriggers=[] # container for ErroTriggers
    print('NameErrors = ', x1)
else:
    x1 = x1 + 1
    ErrorTriggers.append(ErrorTrigger)
#print('Executions:', x1, '||', 'Triggers:', ErrorTriggers)

Snippet 2 - Proxy for your error

# PROXY ERROR => INSERT YOUR CODE FROM HERE ################################################################
list1 = [1,2,3,4]

# 80 % chance of raising an error trying to delete an element that does not exist in the list
if ErrorTrigger > 2:
    elemDelete = 8 # error
else:
    elemDelete = 0 # not error
try:
    del list1[elemDelete]
    print('Executions:', x1, '||', 'Triggers:', ErrorTriggers)
    print('Routine success on attempt', x2 + 1)
    print('Error mesg: None')
    ErrorTriggers=[]
    x2 = 0 # reset error counter

# TO HERE #################################################################################################
except Exception:

    x2 = x2 + 1
    # Will end error handler after 5 attempts
    if x2 < 3:
        # As long as we're UNDER the attempt limit, the next cell executed by:
        display(Javascript('IPython.notebook.execute_cell_range(IPython.notebook.get_selected_index()+1,'+
                           ' IPython.notebook.get_selected_index()+2)'))
    else:
        # If we're OVER the attempt limit, it all ends here. The next cell is NOT run.
        # And NEITHER is the last cell with the button to relaunch the whole thing.

        print('Executions:', x1, '||', 'Triggers:', ErrorTriggers)
        print('Routine aborted after attempt', x2)
        print('Error msg:', sys.exc_info()[1]) # Returns a message describing the error
        # reset variables
        ErrorTriggers = []
        x2 = 0

Snippet 3 - Cell to rerun all cells above as error handler

display(Javascript('IPython.notebook.execute_cells_above()'))

Snippet 4 - Cell to rerun the whole thing with en error probability of 20%

HTML('''<script> </script> <form action="javascript:IPython.notebook.execute_cells_above()"><input type="submit" id="toggleButton" value="Run again!"></form>''')

Screenshot after a few test runs:

I'll gladly add more details if the comments in the snippets are unclear.But if you run the notebook a few times by clicking Run Again! and at the same time have a look at the output of cell 3, you'll quickly grasp how the whole thing is put together:

这篇关于Jupyter Notebook:发生崩溃时如何重新启动上面的所有单元格?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-29 18:10
查看更多