Python :: Aufgabe #311

2 Lösungen Lösungen öffentlich

Feiertage in Deutschland

Anfänger - Python von JKooP - 03.01.2021 um 15:06 Uhr
Die Feiertage sind vorüber – doch die nächsten stehen schon vor der Tür.
Da kann es nicht schaden, mal einen Blick in die Zukunft zu werfen.

Es soll ein Programm entwickelt werden, mit dem es möglich ist,
alle Feiertage (mit Bezeichnung und Datum) eines gewählten Bundeslandes für eine bestimmte Jahreszahl auszugeben.

Dabei sollen sowohl die festen als auch die beweglichen Feiertage berücksichtigt werden.
Ebenfalls soll es die Möglichkeit geben, die gesetzlichen Feiertage für alle Bundesländer auszugeben.

Wer möchte, kann natürlich auch noch die regionalen Feiertage wie z.B. Rosenmontag oder die - wie für einige Beamte üblichen - Feiertage wie z.B. Heilig Abend und Silvester einbringen.

Beispiel für Aufruf:

[datum, bezeichnung] FEIERTAGE(jahr, bundesland, optional: beamter/rosenmontag)

Eine Übersicht zu den einzelnen Bundesländern und den gesetzlichen Feiertagen gibt es hier.

Lösungen:

vote_ok
von felixTheC (1040 Punkte) - 05.01.2021 um 16:06 Uhr
The main part
Quellcode ausblenden Python-Code
import json
from datetime import datetime
from pathlib import Path
import re
from typing import Literal
from typing import Union

import requests
from bs4 import BeautifulSoup
from strongtyping.strong_typing import match_typing

from playarounds.decorator import validate_docstr

ALLOWED_STATES = Literal[
    'Bayern',
    'Niedersachsen',
    'Baden-Württemberg',
    'Nordrhein-Westfalen',
    'Brandenburg',
    'Mecklenburg-Vorpommern',
    'Hessen',
    'Sachsen-Anhalt',
    'Rheinland-Pfalz',
    'Sachsen',
    'Thüringen',
    'Schleswig-Holstein',
    'Saarland',
    'Berlin',
    'Hamburg',
    'Bremen',
    ''
]

@match_typing
def get_holidays(*, year: int, state: ALLOWED_STATES = 'Alle', optional: str = None) -> None:
    data_file = Path('data.json')
    if not data_file.exists():
        raise RuntimeWarning('Please create at first the "data.json"')

    json_data = get_data(data_file)
    dates = [date for date in json_data.keys() if str(year) in date]

    if not dates:
        print('No data available')

    for date in dates:
        data = json_data[date]
        if optional is not None:
            if optional in data.get('optional', ''):
                print(f'{date}: {data["name"]}')
        else:
            state_info = [state.replace(',', '').strip() for state in data['states'].split()]
            if state in state_info or 'Alle' in state_info:
                print(f'{date}: {data["name"]}')


if __name__ == '__main__':
    get_holidays(year=2021, state='Berlin')
    """
    01.01.2021: Neujahr in Deutschland
    08.03.2021: Internationaler Frauentag
    02.04.2021: Karfreitag in Deutschland(Ostern in Deutschland)
    05.04.2021: Ostermontag in Deutschland(Ostern in Deutschland)
    01.05.2021: Tag der Arbeit in Deutschland
    13.05.2021: Christi Himmelfahrt in Deutschland
    24.05.2021: Pfingstmontag in Deutschland(Pfingsten in Deutschland)
    03.10.2021: Tag der Deutschen Einheit
    25.12.2021: 1. Weihnachtstag in Deutschland(Weihnachten in Deutschland)
    26.12.2021: 2. Weihnachtstag in Deutschland(Weihnachten in Deutschland)
    """

    get_holidays(year=2021, state='Bayern')
    """
    01.01.2021: Neujahr in Deutschland
    06.01.2021: Heilige Drei Könige
    02.04.2021: Karfreitag in Deutschland(Ostern in Deutschland)
    05.04.2021: Ostermontag in Deutschland(Ostern in Deutschland)
    01.05.2021: Tag der Arbeit in Deutschland
    13.05.2021: Christi Himmelfahrt in Deutschland
    24.05.2021: Pfingstmontag in Deutschland(Pfingsten in Deutschland)
    03.06.2021: Fronleichnam in Deutschland
    08.08.2021: Augsburger Friedensfest 
    15.08.2021: Mariä Himmelfahrt in Deutschland 
    03.10.2021: Tag der Deutschen Einheit
    01.11.2021: Allerheiligen in Deutschland
    25.12.2021: 1. Weihnachtstag in Deutschland(Weihnachten in Deutschland)
    26.12.2021: 2. Weihnachtstag in Deutschland(Weihnachten in Deutschland)
    """

    get_holidays(year=2021, optional='Rosenmontag')
    """
    15.02.2021: Rosenmontag
    """

    get_holidays(year=2021, state='Bayern', optional='Beamte')
    """
    24.12.2021: Heilig Abend
    31.12.2021: Silvester
    """


