# assert vor und nachbedingung



## DrippleTripple (17. Mrz 2009)

Hallo,

ich habe hier bei java ist auch eine Insel über asserts erfahren. also die möglichkeit bedingungen in das Programm einzubauen, sodass man auf Exceptions verzichtet...

Leider sind da kaum Bsp. so dass ich nicht recht weiß, wann man welche asserts einbauen sollte und wann nicht und ob es immer vorbedingung mit einer nach bedingung verknüpft werden muss. muss es auch assert innerhalb von schleifen geben???

Hier also eine konkrete Frage (eine Aufgabe aus dem anderen Buch):

Es sei die Methode gegeben:

static intf(int n) {
assert n>=0; // Vorbedingung
int s=0,
r=1;
for (int i = 0; i <=n;i++){
s = s+r;
r = r+2;
}
assert...; // Nachbedingung (*)
return s;
}

Und hier nun ein wenig dubiosen Fragen in meinen Augen... 

Welche Werte besitzen r und s zum Zeitpunkt der Ausführung der Nachbedingung? Formulieren Sie eine enstsprechende Nachbedingung. Schreiben Sie die Nachbedingung als Java Ausdruck, so dass dieser in der assert (*) Anweisung verwendet werden kann.

Also ist mir alles ein wenig Schleierhaft. Erstens ist n nirgends deklariert... also kann es ja jeden beliebigen Wert annehmen, welcher größer oder gleich null ist... Die Variablen sind ja von gerde abhängig, da ja n letzendlich bestimmt wie oft die schleife durchalufen wird.

Und Nachbedingung kann doch letzendlich alles sein oder??? 

Stehe da ein wenig auf dem Schlauch und weiß nicht was ich mit sowas nafangen soll... Wäre also für jede Hilfe dankbar.


----------



## Mostly_Harmless (17. Mrz 2009)

DrippleTripple hat gesagt.:


> Also ist mir alles ein wenig Schleierhaft. Erstens ist n nirgends deklariert... also kann es ja jeden beliebigen Wert annehmen, welcher größer oder gleich null ist... Die Variablen sind ja von gerde abhängig, da ja n letzendlich bestimmt wie oft die schleife durchalufen wird.



n kann nicht nur jeden beliebigen Wert annehmen, welcher größer oder gleich null ist, sondern auch einen negativen Wert.
Aber darum geht es ja bei der assert-Anweisung: Du gehst davon aus, dass die Bedingung hinter assert _immer_ wahr ist. Falls das nicht der Fall ist, wird halt ein AssertionError geworfen.



DrippleTripple hat gesagt.:


> Und Nachbedingung kann doch letzendlich alles sein oder???



Wenn du davon ausgehst, dass n >= 0 gilt, dann setz für n einfach mal 0 ein.
Die Schleife wird dann genau einmal ausgeführt, s ist danach also 1.
Eine mögliche Nachbedingung wäre somit:
assert s>=1;

*Meiner Meinung nach sollte auf assert-Anweisungen aber komplett verzichtet werden.*


----------



## DrippleTripple (17. Mrz 2009)

also kann ich wirklicj als nachbedingung fast alles einsetzen oder? sprich genauso s>=2?
 oder muss ich dann den kleinsten möglichen wert wählen? durch die erste assert anweisung habe ich ja schon gewährlesitet, dass wenn n<0 das Programm unterbrochen wird.

Und auf die Frage welche Werte s und r haben, kann wirklich nicht antworten oder??? Sondern eben schreiben, dass die alle möglichen von n und der Nachbedingung (könnte ja sagen s<5) abhängigen Werte annehmen können oder?


----------



## Mostly_Harmless (17. Mrz 2009)

DrippleTripple hat gesagt.:


> also kann ich wirklicj als nachbedingung fast alles einsetzen oder? sprich genauso s>=2?



Die Nachbedingung ist von der Vorbedingung abhängig.
Hättest du als Vorbedingung *assert n>=10*, dann wäre die Nachbedingung in dem Programm, dass s größer gleich dem Wert für s für n=10 ist.



DrippleTripple hat gesagt.:


> oder muss ich dann den kleinsten möglichen wert wählen?



In diesem Fall: ja.



DrippleTripple hat gesagt.:


> Und auf die Frage welche Werte s und r haben, kann wirklich nicht antworten oder??? Sondern eben schreiben, dass die alle möglichen von n und der Nachbedingung (könnte ja sagen s<5) abhängigen Werte annehmen können oder?



