Input and Output

There are several aspects of input and output that can be studied in Mathematica. Standard input and output is handled via the notebook interface of Mathematica and both input and output are usually given as Mathematica expressions, i.e. a function (program) is called by evaluating a Mathematica expression and a result is returned in form of a Mathematica expression. Topics to be treated in this section will be:

Intermediate input and output during program evaluation.

Formatted input and output.

File input and output.

Intermediate Input and Output

Input

The usual way to pass input to a program is by passing parameters when calling the function. However, a program might sometimes want to ask the user for input. This can be done using Input, which will initiate a dialog with the user.

a=Input["Please enter a value:"];

a

The actual appearance of the dialog window depends on the platform, on which Mathematica is running, but it is guaranteed to work on any Mathematica–compatible platform. The only possibility to influence the dialog window is the label that can be specified in the parameter.

Output

Intermediate output during evaluation can be made using Print. Print prints all its arguments directly to the screen, without any separating blanks, etc.

Print[a," ",1]

Print[1,2]

When printing text, it is possible to setup a text fragment, into which certain values are inserted at certain positions. For this we use StringForm.

Print[StringForm["The value of \"``\" is ``.",Unevaluated[a],a]]

Print[StringForm["The value of \"`1`\" is `1`.",Unevaluated[a]]]

Note, that Print does not return any value, it only prints the expressions to the screen as a side–effect. Thus, when returning a value from a program, do not wrap the last statement into Print, since then the program will only print the value to the screen but not return it as a result (although, on the screen, it hardly makes a difference!).

Strings

Strings are a basic data–structure in Mathematica. There are various operations for string manipulation available, see the manual. In addition to output as shown above, strings offer a possibility to keep expressions unevaluated by converting them to string form. Conversion between Mathematica expressions and strings is done by ToString and ToExpression, respectively.

s=ToString[Unevaluated[a=14]]

s

FullForm[s]

ToExpression[s]

a

Formatted Input and Output

Input

In this section we want to describe how formatted mathematical expressions can be processed by the Mathematica FrontEnd. For many of the standard notations in mathematics Mathematica provides support for both input and output.

(b^2)

(7/6)

FullForm[(b^2)]

Power[b,2]

Some notations are even supported, which have no predefined meaning.

b⊕c

b⊕c⊕d//FullForm

??CirclePlus

For giving a meaning to the expression b⊕c it is sufficient to give appropriate definitions for CirclePlus. However, some maybe desirable notations are not known to Mathematica.

(∫_D)f[x]\[DifferentialD]x

Cell[BoxData[
 RowBox[{
  UnderscriptBox["∫", "D"], 
  RowBox[{
   RowBox[{"f", "[", "x", "]"}], 
   RowBox[{"\[DifferentialD]", "x"}]}]}]], "Input",
 CellChangeTimes->{3.420968420707957*^9},
 EmphasizeSyntaxErrors->True]

The Mathematica FrontEnd allows the user to define new mathematical notations.

Box–Structure of Two–Dimensional Expressions

Two–dimensional input and output are based on a box–representation of two–dimensional expressions. Strings are essentially linear expressions, i.e. one character next to the other, and are therefore not expressive enough to capture two–dimensional expressions. Mathematica cells represent their content grouped into boxes, whose type contains information about how the ingredient expressions are positioned, e.g.

a RowBox tells that the ingredient expressions are positioned in a horizontal row,

a SuperscriptBox tells that the ingredient expressions are positioned as basis and superscript,

a GridBox tells that the ingredient expressions are positioned in a grid,

etc.

In order to get some feeling how expressions are represented as boxes, we inspect the box structure of some well–known expressions.

ToBoxes[Unevaluated[1+1]]//FullForm

ToBoxes[Unevaluated[(Subscript[a, 1])+(b^2)+(Sqrt[3])-a/b]]//FullForm

ToBoxes[(Overscript[a, 4])]//FullForm

Note, that box expressions are "normal" Mathematica expressions and all atomic parts of the box expression are represented as strings.

Clear[a]

Parsing Box Expressions

The process of interpreting user input is called parsing. In the Mathematica FrontEnd, parsing happens in two phases:

First, the user input is split into boxes, e.g. "1+1" is split into RowBox[List["1","+","1"]] .

Then, the box structure is translated into the corresponding Mathematica expression, e.g. RowBox[List["1","+","1"]] is turned into Plus[1,1], which will then be sent to the kernel for evaluation.

The translation from boxes to Mathematica expressions is done by MakeExpression, which is intended to be extended by user definitions. If, for certain input, Mathematica does not know how to parse the expression or parses it in an undesired way, then a new definition for MakeExpression might solve the problem. In order to find out the exact box structure of an expression like e.g.

