def check_150_years_age(individual_info_dict):

    age_limit = 150

    # gets dates from individual info
    for individual_id, individual_info in individual_info_dict.items():
        id = individual_id
        birth_date = Date(str(individual_info.get("BIRT")))
        if individual_info.get("DEAT") not in [None, 'NA']:
            death_date = Date(str(individual_info.get("DEAT")))
        else:
            death_date = None

        # calculates age with the dates
        if death_date == None and birth_date != None:
            age = Date.get_dates_difference(birth_date.date_time_obj)
        else:
            if death_date != None and birth_date != None:
                age = Date.get_dates_difference(birth_date.date_time_obj,
                                                death_date.date_time_obj)

        # checks to see if age exceeds age limit and prints error
        if type(age) is not str and age > age_limit and death_date == None:
            print(
                'ERROR: INDIVIDUAL: US07: {}: More than 150 years old - Birth date {}'
                .format(id, birth_date))
        elif type(age) is not str and age > age_limit and death_date != None:
            print(
                'ERROR: INDIVIDUAL: US07: {}: More than 150 years old at death - Birth date {}: Death date {}'
                .format(id, birth_date, death_date))
示例#2
0
def check_birth_before_marriage_of_parents(family_info_dict, individual_info_dict):
   
    for family_id, family_info in family_info_dict.items():
        # gets marriage and divorce dates in family if they exist
        if family_info.get("MARR") not in [None, 'NA']:
            marriage_date = Date(str(family_info.get("MARR")))
        else:
            marriage_date = None
        if family_info.get("DIV") not in [None, 'NA']:
            divorce_date = Date(str(family_info.get("DIV")))
        else:
            divorce_date = None
       
        # obtains all childen in family
        children = family_info.get('CHIL')

        #if children exist, it gets the birth dates and compares it to the marriage/divorce dates, and prints error if marriage is before birth and/or birth is after divorce
        if children not in [None, 'NA']:
            for child in children:
                child_dict = individual_info_dict.get(child)
                birth_date = Date(str(child_dict.get('BIRT')))
                if type(marriage_date) is not str and marriage_date != None and type(marriage_date.date_time_obj) is not str and type(birth_date.date_time_obj) is not str:
                    if marriage_date not in [None, 'NA'] and marriage_date.date_time_obj < birth_date.date_time_obj:
                        print('ANOMOLY: FAMILY: US08: {}: Child {} born {} before marriage on {}'.format(family_id, child, birth_date, marriage_date))
                if type(divorce_date) is not str and divorce_date != None and type(divorce_date.date_time_obj) is not str and type(birth_date.date_time_obj) is not str:
                    if divorce_date not in [None, 'NA'] and birth_date.date_time_obj > divorce_date.date_time_obj:
                        print('ANOMOLY: FAMILY: US08: {}: Child {} born {} after divorce on {}'.format(family_id, child, birth_date, divorce_date))
    def test_us04(self):
        """ Test for US04 """
        # Test with GEDCOM individual @I4@

        husb_id = '@I4@'
        wife_id = '@I6@'
        marriage_dt = Date('18 Jun 2019')
        divorce_dt = Date('18 Jun 2018')
        fam_id = '@F3@'
        error_chk = True
        self.assertEqual(
            us04(husb_id, wife_id, marriage_dt, divorce_dt, fam_id, True),
            error_chk)

        return None
