Links


Course Website
Modus
Sage Tutorial
Python Tutorials


Sage Website
Overview






Every Single Copy of Sage Includes...

  1. ATLAS: Automatically Tuned Linear Algebra Software
  2. BLAS: Basic Fortan 77 linear algebra routines
  3. Bzip2: High-quality data compressor
  4. Cddlib: Double Description Method of Motzkin
  5. Common Lisp: Multiparadigm and general-purpose programming language
  6. CVXOPT: Convex optimization, linear programming, least squares, etc.
  7. Cython: C-Extensions for Python
  8. F2c: Converts Fortran 77 to C code
  9. Flint: Fast Library for Number Theory
  10. FpLLL: Euclidian lattice reduction
  11. FreeType: A Free, High-Quality, and Portable Font Engine
  12. G95: Open source Fortran 95 compiler
  13. GAP: Groups, Algorithms, Programming
  14. GD: Dynamic graphics generation tool
  15. Genus2reduction: Curve data computation
  16. Gfan: Gröbner fans and tropical varieties
  17. Givaro: C++ library for arithmetic and algebra
  18. GMP: GNU Multiple Precision Arithmetic Library
  19. GMP-ECM: Elliptic Curve Method for Integer Factorization
  20. GNU TLS: Secure networking
  21. GSL: Gnu Scientific Library
  22. JsMath: Script implementation of LaTeX
  23. IML: Integer Matrix Library
  24. IPython: Interactive Python shell
  25. LAPACK: Fortan 77 linear algebra library
  26. Lcalc: L-functions calculator
  27. Libgcrypt: General purpose cryptographic library
  28. Libgpg-error: Common error values for GnuPG components
  29. Linbox: C++ linear algebra library
  30. M4RI: Linear Algebra over GF(2)
  31. Matplotlib: Python plotting library
  32. Maxima: computer algebra system
  33. Mercurial: Revision control system
  34. MoinMoin Wiki
  35. MPFI: Multiple Precision Floating-point Interval library
  36. MPFR: C library for multiple-precision floating-point computations with correct rounding
  37. ECLib:Cremona's Programs for Elliptic curves
  38. NetworkX: Graph theory
  39. NTL: Number theory C++ library
  40. Numpy: Numerical linear algebra
  41. OpenCDK: Open Crypto Development Kit
  42. PALP: A Package for Analyzing Lattice Polytopes
  43. PARI/GP: Number theory calculator
  44. Pexpect: Pseudo-tty control for Python
  45. PNG: Bitmap image support
  46. PolyBoRi: Polynomials Over Boolean Rings
  47. PyCrypto: Python Cryptography Toolkit
  48. Python: Interpreted language
  49. Qd: Quad-double/Double-double Computation Package
  50. R: Statistical Computing
  51. Readline: Line-editing
  52. Rpy: Python interface to R
  53. Scipy: Python library for scientific computation
  54. Singular: fast commutative and noncommutative algebra
  55. Scons: Software construction tool
  56. SQLite: Relation database
  57. Sympow: L-function calculator
  58. Symmetrica: Representation theory
  59. Sympy: Python library for symbolic computation
  60. Tachyon: lightweight 3d ray tracer
  61. Termcap: Simplifies the process of writing portable text mode applications
  62. Twisted: Python networking library
  63. Weave: Tools for including C/C++ code within Python
  64. Zlib: Data compression library
  65. ZODB: Object-oriented database






Installation
How to start and use notebooks (see also Help)






Introduction to Sage


Based on the Sage Tutorial


Assignment, Equality, and Arithmetic

With some minor exceptions, Sage uses the Python programming language, so most introductory books on Python will help you to learn Sage.

