Seite 1 von 1
Simple Logik If or will nicht
Verfasst: Dienstag 18. April 2017, 13:16
von kani
Hier mal ein simples Beispiel:
Herraus kommt bei Days dann bei mir immer der falsche Wert 31Tage hat der April.
schon tage lang rumprobiert mit if /not /or komm nicht drauf warum!?
beispiel auszug aus mein Ziel zeit Rechner.
Code: Alles auswählen
month = 4
if month == 1 or 3 or 5 or 7 or 8 or 10 or 12:
days = 31
elif month == 4 or 6 or 9 or 11:
days = 30
else:
print ('fehler')
print (month)
print (days)
Re: Simple Logik If or will nicht
Verfasst: Dienstag 18. April 2017, 13:20
von Liffi
kani hat geschrieben:
month = 4
if month == 1 or 3 or 5 or 7 or 8 or 10 or 12:
days = 31
Ist immer wahr. Erste Abfrage ist: month == 1 -> wahr wenn month 1 ist. or 3 -> immer wahr. or 5 -> immer wahr...
Vielleicht willst du etwas benutzen wie:
Re: Simple Logik If or will nicht
Verfasst: Dienstag 18. April 2017, 13:24
von Zizibee
Was du wohl gemeint hast:
Code: Alles auswählen
if month == 1 or month == 3 or month == 5 or month == 7 or month == 8 or month == 10 or month == 12:
days = 31
Re: Simple Logik If or will nicht
Verfasst: Dienstag 18. April 2017, 13:40
von kani
Achja danke an alle hatte schon wieder vergessen das ich immer wieder month extra davorschreiben muss bei jeder einzelnen bedingung. (Bin noch beginner im Selbststudium da vergisst man schon mal sowas wichtiges wieder danke!)
Thema: Erledigt Kann geschlossen werden!
mfg Kani
Re: Simple Logik If or will nicht
Verfasst: Dienstag 18. April 2017, 13:53
von BlackJack
@kani: Wenn der Fehlerzweig genommen wird, dann wird danach ja trotzdem noch versucht `days` auszugeben, was dann aber zu einem `NameError` führt. Das ist also irgendwie nur eine halbe Fehlerbehandlung.
Re: Simple Logik If or will nicht [Tage pro Monat Ausrechnen]
Verfasst: Dienstag 18. April 2017, 14:51
von kani
Stimmt BlackJack habs gemerkt das es noch nicht Funktioniert! Allerdings erst später g*!
Habe aber selbst eine lösung gefunden nach stunden langem rum probieren sogar mit Schaltjahr berücksichtigung bis Jahr xxxx. Allerdings mit viel schreiben/code das müste auch irgentwie einfacher gehen bzw. mit weniger code möglich sein. Aber egal hauptsache ich hab nen Funktioenierenden Code mit Python 3.6.:
Code: Alles auswählen
d = Tage
mo = monate
y = Jahr
if mo == 1:
d = 31
elif mo == 2:
if y == 2016:
d = 29
elif y == 2020:
d = 29
elif y == 2024:
d = 29
elif y == 2028:
d = 29
elif y == 2032:
d = 29
elif y == 2036:
d = 29
elif y == 2040:
d = 29
elif y == 2044:
d = 29
elif y == 2048:
d = 29
elif y == 2052:
d = 29
elif y == 2056:
d = 29
elif y == 2060:
d = 29
elif y > 2060:
d = 0000
else:
d = 28
elif mo == 3:
d = 31
elif mo == 4:
d = 30
elif mo == 5:
d = 31
elif mo == 6:
d = 30
elif mo == 7:
d = 31
elif mo == 8:
d = 31
elif mo == 9:
d = 30
elif mo == 10:
d = 31
elif mo == 11:
d = 30
elif mo == 12:
d = 31
else:
print ('Fehler Bitte geben Sie das nächste mal eine Zahl von 1-12 ein!')
dann kommt hier die ausgabe der Tage....
Re: Simple Logik If or will nicht
Verfasst: Dienstag 18. April 2017, 15:22
von Liffi
Puh. Ein paar Tipps:
- Variablen lieber nicht abkürzen
- 0000 entspricht 0
- Für Schaltjahre gibt es eine schöne Formel, mit der du wunderbar deine Kenntnisse über Verzweigungen benutzen kannst
- Evtl. bietet sich für die 'einfachen' Monate auch ein dictionary an
Re: Simple Logik If or will nicht
Verfasst: Dienstag 18. April 2017, 15:56
von BlackJack
@kani: Am kürzesten dürfte es mit `calendar.monthrange()` werden.

