Kurs  Cours

14. Input und Output
 Input et output

Die Gliederung dieses Kurses folgt in groben Zügen dem Buch von Nancy Blachman: A Practical Approach.... 
Hinweis: Kapitel 14 lesen!
 L'articulation de ce cours correspond à peu près à celle du livre de Nancy Blachman: A Practical Approach.... 
Indication: Lire le chapitre 14.
WIR94/98/99 // Copyright Rolf Wirz

Problem: Datenimport und Datenexport in und von Mathematica.
  Problème: Importation et exportation de données dans et de Mathematica.

14.1. Input
       Input

14.1.1. Dateneingabe via Tastatur während des
Programmlauf
 Entrée des données par les touches pendant que le programme marche

Studiere:    Etudie:

?Input

?InputString

?BaseForm

BaseForm[15,2]+BaseForm[17,2]

benutzerInput = Input[
"Schreibe eine Zahl zwischen 1 und 10: \
Ecris un nombre entre 1 et 10:"]

Achtung: Das nachfolgende Programm bricht erst ab, wenn keine Integer-Zahl eingegeben wird! Probiere:
  Attention: Le programme suivant s'interrompt seulement si on n'entre pas le nombre Integer! Essaie:

dualUmwandlung:=
	Module[{
			benutzerInput},
			While[
				IntegerQ[
					userInput = Input[
	"Schreibe eine Zahl zwischen 1 und 10: \
	Ecris un nombre entre 1 et 10:"]
						],
				Print[userInput, " = ",
						BaseForm[userInput, 2]]
			]
	];

dualUmwandlung

14.1.2. Datenimport von einem File
         Importation de données d'un fichier
        
Achtung: Achte auf das zu deinem Betriebssystem lauffähige Beispiel! 
Der Umgang mit externen Dateien von Mathematica aus hat ab Version 3.0 eine grosse Veränderung erfahren!
 Attention: Prends seulement les exemples qui tournent sur ton propre système! 
Le traitement des fichiers externes depuis Mathematica a beaucoup changé depuis la version 3.0!

Beispiel:
(Das File AAAdaten) befindet sich wahrscheinlich in Deinem Verzeichnis C:\Programme\WolframResearch\Mathematica\3.0 (win98). - Sonst musst Du Deinen mir nicht bekannten Pfad suchen!)
  Exemple:
(Le file AAAdanten.nb (aadaten.ma)  se trouve probablement dans le directoire C:\Programme\WolframResearch\Mathematica\3.0 (win98). - Si non tu dois chercher ton "path" que je ne connais pas!)

Mathematica 3.02, Windows98
Beispiel: neues Verzeichnis erstellen:
  Faire un nouveau directoire:

CreateDirectory["C:\work"]

x = Sin[3] // N   >> AAADaten

<< AAADaten

