CoCalc Public Filesinteractive-widgets / intro.sagews
Authors: Travis Scholl, William A. Stein
Description: an example of some interacts
Compute Environment: Ubuntu 18.04 (Deprecated)

## Interact: Sage's analogue of Mathematica's manipulate...

Take any Python function and put @interact in the line before it, and it becomes interactive.

def g(n, m):
print n, "×", m, "=", n*m

g(5,3)

5 × 3 = 15

Now, let's make it interactive

• expect errors until you fill in values for n and m below!
@interact
def g(n, m):
print n, "×", m, "=", n*m

Interact: please open in CoCalc
# this time give default values:
@interact
def g(n=4, m=7):
print n, "×", m, "=", n*m

Interact: please open in CoCalc
pi + e +e

pi + 2*e
N(pi + e +e, digits=100)

8.578156310507883709183218325984827879711663586775024970908879847755969666993304187770799182392449923

# this time give specific values:
@interact
def g(n=(0,pi/2,..12), m=(0,pi,..,12)):
print n, "×", m, "=", n*m

Interact: please open in CoCalc
# this time give specific values *and* specify the operation.
@interact
def g(n=(1..12), m=(1..12), operation=['multiply', 'add']):
if operation == 'multiply':
print n, "×", m, "=", n*m
else:
print n, "+", m, "=", n+m

Interact: please open in CoCalc

As you're starting to see, you can make these interacts very sophisticated.


var('x,y,t,z')
f(x,y)=sin(x)*cos(y)

pif = float(pi)

line_thickness=3
surface_color='blue'
plane_color='purple'
line_color='red'
tangent_color='green'

@interact
def myfun(location=input_grid(1, 2, default=[0,0], label = "Location (x,y)", width=2), angle=slider(0, 2*pif, label = "Angle"),
show_surface=("Show surface", True)):
location3d = vector(location[0]+[0])
location = location3d[0:2]
direction3d = vector(RDF, [cos(angle), sin(angle), 0])
direction=direction3d[0:2]
cos_angle = math.cos(angle)
sin_angle = math.sin(angle)
direction_vector=line3d([location3d, location3d+direction3d], arrow_head=True, rgbcolor=line_color, thickness=line_thickness)
curve_point = (location+t*direction).list()
curve = parametric_plot(curve_point+[f(*curve_point)], (t,-3,3),color=line_color,thickness=line_thickness)
plane = parametric_plot((cos_angle*x+location[0],sin_angle*x+location[1],t), (x, -3,3), (t,-3,3),opacity=0.8, color=plane_color)
pt = point3d(location3d.list(),color='green', size=10)

tangent_line = parametric_plot((location[0]+t*cos_angle, location[1]+t*sin_angle, f(*location)+t*df(*location)*(direction)), (t, -3,3), thickness=line_thickness, color=tangent_color)
picture3d = direction_vector+curve+plane+pt+tangent_line

picture2d = contour_plot(f(x,y), (x,-3,3),(y,-3,3), plot_points=100)
picture2d += arrow(location.list(), (location+direction).list())
picture2d += point(location.list(),rgbcolor='green',pointsize=40)
if show_surface:
picture3d += plot3d(f, (x,-3,3),(y,-3,3),opacity=0.7)

dff = df(location[0], location[1])
dff3d = vector(RDF,dff.list()+[0])
picture3d += line3d([location3d, location3d+dff3d], arrow_head=True, rgbcolor=gradient_color, thickness=line_thickness)
picture2d += arrow(location.list(), (location+dff).list(), rgbcolor=gradient_color, width=line_thickness)
show(picture3d,aspect_ratio=[1,1,1])
show(picture2d, aspect_ratio=1)

(x, y, t, z)
Interact: please open in CoCalc
interact?

File: /cocalc/lib/python2.7/site-packages/smc_sagews/sage_salvus.py
Signature : interact(self, f=None, layout=None, width=None, style=None, update_args=None, auto_update=True, flicker=False, output=True)
Docstring :
Use interact to create interactive worksheet cells with sliders,
text boxes, radio buttons, check boxes, color selectors, and more.

Put "@interact" on the line before a function definition in a cell
by itself, and choose appropriate defaults for the variable names
to determine the types of controls (see tables below).  You may
also put "@interact(layout=...)" to control the layout of controls.
Within the function, you may explicitly set the value of the
control corresponding to a variable foo to bar by typing
interact.foo = bar.

