Problem mit if else Anweisungen

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
__es.2007__
User
Beiträge: 2
Registriert: Donnerstag 25. Mai 2023, 19:26

Hallo Allerseits
Ich bin blutiger Anfänger und bitte daher bei folgender Frage um Nachsicht.
Ich habe versucht mein erstes eigenes Programm, einen Gehaltsrechner, zu schreiben, jedoch bin ich leider auf ein Problem gestoßen, welches ich leider nicht selbst beheben kann. Code lautet wie folgt:

def calc_pay_jahr_n(lohnsteuer): # für Lohnsteuer pro Jahr
return lohn_jahr_b - lohnsteuer


def calc_pay_monat_n(): # für Monatslohn netto
return round(lohn_jahr_n / 12 - float(calc_percent()), 2)


def calc_percent(): # für Reststeuer
if Kirche == "Ja" or "ja":
return round(lohn_monat_b / 100 * 19.925, 2) + round(Lohnsteuer / 12 * 0.009, 2)
else:
return round(lohn_monat_b / 100 * 19.925, 2)


def print_solution(lohn_jahr_p, lohn_monat_p): # Printfunktion für Ergebnis
print("Sie verdienen im Jahr daher abzüglich der Lohnsteuer " + lohn_jahr_p + " Euro")
print("Daraus ergibt sich abzüglich der restlichen Abgaben ein Monatslohn von " + lohn_monat_p + " Euro Netto")


Kirche = input("Sind sie Mitglied in der Kirchgemeinde? Antwort hier eintragen (Ja oder nein): ")
lohn_stunde = input("Bitte geben sie hier ihren Lohn pro Stunde an: ")
lohn_tag = input("Bitte geben sie die Anzahl der Stunden ein, die sie pro Tag arbeiten: ")
lohn_monat_b = int(lohn_tag) * 5 * 4 * float(lohn_stunde)
lohn_jahr_b = int(lohn_monat_b) * 12
if float(lohn_stunde) < 12.50:
print("Sie verdienen unter Mindestlohn. Wir würden ihnen empfehlen, sich einen fairer bezahlten Job zu suchen")
else:
print("Ihr Lohn pro Monat beträgt " + str(lohn_monat_b) + " Euro Brutto")
print("Daraus ergibt sich ein Jahreslohn von " + str(lohn_jahr_b) + " Euro brutto")
if lohn_jahr_b >= 20000: # Steuer für Lohn von 20.000
Lohnsteuer = 1748
lohn_jahr_n = calc_pay_jahr_n(1748)
print_solution(str(calc_pay_jahr_n(1748)), str(calc_pay_monat_n()))
elif lohn_jahr_b >= 30000: # Steuer für Lohn von 30.000
Lohnsteuer = 4748
lohn_jahr_n = calc_pay_jahr_n(4748)
lohn_monat_n = calc_pay_monat_n()
print_solution(str(lohn_jahr_n), str(lohn_monat_n))
elif lohn_jahr_b >= 40000: # Steuer für Lohn von 40.000
Lohnsteuer = 8620
lohn_jahr_n = calc_pay_jahr_n(8620)
lohn_monat_n = calc_pay_monat_n()
print_solution(str(lohn_jahr_n), str(lohn_monat_n))
elif lohn_jahr_b >= 60000: # Steuer für Lohn von 60.000
Lohnsteuer = 16820
lohn_jahr_n = calc_pay_jahr_n(16820)
lohn_monat_n = calc_pay_monat_n()
print_solution(str(lohn_jahr_n), str(lohn_monat_n))
elif lohn_jahr_b >= 80000: # Steuer für Lohn von 80.000
Lohnsteuer = 26274
lohn_jahr_n = calc_pay_jahr_n(26274)
lohn_monat_n = calc_pay_monat_n()
print_solution(str(lohn_jahr_n), str(lohn_monat_n))
elif lohn_jahr_b >= 100000: # Steuer für Lohn von 100.000
Lohnsteuer = 36012
lohn_jahr_n = calc_pay_jahr_n(36012)
lohn_monat_n = calc_pay_monat_n()
print_solution(str(lohn_jahr_n), str(lohn_monat_n))
elif lohn_jahr_b >= 200000: # Steuer für Lohn von 200.000
Lohnsteuer = 86012
lohn_jahr_n = calc_pay_jahr_n(86012)
lohn_monat_n = calc_pay_monat_n()
print_solution(str(lohn_jahr_n), str(lohn_monat_n))

Nun habe ich ein Problem, dass bei der If Anweisung, bei der durch die Variable Kirche bestimmt wird, ob man Kirchsteuer bezahlen muss oder nicht (Blau markiert). Mein Problem besteht darin, dass egal was man in die Variable Kirche für einen Wert übergibt, immer der Code Block unter der If-Anweisung und nie unter der Else- Anweisung ausgeführt wird. Angedacht war es von mir, dass der Codeblock unter else immer dann ausgeführt wird, wenn Kirche = "Ja" oder "ja" nicht zutrifft. Hat jemand vielleicht eine Lösung dafür?
Benutzeravatar
ThomasL
User
Beiträge: 1366
Registriert: Montag 14. Mai 2018, 14:44
Wohnort: Kreis Unna NRW

Code: Alles auswählen

if Kirche == "Ja" or "ja":
funktoniert nicht wie du denkst.

Die Abfrage muss so lauten

Code: Alles auswählen

if Kirche == "Ja" or Kirche == "ja":
Deine Version liefert immer True.
Ich bin Pazifist und greife niemanden an, auch nicht mit Worten.
Für alle meine Code Beispiele gilt: "There is always a better way."
https://projecteuler.net/profile/Brotherluii.png
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

Deine if-Bedingung lautet auch (Kirche == "Ja") or ("ja"). Also entweder ist Kirche gleich "Ja" oder "ja" ist ein nicht-leerer String, und zweiteres trifft immer zu. In solchen Bedingungen benutz man den in-Operator und eine Liste, bzw. einfach .lower.

Globale Variablen benutzt man nicht, alles, was Funktionen brauchen, muß als Argument übergeben werden. Variablennamen schreibt man komplett klein und ohne kryptische Abkürzungen. Was sollten die _p- oder _n-Suffixe denn bedeuten? Ich habe es nicht herausfinden können.
lohn_stunde und lohn_tag sehen so aus, als ob sie vom selben Typ sind, sind sie aber nicht, das eine ist ein Geldbetrag und das andere eine Zeitangabe, dieser Unterschied sollte man am Veriablennamen erkennen!
Eingaben wandelt man einmal in eine Zahl um und nicht jedesmal, wenn man mit der Zahl etwas rechnen will.
`print_solution` sollte keine Strings als Argumente erwarten, das wird auch wieder aus dem Variablennamen nicht klar. Da man aber eh f-Strings benutzt, ist das explizite Umwandeln in str nicht nötig.

Zahlenwerte stehen nicht irgendwo mitten im Code, sondern werden als Konstanten an den Anfang der Datei geschrieben, damit man sie schnell finden und ändern kann.

Das Hauptprogramm steht in einer Funktion `main`, damit man erst gar nicht in Versuchung kommt, globale Variablen zu benutzen.

Die vielen if-Blöcke sind nahezu identisch, das kann man also gut zusammenfassen.

Code: Alles auswählen

STEUERSATZ = 19.925 / 100
KIRCHENSTEUERSATZ = 0.009

def calc_jahreslohn_netto(jahreslohn_brutto, lohnsteuer):
    return jahreslohn_brutto - lohnsteuer

def calc_monateslohn_netto(jahreslohn_netto, monats_lohn_brutto, kirchensteuerpflichtig, lohnsteuer):
    return jahreslohn_netto / 12 - calc_percent(monats_lohn_brutto, kirchensteuerpflichtig, lohnsteuer)

def calc_percent(monats_lohn_brutto, kirchensteuerpflichtig, lohnsteuer):
    # für Reststeuer
    if kirchensteuerpflichtig:
        return monats_lohn_brutto * STEUERSATZ + lohnsteuer / 12 * KIRCHENSTEUERSATZ
    else:
        return monats_lohn_brutto * STEUERSATZ

