**PREP Interact Quickstart
system:sage


<h1>Sage Interact Quickstart</h1>
<p><span id="cell_outer_0">This&nbsp;<a href="http://www.sagemath.org/" target="_blank">Sage</a>&nbsp;worksheet was developed for the MAA PREP Workshop "Sage: Using Open-Source Mathematics Software with Undergraduates" (funding provided by NSF DUE 0817071).</span></p>
<p>Invaluable resources are the Sage wiki <a href="http://wiki.sagemath.org/interact" target="_blank">http://wiki.sagemath.org/interact</a> (type "sage interact" into Google) and the <a href="http://sagemath.org/doc/reference/sagenb/notebook/interact.html#sagenb.notebook.interact.interact" target="_blank">interact documentation</a>, as well as <a href="http://interact.sagemath.org">http://interact.sagemath.org</a>.</p>
<p>&nbsp;</p>

{{{id=43|

///
}}}

<p>Start by getting the commands for what you want the output to look like. &nbsp;Here we just want a simple plot.</p>

{{{id=27|
plot(x^2,(x,-3,3))
///
<html><font color='black'><img src='cell://sage0.png'></font></html>
}}}

<p>Then abstract out the parts you want to change. &nbsp;We'll be letting the user change the function, so let's make that a variable $f$.</p>

{{{id=28|
f=x^3
plot(f,(x,-3,3))
///
<html><font color='black'><img src='cell://sage0.png'></font></html>
}}}

<p>Now make this a "def" function. &nbsp;The "show" or "print" is needed since the output is not automatically printed from within a function. &nbsp;Note also that we give the variable a default value of x^2. &nbsp;This is what $f$ is if the user does not specify a value for $f$.</p>

{{{id=29|
def myplot(f=x^2):
    show(plot(f,(x,-3,3)))
///
}}}

<p>Let's test the def function myplot by just calling it.</p>

{{{id=30|
myplot()
///
<html><font color='black'><img src='cell://sage0.png'></font></html>
}}}

<p>If we call it with a different value for f, we should get a different plot.</p>

{{{id=32|
myplot(f=x^3)
///
<html><font color='black'><img src='cell://sage0.png'></font></html>
}}}

<p>Now to make a control to enter the function, we just preface the function with @interact.</p>

{{{id=35|
@interact
def myplot(f=x^2):
    show(plot(f,(x,-3,3)))
///
}}}

<p>Tech tip: Technically what the @interact does is wrap the function, so the above is equivalent to:</p>
<p>def myplot(..): ...</p>
<p>myplot=interact(myplot)</p>

{{{id=54|

///
}}}

<p>Note that we can still call our function, even when we've used @interact. &nbsp;This is often useful in debugging it.</p>

{{{id=51|
myplot(x^4)
///
<html><font color='black'><img src='cell://sage0.png'></font></html>
}}}

<p>We can go ahead and replace other parts of the expression with variables. &nbsp;Note the "_" is the function name now. &nbsp;That is a convention for throw-away names that we don't care about.</p>

{{{id=15|
@interact
def g(f=x^2,a=-3,b=3):
    show(plot(f,(x,a,b)))
///
}}}

{{{id=59|
g(x^3,a=2)
///
<html><font color='black'><img src='cell://sage0.png'></font></html>
}}}

<p>If we pass ('label', default_value) in for a control, then the control gets the label when printed.</p>

{{{id=56|
@interact
def _(f=('$f$',x^2),a=('lower',-3),b=('upper',3)):
    show(plot(f,(x,a,b)))
///
}}}

<p>We can specify the type of control explicitly, along with options.</p>