Type "interact.controls.[tab]" to get access to all of the
controls.

INPUT:

* "f" -- function

* "width" -- number, or string such as '80%', '300px', '20em'.

* "style" -- CSS style string, which allows you to change the
border, background color, etc., of the interact.

* "update_args" -- (default: None); list of strings, so that only
changing the corresponding controls causes the function to be re-
evaluated; changing other controls will not cause an update.

* "auto_update" -- (default: True); if False, a button labeled
'Update' will appear which you can click on to re-evalute.

* "layout" -- (default: one control per row) a list [row0, row1,
...] of lists of tuples row0 = [(var_name, width, label), ...],
where the var_name's are strings, the widths must add up to at
most 12, and the label is optional.  This will layout all of the
controls and output using Twitter Bootstraps "Fluid layout", with
spans corresponding to the widths.   Use var_name='' to specify
where the output goes, if you don't want it to last.  You may
specify entries for controls that you will create later using
interact.var_name = foo.

NOTES: The flicker and layout options above are only in SALVUS.
For backwards compatibility with the Sage notebook, if layout is
a dictionary (with keys 'top', 'bottom', 'left', 'right'), then
the appropriate layout will be rendered as it used to be in the
Sage notebook.

OUTPUT:

* creates an interactive control.

There are also some defaults that allow you to make controls
automatically without having to explicitly specify them.  E.g., you
can make "x" a continuous slider of values between "u" and "v" by
just writing "x=(u,v)" in the argument list.

* "u" - blank input_box

* "u=elt" - input_box with "default=element", unless other rule
below

* "u=(umin,umax)" - continuous slider (really 100 steps)

* "u=(umin,umax,du)" - slider with step size "du"

* "u=list" - buttons if "len(list)" at most 5; otherwise, drop
down

* "u=generator" - a slider (up to 10000 steps)

* "u=bool" - a checkbox

* "u=Color('blue')" - a color selector; returns "Color" object

* "u=matrix" - an "input_grid" with "to_value" set to
"matrix.parent()" and default values given by the matrix

* "u=(default, v)" - "v" anything as above, with given "default"
value

* "u=(label, v)" - "v" anything as above, with given "label" (a
string)

EXAMPLES:

The layout option:

@interact(layout={'top': [['a', 'b']], 'left': [['c']],
'bottom': [['d']], 'right':[['e']]})
def _(a=x^2, b=(0..20), c=100, d=x+1, e=sin(2)):
print(a+b+c+d+e)

We illustrate some features that are only in Salvus, not in the
Sage cell server or Sage notebook.

You can set the value of a control called foo to 100 using
interact.foo=100. For example:

@interact
def f(n=20, twice=None):
interact.twice = int(n)*2

In this example, we create and delete multiple controls depending
on properties of the input:

@interact
def f(n=20, **kwds):
print(kwds)
n = Integer(n)
if n % 2 == 1:
del interact.half
else:
interact.half = input_box(n/2, readonly=True)
if n.is_prime():
interact.is_prime = input_box('True', readonly=True)
else:
del interact.is_prime

We illustrate not automatically updating the function until a
button is pressed:

@interact(auto_update=False)
def f(a=True, b=False):
print a, b

You can access the value of a control associated to a variable foo
that you create using interact.foo, and check whether there is a
control associated to a given variable name using hasattr:

@interact
def f():
if not hasattr(interact, 'foo'):
interact.foo = 'hello'
else:
print(interact.foo)

An indecisive interact:

@interact
def f(n=selector(['yes', 'no'])):
for i in range(5):
interact.n = i%2
sleep(.2)

We use the style option to make a holiday interact:

@interact(width=25,
style="background-color:lightgreen; border:5px dashed red;")
def f(x=button('Merry ...',width=20)):
pass

We make a little box that can be dragged around, resized, and is
updated via a computation (in this case, counting primes):

@interact(width=30,
style="background-color:lightorange; position:absolute; z-index:1000; box-shadow : 8px 8px 4px #888;")
def f(prime=text_control(label="Counting primes: ")):
salvus.javascript("cell.element.closest('.salvus-cell-output-interact').draggable().resizable()")
p = 2
c = 1
while True:
interact.prime = '%s, %.2f'%(p, float(c)/p)
p = next_prime(p)
c += 1
sleep(.25)