def print_solution(jahreslohn_netto, monats_lohn_netto):
    print(f"Sie verdienen im Jahr daher abzüglich der Lohnsteuer {jahreslohn_netto} Euro")
    print(f"Daraus ergibt sich abzüglich der restlichen Abgaben ein Monatslohn von {monats_lohn_netto} Euro Netto")


def main():
    kirchensteuerpflichtig = input(
        "Sind sie Mitglied in der Kirchgemeinde? Antwort hier eintragen (Ja oder nein): "
    ).lower() == 'ja'
    stundenlohn = float(input("Bitte geben sie hier ihren Lohn pro Stunde an: "))
    stunden_pro_tag = int(input("Bitte geben sie die Anzahl der Stunden ein, die sie pro Tag arbeiten: "))
    monats_lohn_brutto = stunden_pro_tag * 5 * 4 * stundenlohn
    jahreslohn_brutto = monats_lohn_brutto * 12
    if stundenlohn < 12.50:
        print("Sie verdienen unter Mindestlohn. Wir würden ihnen empfehlen, sich einen fairer bezahlten Job zu suchen")
    else:
        print(f"Ihr Lohn pro Monat beträgt {monats_lohn_brutto:.2f} Euro Brutto")
        print(f"Daraus ergibt sich ein Jahreslohn von {jahreslohn_brutto:.2f} Euro brutto")
        if jahreslohn_brutto >= 20000:  # Steuer für Lohn von 20.000
            lohnsteuer = 1748
        elif jahreslohn_brutto >= 30000:  # Steuer für Lohn von 30.000
            lohnsteuer = 4748
        elif jahreslohn_brutto >= 40000:  # Steuer für Lohn von 40.000
            lohnsteuer = 8620
        elif jahreslohn_brutto >= 60000:  # Steuer für Lohn von 60.000
            lohnsteuer = 16820
        elif jahreslohn_brutto >= 80000:  # Steuer für Lohn von 80.000
            lohnsteuer = 26274
        elif jahreslohn_brutto >= 100000:  # Steuer für Lohn von 100.000
            lohnsteuer = 36012
        elif jahreslohn_brutto >= 200000:  # Steuer für Lohn von 200.000
            lohnsteuer = 86012

        jahreslohn_netto = calc_jahreslohn_netto(jahreslohn_brutto, lohnsteuer)
        monats_lohn_netto = calc_monateslohn_netto(
            jahreslohn_netto, monats_lohn_brutto, kirchensteuerpflichtig,
            lohnsteuer)
        print_solution(jahreslohn_netto, monats_lohn_netto)

if __name__ == "__main__":
    main()
__es.2007__
User
Beiträge: 2
Registriert: Donnerstag 25. Mai 2023, 19:26

vielen Dank für die ganzen Antworten!
Ich konnte durch die Hilfe mein Problem jetzt lösen. Jedoch bin ich über den Wert nicht leerer String gestolpert, kann mir diesen vielleicht jemand erklären und wieso dieser immer als true ausgewertet wird? Leider kann ich zu diesem Thema irgendwo sonst etwas finden. Das n stand übrigens immer für netto und das b für brutto, tut mir leid falls das Unverständlichkeiten hervorgerufen hat
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

Es gibt einige Werte, die in if-Bedingungen als wahr ausgewertet werden, eine Zahl ungleich 0, alle Objekte, die eine Länge haben und deren Länge nicht 0 ist, usw.
Ein nicht-leerer String ist also ein String, dessen Länge nicht 0 ist, also mindestens ein Zeichen enhält. Ein leerer String enhält kein Zeichen "".
Benutzeravatar
__blackjack__
User
Beiträge: 13080
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Um das noch mal mit ein bisschen Code zu unterfüttern:

Code: Alles auswählen

In [119]: bool("")
Out[119]: False

In [120]: bool("x")
Out[120]: True

In [121]: bool("xyz")
Out[121]: True
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Benutzeravatar
DeaD_EyE
User
Beiträge: 1017
Registriert: Sonntag 19. September 2010, 13:45
Wohnort: Hagen
Kontaktdaten:

Ich beziehe mich mal nur auf diesen Teil:

Code: Alles auswählen

if jahreslohn_brutto >= 20000:  # Steuer für Lohn von 20.000
            lohnsteuer = 1748
        elif jahreslohn_brutto >= 30000:  # Steuer für Lohn von 30.000
            lohnsteuer = 4748
        elif jahreslohn_brutto >= 40000:  # Steuer für Lohn von 40.000
            lohnsteuer = 8620
        elif jahreslohn_brutto >= 60000:  # Steuer für Lohn von 60.000
            lohnsteuer = 16820
        elif jahreslohn_brutto >= 80000:  # Steuer für Lohn von 80.000
            lohnsteuer = 26274
        elif jahreslohn_brutto >= 100000:  # Steuer für Lohn von 100.000
            lohnsteuer = 36012
        elif jahreslohn_brutto >= 200000:  # Steuer für Lohn von 200.000
            lohnsteuer = 86012
Die Einrückung ist falsch. Alles nach der ersten Zeile des geposteten Codes muss um 8 leerzeichen reduziert werden.
Wenn `jahreslohn_brutto` unter 20_000 liegt, wird `lohnsteuer` nicht zugewiesen, was dann bei einem späteren Zugriff mit einem `NameError` endet.
Wenn `jahreslohn_brutto` == 30_000 ist, wird tortzdem die lohnsteuer der ersten Bedingung zugewiesen, da diese Wahr ist.


Ich habe das mal in eine Funktion gepackt und den Vergleich umgedreht.
Der else-Block wird ausgeführt, wenn `jahreslohn_brutto` über 200_000 liegt.
Ich gebe dann einfach den gleichen Wert wie für 200_000 aus.

Code: Alles auswählen

def lohnsteuer1(jahreslohn_brutto):
    if jahreslohn_brutto <= 20000:
        return 1748
    elif jahreslohn_brutto <= 30000:
        return 4748
    elif jahreslohn_brutto <= 40000:
        return 8620
    elif jahreslohn_brutto <= 60000:
        return 16820
    elif jahreslohn_brutto <= 80000:
        return 26274
    elif jahreslohn_brutto <= 100000:
        return 36012
    elif jahreslohn_brutto <= 200000:
        return 86012
    else:
        return 86012
Wenn man eine andere Datenstruktur verwendet, kann man die Daten einfacher verändern und muss wenig Code bei Änderungen bearbeiten.

Code: Alles auswählen

def lohnsteuer2(jahreseinkommen):
    lohnsteuer_mapping = {
        20_000: 1748,
        30_000: 4748,
        40_000: 8620,
        60_000: 16820,
        80_000: 26274,
        100_000: 36012,
        200_000: 86012,
    }
    # seit Python 3.7 behalten dicts die Reihenfolge der Keys
    for max_einkommen, lohnsteuer in lohnsteuer_mapping.items():
        if jahreseinkommen <= max_einkommen:
            return lohnsteuer

    return lohnsteuer
Falls die letzte Bedingung nicht erfüllt ist, wird die for-Schleife verlassen, dann aber `lohnsteuer` zurückgegeben. In diesem Fall hat `lohnsteuer` den letzten Wert.
sourceserver.info - sourceserver.info/wiki/ - ausgestorbener Support für HL2-Server
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

__es.2007__ hat geschrieben: Donnerstag 25. Mai 2023, 20:41 Jedoch bin ich über den Wert nicht leerer String gestolpert, kann mir diesen vielleicht jemand erklären und wieso dieser immer als true ausgewertet wird? Leider kann ich zu diesem Thema irgendwo sonst etwas finden.
Die Dokumentation von Python ist groß, aber es lässt sich dann doch die passende Stelle entdecken: Boolean operations.

Zitat des relevanten Teils: "In the context of Boolean operations, and also when expressions are used by control flow statements, the following values are interpreted as false: `False`, `None`, numeric zero of all types, and empty strings and containers (including strings, tuples, lists, dictionaries, sets and frozensets). All other values are interpreted as true."
Antworten