Verbesserungsvorschläge Taschenrechner

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Benutzeravatar
SenseiBeko
User
Beiträge: 2
Registriert: Mittwoch 12. August 2020, 09:44

Hallo zusammen

Ich habe angefangen mir Python als erste Programmiersprache selber bei zu bringen.

Aus dem bis jetzt gelernten habe ich mir einen einfachen Rechner mit den Arithmetischen Grundfunktionen geschrieben.

Da ich hauptsächlich alleine programmiere und ich niemanden habe wo mir helfen oder Verbesserungsvorschläge bringen könnte, dachte ich mir das ich euch Frage :D.

Code:

Code: Alles auswählen

def Divide():
  a = float(input('Num 1: '))
  b = float(input('Num 2: '))
  sum = float(a / b)
  print('Sum of: ' + str(a) + ' / ' + str(b) + ' = ' + str(sum))

def Multiply():
  a = float(input('Num 1: '))
  b = float(input('Num 2: '))
  sum = float(a * b)
  print('Sum of: ' + str(a) + ' * ' + str(b) + ' = ' + str(sum))

def Sub():
  a = float(input('Num 1: '))
  b = float(input('Num 2: '))
  sum = float(a - b)
  print('Sum of: ' + str(a) + ' - ' + str(b) + ' = ' + str(sum))

def Add():
  a = float(input('Num 1: '))
  b = float(input('Num 2: '))
  sum = float(a + b)
  print('Sum of: ' + str(a) + ' + ' + str(b) + ' = ' + str(sum))

def main():
  user_choice = int(input('0 Add, 1 Sub, 2 Multiply, 3 Divide. Your input: '))
  if user_choice == 0:
    Add()
  elif user_choice == 1:
    Sub()
  elif user_choice == 2:
    Multiply()
  elif user_choice == 3:
    Divide()
      

main()
War mein Gedanke beim coden des Rechners richtig? Gibt es Verbesserungsvorschläge an welcher Stelle ich den Code optimieren könnte?

Über jegliches Feedback würde ich mich sehr freuen!

Grüsse
Beko
Jankie
User
Beiträge: 592
Registriert: Mittwoch 26. September 2018, 14:06

Ich würde die Eingabe der Zahlen nur einmal in der main machen und dann die Werte an die entsprechende Funktion übergeben, diese gibt dann mit return den Wert zurück.
Die Benennung der Funktionen und die Einrückung ist auch nicht nach der Konvention.
Strings stückelt man nicht mit + zusammen, sondern benutzt Stringformatierung bzw. f-String.
Exceptionhandling fehlt komplett.


Code: Alles auswählen

def divide(first_number, second_number):
    try:
        return first_number / second_number
    except ZeroDivisionError:
        return 0 #x/0 ist immer 0

def multiply(first_number, second_number):
    return first_number * second_number

def subtract(first_number, second_number):
    return first_number - second_number

def add(first_number, second_number):
    return first_number + second_number

def main():
    while True:
        try:
            user_choice = int(input('0 Add, 1 Sub, 2 Multiply, 3 Divide. Your input: '))
            first_number = float(input("Zahl1: "))
            second_number = float(input("Zahl2: "))
            break
        except ValueError:
            print("Fehler bei der Eingabe!")
    if user_choice == 0:
        ergebnis = add(first_number, second_number)
    elif user_choice == 1:
        ergebnis = subtract(first_number, second_number)
    elif user_choice == 2:
        ergebnis = multiply(first_number, second_number)
    elif user_choice == 3:
        ergebnis = divide(first_number, second_number)
    print(f"Ergebnis: {ergebnis}")
      

main()
Benutzeravatar
DeaD_EyE
User
Beiträge: 1240
Registriert: Sonntag 19. September 2010, 13:45
Wohnort: Hagen
Kontaktdaten:

Endlich weiß ich jetzt, wie man durch 0 teilen kann...

Code: Alles auswählen

def divide(first_number, second_number):
    try:
        return first_number / second_number
    except ZeroDivisionError:
        return 0 #x/0 ist immer 0
Mit Python kann man solche komischen Sachen machen. Hab ich auch schon, aber es wäre besser zu verhindern, dass erst gar nicht durch 0 geteilt werden kann.
Wenn man z.B. Durchschnittswerte von einer Liste berechnen möchte, muss ich ja vorher auch schauen, ob die Liste überhaupt Elemente hat.
Keine Daten == kein Durchschnittswert und eine 0 wäre komplett falsch.