示例#4
0
def list_upcoming_birthdays(individual_info_dict, use_todays_date=True):
    """ Lists all birthdays within a month in a GEDCOM file. """
    
    upcoming_birthday_list = []
    if use_todays_date == True:
        today = datetime.date.today()
    else:
        today = datetime.date(2019, 6, 1)
    for individual_id, individual_info in individual_info_dict.items():
        id = individual_id
        name = individual_info.get('NAME')
        birth_date = Date(str(individual_info.get("BIRT"))).date_time_obj
        if birth_date not in [None, 'NA', '']:
            this_year_birthday = datetime.date(today.year, birth_date.month, birth_date.day)
            difference = this_year_birthday - today
            if difference > datetime.timedelta(0) and difference < datetime.timedelta(30):
                info = [id, name]
                upcoming_birthday_list.append(info)

    pt = ''
    if len(upcoming_birthday_list) > 0:
        pt = PrettyTable(field_names=["ID", "Name"])
        for id, name in upcoming_birthday_list:
            mults_info_list = [id, name]
            pt.add_row(mults_info_list)
    if pt != '':
        return_print = "US38: List: The following individuals have upcoming birthdays within 30 days!\n" + str(pt)
    else:
        return_print = None

    return return_print
    def test_us05(self):
        """ Test for US05 """
        # Test with GEDCOM individual @I6@

        husb_id = '@I4@'
        wife_id = '@I6@'
        husb_death_dt = Date('18 Jun 2020')
        wife_death_dt = Date('18 Jun 2017')
        marriage_dt = Date('18 Jun 2019')
        fam_id = '@F3@'
        error_chk = [False, True]
        self.assertEqual(
            us05(husb_id, husb_death_dt, wife_id, wife_death_dt, marriage_dt,
                 fam_id, True), error_chk)

        return None
    def test_us02_us10(self):
        """ Test for US02 and US10 """
        # Test with GEDCOM individual @I4@

        husb_id = '@I4@'
        wife_id = '@I6@'
        husb_birth_dt = Date('18 Jun 2021')
        wife_birth_dt = Date('18 Jun 2000')
        marriage_dt = Date('18 Jun 2019')
        fam_id = '@F3@'
        error_chk = [True, False, True, False]
        # Must add functionality of Date Class prior to sending dates to US02
        self.assertEqual(
            us02(husb_id, husb_birth_dt, wife_id, wife_birth_dt, marriage_dt,
                 fam_id, True), error_chk)

        return None
示例#7
0
def check_bigamy(individual_info_dict, family_info_dict):
    for individual_id, individual_info in individual_info_dict.items():
        id = individual_id
        name_place = individual_info.get('NAME')
        name = re.sub('/', '', name_place)
        marriage_count = 0
        start_dates = []
        end_dates = []
        for family_id, family_info in family_info_dict.items():
            
            wife_id = family_info.get('WIFE')
            husband_id = family_info.get('HUSB')
            
            if id == wife_id or id == husband_id:
                if id == wife_id:
                    spouse_death = individual_info_dict[husband_id].get('DEAT')
                    # print(family_info.get('MARR'))
                    # print(spouse_death)
                elif id == husband_id:
                    spouse_death = individual_info_dict[wife_id].get('DEAT')
                    # print(family_info.get('MARR'))
                    # print(spouse_death)
                Range = namedtuple('Range', ['start', 'end'])
                if family_info.get('DIV') not in [None, 'NA']:
                    length_of_marriage = Range(start=family_info.get('MARR'), end=family_info.get('DIV'))
                elif spouse_death not in [None, 'NA']:
                    length_of_marriage = Range(start=family_info.get('MARR'), end=spouse_death)
                else:
                    length_of_marriage = Range(start=family_info.get('MARR'), end=Date(datetime.datetime.today().strftime('%d %b %Y')))
                
                if family_info.get('MARR') not in [None, 'NA']:
                    start_dates.append(length_of_marriage.start.date_time_obj)
                    end_dates.append(length_of_marriage.end.date_time_obj)
                marriage_count += 1
        more_than_one_marriage_at_given_time = False


        if marriage_count > 1:
            latest_start = max(start_dates)
            earliest_end = min(end_dates)
            if type(latest_start) is not str and latest_start != None:
                if type(earliest_end) is not str and earliest_end != None:
                    delta = (earliest_end - latest_start).days
                    overlap = max(0, delta)
                    if overlap > 0:
                        more_than_one_marriage_at_given_time = True
        
        if more_than_one_marriage_at_given_time == True:
            print('ANOMOLY: INDIVIDUAL: US11: {}: Bigamy detected: {} married to multiple spouses at the same time'.format(id, name))
