Liste der Wochen eines Jahres

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
blinky
User
Beiträge: 6
Registriert: Samstag 15. März 2008, 22:12

Liebe Pythonisten,

nach einigem Herumgehacke mit Django habe ich mir zum Ziel gesetzt, Python langfristig ein bisschen besser zu lernen. Dazu möchte ich gerne einen Kalendar in Python erstellen. Ich würde gerne entweder Daten generieren, die später in InDesign importiert werden können, oder direkt eine PDF-Datei erstellen (pyCairo gefällt mir ganz gut).

Nun möchte ich gerne für jede Woche im Jahr eine Seite erzeugen. Dazu stelle ich mir eine Liste vor, die die Wochen des Jahres enthält, die wiederum (als Listen) die jeweiligen Tage als datetime.date-Objekte enthalten. Diese Liste würde ich dann durchiterieren, um den Kalender zu erzeugen.

Im Moment verwende ich den Output aus dem calendar-Modul(mit mäßigem Erfolg), frage mich aber, ob es nicht doch einen einfacheren und eleganteren Weg gibt, eine solche Liste zu erzeugen. Ich wäre Euch riesig dankbar, wenn ihr mir einen Tipp geben könntet oder einen Hinweis, in welchem Bereich ich suchen sollte.

Vielen Dank


Blinky
Nikolas
User
Beiträge: 102
Registriert: Dienstag 25. Dezember 2007, 22:53
Wohnort: Freiburg im Breisgau

Schau dir mal hier den dritten Post an.
http://www.daniweb.com/forums/post148294-3.html

Code: Alles auswählen

for month in range(1,12): # oder 13?
  for day in range(1,32):
      Datum erstellen
      prüfen, ob man nicht gerade den 31.2 oder so was erstellt hat
      prüfen, ob dayOfWeek==0 (Montag)
      -> du hast einen neuen Eintrag für deine Liste
Erwarte das Beste und sei auf das Schlimmste vorbereitet.
Benutzeravatar
Trundle
User
Beiträge: 591
Registriert: Dienstag 3. Juli 2007, 16:45

Man könnte die `monthdatescalendar`-Methode eines `Calendar`-Objekts benutzen. Die liefert einem ja schon `datetime.date`-Objekte. Man müsste eben nur überprüfen, ob die Woche am Anfang eines Monats nicht die letzte Woche des vorherigen Monats ist (weil ja immer 7 Tage aufgefüllt werden).
Könnte vielleicht so aussehen:

Code: Alles auswählen

from calendar import Calendar

cal = Calendar()
weeks = list()
for month in xrange(1, 13):
    for week in cal.monthdatescalendar(2008, month):
        if not weeks or weeks[-1] != week:
            weeks.append(week)
# `weeks` ist nun eine Liste mit allen Wochen des Jahres 2008,
# die wiederum eine Liste mit 7 `datetime.date`-Objekten sind
rayo
User
Beiträge: 773
Registriert: Mittwoch 5. November 2003, 18:06
Wohnort: Schweiz
Kontaktdaten:

Hi

Ich würde das so lösen, reicht ja immer den Montag der Woche zu nehmen :)

Code: Alles auswählen

import datetime

def get_weeks(year):
    weeks = []
    
    # 1. Januar 
    first = datetime.date(year, 1, 1)
    
    # Montag in der 1. Woche
    current = first-datetime.timedelta(days=first.weekday())
    
    one_week = datetime.timedelta(days=7)
    
    # kalender jahr == gewuenschtes jahr
    while current.isocalendar()[0] == year:
        # Tuple aus Wochennummer, Startdatum (Montag)
        weeks.append((current.isocalendar()[1], current))
        
        # naechste Woche
        current += one_week
    
    return weeks
    
print get_weeks(2008)
Ausgabe:

Code: Alles auswählen

[(1, datetime.date(2007, 12, 31)),
 (2, datetime.date(2008, 1, 7)),
 (3, datetime.date(2008, 1, 14)),
 (4, datetime.date(2008, 1, 21)),
 (5, datetime.date(2008, 1, 28)),
 (6, datetime.date(2008, 2, 4)),
 (7, datetime.date(2008, 2, 11)),
 (8, datetime.date(2008, 2, 18)),
 (9, datetime.date(2008, 2, 25)),
 (10, datetime.date(2008, 3, 3)),
 (11, datetime.date(2008, 3, 10)),
 (12, datetime.date(2008, 3, 17)),
 (13, datetime.date(2008, 3, 24)),
 (14, datetime.date(2008, 3, 31)),
 (15, datetime.date(2008, 4, 7)),
 (16, datetime.date(2008, 4, 14)),
 (17, datetime.date(2008, 4, 21)),
 (18, datetime.date(2008, 4, 28)),
 (19, datetime.date(2008, 5, 5)),
 (20, datetime.date(2008, 5, 12)),
 (21, datetime.date(2008, 5, 19)),
 (22, datetime.date(2008, 5, 26)),
 (23, datetime.date(2008, 6, 2)),
 (24, datetime.date(2008, 6, 9)),
 (25, datetime.date(2008, 6, 16)),
 (26, datetime.date(2008, 6, 23)),
 (27, datetime.date(2008, 6, 30)),
 (28, datetime.date(2008, 7, 7)),
 (29, datetime.date(2008, 7, 14)),
 (30, datetime.date(2008, 7, 21)),
 (31, datetime.date(2008, 7, 28)),
 (32, datetime.date(2008, 8, 4)),
 (33, datetime.date(2008, 8, 11)),
 (34, datetime.date(2008, 8, 18)),
 (35, datetime.date(2008, 8, 25)),
 (36, datetime.date(2008, 9, 1)),
 (37, datetime.date(2008, 9, 8)),
 (38, datetime.date(2008, 9, 15)),
 (39, datetime.date(2008, 9, 22)),
 (40, datetime.date(2008, 9, 29)),
 (41, datetime.date(2008, 10, 6)),
 (42, datetime.date(2008, 10, 13)),
 (43, datetime.date(2008, 10, 20)),
 (44, datetime.date(2008, 10, 27)),
 (45, datetime.date(2008, 11, 3)),
 (46, datetime.date(2008, 11, 10)),
 (47, datetime.date(2008, 11, 17)),
 (48, datetime.date(2008, 11, 24)),
 (49, datetime.date(2008, 12, 1)),
 (50, datetime.date(2008, 12, 8)),
 (51, datetime.date(2008, 12, 15)),
 (52, datetime.date(2008, 12, 22))]
