Zurück zum Inhaltsverzeichnis

Kapitel 30

Fehlerbehandlung

tracelast

> restart:

> test:=proc(a,b)
local n1, n2, i:
n1:=a: n2=b:
seq(i,i=n1..n2);
end:

> test(3,4);

Error, (in test) unable to execute seq

> tracelast;

test called with arguments: 3, 4
#(test,3): seq(i,i = n1 .. n2)

Error, (in test) unable to execute seq

locals defined as: n1 = 3, n2 = n2, i = i

trace

> restart:

> test:=proc(x)
if x>1 then x*test(x-1)
else 1 fi:
end:

> trace(test);

> test(2);

test(2)

> test:=proc(x)
option trace:
if x>1 then x*test(x-1)
else 1 fi:
end:

> test(2);

{--> enter test, args = 2

{--> enter test, args = 1

1

<-- exit test (now in test) = 1}

2

<-- exit test (now at top level) = 2}

2

debugging procedures

> restart;

> f:=proc(x)
option remember;
if x=0 then 0
elif x=1 then 1
else f(x-1)+f(x-2) fi
end:

> f(2.5);

Error, (in f) too many levels of recursion

> showstat(f);


f := proc(x)
1 if x = 0 then
2 0
elif x = 1 then
3 1
else
4 f(x-1)+f(x-2)
fi
end

> stopat(f,4,x<0);

[f]

> f(2.5);

f:
4? f(x-1)+f(x-2)

DBG> x;

-.5
f:
4? f(x-1)+f(x-2)

DBG> where

TopLevel: f(2.5)
[2.5]
f: f(x-1)+f(x-2)
[1.5]
f: f(x-1)+f(x-2)
[.5]
f: f(x-1)+f(x-2)
[-.5]
f:
4? f(x-1)+f(x-2)

DBG> list


f := proc(x)
1 if x = 0 then
2 0
elif x = 1 then
3 1
else
4?! f(x-1)+f(x-2)
fi
end

DBG> quit

Warning, computation interrupted

printlevel, infolevel

> test:=proc(x)
if x>1 then x*test(x-1)
else 1 fi:
end:

> printlevel:=20:

> test(3);

{--> enter test, args = 3

{--> enter test, args = 2

{--> enter test, args = 1

1

<-- exit test (now in test) = 1}

2

<-- exit test (now in test) = 2}

6

<-- exit test (now at top level) = 6}

6

> printlevel:=1:

>

> test:=proc(x)
userinfo(3, `test`, `Hello, Maple!`):
x^2:
end:

> test(3);

9

> infolevel[test]:=3:

> test(3);

test: Hello, Maple!

9

traperror

> test:=proc(x) 1/x: end:

> traperror(test(3));

1/3

> lasterror;

lasterror

> traperror(test(0));

`division by zero`

> lasterror;

maplemint

> seqn:= proc( f, l::list )
local i, data, range, `&vgl`;
range:=l:
# type checking
if not type(range[1],name=`..`) then
ERROR(`falscher Parameter`, range);
elif nops(range)>1 then
if not type(range[2], algebraic) or evalf(range[2])=0 then
ERROR(`falscher Parameter`, range);
fi;
else
range:=[ op(range), 1]:
fi;
# data will contain the nested list
data:=[]:
# i is the loop variable
i:=op(1,op(2,range[1])):
# up- or down-loop?
if evalf(range[2])>0 then `&vgl`:=(x,y)->(x<=y):
else `&vgl`:=(x,y)->(x>=y): fi:
# execute outer-loop
while evalf(i) &vgl evalf(op(2,op(2,range[1]))) do
if nargs>2 then
# call seqn recursivly for inner loops
data := [ op(data),
seqn( eval(subs( op(1,range[1])=i, f)),
op(eval(subs( op(1,range[1])=i, [args[3..nargs]])))) ];
else
data := [ op(data), eval(subs( op(1,range[1])=i, f)) ];
fi:
i:=eval(i)+range[2];
od;
[op(data)];
end:

> maplemint(seqn);

These local variables have the same name as system names:
range
These local variables have the same name as constants:
37
These names were used as global names, but were not declared:
`falscher Parameter`
These local variables were assigned a value, but otherwise unused:
`&vgl`

