from datetime import date from person import Person from mariage import Mariage event_types = ['N', 'M', 'A', 'D'] class Event: def __init__(self, event_type: str, event_date: date, current_date: date, person_a: Person, person_b: Person = None): if event_type not in event_types: raise ValueError('{} is not in {}'.format(event_type, event_types)) self._type = event_type self._date = event_date self._current_date = current_date self._p_a = person_a self._p_b = person_b def get_year_span(self) -> int: return self._current_date.year - self._date.year def event_description(self) -> str: y = self.get_year_span() if self._type == 'N': return '{}{} né{} il y a {} an{}'.format( self._p_a.formatted_name(), ' (a épousé {})'.format(self._p_b.formatted_name()) if self._p_b else '', '' if self._p_a.is_male() else 'e', y, 's' if y > 1 else '' ) if self._type == 'M': return '{} a épousé {} il y a {} an{}'.format( self._p_a.formatted_name(), self._p_b.formatted_name(), y, 's' if y > 1 else '' ) if self._type == 'A': return '{} s\'est uni{} à {} il y a {} an{}'.format( self._p_a.formatted_name(), '' if self._p_a.is_male() else 'e', self._p_b.formatted_name(), y, 's' if y > 1 else '' ) return '{}{} décédé{} il y a {} an{}'.format( self._p_a.formatted_name(), ' (a épousé {})'.format(self._p_b.formatted_name()) if self._p_b else '', '' if self._p_a.is_male() else 'e', y, 's' if y > 1 else '' ) def event_date_as_str(self) -> str: day = str(self._date.day) if self._date.day > 9 else '0' + str(self._date.day) month = str(self._date.month) if self._date.month > 9 else '0' + str(self._date.month) return '{}/{}/{}'.format(day, month, self._date.year) def get_actual_weekday(self) -> int: return self._current_date.weekday() def type_str(self): if self._type == 'A': return 'U' return self._type def load_persons_to_dict(members_file: str) -> dict: id_to_person = {} first_line = True # CSV structure from Heredis # Gender,Name,First Names,N : Date of Birth,D : Date of Death,Name of father (to detect in laws) with open(members_file, 'r', encoding='utf-8') as members: for line in members: if first_line: first_line = False continue line.strip() infos = line.split(',') birth = infos[3][4:].split('/') death = None if infos[4] == '' else infos[4][4:].split('/') p = Person(infos[0], # Gender infos[2], # First names infos[1], # Last name date(int(birth[2]), int(birth[1]), int(birth[0])), # Date of birth YYYY MM DD None if not death else date(int(death[2]), int(death[1]), int(death[0])), # Date of death YYYY MM DD infos[5] == '') # If empty, this is an in law id_to_person[p.get_hash_id()] = p return id_to_person def load_mariage_to_list(mariages_file: str) -> list: mariage_lst = [] first_line = True # CSV format from Heredis # T : Date of Event,Name1 | Name2, FirstName1 | FirstName 2, Event long name, DoB1 | DoB2 with open(mariages_file, 'r', encoding='utf-8') as mariages: for line in mariages: if first_line: first_line = False continue line.strip() infos = line.split(',') union_type = infos[0][0] doe = infos[0][4:].split('/') name1 = infos[1].split('|')[0].strip() name2 = infos[1].split('|')[1].strip() first_name1 = infos[2].split('|')[0].strip() first_name2 = infos[2].split('|')[1].strip() dob1 = infos[4].split('|')[0].strip()[4:].split('/') dob2 = infos[4].split('|')[1].strip()[4:].split('/') id1 = Person.get_id(first_name1, name1, date(int(dob1[2]), int(dob1[1]), int(dob1[0]))) id2 = Person.get_id(first_name2, name2, date(int(dob2[2]), int(dob2[1]), int(dob2[0]))) m = Mariage( id1, id2, date(int(doe[2]), int(doe[1]), int(doe[0])), union_type ) mariage_lst.append(m) return mariage_lst def find_significant_other(mariages: list, uid: int) -> int: for m in mariages: if m.in_this_union(uid): return m.get_so(uid) return -1 def create_events_from_span(start: date, end: date, members_file: str, mariages_file: str) -> list: id_to_person = load_persons_to_dict(members_file) mariages = load_mariage_to_list(mariages_file) cur_year = start.year events = [] for p in id_to_person.values(): so = find_significant_other(mariages, p.get_hash_id()) if so == p.get_hash_id(): print(f"What ??? {so}") if not p.is_dead(): birth = p.birth() birth_in_year = date(cur_year, birth.month, birth.day) if start <= birth_in_year <= end: e = Event('N', birth, birth_in_year, p, None if so == -1 else id_to_person[so]) events.append(e) birth_in_year = date(cur_year + 1, birth.month, birth.day) if start <= birth_in_year <= end: e = Event('N', birth, birth_in_year, p, None if so == -1 else id_to_person[so]) events.append(e) else: death = p.death() death_in_year = date(cur_year, death.month, death.day) if start <= death_in_year <= end: e = Event('D', death, death_in_year, p, None if so == -1 else id_to_person[so]) events.append(e) death_in_year = date(cur_year + 1, death.month, death.day) if start <= death_in_year <= end: e = Event('D', death, death_in_year, p, None if so == -1 else id_to_person[so]) events.append(e) for m in mariages: m_date = m.event_date() date_in_year = date(cur_year, m_date.month, m_date.day) if start <= date_in_year <= end: e = Event(m.union(), m_date, date_in_year, id_to_person[m.id_a()], id_to_person[m.id_b()]) events.append(e) date_in_year = date(cur_year + 1, m_date.month, m_date.day) if start <= date_in_year <= end: e = Event(m.union(), m_date, date_in_year, id_to_person[m.id_a()], id_to_person[m.id_b()]) events.append(e) return events