Final Project

Adding a Directional Pad and a 2 Dimensional Slider to @Interact

by Ethan and Jacob Celletti

As a final project we chose to add more functionality to the notebook specifically the @interact module. The interact module currently contains no directional pad (or dpad) object and currently contains only a linear slider for changing a single variable over a discrete range. For the first part of our project we implemented a dpad that manipulates a set of data, technically returning a list of updated points to the interactable object. The second part of our project was to implement a 2 dimensional slider for manipulating  two variables at once so you would only need a single slider instead of two.

{{{id=9| @interact def _ (D = dpad(), S = slider_2d(0,1,0,1)): print "Your Standard DPad and 2D Slider"; ///
DPad 
            
Slider2D 
}}}

For both parts of our project we have created docstrings with sage command line examples. Because of the nature of the interact module all functionality is unavailable in the sage command line but it will display a representation of each class in text format. Therefore the only useful way of implementing the DPad and the 2D slider is in the notebook.

{{{id=15| /// }}}

In order to create a interactable dpad,as seen below, dpad does not require any parameters and will initially begin at point (0,0) and increment in steps of 1 in each direction unless you change the default_point, horiz_step, and vert_step. By default dpad has a label of "DPad". There is currently no implemented type for dpad but it could be implemented. Finally there is the parameter kwargs which is a dictionary of optional keyboard options if needed.

Dpad is used to change the values of an array from your given array in increments given by the horiz_step and vert_point. It can be used to increment any two integers you need to.

{{{id=7| @interact dpad? ///

File: /home/sage/devel/sagenb/sagenb/notebook/interact.py

Type: <type ‘classobj’>

Definition: dpad( [noargspec] )

Docstring:

Class that creates a DPad that can change/shift an array of two integers (a point) up, left, right, down or diagonal.

INPUT:

  • default_point - an array of two integers; default value of the point position
  • horiz_step - an integer; the interval/step when a horizonal button is pushed
  • vert_step - an integer; the interval/step when a vertical button is pushed
  • label - a string; the label rendered to the left of the dpad
  • type - a type;
  • kwargs - a dictionary; additional keyboard options

EXAMPLES:

sage: dpad()
Directional Pad: DPad = initial point:((0, 0)), horizontal step:1, vertical-step:1
sage: dpad([2,3],3,5)
Directional Pad: DPad = initial point:([2, 3]), horizontal step:3, vertical-step:5
}}}

In the below example is a very simple dpad with all default values. As you update the dpad the line point updates accordingly in steps of 1.

{{{id=1| @interact def _(H = dpad()): print H line([H,(10,10)]).show(figsize=4) ///
DPad 
            
}}}

The below example creates a 2D representation of a graph of a path followed and then a 3D example based off a 3 dimensional path being followed. The first plot uses the first dpad's value and plots lines between the points. The second plot uses the first value from the first dpad, combines the second value from dpad a and the first value from dpad b, and then the second value from dpad b to plot a  3d line.

{{{id=28| Path = []; Path3d = []; @interact def _(a = dpad(),b = dpad()): Path.append(a) Path3d.append([a[0],a[1]+b[0],b[1]]) print a[0], a[1]+b[0], b[1] if len(Path) >= 2: line3d(Path3d).show(figsize=3) line(Path).show(figsize=3) ///
DPad 
            
DPad 
            
}}}

Below the dpad starts at [1,1] and moves horizontally in steps of 2 with a default vertical step. It plots a sinusoidal curve with wavelength based on the second manipulated value from the dpad and has a range dependent on the first value from the list.

{{{id=29| @interact def _(a = dpad(default_point=[1,1], horiz_step=2)): if(-a[0] >= a[0]): a[0] = 2 plot(sin(a[1]*x),(-a[0]*pi,a[0]*pi),color=hue(0.5)).show(figsize=4) ///
DPad 
            
}}}

The 2 dimensional slider method creates a slider box where the first variable is manipulated along the x-axis and the second variable along the y-axis. In order to create the 2D slider, in the interact module, you call the slider_2d class with __init__ parameters x_begin ,x_end, y_begin, y_end,  x_step, y_step, size, label, type, and  kwargs. The x_begin, x_end,y_begin, and y_end set the limits of the x and y variables while the x_step and y_step parameters, which are not required and initialized to 1, denote the step sizes between the beginning and ending variables. The size parameter denotes the pixel width and height of the input slider box. The label parameter displays to the left of the slider box and is a string initialized to "Slider2D". The type is currently not implemented but could be the type of input that the class should expect or what the values should be coerced into if possible. Finally kwargs is an optional dictionary of keyboard options. Most of this information can be found in the docstring along with multiple examples of what sage would do in the command line.

Below we demonstrate how slider_2d can be used and what some of its limitations are.

{{{id=12| @interact slider_2d? ///

File: /home/sage/devel/sagenb/sagenb/notebook/interact.py

Type: <type ‘classobj’>

Definition: slider_2d( [noargspec] )

Docstring:

Class that creates a 2 dimensional slider that contributes to 2 variables

INPUT:

  • x_beign - an integer; the start value of the x-axis on the slider
  • x_end - an integer; the end value of the x-axis ont the slider
  • y_begin - an integer; the start value of the y-axis on the slider
  • y_end - an integer; the end value of the y-axis on the slider
  • x_step - an integer; the size of each step between each value on x-axis
  • y_step - an integer; the size of each step between each value on y-axis
  • size - an array; the pixel size of the heighth, width of the slider
  • label - a string; the label rendered to the left of the slider
  • type - a type;
  • kwargs - a dictionary; additional keyboard options

EXAMPLES:

sage: slider_2d(1,2,3,4)
Slider2D: Slider2D = horizontal: [1,2,..,2], vertical: [3,4,..,4]
sage: slider_2d(1,50,3,45,4,5,label="The Slider!")
Slider2D: The Slider! = horizontal: [1,5,..,50], vertical: [3,8,..,45]
}}}

In the example below the slider is used to denote the beginning point of a line with x in the range [10,100] in steps of 10 and y in the range [4,20] in steps of 2. Therefore the bottom left corner of the box is the point (10,4) and the upper right corner is the point (100, 20) with values spanning in-between according to their stepsizes.

{{{id=2| @interact def _(P = slider_2d(10,100,4,20,10,2,(150,200))): print "The point P is", P; S = point((0,0)) + line([P,(1|20,30)]); S.show(); ///
Slider2D 
}}}

In the example below we chose to manipulate the x and y variables in a parametric equation where the parametric plot is manipulated by x and y and the parametric variable ranges from 0 to pi/10 y's.

This example also shows the manipulation of the x and y steps, the size of the input box is changed and the label is manipulated including html code.

{{{id=19| @interact def _(P = slider_2d(1,20,1,30,2,3,[200,100],"x ⊂ [1,20]
y ⊂ [1,30]")): x = P[0]; y = P[1]; var('t') print P parametric_plot((x*sin(2*t),y*sin(t)),(t,0,pi*y/10)).show(figsize=6) ///
x ⊂ [1,20]
y ⊂ [1,30] 
}}}

The example draws a vector from the origin to the new point P and continues to accumulate vectors as you choose new points.

In this example the size of the slider box is manipulated as well as the label being changed.

{{{id=16| ar=[(0,0)]; @interact def _(P = slider_2d(0,10,0,20,size=[200,120],label="x ⊂ [1,200]
y ⊂ [30,935]")): ar.append(P); pl = point(ar[0]); for pt in ar: pl += arrow2d(ar[0],tuple(pt)); pl.show() ///
x ⊂ [1,200]
y ⊂ [30,935] 
}}}

General Issues:


Dpad Issues:
    


Slider Issues:

EX 1

{{{id=38| @interact def _(H = dpad(), G = dpad(default_point=[1,1], horiz_step=2)): print H,G line([H,G]).show() /// }}}

EX 2

{{{id=34| @interact def _(P = slider_2d(0,10,0,10,2,2,label = "S1",size = (10,10)), Q = slider_2d(1,11,1,11,2,2,label = "S2",size = (500,100)) ): print "P","x =",P[0], "y =", P[1]; print "Q","x =",Q[0], "y =", Q[1]; line([P,Q]).show(figsize=4); ///
S1 
S2 
}}}

We hope that sometime in the future these features or features like them will be added to sage's @interact module because we believe that they will contribute greatly to variable manipulation within sage. With more time we could have made each class handle more special cases, take care of any bugs that may arise, and optimize them for efficiency.

{{{id=39| /// }}}