Objektorientierte Programmierung
LVA 185.162, VL 2.0, 2010 W

Hinweise zur Beurteilung der 4. Übungsaufgabe

Einleitung:

Die vorläufige Beurteilung der 4. Aufgabe (reguläre Abgabe) ist zwiespältig ausgefallen, für einige Gruppen besser, für andere schlechter (im Vergleich zum letzten Jahr). Diese Seite soll die häufigsten und wichtigsten Fehler, die dabei gemacht wurden, aufzeigen, weitere Hinweise zum Erkennen und Vermeiden der Fehler geben, wahrscheinliche Gründe für das Zustandekommen der Fehler erklären und das Beurteilungsschema kurz erläutern.

Bei einer nachträglichen Abgabe ist zu beachten, dass die Beanstandung konkreter Fehler der regulären Abgabe keine direkten Rückschlüsse auf eine korrekte Lösung zulässt. Durch das Ausbessern dieser Fehler wird die Lösung nicht notwendigerweise richtig, sondern kann andere (nicht selten noch schwerwiegendere) Fehler enthalten. Versuchen Sie daher, die Gründe für Ihre Fehler und die richtige Lösung zu verstehen.

Schwerwiegendste Fehler:

Die Aufgabe ist so aufgebaut, dass die Untertypbeziehungen zwischen den geforderten Typen eindeutig sind. In vielen Lösungen wurden diese jedoch nicht richtig erkannt. Außerdem wurden Teilaufgaben, die bei der Erkennung falscher Lösungen helfen sollten, häufig nicht gemacht und Empfehlungen in der Aufgabenstellung nicht beachtet. Folgende Klassen von Fehlern spielen eine große Rolle:
Untertypbeziehung angenommen, wo keine besteht:
Das ist ein häufiger Grund für starke Punkteabzüge. Durch die genaue Beschreibung der geforderten Typen besteht wenig Spielraum beim Entwurf geeigneter Untertypbeziehungen. Trotzdem wurden alle möglichen Arten von Untertypbeziehungen angenommen, die nach dem Ersetzbarkeitsprinzip gar nicht existieren können. Die Methode transform ist hauptsächlich davon betroffen. Starke Punkteabzüge kommen vor allem daher, dass falsche Untertypbeziehungen ein wichtiger Grund für schwerwiegende Softwarefehler und nicht wartbaren Code in praktisch eingesetzten Systemen sind.
Keine Untertypbeziehung angenommen, wo eine bestehen könnte:
Das kommt noch häufiger vor und führt zu deutlichen Punkteabzügen, da das Erkennen von Untertypbeziehungen der wichtigste Schwerpunkt dieser Aufgabe ist. Die Punkteabzüge sind weniger stark als im umgekehrten Fall, da solche Fehler zwar die Wartung erschweren, aber nicht zu falschem Verhalten der Software führen.
Keine, nicht hinreichende oder zu ungenaue Zusicherungen:
Untertypbeziehungen beruhen zum größten Teil auf Zusicherungen. Bei vielen Lösungen waren die Zusicherungen in der einen oder anderen Form mangelhaft. Vor allem haben viele Gruppen die Nachbedingungen auf transform, auf die es in dieser Aufgabe hauptsächlich ankommt, nur halbherzig formuliert. Für mangelhafte Zusicherungen wurden je nach Größe des Problems unterschiedlich viele Punkte abgezogen.
Fehlende Begründung für nicht vorhandene Untertypbeziehungen:
In der Aufgabenstellung waren Gegenbeispiele für nicht vorhandene Untertypbeziehungen verlangt. Dieser Teil wurde am häufigsten ignoriert, obwohl entsprechende Überlegungen fast automatisch zu einer richtigen Typhierarchie geführt hätten.
Kopieren einer Standardlösung:
Anscheinend haben sich einige Teilnehmer nicht auf die eigenen Fähigkeiten verlassen, sondern die eigenen Lösungen auf einem von anderen entwickelten Grundgerüst aufgebaut. Häufig führt dies jedoch zu einer ganzen Reihe kleiner Unstimmigkeiten und Fehler, die daher rühren, dass das Grundgerüst nicht gut mit anderen Teilen harmoniert. Beispielsweise passen Typhierarchien und Zusicherungen nicht zusammen, oder mangels Mitwirkung bei der Entwicklung der Typhierarchien fehlen brauchbare Ideen für das Testen der Untertypbeziehungen und für die Begründung nicht vorhandener Untertypbeziehungen. Solche Unstimmigkeiten führen nicht selten zu Punkteabzügen in der vorläufigen Beurteilung. Vor allem entsteht durch das Kopieren (wesentlicher Teile) der Lösung jedoch die Gefahr einer negativen Beurteilung oder zumindest einer gravierenden Herabstufung beim Abgabegespräch.

