Taschenrechner addiert nur

Code-Stücke können hier veröffentlicht werden.
Antworten
Benutzeravatar
Selectet
User
Beiträge: 4
Registriert: Montag 5. September 2022, 14:07

Hallo,

ich bin gerade dabei Python zu lernen (ich habe sonst noch keine Vorkenntnisse in anderen Programmier- Scriptsprachen) und wollte etwas mit Funktionen und Schleifen herumspielen..
Soweit funktioniert auch alles, allerdings rechnet der Taschenrechner immer plus, egal welche Auswahl ich treffe.. Kann mir jemand sagen wo der Fehler liegt?

Code: Alles auswählen

### Variablen ###
wert1 = None
wert2 = None
counter = 0
result = None
add_result = None
sub_result = None
mul_result = None
div_result = None
loop = 0


### Funktionen ###
def add(wert1, wert2, add_result):
    add_result = wert1 + wert2
    return add_result

def sub(wert1, wert2, sub_result):
    sub_result = wert1 - wert2
    return sub_result

def mul(wert1, wert2, mul_result):
    mul_result = wert1 * wert2
    return mul_result

def div(wert1, wert2, div_result):
    div_result = wert1 / wert2
    return div_result

### Taschenrechner ###
while loop == 0:
    print('\nTaschenrechner')
    print('Mit welchen Operator soll gerechnet werden?')
    print('1: Addition', '2: Subtraktion', '3: Multiplikation', '4: Divition', '5: Beenden', sep='\n')
    counter = int(input('\nBitte wählen: '))
    if counter == 1:
        print('Addition')
        wert1 = int(input('Wert 1: '))
        wert2 = int(input('Wert 2: '))
        result_prt = add(wert1, wert2, add_result)
        print(result_prt)
    elif counter == 2:
        print('Subtraktion')
        wert1 = int(input('Wert 1: '))
        wert2 = int(input('Wert 2: '))
        result_prt = add(wert1, wert2, sub_result)
        print(result_prt)
    elif counter == 3:
        print('Multiplikation')
        wert1 = int(input('Wert 1: '))
        wert2 = int(input('Wert 2: '))
        result_prt = add(wert1, wert2, mul_result)
        print(result_prt)
    elif counter == 4:
        print('Division')
        wert1 = int(input('Wert 1: '))
        wert2 = int(input('Wert 2: '))
        result_prt = add(wert1, wert2, div_result)
        print(result_prt)
    elif counter == 5:
        loop = 1
    else:
        print('Bitte wähle einen gültigen Wert!')
        
Benutzeravatar
Dennis89
User
Beiträge: 1153
Registriert: Freitag 11. Dezember 2020, 15:13

Hallo,

wieso rufst du in jeder 'if/elif'-Abfrage 'add' auf?

Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

Variablen definiert man nicht auf Vorrat, sondern dann, wenn man sie wirklich braucht. Die Einzige Variable, die dann übrig bleibt ist `loop`, die direkt vor der while-Schleife mit 0 initialisiert wird.
Die while-loop-Schleife sollte aber sowieso eine while-True-Schleife sein, die an passender Stelle abgebrochen wird.
Dann programmiert man nicht, indem man Code vielfach kopiert und leicht ändert, sondern indem man gleiche Funktionalität in Funktionen kapselt. Und im Kopieren liegt Dein Fehler.
Benutzeravatar
__blackjack__
User
Beiträge: 13077
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Selectet: Ergänzende Anmerkungen: Die Kommentare sind überflüssig. Das dort Variablen und Funktionen definiert werden, sieht man auch ohne den Kommentar das dort Variablen und Funktionen definiert werden.

Auf Modulebene sollte nur Code stehen der Konstanten, Funktionen, und Klassen definiert. Das Hauptprogramm steht üblicherweise in einer Funktion die `main()` heisst.

Die Rechenfunktionen bekommen alle ein drittes Argument das überhaupt gar nicht verwendet wird.

Beim Namen für das Ergebnis einer Funktion macht es keinen Sinn den Namen der Funktion noch mal zu wiederholen. `add_result` das als Rückgabewert in einer `add()`-Funktion verwendet wird, bringt dem Leser keinen Mehrwert über `result`. Man sieht ja in welcher Funktion das steht, und das es als Rückgabewert verwendet wird.

Code: Alles auswählen

def add(wert1, wert2):
    result = wert1 + wert2
    return result


def sub(wert1, wert2):
    result = wert1 - wert2
    return result


def mul(wert1, wert2):
    result = wert1 * wert2
    return result


def div(wert1, wert2):
    result = wert1 / wert2
    return result
Dann macht es aber nicht wirklich Sinn das Ergebnis überhaupt an einen Namen zu binden, der einzig und allein in der nächsten Zeile in einer ``return``-Anweisung verwendet wird:

Code: Alles auswählen

def add(wert1, wert2):
    return wert1 + wert2


def sub(wert1, wert2):
    return wert1 - wert2


