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
Liste der Wochen eines Jahres
-
- 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
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.
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:
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
-
- 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
Ausgabe:
Gruss
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)
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))]
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?
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?
-
- Python-Forum Veteran
- Beiträge: 16025
- Registriert: Freitag 20. Juni 2003, 16:30
- Kontaktdaten:
Nein, aus guten, schon öfter diskutierten Gründen solltest du den so lassen wie er ist. Wir finden, dass gelöst-Markierungen kontraproduktiv sind.blinky hat geschrieben:PS: Ich weiß nicht, wie es hier im Forum üblich ist: Sollte ich diesen Thread irgendwie als gelöst markieren?
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Calendar.monthdatescalendar scheint es aber erst ab Python 2.5 zu geben.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
Danke für die Antwort von höchster Stelle - wird gemacht!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.

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)?
-
- Python-Forum Veteran
- Beiträge: 16025
- Registriert: Freitag 20. Juni 2003, 16:30
- Kontaktdaten:
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.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)?
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice