2. UniScript in Beispielen

An einigen kleinen Beispielen soll Ihnen die Benutzung von UniScript gezeigt werden. Es ist empfehlenswert, wenn Sie dazu UniPlot starten und die Beispiele eingeben.

Starten Sie also UniPlot und klicken Sie mit der Maus auf den Schalter mit dem Symbol eines Taschenrechners Main_Command.

Es erscheint das Kommandofenster von UniScript mit einer Copyright-Meldung. Vergrößern Sie das Kommandofenster auf Vollbilddarstellung.

../../_images/UniScript-Vollbild.png

Der Stern * ist der sogenannte Prompt. Er zeigt Ihnen, daß UniScript für Ihre Eingaben bereit ist.

2.1. UniScript als Taschenrechner

Geben Sie ein

* 7 + 12
    19.0000
* 5-7
    -2.0000
* 3*5
    15.0000
* 1/2
    0.5000
* (2 + 5)*5
    35.0000
* y = sin(0.5)
* y
    0.4794
*

Sie können UniScript wie einen leistungsfähigen Taschenrechner verwenden. UniScript kann jedoch mehr, z. B. mit Matrizen rechnen.

2.2. Matrizenrechnung

Die Gleichung

\begin{pmatrix}
   4 & 7 \\
   2 & 5
 \end{pmatrix}
 \cdot
 \begin{pmatrix}
   x_{1} \\
   x_{2}
 \end{pmatrix}
 =
 \begin{pmatrix}
   1 \\
   4
 \end{pmatrix}

kann mit UniScript folgendermaßen gelöst werden:

* a = [4,7;2,5]
* a
    4.0000   7.0000
    2.0000   5.0000
* b = [1;4]
* b
    1.0000
    4.0000
* x = a\b
* x
   -3.8333
    2.3333
* a * x
    1.0000
    4.0000

Matrizen werden in UniScript eingegeben, indem man die Spalten der Matrix durch ein Komma trennt und die Zeilen durch ein Semikolon. Die Zeile x = a\b löst das lineare Gleichungssystem. Das \-Zeichen ist der sogenannte Links-Divisions-Operator. Dieser Operator ist speziell für das Lösen von Gleichungssystemen mit reellen und komplexen Elementen gedacht. UniScript verwendet dazu die sehr leistungsfähigen Berechnungsverfahren der LAPACK-Library, so daß auch große Gleichungssysteme schnell und stabil gelöst werden können.

UniScript kann noch einige andere Matrizenoperationen ausführen, z. B. die Determinate berechnen, die Inverse oder die Eigenwerte.

* det(a)
    6.0000
* a^-1
    0.8333  -1.1667
   -0.3333   0.6667
* eig(a)
    8.2749 + 0.0000i
    0.7251 + 0.0000i

Die Eigenwerte wurden als komplexe Zahlen berechnet. Komplexe Zahlen werden eingegeben, indem man ein i hinter die Zahl schreibt.

* (3 + 5i) * (2 + 7i)
 -29.0000 + 31.0000i

Fast alle mathematischen UniScript-Funktionen können auch mit komplexen Zahlen rechnen, versuchen Sie z. B. sqrt(-1).

2.3. Editieren im Kommandofenster

Sie können Ihre Kommandos mit den Pfeiltasten editieren.

  • Die Einfg-Taste (Insert) schaltet zwischen Einfüge- und Überschreibmodus hin und her.
  • Die BACKSPACE-Taste löscht das Zeichen vor dem Cursor,
  • die Entf-Taste das Zeichen unter dem Cursor.
  • Mit den Pfeiltasten nach oben und nach unten können Sie bereits abgeschickte Anweisungen zurückholen (sogenannte Command-History).
  • Mit der F7-Taste erhalten Sie ein Listenfeld mit den 100 zuletzt eingegebenen Anweisungen.
  • Mit der F8-Taste können Sie die Zeilen zurückholen, die mit den Buchstaben vor dem Cursor anfangen.
  • Mit der Esc-Taste kann die Eingabezeile gelöscht werden. Außerdem kann mit der Esc-Taste eine laufende Funktion abgebrochen werden.

Siehe auch Ansicht=>Kommando-Fenster.

Das Kommandofenster wird hauptsächlich dazu verwendet, um Befehle auszuprobieren und sich die Werte von Variablen anzuschauen. In allen anderen Fällen wird ein Editor verwendet.

2.4. Verwenden eines Editors

Um einen Editor zu erzeugen, geben Sie im Kommandofenster den Befehl EdCreate ein und ordnen Sie die Fenster nebeneinander an.