try - catch - finally

Sicheres schreiben in Dateien:

> speicherePZ:=proc(Dateiname,anzahl)
local datnr,i;
try
datnr:=fopen(Dateiname,WRITE,TEXT);
catch "file I/O error":
error "Datei %1 konnte nicht geöffnet werden!",Dateiname;
end try;
i:=1;
try
while i<=anzahl do
fprintf(datnr,"Die %dte Primzahl ist: %d\n",i,ithprime(i));
i:=i+1;
if i>5 then
error "Zahl zu groß %1",i;
end if;
end do
catch:
printf("Das war ein Fehler: i=%d",i);
error;
finally
fclose(datnr);
end try
end proc:

> speicherePZ("c:\\dat1.txt",20);

Das war ein Fehler: i=6

Error, (in speicherePZ) Zahl zu groß 6

>

>

Analyse des Zeit- und Speicherbedarfs von Prozeduren

showtime

> restart:

> showtime();

O1 := simplify(sin(x)^2+cos(x)^2);

1

time = 0.34, bytes = 215930

O2 := int(1/(1+x^5),x):

time = 1.67, bytes = 1841878

O3 := O1;

1

time = 0.01, bytes = 3114

O4 := off;

profile

> restart:

> nestprint:=proc(x)
local i,n;
if nargs=2 then n:=args[2]; else n:=0; fi:
for i from 0 to n do printf(` `); od:
if type(x,function) then
lprint(op(0,x));
for i from 1 to nops(x) do: nestprint(op(i,x),n+1): od:
elif nops(x)>1 then
lprint(whattype(x));
for i from 1 to nops(x) do: nestprint(op(i,x),n+1): od:
else
lprint(op(x));
fi;
end:

>

> profile(nestprint,lprint,int):

> nestprint( int(1/(1+x^5),x));

`+`

`*`

fraction

1

5

ln

`+`

x

1

`*`

fraction

-1

20

ln

`+`

`*`

2

`^`

x

2

`*`

-1

x

`*`

-1

`^`

5

fraction

1

2

x

2

`*`

fraction

-1

20

ln

`+`

`*`

2

`^`

x

2

`*`

-1

x

`*`

-1

`^`

5

fraction

1

2

x

2

`^`

5

fraction

1

2

`*`

`^`

`+`

10

`*`

-2

`^`

5

fraction

1

2

fraction

-1

2

arctan

`*`

`+`

`*`

4

x

-1

`*`

-1

`^`

5

fraction

1

2

`^`

`+`

10

`*`

-2

`^`

5

fraction

1

2

fraction

-1

2

`*`

fraction

-1

5

`^`

`+`

10

`*`

-2

`^`

5

fraction

1

2

fraction

-1

2

arctan

`*`

`+`

`*`

4

x

-1

`*`

-1

`^`

5

fraction

1

2

`^`

`+`

10

`*`

-2

`^`

5

fraction

1

2

fraction

-1

2

`^`

5

fraction

1

2

`*`

fraction

1

20

ln

`+`

`*`

2

`^`

x

2

`*`

-1

x

`*`

`^`

5

fraction

1

2

x

2

`^`

5

fraction

1

2

`*`

fraction

-1

20

ln

`+`

`*`

2

`^`

x

2

`*`

-1

x

`*`

`^`

5

fraction

1

2

x

2

`*`

`^`

`+`

10

`*`

2

`^`

5

fraction

1

2

fraction

-1

2

arctan

`*`

`+`

`*`

4

x

-1

`^`

5

fraction

1

2

`^`

`+`

10

`*`

2

`^`

5

fraction

1

2

fraction

-1

2

`*`

fraction

1

5

`^`

`+`

10

`*`

2

`^`

5

fraction

1

2

fraction

-1

2

arctan

`*`

`+`

`*`

4

x

-1

`^`

5

fraction

1

2

`^`

`+`

10

`*`

2

`^`

5

fraction

1

2

fraction

-1

2

`^`

5

fraction

1

2

> showprofile();

function depth calls time time% bytes bytes%

---------------------------------------------------------------------------