Re: Simple Logik If or will nicht
Verfasst: Mittwoch 19. April 2017, 13:49
von Zizibee
Ich hatte etwas Zeit und wollte versuchen das "Tage_pro_Monat-Programm" (für meine Verhältnisse) einmal schön umzusetzen. Meint ihr das passt so oder würde man das mit Python anders lösen? Ist das dictionary in der get_days Funktion vielleicht doch nicht so geeignet?
Code: Alles auswählen
def main():
while True:
try:
month = int(input('Eingabe Monat: '))
if 0 < month < 13: break
except ValueError:
print('Falsche Eingabe, erlaubt ist 1 - 12')
# Jahrszahl nur für den Februar nötig
if month == 2:
while True:
try:
year = int(input('Eingabe Jahr: '))
if year > 0: break
except ValueError:
print('Falsche Eingabe, nur Zahlen erlaubt')
output(month, get_days(month, year), year)
else:
output(month, get_days(month))
def get_days(month, year = None):
'''Gibt die Anzahl der Tage von month zurück. year wird nur beim Monat Februar benötigt'''
# Länge der Monate in einem dictionary speichern
month_days = dict.fromkeys([1, 3, 5, 7, 8, 10, 12], 31)
month_days.update(dict.fromkeys([4, 6, 9, 11], 30))
month_days.update({2: {'is_leapyear': 29, 'no_leapyear': 28}})
if year is None: # Für alle Monate außer Februar
return month_days[month]
elif month == 2 and year is not None: # Für den Februar
if (year % 4 == 0 and year % 100 != 0) or (year % 4 == 0 and year % 100 == 0 and year % 400 == 0): #Schaltjahr
leapyear = 'is_leapyear'
else:
leapyear = 'no_leapyear'
return month_days[month][leapyear]
else:
return -1
def output(month, days, year = None):
'''Gibt die Tage, den Monat und ggf. das Jahr ordentlich aus'''
# dictionary mit den Monatsnamen
month_names = {1: 'Januar', 2: 'Februar', 3: 'März', 4: 'April', 5: 'Mai', 6: 'Juni', 7: 'Juli', 8: 'August', 9: 'September', 10: 'Oktober', 11:'November', 12: 'Dezember'}
if year is None:
print('Der {} hat {} Tage'.format(month_names[month], days))
else:
print('Der {} im Jahr {} hat {} Tage'.format(month_names[month], year, days))
if __name__ == '__main__':
main()
Mir ist übrigens bewusst, dass man das Programm mit BlackJacks Vorschlag noch geringfügig kürzen kann
Code: Alles auswählen
import calendar
month = int(input('Eingabe Monat: '))
year = int(input('Eingabe Jahr: '))
print(calendar.monthrange(year, month)[1])
Re: Simple Logik If or will nicht
Verfasst: Mittwoch 19. April 2017, 14:21
von Sirius3
@Zizibee: es ist wohl nicht Absicht, dass bei Falscheingaben nicht immer die Fehlermeldung kommt. Die Funktion get_days ist seltsam, da sie bei month=2 nur mit year!=None funktioniert, für month!=2 aber nur mit year == None. Die if-Bedingung für ein Schaltjahr ist auch noch zu kompliziert. Außerdem wird das Wörterbuch für month == 2 ja nicht wirklich gebraucht. Statt -1 bei falschen Parametern sollte die Funktion auch eine Exception werfen.
Re: Simple Logik If or will nicht
Verfasst: Mittwoch 19. April 2017, 15:05
von Zizibee
@Sirius: Danke für die konstruktive Antwort!
Sirius3 hat geschrieben:es ist wohl nicht Absicht, dass bei Falscheingaben nicht immer die Fehlermeldung kommt.
Das ist mir zwar aufgefallen, aber leider ist mir keine Lösung eingefallen, um in try abzufragen, ob der Wert in einem bestimmten Wertebereich liegt und dann eine Exception zu werfen :K
Sirius3 hat geschrieben:Die Funktion get_days ist seltsam, da sie bei month=2 nur mit year!=None funktioniert, für month!=2 aber nur mit year == None.
Da hast du wohl recht, das ist zum Anwenden umständlich und kompliziert. Werde ich überarbeiten
Sirius3 hat geschrieben:Die if-Bedingung für ein Schaltjahr ist auch noch zu kompliziert.
Jetzt da du es sagst... aber bestimmt hast du noch mehr gesehen als ich
Sirius3 hat geschrieben:Außerdem wird das Wörterbuch für month == 2 ja nicht wirklich gebraucht. Statt -1 bei falschen Parametern sollte die Funktion auch eine Exception werfen.
Das month == 2 kam erst rein, als ich Fehler abfangen wollte und das return -1 hinzu kam. Das werde ich zusammen mit der kompletten Funktion überarbeiten.
Re: Simple Logik If or will nicht
Verfasst: Donnerstag 20. April 2017, 13:51
von Zizibee
Ich habe die Punkte überarbeitet und denke bzw. hoffe, dass es jetzt passt.
Der try... except Block für die Eingabe wurde angepasst und der Wertebereich wird jetzt über einen AssertionError abgefangen. Ich hoffe ich habe sie im Sinne des Erfinders angewendet.
Code: Alles auswählen
def main():
while True:
try:
month = int(input('Eingabe Monat: '))
assert 0 < month < 13
break
except ValueError:
print('ValueError: Falsche Eingabe, es sind nur ganze Zahlen erlaubt')
except AssertionError:
print('AssertionError: Falsche Eingabe, erlaubt ist 1 - 12')
# Jahrszahl ist nur für den Februar nötig
if month == 2:
while True:
try:
year = int(input('Eingabe Jahr: '))
assert year > 0
break
except ValueError:
print('Falsche Eingabe, es sind nur ganze Zahlen erlaubt')
except AssertionError:
print('Falsche Eingabe, es sind nur positive Zahlen erlaubt')
output(month, get_days(month, year), year)
else:
output(month, get_days(month))
Die Funktion get_days() akzeptiert nun bei allen Monaten Jahreszahlen und sollte dadurch robuster in der Anwendung sein. Zusätzlich erhält man bei einem fehlerhaften Aufruf keine -1 mehr als Rückgabewert, sondern es wird eine Exception geworfen. Auch wurde die Bedingung für das Schaltjahr vereinfacht.
Code: Alles auswählen
def get_days(month, year = None):
'''Gibt die Anzahl der Tage von month zurück. year wird nur beim Monat Februar benötigt'''
# Länge der Monate in einem dictionary speichern
month_days = dict.fromkeys([1, 3, 5, 7, 8, 10, 12], 31)
month_days.update(dict.fromkeys([4, 6, 9, 11], 30))
month_days.update({2: {'is_leapyear': 29, 'no_leapyear': 28}})
if month == 2:
try:
if (year % 4 == 0 and (year % 100 != 0 or year % 400 == 0)): #Schaltjahr
leapyear = 'is_leapyear'
else:
leapyear = 'no_leapyear'
return month_days[month][leapyear]
except TypeError:
print('Error in get_days(), fehlende Jahreszahl bei Februar => Jahr wird auf "kein Schaltjahr" gesetzt')
return month_days[month]['no_leapyear']
else:
return month_days[month]
An der Ausgabe habe ich nichts geändert.
Re: Simple Logik If or will nicht
Verfasst: Donnerstag 20. April 2017, 14:10
von __deets__
Assertions sind nicht fuer so etwas gedacht. Man kann sie naemlich auch automatisch rausschmeissen, wenn man pyo (optimierte Python Bytecode Dateien) erzeugt.
Stattdessen eine einfach Abfrage "if year <= 0" machen.
Und statt string-Konstanten in leapyear einfach
Code: Alles auswählen
is_leapyear = (year % 4 == 0 and (year % 100 != 0 or year % 400 == 0))
und dann einfach das dict von "is_leapyear": 29 auf True: 29 aendern.
Re: Simple Logik If or will nicht
Verfasst: Donnerstag 20. April 2017, 14:43
von Zizibee
__deets__ hat geschrieben:Assertions sind nicht fuer so etwas gedacht. Man kann sie naemlich auch automatisch rausschmeissen, wenn man pyo (optimierte Python Bytecode Dateien) erzeugt.
Stattdessen eine einfach Abfrage "if year <= 0" machen.
Also dann so in der Art? Auch wenn dann für den Wertebereich streng genommen keine Exception geworfen wird?
Code: Alles auswählen
try:
month = int(input('Eingabe Monat: '))
is 0 < month < 13:
break
else:
print('Falsche Eingabe, erlaubter Zahlenbereich ist 1 - 12')
except ValueError:
print('ValueError: Falsche Eingabe, es sind nur ganze Zahlen erlaubt')
Re: Simple Logik If or will nicht
Verfasst: Donnerstag 20. April 2017, 16:05
von __deets__
Eine Exception ist doch kein Selbstzweck. Wenn du willst, kannst du natuerlich im else-Zweig ebenfalls einen ValueError werfen, und dann deine Fehlermeldung entsprechend so aendern, dass es nur noch heisst "Falsche Eingabe, es sind nur ganze Zahlen von 1 - 12 erlaubt".
Das "ValueError: " in der Fehlermeldung bei dir wuerde ich mir uebrigens sparen, damit kann kein Benutzer etwas anfangen. Der Rest der Meldung reicht.