Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
r""" Interacts for the Sage Jupyter notebook
This is mostly the same as the stock ``ipywidgets.interact``, but with some customizations for Sage.
TESTS:
We need to setup a proper test environment for widgets::
sage: from ipywidgets.widgets.tests.utils import setup_test_comm sage: setup_test_comm()
EXAMPLES::
sage: from sage.repl.ipython_kernel.interact import interact sage: @interact ....: def f(x=(0,10)): ....: pass Interactive function <function f at ...> with 1 widget x: IntSlider(value=5, description=u'x', max=10) sage: f.widget.children (IntSlider(value=5, description=u'x', max=10), Output()) """
#***************************************************************************** # Copyright (C) 2017 Jeroen Demeyer <jdemeyer@cage.ugent.be> # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # http://www.gnu.org/licenses/ #*****************************************************************************
""" Wrapper around the ipywidgets interactive which handles some SageNB specifics.
EXAMPLES::
sage: from sage.repl.ipython_kernel.interact import sage_interactive sage: def myfunc(x=10, y="hello", z=None): pass sage: sage_interactive(myfunc, x=(0,100), z=["one", "two", "three"]) Interactive function <function myfunc at ...> with 3 widgets x: IntSlider(value=10, description=u'x') y: Text(value=u'hello', description=u'y') z: Dropdown(description=u'z', options=('one', 'two', 'three'), value=None) """ """ See :class:`ipywidgets.widgets.interaction.interactive`
TESTS::
sage: from sage.repl.ipython_kernel.interact import sage_interactive sage: def myfunc(): pass sage: sage_interactive(myfunc, dict(manual=True)) Manual interactive function <function myfunc ...> with 0 widgets
::
sage: def myfunc(auto_update=False): pass sage: sage_interactive(myfunc) Manual interactive function <function myfunc ...> with 0 widgets sage: def myfunc(auto_update=None): pass sage: sage_interactive(myfunc) Interactive function <function myfunc ...> with 0 widgets """ # Use *args to avoid name clash with keyword arguments else:
# Check for auto_update in signature else:
# In Sage, manual interacts are always run once else: # In automatic mode, clicking on a ToggleButtons button # should also run the interact
""" Textual representation of this interactive function.
EXAMPLES::
sage: from sage.repl.ipython_kernel.interact import sage_interactive sage: def myfunc(): pass sage: sage_interactive(myfunc) Interactive function <function myfunc ...> with 0 widgets """ self.f, n, "s" if n != 1 else "")
""" Return the fixed signature of the interactive function (after a possible ``auto_update`` parameter was removed).
EXAMPLES::
sage: from sage.repl.ipython_kernel.interact import sage_interactive sage: def myfunc(x=[1,2,3], auto_update=False): pass sage: sage_interactive(myfunc).signature().parameters # py2 OrderedDict([('x', <Parameter ... 'x'>)]) sage: sage_interactive(myfunc).signature().parameters # py3 mappingproxy({'x': <Parameter "x=[1, 2, 3]">}) """
def widget_from_single_value(cls, abbrev, *args, **kwds): """ Convert a single value (i.e. a non-iterable) to a widget.
This supports the Sage :class:`Color` class. Any unknown type is changed to a string for evaluating. This is meant to support symbolic expressions like ``sin(x)``.
EXAMPLES::
sage: from sage.repl.ipython_kernel.interact import sage_interactive sage: sage_interactive.widget_from_single_value("sin(x)") Text(value=u'sin(x)') sage: sage_interactive.widget_from_single_value(sin(x)) EvalText(value=u'sin(x)') sage: from sage.plot.colors import Color sage: sage_interactive.widget_from_single_value(Color('cornflowerblue')) SageColorPicker(value='#6495ed') """ # Support Sage Colors # Get widget from IPython if possible # If IPython didn't construct a widget and the abbrev is not an # iterable, return an EvalText widget
def widget_from_tuple(cls, abbrev, *args, **kwds): """ Convert a tuple to a widget.
This supports two SageNB extensions: ``(description, abbrev)`` if ``description`` is a string and ``(default, abbrev)`` if ``abbrev`` is not a single value.
Symbolic expressions are changed to a floating-point number.
EXAMPLES::
sage: from sage.repl.ipython_kernel.interact import sage_interactive sage: sage_interactive.widget_from_tuple( (0, 10) ) IntSlider(value=5, max=10) sage: sage_interactive.widget_from_tuple( ("number", (0, 10)) ) IntSlider(value=5, description=u'number', max=10) sage: sage_interactive.widget_from_tuple( (3, (0, 10)) ) IntSlider(value=3, max=10) sage: sage_interactive.widget_from_tuple( (2, dict(one=1, two=2, three=3)) ) Dropdown(index=1, options={'three': 3, 'two': 2, 'one': 1}, value=2) sage: sage_interactive.widget_from_tuple( (sqrt(2), pi) ) FloatSlider(value=2.277903107981444, max=3.141592653589793, min=1.4142135623730951) """ # Support (description, abbrev) # Support (default, abbrev) # Numerically evaluate symbolic expressions else:
def widget_from_iterable(cls, abbrev, *args, **kwds): """ Convert an unspecified iterable to a widget.
This behaves like in ipywidgets, except that an iterator (like a generator object) becomes a ``SelectionSlider``.
EXAMPLES::
sage: from sage.repl.ipython_kernel.interact import sage_interactive sage: sage_interactive.widget_from_iterable([1..5]) Dropdown(options=(1, 2, 3, 4, 5), value=1) sage: sage_interactive.widget_from_iterable(iter([1..5])) SelectionSlider(options=(1, 2, 3, 4, 5), value=1) sage: sage_interactive.widget_from_iterable((1..5)) SelectionSlider(options=(1, 2, 3, 4, 5), value=1) sage: sage_interactive.widget_from_iterable(x for x in [1..5]) SelectionSlider(options=(1, 2, 3, 4, 5), value=1) sage: def gen(): ....: yield 1; yield 2; yield 3; yield 4; yield 5 sage: sage_interactive.widget_from_iterable(gen()) SelectionSlider(options=(1, 2, 3, 4, 5), value=1) """
# @interact decorator |