Created
May 12, 2018 21:07
-
-
Save deeplook/64ad3d00262acfcb2da2f943d8b21571 to your computer and use it in GitHub Desktop.
List bridge days for one year and country
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"cells": [ | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"# Bridge Days\n", | |
"\n", | |
"Bridge days are normal working days that happen to be between two non-working days, be they holidays or weekend days (Sat/Sun). So, they should normally fall on Mondays or Fridays, unless there are, e.g. two holidays during a week, like on Monday and Wednesday (very unlikely).\n", | |
"\n", | |
"This notebook contains some very simple code to calculate the list of bridge days for some given year and country as a simple use case for the ``holidays`` pacakge, see https://pypi.org/project/holidays/." | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"## Experiment with the `holidays` package" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 1, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"from datetime import date\n", | |
"import holidays" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 2, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"swiss_holidays = holidays.Switzerland()" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 3, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"False" | |
] | |
}, | |
"execution_count": 3, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"date(2018, 5, 9) in swiss_holidays" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 4, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"True" | |
] | |
}, | |
"execution_count": 4, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"date(2018, 5, 10) in swiss_holidays" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 5, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"'Auffahrt'" | |
] | |
}, | |
"execution_count": 5, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"swiss_holidays.get(date(2018, 5, 10))" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 6, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"{datetime.date(2018, 1, 1): 'Neujahr',\n", | |
" datetime.date(2018, 3, 30): 'Karfreitag',\n", | |
" datetime.date(2018, 4, 2): 'Ostermontag',\n", | |
" datetime.date(2018, 5, 1): 'Maifeiertag',\n", | |
" datetime.date(2018, 5, 10): 'Christi Himmelfahrt',\n", | |
" datetime.date(2018, 5, 21): 'Pfingstmontag',\n", | |
" datetime.date(2018, 10, 3): 'Tag der Deutschen Einheit',\n", | |
" datetime.date(2018, 12, 25): 'Erster Weihnachtstag',\n", | |
" datetime.date(2018, 12, 26): 'Zweiter Weihnachtstag'}" | |
] | |
}, | |
"execution_count": 6, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"holidays.Germany(prov=\"BE\", years=2018)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 7, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"{datetime.date(2018, 1, 1): 'Neujahr',\n", | |
" datetime.date(2018, 1, 6): 'Heilige Drei Könige',\n", | |
" datetime.date(2018, 3, 30): 'Karfreitag',\n", | |
" datetime.date(2018, 4, 2): 'Ostermontag',\n", | |
" datetime.date(2018, 5, 1): 'Maifeiertag',\n", | |
" datetime.date(2018, 5, 10): 'Christi Himmelfahrt',\n", | |
" datetime.date(2018, 5, 21): 'Pfingstmontag',\n", | |
" datetime.date(2018, 5, 31): 'Fronleichnam',\n", | |
" datetime.date(2018, 8, 15): 'Mariä Himmelfahrt',\n", | |
" datetime.date(2018, 10, 3): 'Tag der Deutschen Einheit',\n", | |
" datetime.date(2018, 11, 1): 'Allerheiligen',\n", | |
" datetime.date(2018, 12, 25): 'Erster Weihnachtstag',\n", | |
" datetime.date(2018, 12, 26): 'Zweiter Weihnachtstag'}" | |
] | |
}, | |
"execution_count": 7, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"holidays.Germany(prov=\"BY\", years=2018)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 8, | |
"metadata": { | |
"scrolled": true | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"{datetime.date(2018, 1, 1): 'Neujahrestag',\n", | |
" datetime.date(2018, 4, 1): 'Ostern',\n", | |
" datetime.date(2018, 3, 30): 'Karfreitag',\n", | |
" datetime.date(2018, 4, 2): 'Ostermontag',\n", | |
" datetime.date(2018, 5, 1): 'Tag der Arbeit',\n", | |
" datetime.date(2018, 5, 10): 'Auffahrt',\n", | |
" datetime.date(2018, 5, 20): 'Pfingsten',\n", | |
" datetime.date(2018, 5, 21): 'Pfingstmontag',\n", | |
" datetime.date(2018, 8, 1): 'Nationalfeiertag',\n", | |
" datetime.date(2018, 12, 25): 'Weihnachten',\n", | |
" datetime.date(2018, 12, 26): 'Stephanstag'}" | |
] | |
}, | |
"execution_count": 8, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"holidays.Switzerland(prov=\"BS\", years=2018)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"## Get all bridge days for one year" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 9, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"from datetime import datetime, timedelta\n", | |
"from calendar import day_name" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 10, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"def is_working_day(holi, dt):\n", | |
" \"\"\"Is this a working day (not a holiday or Sat/Sun)?\"\"\"\n", | |
" \n", | |
" return not (dt in holi or dt.weekday() in (5, 6))" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 11, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"def bridge_days_for_holiday(holi, dt):\n", | |
" \"\"\"Get working days before/after one given date (2 day window).\"\"\"\n", | |
" \n", | |
" dtm2, dtm1, dtp1, dtp2 = \\\n", | |
" [dt + timedelta(days=days) for days in [-2, -1, 1, 2]]\n", | |
" wd = is_working_day\n", | |
" if wd(holi, dtm1) and not wd(holi, dtm2):\n", | |
" yield dtm1\n", | |
" if wd(holi, dtp1) and not wd(holi, dtp2):\n", | |
" yield dtp1" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 12, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"def show_bridge_days(holi):\n", | |
" \"\"\"List bridge days for an entire year.\"\"\"\n", | |
" \n", | |
" for dt, name in sorted(holi.items()):\n", | |
" weekday = day_name[dt.weekday()]\n", | |
" for bridge_day in bridge_days_for_holiday(holi, dt):\n", | |
" print('Holiday date: {} ({}) - {} -- bridge day: {}'.format(dt, weekday, name, bridge_day))" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 13, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"berlin_holidays_2018 = holidays.Germany(prov=\"BE\", years=2018)\n", | |
"bavaria_holidays_2018 = holidays.Germany(prov=\"BY\", years=2018)\n", | |
"basel_holidays_2018 = holidays.Switzerland(prov=\"BS\", years=2018)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 14, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"Holiday date: 2018-05-01 (Tuesday) - Maifeiertag -- bridge day: 2018-04-30\n", | |
"Holiday date: 2018-05-10 (Thursday) - Christi Himmelfahrt -- bridge day: 2018-05-11\n", | |
"Holiday date: 2018-12-25 (Tuesday) - Erster Weihnachtstag -- bridge day: 2018-12-24\n" | |
] | |
} | |
], | |
"source": [ | |
"show_bridge_days(berlin_holidays_2018)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 15, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"Holiday date: 2018-05-01 (Tuesday) - Maifeiertag -- bridge day: 2018-04-30\n", | |
"Holiday date: 2018-05-10 (Thursday) - Christi Himmelfahrt -- bridge day: 2018-05-11\n", | |
"Holiday date: 2018-05-31 (Thursday) - Fronleichnam -- bridge day: 2018-06-01\n", | |
"Holiday date: 2018-11-01 (Thursday) - Allerheiligen -- bridge day: 2018-11-02\n", | |
"Holiday date: 2018-12-25 (Tuesday) - Erster Weihnachtstag -- bridge day: 2018-12-24\n" | |
] | |
} | |
], | |
"source": [ | |
"show_bridge_days(bavaria_holidays_2018)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 16, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"Holiday date: 2018-05-01 (Tuesday) - Tag der Arbeit -- bridge day: 2018-04-30\n", | |
"Holiday date: 2018-05-10 (Thursday) - Auffahrt -- bridge day: 2018-05-11\n", | |
"Holiday date: 2018-12-25 (Tuesday) - Weihnachten -- bridge day: 2018-12-24\n" | |
] | |
} | |
], | |
"source": [ | |
"show_bridge_days(basel_holidays_2018)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"## Challenge: Draw a world map of #holidays and #bridge days / year\n", | |
"\n", | |
"More to come… But notice, that the ``holidays`` package does not provide holidays for all countries!" | |
] | |
} | |
], | |
"metadata": { | |
"kernelspec": { | |
"display_name": "Python 3", | |
"language": "python", | |
"name": "python3" | |
}, | |
"language_info": { | |
"codemirror_mode": { | |
"name": "ipython", | |
"version": 3 | |
}, | |
"file_extension": ".py", | |
"mimetype": "text/x-python", | |
"name": "python", | |
"nbconvert_exporter": "python", | |
"pygments_lexer": "ipython3", | |
"version": "3.6.3" | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 1 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment