Updating interact to work with latest state of widgets.

This commit is contained in:
Brian E. Granger 2014-01-30 10:06:36 -08:00 committed by MinRK
parent faebb43e01
commit 93047f1d3c
2 changed files with 353 additions and 137 deletions

View File

@ -13,8 +13,8 @@
# Imports
#-----------------------------------------------------------------------------
from IPython.html.widgets import (Widget, TextBoxWidget,
FloatSliderWidget, IntSliderWidget, CheckBoxWidget, DropdownWidget,
from IPython.html.widgets import (Widget, TextWidget,
FloatSliderWidget, IntSliderWidget, CheckboxWidget, DropdownWidget,
ContainerWidget)
from IPython.display import display, clear_output
from IPython.utils.py3compat import string_types, unicode_type
@ -31,45 +31,62 @@ def _matches(o, pattern):
return all(isinstance(obj,kind) for obj,kind in comps)
def _min_max_value(o):
min = o[0]
max = o[1]
if not max > min:
raise ValueError('max must be greater than min: (min={0}, max={1})'.format(min, max))
value = min + abs(o[0]-o[1])/2
def _get_min_max_value(min, max, value):
"""Return min, max, value given input values with possible None."""
if value is None:
if not max > min:
raise ValueError('max must be greater than min: (min={0}, max={1})'.format(min, max))
value = min + abs(min-max)/2
value = type(min)(value)
elif min is None and max is None:
if value == 0.0:
min, max, value = 0.0, 1.0, 0.5
elif value == 0:
min, max, value = 0, 1, 0
elif isinstance(value, float):
min, max = -value, 3.0*value
elif isinstance(value, int):
min, max = -value, 3*value
else:
raise TypeError('expected a number, got: %r' % number)
else:
raise ValueError('unable to infer range, value from: ({0}, {1}, {2})'.format(min, max, value))
return min, max, value
def _widget_abbrev(o):
if isinstance(o, string_types):
return TextBoxWidget(value=unicode_type(o))
return TextWidget(value=unicode_type(o))
elif isinstance(o, dict):
values = [unicode_type(k) for k in o]
w = DropdownWidget(value=values[0], values=values)
w.actual_values = o
labels = [unicode_type(k) for k in o]
values = o.values()
w = DropdownWidget(value=values[0], values=values, labels=labels)
return w
# Special case float and int == 0.0
# get_range(value):
elif isinstance(o, bool):
return CheckBoxWidget(value=o)
return CheckboxWidget(value=o)
elif isinstance(o, float):
return FloatSliderWidget(value=o, min=-o, max=3.0*o)
min, max, value = _get_min_max_value(None, None, o)
return FloatSliderWidget(value=o, min=min, max=max)
elif isinstance(o, int):
return IntSliderWidget(value=o, min=-o, max=3*o)
min, max, value = _get_min_max_value(None, None, o)
return IntSliderWidget(value=o, min=min, max=max)
if isinstance(o, (list, tuple)):
if _matches(o, (int, int)):
min, max, value = _min_max_value(o)
return IntSliderWidget(value=int(value), min=min, max=max)
min, max, value = _get_min_max_value(o[0], o[1], None)
return IntSliderWidget(value=value, min=min, max=max)
elif _matches(o, (int, int, int)):
min, max, value = _min_max_value(o)
return IntSliderWidget(value=int(value), min=min, max=max, step=o[2])
min, max, value = _get_min_max_value(o[0], o[1], None)
return IntSliderWidget(value=value, min=min, max=max, step=o[2])
elif _matches(o, (float, float)):
min, max, value = _min_max_value(o)
min, max, value = _get_min_max_value(o[0], o[1], None)
return FloatSliderWidget(value=value, min=min, max=max)
elif _matches(o, (float, float, float)):
min, max, value = _min_max_value(o)
min, max, value = _get_min_max_value(o[0], o[1], None)
return FloatSliderWidget(value=value, min=min, max=max, step=o[2])
elif _matches(o, (float, float, int)):
min, max, value = _min_max_value(o)
min, max, value = _get_min_max_value(o[0], o[1], None)
return FloatSliderWidget(value=value, min=min, max=max, step=float(o[2]))
elif all(isinstance(x, string_types) for x in o):
return DropdownWidget(value=unicode_type(o[0]),
@ -84,7 +101,7 @@ def interactive(f, **kwargs):
widgets = []
container = ContainerWidget()
container.result = None
container.arguments = dict()
container.kwargs = dict()
for key, value in kwargs.items():
if isinstance(value, Widget):
widget = value
@ -92,6 +109,7 @@ def interactive(f, **kwargs):
widget = _widget_abbrev(value)
if widget is None:
raise ValueError("Object cannot be transformed to a Widget")
widget.description = key
widgets.append((key,widget))
widgets.sort(key=lambda e: e[1].__class__.__name__)
container.children = [e[1] for e in widgets]
@ -101,9 +119,7 @@ def interactive(f, **kwargs):
actual_kwargs = {}
for key, widget in widgets:
value = widget.value
if hasattr(widget, 'actual_values'):
value = widget.actual_values[value]
container.arguments[key] = value
container.kwargs[key] = value
actual_kwargs[key] = value
if co:
clear_output(wait=True)
@ -112,9 +128,8 @@ def interactive(f, **kwargs):
# Wire up the widgets
for key, widget in widgets:
widget.on_trait_change(call_f, 'value')
widget.description = key
container.on_displayed(lambda : call_f(None, None, None))
container.on_displayed(lambda _: call_f(None, None, None))
return container

File diff suppressed because one or more lines are too long