import sys
from interact_sagecell import interact
def _dynamic(var, control=None):
if control is None:
control = sys._sage_.namespace.get(var,'')
old_value = [sys._sage_.namespace.get(var,None)]
@interact(layout=[[(var,12)]], output=False)
def f(self, x=(var,control)):
if x is not old_value[0]:
sys._sage_.namespace[var]=x
old_value[0] = x
def g(var,y):
f.x = y
sys._sage_.namespace.on(var,'change', g)
if var in sys._sage_.namespace:
g(var, sys._sage_.namespace[var])
def dynamic(*args, **kwds):
"""
Make variables in the global namespace dynamically linked to a control from the
interact label (see the documentation for interact).
EXAMPLES:
Make a control linked to a variable that doesn't yet exist::
dynamic('newname')
Make a slider and a selector, linked to t and x::
dynamic(t=(1..10), x=[1,2,3,4])
t = 5 # this changes the control
"""
for var in args:
if not isinstance(var, str):
i = id(var)
for k,v in sys._sage_.namespace.items():
if id(v) == i:
_dynamic(k)
return
else:
_dynamic(var)
for var, control in kwds.items():
_dynamic(var, control)
def dynamic_expression(v, vars):
"""
sage: t=5
sage: dynamic(t)
sage: dynamic_expression('2*t','t')
"""
@interact(output=False, readonly=True)
def f(t=(0,2)):
pass
def g(var,val):
f.t = eval(v)
for vv in vars:
sys._sage_.namespace.on(vv,'change',g)
imports = {"dynamic": dynamic,
"dynamic_expression": dynamic_expression}