int 1 1 .200 55.40 1854316 64.82

nestprint 10 285 .101 27.98 931784 32.57

lprint 1 285 .060 16.62 74528 2.61

---------------------------------------------------------------------------

total: 12 571 .361 100.00 2860628 100.00

> unprofile(nestprint,lprint,int):

Die neue Funktion seqn

> restart:

Version 1: seq1

> seq1:= proc( f::uneval, range::uneval )
local i, data,von,bis,inc, `&vgl`, seqvar;
if not type(range,name=`..`) then
error "Das zweite Argument soll die Form name=Bereich haben %0",range;
end if;
von:= eval(lhs(rhs(range)));
bis:= eval(rhs(rhs(range)));
seqvar:= lhs(range);
if (nargs>2) then
inc:=args[3];
elif is(von >= bis) then
inc:=-1;
else inc:=1;
end if;
if is(inc=0) then
error "Das Schleifeninkrement darf nicht 0 sein";
end if:
if not (type(eval(inc),algebraic)) then
error "Das Inkrement muss algebraisch sein";
end if;
if (is(von <= bis) and is(inc>0)) or (is(von>=bis) and is(inc>0)) then
`&vgl`:=(x,y)->is(x <= y);
else
`&vgl`:= (x,y)->is(x >= y);
end if;
data:=NULL:
i:=von;
while is(i &vgl bis) do
data := data, eval(subs( seqvar=i, f));
i:=i+inc;
end do;
data;
end:

>

>

> seq1(x^2, x=6..2, -0.5);

36, 30.25, 25.00, 20.25, 16.00, 12.25, 9.00, 6.25, ...

> seq1(x^2, x=0..Pi, Pi/4);

0, 1/16*Pi^2, 1/4*Pi^2, 9/16*Pi^2, Pi^2

> x:=3:seq1(x^2, x=2..3,1);

4, 9

> x:='x':

> seq1(sin(n*x),x=0..2*Pi, Pi/2);

