Printing

Contents

The print-Statement

print expression;
print expression, ..., expression;
print expression : parameters;
Print the value of the expression. Some limited ways of formatting output are described in the section on strings. Four levels of printing (that may in specific cases coincide) exist, and may be indicated after the colon: Default (which is the same as the level obtained if no level is indicated), Minimal, Maximal, and Magma. The last of these produces output representing the value of the identifier as valid Magma-input (when possible).

Formatted Printing

printf format, expression, ..., expression;
Print values of the expressions under control of format. The first argument, the format string, must be a string which contains two types of objects: plain characters, which are simply printed, and conversion specifications (indicated by the % character), each of which causes conversion and printing of zero or more of the expressions. (Use %% to get a literal percent character.) Currently, the only conversion specifications allowed are: %o and %O, which stand for "object", %m, which stands for "magma", and %h, which stands for "hexadecimal".

The hexadecimal conversion specification will print its argument in hexadecimal; currently, it only supports integer arguments. The object and magma conversion specifications each print the corresponding argument; they differ only in the printing mode used. The %o form uses the default printing mode, while the %O form uses the printing mode specified by the next argument (as a string). The "magma" conversion specification uses a printing mode of Magma. It is thus equivalent to (but shorter than) using %O and an extra argument of "Magma".

For each of these conversion specifications, the object can be printed in a field of a particular width by placing extra characters immediately after the % character: digits describing a positive integer, specifying a field with width equal to that number and with right-justification; digits describing a negative integer, specifying a field with width equal to the absolute value of the number and with left-justification; or the character * specifying a field width given by the next appropriate expression argument (with justification determined by the sign of the number). This statement is thus like the C language function printf(), except that %o (and %O and %m) covers all kinds of objects --- it is not necessary to have different conversion specifications for the different types of Magma objects. Note also that this statement does not print a newline character after its arguments while the print statement does (a \n character should be placed in the format string if this is desired). A newline character will be printed just before the next prompt, though, if there is an incomplete line at that point.

Example IO_printf (H3E4)

The following statements demonstrate simple uses of printf.
> for i := 1 to 150 by 33 do printf "[%3o]\n", i; end for;
[  1]
[ 34]
[ 67]
[100]
[133]
> for i := 1 to 150 by 33 do printf "[%-3o]\n", i; end for;
[1  ]
[34 ]
[67 ]
[100]
[133]
> for w := 1 to 5 do printf "[%*o]", w, 1; end for;
[1][ 1][  1][   1][    1]

Example IO_printf2 (H3E5)

Some further uses of the printf statement are illustrated below.
> x := 3;
> y := 4;
> printf "x = %o, y = %o\n", x, y;
x = 3, y = 4
> printf "G'"; printf "day";
G'day
> p := 53.211;
> x := 123.2;
> printf "%.3o%% of %.2o is %.3o\n", p, x, p/100.0 * x;
53.211
> Zx<x> := PolynomialRing(Integers());
> printf "%O\n", x, "Magma";
Polynomial(\[0, 1])
fprintf file, format, expression, ..., expression;
Print values of the expressions under control of format into the file given by file. The first argument file must be either a string specifying a file which can be opened for appending (tilde expansion is performed on the filename), or a file object (see the section below on external files) opened for writing. The rest of the arguments are exactly as in the printf statement. In the string (filename) case, the file is opened for appending, the string obtained from the formatted printing of the other arguments is appended to the file, and the file is closed. In the file object case, the string obtained from the formatted printing of the other arguments is simply appended to the file. Note that this statement, like printf, does not print a newline character after its arguments (a \n character should be placed in the format string if this is desired).

Example IO_fprintf (H3E6)

The following statements demonstrate a (rather contrived) use of fprintf with a file pipe.
> p := 1000000000000000000000000000057;
> F := POpen("sort -n", "w");
> for i := 100 to 110 do
>    fprintf F, "%30o (2^%o mod p)\n", 2^i mod p, i;
> end for;
> // Close F and then see output on standard output:
> delete F;
 37107316853453566312041115519 (2^109 mod p)
 70602400912917605986812821219 (2^102 mod p)
 74214633706907132624082231038 (2^110 mod p)