Gruss
blinky
User
Beiträge: 6
Registriert: Samstag 15. März 2008, 22:12

Hej,

wow, riesigen Dank für eure schnellen und hilfreichen Antworten! Die haben mir schon riesig weitergeholfen.

Vielen Dank erstmal an Nikolas - eine ähnliche Lösung habe ich gerade am laufen (hätte ich vielleicht auch posten können - sorry!). Sie erfasst mit calendar.monthrange() die Länge eines Monats und iteriert ihn dann durch.

Größen Dank auch an Trundle für die innovative Lösung - so hätte ich mir das vorgestellt, nur kam ich irgendwie nicht an die Calendar()-Klasse dran. Jetzt weiß ich, was ich bei meinen Versuchen falsch gemacht hatte: Ich hätte die Klasse explizit importieren (wie das auch im Code gemacht wurde) oder cal = calendar.Calendar() schreiben müssen.

Sehr gut gefällt mir auch die Lösung von Rayo, danke! Das datetime-Modul scheint ja ziemlich flexibel zu sein - das werde ich mir auf jeden fall mal anschauen.

Ok - Ich werde, denke ich, die ganzen Vorschläge ein bisschen kombinieren und mal sehen, was rauskommt. Nochmal vielen Dank!

Blinky

PS: Ich weiß nicht, wie es hier im Forum üblich ist: Sollte ich diesen Thread irgendwie als gelöst markieren?
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

blinky hat geschrieben:PS: Ich weiß nicht, wie es hier im Forum üblich ist: Sollte ich diesen Thread irgendwie als gelöst markieren?
Nein, aus guten, schon öfter diskutierten Gründen solltest du den so lassen wie er ist. Wir finden, dass gelöst-Markierungen kontraproduktiv sind.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

Trundle hat geschrieben:Man könnte die `monthdatescalendar`-Methode eines `Calendar`-Objekts benutzen. Die liefert einem ja schon `datetime.date`-Objekte. Man müsste eben nur überprüfen, ob die Woche am Anfang eines Monats nicht die letzte Woche des vorherigen Monats ist (weil ja immer 7 Tage aufgefüllt werden).
Könnte vielleicht so aussehen:

Code: Alles auswählen

from calendar import Calendar

cal = Calendar()
weeks = list()
for month in xrange(1, 13):
    for week in cal.monthdatescalendar(2008, month):
        if not weeks or weeks[-1] != week:
            weeks.append(week)
# `weeks` ist nun eine Liste mit allen Wochen des Jahres 2008,
# die wiederum eine Liste mit 7 `datetime.date`-Objekten sind
Calendar.monthdatescalendar scheint es aber erst ab Python 2.5 zu geben.
Benutzeravatar
Trundle
User
Beiträge: 591
Registriert: Dienstag 3. Juli 2007, 16:45

HWK hat geschrieben:Calendar.monthdatescalendar scheint es aber erst ab Python 2.5 zu geben.
`calendar.Calendar` gibt es erst ab Python2.5.
blinky
User
Beiträge: 6
Registriert: Samstag 15. März 2008, 22:12

Leonidas hat geschrieben: [...] aus guten, schon öfter diskutierten Gründen solltest du den so lassen wie er ist. Wir finden, dass gelöst-Markierungen kontraproduktiv sind.
Danke für die Antwort von höchster Stelle - wird gemacht! :D

Vielleicht noch eine Frage: Wäre es zulässig, einfach "calendar.Calendar().monthdatescalendar(year, month)" zu schreiben, anstelle einen Kalender zu initialisieren? Hat das irgendwelche Nachteile (oder ist es stilistisch schlecht oder beides)?
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

blinky hat geschrieben:Vielleicht noch eine Frage: Wäre es zulässig, einfach "calendar.Calendar().monthdatescalendar(year, month)" zu schreiben, anstelle einen Kalender zu initialisieren? Hat das irgendwelche Nachteile (oder ist es stilistisch schlecht oder beides)?
Nein, solange du die nicht brauchst macht das eigentlich keinen Unterschied. Es ist aber recht lang und somit könntest du über die 79-Zeichen Zeilenlänge kommen, was nicht so sonderlich gerne gesehen wird, wenn du die überschreitest.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Antworten