Beispiel:

Code: Alles auswählen

daten = []
mean = sum(daten) / len(daten)

Code: Alles auswählen

---------------------------------------------------------------------------
ZeroDivisionError                         Traceback (most recent call last)
<ipython-input-6-5f39acc79ff0> in <module>
      1 daten = []
----> 2 mean = sum(daten) / len(daten)

ZeroDivisionError: division by zero
Bugfix:

Code: Alles auswählen

daten = []
if daten:
    mean = sum(daten) / len(daten)
    print(mean)
else:
    print("Die Liste ist leer!")
Auch für einen Taschenrechner gilt: Division durch null ist unmöglich.
Die Exception ZeroDivisionError würde ich in der Funktion überhaupt nicht abfragen, sondern derjenige sollte das tun, der die Funktion aufruft.

Für die Operatoren +, -, *, und / kann man auch ein dict anlegen und die Funktionen aus dem Modul operator zuordnen.
Das sieht richtig schön aus, wenn man das konsequent durchzieht.

Code: Alles auswählen

import operator


OPERATORS = {
    "+": operator.add,
    "-": operator.sub,
    "/": operator.truediv,
    "*": operator.mul,
    "%": operator.mod,
}
OP_STR = ", ".join(OPERATORS)


def get_operator(question):
    while True:
        try:
            user_data = input(question)
            return OPERATORS[user_data]
        except KeyError:
            print(f"Operator '{user_data}' ist ungültig")


def get_float(question):
    while True:
        try:
            user_data = input(question)
            return float(user_data)
        except ValueError:
            print(f"{user_data} ist keine gültige Gleitkommazahl")


def main():
    frage_op = f"Bitte einen Operator angeben [ {OP_STR} ]: "
    frage_zahl = "Bitte eine Gleitkommazahl eingeben: "
    while True:
        operator = get_operator(frage_op)
        a = get_float(frage_zahl)
        b = get_float(frage_zahl)
        try:
            ergebnis = operator(a, b)
            print("Ergebnis:", ergebnis)
        except ZeroDivisionError:
            print("Division durch null!")


if __name__ == "__main__":
    main()

sourceserver.info - sourceserver.info/wiki/ - ausgestorbener Support für HL2-Server
Jankie
User
Beiträge: 592
Registriert: Mittwoch 26. September 2018, 14:06

Ups..naja, Mathe war nie meine Stärke.
Hab da wohl was vertauscht, 0/x ist immer 0, nicht andersherum.
Sirius3
User
Beiträge: 18272
Registriert: Sonntag 21. Oktober 2012, 17:20

@SenseiBeko: Es ist seltsam, dass bei Dir das Ergebnis einer Division oder Multiplikation `sum` heißt. Ganz wichtig ist, dass die Namen zum Code passen, denn sonst weiß man nicht, ob die Namen falsch sind oder der Code.
Gut an Deinem Code ist, das schon alles in Funktionen steckt. Wichtig ist es, sich von Anfang an an die Konventionen zu halten, dass immer mit 4 Leerzeichen pro Ebene eingerückt wird und Variablen wie Funktionsnamen komplett klein geschrieben werden. Das Ergebnis einer Rechenoperation mit zwei Floats ist auch ein Float. Das nochmal mit float umzuwandeln ist also überflüssig. Strings werden nicht mit + zusammengestückelt, weil es format-Strings gibt.

Code: Alles auswählen

def devide():
    a = float(input('Num 1: '))
    b = float(input('Num 2: '))
    division = a / b
    print(f'Division of: {a} / {b} = {division}')
Dann bist Du schon auf einem guten Weg. Die advanced Dinge mit Funktionsobjekten können dann später noch dazu kommen.
Benutzeravatar
SenseiBeko
User
Beiträge: 2
Registriert: Mittwoch 12. August 2020, 09:44

Guten Abend zusammen.

Mit dem durch 0 teilen ist mir gar nicht aufgefallen :D.

Vielen Dank für eure Feedbacks, ich werde mir das alles jetzt durch gehen.

Liebe Grüsse
Beko
Antworten