________________________________________________________________________________
Inhalt....: Einfache Prozeduren mit Fehlerabfragen
Kategorie.: Handwerkskasten
Mathematik: Programmierung
MuPAD.....: 3.0.0
Datum.....: 2002-08-14
Autoren...: Kai Gehrs <acrowley@mupad.de>
Funktionen: if, then, proc, random, isprime, error
________________________________________________________________________________
Elementare MuPAD-Funktionen:
Einfache Prozeduren in MuPAD
Dieses Notebook ist das zweite Notebook im Rahmen des Handwerkskastens zum Thema
"Einfache eigene MuPAD Prozeduren definieren".
In den Notebooks zur if-Anweisung und zu for-Schleifen im Handwerkskasten
wie auch im Notebook Einfache_Prozeduren_1 des Handwerkskastens haben
wir einfache Programmkonstrukte kennengelernt. Hier wollen wir eine Prozedur
schreiben, die schon ein kleines bißchen umfangreicher ist als die Prozedur
Summen, die in dem Notebook Einfache_Prozeduren_1 kennengelernt.
Als nächstes wollen wir eine weitere kleine Prozedur schreiben. Sie soll
zwei Werte u und o als Argumente erhalten und zusätzlich ein drittes
Argument n. Bei Eingabe von natürlichen Zahlen u < o und n sollen n
Zufallszahlen aus dem Bereich von u bis o erzeugt werden. Dabei sollen
doppelt vorkommende Zahlen nicht mehrfach gespeichert werden.
Anschließend soll unter den erzeugten Zufallszahlen die Anzahl der
Primzahlen (d.h. derjenigen Zahlen, die nur durch 1 und sich selbst teilbar
sind) bestimmt werden.
Wir beginnen wieder mit dem üblichen "Gerüst" für unsere Prozedur,
die wir schlicht Primzahlen nennen wollen:
Primzahlen:= proc(u, o, n)
begin
return();
end_proc:
Innerhalb der Prozedur müssen jetzt zuerst n Zufallszahlen aus dem
Bereich von u bis o erzeugt und gespeichert werden. Da doppelte
Vorkommen unberücksichtigt bleiben sollen, entscheiden wir uns,
die Zahlen in einer Menge zu speichern. Wir nennen diese Menge
Zufallszahlen und deklarieren sie, wie üblich, als lokale Variable der
Prozedur:
Primzahlen:= proc(u, o, n)
local Zufallszahlen;
begin
return();
end_proc:
Zum erzeugen der Zufallszahlen im Bereich von u bis o verwenden wir wie
schon in dem Notebook zu for-Schleifen den MuPAD Befehl random(u..o).
Primzahlen:= proc(u, o, n)
local Zufallszahlen, Zufall;
begin
Zufall:= random(u..o);
return();
end_proc:
Wir benötigen n Zufallszahlen und speichern diese in einer Menge, die
wir der Variablen Zufallszahlen zuweisen:
Primzahlen:= proc(u, o, n)
local Zufallszahlen, Zufall;
begin
Zufall:= random(u..o);
Zufallszahlen:= {Zufall() $ i = 1..n};
return();
end_proc:
Wir haben die Variable i als Laufvariable für den Sequenzoperator $
verwendet. Sicherheitshalber kennzeichnen wir i ebenfalls als lokale
Variable - zudem benötigen wir sowieso für eine for-Schleife noch
eine Laufvariable.
Primzahlen:= proc(u, o, n)
local Zufallszahlen, Zufall, i;
begin
Zufall:= random(u..o);
Zufallszahlen:= {Zufall() $ i = 1..n};
return();
end_proc:
Nun zum mathematischen Teil unserer Prozedur: Wir wollen wissen,
wie viele Primzahlen sich in der Menge Zufallszahlen befinden. Der erste
Schritt ist also, eine for-Schleife zu schreiben, die nacheinander
alle Elemente der Menge durchläuft. Innerhalb der for-Schleife
können wir dann testen, ob die gerade betrachtete Zahl i eine
Primzahl ist.
Primzahlen:= proc(u, o, n)
local Zufallszahlen, Zufall, i;
begin
Zufall:= random(u..o);
Zufallszahlen:= {Zufall() $ i = 1..n};
for i in Zufallszahlen do
end_for;
return();
end_proc:
Als nächstes benötigen wir eine Zählvariable Zaehler, in der wir
die Anzahl aller Primzahlen in der Menge Zufallszahlen speichern.
Zu Beginn, d.h. noch vor der for-Schleife, sollte diese Variable
auf den Wert 0 gesetzt werden. Auch sollten wir daran denken,
die Variable Zaehler als lokale Variable zu deklarieren.
Primzahlen:= proc(u, o, n)
local Zufallszahlen, Zufall, i, Zaehler;
begin
Zufall:= random(u..o);
Zufallszahlen:= {Zufall() $ i = 1..n};
Zaehler:= 0;
for i in Zufallszahlen do
end_for;
return();
end_proc:
Jetzt müssen wir innerhalb der for-Schleife nur noch mit Hilfe einer
if-Anweisung und des Befehls isprime( i ) testen, ob der aktuelle
Wert von i eine Primzahl ist, oder nicht. Falls i eine Primzahl ist,
erhöhen wir den Wert der Variablen Zaehler um 1. Falls i keine
Primzahl ist, so müssen wir gar nichts tun. Daher können wir uns
den else Teil der if-Anweisung sparen.
Primzahlen:= proc(u, o, n)
local Zufallszahlen, Zufall, i, Zaehler;
begin
Zufall:= random(u..o);
Zufallszahlen:= {Zufall() $ i = 1..n};
Zaehler:= 0;
for i in Zufallszahlen do
if isprime(i) = TRUE then
Zaehler:= Zaehler + 1;
end_if;
end_for;
return();
end_proc:
Abschließend brauchen wir nur noch das Ergebnis, also den Wert
der Variablen Zaehler zurückgeben.
Primzahlen:= proc(u, o, n)
local Zufallszahlen, Zufall, i, Zaehler;
begin
Zufall:= random(u..o);
Zufallszahlen:= {Zufall() $ i = 1..n};
Zaehler:= 0;
for i in Zufallszahlen do
if isprime(i) = TRUE then
Zaehler:= Zaehler + 1;
end_if;
end_for;
return(Zaehler);
end_proc:
Wir erproben unsere Prozedur an zwei Beispielen:
Primzahlen(23, 45, 6)
![]()
Da wir Zufallszahlen betrachten, ist es klar, dass die obige Eingabezeile
bei mehrfacher Auswertung mit gleichen Argumenten durchaus verschiedene
Ergebnisse zurückliefern kann.
Primzahlen(23, 45, 6)
![]()
Auch für größere Werte von u, o und n ist unsere Prozedur durchaus
schnell mit ihrer Berechnung fertig.
Primzahlen(472, 67482776, 10000)
![]()
Primzahlen(472, 67482776, 10000)
![]()
Primzahlen(472, 67482776, 10000)
![]()
Streng genommen ist unsere Prozedur jedoch noch nicht vollständig.
Jemand könnte z.B. auf die Idee kommen, für u einen größeren
Wert als für o zu wählen:
Primzahlen(7, 4, 3)
Error: invalid range [random]
Dann liefert MuPAD zwar von sich aus eine Fehlermeldung, aber diese ist
für einen Benutzer, der nicht weiß, wie unsere Prozedur funktioniert,
unter Umständen schwierig zu verstehen. Wir können diese unzulässige
Eingabe z.B. durch eine if-Anweisung zuvor abfangen. Wir prüfen einfach,
ob die Zahl u kleiner ist, als die Zahl o. Ist dieses der Fall, so darf unsere
Prozedur einfach weiterrechnen. Andernfalls, also wenn u größer oder
gleich o ist, so geben wir die Fehlermeldung aus:
Error: das erste Argument muss kleiner als das zweite sein
Wie wir das in unserer Prozedur realisieren können, sehen wir jetzt:
Primzahlen:= proc(u, o, n)
local Zufallszahlen, Zufall, i, Zaehler;
begin
if u >= o then
error("das erste Argument muss kleiner als das zweite sein");
end_if;
Zufall:= random(u..o);
Zufallszahlen:= {Zufall() $ i = 1..n};
Zaehler:= 0;
for i in Zufallszahlen do
if isprime(i) = TRUE then
Zaehler:= Zaehler + 1;
end_if;
end_for;
return(Zaehler);
end_proc:
Schauen wir uns an, was nun bei der unzulässigen Eingabezeile von oben
geschieht:
Primzahlen(7, 4, 3)
Funktioniert unsere Prozedur denn auch noch, wenn wir korrekte
Eingabeparameter wählen?
Primzahlen(3, 135, 10)
Wie wir sehen, ist dies der Fall. Das liegt daran, dass wir bei der
neu eingefügten if-Anweisung wieder auf den else Teil verzichtet haben.
In dem Fall, dass u echt kleiner als o ist, ist die Bedingung der
if-Anweisung nicht erfüllt, d.h. sie wird von MuPAD einfach ignoriert
und die folgenden Programmzeilen wie gewünscht ausgeführt.
Auf ähnliche Weise kann man auch prüfen, ob für n ein sinnvoller
Wert gewählt wurde. Es sollte n z.B. einen Wert haben, der
größer als Null ist.
Primzahlen(3, 135, -4)
Momentan gibt es bei Wahl eines unsinnigen Wertes für n zwar
u.U. keine Fehlermeldung (wie wir sehen), aber dennoch können wir
dem Benutzer der Prozedur Primzahlen mit Hilfe einer Fehlermeldung
explizit mitteilen, dass der gewählt Wert für n nicht sinnvoll ist.
Primzahlen:= proc(u, o, n)
local Zufallszahlen, Zufall, i, Zaehler;
begin
if u >= o then
error("das erste Argument muss kleiner als das zweite sein");
end_if;
if n <= 0 then
error("das dritte Argument muss eine natürliche Zahl sein");
end_if;
Zufall:= random(u..o);
Zufallszahlen:= {Zufall() $ i = 1..n};
Zaehler:= 0;
for i in Zufallszahlen do
if isprime(i) = TRUE then
Zaehler:= Zaehler + 1;
end_if;
end_for;
return(Zaehler);
end_proc:
Damit ist obige Eingabezeile nicht mehr ohne Fehlermeldung durchführbar:
Primzahlen(3, 135, -4)
Zur Übung könnte man nun auch die erste Prozedur Summen mit den
entsprechenden, sinnvollen Fehlerabfragen versehen (siehe dazu das
Notebook Einfache_Prozeduren_1 des Handwerkskastens).
Generell gibt es in MuPAD noch viel mehr Möglichkeiten, bestimmte
Werte zu testen. So haben wir in der Prozedur Primzahlen nirgendwo
getestet, ob die eingegebenen Werte für u, o und n tatsächlich
ganzzahlig sind. Fälle, in denen der Benutzer u = 1/3 wählt, sind damit
nicht ausreichend abgefangen.
Eine vollkommen exakte Fehlerbehandlung wollen wir hier aber nicht
durchführen, denn eine solche ist auch von Prozedur zu Prozedur
verschieden, d.h. wir können kein allgemein gültiges Rezept angeben.
Da eine solche auch recht technisch werden kann, verzichten wir hier
darauf und verweisen auf das MuPAD Tutorium, in dem eine Vielzahl
von Beispielen angegeben ist.
Viele Beispiele zu weiteren Prozeduren finden sich auch in der
Materialsammlung unter
schule.mupad.de/material
Dort bietet sich die Möglichkeit einer Volltextsuche innerhalb aller
zum Download bereitstehenden MuPAD Notebooks. Sucht man an
dieser Stelle nach dem Begriff proc, so taucht eine Vielzahl von
Notebooks auf, in denen eigene Prozeduren vorgestellt und/oder
benutzt werden. Beachten Sie bitte auch das Notebook
Einfache Prozeduren
im Handwerkskasten.
_______________________________________________________________________________
Anmerkungen:
1. Weitere Anregungen finden Sie unter: http://schule.mupad.de bzw. http://studium.mupad.de
_______________________________________________________________________________