]> AND Private Git Repository - predictops.git/blob - predictops/source/holidays.py
Logo AND Algorithmique Numérique Distribuée

Private GIT Repository
Refactoring, fin du lever/coucher de soleil, et début de sentinelles
[predictops.git] / predictops / source / holidays.py
1 from configparser import ConfigParser
2 from datetime import datetime, timedelta
3 from jours_feries_france.compute import JoursFeries
4 from logging import getLogger
5 from logging.config import fileConfig
6 from pathlib import Path
7 from vacances_scolaires_france import SchoolHolidayDates
8
9 import itertools
10
11 fileConfig((Path.cwd() / 'config') / 'logging.cfg')
12 logger = getLogger()
13
14
15 class Holidays:
16
17     _start = None
18     _end = None
19
20     def __init__(self, config_file):
21
22         self._config = ConfigParser()
23         self._config.read(config_file)
24
25         # Collecting holidays features
26         self._features = [section for section in self._config
27                           if self._config[section].getboolean('binary')
28                           or self._config[section].getboolean('categorical')
29                           or self._config[section].getboolean('numerical')]
30
31         self._dated_features = {}
32
33     @property
34     def start(self):
35         return self._start
36
37     @start.setter
38     def start(self, x):
39         self._start = x
40
41     @property
42     def end(self):
43         return self._end
44
45     @end.setter
46     def end(self, x):
47         self._end = x
48
49     def _get_academic_zone(self, name, date):
50         dict_zones = {
51             'Caen': ('A', 'B'),
52             'Clermont-Ferrand': ('A', 'A'),
53             'Grenoble': ('A', 'A'),
54             'Lyon': ('A', 'A'),
55             'Montpellier': ('A', 'C'),
56             'Nancy-Metz': ('A', 'B'),
57             'Nantes': ('A', 'B'),
58             'Rennes': ('A', 'B'),
59             'Toulouse': ('A', 'C'),
60             'Aix-Marseille': ('B', 'B'),
61             'Amiens': ('B', 'B'),
62             'Besançon': ('B', 'A'),
63             'Dijon': ('B', 'A'),
64             'Lille': ('B', 'B'),
65             'Limoges': ('B', 'A'),
66             'Nice': ('B', 'B'),
67             'Orléans-Tours': ('B', 'B'),
68             'Poitiers': ('B', 'A'),
69             'Reims': ('B', 'B'),
70             'Rouen ': ('B', 'B'),
71             'Strasbourg': ('B', 'B'),
72             'Bordeaux': ('C', 'A'),
73             'Créteil': ('C', 'C'),
74             'Paris': ('C', 'C'),
75             'Versailles': ('C', 'C')
76         }
77         if date < datetime(2016, 1, 1):
78             return dict_zones[name][0]
79         else:
80             return dict_zones[name][1]
81
82     @property
83     def dated_features(self):
84         if self._dated_features == {}:
85             logger.info("Adding holidays features")
86             bankHolidays = tuple(itertools.chain.from_iterable(list(JoursFeries.for_year(k).values())
87                                                                for k in range(self.start.year, self.end.year + 1)))
88             bankHolidaysEve = tuple(u - timedelta(days=1) for u in bankHolidays)
89             name = self._config['ZONE']['name']
90             date = self._start
91             Date = datetime.date(date)
92             tomorrow = date + timedelta(days=1)
93             Tomorrow = datetime.date(tomorrow)
94             d = SchoolHolidayDates()
95             dict_hour = {
96                 'bankHolidays': Date in bankHolidays,
97                 'bankHolidaysEve': Date in bankHolidaysEve,
98                 'holidays': d.is_holiday_for_zone(Date, self._get_academic_zone(name, date)),
99                 'holidaysEve': d.is_holiday_for_zone(Tomorrow, self._get_academic_zone(name, tomorrow))
100             }
101             while date <= self._end:
102                 self._dated_features[date] = dict_hour
103                 current = date
104                 date += timedelta(hours=1)
105                 if date.day != current.day:
106                     Date = datetime.date(date)
107                     tomorrow = date + timedelta(days=1)
108                     Tomorrow = datetime.date(tomorrow)
109                     dict_hour = {
110                         'bankHolidays': Date in bankHolidays,
111                         'bankHolidaysEve': Date in bankHolidaysEve,
112                         'holidays': d.is_holiday_for_zone(Date, self._get_academic_zone(name, date)),
113                         'holidaysEve': d.is_holiday_for_zone(Tomorrow, self._get_academic_zone(name, tomorrow))
114                     }
115         return self._dated_features