Sage uses = for assignment. It uses ==,<=,>=,< and > for comparison: {{{id=1| a = 5 /// }}} {{{id=2| a /// 5 }}} {{{id=3| 2 == 3 /// False }}} {{{id=4| 2 < 3 /// True }}} {{{id=5| a == 5 /// True }}}

Sage provides all of the basic mathematical operations: {{{id=6| 2+4*6 /// 26 }}} {{{id=7| 2**6 # ** means exponent /// 64 }}} {{{id=8| 2^6 # ^ is a synonym for ** (unlike in Python) /// 64 }}} {{{id=9| 10 % 3 # for integer arguments, % means mod, i.e., remainder /// 1 }}} {{{id=10| 10/4 /// 5/2 }}} {{{id=11| 10//4 # for integer arguments, // returns the integer quotient /// 2 }}} {{{id=15| 4 * (10 // 4) + 10 % 4 == 10 /// True }}} {{{id=12| 2345^98 # arbitrary precision /// 1879312537156040227304800937029250945996419733488500849760174594685063601299599011178197702306691856869053751204298304807715200029567547302257341824069952997802594773365541370823811696392671323977639889323921481055923347588862647026214659502037417043419435219410766862699746022191346706887472850500131471562781371176242828369140625 }}} {{{id=17| 3^2*4 + 2%5 /// 38 }}}

The computation of an expression like 3^2*4 + 2%5 depends on the order in which the operations are applied; this is specified in the ``operator precedence table'' in Section A.1.

Sage also provides many familiar mathematical functions; here are just a few examples: {{{id=13| pi /// pi }}} {{{id=14| sin(pi/3) /// 1/2*sqrt(3) }}} {{{id=24| exp(1) /// e }}} {{{id=16| n(e) # n(-) returns a numerical approximation to its argument /// 2.71828182845905 }}} {{{id=25| n(pi,digits=200) /// 3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303820 }}}

Python is dynamically typed, so the value referred to by each variable has a type associated with it, but a given variable may hold values of any Python type within a given scope: {{{id=18| a = 5 # a is an integer type(a) /// }}} {{{id=19| b = 5/3 # b is a rational number type(b) /// }}} {{{id=20| a + b /// 20/3 }}} {{{id=21| a = "hello" # now a is a string type(a) /// }}} The C programming language, which is statically typed, is much different; a variable declared to hold an int can only hold an int in its scope.


Getting Help, Tab Completion

Sage has extensive built-in documentation, accessible by typing the name of a function or a constant (for example), followed by a question mark: {{{id=36| exp? /// }}}

Auto Completion with TAB {{{id=35| di /// }}} {{{id=37| diff? /// }}}

Source code with ?? {{{id=38| subsets?? /// }}}

Solving Equations and Variables

The solve function solves equations. To use it, first specify some variables; then the arguments to solve are an equation (or a system of equations), together with the variables for which to solve: {{{id=34| solve(x^2 + 3*x + 2, x) # x is very special and needs not to be declared explicitly /// [x == -2, x == -1] }}} {{{id=39| solve(y^2 + 3*y + 2, y) # for y it doesn't work /// Traceback (most recent call last): File "", line 1, in File "_sage_input_17.py", line 10, in exec compile(u'open("___code___.py","w").write("# -*- coding: utf-8 -*-\\n" + _support_.preparse_worksheet_cell(base64.b64decode("c29sdmUoeV4yICsgMyp5ICsgMiwgeSkgICAjIGZvciB5IGl0IGRvZXNuJ3Qgd29yaw=="),globals())+"\\n"); execfile(os.path.abspath("___code___.py"))' + '\n', '', 'single') File "", line 1, in File "/tmp/tmpJgX3ml/___code___.py", line 3, in exec compile(u"solve(y**_sage_const_2 + _sage_const_3 *y + _sage_const_2 , y) # for y it doesn't work" + '\n', '', 'single') File "", line 1, in NameError: name 'y' is not defined }}} {{{id=27| y = var('y') solve(y^2 + 3*y + 2, y) /// [y == -2, y == -1] }}}

You can solve equations for one variable in terms of others: {{{id=28| x, b, c = var('x b c') solve(x^2 + b*x + c == 0, x) # quadratic equation /// [x == -1/2*b - 1/2*sqrt(b^2 - 4*c), x == -1/2*b + 1/2*sqrt(b^2 - 4*c)] }}} {{{id=135| x, b, c, d = var('x b c d') solve(x^3 + b*x^2 + c*x + d == 0, x) # cubic equation /// [x == -1/18*(-I*sqrt(3) + 1)*(b^2 - 3*c)/(1/6*sqrt(-1/3*b^2*c^2 + 4/3*c^3 + 2/3*(2*b^3 - 9*b*c)*d + 9*d^2) - 1/27*b^3 + 1/6*b*c - 1/2*d)^(1/3) - 1/2*(I*sqrt(3) + 1)*(1/6*sqrt(-1/3*b^2*c^2 + 4/3*c^3 + 2/3*(2*b^3 - 9*b*c)*d + 9*d^2) - 1/27*b^3 + 1/6*b*c - 1/2*d)^(1/3) - 1/3*b, x == -1/18*(I*sqrt(3) + 1)*(b^2 - 3*c)/(1/6*sqrt(-1/3*b^2*c^2 + 4/3*c^3 + 2/3*(2*b^3 - 9*b*c)*d + 9*d^2) - 1/27*b^3 + 1/6*b*c - 1/2*d)^(1/3) - 1/2*(-I*sqrt(3) + 1)*(1/6*sqrt(-1/3*b^2*c^2 + 4/3*c^3 + 2/3*(2*b^3 - 9*b*c)*d + 9*d^2) - 1/27*b^3 + 1/6*b*c - 1/2*d)^(1/3) - 1/3*b, x == -1/3*b + 1/9*(b^2 - 3*c)/(1/6*sqrt(-1/3*b^2*c^2 + 4/3*c^3 + 2/3*(2*b^3 - 9*b*c)*d + 9*d^2) - 1/27*b^3 + 1/6*b*c - 1/2*d)^(1/3) + (1/6*sqrt(-1/3*b^2*c^2 + 4/3*c^3 + 2/3*(2*b^3 - 9*b*c)*d + 9*d^2) - 1/27*b^3 + 1/6*b*c - 1/2*d)^(1/3)] }}}

You can also solve for several variables: {{{id=29| x, y = var('x y') solve([x+y == 6, x-y == 4], x, y) /// [[x == 5, y == 1]] }}}

Plotting, Differentiating, and Integrating

Sage allows you to plot functions easily. Plots can be added.

{{{id=31| p1 = plot(sin(x), (x, 0, 2*pi)) p1 /// }}} {{{id=136| p2 = plot(cos(x), (x, 0, 3*pi), color = 'red') p1 + p2 /// }}}

Sage knows how to differentiate and integrate many functions. For example, to differentiate sin(x) with respect to x, do the following: {{{id=49| diff(sin(x), x) /// cos(x) }}}

Compute higher derivatives: {{{id=51| diff(sqrt(exp(sin(x^2+1))+cos(x))+log(x), x, 5) /// 1/2*(32*x^5*e^(sin(x^2 + 1))*cos(x^2 + 1)^5 - 320*x^5*e^(sin(x^2 + 1))*sin(x^2 + 1)*cos(x^2 + 1)^3 + 480*x^5*e^(sin(x^2 + 1))*sin(x^2 + 1)^2*cos(x^2 + 1) - 320*x^5*e^(sin(x^2 + 1))*cos(x^2 + 1)^3 + 480*x^5*e^(sin(x^2 + 1))*sin(x^2 + 1)*cos(x^2 + 1) + 160*x^3*e^(sin(x^2 + 1))*cos(x^2 + 1)^4 + 32*x^5*e^(sin(x^2 + 1))*cos(x^2 + 1) - 960*x^3*e^(sin(x^2 + 1))*sin(x^2 + 1)*cos(x^2 + 1)^2 + 480*x^3*e^(sin(x^2 + 1))*sin(x^2 + 1)^2 - 640*x^3*e^(sin(x^2 + 1))*cos(x^2 + 1)^2 + 160*x^3*e^(sin(x^2 + 1))*sin(x^2 + 1) + 120*x*e^(sin(x^2 + 1))*cos(x^2 + 1)^3 - 360*x*e^(sin(x^2 + 1))*sin(x^2 + 1)*cos(x^2 + 1) - 120*x*e^(sin(x^2 + 1))*cos(x^2 + 1) - sin(x))/sqrt(e^(sin(x^2 + 1)) + cos(x)) - 5/4*(2*x*e^(sin(x^2 + 1))*cos(x^2 + 1) - sin(x))*(16*x^4*e^(sin(x^2 + 1))*cos(x^2 + 1)^4 - 96*x^4*e^(sin(x^2 + 1))*sin(x^2 + 1)*cos(x^2 + 1)^2 + 48*x^4*e^(sin(x^2 + 1))*sin(x^2 + 1)^2 - 64*x^4*e^(sin(x^2 + 1))*cos(x^2 + 1)^2 + 16*x^4*e^(sin(x^2 + 1))*sin(x^2 + 1) + 48*x^2*e^(sin(x^2 + 1))*cos(x^2 + 1)^3 - 144*x^2*e^(sin(x^2 + 1))*sin(x^2 + 1)*cos(x^2 + 1) - 48*x^2*e^(sin(x^2 + 1))*cos(x^2 + 1) + 12*e^(sin(x^2 + 1))*cos(x^2 + 1)^2 - 12*e^(sin(x^2 + 1))*sin(x^2 + 1) + cos(x))/(e^(sin(x^2 + 1)) + cos(x))^(3/2) - 5/2*(4*x^2*e^(sin(x^2 + 1))*cos(x^2 + 1)^2 - 4*x^2*e^(sin(x^2 + 1))*sin(x^2 + 1) + 2*e^(sin(x^2 + 1))*cos(x^2 + 1) - cos(x))*(8*x^3*e^(sin(x^2 + 1))*cos(x^2 + 1)^3 - 24*x^3*e^(sin(x^2 + 1))*sin(x^2 + 1)*cos(x^2 + 1) - 8*x^3*e^(sin(x^2 + 1))*cos(x^2 + 1) + 12*x*e^(sin(x^2 + 1))*cos(x^2 + 1)^2 - 12*x*e^(sin(x^2 + 1))*sin(x^2 + 1) + sin(x))/(e^(sin(x^2 + 1)) + cos(x))^(3/2) + 15/4*(2*x*e^(sin(x^2 + 1))*cos(x^2 + 1) - sin(x))^2*(8*x^3*e^(sin(x^2 + 1))*cos(x^2 + 1)^3 - 24*x^3*e^(sin(x^2 + 1))*sin(x^2 + 1)*cos(x^2 + 1) - 8*x^3*e^(sin(x^2 + 1))*cos(x^2 + 1) + 12*x*e^(sin(x^2 + 1))*cos(x^2 + 1)^2 - 12*x*e^(sin(x^2 + 1))*sin(x^2 + 1) + sin(x))/(e^(sin(x^2 + 1)) + cos(x))^(5/2) + 45/8*(2*x*e^(sin(x^2 + 1))*cos(x^2 + 1) - sin(x))*(4*x^2*e^(sin(x^2 + 1))*cos(x^2 + 1)^2 - 4*x^2*e^(sin(x^2 + 1))*sin(x^2 + 1) + 2*e^(sin(x^2 + 1))*cos(x^2 + 1) - cos(x))^2/(e^(sin(x^2 + 1)) + cos(x))^(5/2) - 75/8*(2*x*e^(sin(x^2 + 1))*cos(x^2 + 1) - sin(x))^3*(4*x^2*e^(sin(x^2 + 1))*cos(x^2 + 1)^2 - 4*x^2*e^(sin(x^2 + 1))*sin(x^2 + 1) + 2*e^(sin(x^2 + 1))*cos(x^2 + 1) - cos(x))/(e^(sin(x^2 + 1)) + cos(x))^(7/2) + 105/32*(2*x*e^(sin(x^2 + 1))*cos(x^2 + 1) - sin(x))^5/(e^(sin(x^2 + 1)) + cos(x))^(9/2) + 24/x^5 }}}

To compute the partial derivatives of x2 + 17y2 with respect to x and y, respectively: {{{id=33| f = x^2 + 17*y^2 /// }}} {{{id=53| f.diff(x) /// 2*x }}} {{{id=54| f.diff(y) /// 34*y }}} {{{id=55| g = x^3+x /// }}} {{{id=56| g.diff() /// 3*x^2 + 1 }}} {{{id=57| f.diff() /// Traceback (most recent call last): File "", line 1, in File "_sage_input_52.py", line 10, in exec compile(u'open("___code___.py","w").write("# -*- coding: utf-8 -*-\\n" + _support_.preparse_worksheet_cell(base64.b64decode("Zi5kaWZmKCk="),globals())+"\\n"); execfile(os.path.abspath("___code___.py"))' + '\n', '', 'single') File "", line 1, in File "/tmp/tmpuFM70J/___code___.py", line 2, in exec compile(u'f.diff()' + '\n', '', 'single') File "", line 1, in File "expression.pyx", line 2952, in sage.symbolic.expression.Expression.derivative (sage/symbolic/expression.cpp:15056) File "derivative.pyx", line 213, in sage.misc.derivative.multi_derivative (sage/misc/derivative.c:2349) File "expression.pyx", line 3014, in sage.symbolic.expression.Expression._derivative (sage/symbolic/expression.cpp:15307) ValueError: No differentiation variable specified. }}}

We move on to integrals, both indefinite and definite. To compute the indefinite integral of x sin(x2) and the definite integral, as x goes from 0 to 1, of x/(x2 + 1): {{{id=59| int = integral(x*sin(x^2), x) int /// -1/2*cos(x^2) }}} {{{id=40| diff(int,x) /// x*sin(x^2) }}} {{{id=41| integral(x/(x^2+1), x, 0, 1) /// 1/2*log(2) }}} {{{id=134| integral(sqrt(x)/sqrt(x+1),x) /// sqrt(x + 1)/(((x + 1)/x - 1)*sqrt(x)) + 1/2*log(sqrt(x + 1)/sqrt(x) - 1) - 1/2*log(sqrt(x + 1)/sqrt(x) + 1) }}}

Linear Algebra

Sage provides standard constructions from linear algebra, e.g., the characteristic polynomial, echelon form, trace, decomposition, etc., of a matrix.

Creation of matrices and matrix multiplication is easy and natural:

{{{id=42| A = Matrix([[1,2,3],[3,2,1],[1,1,1]]) w = vector([1,1,-4]) w*A /// (0, 0, 0) }}} {{{id=43| A*w /// (-9, 1, -2) }}}

We create the space Mat3 3(Q):

{{{id=44| M = MatrixSpace(QQ, 3) M /// Full MatrixSpace of 3 by 3 dense matrices over Rational Field }}} (To specify the space of 3 by 4 matrices, you would use MatrixSpace(QQ,3,4). If the number of columns is omitted, it defaults to the number of rows, so MatrixSpace(QQ,3) is a synonym for MatrixSpace(QQ,3,3).)

We create a matrix as an element of M.

{{{id=45| A = M(range(9)) A /// [0 1 2] [3 4 5] [6 7 8] }}}

Next we compute its reduced row echelon form.

{{{id=46| A.echelon_form() /// [ 1 0 -1] [ 0 1 2] [ 0 0 0] }}}

Programming in Sage

Functions, Indentation, and Counting

To define a new function in Sage, use the def command and a colon after the list of variable names. For example: {{{id=47| def is_even(n): return n%2 == 0 /// }}} {{{id=48| is_even(9) /// False }}}

You do not specify the types of any of the input arguments. You can specify multiple inputs, each of which may have an optional default value. For example, the function below defaults to divisor=2 if divisor is not specified.

{{{id=74| def is_divisible_by(number, divisor=2): return number % divisor == 0 /// }}} {{{id=50| is_divisible_by(6, 3) /// True }}}

You can also explicitly specify one or either of the inputs when calling the function; if you specify the inputs explicitly, you can give them in any order: {{{id=76| is_divisible_by(6) /// True }}} {{{id=52| is_divisible_by(divisor = 5, number = 21) /// False }}}

In Python, blocks of code are not indicated by curly braces or begin and end blocks as in many other languages. Instead, blocks of code are indicated by indentation, which must match up exactly. For example, the following is a syntax error because the return statement is not indented the same amount as the other lines above it. {{{id=78| def even(n): v = [] for i in range(3, n): if i % 2 == 0: v.append(i) return v /// }}} {{{id=83| even(9) /// [] }}} If you fix the indentation, the function works: {{{id=80| def even(n): v = [] for i in range(3, n): if i % 2 == 0: v.append(i) return v /// }}} {{{id=84| even(9) /// [4, 6, 8] }}}

Semicolons are not needed at the ends of lines; a line is in most cases ended by a newline. However, you can put multiple statements on one line, separated by semicolons: {{{id=91| a = 5; b = a + 3; c = b^2; c /// 64 }}}

If you would like a single line of code to span multiple lines, use a terminating backslash: {{{id=93| 2 + \ 3 /// 5 }}}

In Sage, you count by iterating over a range of integers. For example, the first line below is exactly like for(i=0; i<3; i++) in C++ or Java: {{{id=95| for i in range(3): print i /// 0 1 2 }}} The first line below is like for(i=2;i<5;i++). {{{id=97| for i in range(2,5): print i /// 2 3 4 }}} The third argument controls the step, so the following is like for(i=1;i<6;i+=2). {{{id=99| for i in range(1, 6, 2): print i /// 1 3 5 }}}

Often you will want to create a nice table to display numbers you have computed using Sage. One easy way to do this is to use string formatting. Below, we create three columns each of width exactly 6 and make a table of squares and cubes.

{{{id=58| for i in range(5): print '%6s %6s %6s'%(i, i^2, i^3) /// 0 0 0 1 1 1 2 4 8 3 9 27 4 16 64 }}}

Lists, Tuples, Sets, Dictionaries

The most basic data structure in Sage is the list, which is -- as the name suggests -- just a list of arbitrary objects. For example, the range command that we used creates a list: {{{id=102| range(2,10) /// [2, 3, 4, 5, 6, 7, 8, 9] }}}

Here is a more complicated list: {{{id=104| v = [1, "hello", 2/3, sin(x^2)] v /// [1, 'hello', 2/3, sin(x^2)] }}}

List indexing is 0-based, as in many programming languages. {{{id=60| v[2] /// 2/3 }}}

Use len(v) to get the length of v, use v.append(obj) to append a new object to the end of v, and use del v[i] to delete the ith entry of v: {{{id=107| len(v) /// 4 }}} {{{id=61| v.append(1.5) v /// [1, 'hello', 2/3, sin(x^2), 1.50000000000000] }}} {{{id=62| del v[1] v /// [1, 2/3, sin(x^2), 1.50000000000000] }}}

Tuples are similar to lists, except they are immutable, meaning once they are created they can't be changed. {{{id=109| v = (1,2,3,4); v /// (1, 2, 3, 4) }}} {{{id=110| type(v) /// }}} {{{id=111| v[1] = 5 /// Traceback (most recent call last): File "", line 1, in File "_sage_input_51.py", line 10, in exec compile(u'open("___code___.py","w").write("# -*- coding: utf-8 -*-\\n" + _support_.preparse_worksheet_cell(base64.b64decode("dlsxXSA9IDU="),globals())+"\\n"); execfile(os.path.abspath("___code___.py"))' + '\n', '', 'single') File "", line 1, in File "/tmp/tmpzNq8rx/___code___.py", line 3, in exec compile(u'v[_sage_const_1 ] = _sage_const_5 ' + '\n', '', 'single') File "", line 1, in TypeError: 'tuple' object does not support item assignment }}} Python has a built-in set type. The main feature it offers is very fast lookup of whether an element is in the set or not, along with standard set-theoretic operations. {{{id=65| X = set([1,19,'a']); Y = set([1,1,1,2/3]) Y /// set([1, 2/3]) }}} {{{id=66| 'a' in X /// True }}} {{{id=119| 'a' in Y /// False }}} {{{id=113| X.intersection(Y) /// set([1]) }}}

Sage also has its own set type that is (in some cases) implemented using the built-in Python set type, but has a little bit of extra Sage-related functionality. Create a Sage set using Set(...). For example, {{{id=115| X = Set([1,1,1,2/3]) X /// {1, 2/3} }}} {{{id=116| 1 in X /// True }}} {{{id=117| X.intersection(Set([1])) /// {1} }}}

Another important data structure is the dictionary (or associative array). This works like a list, except that it can be indexed with almost any object (the indices must be immutable): {{{id=67| d = {'hi':-2, 3/8:pi, e:pi} /// }}} {{{id=68| d[3/8] /// pi }}}

Iterators

Iterators are a recent addition to Python that are particularly useful in mathematics applications. We make an iterator over the squares of the nonnegative integers up to $ 10000000$ {{{id=125| v = (n^2 for n in xrange(10000000)) /// }}} {{{id=126| v.next() /// 0 }}} {{{id=127| v.next() /// 1 }}} {{{id=128| v.next() /// 4 }}}

Control Statements

While {{{id=69| a, b = 0, 1 while b < 1000: print b, a, b = b, a+b /// 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 }}}

and if. {{{id=70| def test(y): if y < 0: print "negative" elif y == 0: print "zero" elif y == 1: print "one" else: print "other" /// }}} {{{id=71| test(1) /// one }}} {{{id=133| test(-1) /// negative }}}

Exporting Worksheets and Shutting Down the Sage Server

File -> Download to a file

Ctrl-C in the console.

{{{id=132| /// }}}