Some helper functions to grab easy the data
Quellcode ausblenden Python-Code
@match_typing
@validate_docstr
def get_feiertage_html(year: int = 2021) -> None:
    """
    :validate year: lambda x: 2014 <= x <= 2023
    :return:
    """
    resp = requests.get(f'https://www.ferienwiki.de/feiertage/{year}/de')
    html_file = Path('templates', f'feiertage_{year}.html')

    with html_file.open('w') as file:
        file.write(resp.content.decode('utf8'))


@match_typing
def get_data(data_file: Path) -> dict:
    if data_file.exists():
        with data_file.open('r') as file:
            data_set = json.load(file)
    else:
        data_set = {}
    return data_set


@match_typing
def write_data(data: dict):
    with Path('data.json').open('w') as file:
        json.dump(data, file)


@match_typing
def add_holiday(date: str, name: str, states: ALLOWED_STATES, optional_info: str = None):
    datetime.strptime(date, '%d.%m.%Y')  # to validate the date format, raises an error if wrong format
    data_file = Path('data.json')
    data = get_data(data_file)
    data[date] = {'name': name,
                  'states': states}
    if optional_info is not None:
        data['date']['optional'] = optional_info


@match_typing
def extract_and_save_data(filename: Union[str, Path]) -> None:
    td_tag = r'(<(\/)?td>)'
    data_file = Path('data.json')
    data = get_data(data_file)
    with Path(filename).open('r') as file:
        soup = BeautifulSoup(file.read(), 'html.parser')
        elements = soup.find_all('td')
        step = 4
        while step <= len(elements):
            date = ''
            name = ''
            state = ''
            for index, elem in enumerate(elements[step: step + 4]):
                elem = re.sub(td_tag, '', str(elem))
                sub_elem = BeautifulSoup(elem, 'html.parser', multi_valued_attributes=None).text
                if index == 0:
                    name = sub_elem
                elif index == 1:
                    date = sub_elem.split()[0]
                elif index == 2:
                    state = sub_elem
                else:
                    continue
            data[date] = {'name': name,
                          'states': state}
            step += 4
    write_data(data)


def extract_all_data() -> None:
    [extract_and_save_data(file) for file in Path('templates').glob('*.html')]
vote_ok
von Chrisu90 (900 Punkte) - 06.01.2021 um 14:55 Uhr
Quellcode ausblenden Python-Code
print('#### Feiertage 2021 Österreich ####')
print('## BGL ## KTN ## NOE ## OOE ## SBG ## STMK ## T ## W ## VBG ##\n')

feiertage_bgl = {'Neujahr': '01.01', 'Heilige Drei Könige': '06.01', 'Karfreitag': '10.04 [Evangelischer]'
    , 'Ostersonntag': '12.04', 'Ostermontag': '13.04', 'Staatsfeiertag': '01.05'
    , 'Christi Himmelfahrt': '21.05', 'Pfingstsonntag': '31.05', 'Pfingstmontag': '01.06'
    , 'Fronleichnam': '11.06', 'Maria Himmelfahrt': '15.08', 'Nationalfeiertag': '26.10'
    , 'Allerheiligen': '01.11', 'Martinstag': '11.11 [für Schulen/Behörden]', 'Maria Empfängnis': '08.12'
    , 'Christtag': '25.12', 'Stefanitag': '26.12'}

feiertage_ktn = {'Neujahr': '01.01', 'Heilige Drei Könige': '06.01', 'Josef': '19.03 [Schulen/Behörden]'
    , 'Karfreitag': '10.04 [Evangelischer]', 'Ostersonntag': '12.04', 'Ostermontag': '13.04'
    , 'Staatsfeiertag': '01.05'
    , 'Christi Himmelfahrt': '21.05', 'Pfingstsonntag': '31.05', 'Pfingstmontag': '01.06'
    , 'Fronleichnam': '11.06', 'Maria Himmelfahrt': '15.08', 'Tag der Volksabstimmung': '10.10'
    , 'Nationalfeiertag': '26.10'
    , 'Allerheiligen': '01.11', 'Maria Empfängnis': '08.12'
    , 'Christtag': '25.12', 'Stefanitag': '26.12'}

