wiki:Jython
Last modified 5 weeks ago Last modified on 04/23/12 12:59:14
Note: this page documents features present in the development version - some features may not be present or not work in the latest beta release

Python Scripting in GeoGebra

Note: the version of Python used in GeoGebra is 2.5 (the technical reason for this is that this is the latest version of Jython, the Java implementation of Python). You will not be able to use features of Python 2.6 or Python 2.7. When reading online docs, look out for notices such as new in version 2.6.

The Python Window

  • Run GeoGebra 5 Beta Webstart
  • Select Python Window in the View menu to open the Python window (a few seconds wait may be needed the first time round).
  • The Python Window contains three panes:
Interactive
Here you can enter python statements and see their effect immediately. With Alt+UP / Alt+DOWN you can navigate the history of commands you have entered
Script
Here you can write the script that will be executed when the .ggb file is loaded. You can also execute this script at any point
Events
Here you can select any GeoGebra object and enter the Python code that will be executed when this object is clicked or updated. Within this script, the object that is the target of the event can be referred to as self

Demo

Copy and paste this script into the interactive pane

geo.A = (1,2)

# Create some random points
import random
xcoords = [random.uniform(-2, 5) for i in range(8)]
ycoords = [random.uniform(-2, 5) for i in range(8)]
points = [Point(x, y) for x, y in zip(xcoords, ycoords)]

# Join them all to A
segments = [Segment(p, geo.A) for p in points]

# Make a function that shows only the shortest segment
def show_shortest(moved_point):
   for s in segments: s.visible = False
   shortest = min(segments, key=float)
   shortest.visible = True

# Invoke this every time A is updated
geo.A.onupdate = show_shortest

# Now move A around in the Euclidian view!

The Python and GeoGebra namespaces

Since both Python and GeoGebra deal with objects which have names, it is important to be able to access easily the GeoGebra objects from Python but not to mix up both kinds of objects. GeoGebra objects can be accessed (and created) in Python by prefixing their name with $ or geo.. So if there is a point called A, it can be referred as $A or geo.A from Python. All other names are only accessible from Python.

As the above only allows ASCII names, there is a syntax for accessing non-ASCII name which may be common in other languages. The following will all return the GeoGebra object named A:

$A
geo.A
$['A']

Also, there is a convenient syntax for accessing or updating spreadsheet cells:

$['B', 2] = 12 # Set B2 to 12
$[3, 1] = 42 # Set C1 to 42 (A=1, B=2, ...)
$['A', 1] = (2, 2) # Set A1 to the point (2, 2)
$['A', 1].color = Color.RED # Change the color of the point

Points and Vectors

You can create points and vectors from coordinates

$A = Point(1, 2)
$B = Point(-2, 3)
$u = Vector(1, -1)

You can create a point from a vector

$C = Point($u)

You can create a vector from a point

$r_A = Vector($A)

You can create a vector joining two points

$v = Vector($A, $B)

If A is a point or a vector:

  • $A.x gives you its x-coordinate
  • $A.y gives you its y-coordinate
  • $A.coords gives you its coordinates as a tuple (ordered pair)

However, you don't get the result as a number but as an expression whose value changes dynamically as the point or vector moves. To get the current value, you need to use A.x.value and A.y.value. The above also allows you to set the coordinates of a point or vector:

$A.x = 3
$B.coords = (-1, 2)

sets the x-coordinate of A to 3 and the coordinates of B to (-1, 2). You can also use these to link points together:

$C = Point(2*$A.x, 1+$B.y)

creates a point C whose x-coordinate is always twice that of A, an y-coordinate is always one more than that of B.

Points have the following additional attributes:

  • point_size: an integer which represents the size of the point.

Attributes common to all elements

The following attributes don't just apply to points and vectors, but to all GeoGebra elements

  • caption (a caption string)
  • color (to set, use e.g. Color.RED or Color(0.5, 0.9, 0.8), i.e. like java.awt.Color)
  • defined (boolean, read only): true if the element is defined
  • infinite (boolean, read only): true if the element is infinite
  • label (a string)
  • label_color
  • label_mode can be any of "name", "name+value", "value", "caption"
  • label_visible (boolean)
  • layer (integer): the layer, between 0 and 9 where the element is displayed
  • trace (boolean): if true, the element is being traced
  • visible (boolean)

For example, the following creates a red point with a black caption saying "Click Me":

$P = Point(3, 1)
$P.color = Color.RED
$P.label_color = Color.BLACK
$P.label_mode = "caption"
$P.caption = "Click Me"