s<5 würde hier aber _niemals wahr_ ergeben, solange die Vorbedingung erfüllt wird.
Daher ist die Nachbedingung wie gesagt von der Vorbedingung abhängig.


----------



## DrippleTripple (17. Mrz 2009)

Bestimme ich also über die Nachbedingung und die variable S den wert von n?
Zumindest auf diesen Fall bezogen? Versuche mich gleich sleber an einem Besipiel, würde mich freuen, wenn du mir dann sagen könntest ob ich das richtig gemacht habe.


----------



## Mostly_Harmless (17. Mrz 2009)

DrippleTripple hat gesagt.:


> Bestimme ich also über die Nachbedingung und die variable S den wert von n?



Genau umgekehrt: Deine *Annahme* über den Wert von n (VORbedingung) bestimmt über das Ergebnis s (NACHbedingung).



DrippleTripple hat gesagt.:


> Versuche mich gleich sleber an einem Besipiel, würde mich freuen, wenn du mir dann sagen könntest ob ich das richtig gemacht habe.



Nur zu.


----------



## DrippleTripple (17. Mrz 2009)

static int f(int n){
assert n>=1;
int i=1,
    s=0;
while (i<=n){
s+=i*(3*i-1),
i++;
}
assert ... ; // die zu bestimmende Nachbedingung
return s;
}

also würde ich sagen dass meine nachbedingung s>=2 sein sollte;

die werte von s und sind dann beim durchlaufen der nachbedingung 2 und 2

jetzt werde ich noch gefragt schrieben sie die nachbedingung als java ausdruck hin,

das ist doch dann einfach assert s>=2; oder??? 

und ich soll eine partielle Korrektheit bezüglich der Vor und Nachbedingung mittels einer geeigntene Schleifenvariante bestimmen. Das weiß ich leider nicht.., genau wie das gemacht werden soll.


----------



## fjord (17. Mrz 2009)

DrippleTripple hat gesagt.:


> [...]
> Hier also eine konkrete Frage (eine Aufgabe aus dem anderen Buch):
> 
> Es sei die Methode gegeben:
> ...


Was für ein Buch hat so eine Aufgabe? 
Ist imo ganz schlechter Stil und um mal aus den Java-Docs zu assertions zu zitieren:





> *Do not use assertions to check the parameters of a public method.* An assert is inappropriate because the method guarantees that it will always enforce the argument checks. It must check its arguments whether or not assertions are enabled. Further, the assert construct does not throw an exception of the specified type. It can throw only an AssertionError.



Deine Aussage, dass man mit assertions auf Exceptions verzichten kann, ist so auch nicht richtig. Exceptions sind dafür da, um Abweichungen vom normalen Programmablauf zu signalisieren, so dass das Programm entsprechend darauf reagieren kann. Dies könnte z. B. eine NumberFormatException sein, die Auftritt beim parsen einer Benutzereingabe.
Assertions dagegen sind dafür da um Bugs zu finden. Damit sichert man dem Programm Bedingungen zu, die einfach nie auftreten dürfen. Wenn dein Programm gänzlich fehlerfrei ist, darf kein einziger AssertionError geworfen werden, Exceptions hingegen sind möglich und evtl. auch nötig.


----------



## Mostly_Harmless (17. Mrz 2009)

DrippleTripple hat gesagt.:


> also würde ich sagen dass meine nachbedingung s>=2 sein sollte;
> [...]
> das ist doch dann einfach assert s>=2; oder???



Genau. 



DrippleTripple hat gesagt.:


> und ich soll eine partielle Korrektheit bezüglich der Vor und Nachbedingung mittels einer geeigntene Schleifenvariante bestimmen. Das weiß ich leider nicht.., genau wie das gemacht werden soll.



Wenn du den Begriff "Partielle Korrektheit" nicht verstehst, steht dazu was in der Wikipedia.

Allerdings weiß ich ehrlich gesagt auch nicht genau, was jetzt an der Schleife geändert werden soll.

*Edit: Und wie ich bereits angemerkt hab und fjord nun bestätigt hat: assert-Anweisungen sind nicht schön.*


----------



## DrippleTripple (17. Mrz 2009)

@fjord: Das Buch heißt Java Start Up Und danke dir für die richtigstellung bezüglich der exception und assert anweisung.

Ja danke hm, verstehe zwar nun was partielle Korrektheit bedeutet aber weiß ich nicht was ich der Schleife  ändern soll.

Na ich schaue noch mal.


----------

