Verfasst: Montag 12. März 2007, 15:26
Das mit den Schleifen zum Beseitigen von sich wiederholendem Code hast Du richtig verstanden.
Mit der Trennung meine ich, dass man Taschenrecher-Logik und GUI komplett trennt. Das ist jetzt bei Dir beides sehr eng miteinander verknüpft. Du speicherst zum Beispiel für das Programm wichtige Daten in der GUI (`self.ausgabe`) und die meisten Aktionen machen etwas mit dem internen Zustand des Taschenrechners *und* mit der GUI.
Dadurch lässt sich der Taschenrechner bzw. die einzelnen Funktionen nicht ohne GUI testen. Das macht automatisierte Tests und die Fehlersuche schwierig.
Hier ist mal ein minimales Beispiel eines Rechners ohne GUI, der so ähnlich aufgebaut ist wie Deiner:
Den kann man jetzt interaktiv, oder mit einem Testprogramm ausprobieren:
Und wenn man sicher ist, das alles funktioniert, kann man eine GUI draufsetzen.
Diese Trennung wird umso wichtiger und nützlicher je komplexer die beiden Hälften Programmlogik und GUI werden. Und für einen vernünftigen Rechner müssten beide noch ein wenig komplexer werden. Diese `eval()`-Geschichte ist nämlich alles andere als robust.
Mit der Trennung meine ich, dass man Taschenrecher-Logik und GUI komplett trennt. Das ist jetzt bei Dir beides sehr eng miteinander verknüpft. Du speicherst zum Beispiel für das Programm wichtige Daten in der GUI (`self.ausgabe`) und die meisten Aktionen machen etwas mit dem internen Zustand des Taschenrechners *und* mit der GUI.
Dadurch lässt sich der Taschenrechner bzw. die einzelnen Funktionen nicht ohne GUI testen. Das macht automatisierte Tests und die Fehlersuche schwierig.
Hier ist mal ein minimales Beispiel eines Rechners ohne GUI, der so ähnlich aufgebaut ist wie Deiner:
Code: Alles auswählen
class Calculator(object):
def __init__(self):
self.display = ''
self.expression = ''
def clear(self):
self.display = ''
self.expression = ''
def enter_number(self, number):
self.expression += number
self.display = number
def enter_operator(self, operator):
assert operator in list('+-*/')
self.expression += operator
def evaluate(self):
try:
self.display = eval(self.expression)
except (SyntaxError, ArithmeticError):
self.display = 'Error'
self.expression = self.display
Code: Alles auswählen
In [68]: a = test.Calculator()
In [69]: a.display
Out[69]: ''
In [70]: a.enter_number('42')
In [71]: a.display
Out[71]: '42'
In [72]: a.expression
Out[72]: '42'
In [73]: a.enter_operator('+')
In [74]: a.display
Out[74]: '42'
In [75]: a.expression
Out[75]: '42+'
In [76]: a.enter_number('23')
In [77]: a.expression
Out[77]: '42+23'
In [78]: a.display
Out[78]: '23'
In [79]: a.evaluate()
In [80]: a.display
Out[80]: 65
In [81]: a.expression
Out[81]: 65
Diese Trennung wird umso wichtiger und nützlicher je komplexer die beiden Hälften Programmlogik und GUI werden. Und für einen vernünftigen Rechner müssten beide noch ein wenig komplexer werden. Diese `eval()`-Geschichte ist nämlich alles andere als robust.