(∫_D)f[x]\[DifferentialD]x

one must look at the "internal structure" of the input cell. For this, select the cell and choose "Format -> Show Expression", which will reveal the internal form of the expression.

Cell[BoxData[
    RowBox[{
      UnderscriptBox["∫", "D"], 
      RowBox[{
        RowBox[{"f", "[", "x", "]"}], 
        RowBox[{"\[DifferentialD]", "x"}]}]}]], "Input"]

Suppose you want to have (∫_D)f[x]dx interpreted as DomainIntegral[f[x],x,D]. What you need to do is to define a rule for MakeExpression, which says: "Parse (∫_D)f[x]dx as if you would parse DomainIntegral[f[x],x,D]". It is important to implement the new syntax rule using a recursive call of MakeExpression, which goes back to the built–in MakeExpression definitions.

ToBoxes[DomainIntegral[f[x],x,D]]//FullForm

MakeExpression[RowBox[{UnderscriptBox["∫",dom_],RowBox[{expr_,RowBox[{"\[DifferentialD]",var_}]}]}],StandardForm]:=MakeExpression[RowBox[{"DomainIntegral","[",RowBox[{expr,",",var,",",dom}],"]"}],StandardForm]

(∫_D)f[x]\[DifferentialD]x

(∫_D)f[x]\[DifferentialD]x

MakeExpression[RowBox[{UnderscriptBox["∫",dom_],RowBox[{expr_,RowBox[{"\[DifferentialD]",var_}]}]}],TraditionalForm]:=MakeExpression[RowBox[{"DomainIntegral","[",RowBox[{expr,",",var,",",dom}],"]"}],TraditionalForm]

(∫_D)f(x)\[DifferentialD]x

Output

Number Formatting

Various forms of formatting are available for numbers, e.g. NumberForm, EngineeringForm, ScientificForm, etc.

EngineeringForm[(10.0^10)]

ScientificForm[(10.0^10)]

Print[StringForm["The value of 100000*π is ``.",ScientificForm[N[100000π]]]]

Print[StringForm["The value of 100000*π is ``.",EngineeringForm[N[100000π]]]]

Print[StringForm["The value of 100000*π is ``.",NumberForm[N[100000π],10]]]

Expression Formatting

As we have already seen above, even Print allows some formatted output, i.e. it is not restricted to just string output.

Print["Formatted expression: ",(b^2)]

Print[StyleForm["Formatted expression: ",FontColor->RGBColor[1,0,0],FontFamily->"Times"],(b^2)]

Print[StyleForm[StringForm["Formatted expression: ``",(b^2)],FontColor->RGBColor[1,0,0],FontFamily->"Times"]]

Now we want to investigate how expressions can be formatted when they are displayed. Suppose you want every sum expression to be written in its TreeForm.

TreeForm[Unevaluated[1+(4*5)]]

Unprotect[Plus];

Format[poly_Plus]:=TreeForm[poly]

3(x^2)+5(x^4)

Clear[Plus]

Similar to TreeForm, there are various other format types, like e.g. TraditionalForm, TableForm, MatrixForm, etc. that can be used in Format. We show some of the possibilities of TableForm in an example for printing the operation table of (Subscript[ℤ, 5]) w.r.t. Plus.