Ersetzbarkeit:

Folgende Hinweise beziehen sich nur auf einige wenige Beziehungen zwischen den in dieser Aufgabe vorgegebenen Typen, die exemplarisch dargestellt werden. Es werden nicht alle denkbaren Beziehungen angesprochen.
Ist VarPretty Untertyp von LongPretty?
Um diese Frage zu beantworten, brauchen wir nur die beiden Beschreibungen (genauer: die Zusicherungen) der Typen gegenüberstellen. Die Antwort ist Ja, wenn die Nachbedingungen und Invarianten in VarPretty jenen in LongPretty entsprechen, aber möglicherweise genauer sind (also auf mehr Details eingehen), und die Vorbedingungen in LongPretty jenen von VarPretty entsprechen, aber möglicherweise genauer sind.

Nachbedingungen auf transform in LongPretty beschreiben recht genau, wie der Eingabe-String verändert wird. Nachbedingungen auf transform in VarPretty beschreiben nur bedingt dasselbe Verhalten wie in LongPretty, da das Ergebnis vom Inhalt einer zusätzlichen Variable abhängt. In bestimmten Fällen verhält sich transform in VarPretty tatsächlich gleich wie in LongPretty, aber nicht immer. Nach Aufrufen von setMode und reset kann sich transform in VarPretty ganz anders verhalten als in LongPretty. Da für Ersetzbarkeit das Verhalten immer kompatibel sein muss (und nicht nur manchmal) ist zwischen diesen Typen keine Ersetzbarkeit gegeben. Testfälle, in denen setMode und reset aufgerufen werden, zeigen das unterschiedliche Verhalten zwischen den beiden Typen auf.

Ein wichtiger Grund für die fehlende Untertypbeziehung zwischen diesen beiden Typen ist folgender: Das Verhalten von transform ist in beiden Klassen so genau festgelegt, dass man eine Beschreibung (= Nachbedingung) nicht mehr als allgemeinere Variante der anderen ansehen kann. Man könnte die Beschreibung in LongPretty verallgemeinern, indem man weniger Details festlegt, und dadurch VarPretty zu einem Untertyp von LongPretty werden lässt. Diese verallgemeinerte Beschreibung würde jedoch nicht der Aufgabenstellung entsprechen und daher als falsch beurteilt werden. Aber in einer abstrakten gemeinsamen Oberklasse kann man die Beschreibung durchaus auf diese Weise verallgemeinern, ohne eine Bedingung in der Aufgabenstellung zu verletzen.

Ist NoPretty Untertyp von BlockPretty?
Diese Untertypbeziehung ist tatsächlich gegeben: Eine Instanz von NoPretty entspricht einer Instanz von BlockPretty wenn der Parameter des Konstruktors auf 0 gesetzt wird, da dieser Wert (nach Erzeugung der Instanz) nicht mehr geändert werden kann. Dadurch entsprechen einander auch die Zusicherungen aller Instanzmethoden der beiden Klassen bei diesem Parameterwert (in jedem Fall, das heißt, egal welche erlaubten Methoden ausgeführt werden). NoPretty ist spezieller als BlockPretty. Umgekehrt kann BlockPretty deswegen kein Untertyp von NoPretty sein, da sonst ja auch Instanzen von BlockPretty, die Leerzeilen einfügen, Instanzen von NoPretty wären und damit die Nachbedingung verletzen würden.