Attributes can be set at object creation in a simpler way. The following has the same effect as above:

$P = Point(3, 1, color=Color.RED, label_color=Color.BLACK, label_mode='caption', caption="Click Me")

Paths

Lines and segments

This creates a line l through points A and B

$l = Line($A, $B)

This creates a line l1 through A with direction the vector u

$l_1 = Line($A, $u)

Rays and segments can also be created:

$r = Ray((1, 1), (2, 0))
$s = Segment((-3, 0), (2, 1))

Segments have two attributes called startpoint and endpoint. Lines, segments and rays have an attribute called direction which gives their direction vector.

Axes

There are two special objects, $xAxis and $yAxis which represent the two coordinate axes. What can be done with them is limited at the moment. They have the following attributes:

  • visible: this allows to check and change the visibility of an axis

The following hides both axes from view.

$xAxis.visible = False
$yAxis.visible = False

Circles, Ellipses, Hyperbolae, Parabolae

the code below creates four circles:

  • C1 with centre (1, 1) and through (3, 2)
  • C2 through the points (0, 0), (4, 0), (4, 3)
  • C3 with centre A and radius BC
  • C4 with centre (-2, 0) and radius 3
$C_1 = Circle((1, 1), (3, 2))
$C_2 = Circle((0, 0), (4, 0), (4, 3))
$C_3 = Circle($A, Segment($B, $C))
$C_4 = Circle((-2, 0), 3)

The code below creates two ellipses, two hyperbolae and a parabola:

  • E1 with foci at (-2, 0), (2, 0) and semi major axis 3
  • E2 with foci at (1, 1), (3, 1) and passing through (2, 2)
  • H1 with foci at (-2, 0), (2, 0) and semi major axis 1
  • H2 with foci at (1, 1), (3, 1) and passing through (4, 2)
  • P with focus (0, 0) and directrix the line joining A and B
$E_1 = Ellipse((-2, 0), (2, 0), 3)
$E_2 = Ellipse((1, 1), (3, 1), (2, 2))
$H_1 = Hyperbola((-2, 0), (2, 0), 1)
$H_2 = Hyperbola((1, 1), (3, 1), (4, 2))
$P = Parabola((0, 0), Line($A, $B))

Path attributes

All paths (lines and curves) have the following attributes:

  • thickness (a numerical value)
  • linetype (this is a string; can be 'full', 'short-dash','long-dash', 'dot', 'dash-dot')

Polygons and PolyLines

To create a polygon through *A*, *B* and *C* you can do either:

$ABC = Polygon($A, $B, $C)

or

$ABC = Polygon([$A, $B, $C])

The latter is useful if you want want to create a polygon from an arbitrary sequence of points.

Polygons have the following attributes:

  • boundary: the boundary of the Polygon as a PolyLine
  • points: a Python list of all the vertices of the polygon (can also be obtained as list(poly))
  • edges: a Python list of all the edges of the polygon
  • area or value: the area of the polygon
  • directed_area: the area with a sign (+ anticlockwise, - clockwise)

The length of a polygon, len(poly) is the number of points on the polygon. The point with index i can be obtained using poly[i].

PolyLines are similar but they do not have edges, area or directed_area attributes, and their value attribute returns their total length.

Text

One can create text object as follows:

t = Text("Hello there!")

Text objects have the following attributes:

  • origin (a point). It can be read or set.
  • text: the string for the text obect. It can be read or set.
  • latex (a boolean): true if the text object should be displayed as LaTeX.

This moves the origin of the text to (2, 2) and sets the text displayed to "Abracadabra".

t.origin.coords = (2, 2)
t.text = "Abracadabra"

You can also do the following change the origin. However, this will create a new origin point, whereas the above keeps the same point but updates its coordinates.

t.origin = (3, 1)

This sets the origin of the text to the point A, so if A moves, so does the text:

t.origin = $A

Lists

GeoGebra lists are not to be confused with Python lists. List object can be created as follows:

my_list = List(1, 2, 3) # A geogebra list
python_list = [1, 2, 3] # A Python list

