Warum immer Sonntag? (Datum in Wochentag umrechnen Python)?
Hallo,
Warum schmeißt er mir immer ein Sonntag entgegen, egal welches Datum ich eingebe?
print("Datum als Wochentag")
Rohling = 0
Wochentagcode = 0
Monatscode = 0
yearcode = 0
Schaltjahr = False
schalterjahr2 = []
def schaltjahre_berechnung():
schalterjahr1 = 1904
while schalterjahr1 <= 2160:
schalterjahr1 += 4
schalterjahr2.append(schalterjahr1)
return schalterjahr2
Tag = int(input("Tag: "))
Monat = int(input("Monat: "))
Jahr = int(input("Jahr: "))
letzte_zwei_ziffern_des_jahres = Jahr % 100
def Schaltjahrjahr(schalterjahr2):
if schalterjahr2 == Jahr:
Schaltjahr = True
#if Schaltjahr:
#Januar = 5
#Februar = 1
def Monate(Monat):
if Monat == 1:
Monatscode = 6
elif Monat == 2:
Monatscode = 2
elif Monat == 3:
Monatscode = 2
elif Monat == 4:
Monatscode = 5
elif Monat == 5:
Monatscode = 0
elif Monat == 6:
Monatscode = 3
elif Monat == 7:
Monatscode = 5
elif Monat == 8:
Monatscode = 1
elif Monat == 9:
Monatscode = 4
elif Monat == 10:
Monatscode = 6
elif Monat == 11:
Monatscode = 2
else:
Monatscode = 4
return Monatscode
def Jahrescode(letzte_zwei_ziffern_des_jahres):
firststep = letzte_zwei_ziffern_des_jahres / 4
secondstep = letzte_zwei_ziffern_des_jahres + firststep
yearcode = secondstep % 7
return yearcode
def Formel(Tag, Monatscode, yearcode):
if Jahr < 2000:
yearcode += 1
Rohling = Tag + Monatscode + yearcode
Wochentagcode = Rohling % 7
return Wochentagcode
def Wochentage(Wochentagcode):
if Wochentagcode == 1:
print("Mittwoch")
elif Wochentagcode == 2:
print("Dienstag")
elif Wochentagcode == 3:
print("Mittwoch")
elif Wochentagcode == 4:
print("Donnerstag")
elif Wochentagcode == 5:
print("Freitag")
elif Wochentagcode == 6:
print("Samstag")
elif Wochentagcode == 7 or Wochentagcode == 0:
print("Sonntag")
else:
print("Error!")
Schaltjahrjahr(schalterjahr2)
Monate(Monat)
Jahrescode(letzte_zwei_ziffern_des_jahres)
Formel(Tag,Monatscode,yearcode)
Wochentage(Wochentagcode)
Danke
4 Antworten
Na das ist ja mal ein chaotischer Code.
Das Problem ist wahrscheinlich, dass du den Variablennamen "Wochentagcode" an verschiedenen Stellen verwendest. Als "globale" Variable, als lokale Variable, als Parameter einer Funktion.
Du solltest dich da etwas gedanklich sortieren, das Problem hast du offenbar auch mit anderen Variablen. Schau dir nochmal an, was Funktionsparameter sind, und was Rückgabewerte sind.
Wochentagcode == 7
brauchst du nicht checken, der Fall sollte nie eintreten.
Davon abgesehen würde ich den Code völlig anders schreiben, mehr in der Art:
monatscode = [6, 2, 2, 5, (etc)]
wochentage = ["Sonntag", "Mittwoch", "Dienstag", (etc..) ]
Und dann kannst du mit
wochentag[wochentagscode]
Darauf zugreifen. Ich behaupte, das wäre ein bisschen sauberer (definitiv kürzer), und da würde dir dann evtl. der Fehler auch eher auffallen. Diese ewig langen elifs sind ja grauenhaft :D
Edit: Wie hier angemerkt wurde, veränderst du nie deinen Wochentagscode, weil du den Wochentagscode als lokale Variable einführst, die die Globale Variable verdeckt.
Kurzes Beispiel:
x = 0
def f(x):
x = 1
return x
f(1)
print(x) # x = 0
Machst du das ganze, um zu wissen, wie man "zu Fuß" den Wochentag eines bestimmten Datums bestimmt? Du könntest auch einfach die integrierten Funktionen benutzen:
from datetime import date
tage = ["Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag", "Sonntag"]
Tag = int(input("Tag: "))
Monat = int(input("Monat: "))
Jahr = int(input("Jahr: "))
print(tage[date(Jahr, Monat, Tag).weekday()])
ok, deshalb frag ich ja. Ich nehme mir mal deinen Code und schreibe einige Kommentare rein:
print("Datum als Wochentag")
Rohling = 0
Wochentagcode = 0
Monatscode = 0
yearcode = 0 #### Achte drauf, dass du einheitlich bist. Also nicht englisch/deutsch durcheinander und auch nicht groß/klein durcheinander.
Schaltjahr = False
schalterjahr2 = [] #### und achte auch auf die Rechtschreibung ;)
def schaltjahre_berechnung():
#### Die Liste mit den Schaltjahren kannst du dir eigentlich sparen. Um zu testen, ob eine Zahl durch 4 teilbar ist, kannst du 'if Jahr % 4 == 0' benutzen. Diese Funktion hat zusätzlich den kleinen Fehler, dass das Jahr 2100 eingefügt wird, obwohl es kein Schaltjahr ist.
schalterjahr1 = 1904
while schalterjahr1 <= 2160:
schalterjahr1 += 4
schalterjahr2.append(schalterjahr1)
return schalterjahr2
#### Mache den ausführbaren Teil des Programmes am besten unter alle Funkions- und Klassendefinitionen. Wenn das irgendwo zwischendrin ist, suchst du es bei größeren Projekten ewig.
Tag = int(input("Tag: "))
Monat = int(input("Monat: "))
Jahr = int(input("Jahr: "))
letzte_zwei_ziffern_des_jahres = Jahr % 100 #### Warum so ein langer Name und warum wieder Kleinbuchstaben, wenn die anderen Variablen mit Großbuchstaben anfangen?
def Schaltjahrjahr(schalterjahr2): #### Jahrjahr?
if schalterjahr2 == Jahr: #### Was willst du hier machen? 'schalterjahr2' ist eine Liste und 'Jahr' ist eine Zahl. Die sind nie gleich. Wenn du prüfen willst, ob Jahr in schalterjahr2 ist, lautet der Befehl 'if Jahr in schalterjahr2:'
Schaltjahr = True #### Diese Variable wird nur innerhalb dieser Funktion gesetzt. Die Variable Schaltjahr, die oben definiert wird, wird hiervon nicht beeinflusst. Wenn du die überschreiben willst, muss in dieser Funktion noch 'global Schaltjahr' stehen.
#if Schaltjahr:
#Januar = 5
#Februar = 1
def Monate(Monat):
#### mach hier draus lieber ein Tupel. 'Monatscodes = (0,6,2,2,5,0,3,5,1,4,6,2,4)'. Du kannst dann mit Monatscodes[Monat] die entsprechende Zahl kriegen.
if Monat == 1:
Monatscode = 6
elif Monat == 2:
Monatscode = 2
elif Monat == 3:
Monatscode = 2
elif Monat == 4:
Monatscode = 5
elif Monat == 5:
Monatscode = 0
elif Monat == 6:
Monatscode = 3
elif Monat == 7:
Monatscode = 5
elif Monat == 8:
Monatscode = 1
elif Monat == 9:
Monatscode = 4
elif Monat == 10:
Monatscode = 6
elif Monat == 11:
Monatscode = 2
else:
Monatscode = 4
return Monatscode
def Jahrescode(letzte_zwei_ziffern_des_jahres):
#### Hier gilt auch wieder: nicht englisch/deutsch, groß/klein und camel_case/einwort mischen.
firststep = letzte_zwei_ziffern_des_jahres / 4
secondstep = letzte_zwei_ziffern_des_jahres + firststep
yearcode = secondstep % 7
return yearcode
def Formel(Tag, Monatscode, yearcode):
if Jahr < 2000:
yearcode += 1
#### Wahrscheinlich nicht wichtig, aber 'Rohling' und 'Wochentagcode' werden hier auch nur lokal in der Funktion geschrieben. Die globalen Variablen bleiben unberührt.
Rohling = Tag + Monatscode + yearcode
Wochentagcode = Rohling % 7
return Wochentagcode
def Wochentage(Wochentagcode):
#### Hier auch das Gleiche, wie bei den Monatscodes. Mach einfach ein Tupel (eine nicht veränderbare Liste) draus. 'Wochentage = ("Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag")'
if Wochentagcode == 1:
print("Mittwoch")
elif Wochentagcode == 2:
print("Dienstag")
elif Wochentagcode == 3:
print("Mittwoch")
elif Wochentagcode == 4:
print("Donnerstag")
elif Wochentagcode == 5:
print("Freitag")
elif Wochentagcode == 6:
print("Samstag")
elif Wochentagcode == 7 or Wochentagcode == 0:
print("Sonntag")
else:
print("Error!")
Schaltjahrjahr(schalterjahr2) #### Die Liste schalterjahr2 ist an dieser Stelle nicht gefüllt, außerdem funktioniert die Funktion 'Schaltjahrjahr' wie oben erwähnt nicht richtig.
Monate(Monat)
Jahrescode(letzte_zwei_ziffern_des_jahres)
Formel(Tag,Monatscode,yearcode)
Wochentage(Wochentagcode)
#### Es wird nichts ausgegeben. (Kein print())
Ich bin ein wenig unkreativ beim Namen für Variablen erfinden :)
ich hab deinen Code mal ein bisschen aufgeräumt und so angepasst, dass man ihn wahlweise als eigenständiges Script ausführen oder als Modul importieren kann. Dabei ist mir noch aufgefallen, dass in der Formel nirgendwo geprüft wird, ob das Jahr ein Schaltjahr ist. Dadurch ist in Schaltjahren in den Monaten Januar und Februar ein falscher Tag rausgekommen. Das hab ich aber auch korrigiert. Der Code sollte jetzt für die Jahre 1900-2099 korrekt funktionieren.
def ist_schaltjahr(jahr):
if jahr % 4 == 0 and (jahr % 100 != 0 or jahr % 400 == 0):
return True
return False
def berechne_wochentag(tag, monat, jahr, als_wort=True):
monatscodes = (0,6,2,2,5,0,3,5,1,4,6,2,4)
wochentage = ("Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag")
jahrescode = jahr % 100 + ((jahr % 100) // 4)
if jahr < 2000: jahrescode += 1
if ist_schaltjahr(jahr) and monat < 3: tag -= 1
wochentag = (tag + monatscodes[monat] + jahrescode) % 7
if als_wort: return wochentage[wochentag]
return wochentag
def main():
tag = int(input("Tag: "))
monat = int(input("Monat: "))
jahr = int(input("Jahr: "))
print(berechne_wochentag(tag, monat, jahr))
if __name__ == "__main__":
main()
Weil der immer mit dem code 0 in die Funktion geht. Du schmeißt das Ergebnis aus deiner Formel weg und nimmst immer den Code, den du global mit 0 definiert hast.
Aber, wenn ich es nicht virher mit null definiere kommt auch ein error, wie umgehe ich das dann?
Indem du deine Funktionen auch als solche benutzt und den Rückgabewert dann zuweist statt sinnlos auf einer funktionsinternen Variable herumzuschreiben, die du so wie die globale Variable benannt hast, weil du denkst, dass dann die globale Variable beschrieben wird.
Ich will das Programmieren lernen, da macht es nicht viel sinn, einfach ein modul zu benutzen, denke ich