7.3Implementierung des Taschenrechners
Nun wollen wir alles bisher gelernte zusammenführen und das Skript taschenrechner.py
entwickeln.
Dazu werden wir zuerst eine einzelne “Rechen-Interaktion” programmieren und diese dann in einer Schleife wiederholen. Abschließend erstellen wir daraus wieder ein ausführbares Skript.
Für die Implementierung bleiben folgende Fragen zu klären:
- Welche Operatoren sind erlaubt? Wie werden diese erkannt und wie wird die korrekte Funktionalität in Python ausgelöst?
- Welche Zahlen-Datentypen werden akzeptiert? Wie wird mit Eingaben, die nicht in eine Zahl umgewandelt werden können, umgegangen?
Recheninteraktion¶
Eine Recheninteraktion soll wie folgt gestaltet sein:
- Es wird ein mathematischer Operator abgefragt.
- Es wird mindestens ein Operand abgefragt.
- Das Ergebnis der Berechnung wird ausgegeben.
“naive” Implementierung¶
Nehmen wir zuerst einmal an, dass die Nutzer*innen keine Fehler machen und wir nur Eingaben erhalten, die unserem Design entsprechen. Nehmen wir weiter an, dass die Addition von zwei Operanden durchgeführt werden soll.
Wir implementieren die Funktion calculate()
, die drei Nutzer*innen-Eingaben einliest und das Ergebnis der Berechnung zurück gibt.
Dabei orientieren wir uns an dieser Beispielinteraktion:
> +
>> 3
>> 4
>>
7
def calculate():
operator = input("> ")
op1 = int(input(">> "))
op2 = int(input(">> "))
empty = input(">> ")
return op1 + op2
Ob alles funktioniert hat können Sie mit dem nachfolgenden Code testen. Das assert
-Statement überprüft, ob der erste Ausdruck wahr ist. Wenn nein, dann wird der zweite Ausdruck als AssertionError()
ausgegeben.
assert 35 == calculate(), "Operator: +, Operand 1: 10, Operand 2: 25 FEHLER: Nicht erfolgreich"
> +
>> 10
>> 25
>>
Diese Implementierung ignoriert aktuell die Eingabe des Operators. Dann werden zwei Zahlen eingelesen und als Ganzzahl interpretiert. Es folgt das einlesen einer leeren Zeile, welche das Ende der Operanden-Eingabe signalisiert und es wird - hart codiert - das Ergebnis der Berechnung zurückgegeben.
# TIPPEN SIE DIESEN CODE AB UND ÄNDERN SIE IHN DANN
def calculate():
operator = input("> ")
op1 = int(input(">> "))
op2 = int(input(">> "))
empty = input(">> ")
return op1 + op2
assert 35 == calculate(), "Operator: '+', Operand 1: 10, Operand 2: 25 FEHLER: Nicht erfolgreich"
assert calculate() is None, "Operator: '-' sollte als Fehler erkannt werden"
> +
>> 10
>> 25
>>
> -
>> 1
>> 1
>>
---------------------------------------------------------------------------
AssertionError Traceback (most recent call last)
Cell In[6], line 2
1 assert 35 == calculate(), "Operator: '+', Operand 1: 10, Operand 2: 25 FEHLER: Nicht erfolgreich"
----> 2 assert calculate() is None, "Operator: '-' sollte als Fehler erkannt werden"
AssertionError: Operator: '-' sollte als Fehler erkannt werden
✅ Lösung
def calculate():
operator = input("> ")
if operator != "+":
return None
op1 = int(input(">> "))
op2 = int(input(">> "))
empty = input(">> ")
return op1 + op2
assert 35 == calculate(), "Operator: '+', Operand 1: 10, Operand 2: 25 FEHLER: Nicht erfolgreich"
assert calculate() is None, "Operator: '-' sollte als Fehler erkannt werden"
> +
>> 10
>> 25
>>
> -
Korrekte Behandlung der Operanden¶
Bisher gehen wir immer von genau 2 Operanden (und einer leeren Eingabe) aus. Der nächste Schritt ist es, eine variable Anzahl von Operanden einzulesen.
Konzeptionell wollen wir also:
- eine Eingabe der Nutzer*in einlesen,
- überprüfen, ob diese leer ist und ggf. das einlesen beenden
- ansonsten die Eingabe in eine Zahl umwandeln und
- zwischenspeichern, bis alle Zahlen eingelesen sind.
Um mehrere Werte in einer Variablen zu speichern lernen wir einen neuen Datentyp kennen: die Liste (list()
, []
). Eine Liste kann mehrere Werte enthalten und es können Werte am Ende hinzugefügt werden. Dann kann die Liste durchlaufen werden und mit jedem Wert etwas getan werden.
Verkleinern wir das Problem noch weiter, so wollen wir diese Interaktion ermöglichen:
>> 1
>> 2
>> 3
>>
Am Ende dieser Eingaben sollten die Werte 1
, 2
und 3
in einer Liste gespeichert sein. Das kann beispielsweise so aussehen:
numbers = [] # define an empty list to store the numbers
while True: # loop indefinitely until we `break` out on empty input
text = input(">> ")
if "" == text:
break
else:
number = int(text)
numbers.append(number) # append entered number to list of numbers
numbers # the last value of a cell is printed as its result
>> 1
>> 2
>> 3
>>
[1, 2, 3]
Nun haben wir es fast geschafft. Es fehlt nur noch die korrekte Behandlung mehrerer Operanden bei der Berechnung des Ergebnisses.
Verkleinern wir das Problem wieder, so können wir eine Variable erstellen, welche am Schluss das Ergebnis beinhalten soll und anschließend können wir für alle Operanden das Ergebnis mit dem Operanden verrechnen. Am einfachsten geht das mit der sogenannten for
-Schleife:
numbers = [1, 2, 3]
result = 0
for number in numbers:
result += number
result
6
Die Programmschleife¶
Die Programmschleife soll in jedem Schritt:
- die Recheninteraktions-Funktion aus dem vorherigen Abschnitt aufrufen und
- das Rechenergebnis ausgeben, falls vorhanden
- die Schleife soll beendet werden, wenn kein Operator übergeben wurde
Für die Lösung dieses Problems lernen wir noch ein weiteres sehr nützliches Syntaxelement von Python kennen – den sogenannten Walross-Operator :=
.
Dieser erlaubt es in den Bedingungen von if
, while
, usw. das Ergebnis der Bedingung in einer Variablen abzuspeichern. Dadurch kann unsere Programmschleife wie folgt aussehen:
while result := calculate():
print(result)
> +
>> 1
>> 2
>>
3
> +
>> 1
>>
1
>