Hallo.
Einige Dinge hast du ja schon selbst festgestellt, die hättest du auch gleich umsetzen können. Besonders die Umwandlung der Werte in Integer fällt hier auf. Da du das in jeder Funktion machst, in der Funktion zur Division sogar doppelt, sind die ganzen int-Aufrufe dort falsch und gehören nach außen. Zudem schränkst du dich damit auch unnötig ein, denn deine ganzen Funktionen können auch mit beliebigen anderen Zahlen oder Objekten arbeiten, welche die implementierten Operationen unterstützen. Wenn du alles in Integer presst, dann nimmst du dir diese Möglichkeit. Damit arbeitet du ein ein wenig gegen die Sprache, da das gerade ein Vorteil von so dynamischen Sprachen ist.
Das ganze hat aber noch einen Nachteil: Eine Funktion sollte genau eine Aufgabe haben. Eine add-Funktion sollte also einfach nur zwei Werte addieren. Zusätzlich wandelst du aber die Werte noch von Strings in Integer, bzw. von einem beliebigem Objekt in einen Integer. Diese Regel gilt ganz allgemein, unabhänig von der Sprache.
Dann fällt sofort auf, dass du die Ergebnisse der Berechnungen an "ergebnis" bindest und in der nächsten Zeile diesen Wert dann mittels return zurückgibst. Dass kannst du dir sparen und solltest besser gleich ``return num1 + num2`` schreiben. Stat num1 und num2 könntest du auch bessere Bezeichner wählen, dann ist deren Aufgabe gleich klar. Allerdings musst du die ganzen Operationen gar nicht selbst entwickeln, das operator-Modul besitzt diese bereits.
Da du auch Anmerkungen zu PEP 8 haben wolltest: Um binäre Operatoren sollten Leerzeichen geschrieben werden. Also ``a + b`` und nicht ``a+b``. Oder ``a == b`` statt ``a==b``.
Dann fällt natürlich gleich deine Division auf. Die ist nicht nur "unausgereift", sonder falsch. Der zähler darf durchaus Null sein, du verbietest das allerdings. Ansonsten gilt by Python das EAFP-Prinzip. Einfach probieren die Operation durchzuführen und dann schauen, ob ein fehler aufgetreten ist. Also: Einfach die Division durch Null versuchen und ggf. die Exception abfangen. Dividiere im Interpreter doch einfach mal durch 0, dann siehst du ja was passiert.
Auch hat eine div-Funktion ein weiteres Problem: Bei einer Division durch 0 versetzt du dein Programm in einen ungültigen Zustand. Einfach nichts zurückgeben im Fehlerfall ist nicht die feine Art. Wenn ein Fehler auftritt, dann wirf eine Exception, welche dann weiter oben behandelt werden kann. Auch bei deiner Divisions-Funktion gilt wieder, dass du nicht mehrere Aufgaben vermischen solltest. Du vermischt aber Division und die Fehlerausgabe. Stelle dir folgende Frage: In wie weit müsstest du deine Logik, also die Divisions-Funktion, ändern, wenn du eine GUI verwendest und keine Textausgabe? Die Antwort sollte sein: gar nicht. In deinem Fall sieht es aber noch nicht so aus. Du solltest dir daher sofort angewöhnen Logik und Ausgabe zu trennen.
Der ganze Code von 24 bis zum Ende sollte dort nicht stehen. Code, abgesehen von Konstanten, Funktionen und Klassen, hat auf modulebene nichts zu suchen. Damit handelst du dir nur probleme ein und kannst dein Modul nicht wiederverwenden. Packe den Code also in entsprechende Funktionen. Üblich ist eine main-Funktion, welche am Ende des Codes mittels
aufgerufen wird. Dann ist auch sichergestellt, dass dein Programm nur ausgeführt wird, wenn es direkt aufgerufen wird.
Zeile 25 enthält gleich mehrere Problemchen. Dinge, welche du nicht an einen Namen bindest, solltest du einfach an den einfachen Unterstrich binden, damit drückst du eine Verwerfung des Werts aus:
Dann fällt sofort wieder die schlechte Namenswahl auf. param2 und param3 sind Operanden, param1 ist der Operator. Das solltest du also auch entsprechend benennen.
Zeile 27 ist wieder unnötig und teilweise falsch. Warum darf der Operator und aus Buchstaben bestehen? atan2 ist zum Beispiel ein sehr üblicher Bezeichner. Ansonsten ist auch der Test auf Ziffern mindestens unnötig. Wenn eine Eingabe nicht in einen Integer umgewandelt werden kann, dann fliegt dir schon eine Exception um die Ohren. Die solltest du behandeln. Wie gesagt: EAFP. Und natürlich schränkst du dich damit wieder weiter auf Integer ein, welches unnötig ist.
Die ganze if-Kaskade kannst du, wie du schon vermutet hast, als Dictionary darstellen:
Nicht vorhandenen Operationen kannst du wieder mittels Exception-Handling abfangen.
Die Backslashes in Zeile 37 sind überflüssig, genau so wie in Zeile 44.
Schau dir das argparse-Modul an.
Das Leben ist wie ein Tennisball.