Fehlerursachen:

Die tatsächlichen Ursachen für die schwerwiegendsten Fehler können nur vermutet werden. Folgendes spielt aber sicherlich eine Rolle:
Verwechslung von Untertyp- mit is-a-Beziehungen:
Viele Teilnehmer haben den Umgang mit is-a-Beziehungen schon in anderen Lehrveranstaltungen gelernt. Solche aus der realen Welt abgeleiteten Beziehungen sind vor allem in einer frühen Designphase wichtig, um Softwareeinheiten in Relation zueinander zu setzen und dadurch zu brauchbaren Faktorisierungen zu kommen. Häufig lassen sich is-a-Beziehungen zu Untertypbeziehungen weiterentwickeln, aber nicht immer. Diese Aufgabe wurde absichtlich so gewählt, dass is-a-Beziehungen kaum zu Untertypbeziehungen weiterentwickelt werden können, damit Verwechslungen zwischen diesen Beziehungen möglichst ausgeschlossen werden. Es geht in dieser Aufgabe nicht darum, intuitiv abzuschätzen, ob und wie je zwei Typen zueinander in Beziehung stehen könnten (das wäre eine is-a-Beziehung), sondern ausschließlich darum, ob die Beschreibung eines Typs auch der Beschreibung eines anderen Typs (für alle möglichen Verwendungsfälle) entspricht. Wer das Gefühl hat, dass die Aufgabe je nach Sichtweise verschiedene Lösungen haben kann, hat diese beiden Arten von Beziehungen mit großer Wahrscheinlichkeit miteinander verwechselt. Untertypbeziehungen sind (bei ausreichend klar formulierten Zusicherungen) im Gegensatz zu is-a-Beziehungen immer eindeutig.
Verwechslung von Untertyp- mit Vererbungs-Beziehungen:
Einige Teilnehmer haben Untertypbeziehungen offensichtlich mit Vererbungsbeziehungen verwechselt, vielleicht weil sie mit Vererbung vertraut sind, aber noch keine Erfahrungen mit Untertypbeziehungen haben. Die einfachste Form der direkten Code-Wiederverwendung ergibt sich durch eine Klassenhierarchie, die durch die Reihenfolge der Beschreibungen der Klassen in der Aufgabenstellung vorgegeben scheint. Vielleicht haben sich einige Teilnehmer davon verwirren lassen, dass die scheinbar vorgegebene Reihenfolge, die intuitive is-a-Beziehung und die einfachste Vererbungshierarchie eine einheitliche Struktur ergeben. Diese Hierarchie hat aber leider gar nichts mit Untertypbeziehungen zu tun und widerspricht dem Ersetzbarkeitsprinzip.
Verlassen auf Erfahrung und Intuition statt auf konkrete Grundlagen:
Bei dieser Aufgabe haben auch einige Gruppen, deren Mitglieder schon viel Programmiererfahrung haben, versagt. Ein Mitgrund dürfte darin liegen, dass diese Gruppen die Aufgaben eher nach Intuition lösen, als auf den in den Vorlesungen und im Skriptum behandelten Stoff einzugehen. Eine typische Folge davon ist beispielsweise die Verwechslung verschiedener Arten von Beziehungen zwischen Klassen. Alle zur Lösung dieser Aufgabe notwendigen Grundlagen wurden in den Vorlesungen ausführlich behandelt. Es fehlt aber gelegentlich der Mut, den neu erlernten Stoff auch in die Praxis umzusetzen, und es erscheint fälschlicherweise sicherer, sich auf (unzureichende) eigene Erfahrungen und Intuitionen zu verlassen, als sich auf ein unbekanntes Gebiet zu begeben. Jetzt ist der Punkt gekommen, wo Vorwissen alleine oft nicht mehr ausreicht, um die Aufgaben gut zu lösen. In einigen Fällen haben Testergebnisse sogar klare Verletzungen der Ersetzbarkeit gezeigt – ein deutlicher Hinweis darauf, dass der Begriff der Ersetzbarkeit noch nicht verstanden wurde.
Zu wenig Selbstvertrauen:
Bei einigen Gruppen dürfte mangelndes Selbstvertrauen eine Rolle gespielt haben: Durch zuviel Respekt vor der Aufgabe haben es manche nicht gewagt, selbst entwickelte Klassenhierarchien auszuprogrammieren und Zusicherungen in eigenen Worten zu formulieren. Sicher haben sich viele eher auf irgendwelche in Forumsdiskussionen oder sonst irgendwo im Internet angebotene Informationen als auf das eigene Wissen verlassen. Ganz allgemein sind Diskussionen in Foren durchaus zu begrüßen. Gefährlich wird es aber, wenn man das Gefühl bekommt, dass Lösungen und Argumente von vielen anderen Leuten besser sind als die eigenen (= mangelndes Selbstvertrauen) und daher nur mehr vorgefertigte Lösungen oder Lösungsansätze übernimmt. Damit begibt man sich ganz in Abhängigkeit von Leuten mit mehr Selbstvertrauen (die aber deswegen nicht unbedingt immer bessere Lösungen haben) und kann bzw. möchte bald auch einfachste Aufgaben nicht mehr selbst und ohne Rückbestätigung lösen. Eine fremde Lösung schaut oft nur deswegen besser aus als die eigene, weil man Probleme, die während der Entwicklung der Lösung aufgetaucht sind, nicht mehr sieht, während Probleme der eigenen Lösung ganz offensichtlich sind. Daher ist es ein großes Risiko, sich ganz auf andere (einem oft unbekannte) Leute zu verlassen. Es ist auch deswegen ein Risiko, weil Lösungen, die man nicht selbst gemacht sondern nur abgeschrieben hat und daher beim Abgabegespräch nicht im Detail erklären kann, mit 0 Punkten beurteilt werden (auch wenn man in der vorläufigen Beurteilung viele Punkte bekommen hat). In der Regel fällt es auf, wenn große Teile der Lösung abgeschrieben sind. Beispielsweise passt die Struktur einer Lösung einfach nicht zur Namensgebung oder zu den Kommentaren. Zusammengefasst gilt: Es ist durchaus gerechtfertigt, in Foren Probleme zu diskutieren und auch Lösungsansätze anzubieten oder danach zu fragen. Wissen, das man dabei gewinnt, kann und soll man in die eigenen Lösungen einfließen lassen. Aber man soll sich keinesfalls nur auf andere verlassen, sondern alle gewonnenen Informationen hinterfragen und nur dann verwenden, wenn man sie auch im Detail versteht und die Strukturen, die man übernehmen möchte, auch tatsächlich zur eigenen Lösung passen. Meist funktioniert es nicht, wenn unpassende Strukturen erst passend gemacht werden müssen.
Teilaufgaben und Hinweise ignoriert:
Teile der Aufgabenstellung hatten nur den Zweck, Fehler in der Lösung möglichst rasch aufzudecken. Außerdem wurden Hinweise dazu gegeben, wie die Korrektheit der Lösung sichergestellt werden kann. Viele Gruppen haben die entsprechenden Teile der Aufgabe und die Hinweise einfach ignoriert. Beispielsweise wurde die Ersetzbarkeit nur schlecht getestet, Gegenbeispiele für nicht bestehende Untertypbeziehungen wurden nur selten gegeben, und oft wurden aus einer Oberklasse übernommene Zusicherungen in der Unterklasse nicht wiederholt. Gerade Letzteres hätte viele falsche Untertypbeziehungen rasch auffallen lassen müssen. Das ist beispielsweise auch daran gescheitert, dass viele gar nicht auf die Idee gekommen sind, in einer Unterklasse auch für ererbte Methoden (die deswegen in der Unterklasse nicht implementiert sind) Zusicherungen zu schreiben.
Kleinigkeiten übersehen:
Es ist durchaus möglich, dass so manche Gruppe kleine Details einfach übersehen hat, vor allem was die Untertypbeziehung zwischen NoPretty und BlockPretty betrifft. Beispielsweise kann man leicht übersehen, dass der Konstruktor in BlockPretty auch mit dem Argument 0 umgehen können muss. Andererseits kann man leicht übersehen, dass Variablen (besser als final deklariert), die im Konstruktor gesetzt und dann nicht mehr verändert werden, eine andere Qualität haben als Instanzvariablen, die jederzeit verändert werden können. Es war zwar ein entsprechender Hinweis in der Aufgabenstellung, den man aber möglicherweise zu Beginn der Arbeit an der Struktur noch nicht richtig interpretieren kann. Solchen Problemen kann man nur durch große Aufmerksamkeit bei der Programmierung begegnen.
Nicht alle Arten von Fehlern fließen in die Beurteilung ein, sondern hauptsächlich Fehler, welche die im Vorhinein bekannten Schwerpunkte der Aufgabe betreffen. Kleine Fehler in Implementierungsdetails werden in der Beurteilung ignoriert.