def mul(wert1, wert2):
    return wert1 * wert2


def div(wert1, wert2):
    return wert1 / wert2
Man muss diese Funktionen aber auch gar nicht selbst definieren. In der Standardbibliothek gibt es das `operator`-Modul in dem alle Operatoren von Python als Funktionen definiert sind. Da haben sie ähnliche kryptische Namen, die man zur besseren Lesbarkeit umbenennen kann.

Es gibt vier Zweige die fast identischen Code enthalten. Das macht man als Programmierer nicht. Das ist fehleranfällig wenn man Änderungen vornehmen will oder muss, und macht unnötig Arbeit. Man würde hier beispielsweise eine Funktion schreiben, die den gemeinsamen Code enthält und die Unterschiede als Argument(e) übergeben bekommt.

Code: Alles auswählen

def do_operation(description, function):
    print(description)
    wert1 = int(input("Wert 1: "))
    wert2 = int(input("Wert 2: "))
    result_prt = function(wert1, wert2)
    print(result_prt)
Aufruf für die Addition beispielsweise mit ``do_operation("Addition", add)``.

Man muss hier auch nicht jedes kleine Zwischenergebnis an einen Namen binden.

Was soll `prt` überhaupt bedeuten? Namen sollten keine kryptischen Abkürzungen enthalten. Das ist das Ergebnis, dann sollte das einfach `result` heissen.

Zwischenergebnis (ungetestet):

Code: Alles auswählen

#!/usr/bin/env python3
from operator import (
    add,
    sub as subtract,
    mul as multiplicate,
    truediv as divide,
)


def do_operation(description, function):
    print(description)
    print(function(int(input("Wert 1: ")), int(input("Wert 2: "))))


def main():
    while True:
        print("\nTaschenrechner")
        print("Mit welchen Operator soll gerechnet werden?")
        print(
            "1: Addition",
            "2: Subtraktion",
            "3: Multiplikation",
            "4: Division",
            "5: Beenden",
            sep="\n",
        )
        counter = int(input("\nBitte wählen: "))
        if counter == 1:
            do_operation("Addition", add)
        elif counter == 2:
            do_operation("Subtraktion", add)
        elif counter == 3:
            do_operation("Multiplikation", add)
        elif counter == 4:
            do_operation("Division", add)
        elif counter == 5:
            break
        else:
            print("Bitte wähle einen gültigen Wert!")


if __name__ == "__main__":
    main()
(Enthält immer noch Deinen Fehler, der ist jetzt aber vielleicht auffälliger.)
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Schard
User
Beiträge: 16
Registriert: Freitag 25. Dezember 2020, 01:23
Wohnort: Hannover

Ich würde statt eines "quit" Kommandos EOFError abfangen. Damit kann man insbesondere auf unixoiden Systemen das Programm bei der Eingabeaufforderung einfach mit Strg+D beenden.
Zudem können die unterstützten Operationen in einem dict vordefiniert werden, sodass man diese einfach ausgeben und unterstützte Operationen verifizieren kann.
Mein Vorschlag für Python 3.10 daher:

Code: Alles auswählen

#!/usr/bin/env python3
"""A simple CLI based calculator."""

from typing import Callable, NamedTuple

import operator


class NamedBinaryIntegerOperation(NamedTuple):
    """Bianry operation on integers with a human-readable name."""

    name: str
    function: Callable[[int, int], int]

    def __call__(self, lhs: int, rhs: int) -> None:
        """Print the operation name and its result."""
        print(self.name)
        print(self.function(lhs, rhs))


OPERATIONS = {
    '1': NamedBinaryIntegerOperation('Addition', operator.add),
    '2': NamedBinaryIntegerOperation('Subtraktion', operator.sub),
    '3': NamedBinaryIntegerOperation('Multiplikation', operator.mul),
    '4': NamedBinaryIntegerOperation('Division', operator.floordiv)
}


def print_operations() -> None:
    """Print available operations."""

    for key, (name, _) in OPERATIONS.items():
        print(f'{key}: {name}')


def read_int(prompt: str) -> int:
    """Read an integer from the user."""

    while True:
        try:
            return int(input(prompt))
        except KeyboardInterrupt:
            continue
        except ValueError:
            print('Bitte eine Ganzzahl eingeben!')


def do_calculation() -> None:
    """Do a calculation as specified by the user."""

    print('Taschenrechner')
    print('Mit welchen Operator soll gerechnet werden?')
    print_operations()
    key = input('Bitte wählen: ')

    if (operation := OPERATIONS.get(key)) is None:
        print('Bitte wähle einen gültigen Wert!')
        return

    lhs = read_int('Wert 1: ')
    rhs = read_int('Wert 2: ')
    operation(lhs, rhs)


def main() -> None:
    """Main program loop."""

    while True:
        try:
            do_calculation()
        except EOFError:
            print('\nTschüss!')
            break


if __name__ == '__main__':
    main()
Antworten