129638414606681695789005139447 (2^106 mod p)
141204801825835211973625642438 (2^103 mod p)
259276829213363391578010278894 (2^107 mod p)
267650600228229401496703205319 (2^100 mod p)
282409603651670423947251284876 (2^104 mod p)
518553658426726783156020557788 (2^108 mod p)
535301200456458802993406410638 (2^101 mod p)
564819207303340847894502569752 (2^105 mod p)

Verbose Printing

The following statements allow convenient printing of information conditioned by whether an appropriate verbose flag is turned on.

vprint flag: expression, ..., expression;
vprint flag, n: expression, ..., expression;
If the verbose flag flag (see the function SetVerbose) has a level greater than or equal to n, print the expressions to the right of the colon exactly as in the print statement. If the flag has level 0 (i.e. is not turned on), do nothing. In the first form of this statement, where a specific level is not given, n is taken to be 1. This statement is useful in Magma code found in packages where one wants to print verbose information if an appropriate verbose flag is turned on.
vprintf flag: format, expression, ..., expression;
vprintf flag, n: format, expression, ..., expression;
If the verbose flag flag (see the function SetVerbose) has a level greater than or equal to n, print using the format and the expressions to the right of the colon exactly as in the printf statement. If the flag has level 0 (i.e. is not turned on), do nothing. In the first form of this statement, where a specific level is not given, n is taken to be 1. This statement is useful in Magma code found in packages where one wants to print verbose information if an appropriate verbose flag is turned on.

Automatic Printing

Magma allows automatic printing of expressions: basically, a statement consisting of an expression (or list of expressions) alone is taken as a shorthand for the print-statement.

Some subtleties are involved in understanding the precise behaviour of Magma in interpreting lone expressions as statements. The rules Magma follows are outlined here. In the following, a call-form means any expression of the form f((arguments)); that is, anything which could be a procedure call or a function call.