Beurteilungsschema

Für ein abgegebenes Programm, das sich übersetzen lässt, gibt es 100 Punkte. Davon werden für Fehler im Programm Punkte abgezogen. Generell gibt es mehrere Klassen von Fehlern mit je einer eigenen maximalen Anzahl von abgezogenen Punkten: Einige Fehlerklassen stehen in enger Beziehung zueinander. Diese werden in der Beurteilung berücksichtigt. Wenn beispielsweise Punkte für falsche Untertypbeziehungen abgezogen wurden, dann wurden für mangelhafte Zusicherungen nur mehr weniger Punkte abgezogen, wenn angenommen werden kann, dass die Mängel in den Zusicherungen eine Mitursache für falsche Untertypbeziehungen sind.
Complang
Puntigam
   Kontakt
   Research
   Lehre
      OOP
      Typsysteme
      EP2
      FOOP
      Prog.spr.
      frühere Lehre
         LVAs 2017 W
         LVAs 2017 S
         LVAs 2016 W
         LVAs 2016 S
         LVAs 2015 W
         LVAs 2015 S
         LVAs 2014 W
         LVAs 2014 S
         LVAs 2013 W
         LVAs 2013 S
         LVAs 2012 W
         LVAs 2012 S
         LVAs 2011 W
         LVAs 2011 S
         LVAs 2010 W
            OOP
               1. Aufgabe
               2. Aufgabe
               3. Aufgabe
               4. Aufgabe
                  Beurteilung
               5. Aufgabe
               6. Aufgabe
               7. Aufgabe
               8. Aufgabe
            Typsysteme
         LVAs 2010 S
         LVAs 2009 W
         LVAs 2009 S
         LVAs 2008 W
         LVAs 2008 S
         LVAs 2007 W
         LVAs 2007 S
         LVAs 2006 W
         LVAs 2006 S
         LVAs 2005 W
         LVAs 2005 S
         LVAs 2004 W
         LVAs 2004 S
         LVAs 2003 W
   Links
Sitemap
Kontakt
Fakultät für Informatik
Technische Universität Wien
Anfang | HTML 4.01 | Datenschutzerklärung | letzte Änderung: 2010-11-12 (Puntigam)