0, sin(1/2*n*Pi), sin(n*Pi), sin(3/2*n*Pi), sin(2*n...

> n:=1/8:
seq1(sin(n*x),x=0..2*Pi, Pi/2);

0, sin(1/16*Pi), sin(1/8*Pi), sin(3/16*Pi), 1/2*sqr...

> n:='n':

> seq1([seq1(x*y,x=0..3,1/2)],y=1..2);

[0, 1/2, 1, 3/2, 2, 5/2, 3], [0, 1, 2, 3, 4, 5, 6]

> [seq1([seq1(x*y,y=2..4)],x=0..6,2)];

[[0, 0, 0], [4, 6, 8], [8, 12, 16], [12, 18, 24]]

Version 2: seqn
(Der zweite Parameter muss eine geschachtelte Liste sein)

> seqn:=proc(term::uneval, ll::uneval)
if type(ll,list) then
if type(ll[1],list) then
if nops(ll)=1 then
op(op(ll)):
[seq1(term,%)];
else
op(ll[1]):
ll[2..-1]:
[seq1( seqn(term, %), %%)];
end if:
else
op(ll);
[seq1(term,%)]:
end if:
else
error "Eingabe muss eine Liste oder eine geschachtelte Liste sein %1" ,ll:
end if:
end proc:

> x:='x': y:='y':

> seqn(x,[x=1..3]);

0, 1/4*Pi^2, Pi^2

> seqn( x^y, [[x=0..3], [y=2..4]]);

4, 9, 16

> seqn( x^y, [[x=0..3], [y=0..x]]);

[[0], [1, 1], [1, 2, 4], [1, 3, 9, 27]]

> n:='n': m:=1/Pi: x:=3: y:=4:

> seqn( n*m*x^y, [[x=0..3], [y=2..4]]);

[[0, 0, 0], [n/Pi, n/Pi, n/Pi], [4*n/Pi, 8*n/Pi, 16...

trace seqn and seq1 to see how they work!

> trace(seqn,seq1):

> seqn( x^y, [[x=0..3], [y=0..x]]);

{--> enter seqn, args = x^y, [[x = 0 .. 3], [y = 0 .. x]]

x = 0 .. 3

[[y = 0 .. x]]

{--> enter seq1, args = seqn(x^y,[[y = 0 .. x]]), x = 0 .. 3

von := 0

bis := 3

seqvar := x

inc := 1

`&vgl` := proc (x, y) options operator, arrow; is(x...

data := NULL

i := 0

{--> enter seqn, args = 0, [[y = 0 .. 0]]

y = 0 .. 0

{--> enter seq1, args = 0, y = 0 .. 0

von := 0

bis := 0

seqvar := y

inc := -1

`&vgl` := proc (x, y) options operator, arrow; is(y...

data := NULL

i := 0

data := 0

i := -1

0

<-- exit seq1 (now in seqn) = 0}

[0]

<-- exit seqn (now in seq1) = [0]}

data := [0]

i := 1

{--> enter seqn, args = 1, [[y = 0 .. 1]]

y = 0 .. 1

{--> enter seq1, args = 1, y = 0 .. 1

von := 0

bis := 1

seqvar := y

inc := 1

`&vgl` := proc (x, y) options operator, arrow; is(x...

data := NULL

i := 0

data := 1

i := 1

data := 1, 1

i := 2

1, 1

<-- exit seq1 (now in seqn) = 1, 1}

[1, 1]

<-- exit seqn (now in seq1) = [1, 1]}

data := [0], [1, 1]

i := 2

{--> enter seqn, args = 2^y, [[y = 0 .. 2]]

y = 0 .. 2

{--> enter seq1, args = 2^y, y = 0 .. 2

von := 0

bis := 2

seqvar := y

inc := 1

`&vgl` := proc (x, y) options operator, arrow; is(x...

data := NULL

i := 0

data := 1

i := 1

data := 1, 2

i := 2

data := 1, 2, 4

i := 3

1, 2, 4

<-- exit seq1 (now in seqn) = 1, 2, 4}

[1, 2, 4]

<-- exit seqn (now in seq1) = [1, 2, 4]}

data := [0], [1, 1], [1, 2, 4]

i := 3

{--> enter seqn, args = 3^y, [[y = 0 .. 3]]

y = 0 .. 3

{--> enter seq1, args = 3^y, y = 0 .. 3

von := 0

bis := 3

seqvar := y

inc := 1

`&vgl` := proc (x, y) options operator, arrow; is(x...

data := NULL

i := 0

data := 1

i := 1

data := 1, 3

i := 2

data := 1, 3, 9

i := 3

data := 1, 3, 9, 27

i := 4

1, 3, 9, 27

<-- exit seq1 (now in seqn) = 1, 3, 9, 27}

[1, 3, 9, 27]

<-- exit seqn (now in seq1) = [1, 3, 9, 27]}

data := [0], [1, 1], [1, 2, 4], [1, 3, 9, 27]

i := 4

[0], [1, 1], [1, 2, 4], [1, 3, 9, 27]

<-- exit seq1 (now in seqn) = [0], [1, 1], [1, 2, 4], [1, 3, 9, 27]}

[[0], [1, 1], [1, 2, 4], [1, 3, 9, 27]]

<-- exit seqn (now at top level) = [[0], [1, 1], [1, 2, 4], [1, 3, 9, 27]]}

[[0], [1, 1], [1, 2, 4], [1, 3, 9, 27]]

> untrace(seqn,seq1):

> seqn( x+y+z,[[x=1..2],
[y=10..20, 10],
[z=100..200, 100]]);

[[[111, 211], [121, 221]], [[112, 212], [122, 222]]...

> n:='n': m:=1/Pi: x:=3: y:=4:

> seqn( n*m*x^y, [[x=0..3], [y=2..4]]);

[[0, 0, 0], [n/Pi, n/Pi, n/Pi], [4*n/Pi, 8*n/Pi, 16...

Module

> zähler:=module()
export nächste;
local zahl;
zahl:=0;
nächste:=proc()
zahl:=zahl+1;
end proc;
end module:

> zähler:-nächste();

1

> use zähler in nächste(),nächste(),nächste(); end use;

2, 3, 4

> make_zähler:=proc(start)
local zahl,zähler;
zahl:=start;
zähler:=module()
export nächste;
nächste:=proc()
zahl:=zahl+1;
end proc;
end module:
end proc:

> z1:=make_zähler(5):z2:=make_zähler(0):

> z1:-nächste(),z2:-nächste();

6, 1

>

>

> make_stack:=proc()
local stack,stack_modul;
stack:=[];
stack_modul:=module()
export push,pop,empty;
push:=proc(Objekt)
stack:=[Objekt, op(stack)];
NULL;
end proc;
pop:=proc()
local erg;
if nops(stack)=0 then error "pop mit leerem Stack" end if;
erg:=stack[1];
stack:=stack[2..-1];
erg;
end proc:
empty:=proc()
is(nops(stack)=0);
end proc:
end module;
end proc:

> s1:=make_stack():

> s2:=make_stack():

> s1:-push(3);s2:-push(5);

> eval(op(7,eval(s1:-push)));

stack, [3]

> eval(op(7,eval(s2:-push)));

stack, [5]

> s1:-pop();

3

>

> eval(op(7,eval(s2:-push)));

stack, [5]

> s1:-empty();

true

> s2:-empty();

false

> s2:-pop();

5

stringtools

Der folgende Modul stellt Funktionen zur Bearbeitung von Strings bereit

> restart:

> stringtools:=module()
export left,right,mid,trim,ascii,upper,lower,
pos,vor,nach,split1,replace,frueher;
local i,pos1;
left:=(str::string,n::posint)->str[1..n];
right:=(str::string,n::posint)->str[-n..-1];
mid:=proc(str::string,lnks::posint,anz::posint)
if nargs=2 then
str[lnks..-1];
else
str[lnks..lnks+anz-1];
end if;
end proc;
trim:=proc(str::string)
local s0;
s0:=str;
while s0[1]=" " do
s0:=s0[2..-1];
end do;
s0;
end proc;

ascii:=(str::string)->op(convert(str[1],'bytes'));

upper:=proc(str::string)
local ka,kz,kae,kue,koe,ksz,dist,einsup;
ka:=ascii("a");
kz:=ascii("z");
kae:=ascii("ä");
koe:=ascii("ö");
kue:=ascii("ü");
ksz:=ascii("ß");
einsup:=proc(str)
local asc;
asc:=ascii(str);
if ((asc>=ka) and (asc<=kz)) or (asc=kae) or (asc=kue) or (asc=koe)
then
convert([asc-32],'bytes');
elif (asc=ksz)
then
"SS";
else
str;
end if
end proc;
cat(map(einsup,convert(str,'list'))[],"");
end proc;

lower:=proc(str::string)
local ka,kz,kae,kue,koe,dist,einsdown;
ka:=ascii("A");
kz:=ascii("Z");
kae:=ascii("Ä");
koe:=ascii("Ö");
kue:=ascii("Ü");
einsdown:=proc(str)
local asc;
asc:=ascii(str);
if ((asc>=ka) and (asc<=kz)) or (asc=kae) or (asc=kue) or (asc=koe)
then
convert([asc+32],'bytes');
else
str;
end if
end proc;
cat(map(einsdown,convert(str,'list'))[],"");
end proc;

pos := proc(muster::string,str::string,bereich::{range,integer})
local rng,p;
rng:=1..-1;
if nargs>2 then
if type(bereich,integer) then
rng:=bereich..-1;
else
rng:=bereich;
end if;
end if;
p:=searchtext(muster,str,rng);
if p>0 then
p+lhs(rng)-1;
else
0;
end if;
end proc;

vor:=proc(muster::string,str::string)
local i;
i:=searchtext(muster,str);
if i=0 then
str;
else
str[1..(i-1)];
end if;
end proc;

nach:=proc(muster::string,str::string)
local i;
i:=searchtext(muster,str);
if i=0 then
"";
else
str[i+length(muster)..-1]
end if;
end proc;

split1:=proc(muster::string,str::string)
local i;
i:=searchtext(muster,str);
if i=0 then
str,"";
else
str[1..(i-1)],str[i+length(muster)..-1];
end if
end proc;

replace:=proc(alt::string,neu::string,str::string)
local a,b;
a,b:=split1(alt,str);
if b="" then
str;
else
cat(a,neu,replace(alt,neu,b));
end if;
end proc;

frueher :=proc(str1::string,str2::string)
local s1,s2;
s1:=replace("Ü","UE",replace("Ö","UE",replace("Ä","AE",upper(str1))));
s2:=replace("Ü","UE",replace("Ö","UE",replace("Ä","AE",upper(str2))));
evalb(s1<s2);

end proc;

end module:

> with(stringtools);

[ascii, frueher, left, lower, mid, nach, pos, repla...

> ascii("ß");

223

> upper("Häußer");

> satz_worte:=proc(satz::string)
local w0,s1;
w0,s1:=stringtools:-split1(" ",satz);
if s1="" then
w0;
else
w0,satz_worte(s1);
end if;
end proc:

> satz1:="Der Habicht war so dicht wie lange nicht";

satz1 :=

> satz_worte(satz1);

> sort([%],frueher);

[

>

Packages und Libraries

seq1, seqn, makestack und stringtoos müssen definiert sein. Öffnen Sie andernfalls den vorigen

Abschnitt und führen Sie dort die Definitionen durch.

saving and reading

> save seqn, seq1,make_stack,stringtools, `tools`: # text format

> save seqn, seq1,make_stack,stringtools, `tools.m`: # binary format

> restart:

libname:

savelibname:

> read `tools`:

> seqn(x^y, [[x=1..3], [y=1..3]]);

[[1, 1, 1], [2, 4, 8], [3, 9, 27]]

> s1:=make_stack(): s1:-push(13);s1:-pop();

13

> stringtools:-upper("häßliches Entlein");

building packages

> restart:

libname:

savelibname:

> read `tools`:

> mypack:=table():

> mypack[seqn]:=eval(seqn):

> mypack[seq1]:=eval(seq1):

> mypack[make_stack]:=eval(`make_stack`):

> mypack[seqn](x, [x=1..2, 0.5] );

[1, 1.5, 2.0]

> save mypack, `mypack.m`;

> restart:

libname:

savelibname:

> read `mypack.m`;

> with(mypack);

[make_stack, seq1, seqn]

> seqn(x, [x=0..Pi, Pi/6]);

[0, 1/6*Pi, 1/3*Pi, 1/2*Pi, 2/3*Pi, 5/6*Pi, Pi]

> restart:

libname:

savelibname:

> libname:=libname, `.`;

libname :=

> with(mypack);

[make_stack, seq1, seqn]

> seqn(x, [x=100..0, -10]);

[100, 90, 80, 70, 60, 50, 40, 30, 20, 10, 0]

Neue Libraries bzw. Repositories

Dieser Abschnitt setzt voraus, dass

# maple.ini
savelibname:="C:\\Programme\\Maple 6/mylib":
libname:=libname, savelibname:
print("initfile maple.ini"):
printf("libname: \n"):
print(libname):
printf("savelibname: \n"):
print(savelibname):

Packages in einer neuen Library speichern

> restart:

libname:

savelibname:

Der folgende Befehl darf nur einmal durchgeführt werden. Er erzeugt im angegebenen Verzeichnis eine neue Library

> march('create',savelibname,40);

> read `tools`:

> mypack:=table():

> mypack[seqn]:=eval(seqn):

> mypack[seq1]:=eval(seq1):

> mypack[make_stack]:=eval(make_stack):

> savelib(mypack, `mypack.m`);

>

> savelib(stringtools);

>

Die Benutzung der beiden Packages

>

> restart:

libname:

savelibname:

> with(mypack);

[make_stack, seq1, seqn]

> seqn(x,[x=3..1,-1]);

[3, 2, 1]

> with(stringtools);

[ascii, frueher, left, lower, mid, nach, pos, repla...

Definition von mypack über eine Textdatei

mypack.mpl muss im currend-directory sein

> restart:

libname:

savelibname:

> read `mypack.mpl`:

Benutzung der Package (nichts neues)

> restart:

libname:

savelibname:

> with(mypack);

[seqn]

> seqn(x,[x=1..3]);

[1, 2, 3]

>

Zurück zum Inhaltsverzeichnis