Logische Operatoren

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
VegetarianSalad
User
Beiträge: 7
Registriert: Montag 31. Dezember 2012, 10:46

Hallo! :)
Ich hatte mich schon längere Zeit für das Programmieren interessiert und bringe mir gerade Python mit einem Buch selber bei. (Bin aber totaler Anfänger) Bis jetzt konnte ich die Übungen selber lösen nur ich komme schon seit längere Zeit bei diesem Problem nicht weiter. Es gibt um die Operatoren and,or und not. Meine Aufgabe ist ein Programm zu schreiben das den monatlich zu zahlenden Steuerbetrag anzeigt.
Ich habe jetzt alles kopiert weil ich glaube dass es mehrere Zusammenhänge gibt. Hoffentlich ist es noch übersichtlich.

Code: Alles auswählen

print('Bitte geben sie ihr Bruttogehalt in Euro ein')
x=input()
zahl=float(x)
print('Bitte geben sie ihren Familienstand ein. Ledig ist die Ziffer 1 und')
print('verheiratet die Ziffer 2')
y=input()
bla=float(y) 

if zahl<4000 and y = 1:   <---(Das Gleichheitszeichen hier wird immer als Problem betrachtet. Was hab ich falsch gemacht?)
    z=26/100*zahl
    print('Der monatlich zu zahlende Steuerbetrag beträgt',z,'Euro')
if zahl<4000 and y=2:
    z=22/100*zahl
    print('Der monatlich zu zahlende Steuerbetrag beträgt',z,'Euro')

Die Aufgabe geht noch weiter aber ich bin nur bis hier gekommen.
Danke schonmal!
Zuletzt geändert von VegetarianSalad am Montag 31. Dezember 2012, 11:43, insgesamt 1-mal geändert.
Benutzeravatar
jbs
User
Beiträge: 953
Registriert: Mittwoch 24. Juni 2009, 13:13
Wohnort: Postdam

Stell deine Fragen am Besten nicht um Quelltext und poste bitte lauffähigen Code. Kommentare leitet man in Python mit # ein.

Suche mal nach boolsche Operationen Python und versuche deinen Fehler selbst zu finden.

Anstatt

Code: Alles auswählen

print('Bitte geben sie ihr Bruttogehalt in Euro ein')
x=input()
kannst du auch direkt

Code: Alles auswählen

