notebook/examples/widgets/Variable Inspector.ipynb
2014-01-16 10:57:00 +00:00

11 KiB

Build the Variable Inspector

In [1]:
from IPython.html import widgets
from IPython.display import display
import re

Custom SidePanel View

In [2]:
%%javascript

require(["notebook/js/widget"], function(){

    // Define the FilePickerView
    var SidePanelView = IPython.WidgetView.extend({
        
        render: function(){           
            var table_div = $('<div />', {id: 'var_inspect'})
                .addClass('hbox');
            var body_div = $('<div />')
                .css('width', '80%')
                .css('height', '100%')
                .appendTo(table_div);
            this.panel_div = $('<div />')
                .css('width', '20%')
                .css('height', '100%')
                .appendTo(table_div);
    
            var body = $('body');
            var site = body.find('#site');
            site.detach();
            body.find('#var_inspect').remove();
            body.append(table_div);
            site.appendTo(body_div);
        },

        display_child: function(view) {
            this.panel_div.append(view.$el);
        },
    });
        
    // Register the DatePickerView with the widget manager.
    IPython.widget_manager.register_widget_view('SidePanelView', SidePanelView);
});

Create Variable Inspector Controls

In [3]:
_side_panel = widgets.ContainerWidget(default_view_name="SidePanelView")

_modal_div = widgets.ContainerWidget(parent=_side_panel)
_modal_div.set_css({'padding-top': '60px',
                   'padding-right': '40px',
                   'padding-left': '10px',})

_modal_header = widgets.ContainerWidget(parent=_modal_div)
_modal_header_label = widgets.StringWidget(parent=_modal_header, default_view_name="LabelView")
_modal_header_label.value = '<h3>Variable Inspector</h3>'
_modal_header_execs_label = widgets.StringWidget(parent=_modal_header, default_view_name="LabelView")
_modal_header_execs_label.execs = 0

_modal_body = widgets.ContainerWidget(parent=_modal_div)
_modal_body.vbox()

_modal_body_label = widgets.StringWidget(parent=_modal_body, default_view_name="LabelView")
_modal_body_label.value = 'Not hooked'

_modal_footer = widgets.ContainerWidget(parent=_modal_div)
_modal_footer.vbox()
_var_filter = widgets.SelectionWidget(values=['Public', 'Private', 'IPython'], parent=_modal_footer, value='Public', default_view_name='ToggleButtonsView')

display(_side_panel)

_modal_header.add_class('modal-header')
_modal_body.add_class('modal-body')
_modal_footer.add_class('modal-footer')

Method that Fills the Inspector

In [4]:
_ipython_input = re.compile('_i[0-9]*')

def _fill_inspector():
    
    # Apply filter to variable names.
    names = []
    for name in sorted(_ipython.user_ns):
        
        match = _ipython_input.match(name)
        is_ipython = (match is not None and match.group() == name) or \
                     name == '_dh' or \
                     name == '_ih' or \
                     name == '_ii' or \
                     name == '_iii' or \
                     name == '_oh' or \
                     name == '_sh' or \
                     name == 'get_ipython' or \
                     name == 'In' or \
                     name == 'Out' or \
                     name == 'exit' or \
                     name == 'help' or \
                     name == 'quit' or \
                     name == '_' or \
                     name == '__' or \
                     name == '___'
        
        is_private = name.startswith('_')
        is_public = not is_private
        
        var_filter = _var_filter.value
        if var_filter == 'IPython' and is_ipython:
            names.append(name)
        elif var_filter == 'Private' and (is_private and not is_ipython):
            names.append(name)
        elif var_filter == 'Public' and (is_public and not is_ipython):
            names.append(name)
            
    # Render each name and it's value.
    variable_list_html = """
<table class="table table-bordered table-striped" style="width: 100%; overflow: hidden; table-layout:fixed;">
    <tr><th>Name</th><th>Type</th><th>Value</th>"""
    for name in names:
        var_value = _ipython.user_ns[name]
        var_type = type(var_value)
        var_small_value = str(var_value)[:100].replace("&", "&amp;").replace("<", "&lt;")
        
        if str(var_value) != var_small_value:
            var_small_value += '<br><div class="label label-info">...</div>'
        
        row = """
<tr style='overflow: hidden;'>
    <td style='width: 30%; overflow: hidden;'>{name}</td>
    <td style='width: 30%; overflow: hidden;'>{type}</td>
    <td style='width: 40%; overflow: hidden;'>{small_value}</td>
</tr>
""".format(name=name, type=var_type.__name__, small_value=var_small_value, value=str(var_value))
        variable_list_html += row + '\n'
    variable_list_html += '</table>'
    _modal_body_label.value = variable_list_html
        
    

Hook Cell Execute and Filter Change

In [5]:
_ipython = get_ipython()

try:
    del _ipython._post_execute[handle_cell_executed]
except:
    pass

def _handle_cell_executed():
    _modal_header_execs_label.execs += 1
    _modal_header_execs_label.value = '%d cell executions captured' % _modal_header_execs_label.execs
    _fill_inspector()
_ipython.register_post_execute(_handle_cell_executed)

def _handle_filter_changed():
    _fill_inspector()
_var_filter.on_trait_change(_handle_filter_changed, 'value')

Test

In [6]:
a = 5
In [7]:
b = 3.0
In [8]:
c = a * b
In [9]:
d = "String"
In [10]:
del b