diff --git a/elterndienstplaner.py b/elterndienstplaner.py index 874f61b..0e1860b 100755 --- a/elterndienstplaner.py +++ b/elterndienstplaner.py @@ -214,38 +214,8 @@ class Elterndienstplaner: print("\nBerechne faire Zielverteilung basierend auf historischen Daten...") - # Wenn keine historischen Daten vorhanden, nur aktuellen Monat berechnen - if not self.historische_dienste: - print(" Keine historischen Daten - berechne nur für aktuellen Monat") - for dienst in self.dienste: - benoetigte_dienste_monat = sum( - 1 for tag in self.tage - if dienst in self.benoetigte_dienste.get(tag, []) - ) - - if dienst == 'A': - benoetigte_dienste_monat *= 2 - - if benoetigte_dienste_monat > 0: - gesamt_dienstfaktor_monat = sum( - sum(self.dienstfaktoren.get(e, {}).get(tag, 0) for tag in self.tage) - for e in self.eltern - ) - - if gesamt_dienstfaktor_monat > 0: - for eltern in self.eltern: - monatsfaktor = sum( - self.dienstfaktoren.get(eltern, {}).get(tag, 0) - for tag in self.tage - ) - if monatsfaktor > 0: - anteil = monatsfaktor / gesamt_dienstfaktor_monat - faire_zuteilung = anteil * benoetigte_dienste_monat - ziel_dienste[eltern][dienst] = faire_zuteilung - return ziel_dienste - # Historische Dienste nach Datum gruppieren - historische_tage = set(datum for datum, _, _ in self.historische_dienste) + historische_tage = set(datum for datum, _, _ in self.historische_dienste) if self.historische_dienste else set() print(f" Analysiere {len(historische_tage)} historische Tage mit {len(self.historische_dienste)} Diensten") for dienst in self.dienste: @@ -318,12 +288,15 @@ class Elterndienstplaner: # Debug-Ausgabe für diesen Dienst total_historisch = sum( - ziel_dienste[e][dienst] for e in self.eltern - if dienst in [d for _, _, d in self.historische_dienste if d == dienst] - ) - total_aktuell = benoetigte_dienste_monat + ziel_dienste[e][dienst] - ( + sum(self.dienstfaktoren.get(e, {}).get(tag, 0) for tag in self.tage) / + sum(sum(self.dienstfaktoren.get(e2, {}).get(tag, 0) for tag in self.tage) for e2 in self.eltern) * benoetigte_dienste_monat + if sum(sum(self.dienstfaktoren.get(e2, {}).get(tag, 0) for tag in self.tage) for e2 in self.eltern) > 0 else 0 + ) for e in self.eltern + ) if len(historische_dienste_dieses_typs) > 0 else 0 + print(f" {dienst}: Historisch faire Summe={total_historisch:.1f}, " - f"Aktuell benötigt={total_aktuell}") + f"Aktuell benötigt={benoetigte_dienste_monat}") # Debug-Output: Detaillierte Zielverteilung print("\n Berechnete Zielverteilung (basierend auf tatsächlichen historischen Diensten):") @@ -537,11 +510,14 @@ class Elterndienstplaner: # Solver wählen (verfügbare Solver testen) solver = None try: - solver = pulp.PULP_CBC_CMD(msg=0) # Standard CBC Solver + print("Versuche CBC Solver...") + solver = pulp.PULP_CBC_CMD(msg=0, timeLimit=10) # Standard CBC Solver except: try: + print("Versuche GLPK Solver...") solver = pulp.GLPK_CMD(msg=0) # GLPK falls verfügbar except: + print("Kein spezifizierter Solver verfügbar, verwende Standard.") solver = None # Default Solver prob.solve(solver) diff --git a/elterndienstplaner.sh b/elterndienstplaner.sh index af38121..7b36b36 100755 --- a/elterndienstplaner.sh +++ b/elterndienstplaner.sh @@ -1 +1,2 @@ -/home/jwit/privat/elterndienstplaner/.venv/bin/python elterndienstplaner.py eingabe.csv eltern.csv ausgabe.csv vorherige-ausgaben.csv +DIR=/home/jwit/privat/elterndienstplaner/ +$DIR/.venv/bin/python $DIR/elterndienstplaner.py eingabe.csv eltern.csv ausgabe.csv vorherige-ausgaben.csv diff --git a/test/pseudo/ausgabe.csv b/test/pseudo/ausgabe.csv new file mode 100644 index 0000000..ee800ee --- /dev/null +++ b/test/pseudo/ausgabe.csv @@ -0,0 +1,23 @@ +Datum,Wochentag,Frühstücksdienst,Putznotdienst,Essensausgabenotdienst,Kochen,Elternabend +2026-04-01,Mittwoch,Mra,P,En,, +2026-04-02,Donnerstag,V,Mat,IW,, +2026-04-03,Freitag,,,,, +2026-04-06,Montag,,,,, +2026-04-07,Dienstag,M&S,L,Ms,, +2026-04-08,Mittwoch,L,Fr,V,, +2026-04-09,Donnerstag,El,Th,M&S,, +2026-04-10,Freitag,Ml,Mra,IE,V, +2026-04-13,Montag,Th,Fe,El,, +2026-04-14,Dienstag,M&S,En,Mat,, +2026-04-15,Mittwoch,IE,Fe,Fr,, +2026-04-16,Donnerstag,En,IW,V,,IE M&S +2026-04-17,Freitag,IW,V,P,, +2026-04-20,Montag,Fe,M&S,Ms,, +2026-04-21,Dienstag,P,El,Th,, +2026-04-22,Mittwoch,M&S,Ml,Fe,, +2026-04-23,Donnerstag,P,V,M&S,, +2026-04-24,Freitag,L,IE,Mra,P, +2026-04-27,Montag,Mat,R,Ml,, +2026-04-28,Dienstag,Fr,M&S,L,, +2026-04-29,Mittwoch,Ms,Th,R,, +2026-04-30,Donnerstag,R,Ms,M&S,, diff --git a/test/pseudo/convert_ausgabe.py b/test/pseudo/convert_ausgabe.py new file mode 100644 index 0000000..9befafe --- /dev/null +++ b/test/pseudo/convert_ausgabe.py @@ -0,0 +1,83 @@ +#!/usr/bin/env python3 +# Konvertiert den "Dienstplan Clean" aus Excel in das ausgabe.csv-Format + +import csv +from datetime import datetime +import calendar + +def parse_date(date_str): + """Konvertiert 'Monday, August 11, 2025' zu '2025-08-11'""" + try: + # Parse das englische Datumsformat + date_obj = datetime.strptime(date_str, "%A, %B %d, %Y") + return date_obj.strftime("%Y-%m-%d") + except: + return None + +def get_weekday_german(date_str): + """Gibt den deutschen Wochentag zurück""" + try: + date_obj = datetime.strptime(date_str, "%A, %B %d, %Y") + weekdays = ['Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag', 'Sonntag'] + return weekdays[date_obj.weekday()] + except: + return "" + +# Konvertierung +with open('imp-ausgabe.csv', 'r', encoding='utf-8') as infile: + reader = csv.reader(infile) + header = next(reader) + + # Mapping der Spalten (imp-ausgabe -> ausgabe) + # imp: ,Frühstück,Kochen,Elternabend 1,Elternabend 2,Notdienst Essensausgabe,Putznotdienst + # ziel: Datum,Wochentag,Frühstücksdienst,Putznotdienst,Essensausgabenotdienst,Kochen,Elternabend + + data = [] + for row in reader: + if len(row) < 6: + continue + + date_str = row[0].strip('"') + if not date_str or date_str.startswith('Saturday') or date_str.startswith('Sunday'): + continue # Wochenenden überspringen + + iso_date = parse_date(date_str) + if not iso_date: + continue + + weekday = get_weekday_german(date_str) + + # Dienste extrahieren + fruehstueck = row[1].strip() if len(row) > 1 else '' + kochen = row[2].strip() if len(row) > 2 else '' + elternabend1 = row[3].strip() if len(row) > 3 else '' + elternabend2 = row[4].strip() if len(row) > 4 else '' + essensausgabe = row[5].strip() if len(row) > 5 else '' + putz = row[6].strip() if len(row) > 6 else '' + + # Elternabend kombinieren + elternabend_kombiniert = '' + if elternabend1 and elternabend2: + elternabend_kombiniert = f"{elternabend1} {elternabend2}" + elif elternabend1: + elternabend_kombiniert = elternabend1 + elif elternabend2: + elternabend_kombiniert = elternabend2 + + data.append([iso_date, weekday, fruehstueck, putz, essensausgabe, kochen, elternabend_kombiniert]) + +# Sortieren nach Datum +data.sort(key=lambda x: x[0]) + +# Schreibe neue ausgabe.csv +with open('ausgabe.csv', 'w', newline='', encoding='utf-8') as outfile: + writer = csv.writer(outfile) + + # Header schreiben + writer.writerow(['Datum', 'Wochentag', 'Frühstücksdienst', 'Putznotdienst', 'Essensausgabenotdienst', 'Kochen', 'Elternabend']) + + # Daten schreiben + for row in data: + writer.writerow(row) + +print("Konvertierung abgeschlossen! ausgabe.csv wurde erstellt.") diff --git a/test/pseudo/create_eingabe_april.py b/test/pseudo/create_eingabe_april.py new file mode 100644 index 0000000..a9447c7 --- /dev/null +++ b/test/pseudo/create_eingabe_april.py @@ -0,0 +1,67 @@ +#!/usr/bin/env python3 + +import calendar +from datetime import datetime, date + +# Eltern aus der eltern.csv (alle aktiven in April 2026) +eltern = ['En', 'Fe', 'IE', 'IW', 'L', 'Mra', 'P', 'Th', 'V', 'El', 'M&S', 'Ms', 'Ml', 'Mat', 'R', 'Fr'] + +# April 2026 Kalenderdaten +jahr = 2026 +monat = 4 + +# Deutsche Wochentage +wochentage = ['Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag', 'Sonntag'] + +# Dienste für Werktage (Mo-Fr) +werktag_dienste = 'FPE' + +# Kochen und Elternabend manuell festlegen (beispielhaft) +kochen_tage = [9, 23] # 2 Mittwoche im April +elternabend_tage = [11, 25] # 2 Freitage im April + +print("Erstelle eingabe.csv für April 2026...") + +# CSV erstellen +with open('eingabe.csv', 'w', encoding='utf-8') as f: + # Header schreiben + header = ['Datum', 'Wochentag', 'Dienste'] + eltern + f.write(', '.join(f'{col:12}' for col in header) + '\n') + + # Für jeden Tag im April 2026 + for tag in range(1, calendar.monthrange(jahr, monat)[1] + 1): + datum = date(jahr, monat, tag) + wochentag_name = wochentage[datum.weekday()] + + # Nur Werktage (Montag bis Freitag) + if datum.weekday() < 5: + # Benötigte Dienste bestimmen + dienste = werktag_dienste + + # Kochen hinzufügen + if tag in kochen_tage: + dienste += 'K' + + # Elternabend hinzufügen + if tag in elternabend_tage: + dienste += 'A' + + # Zeile zusammenstellen + zeile = [ + datum.strftime('%Y-%m-%d'), + wochentag_name, + dienste + ] + + # Für alle Eltern: keine Präferenzen, alle verfügbar (leere Strings) + for eltern_name in eltern: + zeile.append('') # Leer = verfügbar, keine Präferenzen + + # Zeile schreiben (formatiert für bessere Lesbarkeit) + f.write(', '.join(f'{cell:12}' for cell in zeile) + '\n') + +print("eingabe.csv für April 2026 erstellt!") +print("- Werktage: Frühstück (F), Putz (P), Essensausgabe (E)") +print(f"- Kochen (K): {kochen_tage}") +print(f"- Elternabend (A): {elternabend_tage}") +print("- Alle Eltern verfügbar, keine Präferenzen") diff --git a/test/pseudo/eingabe.csv b/test/pseudo/eingabe.csv new file mode 100644 index 0000000..60890b6 --- /dev/null +++ b/test/pseudo/eingabe.csv @@ -0,0 +1,23 @@ +Datum , Wochentag , Dienste , En , Fe , IE , IW , L , Mra , P , Th , V , El , M&S , Ms , Ml , Mat , R , Fr +2026-04-01 , Mittwoch , FPE , , , , , , , , , , , , , , , , +2026-04-02 , Donnerstag , FPE , , , , , , , , , , , , , , , , +2026-04-03 , Freitag , , , , , , , , , , , , , , , , , +2026-04-06 , Montag , , , , , , , , , , , , , , , , , +2026-04-07 , Dienstag , FPE , , , , , , , , , , , , , , , , +2026-04-08 , Mittwoch , FPE , , , , , , , , , , , , , , , , +2026-04-09 , Donnerstag , FPE , , , , , , , , , , , , , , , , +2026-04-10 , Freitag , FPEK , , , , , , , , , , , , , , , , +2026-04-13 , Montag , FPE , , , , , , , , , , , , , , , , +2026-04-14 , Dienstag , FPE , , , , , , , , , , , , , , , , +2026-04-15 , Mittwoch , FPE , , , , , , , , , , , , , , , , +2026-04-16 , Donnerstag , FPEA , , , , , , , , , , , , , , , , +2026-04-17 , Freitag , FPE , , , , , , , , , , , , , , , , +2026-04-20 , Montag , FPE , , , , , , , , , , , , , , , , +2026-04-21 , Dienstag , FPE , , , , , , , , , , , , , , , , +2026-04-22 , Mittwoch , FPE , , , , , , , , , , , , , , , , +2026-04-23 , Donnerstag , FPE , , , , , , , , , , , , , , , , +2026-04-24 , Freitag , FPEK , , , , , , , , , , , , , , , , +2026-04-27 , Montag , FPE , , , , , , , , , , , , , , , , +2026-04-28 , Dienstag , FPE , , , , , , , , , , , , , , , , +2026-04-29 , Mittwoch , FPE , , , , , , , , , , , , , , , , +2026-04-30 , Donnerstag , FPE , , , , , , , , , , , , , , , , diff --git a/test/pseudo/eltern.csv b/test/pseudo/eltern.csv new file mode 100644 index 0000000..3be02b4 --- /dev/null +++ b/test/pseudo/eltern.csv @@ -0,0 +1,18 @@ +Name_Kind(er), Zeitraum_Beginn, Zeitraum_Ende, Dienstfaktor, Zeitraum_Beginn2, Zeitraum_Ende2, Dienstfaktor2, Zeitraum_Beginn3, Zeitraum_Ende3, Dienstfaktor3 +En , 2025-08-11 , 2026-07-31 , 1, , , , , +Fe , 2025-08-11 , 2026-07-31 , 1, , , , , +IE , 2025-08-11 , 2026-07-31 , 1, , , , , +IW , 2025-08-11 , 2026-07-31 , 1, , , , , +L , 2025-08-11 , 2026-07-31 , 1, , , , , +Mra , 2025-08-11 , 2026-07-31 , 1, , , , , +P , 2025-08-11 , 2026-07-31 , 1, , , , , +Th , 2025-08-11 , 2026-07-31 , 1, , , , , +V , 2025-08-11 , 2026-07-31 , 1, , , , , +El , 2025-09-15 , 2026-07-31 , 1, , , , , +J , 2025-08-15 , 2025-01-31 , 1, , , , , +M&S , 2025-08-15 , 2026-07-31 , 2, , , , , +Ms , 2025-08-11 , 2026-07-31 , 1, , , , , +Ml , 2025-10-01 , 2026-07-31 , 1, , , , , +Mat , 2025-09-01 , 2026-07-31 , 1, , , , , +R , 2025-08-11 , 2026-07-31 , 1, , , , , +Fr , 2026-01-01 , 2026-07-31 , 1, , , , , diff --git a/test/pseudo/imp-eltern.csv b/test/pseudo/imp-eltern.csv new file mode 100644 index 0000000..fd7c8cd --- /dev/null +++ b/test/pseudo/imp-eltern.csv @@ -0,0 +1,3 @@ +,En,Fe,IE,IW,L,Mra,P,Th,V,El,J,M&S,Ms,Ml,Mat,R,Fr +Eintrittsdatum,,,,,,,,,,15/9,15/8,15/8,,1/10,1/9,,1/1 +Dienstfaktor,,,,,,,,,,,,2,,,,, diff --git a/test/pseudo/vorherige-ausgaben.csv b/test/pseudo/vorherige-ausgaben.csv new file mode 100644 index 0000000..129e162 --- /dev/null +++ b/test/pseudo/vorherige-ausgaben.csv @@ -0,0 +1,168 @@ +Datum,Wochentag,Frühstücksdienst,Putznotdienst,Essensausgabenotdienst,Kochen,Elternabend +2025-08-11,Montag,V,En,Th,, +2025-08-12,Dienstag,IW,Mra,L,, +2025-08-13,Mittwoch,Mra,Th,En,, +2025-08-14,Donnerstag,P,IW,Mra,, +2025-08-15,Freitag,Th,Fe,V,Mra, +2025-08-18,Montag,L,IE,P,, +2025-08-19,Dienstag,IE,L,IW,, +2025-08-20,Mittwoch,Fe,P,IE,, +2025-08-21,Donnerstag,En,IW,Fe,,V Mra +2025-08-22,Freitag,Fe,V,P,, +2025-08-25,Montag,IE,V,Th,, +2025-08-26,Dienstag,En,Mra,L,, +2025-08-27,Mittwoch,IW,Th,Fe,, +2025-08-28,Donnerstag,Mra,P,V,, +2025-08-29,Freitag,Th,L,IW,En, +2025-09-01,Montag,P,Fe,IE,, +2025-09-02,Dienstag,V,IE,En,, +2025-09-03,Mittwoch,L,En,Mra,, +2025-09-04,Donnerstag,Fe,V,P,, +2025-09-05,Freitag,En,Mra,V,, +2025-09-08,Montag,,,,, +2025-09-09,Dienstag,Th,En,IE,, +2025-09-10,Mittwoch,V,L,IW,, +2025-09-11,Donnerstag,Ms,Fe,Mra,, +2025-09-12,Freitag,R,IW,En,Ms, +2025-09-15,Montag,,,,, +2025-09-16,Dienstag,M&S,M&S,Ms,, +2025-09-17,Mittwoch,R,Ms,L,, +2025-09-18,Donnerstag,J,Th,R,,En P +2025-09-19,Freitag,Ms,P,J,, +2025-09-22,Montag,J,Ms,R,, +2025-09-23,Dienstag,P,R,J,, +2025-09-24,Mittwoch,L,J,Ms,, +2025-09-25,Donnerstag,IW,IE,Th,, +2025-09-26,Freitag,IE,IW,Fe,Th, +2025-09-29,Montag,Mat,J,R,, +2025-09-30,Dienstag,J,Ms,Mat,, +2025-10-01,Mittwoch,P,Mat,J,, +2025-10-02,Donnerstag,Th,En,P,, +2025-10-03,Freitag,,,,, +2025-10-06,Montag,M&S,R,Mat,, +2025-10-07,Dienstag,Ml,Mat,M&S,, +2025-10-08,Mittwoch,Mat,Ml,M&S,, +2025-10-09,Donnerstag,M&S,J,Ml,,Th Fe +2025-10-10,Freitag,Mra,M&S,Fe,J, +2025-10-13,Montag,El,Ml,M&S,, +2025-10-14,Dienstag,Ml,R,M&S,, +2025-10-15,Mittwoch,M&S,Mat,El,, +2025-10-16,Donnerstag,Ms,El,Mat,, +2025-10-17,Freitag,R,M&S,Ml,, +2025-10-20,Montag,El,L,M&S,, +2025-10-21,Dienstag,Mat,P,M&S,, +2025-10-22,Mittwoch,M&S,Th,Ms,, +2025-10-23,Donnerstag,Ml,J,El,, +2025-10-24,Freitag,M&S,El,Ml,V, +2025-10-27,Montag,El,M&S,Mat,, +2025-10-28,Dienstag,IW,M&S,El,, +2025-10-29,Mittwoch,V,El,R,, +2025-10-30,Donnerstag,M&S,R,Mra,, +2025-10-31,Freitag,,,,, +2025-11-03,Montag,R,M&S,En,, +2025-11-04,Dienstag,Mat,V,El,, +2025-11-05,Mittwoch,Mra,Mat,V,, +2025-11-06,Donnerstag,El,Ms,Th,, +2025-11-07,Freitag,IE,Mra,IW,R, +2025-11-10,Montag,L,Fe,Ms,, +2025-11-11,Dienstag,Fe,M&S,L,, +2025-11-12,Mittwoch,En,R,M&S,, +2025-11-13,Donnerstag,J,IW,Mat,, +2025-11-14,Freitag,M&S,IE,J,, +2025-11-17,Montag,Ms,El,Ml,, +2025-11-18,Dienstag,M&S,Mat,IE,, +2025-11-19,Mittwoch,Ml,L,M&S,, +2025-11-20,Donnerstag,IW,P,Ms,,Mat J +2025-11-21,Freitag,V,Ml,En,M&S, +2025-11-24,Montag,L,M&S,J,, +2025-11-25,Dienstag,Th,En,Fe,, +2025-11-26,Mittwoch,Mat,Fe,R,, +2025-11-27,Donnerstag,J,Ms,M&S,, +2025-11-28,Freitag,En,Ml,V,, +2025-12-01,Montag,P,V,Mra,, +2025-12-02,Dienstag,R,J,IE,, +2025-12-03,Mittwoch,Mra,Th,P,, +2025-12-04,Donnerstag,Ms,Mra,L,, +2025-12-05,Freitag,Ml,M&S,Th,IE, +2025-12-08,Montag,Fe,M&S,IW,, +2025-12-09,Dienstag,El,IE,M&S,, +2025-12-10,Mittwoch,M&S,Fe,El,, +2025-12-11,Donnerstag,R,El,J,, +2025-12-12,Freitag,,,,, +2025-12-15,Montag,V,M&S,Ml,, +2025-12-16,Dienstag,IE,Ms,Th,, +2025-12-17,Mittwoch,Mra,P,Mat,, +2025-12-18,Donnerstag,Th,Ml,En,, +2025-12-19,Freitag,J,R,Ms,Mat, +2025-12-22,Montag,,,,, +2025-12-23,Dienstag,,,,, +2025-12-24,Mittwoch,,,,, +2025-12-25,Donnerstag,,,,, +2025-12-26,Freitag,,,,, +2025-12-29,Montag,,,,, +2025-12-30,Dienstag,,,,, +2025-12-31,Mittwoch,,,,, +2026-01-01,Donnerstag,,,,, +2026-01-02,Freitag,,,,, +2026-01-05,Montag,Fr,L,Fe,, +2026-01-06,Dienstag,V,Ml,Fr,, +2026-01-07,Mittwoch,Fe,Fr,P,, +2026-01-08,Donnerstag,IE,Mra,Mat,, +2026-01-09,Freitag,Ml,Mat,El,Fe, +2026-01-12,Montag,Fr,M&S,Ml,, +2026-01-13,Dienstag,En,IE,Fr,, +2026-01-14,Mittwoch,R,Fr,Th,, +2026-01-15,Donnerstag,IW,En,IE,,Fe Mat +2026-01-16,Freitag,Th,P,En,L, +2026-01-19,Montag,Fr,M&S,IW,, +2026-01-20,Dienstag,El,IW,Fr,, +2026-01-21,Mittwoch,M&S,Fr,Mra,, +2026-01-22,Donnerstag,Mra,El,M&S,, +2026-01-23,Freitag,Th,Mra,V,IW, +2026-01-26,Montag,Fr,P,R,, +2026-01-27,Dienstag,Fe,Ms,Fr,, +2026-01-28,Mittwoch,IE,Fr,Ml,, +2026-01-29,Donnerstag,El,Fe,IE,, +2026-01-30,Freitag,R,En,Fe,Fr, +2026-02-02,Montag,Fr,R,Mat,, +2026-02-03,Dienstag,P,Mat,Fr,, +2026-02-04,Mittwoch,V,Fr,M&S,, +2026-02-05,Donnerstag,IW,M&S,P,, +2026-02-06,Freitag,L,V,Ms,Ml, +2026-02-09,Montag,Fr,L,Ml,, +2026-02-10,Dienstag,Mat,Ml,Fr,, +2026-02-11,Mittwoch,M&S,Fr,IW,, +2026-02-12,Donnerstag,En,IW,L,, +2026-02-13,Freitag,Ms,IE,Th,Mat, +2026-02-16,Montag,Fr,Ml,Mra,, +2026-02-17,Dienstag,M&S,Th,En,, +2026-02-18,Mittwoch,L,M&S,Fr,, +2026-02-19,Donnerstag,El,Fr,M&S,,Mra Ml +2026-02-20,Freitag,Ml,P,Mat,El, +2026-02-23,Montag,IE,En,M&S,, +2026-02-24,Dienstag,Ms,Mra,P,, +2026-02-25,Mittwoch,En,Th,Ml,, +2026-02-26,Donnerstag,M&S,Fr,El,, +2026-02-27,Freitag,P,El,Fe,M&S, +2026-03-02,Montag,Th,R,Mra,, +2026-03-03,Dienstag,El,Ms,En,, +2026-03-04,Mittwoch,Fe,Mat,IW,, +2026-03-05,Donnerstag,R,M&S,Th,, +2026-03-06,Freitag,Ml,L,IE,Fr, +2026-03-09,Montag,Fr,V,R,, +2026-03-10,Dienstag,V,Fe,L,, +2026-03-11,Mittwoch,IW,IE,Ms,, +2026-03-12,Donnerstag,Mra,IW,V,, +2026-03-13,Freitag,Mat,El,Fr,M&S, +2026-03-16,Montag,M&S,Ml,Mat,, +2026-03-17,Dienstag,Mra,L,M&S,, +2026-03-18,Mittwoch,Mat,M&S,Ml,, +2026-03-19,Donnerstag,Fr,Ms,Fe,,P Th +2026-03-20,Freitag,En,Mat,El,Mra, +2026-03-23,Montag,V,Th,P,, +2026-03-24,Dienstag,R,P,En,, +2026-03-25,Mittwoch,IE,V,R,, +2026-03-26,Donnerstag,IW,M&S,Mra,, +2026-03-27,Freitag,L,IW,Th,Ms, +2026-03-30,Montag,Th,Mra,IW,, +2026-03-31,Dienstag,Fe,IE,Fr,,