TableForm[Array[Mod[#1+#2,5]&,{5,5},{0,0}],TableHeadings->{Range[0,4],Range[0,4]},TableSpacing->{0.5,2}]

As another example, suppose we have a data structure Vec[a], which represents the vector a  and we want Vec[a] to display as (OverVector[a]). Note, that a vector symbol can be put over an expression by OverVector.

(OverVector[b])//FullForm

(OverVector[b])

Format[Vec[a_]]:=OverVector[a]

Vec[a]

Vec[Vec[a]]

Using Format we can easily produce expressions that can be generated by some Mathematica function. Note also, that Format is applied recursively to the result it produces. If we want to produce arbitrary two–dimensional expressions, we need to generate the box structure explicitly and display the boxes using DisplayForm. As an example, suppose we want to display Vec[a] as (Overscript[a, ->]).

Clear[Vec]

Format[Vec[a_]]:=DisplayForm[OverscriptBox[a,"->"]]

Vec[a]

Vec[Vec[a]]

When specifying the box structure directly, one might consider to use the underlying low–level formatting operation MakeBoxes directly, which converts an expression to a box expression. Essentially, it is the same like above only that one saves to apply DisplayForm. The most important differences to Format are, that MakeBoxes does not evaluate its arguments and it does not automatically apply recursively on the resulting expression. In some sense, MakeBoxes is the opposite to MakeExpression. Suppose we want to define a nice output format for DomainIntegral in StandardForm.

(∫_D)f[x]\[DifferentialD]x

MakeBoxes[DomainIntegral[f_,v_,dom_],StandardForm]:=RowBox[{UnderscriptBox["∫",dom],ToBoxes[f,TraditionalForm],RowBox[{"d",v}]}]

(∫_D)f[x]\[DifferentialD]x

(∫_(G[t,x]))f[x]\[DifferentialD]x[t]

This is because we need to transform the ingredient expressions to box form explicitly.

MakeBoxes[DomainIntegral[f_,v_,dom_],StandardForm]:=RowBox[{UnderscriptBox["∫",ToBoxes[dom,TraditionalForm]],ToBoxes[f,TraditionalForm],RowBox[{"d",ToBoxes[v,TraditionalForm]}]}]

(∫_D)f[x]\[DifferentialD]x

(∫_(G[t,x]))f[x]\[DifferentialD]x[t]

File Input and Output

Accessing the File System

When working with external files, we need access to the underlying file system of the computer. Independently of the operationg system, on which Mathematica is running, there are certain commands for communicating with the file system. Mathematica always maintains a current directory, which gives the location of external files in case their name is not specified as an absolute path.

Directory[]

When specifying absolute path names, we suggest to use ToFileName instead of a single string. This makes programs platform independent, because ToFileName composes the string just in the way appropriate for the operating system, on which the program is executed.

SetDirectory[ToFileName[{"Teaching","ProgrammierenInMathematica","Skriptum"}]]

(Of course, the path above needs to be adjusted for your personal settings on the computer where you run the commands in this section!)

Output

We discuss file output first, because we can then write data to some files and read them back into Mathematica later.

Writing Mathematica Expressions

The operator >> redirects any Mathematica output to a file. Usually, files containing Mathematica expressions have the file extension ".m".

Sin[2.3] (x^2)>>out.m

If the file already existed, it will be overwritten. For appending to an existing file, we use >>>.

Sin[2.3] y>>>out.m

!!out.m

We can use Save for saving definitions into a file.

y=10;
f[x_]:=x+y

Save["def.m",f]

!!def.m

Clear[f,y]

Writing Arbitrary Text

stream=OpenWrite["data1.txt"]

Do[
Write[stream,Random[Integer,{0,20}]],{10}]

Write[stream,"some more text\tand more"]

FilePrint["data1.txt"]

Close[stream]

For writing strings (without the quotes) to the file, we better use WriteString.

stream=OpenWrite["data2.dat"]

Do[
WriteString[stream,Random[Integer,{1,20}],"\t",Random[Integer,{1,20}],"\n"],{10}]

!!data2.dat

Close[stream]

For specialized known formats (like CSV, Text, etc.) we can use Export. We refer to the manual for further detail.

Input

When reading data from a file, Mathematica does not only look for the file in the current directory. Rather, it searches all directories in the path.

$Path

FilePrint["out.m"]

Reading Mathematica Expressions

For reading Mathematica expressions from a file we use the operator <<.

t=<<out.m

t

<<data2.dat

All data in the file is interpreted as a Mathematica expression, which will be evaluated and its result is read into the current session.

Clear[f,y]

f[2]

<<def.m

f[2]

?f

Reading Arbitrary Text

FilePrint["data1.txt"]

stream=OpenRead["data1.txt"]

Read[stream]

Read[stream,Number]

Read[stream,{Number,Number}]

While[Skip[stream,Number]===Null]

Read[stream,Character]

Read[stream,Character]

Read[stream,String]

Close[stream]

Reading Structered Text

For structured textual data to be read into the current session we might want to use ReadList.

ReadList["data1.txt",Number]

ReadList["data2.dat",{Number,Number,Number}]

ReadList["data2.dat",{Number,Number},3]

ReadList["data2.dat",Number,RecordLists->True]

For many known file formats (like CSV, Text, etc.) we can use Import in order to read the data into an appropriate Mathematica expression.

Import["data2.dat","Table"]

Exercise: Formatted Input and Output for Periodic Decimal Numbers

Take the datastructure for periodic decimal numbers implemented in an earlier exercise and add formatted input and output for this datastructure. As an example, we might want to input periodic decimal numbers in the form

0.01(OverBar[428571])

Implement the necessary functions such that input in the above style is translated into a Mathematica expression representing a periodic decimal number as implemented in the earlier exercise. Furthermore, provide also formatted output for periodic decimal numbers in the same style such that formatted output can be used as input also. Of course, you can support also any other "nice" format for entering periodic decimal numbers, the above is only a suggestion!

Solution: see separate notebook.