Projekt: Taschenrechner in Python
Baue einen vollständigen Taschenrechner mit Fehlerbehandlung, Verlauf und erweiterten Operationen - dein erstes Python-Praxisprojekt
Projekt: Taschenrechner in Python
In diesem Projekt bauen wir Schritt für Schritt einen vollständigen Taschenrechner in Python. Du wirst dabei viele der Konzepte anwenden, die du bisher gelernt hast — von Funktionen über Schleifen bis hin zur Fehlerbehandlung.
Projektübersicht und Ziele
Unser Taschenrechner soll folgende Funktionen bieten:
- Grundrechenarten: Addition, Subtraktion, Multiplikation, Division
- Erweiterte Operationen: Potenz, Wurzel, Modulo
- Benutzermenü: Interaktive Bedienung über die Konsole
- Fehlerbehandlung: Sinnvolle Fehlermeldungen bei ungültigen Eingaben
- Verlauf: Alle Berechnungen werden gespeichert und können angezeigt werden
Am Ende hast du ein voll funktionsfähiges Programm, das du nach Belieben erweitern kannst.
Schritt 1: Grundoperationen definieren
Wir beginnen mit den vier Grundrechenarten als einzelne Funktionen:
def addieren(a, b):
"""Addiert zwei Zahlen."""
return a + b
def subtrahieren(a, b):
"""Subtrahiert b von a."""
return a - b
def multiplizieren(a, b):
"""Multipliziert zwei Zahlen."""
return a * b
def dividieren(a, b):
"""Dividiert a durch b."""
if b == 0:
raise ValueError("Division durch 0 ist nicht erlaubt!")
return a / b
Jede Funktion hat eine klare Aufgabe. Bei der Division prüfen wir bereits, ob durch Null geteilt wird, und werfen in diesem Fall einen Fehler.
Testen wir die Funktionen:
print(addieren(10, 5)) # 15
print(subtrahieren(10, 5)) # 5
print(multiplizieren(10, 5)) # 50
print(dividieren(10, 5)) # 2.0
Schritt 2: Benutzereingabe und Menü
Jetzt bauen wir ein interaktives Menü, damit der Benutzer den Taschenrechner bedienen kann:
def menue_anzeigen():
"""Zeigt das Hauptmenü an."""
print("\n" + "=" * 40)
print(" PYTHON TASCHENRECHNER")
print("=" * 40)
print("1. Addition (+)")
print("2. Subtraktion (-)")
print("3. Multiplikation (*)")
print("4. Division (/)")
print("5. Beenden")
print("=" * 40)
def zahlen_eingeben():
"""Fragt den Benutzer nach zwei Zahlen."""
zahl1 = float(input("Erste Zahl eingeben: "))
zahl2 = float(input("Zweite Zahl eingeben: "))
return zahl1, zahl2
# Hauptschleife
while True:
menue_anzeigen()
auswahl = input("Wähle eine Operation (1-5): ")
if auswahl == "5":
print("Auf Wiedersehen!")
break
if auswahl in ("1", "2", "3", "4"):
zahl1, zahl2 = zahlen_eingeben()
if auswahl == "1":
ergebnis = addieren(zahl1, zahl2)
print(f"\n{zahl1} + {zahl2} = {ergebnis}")
elif auswahl == "2":
ergebnis = subtrahieren(zahl1, zahl2)
print(f"\n{zahl1} - {zahl2} = {ergebnis}")
elif auswahl == "3":
ergebnis = multiplizieren(zahl1, zahl2)
print(f"\n{zahl1} * {zahl2} = {ergebnis}")
elif auswahl == "4":
ergebnis = dividieren(zahl1, zahl2)
print(f"\n{zahl1} / {zahl2} = {ergebnis}")
else:
print("Ungültige Auswahl! Bitte wähle 1-5.")
Die while True-Schleife sorgt dafür, dass das Programm so lange läuft, bis der Benutzer “5” für Beenden wählt.
Schritt 3: Fehlerbehandlung
Unser Programm kann noch abstürzen, wenn der Benutzer keine gültige Zahl eingibt. Das beheben wir mit try/except:
def zahlen_eingeben():
"""Fragt den Benutzer nach zwei Zahlen mit Fehlerbehandlung."""
while True:
try:
zahl1 = float(input("Erste Zahl eingeben: "))
zahl2 = float(input("Zweite Zahl eingeben: "))
return zahl1, zahl2
except ValueError:
print("Fehler: Bitte gib gültige Zahlen ein!")
def berechnung_ausfuehren(auswahl, zahl1, zahl2):
"""Führt die gewählte Berechnung aus und behandelt Fehler."""
try:
if auswahl == "1":
ergebnis = addieren(zahl1, zahl2)
operator = "+"
elif auswahl == "2":
ergebnis = subtrahieren(zahl1, zahl2)
operator = "-"
elif auswahl == "3":
ergebnis = multiplizieren(zahl1, zahl2)
operator = "*"
elif auswahl == "4":
ergebnis = dividieren(zahl1, zahl2)
operator = "/"
else:
return None
print(f"\n Ergebnis: {zahl1} {operator} {zahl2} = {ergebnis}")
return ergebnis
except ValueError as e:
print(f"\n Fehler: {e}")
return None
Jetzt fangen wir sowohl ungültige Eingaben als auch Division durch Null sauber ab, ohne dass das Programm abstürzt.
Schritt 4: Verlauf / History speichern
Wir fügen eine Liste hinzu, die alle bisherigen Berechnungen speichert:
verlauf = []
def zum_verlauf_hinzufuegen(zahl1, operator, zahl2, ergebnis):
"""Speichert eine Berechnung im Verlauf."""
eintrag = {
"rechnung": f"{zahl1} {operator} {zahl2} = {ergebnis}",
"zahl1": zahl1,
"operator": operator,
"zahl2": zahl2,
"ergebnis": ergebnis
}
verlauf.append(eintrag)
def verlauf_anzeigen():
"""Zeigt alle bisherigen Berechnungen an."""
if not verlauf:
print("\nKein Verlauf vorhanden.")
return
print("\n" + "-" * 40)
print(" BERECHNUNGSVERLAUF")
print("-" * 40)
for i, eintrag in enumerate(verlauf, 1):
print(f" {i}. {eintrag['rechnung']}")
print("-" * 40)
print(f" Gesamt: {len(verlauf)} Berechnungen")
def verlauf_loeschen():
"""Löscht den gesamten Verlauf."""
verlauf.clear()
print("\nVerlauf wurde gelöscht.")
Das Menü erweitern wir um die Optionen “Verlauf anzeigen” und “Verlauf löschen”.
Schritt 5: Erweiterte Operationen
Jetzt fügen wir Potenz, Quadratwurzel und Modulo hinzu:
import math
def potenz(a, b):
"""Berechnet a hoch b."""
return a ** b
def wurzel(a):
"""Berechnet die Quadratwurzel von a."""
if a < 0:
raise ValueError("Quadratwurzel einer negativen Zahl ist nicht definiert!")
return math.sqrt(a)
def modulo(a, b):
"""Berechnet den Rest der Division a / b."""
if b == 0:
raise ValueError("Modulo durch 0 ist nicht erlaubt!")
return a % b
Die Wurzel-Funktion ist besonders, weil sie nur eine Zahl benötigt. Das berücksichtigen wir in der Eingabelogik:
def eine_zahl_eingeben():
"""Fragt den Benutzer nach einer Zahl."""
while True:
try:
zahl = float(input("Zahl eingeben: "))
return zahl
except ValueError:
print("Fehler: Bitte gib eine gültige Zahl ein!")
Schritt 6: Code mit Funktionen organisieren
Jetzt bringen wir alles zusammen in einer sauber organisierten Struktur:
import math
# ============================================
# BERECHNUNGSFUNKTIONEN
# ============================================
def addieren(a, b):
return a + b
def subtrahieren(a, b):
return a - b
def multiplizieren(a, b):
return a * b
def dividieren(a, b):
if b == 0:
raise ValueError("Division durch 0 ist nicht erlaubt!")
return a / b
def potenz(a, b):
return a ** b
def wurzel(a):
if a < 0:
raise ValueError("Quadratwurzel negativer Zahlen nicht definiert!")
return math.sqrt(a)
def modulo(a, b):
if b == 0:
raise ValueError("Modulo durch 0 ist nicht erlaubt!")
return a % b
# ============================================
# OPERATIONEN-ZUORDNUNG
# ============================================
operationen = {
"1": {"name": "Addition", "symbol": "+", "funktion": addieren, "args": 2},
"2": {"name": "Subtraktion", "symbol": "-", "funktion": subtrahieren, "args": 2},
"3": {"name": "Multiplikation", "symbol": "*", "funktion": multiplizieren, "args": 2},
"4": {"name": "Division", "symbol": "/", "funktion": dividieren, "args": 2},
"5": {"name": "Potenz", "symbol": "^", "funktion": potenz, "args": 2},
"6": {"name": "Quadratwurzel", "symbol": "√", "funktion": wurzel, "args": 1},
"7": {"name": "Modulo", "symbol": "%", "funktion": modulo, "args": 2},
}
Durch das Dictionary operationen vermeiden wir lange if/elif-Ketten und machen den Code leicht erweiterbar.
Vollständiger Code
Hier ist das komplette Programm mit allen Funktionen:
import math
# ============================================
# BERECHNUNGSFUNKTIONEN
# ============================================
def addieren(a, b):
"""Addiert zwei Zahlen."""
return a + b
def subtrahieren(a, b):
"""Subtrahiert b von a."""
return a - b
def multiplizieren(a, b):
"""Multipliziert zwei Zahlen."""
return a * b
def dividieren(a, b):
"""Dividiert a durch b."""
if b == 0:
raise ValueError("Division durch 0 ist nicht erlaubt!")
return a / b
def potenz(a, b):
"""Berechnet a hoch b."""
return a ** b
def wurzel(a):
"""Berechnet die Quadratwurzel."""
if a < 0:
raise ValueError("Quadratwurzel negativer Zahlen nicht definiert!")
return math.sqrt(a)
def modulo(a, b):
"""Berechnet a modulo b."""
if b == 0:
raise ValueError("Modulo durch 0 ist nicht erlaubt!")
return a % b
# ============================================
# OPERATIONEN-DICTIONARY
# ============================================
operationen = {
"1": {"name": "Addition", "symbol": "+", "funktion": addieren, "args": 2},
"2": {"name": "Subtraktion", "symbol": "-", "funktion": subtrahieren, "args": 2},
"3": {"name": "Multiplikation", "symbol": "*", "funktion": multiplizieren, "args": 2},
"4": {"name": "Division", "symbol": "/", "funktion": dividieren, "args": 2},
"5": {"name": "Potenz", "symbol": "^", "funktion": potenz, "args": 2},
"6": {"name": "Quadratwurzel", "symbol": "√", "funktion": wurzel, "args": 1},
"7": {"name": "Modulo", "symbol": "%", "funktion": modulo, "args": 2},
}
# ============================================
# VERLAUF
# ============================================
verlauf = []
def zum_verlauf_hinzufuegen(rechnung_text, ergebnis):
"""Speichert eine Berechnung im Verlauf."""
verlauf.append({"rechnung": rechnung_text, "ergebnis": ergebnis})
def verlauf_anzeigen():
"""Zeigt den Berechnungsverlauf an."""
if not verlauf:
print("\n Kein Verlauf vorhanden.")
return
print("\n" + "-" * 40)
print(" BERECHNUNGSVERLAUF")
print("-" * 40)
for i, eintrag in enumerate(verlauf, 1):
print(f" {i}. {eintrag['rechnung']} = {eintrag['ergebnis']}")
print("-" * 40)
print(f" Gesamt: {len(verlauf)} Berechnungen")
def verlauf_loeschen():
"""Löscht den gesamten Verlauf."""
verlauf.clear()
print("\n Verlauf wurde gelöscht.")
# ============================================
# EINGABEFUNKTIONEN
# ============================================
def zahl_eingeben(prompt="Zahl eingeben: "):
"""Fragt nach einer Zahl mit Fehlerbehandlung."""
while True:
try:
return float(input(prompt))
except ValueError:
print(" Fehler: Bitte gib eine gültige Zahl ein!")
def menue_anzeigen():
"""Zeigt das Hauptmenü an."""
print("\n" + "=" * 40)
print(" PYTHON TASCHENRECHNER")
print("=" * 40)
for key, op in operationen.items():
print(f" {key}. {op['name']} ({op['symbol']})")
print()
print(" 8. Verlauf anzeigen")
print(" 9. Verlauf löschen")
print(" 0. Beenden")
print("=" * 40)
# ============================================
# HAUPTPROGRAMM
# ============================================
def main():
"""Startet den Taschenrechner."""
print("\nWillkommen beim Python Taschenrechner!")
while True:
menue_anzeigen()
auswahl = input("Deine Wahl: ").strip()
# Beenden
if auswahl == "0":
print("\nDanke fürs Rechnen! Auf Wiedersehen!")
break
# Verlauf anzeigen
if auswahl == "8":
verlauf_anzeigen()
continue
# Verlauf löschen
if auswahl == "9":
verlauf_loeschen()
continue
# Berechnung ausführen
if auswahl in operationen:
op = operationen[auswahl]
print(f"\n--- {op['name']} ---")
try:
if op["args"] == 2:
a = zahl_eingeben("Erste Zahl: ")
b = zahl_eingeben("Zweite Zahl: ")
ergebnis = op["funktion"](a, b)
rechnung = f"{a} {op['symbol']} {b}"
else:
a = zahl_eingeben("Zahl: ")
ergebnis = op["funktion"](a)
rechnung = f"{op['symbol']}({a})"
# Ergebnis anzeigen
print(f"\n {rechnung} = {ergebnis}")
# Im Verlauf speichern
zum_verlauf_hinzufuegen(rechnung, ergebnis)
except ValueError as e:
print(f"\n Fehler: {e}")
else:
print("\n Ungültige Auswahl! Bitte wähle 0-9.")
# Programm starten
if __name__ == "__main__":
main()
So funktioniert der vollständige Code:
- Funktionen oben: Alle Berechnungsfunktionen sind klar definiert und dokumentiert.
- Dictionary für Operationen: Statt langer
if/elif-Ketten nutzen wir ein Dictionary, das jeder Menüoption eine Funktion zuordnet. - Verlauf als Liste: Jede Berechnung wird als Dictionary in einer Liste gespeichert.
- Hauptschleife: Die
main()-Funktion enthält die Programmlogik in einer übersichtlichen Schleife. - Fehlerbehandlung:
try/exceptfängt alle möglichen Fehler ab.
Erweiterungsideen
Wenn du den Taschenrechner weiter ausbauen möchtest, hier einige Vorschläge:
- Wissenschaftliche Funktionen: Sinus, Cosinus, Tangens, Logarithmus mit dem
math-Modul - Klammern und Ausdrücke: Ganze mathematische Ausdrücke wie
(3 + 5) * 2parsen - GUI mit tkinter: Eine grafische Oberfläche wie ein echter Taschenrechner
- Verlauf in Datei speichern: Mit
json-Modul den Verlauf persistent machen - Einheitenumrechnung: Kilometer zu Meilen, Celsius zu Fahrenheit usw.
- Letzte Ergebnis verwenden: Das vorherige Ergebnis in der nächsten Berechnung nutzen
Was du gelernt hast
In diesem Projekt hast du folgende Konzepte praktisch angewendet:
- Funktionen definieren und aufrufen — jede Operation ist eine eigene Funktion
- Dictionaries — zur eleganten Zuordnung von Menüoptionen zu Funktionen
- While-Schleifen — für das interaktive Menü und die Eingabevalidierung
- Try/Except — für robuste Fehlerbehandlung
- Listen — zum Speichern des Berechnungsverlaufs
- f-Strings — für formatierte Ausgaben
- Module importieren —
mathfür erweiterte Berechnungen - Code-Organisation — Aufteilung in logische Abschnitte
Pro-Tipp: Wenn du den Taschenrechner als OOP-Projekt umbauen möchtest, erstelle eine Taschenrechner-Klasse, die den Verlauf als Attribut speichert und die Operationen als Methoden enthält. Das ist eine hervorragende Übung, um Klassen in einem realen Kontext zu verwenden!
class Taschenrechner:
def __init__(self):
self.verlauf = []
def addieren(self, a, b):
ergebnis = a + b
self._speichern(f"{a} + {b}", ergebnis)
return ergebnis
def _speichern(self, rechnung, ergebnis):
self.verlauf.append({"rechnung": rechnung, "ergebnis": ergebnis})