示例#8
0
def check_parents_not_too_old(individual_info_dict, family_info_dict):
    for family_id, family_info in family_info_dict.items():
        wife_id = family_info.get('WIFE')
        husband_id = family_info.get('HUSB')
        children = family_info.get('CHIL')
        husb_dict = individual_info_dict.get(husband_id)
        wife_dict = individual_info_dict.get(wife_id)
        husb_birth_date = Date(str(husb_dict.get('BIRT')))
        wife_birth_date = Date(str(wife_dict.get('BIRT')))
        parents_too_old = False
        if children not in [None, 'NA']:
            for child in children:
                child_dict = individual_info_dict.get(child)
                birth_date = Date(str(child_dict.get('BIRT')))
                
                too_old_age_difference = 65
                if type(husb_birth_date) is not str and husb_birth_date != None and type(husb_birth_date.date_time_obj) is not str and type(husb_birth_date.date_time_obj) is not str:
                    if type(wife_birth_date) is not str and wife_birth_date != None and type(wife_birth_date.date_time_obj) is not str and type(wife_birth_date.date_time_obj) is not str:
                        if type(birth_date) is not str and birth_date != None and type(birth_date.date_time_obj) is not str and type(birth_date.date_time_obj) is not str:
                            if Date.get_dates_difference(husb_birth_date.date_time_obj, birth_date.date_time_obj) > too_old_age_difference or Date.get_dates_difference(wife_birth_date.date_time_obj, birth_date.date_time_obj) > too_old_age_difference:
                                parents_too_old = True
                    
        if parents_too_old == True:
            print('ANOMOLY: FAMILY: US12: {}: Parents are too old: Parent(s) were greater than 65 years old when child was born'.format(family_id))
示例#9
0
def list_upcoming_anniversaries(individual_info_dict, family_info_dict, use_todays_date=True):
    """ Lists all anniversaries that occur within a month in a GEDCOM file. """
    upcoming_anniversary_list = []
    if use_todays_date == True:
        today = datetime.date.today()
    else:
        today = datetime.date(2019, 6, 1)
    pt = ''
    for family_id, family_info in family_info_dict.items():
        
        wife_id = family_info.get('WIFE')
        husband_id = family_info.get('HUSB')
        wife_name = ''
        husb_name = ''

        for individual_id, individual_info in individual_info_dict.items():
            if individual_id == wife_id:
                wife_name = individual_info.get('NAME')
            elif individual_id == husband_id:
                husb_name = individual_info.get('NAME')
        
        wedding_date = Date(str(family_info.get("MARR"))).date_time_obj
        if wedding_date not in [None, 'NA', '']:
            this_year_anniversary = datetime.date(today.year, wedding_date.month, wedding_date.day)
            difference = this_year_anniversary - today
            if difference > datetime.timedelta(0) and difference < datetime.timedelta(30):
                info = [wife_id, wife_name, husband_id, husb_name]
                upcoming_anniversary_list.append(info)

    pt = ''
    if len(upcoming_anniversary_list) > 0:
        pt = PrettyTable(field_names=["Wife ID", "Wife Name", "Husband ID", "Husband Name"])
        for info in upcoming_anniversary_list:
            pt.add_row(info)
    if pt != '':
        return_print = "US39: List: The following couples have upcoming anniversaries within 30 days!\n" + str(pt)
    else:
        return_print = None

    return return_print