(a)
Any single expression followed by a semicolon which is not a call-form is printed, just as if you had `print' in front of it.
(b)
For a single call-form followed by a semicolon (which could be a function call or procedure call), the first signature which matches the input arguments is taken and if that is procedural, the whole call is taken as a procedure call, otherwise it is taken as function call and the results are printed.
(c)
A comma-separated list of any expressions is printed, just as if you had `print' in front of it. Here any call-form is taken as a function call only so procedure calls are impossible.
(d)
A print level modifier is allowed after an expression list (whether the list has length 1 or more). Again any call-form is taken as a function call only so procedure calls are impossible.
(e)
Any list of objects printed, whether by any of the above rules or by the `print' statement, is placed in the previous value buffer. $1 gives the last printed list, $2 the one before, etc. Note that multi-return values stay as a list of values in the previous value buffer. The only way to get at the individual values of such a list is by assignment to a list of identifiers, or by where (this is of course the only way to get the second result out of Quotrem, etc.). In other places, a $1 expression is evaluated with principal value semantics.

Magma also provides procedures to manipulate the previous value buffer in which $1, etc. are stored.

ShowPrevious() : ->
Show all the previous values stored. This does not change the contents of the previous value buffer.
ShowPrevious(i) : RngIntElt ->
Show the i-th previous value stored. This does not change the contents of the previous value buffer.
ClearPrevious() : ->
Clear all the previous values stored. This is useful for ensuring that no more memory is used than that referred to by the current identifiers.
SetPreviousSize(n) : RngIntElt ->
Set the size of the previous value buffer (this is not how many values are defined in it at the moment, but the maximum number that will be stored). The default size is 3.
GetPreviousSize() : -> RngIntElt
Return the size of the previous value buffer.

Example IO_auto-print (H3E7)

Examples which illustrate point (a):
> 1;
1
> x := 3;
> x;
3
Examples which illustrate point (b):
> 1 + 1;            // really function call '+'(1, 1)
2
> Q := [ 0 ];
> Append(~Q, 1);    // first (in fact only) match is procedure call
> Append(Q, 1);     // first (in fact only) match is function call
[ 0, 1, 1 ]
> // Assuming fp is assigned to a procedure or function:
> fp(x);            // whichever fp is at runtime
> SetVerbose("Meataxe", true);  // simple procedure call
Examples which illustrate point (c):
> 1, 2;
1 2
> // Assuming f assigned:
> f(x), 1;                            // f only can be a function
> SetVerbose("Meataxe", true), 1;     // type error in 'SetVerbose'
> // (since no function form)
Examples which illustrate point (d):
> 1: Magma;
1
> Sym(3), []: Maximal;
Symmetric group acting on a set of cardinality 3
Order = 6 = 2 * 3
[]
> SetVerbose("Meataxe", true): Magma; // type error as above
Examples which illustrate point (e):
> 1;
1
> $1;
1
> 2, 3;
2 3
> $1;
2 3
> Quotrem(124124, 123);
1009 17
> $1;
1009 17
> a, b := $1;
> a;
1009

Indentation

Magma has an indentation level which determines how many initial spaces should be printed before each line. The level can be increased or decreased. Each time the top level of Magma is reached (i.e. a prompt is printed), the level is reset to 0. The level is usually changed in verbose output of recursive functions and procedures. The functions SetIndent and GetIndent are used to control and examine the number of spaces used for each indentation level (default 4).

IndentPush() : ->
Increase (push) the indentation level by 1. Thus the beginning of a line will have s more spaces than before, where s is the current number of indentation spaces.
IndentPush(C) : RngIntElt ->
Increases the indentation level by C.
IndentPop() : ->
Decrease (pop) the indentation level by 1. Thus the beginning of a line will have s fewer spaces than before, where s is the current number of indentation spaces. If the current level is already 0, an error occurs.
IndentPop(C) : RngIntElt ->
Decreases the indent level by C.

Printing to a File

PrintFile(F, x) : MonStgElt, Any ->
Write(F, x) : MonStgElt, Any ->
    Overwrite: BoolElt                  Default: false
Print x to the file specified by the string F. If this file already exists, the output will be appended, unless the optional parameter Overwrite is set to true, in which case the file is overwritten.
WriteBinary(F, s) : MonStgElt, BStgElt ->
    Overwrite: BoolElt                  Default: false
Write the binary string s to the file specified by the string F. If this file already exists, the output will be appended, unless the optional parameter Overwrite is set to true, in which case the file is overwritten.
PrintFile(F, x, L) : MonStgElt, Any, MonStgElt ->
Write(F, x, L) : MonStgElt, Any, MonStgElt ->
    Overwrite: BoolElt                  Default: false
Print x in format defined by the string L to the file specified by the string F. If this file already exists, the output will be appended unless the optional parameter Overwrite is set to true, in which case the file is overwritten. The level L can be any of the print levels on the print command above (i.e., it must be one of the strings "Default", "Minimal", "Maximal", or "Magma").
PrintFileMagma(F, x) : MonStgElt, Any ->
    Overwrite: BoolElt                  Default: false
Print x in Magma format to the file specified by the string F. If this file already exists, the output will be appended, unless the optional parameter Overwrite is set to true, in which case the file is overwritten.

Printing to a String

Magma allows the user to obtain the string corresponding to the output obtained when printing an object by means of the Sprint function. The Sprintf function allows formatted printing like the printf statement.

Sprint(x) : Elt -> MonStgElt
Sprint(x, L) : Elt, MonStgElt -> MonStgElt
Given any Magma object x, this function returns a string containing the output obtained when x is printed. If a print level L is given also (a string), the printing is done according to that level (see the print statement for the possible printing levels).
Sprintf(F, ...) : MonStgElt, ... -> MonStgElt
Given a format string F, together with appropriate extra arguments corresponding to F, return the string resulting from the formatted printing of F and the arguments. The format string F and arguments should be exactly as for the printf statement -- see that statement for details.

Example IO_Sprintf (H3E8)

We demonstrate elementary uses of Sprintf.
> Q := [Sprintf("{%4o<->%-4o}", x, x): x in [1,10,100,1000]];
> Q;
[ {   1<->1   }, {  10<->10  }, { 100<->100 }, {1000<->1000} ]

Redirecting Output

SetOutputFile(F) : MonStgElt ->
    Overwrite: BoolElt                  Default: false
Redirect all Magma output to the file specified by the string F. By using SetOutputFile(F: Overwrite := true) the file F is emptied before output is written onto it.
UnsetOutputFile() : ->
Close the output file, so that output will be directed to standard output again.
HasOutputFile() : -> BoolElt
If Magma currently has an output or log file F, return true and F; otherwise return false.
V2.28, 13 July 2023