{{{id=79|
input_box?
///
<html><!--notruncate-->

<div class="docstring">
    
  <p><strong>File:</strong> /home/sageserver/sage-5.0.1/devel/sagenb/sagenb/notebook/interact.py</p>
<p><strong>Type:</strong> &lt;type &#8216;classobj&#8217;&gt;</p>
<p><strong>Definition:</strong> input_box( [noargspec] )</p>
<p><strong>Docstring:</strong></p>
<blockquote>
<div><p>An input box interactive control.  Use this in conjunction
with the <a class="reference external" href="../../home/sageserver/sage-5.0.1/devel/sage/doc/output/html/en/reference/sagenb/notebook/interact.html#sagenb.notebook.interact.interact" title="(in Sage Reference Manual v5.0.1)"><tt class="xref py py-func docutils literal"><span class="pre">interact()</span></tt></a> command.</p>
<p>INPUT:</p>
<ul class="simple">
<li><tt class="docutils literal"><span class="pre">default</span></tt> - an object; the default put in this input box</li>
<li><tt class="docutils literal"><span class="pre">label</span></tt> - a string; the label rendered to the left of the
box.</li>
<li><tt class="docutils literal"><span class="pre">type</span></tt> - a type; coerce inputs to this; this doesn&#8217;t
have to be an actual type, since anything callable will do.</li>
<li><tt class="docutils literal"><span class="pre">height</span></tt> - an integer (default: 1); the number of rows.
If greater than 1 a value won&#8217;t be returned until something
outside the textarea is clicked.</li>
<li><tt class="docutils literal"><span class="pre">width</span></tt> - an integer; width of text box in characters</li>
<li><tt class="docutils literal"><span class="pre">kwargs</span></tt> - a dictionary; additional keyword options</li>
</ul>
<p>EXAMPLES:</p>
<div class="highlight-python"><div class="highlight"><pre class="literal-block"><span class="gp">sage: </span><span class="n">input_box</span><span class="p">(</span><span class="s">&quot;2+2&quot;</span><span class="p">,</span> <span class="s">&#39;expression&#39;</span><span class="p">)</span>
<span class="go">Interact input box labeled &#39;expression&#39; with default value &#39;2+2&#39;</span>
<span class="gp">sage: </span><span class="n">input_box</span><span class="p">(</span><span class="s">&#39;sage&#39;</span><span class="p">,</span> <span class="n">label</span><span class="o">=</span><span class="s">&quot;Enter your name&quot;</span><span class="p">,</span> <span class="nb">type</span><span class="o">=</span><span class="nb">str</span><span class="p">)</span>
<span class="go">Interact input box labeled &#39;Enter your name&#39; with default value &#39;sage&#39;</span>
<span class="gp">sage: </span><span class="n">input_box</span><span class="p">(</span><span class="s">&#39;Multiline</span><span class="se">\n</span><span class="s">Input&#39;</span><span class="p">,</span><span class="n">label</span><span class="o">=</span><span class="s">&#39;Click to change value&#39;</span><span class="p">,</span><span class="nb">type</span><span class="o">=</span><span class="nb">str</span><span class="p">,</span><span class="n">height</span><span class="o">=</span><span class="mi">5</span><span class="p">)</span>
<span class="go">Interact input box labeled &#39;Click to change value&#39; with default value &#39;Multiline\nInput&#39;</span>
</pre></div>
</div>
</div></blockquote>


</div>
</html>
}}}

{{{id=21|
@interact
def _(f=('$f$',input_box(x^2))):
    show(plot(f,(x,-3,3)))
///
}}}

<p>Here's another type of control: a color picker.</p>

{{{id=81|
color_selector?
///
<html><!--notruncate-->

<div class="docstring">
    
  <p><strong>File:</strong> /home/sageserver/sage-5.0.1/devel/sagenb/sagenb/notebook/interact.py</p>
<p><strong>Type:</strong> &lt;type &#8216;classobj&#8217;&gt;</p>
<p><strong>Definition:</strong> color_selector( [noargspec] )</p>
<p><strong>Docstring:</strong></p>
<blockquote>
<div><p>A color selector (also called a color chooser, picker, or
tool) interactive control.  Use this with the <a class="reference external" href="../../home/sageserver/sage-5.0.1/devel/sage/doc/output/html/en/reference/sagenb/notebook/interact.html#sagenb.notebook.interact.interact" title="(in Sage Reference Manual v5.0.1)"><tt class="xref py py-func docutils literal"><span class="pre">interact()</span></tt></a>
command.</p>
<p>INPUT:</p>
<ul class="simple">
<li><tt class="docutils literal"><span class="pre">default</span></tt> - an instance of or valid constructor argument
to <a class="reference external" href="../../home/sageserver/sage-5.0.1/devel/sage/doc/output/html/en/reference/sage/plot/colors.html#sage.plot.colors.Color" title="(in Sage Reference Manual v5.0.1)"><tt class="xref py py-class docutils literal"><span class="pre">Color</span></tt></a> (default: (0,0,1)); the selector&#8217;s default
color; a string argument must be a valid color name (e.g.,
&#8216;red&#8217;) or HTML hex color (e.g., &#8216;#abcdef&#8217;)</li>
<li><tt class="docutils literal"><span class="pre">label</span></tt> - a string (default: None); the label rendered to
the left of the selector.</li>
<li><tt class="docutils literal"><span class="pre">widget</span></tt> - a string (default: &#8216;jpicker&#8217;); the color
selector widget to use; choices are &#8216;colorpicker&#8217;, &#8216;jpicker&#8217;
and &#8216;farbtastic&#8217;</li>
<li><tt class="docutils literal"><span class="pre">hide_box</span></tt> - a boolean (default: False); whether to hide
the input box associated with the color selector widget</li>
</ul>
<p>EXAMPLES:</p>
<div class="highlight-python"><div class="highlight"><pre class="literal-block"><span class="gp">sage: </span><span class="n">color_selector</span><span class="p">()</span>
<span class="go">Interact color selector labeled None, with default RGB color (0.0, 0.0, 1.0), widget &#39;jpicker&#39;, and visible input box</span>
<span class="gp">sage: </span><span class="n">color_selector</span><span class="p">((</span><span class="mf">0.5</span><span class="p">,</span> <span class="mf">0.5</span><span class="p">,</span> <span class="mf">1.0</span><span class="p">),</span> <span class="n">widget</span><span class="o">=</span><span class="s">&#39;jpicker&#39;</span><span class="p">)</span>
<span class="go">Interact color selector labeled None, with default RGB color (0.5, 0.5, 1.0), widget &#39;jpicker&#39;, and visible input box</span>
<span class="gp">sage: </span><span class="n">color_selector</span><span class="p">(</span><span class="n">default</span> <span class="o">=</span> <span class="n">Color</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mf">0.5</span><span class="p">,</span> <span class="mf">0.25</span><span class="p">))</span>
<span class="go">Interact color selector labeled None, with default RGB color (0.0, 0.5, 0.25), widget &#39;jpicker&#39;, and visible input box</span>
<span class="gp">sage: </span><span class="n">color_selector</span><span class="p">(</span><span class="s">&#39;purple&#39;</span><span class="p">,</span> <span class="n">widget</span> <span class="o">=</span> <span class="s">&#39;colorpicker&#39;</span><span class="p">)</span>
<span class="go">Interact color selector labeled None, with default RGB color (0.50..., 0.0, 0.50...), widget &#39;colorpicker&#39;, and visible input box</span>
<span class="gp">sage: </span><span class="n">color_selector</span><span class="p">(</span><span class="s">&#39;crayon&#39;</span><span class="p">,</span> <span class="n">widget</span> <span class="o">=</span> <span class="s">&#39;colorpicker&#39;</span><span class="p">)</span>
<span class="gt">Traceback (most recent call last):</span>
<span class="c">...</span>
<span class="nc">ValueError</span>: <span class="n-Identifier">unknown color &#39;crayon&#39;</span>
<span class="gp">sage: </span><span class="n">color_selector</span><span class="p">(</span><span class="s">&#39;#abcdef&#39;</span><span class="p">,</span> <span class="n">label</span><span class="o">=</span><span class="s">&#39;height&#39;</span><span class="p">,</span> <span class="n">widget</span><span class="o">=</span><span class="s">&#39;jpicker&#39;</span><span class="p">)</span>
<span class="go">Interact color selector labeled &#39;height&#39;, with default RGB color (0.6..., 0.8..., 0.9...), widget &#39;jpicker&#39;, and visible input box</span>
<span class="gp">sage: </span><span class="n">color_selector</span><span class="p">(</span><span class="s">&#39;abcdef&#39;</span><span class="p">,</span> <span class="n">label</span><span class="o">=</span><span class="s">&#39;height&#39;</span><span class="p">,</span> <span class="n">widget</span><span class="o">=</span><span class="s">&#39;jpicker&#39;</span><span class="p">)</span>
<span class="gt">Traceback (most recent call last):</span>
<span class="c">...</span>
<span class="nc">ValueError</span>: <span class="n-Identifier">unknown color &#39;abcdef&#39;</span>
</pre></div>
</div>
</div></blockquote>


</div>
</html>
}}}

{{{id=19|
@interact
def _(f=input_box(x^2,width=20), color=color_selector(widget='colorpicker', default='red')):
    show(plot(f,(x,-3,3), color=color))
///
}}}

{{{id=37|

///
}}}

{{{id=38|

///
}}}

<p>Here are a bunch of options. &nbsp;Notice the new controls:</p>
<ul>
<li>range slider, which passes in <em>two </em>values, zoom[0] and zoom[1]</li>
<li>True/False get converted to checkboxes</li>
</ul>

{{{id=18|
@interact
def _(f=input_box(x^2,width=20), 
color=color_selector(widget='colorpicker', label=""),
axes=True,
fill=True,
zoom=range_slider(-3,3,default=(-3,3))):
    show(plot(f,(x,zoom[0], zoom[1]), color=color, axes=axes,fill=fill))
///
}}}

<p>That was a bit ugly because all of the controls were stacked on top of each other. &nbsp;We can layout the controls in a grid in the top, bottom, left, or right using the 'layout' parameter.</p>

{{{id=24|
@interact(layout=dict(top=[['f', 'color']], 
left=[['axes'],['fill']], 
bottom=[['zoom']]))
def _(f=input_box(x^2,width=20), 
color=color_selector(widget='colorpicker', label=""),
axes=True,
fill=True,
zoom=range_slider(-3,3, default=(-3,3))):
    show(plot(f,(x,zoom[0], zoom[1]), color=color, axes=axes,fill=fill))
///
}}}

<h1>Control Types</h1>

<p>Sage has:</p>
<ul>
<li>boxes</li>
<li>sliders</li>
<li>range sliders</li>
<li>checkboxes</li>
<li>selectors (dropdown lists or buttons)</li>
<li>grid of boxes</li>
<li>color selectors</li>
<li>plain text</li>
</ul>
<p>We illustrate some of these.</p>

{{{id=9|
@interact
def _(frame=checkbox(True, label='Use frame')):
    show(plot(sin(x), (x,-5,5)), frame=frame)
///
}}}

{{{id=10|
var('x,y')
colormaps=sage.plot.colors.colormaps.keys()
@interact
def _(cmap=selector(colormaps)):
    contour_plot(x^2-y^2,(x,-2,2),(y,-2,2),cmap=cmap).show()
///
}}}

{{{id=13|
var('x,y')
colormaps=sage.plot.colors.colormaps.keys()
@interact
def _(cmap=selector(['RdBu', 'jet', 'gray','gray_r'],buttons=True),
type=['density','contour']):
    if type=='contour':
        contour_plot(x^2-y^2,(x,-2,2),(y,-2,2),cmap=cmap, aspect_ratio=1).show()
    else:
        density_plot(x^2-y^2,(x,-2,2),(y,-2,2),cmap=cmap, frame=True,axes=False,aspect_ratio=1).show()
///
}}}

{{{id=65|

///
}}}

<p>By default, ranges are sliders that divide the range into 500 steps (I think that's the right number...)</p>

{{{id=33|
@interact
def _(n=(1,20)):
    print factorial(n)
///
}}}

<p>You can set the step size to get, for example, just integer values.</p>

{{{id=42|
@interact
def _(n=slider(1,20,step_size=1)):
    print factorial(n)
///
}}}

<p>Or you can explicitly specify the slider values.</p>

{{{id=40|
@interact
def _(n=slider([1..20])):
    print factorial(n)
///
}}}

<p>And the slider values don't even have to be numbers!</p>

{{{id=41|
@interact
def _(fun=('function', slider([sin,cos,tan,sec,csc,cot]))):
    print fun(4.39293)
///
}}}

{{{id=72|

///
}}}

<p>Matrices are automatically converted to a grid of input boxes.</p>

{{{id=71|
@interact
def _(m=('matrix', identity_matrix(2))):
    print m.eigenvalues()
///
}}}

<p>Here's how to get vectors from a grid of boxes.</p>

{{{id=69|
@interact
def _(v=('vector', input_grid(1, 3, default=[[1,2,3]], to_value=lambda x: vector(flatten(x))))):
    print v.norm()
///
}}}

<p>Sometimes we don't want any updates until we specifically say so. &nbsp;We can use the auto_update=False option for that.</p>

{{{id=76|
@interact
def _(m=('matrix', identity_matrix(2)), auto_update=False):
    print m.eigenvalues()
///
}}}

{{{id=78|

///
}}}