x = float(input('Bitte geben sie ihr Bruttogehalt in Euro ein'))
verwenden.
Deine Abfrage auf verheiratet/ledig erfordert keine Umwandlung in eine Zahl, insbesondere, weil es hier auch kein Sinn macht eine Zahl zu verwenden. Du suchst einen Repräsentanten, das heißt du kannst genauso gut 'l' und 'v' verwenden.
Es gibt neben ``if`` auch noch ``elif`` und ``else``.
Ansonsten sei hier auf PEP-8 und insbesondere auf den Aspekt der sehr kurzen Variablennahmen verwiesen.
[url=http://wiki.python-forum.de/PEP%208%20%28%C3%9Cbersetzung%29]PEP 8[/url] - Quak!
[url=http://tutorial.pocoo.org/index.html]Tutorial in Deutsch[/url]
VegetarianSalad
User
Beiträge: 7
Registriert: Montag 31. Dezember 2012, 10:46

Dankeschön! :)
Benutzeravatar
pillmuncher
User
Beiträge: 1484
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

Das Gleichheitszeichen in Python ist ==, das einfache = ist das Zuweisungszeichen. Letzteres verwendest du, um Variablen einen Wert zuzuweisen (genauer: um Namen an Werte zu binden):

Code: Alles auswählen

a = "hallo"
print a
a = "welt"
print a
Das == verwendest du, um Werte zu vergleichen:

Code: Alles auswählen

if a == "welt":
    print 'ja, a ist "welt"'
Und übrigens: mit is vergleicht man Objektidentität, die etwas stärkeres ist, als Gleichwertigkeit:

Code: Alles auswählen

>>> 'welt' == '{0}'.format('welt')
True
>>> 'welt' is '{0}'.format('welt')
False
In specifications, Murphy's Law supersedes Ohm's.
VegetarianSalad
User
Beiträge: 7
Registriert: Montag 31. Dezember 2012, 10:46

Hab jetzt alles nochmal überarbeitet und funktioniert bestens. Danke!

Code: Alles auswählen

x = float(input('Bitte geben sie ihr Bruttogehalt in Euro ein'))
print('Bitte geben sie ihren Familienstand ein (Ledig ist die Ziffer 1')
print('und verheiratet die Ziffer 2)')
a = input()
y = float(a)

if x<4000 and y == 1:
    z=26/100*x
    print('Der monatlich zu zahlende Steuerbetrag beträgt',z,'Euro.')
elif x<4000 and y == 2:
    z=22/100*x
    print('Der monatlich zu zahlende Steuerbetrag beträgt',z,'Euro.')
elif x<=4000 and y == 1:
      z=18/100*18
      print('Der monatlich zu zahlende Steuerbetrag beträgt',z,'Euro.')
elif x<=4000 and y == 2:
      print('Der monatlich zu zahlende Steuerbetrag beträgt',z,'Euro.')
Benutzeravatar
jbs
User
Beiträge: 953
Registriert: Mittwoch 24. Juni 2009, 13:13
Wohnort: Postdam

Da würde ich aber noch ein bisschen vorher Testen.

Wann wird denn deiner Meinung nach eine der letzteren beiden Bedingungen überprüft und wahr?
[url=http://wiki.python-forum.de/PEP%208%20%28%C3%9Cbersetzung%29]PEP 8[/url] - Quak!
[url=http://tutorial.pocoo.org/index.html]Tutorial in Deutsch[/url]
Sirius3
User
Beiträge: 17759
Registriert: Sonntag 21. Oktober 2012, 17:20

Du wiederholst Dich sehr oft. Besser ist es, gleiche Teile nur einmal zu schreiben.
In Deinem Fall:

Code: Alles auswählen

if x<4000 and y == 1:
    steuersatz = 26/100
elif x<4000 and y == 2:
    steuersatz = 22/100
elif [...]

steuer = steuersatz * x
print('Der monatlich zu zahlende Steuerbetrag beträgt {0:.2f} Euro.'.format(steuer))
x,y und z sind immer noch keine guten Variablennamen.
Nimm Namen, an denen man ablesen kann, für was sie stehen.
BlackJack

@VegetarianSalad: `a`, `x`, `y`, und `z` sind keine guten Namen. Die letzten drei würden sich eventuell noch für Koordinaten eignen. Aber in diesem Programm sind sie einfach nur nichtssagende Einbuchstabennamen. Ein Name soll dem Leser des Quelltextes aber vermitteln wofür der Wert im Programm steht, also das Lesen und Verstehen des Programms erleichtern.

Ein grundlegendes Prinzip beim Programmieren ist das DRY-Prinzip: „Don't Repeat Yourself”. Das gilt sowohl für Code als auch für Daten. Bei Deinem Programm werden Teile der Bedingungen wiederholt, die grundlegende Berechnung steht dort wiederholt, sowie die Ausgabe mit immer dem selben Quelltext. Wenn man die Grenze von 4.000 € oder den Ausgabetext mal ändern möchte, dann sollte man das bei einem gut geschriebenen Quelltext jeweils nur an *einer* Stelle im Quelltext machen müssen und nicht vier mal. Das ist fehleranfällig, weil man bei umfangreicheren Programmen die so aussehen schnell mal eine Stelle übersieht oder mehrere verschiedene Stellen nicht exakt gleich verändert bei der Anpassung.

Das Programm ist auch fehlerhaft. Die Vergleiche stimmen mit Sicherheit nicht. Im vorletzen ``elif``-Zweig vermute ich mal das die Berechnung von `z` falsch ist, oder das man die zumindest einfacher schreiben kann in dem man die Konstante einfach ausrechnet. Und im letzten Zweig wird versucht ein `z` auszugeben, welches gar nicht existiert, was zu einem `NameError` führt.

Wenn am Anfang oder am Ende von verschiedenen ``if``-Zweigen der selbe Code steht, dann gehört der *einmal* davor oder danach.

Innerhalb von einem ``if``-, ``elif``-, oder ``else``-Zweig kann man durchaus wieder ``if``-Konstrukte verwenden.

Wenn so ein Konstrukt in einem ``elif`` endet, ist das in der Regel ein „code smell” — da fehlt ein ``else``. Überlege mal was es in Deinem Programm bedeutet wenn dieser ``else``-Zweig ausgeführt wird. Also nachdem Du die Bedingungen korrigiert hast. Für Fälle wo es eigentlich gar keinen Fall geben kann in dem ein ``else`` ausgeführt würde, bietet es sich an ``assert False`` dort reinzuschreiben. Damit man mitbekommt wenn etwas passiert, was eigentlich nie passieren dürfte.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Darüber hinaus solltest Du PEP8 besser beachten. Man lässt idR. Lerrzeichen zwischen Operanden und Operatoren:

Code: Alles auswählen

# Bei Dir
if x<4000 and y == 1:
# besser:
if x < 4000 and y == 1:
Zudem wundert es mich, wieso Du den Tipp mit dem Casten beim ``input`` nur *einmal* umgesetzt hast... was ist denn an Fall zwei so anders, dass Du es dort so belässt wie zuvor?

Was aber wirklich ganz dringend verbessert gehört: Deine Namensgebung! Was bitte schön bedeuten denn ``x`` und ``y`` hier? Bei einer Geradengleichung oder Kurvendiskussion sind das Standardnamen, ok, aber bei einer Steuerberechnung wäre ich jetzt nicht darauf gekommen, dass ``y`` den Familienstand beinhaltet. Es mag Dir lächerlich vorkommen, dass man bei so einem kleinen Script darauf rumhackt, aber glaube mir (respektive "uns", denn das werden Dir hier alle Regulars sagen): Es ist wirklich immanent wichtig, sich von Beginn an immer sinnvolle Namen für Variablen auszudenken. Leonidas hatte da iirc ein nettes Zitat von einem bekannten Informatiker diesbezüglich.

Ich würde ``x`` durch ``salary`` ersetzen und ``y`` durch ``family_status``. Das sind lesbare Namen, die sofort verdeutlichen, was sich hinter einem Namen als Objekt verbirgt.

Wobei man tatsächlich überlegen sollte, für den Familienstand einen anderen Typen zu wählen als einen Integerwert. Man könnte bei nur zwei möglichen Status einen boolschen Wert nutzen und den Namen ``married`` wählen. ``True`` bedeutet ohne groß zu überlegen "verheiratet" und ``False`` "nicht verheiratet" (-> "ledig").

Als letztes würde ich die ``print``-Zeilen aus den Berechnungsästen herausnehmen und zu *einer* Zeile nach den Berechnungen zusammenfassen. Du hast da vier Mal denselben Code stehen - das sollte man niemals so stehen lassen und sich überlegen, wie man das vereinfachen kann. Du kannst doch einfach *nach* den ganzen Berechnungen die ``print``-Zeile einmal hinschreiben. Solltest Du Fälle abfangen wollen, in denen kein Steuerbetrag berechnet und ausgegeben wird, so kann man sich darüber später immer noch Gedanken machen.

Edit: Ok, war nicht schnell genug. Aber damit es deutlich wird, dass wir hier ähnliche Ratschläge geben, poste ich es dennoch ;-)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
VegetarianSalad
User
Beiträge: 7
Registriert: Montag 31. Dezember 2012, 10:46

Danke für die tollen Tipps! Benutze das Buch ,,Einstieg in Python'' (Thomas Teis, Galileo Computing) was hier im Forum sehr kritisiert wird. Ich glaube ich kann es jetzt langsam verstehen warum es nicht so gut ist. Alles was ihr nicht so toll fand wurde im Buch als sehr gute Vorgehensweise dargestellt. Vielleicht kommt das noch nach. Denn so Bücher mit CD sind ja nicht so günstig ;) Empfiehlt ihr denn bessere Bücher? Ich persönlich finde das Buch okay denn es erklärt wirklich so dass ich es als ,,Junger Teenager'' (12, keine Ahnung ob ich hier was zu suchen hab hier hängen anscheinend nur Studenten und Leute auf dem neusten Stand rum. :wink: :lol: ) noch verstehen kann. X,y und z war das kreativste was mir als erstes einfiel aber ich änder das jetzt auch.
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

VegetarianSalad hat geschrieben:Empfiehlt ihr denn bessere Bücher?
Schade dass Weihnachten schon vorbei ist, sonst hätte ich Dir das nicht ganz so günstige "Python Praxisbuch" von Farid Hajji empfohlen. Das ist zwar auf dem Stand von Python 2.5, was ich für den Einstieg aber nicht als Hindernis sehe. Dann finde ich die Bücher von Mark Lutz (auf englisch) noch ganz gut, wenngleich dieser bisweilen zu einem wortreichen Stil neigt. Ansonsten findest Du gute - und zudem kostenfreie - Einführungen z.B. hier
http://www.diveintopython.net/
oder auch hier
http://learnpythonthehardway.org/book/
Das ist zwar alles auf englisch, aber trau Dich ... :)
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