Geben Sie im Editor die folgenden Zeilen ein

a = [4, 7; 2, 5]
b = [1; 4]
print "Die Determinante von", a
print "ist", det(a)
print "Die Lösung der Gleichung"
print "a*x = b, mit a = ", a
print "und b = ", b, "ist", a\b

Speichern Sie Ihre Eingabe unter einem Namen, der mit .ic endet. Die Endung ".ic" steht für IsoCalc. UniScript hieß bis UniPlot 2.1 IsoCalc. Wählen Sie im Menü UniScript den Befehl Laden/Ausführen. UniScript führt Ihre im Editor eingegebenen Anweisungen aus. Die Ausgabe der print-Anweisungen wird in das UniScript-Kommandofenster geschrieben.

Gehen Sie mit dem Cursor auf einen Funktionsnamen und drücken Sie die F1-Taste. Wenn Sie den Cursor auf den det-Funktionsaufruf positionieren, bekommen Sie die folgende Hilfe-Seite.

../../_images/UniScript-dethelp.png

Löschen Sie nun Ihre Editoreingaben (mit dem Befehl alles markieren im Menü Bearbeiten und anschließendem Drücken der DEL-Taste).

2.5. Temperaturtabelle - 1. Version

Es soll nun ein Programm geschrieben werden, das eine Temperaturtabelle ausgibt. In der ersten Spalte sollen die Celsius-Grade stehen und in der zweiten Spalte die Temperatur in Fahrenheit. Für die Umrechnung gilt die Formel C = 5 / 9 * (F - 32).

0    -17.8
20    -6.7
40     4.4
...    ...
260  126.7
280  137.8
300  148.9

Das Beispiel ist einem Buch über die Programmiersprache C entnommen [Kernighan, Brian W., und Ritchie, Dennis M.: Programmieren in C, Hanser, München, 1983]. Es zeigt Ihnen nicht nur die Ähnlichkeit von UniScript und C, sondern führt auch in wichtige Aspekte der Programmierung ein, die für UniScript ebenso gelten wie für C.

Das Programm, das die Tabelle ausgibt, sieht so aus:

/* Umwandlung von Fahrenheit in Celsius
fuer f = 0, 20, ..., 300 */
def main()
{
    lower = 0; /* untere Grenze der Temp.-Tabelle */
    upper = 300; /* obere Grenze */
    step = 20; /* Schrittweite */

    fahr = lower;
    while (fahr <= upper) {
        celsius = (5.0 / 9.0) * (fahr - 32.0);
        printf("%4.0f %6.1f\n", fahr, celsius);
        fahr = fahr + step;
    }
}

Die ersten beiden Zeilen kommentieren das Programm

/* Umwandlung von Fahrenheit in Celsius
fuer f = 0, 20, ..., 300 */

Alle Zeilen, die zwischen /* und */ stehen, werden von UniScript ignoriert.

Mit

def main()
{
    ...
}

wird ein Programm (eine Funktion) definiert. In C gibt es das Schlüsselwort def nicht; es entfällt dort. In UniScript muss jedoch vor den Namen von Funktionen das Schlüsselwort def stehen. main ist der Name der Funktion. In C steht der Name main für das Hauptprogramm. In UniScript ist main ein Name wie jeder andere.

Hinter dem Funktionsnamen main stehen Klammern, die meist eine Liste von Parametern enthalten. In unserem Beispiel ist die Liste leer; die Klammern müssen aber dennoch hinter dem Funktionsnamen stehen, damit UniScript (und der Programmierer) besser erkennt, daß es sich bei main um einen Funktionsnamen handelt. Die geschweiften Klammern { und } umschließen die Anweisungen der Funktion main. Sie haben die Bedeutung von begin und end in anderen Programmiersprachen.

In C folgen hinter der ersten geschweiften Klammer die Deklarationen der Variablen. In UniScript sind Deklarationen von Variablen nicht erforderlich.

Die erste Anweisung ist

lower = 0;

Sie weist der Variablen lower den Wert 0 zu und zwar als doppelt genaue Gleitkommakonstante. Im C-Programm wurde lower als ganze Zahl deklariert. UniScript kennt diesen Datentyp nicht. UniScript kennt lediglich drei Datentypen:

  • Doppelt genaue Gleitkommazahlen.
  • Komplexe Zahlen, bestehend aus zwei doppelt genauen Gleitkommazahlen.
  • Zeichenketten, bestehend aus beliebig vielen Zeichen.

Von allen drei Datentypen können auch Vektoren und Matrizen gebildet werden, wie später gezeigt wird.

Die Zeilen

