Übungsaufgaben

Hausaufgabe: Klassen für arithmetische Ausdrücke definieren

In dieser Aufgabe sollen Sie eine Klassenhierarchie zur Darstellung von arithmetischen Ausdrücken entwerfen.

Entwerfen Sie zunächst ein Klassendiagramm (Modellierung) bevor Sie die Klassen in Python implementieren und testen.

Gemeinsame Oberklasse all Ihrer Klassen soll die folgende Klasse Expression sein:

class Expression:
    def __repr__(self):
        return str(self)

Die Methode __repr__ gibt die Zeichenkette zurück, die bei der Eingabe von Objekten in python3 angezeigt wird. Die gezeigte Implementierung ruft zur Berechnung dieser Zeichenkette (indirekt) die Methode __str__ auf und gibt das Ergebnis zurück. Welche Implementierung von __str__ wird zur Auswertung dieses Aufrufs verwendet?

Definieren Sie eine Klasse Number zur Darstellung von Zahlen. Objekte dieser Klasse sollen zum Beispiel durch einen Aufruf wie Number(42) erzeugt werden können. Überschreiben Sie in der Klassendefinition die Methode __str__ derart, dass eine textuelle Darstellung der dargestellten Zahl zurückgegeben wird. Ist es sinnvoll, die Klasse Number als Unterklasse von Expression zu definieren? Begründen Sie Ihre Antwort. Fügen Sie der Klasse Number außerdem eine Methode value hinzu, die den Wert der dargestellten Zahl zurückliefert.

Definieren Sie Klassen Sum und Product zur Darstellung von Summen und Produkten arithmetischer Ausdrücke. Objekte dieser Klassen sollen, wie Objekte der Klasse Number, über Methoden __str__ und value verfügen. Implementieren Sie diese beiden Methoden so, dass die folgenden Aufrufe in python3 sich wie gezeigt verhalten:

>>> a = Number(17)
>>> a
17
>>> b = Number(4)
>>> b
4
>>> c = Sum(a,b)
>>> c
(17+4) 
>>> d = Product(Number(2), c)
>>> d
(2*(17+4)) 
>>> d.value()
42 

Überlegen Sie, von welcher Klasse Sum und Product erben sollten, um Duplizierung von Quelltext weitgehend zu vermeiden. Gegebenenfalls können Sie auch weitere Klassen definieren. Begründen Sie für jede weitere Klasse, warum Sie ihre Definition für sinnvoll halten.

Hausaufgabe: Klassen für Schachfiguren definieren

In dieser Aufgabe sollen Sie eine Klassenhierarchie zur Repräsentation von Schachfiguren entwerfen. Gemeinsame Oberklasse all Ihrer Klassen soll die folgende Klasse Piece sein:

class Piece:

  def __init__(self, color, field):
    self._color=color
    self.set_position(field)
    
  def position(self):
    return self._position

  def set_position(self, field):
    self._position = field

  def move(self, field):
    if self.is_allowed(field):
      self.set_position(field)

  def __repr__(self):
    return str(self)

Der Konstruktor wird mit Farbe und Position als Argumente aufgerufen (z.B. “white”, “a1”).

Erläutern Sie die Methoden position, set_position und move.

Die Methode __repr__ gibt die Zeichenkette zurück, die bei der Eingabe von Objekten in python3 angezeigt wird. Die gezeigte Implementierung ruft zur Berechnung dieser Zeichenkette (indirekt) die Methode __str__ auf und gibt das Ergebnis zurück.

Definieren Sie eine Klasse Rook zur Repräsentation von Türmen.

Objekte dieser Klasse sollen zum Beispiel durch einen Aufruf wie Rook("white", "a1") erzeugt werden können.

Überschreiben Sie in der Klassendefinition die Methode __str__ derart, dass eine textuelle Darstellung des Turm-Objektes zurückgegeben wird.

Begründen Sie die Zweckmäßigkeit, die Klasse Rook als Unterklasse von Piece zu definieren.

Fügen Sie der Klasse Rook eine boolesche Methode is_allowed hinzu, die ermittelt, ob der Zug auf ein Feld nach den Schachregeln zulässig ist.

Definieren Sie entsprechend Klassen Bishop und Queen zur Repräsentation von Läufern und Damen.

Objekte dieser Klassen sollen, wie Objekte der Klasse Rook, über Methoden __str__ und is_allowed verfügen. Implementieren Sie diese beiden Methoden so, dass die folgenden Aufrufe in python3 sich wie gezeigt verhalten:

>>> r = Rook("white", "a1")
>>> r
Rook (white) at: a1
>>> r.move("a3")    #valid Move
>>> r
Rook (white) at: a3
>>> r.move("b2")    #invalid Move
Rook (white) at: a3
>>> b = Bishop("black","c3")
>>> b
Bishop (black) at: c3
>>> b.move("h8")
>>> b
Bishop (black) at: h8

Analysieren Sie, welche Implementierung von __str__ zur Auswertung des Aufrufs Piece#repr verwendet wird.

Untersuchen Sie die Methoden is_allowed der Klassen Rook, Bishop und Queen auf Redundanz und abstrahieren Sie so, dass Duplizierung von Quelltext weitgehend vermieden wird.