Beispiel: Erstelle ein Verzeichnis C:\work (falls nicht vorhanden).
(Das File AABDaten  befindet sich in Deinem Verzeichnis "work" (win98),  (aadaten.ma: "Mate" (win3.1, 95....), "WirzMathematicaFiles/Daten" (NeXT) usw.) . - Sonst musst Du Deinen mir nicht bekannten Pfad angeben!)
  Exemple: Ouvre un directoire C:\work (si cela n'existe pas encore).
(Le file AABDaten   se trouve dans le directoire "work" (win98), (aadaten.ma: "Mate" (win3.1, 95....), "WirzMathematicaFiles/Daten" (NeXT) etc. ). - Si non tu dois m'indiquer ton "path" que je ne connais pas!)

Schreibe Daten ins File C:\work\AABDaten:
  Ecrire des données dans le fichier C:\work\AABDaten:

\(\("3 4 5 1 2 3 6 6.3 7.8 4 r s t hallo 
	7777 6666 4.321 1.11111, {1,2,3,4}"\  >> c:\work\AABDaten; \)\)

\(\({"Cos[3]//N", \ Cos[3] // N}\ \ \  >> \ c:\work\AACDaten; 
    \)\)

\(\({3\ 4\ 5\ 1\ 2\ 3\ 6\ 6, \ "3 4 5 1 2 3 6 6", \ 

        	{3\ 4\ 5\ 1\ 2\ 3\ 6\ 6}}\ \  >> c:\work\AADDaten; \)\)

Lese das File C:\work\AABDaten:
  Lire le fichier C:\work\AABDaten:

\(<< c:\work\AABDaten\)

\(\(! \(! \(c : \(\work\AABDaten\)\)\)\)\)

win98: 
Erstelle nötigenfalles eine Textdatei "c:\work\AAEDaten.txt" mit Inhalt:
 Si nécessaire composer un fichier "c:\work\AAEDaten.txt" avec le contenu:
1 2 3 4 5 6 7
1.1 1.2 1.3 1.4
11 12 13 14 115
a b c d e f g
Sin[5]\\N hallo
"hallo"

Erstelle ebenso eine Textdatei "c:\work\AAFDaten.txt" mit Inhalt:
 Composer aussi un fichier "c:\work\AAEDaten.txt" avec le contenu:
1 2 3 4 5 6 7
1.1 1.2 1.3 1.4
11 12 13 14 115

Inhalt anschauen:
  Regarder le contenu:

\(\(!! C:\work\AAFdaten.txt\)\)

!!f:\Mathe/Daten/aadaten0 (* win3.1 etc. *)

File einlesen und ausführen:
 Lire le fichier et exécuter:

\(<< C:\work\AAFdaten.txt\)

<<f:\Mathe/Daten/aadaten1 (* win3.1 etc. *)

Was ist los gewesen? Schauen wir weiter:
  Que s'est-il passé? Continuons d'observer:

?<<

?Get

\(\(!! c:\work\AAEDaten.txt\)\)

!!f:\Mathe/Daten/aadaten1 (* win3.1 etc. *)

\(<< c:\work\AAEDaten.txt\)

<<f:\Mathe/Daten/aadaten1 (* win3.1 etc. *)

Get["c:\work\AAEDaten.txt"]

Get["f:\Mathe/Daten/aadaten1"] 
							(* win3.1 etc. *)

1 7 3 4 2 9 (*Produkt! *)

Spezifisch einlesen:
  Lire spécifiquement:

?ReadList

ReadList["c:\work\AAFDaten.txt", Real]

ReadList["f:\Mathe/Daten/aadaten0", Real]
							(* win3.1 etc. *)

?Real

ReadList["c:\work\AAFDaten.txt",  Number]

ReadList["f:\Mathe/Daten/aadaten0", Number]
							(* win3.1 etc. *)

?Number

ReadList["c:\work\AAFDaten.txt", Byte]

ReadList["f:\Mathe/Daten/aadaten0", Byte]
							(* win3.1 etc. *)

?Byte

\(ReadList["c:\work\AAFDaten.txt", 

      																									Character]\)

ReadList["f:\Mathe/Daten/aadaten0", 
				Character]	(* win3.1 etc. *)

?Character

ReadList["c:\work\AAEDaten.txt", String]

ReadList["f:\Mathe/Daten/aadaten0", String]
							(* win3.1 etc. *)

?String

ReadList["c:\work\AAEDaten.txt", Record]

ReadList["f:\Mathe/Daten/aadaten0", Record]
							(* win3.1 etc. *)

?Record

ReadList["c:\work\AAEDaten.txt", Word]

ReadList["f:\Mathe/Daten/aadaten0", Word]
							(* win3.1 etc. *)

?Word

ReadList["f:\Mathe/Daten/aadaten1", Real]
							(* win3.1 etc. *)

ReadList["f:\Mathe/Daten/aadaten1", Number]
							(* win3.1 etc. *)

ReadList["f:\Mathe/Daten/aadaten2", Number]
							(* win3.1 etc. *)

!!f:\Mathe/Daten/aadaten2	(* win3.1 etc. *)

\(ReadList["c:\work\AAFDaten.txt", 

      															{Number, \ Number}]\)

ReadList["f:\Mathe/Daten/aadaten1", 
		{Number, Number}]	(* win3.1 etc. *)

\(ReadList["c:\work\AAFDaten.txt", 

      							{Number, \ Number, \ Number, \ Number}]\)

ReadList["f:\Mathe/Daten/aadaten1", 
		{Number, Number, Number, Number}]
							(* win3.1 etc. *)

\(ReadList["c:\work\AAFDaten.txt", 
															
      Cos[Number]]\)

ReadList["f:\Mathe/Daten/aadaten1", 
		Cos[Number]]		(* win3.1 etc. *)

\(ReadList["c:\work\AAFDaten.txt", 
															
        Cos[Number]]\  // \ N\)

ReadList["f:\Mathe/Daten/aadaten1", 
		Cos[Number]] // N	(* win3.1 etc. *)

!!f:\Mathe/Daten/aadaten3	(* win3.1 etc. *)

\(ReadList["c:\work\AAFDaten.txt", \ 
{String, \ Number, \ Number}]
      \)

ReadList["f:\Mathe/Daten/aadaten3", 
{String, Number, Number}]	(* win3.1 etc. *)

!!f:\Mathe/Daten/aadaten4	(* win3.1 etc. *)

\(ReadList["c:\work\AAFDaten.txt", \ 
{Number, \ Number, \ String}]
      \)

ReadList["f:\Mathe/Daten/aadaten4", 
{Number, Number, String}]	(* win3.1 etc. *)

!!f:\Mathe/Daten/aadaten5	(* win3.1 etc. *)

ReadList["f:\Mathe/Daten/aadaten5", 
{Number, Number, String}]	(* win3.1 etc. *)

Probiere eigene files! 
  Essaie tes propres fichiers!

14.1.3. Einlesen von Records und Words
         Lire Records et Words

Studiere die "Befehle":
  Etudie les "ordres":

?*Record*

?RecordLists

?RecordSeparators

?WordSeparators

?NullRecords

?NullWords

?TokenWords

Studiere die Anwendungen:
  Etudie les applications:

\(\(!! c:\work\AAGDaten.txt\)\)

!!f:\Mathe/Daten/spsheet0 (* win3.1 etc. *)

\(ReadList["c:\work\AAGDaten.txt", \ 
\ {Number, \ Number, \ Number}]
      \)

ReadList["f:\Mathe/Daten/spsheet0", 
 {Number, Number, Number}](* win3.1 etc. *)

\(ReadList["c:\work\AAGDaten.txt", \ 
\ Word, \ 
      RecordLists\  -> True]\)

ReadList["f:\Mathe/Daten/spsheet0",
 Word, RecordLists ->True] (* win3.1 etc. *)

ReadList["c:\work\AAGDaten.txt",   Word]

ReadList["f:\Mathe/Daten/spsheet0", 
 Word]					   (* win3.1 etc. *)

\(ReadList["c:\work\AAGDaten.txt", \ 

      \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ RecordLists\  -> True]\)

ReadList["f:\Mathe/Daten/spsheet0", 
	   RecordLists ->True] (* win3.1 etc. *)

Clear[x];
x = ReadList["f:\Mathe/Daten/spsheet0", 
		Word, 
		WordSeparators -> {"\t"}, 
		RecordLists ->True] (* win3.1 etc. *)

\(\(Clear[x]; 

    x\  = \ ReadList["c:\work\AAGDaten.txt", \ 
		Word, \ 
		
        WordSeparators\  -> \ {"	"}, \ 
		RecordLists\  -> True]\ 
    \)\)

ToExpression[x]

?ToExpression

FullForm[x]

ReadList["f:\Mathe/Daten/spsheet1", 
		{Word, Number, Number, Number},
		WordSeparators -> {" "}, 
		RecordLists ->True] (* win3.1 etc. *)

\(ReadList["c:\work\AAGDaten.txt", \ 

      		{Word, \ Number, \ Number, \ Number}, 
		
      WordSeparators\  -> \ {" "}, \ 
		RecordLists\  -> True]\)

FullForm[%]

14.1.3. Ein längeres Beispiel
         Un exemple plus long

Zuerst definieren wir Funktionen. Damit kðnnen wir obigen Befehl "nachbilden":
  D'abord nous définissons des fonctions. Avec cela nous pouvons "imiter" l'ordre ci-dessus.

Clear[tabSeparate, tabSep];
tabSeparate[str_String]:= Apply[tabSep,
		Characters[str]];
tabSep[x__String,"\t",y___String]:=
		Flatten[{tabSep[x],tabSep[y]},1];
tabSep[x___String]:=
		ToExpression[StringJoin[x]]/;
		FreeQ[{x},"\t"];
ReadList["c:\work\AAGDaten.txt", 
		tabSeparate[String]]

Clear[tabSeparate, tabSep];
tabSeparate[str_String]:=Apply[tabSep,
		Characters[str]];
tabSep[x__String,"\t",y___String]:=
		Flatten[{tabSep[x],tabSep[y]},1];
tabSep[x___String]:=
		ToExpression[StringJoin[x]]/;
		FreeQ[{x},"\t"];
ReadList["f:\Mathe/Daten/spsheet1", 
		tabSeparate[String]](* win3.1 etc. *)

?Characters

?FreeQ

Achtung! Mathematica ist nicht für Datamanagement und Datamanipulation gebaut. Man kann Daten in speziellen Datamanagement-Sprachen oder Programmen (low-level- Programmierung) viel schneller parsen (einlesen und interpretieren) sowie manipulieren. Dies ist bei grösseren Datenmengen wesentlich. Man denke z. B. an  (1000 x 1000)- Matrizen in der Statistik, z.B. bei 1000 Beobachtungen von 1000 Variablen.
  Attention: Mathematica n'est pas conçu pour le "management" ni pour la manipulation des données. On peut lire et intérpréter ("parser") de même que manipuler beaucoup plus rapidement les données à l'aide de langages "datamanagement" ou programmes (programmation low-level). Cela est essentiel pour des quantités plus importantes de données. On pense p.ex. aux matrices (1000 x 1000) dans la statistique, p.ex. 1000 observations de 1000 variables.

14.1.4. Externe Kommandos bis exklusive Version 3.0
           (für WIN98 nicht zu empfehlen)
         Commandements extérieurs jusqu'à version 3.0,
           exclusive (pour WIN98 pas recommandé)

Mit "!Kommando" kann ein externes Kommando ausgeführt werden. Leider haben wir auf NeXT keinen ModulaII-Compiler oder Java-Compiler, so dass wir selbst solche Kommandos bauen könnten. Eine andere Programmiersprache, die den Zweck erfüllen würde, wird an der Schule momentan nicht unterrichtet. Hier ist für NeXT das Programm "aa_ascii", das Umlaute in TeX-Format übersetzt. Studiere das Beispiel:
 Par "commandement !" on peut exécuter un commandement extérieur. Malheureusement nous n'avons pas de compilateur pour ModulaII ou Jave sur NeXT pour pouvoir construire de tels commandements. Une autre langue de programmation qui serve pour le même but n'est actuellement pas enseigné à cette école. Ici on utilise pour NeXT le programme "aa_ascii" qui transforme les "Umlaute" (métaphonie, voyelle infléchie) de l'allemand dans le format TeX. Etudie l'exemple:

!!f:\Mathe/Daten/spsheet2

!f:\Mathe/Daten/aa_ascii 
		f:\Mathe/Daten/spsheet2 
		f:\Mathe/Daten/tex -tex;
ReadList["f:\Mathe/Daten/tex",
	 	{Word, Number, Number, Number},
		 WordSeparators -> {" "}, 
		 RecordLists ->True]

Das "!Kommando" kann auch in ReadList stehen, falls es sich auf eine Operation auf einem File bezieht (und nicht zwei Files aufruft)! Folgendes geht nicht:
 Le "commandement !" peut se trouver aussi dans ReadList, s'il se rapporte à une opération sur un fichier (et n'appelle pas deux fichiers)! La chose suivante ne va pas:

ReadList["!f:\Mathe/Daten/aa_ascii 
		f:\Mathe/Daten/spsheet2 
		f:\Mathe/Daten/tex -tex ",
	 	{Word, Number, Number, Number},
		 WordSeparators -> {" "}, 
		 RecordLists ->True]

Externe Kommandos ab Version 3.0
  Commandements extérieurs à partir de version 3.0

Verwendung externer Programme für Datenmanipulationen von Mathematica aus mit Hilfe der Befehle "Install", "Links", "MLPut...",
"MLGet...", u.s.w. ...... .
Momentan sind keine Programme vorhanden, die problemlos auf irgendwelchen hier unbekannten Systemen laufen. Daher wird auf ein konkretes Beispiel verzichtet. Probiere daher mit eigenen Programmen.
  Utiliser des Programmes externes pour manipuler des données depuis Mathematica à l'aide des ordres "Install", "Links", "MLPut...",
"MLGet...", etc. .... . 
Dans ce moment nous n'avons pas de programmes qui tournent sans problèmes sur n'importe quel système inconnu chez nous. C'est pourquoi nous renonçons à présenter un exemple concret. Essaie avec tes propres programmes.

14.2. Datenexport
       Exportation de données

14.2.1. Zeichenweise in ein File schreiben
 Ecrire les signes l'un après l'autre dans un fichier

Beispiel
 Exemple

Zuerst Daten erzeugen, die exportiert werden sollen:
 D'abord générer les données qui doivent être exportées:

Clear[daten];
daten = Table[Random[Integer,{1,9}],{2},{6}]

Studiere die Befehle:
 Etudie les ordres:

?>>

?Put

??WriteString

?OpenWrite

?Close

?Scan

?Rest

Zum Exportieren wollen wir eine Funktion definieren, die die Generierte in der Art Matrix "Zeilenvektor auf Zeile ... (Record) im File" schreibt:
  Nous allons définir une fonction pour exporter, qui écrit la générée dans la matrice dans le sens "vecteur de ligne sur ligne .... (Record) dans le fichier":

Remove[schreibMatrix];
Off[neufile];
schreibMatrix[fileName_String, data_List] :=
	Block[{ neufile = OpenWrite[fileName]},
		Scan[(WriteString[neufile,First[#]];
				  Scan[WriteString[neufile,
				  "\t",#]&,Rest[#]];
			  WriteString[neufile,"\n"])&, 
			  data];
		Close[neufile]];

schreibMatrix["C:\work\AAHDaten", daten]

\(\(schreibMatrix[
      \*""f:\Mathe/Daten/neuDaten, daten] (* win3.1 etc. *)"\)\)

\(\(!! C:\work\AAHDaten\)\)

!!f:\Mathe/Daten/neuDaten (* win3.1 etc. *)

?schreibMatrix

14.2.2. Abspeichern von Definitionen
         Mémoriser des définitions

Beispiel
 Exemple

Studiere:    Etudie:

?Save

\(f[x_]\  := \ Sin[x^2]/\((E^\((\(-x\))\)\ Cos[x])\); 

    Save["C:\work\AA_f", \ f]\)

f[x_] := Sin[x^2]/(E^(-x) Cos[x]);
Save["f:\Mathe/Daten/AAA_f", f]
						(* win3.1 etc. *)

\(\(!! C:\work\AA_f\)\)

!!f:\Mathe/Daten/AAA_f  (* win3.1 etc. *)

14.2.3.Abspeichern von Output
        Mémoriser l'output

Studiere:    Etudie:

?>

?>>

?>>>

?Put

Probiere aus:    Essaie:

\(Table[f[n], \ {n, \ 20}]\  >> \ 
	C:\work\AAneuDaten\)

Table[f[n], {n, 20}] >> 
	f:\Mathe/Daten/neuDaten  (* win3.1 etc. *)

\(\(!! C:\work\AAneuDaten\)\)

!!f:\Mathe/Daten/neuDaten    (* win3.1 etc. *)

\(\(Put[Table[f[n], \ {n, \ 20}], \ Sin[x], \ "Hallo", \ 
\ 
      "C:\work\AAneuDaten"]\ \ \)\)

Put[Table[f[n], {n, 20}], Sin[x], "Hallo", 
 "f:\Mathe/Daten/neuDaten"]  (* win3.1 etc. *)

\(\(!! C:\work\AAneuDaten\)\)

!!f:\Mathe/Daten/neuDaten    (* win3.1 etc. *)

Was ist mit den Daten von 14.2.3 passiert?
Aue s'est-il passé avec les données de 14.2.3?

2.^0.5

\(2. ^0.5\  >> \ C:\work\AAneuDaten\)

2.^0.5 >> f:\Mathe/Daten/neuDaten 
							(* win3.1 etc. *)

\(\(!! C:\work\AAneuDaten\)\)

!!f:\Mathe/Daten/neuDaten   (* win3.1 etc. *)

Wieso ist das abgespeicherte Resultat genauer als das auf dem Schirm ausgegebene Resultat?
  Pourquoi le résultat mémorisé est-il plus exact que le résultat sorti sur l'écran?

14.3. Manipulation von Strings
       Manipulation de Strings

Studiere die folgenden Befehle:
  Etudie les ordres suivants:

?Read

?ReadList

?OpenAppend

?OpenRead

?StringDrop

?StringInsert

?StringJoin

?StringReplace

?StringReverse

?StringTake

?StringLength

?StringPosition

?StringMatchQ

?StringQ

?StringToStream

?WriteString

?ToString

Probiere aus:    Essaie:

Table[StringJoin["daten.", ToString[i]],{i,6}]

14.4. Eingabe- und Ausgabeform
       Formes d'entrée et de sortie

Studiere die folgenden Befehle:
  Etudie les ordres suivants:

?InputForm

?OutputForm

Beispiele:    Exemples:

Clear[a];
a = x^5/x^2 y +x^y^5

InputForm[a]

OutputForm[a]

\(a\  >> C:\work\AAneuDaten\)

a >> f:\Mathe/Daten/neuDaten  (* win3.1 etc. *)

\(\(!! C:\work\AAneuDaten\)\)

!!f:\Mathe/Daten/neuDaten     (* win3.1 etc. *)

Read["C:\work\AAneuDaten"]

Read["f:\Mathe/Daten/neuDaten"](* win3.1 etc. *)

b  = Read["C:\work\AAneuDaten"]

b = Read["f:\Mathe/Daten/neuDaten"]
							  (* win3.1 etc. *)

b

\(\(!! C:\work\AAneuDaten\)\)

!!f:\Mathe/Daten/neuDaten     (* win3.1 etc. *)

Close["C:\work\AAneuDaten"]

Close["f:\Mathe/Daten/neuDaten"]
							  (* win3.1 etc. *)

b  = Read["C:\work\AAneuDaten"]

b = Read["f:\Mathe/Daten/neuDaten"]
							  (* win3.1 etc. *)

Close["C:\work\AAneuDaten"]

Close["f:\Mathe/Daten/neuDaten"]
							  (* win3.1 etc. *)

14.5. Uebersetzen von Ausdrücken in andere Programmiersprachen und Manipulation von Sourcecode
 Traduire des expressions en d'autres languages de programmation et manipulation de sourcecode

Uebersetzungen
 Tradcuction

Studiere die folgenden Befehle:
  Etudie les ordres suivants:

?CForm

?FortranForm

?TeXForm

?Splice

Beispiele:    Exemple:

Clear[a];
a = x^5/z^2 y +x^y^5 + 
				( x^2 Sin[x^5/z^2 y +x^y^5]);

CForm[a]

FortranForm[a]

TeXForm[a]

Manipulation von Sourcecode
 Manipulation de sourcecode

Im folgenden Beispiel wird gezeigt, wie in den Source-Code eines externen Programms (z.B. in C) direkt Mathematica-Ausdrücke eingesetzt und dann von Mathematica übersetzt werden kðnnen. Der externe Programmteil befindet sich im File AAA.mc. Das übersetzte Programm wird in AAA.c gespeichert!!!!!!!
  Dans l'exemple suivant on montre comme on peut mettre des expressions de Mathematica directement dans le Source-Code d'un autre programme extérieur (p.ex. dand C), ensuite ses expressions peuvent être traduites par Mathematica. La partie extérieur du programme se trouve dans le fichier AAA.mx resp. AAA.mc. Le programme traduit est mémorisé dans AAA.x resp. AAA.c !!!!!!!

\(Sin[3] + Cos[3] >> C:\work\AAA.mx\)

\(\(!! C:\work\AAA.mx\)\)

!!f:\Mathe/Daten/AAA.mc   	(* win3.1 etc. *)

Splice["C:\work\AAA.mx"]

Splice["f:\Mathe/Daten/AAA.mc"] 
							(* win3.1 etc. *)

\(\(!! C:\work\AAA.x\)\)

!!f:\Mathe/Daten/AAA.c		(* win3.1 etc. *)

14.6. Formate
       Formats

Allgemeines
 Généralités

Studiere die folgenden Befehle:
  Etudie les ordres suivants:

?Subscripted

?Superscript

?SequenceForm

Probiere aus:    Etudie:

Subscripted[abc[145]]

SequenceForm[uvw, Superscript[251]]

Ein Anwendungsbeispiel
 Un exemple d'application

Remove[a, n, m];
Format[a[n_, m_]] := Subscripted[a[n, m]];
Array[a, {2, 2}] // MatrixForm

"Putzmaschine" einsetzen
 Employer la "machine de nettoyage"

Remove["Global`@*"]