feiertage_noe = {'Neujahr': '01.01', 'Heilige Drei Könige': '06.01', 'Karfreitag': '10.04 [Evangelischer]'
    , 'Ostersonntag': '12.04', 'Ostermontag': '13.04', 'Staatsfeiertag': '01.05'
    , 'Christi Himmelfahrt': '21.05', 'Pfingstsonntag': '31.05', 'Pfingstmontag': '01.06'
    , 'Fronleichnam': '11.06', 'Maria Himmelfahrt': '15.08', 'Nationalfeiertag': '26.10'
    , 'Allerheiligen': '01.11', 'Leopoldtag': '15.11 [Schulen/Behörden]', 'Maria Empfängnis': '08.12'
    , 'Christtag': '25.12', 'Stefanitag': '26.12'}

feiertage_ooe = {'Neujahr': '01.01', 'Heilige Drei Könige': '06.01', 'Karfreitag': '10.04 [Evangelischer]'
    , 'Ostersonntag': '12.04', 'Ostermontag': '13.04', 'Staatsfeiertag': '01.05', 'Florian': '04.05'
    , 'Christi Himmelfahrt': '21.05', 'Pfingstsonntag': '31.05', 'Pfingstmontag': '01.06'
    , 'Fronleichnam': '11.06', 'Maria Himmelfahrt': '15.08', 'Nationalfeiertag': '26.10'
    , 'Allerheiligen': '01.11', 'Maria Empfängnis': '08.12'
    , 'Christtag': '25.12', 'Stefanitag': '26.12'}

feiertage_sbg = {'Neujahr': '01.01', 'Heilige Drei Könige': '06.01', 'Josef': '19.03 [Schulen/Behörden]'
    , 'Karfreitag': '10.04 [Evangelischer]'
    , 'Ostersonntag': '12.04', 'Ostermontag': '13.04', 'Staatsfeiertag': '01.05'
    , 'Christi Himmelfahrt': '21.05', 'Pfingstsonntag': '31.05', 'Pfingstmontag': '01.06'
    , 'Fronleichnam': '11.06', 'Maria Himmelfahrt': '15.08', 'Nationalfeiertag': '26.10'
    , 'Allerheiligen': '01.11', 'Maria Empfängnis': '08.12'
    , 'Christtag': '25.12', 'Stefanitag': '26.12'}

feiertage_stmk = {'Neujahr': '01.01', 'Heilige Drei Könige': '06.01', 'Josef': '19.03 [Schulen/Behörden]'
    , 'Karfreitag': '10.04 [Evangelischer]'
    , 'Ostersonntag': '12.04', 'Ostermontag': '13.04', 'Staatsfeiertag': '01.05'
    , 'Christi Himmelfahrt': '21.05', 'Pfingstsonntag': '31.05', 'Pfingstmontag': '01.06'
    , 'Fronleichnam': '11.06', 'Maria Himmelfahrt': '15.08', 'Rupert': '24.09', 'Nationalfeiertag': '26.10'
    , 'Allerheiligen': '01.11', 'Maria Empfängnis': '08.12'
    , 'Christtag': '25.12', 'Stefanitag': '26.12'}

feiertage_t = {'Neujahr': '01.01', 'Heilige Drei Könige': '06.01', 'Josef': '19.03 [Schulen/Behörden]'
    , 'Karfreitag': '10.04 [Evangelischer]'
    , 'Ostersonntag': '12.04', 'Ostermontag': '13.04', 'Staatsfeiertag': '01.05'
    , 'Christi Himmelfahrt': '21.05', 'Pfingstsonntag': '31.05', 'Pfingstmontag': '01.06'
    , 'Fronleichnam': '11.06', 'Maria Himmelfahrt': '15.08', 'Nationalfeiertag': '26.10'
    , 'Allerheiligen': '01.11', 'Maria Empfängnis': '08.12'
    , 'Christtag': '25.12', 'Stefanitag': '26.12'}

feiertage_w = {'Neujahr': '01.01', 'Heilige Drei Könige': '06.01'
    , 'Karfreitag': '10.04 [Evangelischer]'
    , 'Ostersonntag': '12.04', 'Ostermontag': '13.04', 'Staatsfeiertag': '01.05'
    , 'Christi Himmelfahrt': '21.05', 'Pfingstsonntag': '31.05', 'Pfingstmontag': '01.06'
    , 'Fronleichnam': '11.06', 'Maria Himmelfahrt': '15.08', 'Nationalfeiertag': '26.10'
    , 'Allerheiligen': '01.11', 'Maria Empfängnis': '08.12'
    , 'Christtag': '25.12', 'Stefanitag': '26.12'}