VegetarianSalad hat geschrieben:(12, keine Ahnung ob ich hier was zu suchen hab hier hängen anscheinend nur Studenten und Leute auf dem neusten Stand rum. :wink: :lol: )
Also ich habe seinerzeit auch mit 12 angefangen zu programmieren... damals auf dem C64, ohne Internet oder Leute, die mir Tipps hätten geben können. Ich hatte nur einige Zeitschriften und ein Basic Buch... insofern: Das Alter alleine ist nicht entscheidend, sondern der eigene Antrieb :-) Und wenn Du eben mal etwas nicht sofort kapierst, dann ist das nicht weiter schlimm. Das geht uns "älteren" Semstern durchaus auch so... Erkenntnis stellt sich eben nicht einfach nach Plan ein, sondern braucht ab und an mehrere Anläufe. Ich kann mich noch so gut an einen Abend anno '92 erinnern, an dem ich endlich kapiert habe, wozu Arrays gut sind, obwohl ich davor schon einige Monate immer wieder versucht hatte, das zuz kapieren...
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

kbr hat geschrieben:Ansonsten findest Du gute - und zudem kostenfreie - Einführungen z.B. hier
http://www.diveintopython.net/
DIP ist 9 Jahre alt und auf dem Stand von 2.4, wenn man großzügig ist und vom letzten Update ausgeht. Die Sprache hat sich zwar nicht fundamental geändert aber Änderung hat es in der Zeit schon einige gegeben, dass führt dann zu "interessanten" Abschnitten wie diesem oder dazu dass beim Umgang mit Dateien kein with benutzt wird. Von PEP 8 scheint der Autor auch nicht sonderlich viel zu halten. Wenn ich Abschnitte mit Titeln wie "Using sys.modules" sehe und daran denke was Anfänger für Code schreiben nach dieser Lektüre schreiben werden, läuft es mir kalt den Rücken runter. Abschnitte zu Themen wie HTML/XML Processing und HTTP sind so veraltet, dass ich geneigt bin solchen Code heute als falsch zu bezeichnen und der Abschnitt zu unit testing ist auch nur unglücklicherweise noch relevant, zumindest von tox sollte man aber dennoch gehört haben und es würde auch nicht schaden, wenn ein Anfänger Alternativen zu unittest kennen würde. Liest man weiter kommt man an einem Abschnitt mit dem Titel "Dynamically importing modules" vorbei, auch so ein Thema von dem ein Anfänger am besten als erstes Bescheid wissen sollte.