def gedcom_file_parser(path, return_duplicate_ids = False):
    """gedcom file parser opens and reads a gedcom file line-byline
    and stores the fields of individuals and families in separate dictionaries.
    The key of individuals dictionary is the individual id, for families dictionary 
    it is family id.
    
    Arguments:
        path {string} -- this is the path of the gedcom file
    
    Returns:
        {tuple of dictionaries} -- the return value is a tuple of
        individuals and families dictionary
    """
    try:
        fp = open(path, "r")
    except FileNotFoundError:
        print("Can't open", path)
    else:
        duplicate_ids = []
        with fp:
            line = fp.readline()
            individuals_dict = dict()
            family_dict = dict()
            while line:
                if line != "":
                    tag_array = LEVEL_TAGS.get(line[0])
                    line_split = line.split()
                    if tag_array == None:
                        line = fp.readline()
                        continue
                    elif line_split[0] == "0":
                        if len(line_split) > 2 and line_split[2] == "INDI":
                            individual_id = line_split[1]
                            if individuals_dict.get(individual_id) != None:
                                duplicate_ids.append(individual_id)
                                line = fp.readline()
                                continue
                            individuals_dict[individual_id] = {}
                            line = fp.readline().rstrip("\n")
                            if line:
                                line_split = line.split()
                                while "INDI" not in line_split:
                                    if "FAM" in line_split or not line:
                                        break
                                    if line_split[1] in get_individual_info_tags():
                                        if line_split[1] == "BIRT":
                                            line = fp.readline().rstrip("\n")
                                            if line != "":
                                                line_split = line.split()
                                                if line_split[1] == "DATE":
                                                    individuals_dict[individual_id]["BIRT"] = Date(" ".join(
                                                        line_split[2:]))
                                        elif line_split[1] == "DEAT":
                                            line = fp.readline().rstrip("\n")
                                            if line != "":
                                                line_split = line.split()
                                                if line_split[1] == "DATE":
                                                    individuals_dict[individual_id]["DEAT"] = Date(" ".join(
                                                        line_split[2:]))
                                        else:
                                            individuals_dict[individual_id][line_split[1]] = " ".join(
                                                line_split[2:])
                                        line = fp.readline().rstrip("\n")
                                        line_split = line.split()
                                    else:
                                        line = fp.readline().rstrip("\n")
                                        line_split = line.split()
                                        continue
                        if "FAM" in line_split and len(line_split) > 2:
                            family_id = line_split[1]
                            if family_dict.get(family_id) != None:
                                duplicate_ids.append(family_id)
                                line = fp.readline()
                                continue
                            family_dict[family_id] = {}
                            line = fp.readline().rstrip("\n")
                            line_split = line.split()
                            while "FAM" not in line_split:
                                if line:
                                    if line_split[1] in get_family_info_tags():
                                        if line_split[1] == "MARR":
                                            line = fp.readline().rstrip("\n")
                                            if line:
                                                line_split = line.split()
                                                if line_split[1] == "DATE":
                                                    family_dict[family_id]["MARR"] = Date(" ".join(
                                                        line_split[2:]))
                                        elif line_split[1] == "DIV":
                                            line = fp.readline().rstrip("\n")
                                            if line:
                                                line_split = line.split()
                                                if line_split[1] == "DATE":
                                                    family_dict[family_id]["DIV"] = Date(" ".join(
                                                        line_split[2:]))
                                        elif line_split[1] == "CHIL":
                                            if family_dict[family_id].get("CHIL") == None:
                                                family_dict[family_id]["CHIL"] = [
                                                    line_split[2]]
                                            else:
                                                family_dict[family_id]["CHIL"].append(
                                                    line_split[2])
                                        else:
                                            family_dict[family_id][line_split[1]] = " ".join(
                                                line_split[2:])
                                        line = fp.readline().rstrip("\n")
                                        line_split = line.split()
                                    else:
                                        line = fp.readline().rstrip("\n")
                                        line_split = line.split()
                                        continue
                                else:
                                    break
                        else:
                            if "INDI" not in line_split:
                                line = fp.readline().rstrip("\n")
                            continue
                    else:
                        line = fp.readline().rstrip("\n")
                        continue
        if return_duplicate_ids:
            return individuals_dict, family_dict, duplicate_ids
        else:
            return individuals_dict, family_dict