# I/O — input and output¶

How are expressions interpreted? How can I represent expressions nicely?

Fractions are represented in simplified form:

In [1]:

    4/2

Out[1]:

    2

If we enforce enumerators and denominators as python integers, the result is zero.

In [2]:

    int(1)/int(3)

Out[2]:

    0

If we don't enforce python integers, sage integers will be used. Sage integers give rational results for division:

In [3]:

    1/3

Out[3]:

    1/3

But how does it work? In python ‘1/3’ is the division of python integers. How is ‘1/3’ is different in sagemath? ‘preparse’ reveals the secret:

In [4]:

    preparse("1/3")

Out[4]:

    'Integer(1)/Integer(3)'

Constants are replaced by sagemath. Integers are replaced with ‘Integer’ instances by sagemath. So, ‘int’ is the integer class of python…

In [5]:

    int

Out[5]:

    <type 'int'>

… whereas ‘Integer’ is the integer class of sagemath. ‘Integer’ instances are - in general - more sophisticated than python's integers. ‘Integer’ instances are embebbed in the algebraic infrastructure of sagemath.

In [6]:

    Integer

Out[6]:

    <type 'sage.rings.integer.Integer'>

This is relevant if you use ‘range’.
‘range’ is a common python function to generate a sequence of numbers.
‘range’ returns ‘int’ instances…

In [7]:

    type(range(10)[0])

Out[7]:

    <type 'int'>

… whereas sagemath's ‘srange’ returns sagemath integers:

In [8]:

    type(srange(10)[0])

Out[8]:

    <type 'sage.rings.integer.Integer'>

Instead of calling ‘int()’ to instantiate python integers, you can also append a ‘r’:

In [9]:

    print(preparse('2r'))
    print(type(2r))

    2
    <type 'int'>

Now we can also inspect more complex expressions from before. The syntax is invalid in python, but we can inspect how sagemath rewrites expressions for python:

In [10]:

    preparse('R.<x> = PolynomialRing(QQ)')

Out[10]:

    "R = PolynomialRing(QQ, names=('x',)); (x,) = R._first_ngens(1)"

‘x’ is a predefined, symbolic variable (besides ‘oo’, ‘e’, ‘i’ and many classes):

In [11]:

    x

Out[11]:

    x

It represents a symbolic expression:

In [12]:

    type(x)

Out[12]:

    <type 'sage.symbolic.expression.Expression'>

We can also define our own symbolic variable. Unlike ‘x’, ‘y’ is not predefined:

In [13]:

    var('y', domain='complex')

Out[13]:

    y

Here we see how symbolic variables can be combined with other expressions and those expressions can be simplified or expanded according to mathematical laws:

In [14]:

    expr = (4 + y^2) * (4 + 3 + y^2)
    print(expr.simplify())
    print(expr.expand())

    (y^2 + 7)*(y^2 + 4)
    y^4 + 11*y^2 + 28

Given some expression, we can also call a symbolic expression with keyword arguments like `a=3` to substitute symbolic variables with values:

In [15]:

    var('x a b c')
    expr = (a * x^2 + b * x + c)(a=3, b=5/99, c=pi)
    expr

Out[15]:

    pi + 3*x^2 + 5/99*x

‘show()’ enforces a more beautiful rendering in the browser (MathJax library)

In [16]:

    show(expr)

The default display mode is ‘plain’ and gives plain text representations:

In [17]:

    %display plain
    1/2

Out[17]:

    1/2

With display mode ‘typeset’ the MathJax rendering engine is used for all representations that follow:

In [18]:

    %display typeset
    1/2

Out[18]:

We can ask for a list of display mode by asking the documentation:

In [19]:

    %display?

    Docstring:
       A magic command to switch between simple display and ASCII art
       display.

       * "args" -- string.  See
         "sage.misc.display_hook.DisplayHookBase.set_display()" for
         allowed values. If the mode is "ascii_art", it can optionally be
         followed by a width.

       How to use: if you want activate the ASCII art mod:

          sage: from sage.repl.interpreter import get_test_shell
          sage: shell = get_test_shell()
          sage: shell.run_cell('%display ascii_art')

       That means you don't have to use "ascii_art()" to get an ASCII art
       output:

          sage: shell.run_cell("i = var('i')")
          sage: shell.run_cell('sum(i^2*x^i, i, 0, 10)')
               10       9       8       7       6       5       4      3      2
          100*x   + 81*x  + 64*x  + 49*x  + 36*x  + 25*x  + 16*x  + 9*x  + 4*x  + x

       Then when you want return in 'textual mode':

          sage: shell.run_cell('%display text plain')
          sage: shell.run_cell('%display plain')        # shortcut for "text plain"
          sage: shell.run_cell('sum(i^2*x^i, i, 0, 10)')
          100*x^10 + 81*x^9 + 64*x^8 + 49*x^7 + 36*x^6 + 25*x^5 + 16*x^4 + 9*x^3 + 4*x^2 + x

       Sometime you could have to use a special output width and you could
       specify it:

          sage: shell.run_cell('%display ascii_art')
          sage: shell.run_cell('StandardTableaux(4).list()')
          [
          [                                                                  1  4
          [                 1  3  4    1  2  4    1  2  3    1  3    1  2    2
          [   1  2  3  4,   2      ,   3      ,   4      ,   2  4,   3  4,   3   ,

                             1 ]
             1  3    1  2    2 ]
             2       3       3 ]
             4   ,   4   ,   4 ]
          sage: shell.run_cell('%display ascii_art 50')
          sage: shell.run_cell('StandardTableaux(4).list()')
          [
          [
          [                 1  3  4    1  2  4    1  2  3
          [   1  2  3  4,   2      ,   3      ,   4      ,

                                                    1 ]
                            1  4    1  3    1  2    2 ]
            1  3    1  2    2       2       3       3 ]
            2  4,   3  4,   3   ,   4   ,   4   ,   4 ]

       As yet another option, typeset mode. This is used in the emacs
       interface:

          sage: shell.run_cell('%display text latex')
          sage: shell.run_cell('1/2')
          newcommand{Bold}[1]{mathbf{#1}}frac{1}{2}

       Switch back:

          sage: shell.run_cell('%display default')

       Switch graphics to default to vector or raster graphics file
       formats:

          sage: shell.run_cell('%display graphics vector')
    File:      ~/Notebooks/</home/sage/sage/local/lib/python2.7/site-packages/decorator.pyc:decorator-gen-126>

‘ascii_art’ is probably an amusing one, but maybe helpful if you run sagemath in a terminal:

In [20]:

    %display ascii_art
    x^5 + 4/5*x + 25^x

Out[20]:

      x    5   4*x
    25  + x  + ---
                5

Let's switch back to typeset display mode:

In [21]:

    %display typeset

We consider a matrix representation example.

‘print()’ and ‘show()’ give different results, because

- ‘print()’ desires the python style plaintext representation
- ‘show()’ desires the MathJax rendered typeset representation

In [22]:

    print(matrix.hilbert(3))
    show(matrix.hilbert(3))

    [  1 1/2 1/3]
    [1/2 1/3 1/4]
    [1/3 1/4 1/5]

If you want to enable ‘%display typeset‘ globally (i.e. in a startup configuration file), don't use ‘%display typeset’ but the ‘pretty_print_default’ function.

In [23]:

    pretty_print_default(True)

sagemath can also print arbitrary LaTeχ expressions:

In [24]:

    LatexExpr("\int x \cos(x) dx")

Out[24]:

You can also make entire cells to be LaTeχ input:

In [25]:

    %%latex
    Kleiner Gauß: $\frac{n(n-1)}2$

Kleiner Gauß: $\frac{n(n-1)}2$

Given any expression, call ‘latex()’ to retrieve its LaTeχ representation:

In [26]:

    print(latex(5*x^2 + 1/4*x))

    5 \, x^{2} + \frac{1}{4} \, x

This is possible, because every sagemath object implements the method ‘_latex_’:

In [27]:

    pi._latex_()

Out[27]:

‘view’ is another representation function. It calls LaTeχ itself to render an expression. LaTeχ is not installed on this particular docker image and hence an error is displayed.

In [28]:

    view(3*x+5/6*x)

    Error: PDFLaTeX does not seem to be installed.  Download it from
    ctan.org and try again.
    Latex error