LPTHW ist allerdings durchaus empfehlenswert und in der Dokumentation ist auch gutes Tutorial, welches zwangsläufig immer aktuell ist.
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

DasIch hat geschrieben:DIP ist 9 Jahre alt und auf dem Stand von 2.4, wenn man großzügig ist und vom letzten Update ausgeht.
Hm... ich fürchte ich habe mir DIP wohl ziemlich lange selbst nicht mehr angeschaut. Immerhin scheint http://getpython3.com/diveintopython3/ aktueller zu sein; habe das Skript bislang aber noch nicht kritisch gelesen.
VegetarianSalad
User
Beiträge: 7
Registriert: Montag 31. Dezember 2012, 10:46

Danke für die Tipps! Ich schau mir mal die Internetseiten an und ich denke dass man im Internet (da man alles im Internet findet) auch nach den Änderungen der Versionsänderungen nachschauen kann.
VegetarianSalad
User
Beiträge: 7
Registriert: Montag 31. Dezember 2012, 10:46

Hyperion hat geschrieben:
VegetarianSalad hat geschrieben:(12, keine Ahnung ob ich hier was zu suchen hab hier hängen anscheinend nur Studenten und Leute auf dem neusten Stand rum. :wink: :lol: )
Also ich habe seinerzeit auch mit 12 angefangen zu programmieren...
Vielleicht hätte ich noch erwähnen sollen dass ich ein Mädchen bin. :) Ist ja nicht deine Schuld.
Zuletzt geändert von VegetarianSalad am Donnerstag 3. Januar 2013, 18:31, insgesamt 2-mal geändert.
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

VegetarianSalad hat geschrieben:und ich denke dass man im Internet (da man alles im Internet findet) auch nach den Änderungen der Versionsänderungen nachschauen kann.
Ich habe so meine Probleme mit dem Satz, aber ich glaube du suchst das hier: http://docs.python.org/2/whatsnew/

leider gibts das nicht zwischen groesseren Spruengen und auch nicht uebersetzt.
Antworten