Hilfe für Operatoren Aufgabe

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
Sphere
User
Beiträge: 8
Registriert: Freitag 31. Juli 2015, 14:21

Hey,
Ich bin relativ neu in der Welt des Programmierens und lerne es nun seit 2-3 Tagen.
Angefangen habe Ich mit Python, da es eine gute Sprache für Neulinge sein soll.
Lernen tue Ich mit einem Buch, dass mir nach jedem Kapitel eine Aufgabe stellt die Ich bearbeiten soll.
Bis jetzt hat alles wunderbar geklappt, doch jetzt bin Ich an einer Aufgabe hängen geblieben und zwar soll man
mit mehreren Bedingungen den Steuersatz des monatlichen Bruttogehalts und dem familiären Status, mit Operatoren, wiedergeben.

Mein Problem liegt bei der zweiten Eingabe des Benutzers, nähmlich soll dieser seinen Familiären Status eingeben und mit diesem input weiß ich nicht wie Ich weiter arbeiten soll, denn wenn Ich mein Programm starte gibt es spätestens in Line 12 einen NameError.

Ich wäre euch für eure Hilfe sehr dankbar, Ich möchte kein ganzen Lösungsvorschlag sondern vielleicht nur einen kleinen Hinweis, damit Ich selber das Programm zuende schreiben kann.



Der Code

Der Fehler
BlackJack

@Sphere: Der Name `a` ist ja auch in der Tat nirgends definiert. Was erwartest Du denn was in der Zeile passieren soll?

Die Namensgebung ist auch sehr schlecht. Statt `x`, `y`, `a`, und `b` sollte man Namen verwenden die dem Leser verraten was der Wert der dahinter steckt *bedeutet*. Zum Beispiel `brutto_gehalt`, `familienstand`, und `VERHEIRATET` und `LEDIG` als Namen für die beiden Zeichenketten. Wenn es bei den beiden Wahlmöglichkeiten bleibt würde sich auch statt `familienstand` ein Name `ist_ledig` anbieten der je nach Status an `True` oder `False` gebunden wird.
Sphere
User
Beiträge: 8
Registriert: Freitag 31. Juli 2015, 14:21

@BlackJack Danke für die Tipps, werde das sofort ändern!
BlackJack

@Sphere: Noch ein paar Anmerkungen: Bildschirmfotos irgendwo anders hochladen und hier verlinken ist nicht besonders praktisch. Du kannst den Quelltext direkt hier im Beitrag einfügen und mit Code-Tags (da gibt's über dem Texteingabefeld eine Schaltfläche für) auch farbige Syntaxhervorhebung erreichen.

Zwischen Funktionsname und Klammern für den Aufruf gehört kein Leerzeichen. Bei `input()` hast Du das ja auch nicht, aber bei jedem `print()`‽

Die `print()`-Aufrufe vor den `input()`-Aufrufen sind überflüssig, denn den Text hätte man auch `input()` als Argument mitgeben können.

Die Kommentare sind allesamt überflüssig weil sie dem Leser keinerlei Mehrwert bieten. Das bisschen was die aussagen sieht man auch am Code problemlos.

Wenn der Benutzer weder 'verheiratet' noch 'ledig' eingibt, dann endet Dein Programm mit einer Ausnahme. Das ist also fehlerhaft.

Die ganzen ``if``-Bedingungen die am Ende die Ausgabe bestimmen schliessen sich alle gegenseitig aus, dass heisst wenn eine davon zutrifft, dann tun das alle anderen nicht. Deshalb sollte man dort ``elif`` einsetzen, damit nur solange Prüfungen durchgeführt werden bis das Ergebnis feststeht und nicht in dem Fall noch weitere, unnötige Prüfungen ausgeführt werden.

Letztlich würde man hier sehr wahrscheinlich sowieso ``if``\s verschachteln und auch mit ``else`` arbeiten, denn auch bei den Teilbedingungen die dort mit ``and`` verknüpft werden, handelt es sich ja um sich jeweils gegenseitig ausschliessende Bedingungen, wer mehr als 4000 verdient kann nicht gleichzeitig weniger verdienen, und wer verheiratet ist kann nicht gleichzeitig ledig sein. Man muss also nur jeweils eine der Bedingungen prüfen und kann den anderen Fall dann ohne zusätzliche Prüfung mit einem ``else`` abarbeiten.

Wiederholungen von Code und Daten sollte man vermeiden weil das schnell fehlerhanfällig bei Programmänderungen wird, oder zumindest mehr Arbeit erfordert, weil man Code und/oder Daten dann nicht nur an einer Stelle verändern kann, sondern immer darauf achten muss auch alle Kopien anzupassen und das auch noch exakt gleich oder zumindest so das es am Ende den gleichen Effekt hat. In jedem der Zweige bei der Ausgabe steht im Grunde der gleiche `print()`-Aufruf dessen Text sich nur durch die Ziffern vor dem Prozentzeichen unterscheiden. Wenn man den Text nun anpassen möchte, muss man das an vier Stellen tun. Wenn man in den Verzweigungen nur den Steuersatz ermittelt und an einen Namen bindet, kann man die Ausgabe *nach* der Ermittlung machen und hat den Text nur *einmal* im Quelltext stehen.

Ich komme dann ungefähr bei so etwas heraus (ungetestet):

Code: Alles auswählen

def main():
    salary = float(input('Bitte geben Sie Ihr monatliches Bruttogehalt ein: '))

    civil_status = input(
        'Bitte geben Sie Ihren familiären Status an (ledig/verheiratet): '
    ).strip().lower()
    if civil_status == 'ledig':
        is_married = False
    elif civil_status == 'verheiratet':
        is_married = True
    else:
        print('Unbekannter familiärer Status:', civil_status)
        return

    if salary > 4000:
        tax_rate = 22 if is_married else 26
    else:
        tax_rate = 18 if is_married else 22
    print('{0}% Steuersatz'.format(tax_rate))



if __name__ == '__main__':
    main()
Was man hier jetzt als nächstes angehen könnte/sollte wäre den Code sinnvoll auf Funktionen zu verteilen. Zum Beispiel für die beiden Benutzereingaben welche schreiben die auch mit Fehleingaben umgehen können, in dem sie beispielsweise den Benutzer solange nach einer Eingabe fragen, bis die akzeptiert werden kann.
Antworten