Subscript notation can be used to get or delete an item at a given position (but not to set it as I didn't find such a method in GeoList.java):

print my_list[1] # show the second item (the first has index 0)
del my_list[0] # remove the first item

A new item can be added at the end of a list with the append method:

my_list.append(42)

It is possible to loop over a list:

for item in my_list:
    print item + 10

You can convert a GeoGebra list to a Python list:

python_list = list(my_list)

You can remove all elements from a GeoGebra list with the clear method:

my_list.clear()

Functions

Functions can easily be defined in Python:

def f(x): return sin(x)/x

$f = Function(f)

Bivariate functions also work. Functions have an implicitcurve attribute:

def f(x, y): return x**2+y**2 - 5
$f = Function(f)
$c = f.implicitcurve

Functions can contain inequalities:

def f(x, y): return x**2 > x + y
geo.f = Function(f)

Turtles

Turtles are objects that can be moved and draw shapes in the euclidian view (see the logo programming language) To create a new turtle, just do:

t = Turtle()

Turtles can be moved and the nice thing about them is that they are animated, i.e. you can watch them move. Their speed can be adjusted, see below. Here is a simple example of drawing a regular pentagon with the turtle defined above:

t.pen_color = Color.RED
for i in range(5):
    t.forward(2)
    t.turn_left(72)

Note how you can see the turtle move and turn smoothly. If you would prefer the turtle to draw instantly, you can do

t.speed = 0

Turtle objects have the following attributes:

  • pen_color: can be used to get or set the color of the turtle pen
  • position: can be used to get or set the current position of the turtle
  • angle: can be used to get or set the current orientation of the turtle
  • pen_thickness: get or set the thickness of the turtle pen
  • running: set to True to animate the turtle, false to stop it moving
  • speed: the animation speed of the turtle - it is a floating point number between 0 and 1. 0 means instant, 0.01 very slow, 1 very fast (default 0.1)

Turtle objects have the following methods:

  • forward(distance): to move forward by distance units. It will also draw a line if the pen is down.
  • turn_left(angle): to turn left by angle degrees
  • turn_right(angle): to turn right by angle degrees
  • clear(): resets the position and angle of the turtle and clears the drawing.

Intersections

Intersect(x, y) works where x, y are lines or conics at the moment. An Intersect object can be cast to a list or a tuple in order to find the intersection points. E.g.

E.g.

l = Line((0, 1), (2, 2))
c = Circle((0, 0), 3)
p, q = Intersect(l, c)

To check if an intersection point p exists, use not p.infinite (or p.infinite to check that the intersection does not exist). Note that p.defined won't work because as the underlying geometric model for GeoGebra is projective, two lines always intersect.

Accessing selected objects

The selection object allows access to the current selection:

  • selection.all returns a list of all selected objects
  • selection.filter(<type>) returns a list of all selected objects of type <type>

As a convenience, the following can also be used:

  • selection.points
  • selection.vectors
  • selection.lines
  • selection.segments

Event handling

You can use the Events pane in the Python Window to select an object and an event, then type in a script in the editor text area. The target of the object can be referred to as self. E.g. you could write this in the onupdate field of a point:

if self.x < 0:
    self.caption = "negative x"
else:
    self.caption = "positive x"

As long as the point's label mode is set to 'caption', you will see the point's caption change if you move it across the y-axis.

All variables defined in the Python Script are accessible in event scripts. However, if you want to change the value of a variable, you need to declare it as global - otherwise a new variable local to the event script is created. E.g.

global score
score += 1

You can also add event handlers directly by defining the following attributes on elements:

  • onupdate
  • onadd
  • onremove
  • onclick
  • onrename

the attributes must be set to a function with one argument (which is the target of the event)

E.g.

def paint_blue(pt):
   pt.color = Color.BLUE

geo.A.onclick = paint_blue

Special Methods

  • answer = input(<question>) opens a free-text dialog and the (String) response is put in <answer>
  • answer = input(<question>, <default answer>) as above, but the dialog is filled in with <default answer> initially
  • alert(<text>) shows a message box containing the <text>
  • debug(<text>) prints <text> to the Java Console
  • command(<text>) evaluate a GeoGebra command and return a list of Elements
>>> command("3x+2y=12")
[<a: 2x + 3y = 12>]
>>> x, y = 3, 2
>>> r = 4
>>> command('Circle', (x, y), r)
[<c: (x - 3)² + (y - 2)² = 16>]

Concurrency in Python

See this page: Jython/Concurrency

Accessing the GeoGebra API

To call GgbAPI, you just need to prepend the call with ggbApplet. (ie the same syntax as from JavaScript)

E.g.

ggbApplet.evalCommand("x^2 + y^2 = 4")
ggbApplet.startAnimation()

Example Scripts

Best fit algebraic curve

Development

Interfacing with expEYES

Making Jython work with WebStart

Python -> JavaScript

Python in the Browser

Python in signed applets