Ipython/Jupyter - 我们可以编程"运行上面的所有单元格"吗?

Rom*_*uin 13 python jupyter

我正在使用带有python的jupyter 4,当发生崩溃时,我需要我的脚本执行"重新启动上面的所有单元格".可能吗 ?

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

谢谢.

ves*_*and 15

您始终可以使用 重新启动活动单元格上方的所有单元格Cell > Run All Above。但是,当谈到以编程方式可靠地执行此操作时,我有好消息也有坏消息要告诉您。


让我们把关于问题 2 的坏消息排除在外:不


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

根据通过github 上的小部件和条件执行特定单元格

我们没有单元的 Id 来以编程方式处理它们。

再往下看同一篇文章:

有一些 API 可以运行由数字标识的单元格,但不幸的是,如果您在上方某处插入或删除单元格,数字会发生变化。


现在是关于第一个问题的好消息:是的


...但不能 100% 确定它会根据您问题中的详细信息解决您的错误处理需求。但我们稍后会谈到这一点。因为好消息是标题中的问题的答案

发生崩溃时如何重新启动上面的所有单元格?

是的,我们可以!

这个问题最难(甚至不可能)的部分是将它实现为一种强大的错误处理方法。如果您只对此感兴趣,请跳到The hard part我的答案末尾的部分。现在,让我们继续easy part以编程方式运行菜单选项Cell > Run All(如 Nic Cottrell 的回答中所述)。您有两个选择:

选项 1 -通过执行一个单元来运行上面的所有单元:

如果您在单元格中插入以下代码段并运行它,上面的所有单元格都将被执行:

from IPython.display import Javascript
display(Javascript('IPython.notebook.execute_cells_above()'))
Run Code Online (Sandbox Code Playgroud)

选项 2 -单击按钮运行上面的所有单元格:

如果您在单元格中插入以下代码段并运行它,当您单击出现的按钮时,将执行上面的所有单元格:

片段:

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>''')
Run Code Online (Sandbox Code Playgroud)

输出:

在此处输入图片说明


THE HARD PART

那么,当发生崩溃时,我们如何设置它来处理错误?我不是这方面的专家,但我想我已经能够做出适合您的设置。但这很可能取决于所讨论的错误类型和您的工作流程的其余部分。

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

第二个错误将作为您的错误的代理,并且是每次您尝试从不存在的列表中删除元素时发生的 AssignmentError 。这给我们带来了真正的挑战,因为如果您的错误处理程序在每次触发错误时都重新运行上面的所有单元格,您将很快陷入错误循环。但是我们将使用一个计数器来处理它,该计数器在几次运行后退出单元格的循环执行。

似乎不存在重新运行现有单元run cells above功能或初始化功能的单元,这也有点问题。但是我们将使用来自同一个 github 帖子的另一个建议来处理这个问题:

执行以下操作可帮助我执行代码单元格正下方的单元格。您还可以更改值以获取笔记本其他部分的单元格。 display(Javascript('IPython.notebook.execute_cell_range(IPython.notebook.get_selected_index()+1, IPython.notebook.get_selected_index()+2)'))

带有建议工作流程的笔记本:

在四个单元格中插入以下四个片段。单击菜单选项Cell > Run all一次,我们就可以开始了!

片段 1 - 导入和设置

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)
Run Code Online (Sandbox Code Playgroud)

代码段 2 - 您的错误的代理

# 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
Run Code Online (Sandbox Code Playgroud)

代码段 3 - 将上面的所有单元格重新运行为错误处理程序的单元格

display(Javascript('IPython.notebook.execute_cells_above()'))
Run Code Online (Sandbox Code Playgroud)

代码段 4 - 以 20% 的错误概率重新运行整个过程的单元格

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

几次测试运行后的屏幕截图:

在此处输入图片说明

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

在此处输入图片说明


Nic*_*ell 5

我正在运行Notebook服务器5.4.0,并且我有一个选项Cell > Run All Above似乎可以做到这一点。

在此处输入图片说明

  • 问题是如何在python中对其进行编程 (2认同)