def parents_not_too_old(fams, inds): """ US12: Parents not too old. Mother should be less than 60 years older than her children and father should be less than 80 years older than his children """ for fam in fams: # print('husb"') # print(fam['husb']) # print('wife:') # print(fam['wife']) father_ind = get_ind_by_id(fam["husb"], inds) mother_ind = get_ind_by_id(fam["wife"], inds) if 'birt' not in father_ind.__dict__.keys() or 'birt' not in mother_ind.__dict__.keys(): continue fa_year_birth = datetime.datetime.strptime(str(father_ind['birt']), '%d %b %Y').year # print(fa_year_birth) ma_year_birth = datetime.datetime.strptime(str(mother_ind['birt']), '%d %b %Y').year for child_id in fam['chil']: # print('child:') # print(child_id) child_ind = get_ind_by_id(child_id, inds) if 'birt' not in child_ind.__dict__.keys(): continue # print(child_ind['birt']) ch_year_birth = datetime.datetime.strptime(str(child_ind['birt']), '%d %b %Y').year if (ch_year_birth - ma_year_birth) > 60 or (ch_year_birth - fa_year_birth) > 80: return f"ERROR: FAMILY: LINE: {child_ind['birt'].line} US12: Parents too old!"
def birth_after_death_of_parents(fams, inds): """ US09: Child should born before the death of the parent. """ for fam in fams: father_ind = get_ind_by_id(fam["husb"], inds) if str(father_ind['deat']) == 'NA': fa_year_death = 9999 else: fa_year_death = datetime.datetime.strptime(str(father_ind['deat']), '%d %b %Y').year mother_ind = get_ind_by_id(fam["wife"], inds) if str(mother_ind['deat']) == 'NA': ma_year_death = 9999 else: ma_year_death = datetime.datetime.strptime(str(mother_ind['deat']), '%d %b %Y').year for child_id in fam['chil']: # print('child:') # print(child_id) child_ind = get_ind_by_id(child_id, inds) # print(child_ind['birt']) if 'birt' not in child_ind.__dict__.keys(): continue ch_year_birth = datetime.datetime.strptime(str(child_ind['birt']), '%d %b %Y').year if (ma_year_death - ch_year_birth) < 0 or (fa_year_death - ch_year_birth) < 0: return f"ERROR: INDIVIDUAL: LINE: {child_ind['birt'].line}: US09: Child birth after parent death!"
def marriage_before_death(inds, fams): """ Marriage should occur before death of either spouse @param inds: @param fams: @return: """ results = [] for fam in fams: marr = fam['marr'] marr_time = datetime.strptime(marr.value, '%d %b %Y') husb = get_ind_by_id(fam['husb'], inds) wife = get_ind_by_id(fam['wife'], inds) if 'deat' in husb.__dict__.keys(): deat_husb = datetime.strptime(husb['deat'].value, '%d %b %Y') if marr_time > deat_husb: results.append( f"ERROR: FAMILY: US05: {marr.line}: {husb['id'].value}: Marriage {marr.value} is after death." ) if 'deat' in wife.__dict__.keys(): deat_wife = datetime.strptime(wife['deat'].value, '%d %b %Y') if marr_time > deat_wife: results.append( f"ERROR: FAMILY: US05: {marr.line}: {wife['id'].value}: Marriage {marr.value} is after death." ) return results
def divorce_before_death(inds, fams): """ Divorce can only occur before death of both spouses @param inds: @param fams: @return: """ results = [] for fam in fams: if 'div' in fam.__dict__.keys(): div = fam['div'] div_time = datetime.strptime(div.value, '%d %b %Y') else: continue husb = get_ind_by_id(fam['husb'], inds) wife = get_ind_by_id(fam['wife'], inds) if 'deat' in husb.__dict__.keys(): deat_husb = datetime.strptime(husb['deat'].value, '%d %b %Y') if div_time > deat_husb: results.append( f"ERROR: FAMILY: US06: {div.line}: {husb['id'].value}: Divorce {div.value} is after death." ) if 'deat' in wife.__dict__.keys(): deat_wife = datetime.strptime(wife['deat'].value, '%d %b %Y') if div_time > deat_wife: results.append( f"ERROR: FAMILY: US06: {div.line}: {wife['id'].value}: Divorce {div.value} is after death." ) return results
def marriage_after_14(fams, inds): """ US10: Marriage date should be at least 14 years after birth date for a person """ for fam in fams: father_ind = get_ind_by_id(fam["husb"], inds) if 'birt' not in father_ind.__dict__.keys(): continue fa_year_birth = datetime.datetime.strptime(str(father_ind['birt']), '%d %b %Y').year mother_ind = get_ind_by_id(fam["wife"], inds) if 'birt' not in mother_ind.__dict__.keys(): continue ma_year_birth = datetime.datetime.strptime(str(mother_ind['birt']), '%d %b %Y').year marr_date = datetime.datetime.strptime(str(fam['marr']), '%d %b %Y').year if (marr_date - fa_year_birth) < 14 or (marr_date - ma_year_birth) < 14: return f"ERROR: FAMILY: LINE: {fam['marr'].line}: US10: Parents less than 14 years old!"
def list_orphans(inds, fams): """ US 33 List all orphaned children (both parents dead and child < 18 years old) in a GEDCOM file @param inds: @param fams: @return: """ orphans_list = [] for fam in fams: husb = get_ind_by_id(fam['husb'].value, inds) if husb['alive'].value == 'True': continue wife = get_ind_by_id(fam['wife'].value, inds) if wife['alive'].value == 'True': continue for chil in fam['chil']: chil = get_ind_by_id(chil, inds) if chil['age'].value != 'NA': if int(chil['age'].value) < 18: orphans_list.append(chil) return orphans_list
def male_last_names(fams, inds): """ US16: Male last names All male members of a family should have the same last name """ for fam in fams: father_ind = get_ind_by_id(fam["husb"], inds) if 'sex' not in father_ind.__dict__.keys(): continue fa_name = str(father_ind['name']) for child_id in fam['chil']: # print('child:') # print(child_id) child_ind = get_ind_by_id(child_id, inds) ch_name = str(child_ind['name']) ch_gender = str(child_ind['sex']) # print(str(ch_name)[-3:]) # print(ch_gender == 'M') if 'sex' not in child_ind.__dict__.keys(): continue if ch_gender == 'M' and fa_name[-3:] != ch_name[-3:]: return f"ERROR: FAMILY: LINE: {child_ind['name'].line} US16: All male members of a family should have the same last name!"
def list_multiple_births(inds, fams): """ US 32 List all multiple births in a GEDCOM file @param inds: @param fams: @return: """ multiple_births_list = [] multiple_births_ids = set() for fam in fams: if len(fam['chil']) > 1: for id_chil in fam['chil']: multiple_births_ids.add(id_chil) for mb_id in multiple_births_ids: ind = get_ind_by_id(mb_id, inds) multiple_births_list.append(ind) return multiple_births_list
def siblings_spacing(fams, inds): """ US13: Siblings spacing Birth dates of siblings should be more than 8 months apart or less than 2 days apart """ for fam in fams: child_birth_date_list = [] for child_id in fam['chil']: child_ind = get_ind_by_id(child_id, inds) child_birth_date = datetime.datetime.strptime( str(child_ind['birt']), '%d %b %Y') # print(child_birth_date) child_birth_date_list.append(child_birth_date) # print(child_birth_date_list) for date1 in child_birth_date_list: for date2 in child_birth_date_list: time_diff = date2 - date1 if datetime.timedelta( days=240) > time_diff > datetime.timedelta(days=2): return f"ERROR: FAMILY: {fam['id']} US13: Birth dates of siblings should be more than 8 months apart or less than 2 days apart!"
def birth_before_marriage_of_parents(inds, fams): results = '' for fam in fams: marr = fam['marr'] marr_date = datetime.datetime.strptime(marr.value, '%d %b %Y') chils = fam['chil'] for chil_id in chils: chil = get_ind_by_id(chil_id, inds) if 'birt' not in chil.__dict__.keys(): continue birth_date = chil['birt'].value birth_date = datetime.datetime.strptime(birth_date, '%d %b %Y') if birth_date < marr_date: results += f"ERROR: INDIVIDUAL: US08: line{chil['birt'].line}: {chil['id'].value}: Child birthday {chil['birt'].value} before parents' marriage date {marr.value}\n" if 'div' in fam.__dict__.keys(): div = fam['div'] div_date = datetime.datetime.strptime(div.value, '%d %b %Y') if (birth_date - div_date).days > 270: results += f"ERROR: INDIVIDUAL: US08: line{chil['birt'].line}: {chil['id'].value}: Child birthday {chil['birt'].value} is more than 9 months after parents' divorce date {marr.value}\n" return results
def multiple_births(fams, inds): """ US14: Multiple births. No more than five siblings should be born at the same time """ for fam in fams: if len(fam['chil']) >= 5: for child_id in fam['chil']: child_birth_year_list = [] child_birth_year_set = set() child_ind = get_ind_by_id(child_id, inds) if 'birt' not in child_ind.__dict__.keys(): continue ch_birth_year_month = datetime.datetime.strptime( str(child_ind['birt']), '%d %b %Y').year * 10 + datetime.datetime.strptime( str(child_ind['birt']), '%d %b %Y').month child_birth_year_list.append(ch_birth_year_month) child_birth_year_set.add(ch_birth_year_month) if len(child_birth_year_list) - len(child_birth_year_set) < 5: return f"ERROR: FAMILY: LINE: {child_ind['birt'].line} US14: more than five siblings born at the same time!"
def list_living_married(inds, fams): """ US 30 List all living married people in a GEDCOM file @param inds: @param fams: @return: """ living_married_list = [] id_inds = set() for fam in fams: if 'div' in fam.__dict__.keys(): continue else: id_inds.add(fam['husb'].value) id_inds.add(fam['wife'].value) for id_ind in id_inds: ind = get_ind_by_id(id_ind, inds) if 'deat' in ind.__dict__.keys(): continue living_married_list.append(ind) return living_married_list
def order_sibling_by_age(inds, fams): """ US 28 List siblings in families by decreasing age, i.e. oldest siblings first @param inds: @param fams: @return: """ for fam in fams: chils = [get_ind_by_id(chil, inds) for chil in fam['chil']] chils = [ ind if 'birt' in ind.__dict__.keys() else None for ind in chils ] try: chils.remove(None) except ValueError: pass chils = sorted(chils, key=lambda ind: datetime.datetime.strptime( ind['birt'].value, '%d %b %Y').timestamp()) fam['chil'] = [chil['id'] for chil in chils] return fams