upper = 0;
step = 20;
fahr = lower;

weisen den anderen in dieser Funktion verwendeten Variablen Anfangswerte zu.

Es folgt eine sogenannte while-Schleife:

while (fahr <= upper) {
    ...
    fahr = fahr + step;
}

In der while-Schleife wird zunächst die Bedingung fahr <= upper ausgewertet. Trifft sie zu, d.h. fahr ist kleiner oder gleich upper, werden die Anweisungen innerhalb der while-Schleife ausgeführt. Am Ende der while-Schleife wird fahr um step (gleich 20) erhöht, was dazu führt, daß fahr irgendwann größer als upper wird, wodurch die while-Schleife beendet wird.

Ein paar Worte zur Formatierung von Funktionen: Man hätte alle Anweisungen der Funktion auch linksbündig schreiben können, das Programm ist jedoch besser lesbar, wenn die Anweisungen um eine Tabulatorposition nach rechts eingerückt werden. Anweisungen innerhalb von Schleifen oder if-Anweisungen werden um eine weitere Tabulatorposition eingerückt. Die Tabulatorweite wird im Editor am besten so eingestellt, daß ein Tabulator 4 Leerzeichen entspricht.

Innerhalb der while-Schleife befinden sich noch die beiden Anweisungen

celsius = (5.0 / 9.0) * (fahr - 32.0);
printf("%4.0f %6.1f\n", fahr, celsius);

Die erste Anweisung führt die Umrechnung Fahrenheit in Celsius durch und die zweite Anweisung gibt die aktuellen Werte für fahr und celsius im UniScript-Kommandofenster aus. Für die Ausgabe wird die Funktion printf verwendet. Das Zeichen f am Ende des Funktionsnamens steht für formatiert.

printf hat in diesem Beispiel drei Argumente. Das erste Argument ist "%4.0f %6.1f\n". Die Zeichenkette beschreibt, wie die anderen beiden Argumente fahr und celsius ausgegeben werden sollen. Die Zeichenkette enthält dazu die beiden Format-Elemente %4.0f und %6.1f. Format-Elemente beginnen mit einem Prozentzeichen. %4.0f bedeutet, daß der Parameter fahr mit insgesamt 4 Stellen ausgegeben wird und keine Nachkommastellen ausgegeben werden. Das %f bedeutet, daß die Zahl als Fließkommazahl ausgegeben wird. Entsprechend bewirkt %6.1f, daß celsius mit 6 Stellen ausgegeben wird, davon eine Stelle nach dem Komma. Die printf-Funktion verwendet als Dezimaltrennzeichen den Punkt . und kein Komma , wie im Deutschen üblich. Zeichen außerhalb von Format-Elementen werden direkt ausgegeben, wie das Leerzeichen zwischen den beiden Format-Elementen in der Beispiel-Funktion. Die beiden Zeichen \n bewirken, daß die nächsten Zeichen in einer neuen Zeile ausgegeben werden.

In der Funktion main() werden 5 Variablen verwendet, nämlich: lower, upper, step, fahr und celsius. Diese Variablen werden erzeugt, wenn die Funktion aufgerufen wird und gelöscht, kurz bevor die Funktion beendet wird.

Falls Sie es nicht bereits getan haben, geben Sie nun die Funktion in einem Editor ein; speichern Sie die Funktion z. B. unter dem Namen celsius.ic. Führen Sie im Editor im Menü UniScript den Befehl Speichern/Ausführen aus.

Sie können die Funktion ausführen, indem Sie die Funktion im UniScript-Kommando-Fenster aufrufen:

* main()

Experimentieren Sie ein wenig mit der Funktion. Ändern Sie z. B. die Format-Zeichenkette der printf-Funktion. Führen Sie nach jeder Änderung im Editor den Menü-Befehl Laden/Ausführen aus, und rufen Sie die Funktion im UniScript-Kommando-Fenster auf.

2.6. Temperaturtabelle - 2. Version

Wir wollen nun eine neue Funktion schreiben, die die gleiche Ausgabe wie main() erzeugt. Wir nennen Sie main2(). Sie können Sie in die selbe Datei wie main() schreiben; in UniScript kann eine Datei beliebig viele Funktionen enthalten.

/* Umwandlung von Fahrenheit in Celsius
fuer f = 0, 20, ..., 300
  -- 2. Fassung -- */
def main2()
{
    for (fahr in 0:20:300) {
        printf("%4d %6.1f\n", fahr, 5/9 * (fahr-32));
    }
}

main2() verwendet anstatt der while-Schleife eine for-Schleife. Sie hat in UniScript die Form:

for (var in vektor) {
    ...
}

for und in sind Schlüsselwörter, var steht für einen beliebigen Variablennamen, vektor steht für den Namen eines Vektors oder für einen konstanten Vektor.

Vektoren können in UniScript auf verschiedene Weise erzeugt werden. Eine Möglichkeit ist die Aufzählung der Elemente in eckigen Klammern wie weiter oben bereits gezeigt.

vektor = [0,20,40,60,80]

Eine andere Möglichkeit ist die Verwendung des Vektor-Erzeugungs-Operators : in der Form:

vektor = start:step:end

step kann auch weggelassen werden (vektor = start:end), dann wird für step 1.0 verwendet. 0:20:100 erzeugt beispielsweise den Vektor [0, 20, 40, 60, 80, 100].

Die for-Schleife

for (fahr in 0:20:300) {
    printf("%4d %6.1f\n", fahr, (5/9)*(fahr-32.0));
}

erzeugt am Anfang der Schleife den Vektor 0:20:300 und weist fahr nacheinander die Werte 0, 20, 40 bis 300 zu.

Wenn am Anfang einer Schleife bekannt ist, wie oft eine Schleife ausgeführt werden muss, ist die for-Schleife besser geeignet als die while-Schleife, so daß main2() sicherlich eine bessere Lösung ist als main().

2.7. Temperaturtabelle - 3. Version

Es gibt in UniScript noch bessere Lösungen. Es kann bei diesem Problem ganz auf Schleifen verzichtet werden:

def main3()
{
    fahr = (0:20:300)';
    printf("%4.0f %6.1f\n", fahr, (5/9)*(fahr-32));
}

In main() und main2() wurden skalare Werte an die Funktion printf übergeben, nämlich nacheinander die Werte 0, 20, 40 usw. In main3() wird mit der Anweisung

fahr = (0:20:300)';

ein Spaltenvektor erzeugt. ' ist der Transponierungs-Operator, der aus dem Zeilenvektor 0:20:300 einen Spaltenvektor macht. Da fahr ein Spaltenvektor ist, ist auch (5/9)*(fahr-32) ein Spaltenvektor mit genau so vielen Zeilen wie fahr. printf arbeitet so oft die Format- Zeichenkette "%4.0f %6.1f\n" ab, wie Zeilen in den anderen Argumenten sind; printf hat sozusagen eine eingebaute for-Schleife.

Es gibt in UniScript viele Funktionen mit eingebauten for-Schleifen

y = sin(0:2*PI/100:2*PI)

erzeugt z. B. den Vektor y mit 100 Werten, ohne daß die Verwendung einer Schleife erforderlich ist. Dadurch können mit UniScript sehr kompakte Programme geschrieben werden.

2.8. Temperaturtabelle - 4. Version

Es soll nun die Temperatur-Tabellen-Ausgabe nicht als Funktion, sondern in einer einzigen Anweisung geschrieben werden. Sie können den Funktionsaufruf entweder direkt ins UniScript-Kommandofenster schreiben oder in einen Editor. Bei jedem UniScript=>Speichern/Ausführen-Befehl wird die Zeile direkt ausgeführt.

printf("%4d %6.1f\n", fahr = (0:20:300)', 5/9*(fahr-32));

Die Zeile zeigt eine weitere interessante Möglichkeit von UniScript, kompakte Programme zu schreiben. Eine Zuweisung ist nicht nur eine Anweisung wie bei den meisten Programmiersprachen, sondern wie in C auch ein Ausdruck. Dadurch sind Formulierungen wie a = 3 * (b = 5) möglich - a bekommt den Wert 15, und b den Wert 5 in einer Anweisung zugewiesen.

In UniScript gibt es als vereinfachte Ausgabemöglichkeit die print-Anweisung, bei der kein Format-String erforderlich ist. print ist kein Funktionsaufruf, sondern eine in die Sprache UniScript eingebaute Anweisung. Es werden deshalb keine Klammern um die Argumente geschrieben. Die Zeile

print [fahr = (0:20:300)', 5/9*(fahr-32)];

erzeugt zunächst aus den beiden Vektoren eine Matrix mit zwei Spalten, die anschließend in einem Standard-Format ausgegeben wird.

Würde print in der Form

print fahr = (0:20:300)', 5/9*(fahr-32)

geschrieben werden, so würden die beiden Vektoren nacheinander ausgegeben werden.

Der Nachteil der print-Anweisung ist, daß keine genaue Kontrolle über die Ausgabe vorhanden ist. (Schauen Sie sich die format-Funktion im Hilfe-System an. Mit dieser Funktion kann das Standard-Format geändert werden.) Außerdem kann mit der print-Anweisung nicht direkt in Dateien geschrieben werden, wie dies mit einer speziellen Version der printf-Funktion möglich ist (fprintf).

2.9. Ausgabe der Temperaturtabelle als Grafik

Als letztes Beispiel soll die Temperatur-Fahrenheit-Tabelle als Diagramm dargestellt werden. Ein Diagramm kann mit der Funktion plot erzeugt werden.

h = plot(fahr = 0:20:300, 5/9 * (fahr - 32))

plot ist eine Funktion, die selber in UniScript geschrieben ist. Sie können sich den Quelltext von plot in der Datei script/plot.ic anschauen. plot hat den Zweck, XY-Diagramme aus Funktionen oder Vektoren zu erzeugen. In der Abbildung sehen Sie das Ergebnis des plot-Aufrufs.

../../_images/UniScriptFahrenheitCelsius.png

Das Diagramm muss bei Ihnen nicht exakt genau so aussehen; plot verwendet die Standard-Einstellungen, die Sie mit dem Befehl Extras in UniPlot verändern können.

Die plot-Funktion hat ein neues Fenster erzeugt, in das Fenster ein Koordinatensystem gezeichnet, und die x- und die y-Koordinaten als Kurvenzug im Koordinatensystem ausgegeben.

Für diese drei Begriffe sollen im folgenden die Begriffe Dokument, Layer und Datensatz verwendet werden. Ein Fenster repräsentiert ein Dokument, ein Dokument ist der Inhalt des Fensters. In einem Dokument können ein oder mehrere Layer enthalten sein. Ein Layer hat ein Koordinatensystem, das nicht unbedingt sichtbar sein muss. Ein Layer kann neben Datensätzen auch Zeichenelemente enthalten. Ein Datensatz hat Datenpunkte mit Koordinaten. Er enthält aber auch Informationen über seine Darstellungsart.

UniPlot ist in der objekt-orientierten Programmiersprache C++ programmiert worden. Dokumente, Layer und Datensätze sind dabei die Objekte, die mit UniPlot/UniScript erzeugt und verändert werden können. UniScript selber ist keine objekt-orientierte Programmiersprache. Um die Objekte dennoch zu verändern, werden in UniScript Zugriffsnummern (handle) auf die von UniPlot erzeugten Objekte verwendet.

Der Aufruf

h = plot(fahr = 0:20:300, 5/9 * (fahr - 32))

gibt einen Vektor von Zugriffsnummern zurück.

  • h[1] ist dabei die Zugriffsnummer der Dokument-Seite,
  • h[2] ist die Zugriffsnummer des Layers (Diagramms) und
  • h[3] die Zugriffsnummer des Datensatzes.

Ordnen Sie das Kommandofenster und das Fenster mit dem Diagramm nebeneinander an und geben Sie im Kommandofenster

PagePrint(h[1])

ein. Das Dokument wird gedruckt. Die Namen aller UniScript-Funktionen, die Dokumente verändern können, fangen mit den Buchstaben Doc an. Um eine Liste dieser Funktionen zu erhalten, geben Sie what("Doc*") ein:

* what ("Doc*")
DocAddPage
DocCopyPage
DocCreate
DocDestroy
DocGetActivePage
DocGetAllPages
...
DocSetProtectionFlags
DocSetReadOnly
DocSetSummaryInfo
DocSetTitle
DocShow
   54 function(s) defined

Die Funktion what gibt die Namen aller geladenen Funktionen aus, die ein bestimmtes Muster haben. Versuchen Sie what(), what("Layer*") und what("XY*").

Schauen Sie sich die Beschreibungen der Funktionen im Hilfesystem an. Um die Beschreibung einer bestimmten Funktion zu erhalten, können Sie im Kommandofenster den Namen der Funktion schreiben, mit der Pfeiltaste nach links ein Zeichen zurückgehen und die F1-Taste drücken. Anschließend löschen Sie den Namen wieder mit der ESC-Taste.

Zum Schluß sollen noch die Achsenbeschriftungen geändert werden

LayerSetAxisTitle(h[2], "X", "Celsius")
LayerSetAxisTitle(h[2], "Y", "Fahrenheit")
PageReplot(h[1])

Normalerweise würde man die Achsenbeschriftungen mit UniPlot interaktiv ändern. Wenn die Achsenbeschriftungen aber automatisch erzeugt werden sollen, z. B. indem die Texte aus einer Datei gelesen werden, muss UniScript verwendet werden.

id-1087286