feiertage_vbg = {'Neujahr': '01.01', 'Heilige Drei Könige': '06.01', 'Josef': '19.03 [Schulen/Behörden]'
    , 'Karfreitag': '10.04 [Evangelischer]', 'Ostersonntag': '12.04', 'Ostermontag': '13.04'
    , 'Staatsfeiertag': '01.05'
    , 'Christi Himmelfahrt': '21.05', 'Pfingstsonntag': '31.05', 'Pfingstmontag': '01.06'
    , 'Fronleichnam': '11.06', 'Maria Himmelfahrt': '15.08'
    , 'Nationalfeiertag': '26.10'
    , 'Allerheiligen': '01.11', 'Maria Empfängnis': '08.12'
    , 'Christtag': '25.12', 'Stefanitag': '26.12'}

feiertage_ges = {'Neujahr': '01.01', 'Heilige Drei Könige': '06.01'
    , 'Karfreitag': '10.04 [Evangelischer]', 'Ostersonntag': '12.04', 'Ostermontag': '13.04'
    , 'Staatsfeiertag': '01.05'
    , 'Christi Himmelfahrt': '21.05', 'Pfingstsonntag': '31.05', 'Pfingstmontag': '01.06'
    , 'Fronleichnam': '11.06', 'Maria Himmelfahrt': '15.08'
    , 'Nationalfeiertag': '26.10'
    , 'Allerheiligen': '01.11', 'Maria Empfängnis': '08.12'
    , 'Christtag': '25.12', 'Stefanitag': '26.12'}

feiertag = input('Gib bitte die Bundesland-Kennzeichnung ein: ')
feiertag = feiertag.lower()


if feiertag == 'bgl':
    print('\nFeiertage 2021 für Burgenland: ')
    for i in feiertage_bgl:
        print("{feiertag}: {datum}".format(feiertag=i, datum=feiertage_bgl[i]))
elif feiertag == 'ktn':
    print('\nFeiertage 2021 für Kärnten: ')
    for i in feiertage_ktn:
        print("{feiertag}: {datum}".format(feiertag=i, datum=feiertage_ktn[i]))
elif feiertag == 'noe':
    print('\nFeiertage 2021 für Niederösterreich: ')
    for i in feiertage_noe:
        print("{feiertag}: {datum}".format(feiertag=i, datum=feiertage_noe[i]))
elif feiertag == 'ooe':
    print('\nFeiertage 2021 für Oberösterreich: ')
    for i in feiertage_ooe:
        print("{feiertag}: {datum}".format(feiertag=i, datum=feiertage_ooe[i]))
elif feiertag == 'sbg':
    print('\nFeiertage 2021 für Salzburg: ')
    for i in feiertage_sbg:
        print("{feiertag}: {datum}".format(feiertag=i, datum=feiertage_sbg[i]))
elif feiertag == 'stmk':
    print('\nFeiertage 2021 für Steiermark: ')
    for i in feiertage_stmk:
        print("{feiertag}: {datum}".format(feiertag=i, datum=feiertage_stmk[i]))
elif feiertag == 't':
    print('\nFeiertage 2021 für Tirol: ')
    for i in feiertage_t:
        print("{feiertag}: {datum}".format(feiertag=i, datum=feiertage_t[i]))
elif feiertag == 'w':
    print('\nFeiertage 2021 für Wien: ')
    for i in feiertage_w:
        print("{feiertag}: {datum}".format(feiertag=i, datum=feiertage_w[i]))
elif feiertag == 'vbg':
    print('\nFeiertage 2021 für Vorarlberg: ')
    for i in feiertage_vbg:
        print("{feiertag}: {datum}".format(feiertag=i, datum=feiertage_vbg[i]))
else:
    print('Eingabe nicht erkannt!')

gesamtabfrage = input('\nMöchtest du noch wissen welche Feiertage das ganze Land gemeinsam hat? j/n ')
gesamtabfrage= gesamtabfrage.lower()

if gesamtabfrage == 'j':
    print('\nFeiertage für ganz Österreich: ')
    for i in feiertage_ges:
        print("{feiertag}: {datum}".format(feiertag=i, datum=feiertage_ges[i]))
else:
    print('Bis zum nächsten mal...')