def test_check_multiple_births_invalid(self): print('US14: Testing family with > 5 multiple births...') invaliParsedFile = { 'family': { '@F6000000089090979889@': { 'Children': { '@I6000000089090979883@', '@I6000000089090979871@', '@I6000000089090979874@', '@I6000000089090979891@', '@I6000000089090979877@', '@I6000000089090979880@' }, 'Married': '4 JUL 1990', 'Spouse 1': '@I6000000089090867827@', 'Spouse 2': '@I6000000089090979886@', 'Spouse 1 Name': 'Brian', 'Spouse 2 Name': 'Jane Lancing /Smith/', 'Divorced': 'NA' } }, 'members': { '@I6000000089090867827@': { 'ID': '@I6000000089090867827@', 'Child': 'NA', 'Spouse': {'@F6000000089090867863@', '@F6000000089090979889@'}, 'Name': 'Brian', 'Gender': 'M', 'Birthday': '21 SEP 1756', 'Death': 'NA', 'Alive?': 'Y', 'Age': 262 }, '@I6000000089090979886@': { 'ID': '@I6000000089090979886@', 'Child': 'NA', 'Spouse': {'@F6000000089090979889@'}, 'Name': 'Jane Lancing /Smith/', 'Gender': 'F', 'Birthday': '12 APR 1959', 'Death': 'NA', 'Alive?': 'Y', 'Age': 59 }, '@I6000000089090979891@': { 'ID': '@I6000000089090979891@', 'Child': {'@F6000000089090979889@'}, 'Spouse': 'NA', 'Name': 'Jason /Smith/', 'Gender': 'M', 'Birthday': '15 AUG 1990', 'Death': 'NA', 'Alive?': 'Y', 'Age': 28 }, '@I6000000089090979871@': { 'ID': '@I6000000089090979871@', 'Child': {'@F6000000089090979889@'}, 'Spouse': 'NA', 'Name': 'Jackson /Smith/', 'Gender': 'M', 'Birthday': '15 AUG 1990', 'Death': 'NA', 'Alive?': 'Y', 'Age': 28 }, '@I6000000089090979880@': { 'ID': '@I6000000089090979880@', 'Child': {'@F6000000089090979889@'}, 'Spouse': 'NA', 'Name': 'Janet /Smith/', 'Gender': 'F', 'Birthday': '15 AUG 1990', 'Death': 'NA', 'Alive?': 'Y', 'Age': 28 }, '@I6000000089090979877@': { 'ID': '@I6000000089090979877@', 'Child': {'@F6000000089090979889@'}, 'Spouse': 'NA', 'Name': 'Jasmine /Smith/', 'Gender': 'F', 'Birthday': '15 AUG 1990', 'Death': 'NA', 'Alive?': 'Y', 'Age': 28 }, '@I6000000089090979874@': { 'ID': '@I6000000089090979874@', 'Child': {'@F6000000089090979889@'}, 'Spouse': 'NA', 'Name': 'Jamie /Smith/', 'Gender': 'F', 'Birthday': '15 AUG 1990', 'Death': 'NA', 'Alive?': 'Y', 'Age': 28 }, '@I6000000089090979883@': { 'ID': '@I6000000089090979883@', 'Child': {'@F6000000089090979889@'}, 'Spouse': 'NA', 'Name': 'Joel /Smith/', 'Gender': 'M', 'Birthday': '15 AUG 1990', 'Death': 'NA', 'Alive?': 'Y', 'Age': 28 } } } errors = set() errors = FamilyValidation.check_multiple_births( invaliParsedFile, errors) for err in errors: self.assertEqual(err.errCode, Error.ErrorEnum.US14, msg='Failed to generate US14 error')
def test_check_multiple_births_valid(self): print('US14: Testing family with < 5 multiple births...') validParsedFile = { 'family': { '@F6000000086661172986@': { 'Children': {'@I6000000086661584835@'}, 'Married': '15 MAR 1982', 'Spouse 1': '@I6000000086661172981@', 'Spouse 2': '@I6000000086661506862@', 'Spouse 1 Name': 'Brian /Smith/', 'Spouse 2 Name': 'Rebecca /Smith/', 'Divorced': 'NA' } }, 'members': { '@I6000000086661584835@': { 'ID': '@I6000000086661584835@', 'Child': {'@F6000000086661172986@'}, 'Spouse': 'NA', 'Name': 'George /Smith/', 'Gender': 'M', 'Birthday': '2 JAN 1987', 'Death': 'NA', 'Alive?': 'Y', 'Age': 32 }, '@I6000000086661172981@': { 'ID': '@I6000000086661172981@', 'Child': 'NA', 'Spouse': {'@F6000000086661172986@'}, 'Name': 'Brian /Smith/', 'Gender': 'M', 'Birthday': '21 SEP 1956', 'Death': 'NA', 'Alive?': 'Y', 'Age': 62 }, '@I6000000086661506862@': { 'ID': '@I6000000086661506862@', 'Child': {'@F6000000086661201064@'}, 'Spouse': {'@F6000000086661172986@'}, 'Name': 'Rebecca /Smith/', 'Gender': 'F', 'Birthday': '13 MAY 1972', 'Death': 'NA', 'Alive?': 'Y', 'Age': 46 } } } errors = set() errors = FamilyValidation.check_multiple_births( validParsedFile, errors) self.assertEqual( len(errors), 0, msg='Failed to check valid family for multiple births')
def test_check_same_name_invalid(self): print( 'US25: Testing family with > 1 child having the same name (invalid)' ) invalidParsedFile = { 'family': { '@F6000000089090979889@': { 'Children': { '@I6000000089090979883@', '@I6000000089090979871@', '@I6000000089090979874@', '@I6000000089090979891@', '@I6000000089090979877@', '@I6000000089090979880@' }, 'Married': '4 JUL 1990', 'Spouse 1': '@I6000000089090867827@', 'Spouse 2': '@I6000000089090979886@', 'Spouse 1 Name': 'Brian', 'Spouse 2 Name': 'Jane Lancing /Smith/', 'Divorced': 'NA' } }, 'members': { '@I6000000089090867827@': { 'ID': '@I6000000089090867827@', 'Child': 'NA', 'Spouse': {'@F6000000089090867863@', '@F6000000089090979889@'}, 'Name': 'Brian', 'Gender': 'M', 'Birthday': '21 SEP 1756', 'Death': 'NA', 'Alive?': 'Y', 'Age': 262 }, '@I6000000089090979886@': { 'ID': '@I6000000089090979886@', 'Child': 'NA', 'Spouse': {'@F6000000089090979889@'}, 'Name': 'Jane Lancing /Smith/', 'Gender': 'F', 'Birthday': '12 APR 1959', 'Death': 'NA', 'Alive?': 'Y', 'Age': 59 }, '@I6000000089090979891@': { 'ID': '@I6000000089090979891@', 'Child': {'@F6000000089090979889@'}, 'Spouse': 'NA', 'Name': 'Jason /Smith/', 'Gender': 'M', 'Birthday': '15 AUG 1990', 'Death': 'NA', 'Alive?': 'Y', 'Age': 28 }, '@I6000000089090979871@': { 'ID': '@I6000000089090979871@', 'Child': {'@F6000000089090979889@'}, 'Spouse': 'NA', 'Name': 'Jackson /Smith/', 'Gender': 'M', 'Birthday': '15 AUG 1990', 'Death': 'NA', 'Alive?': 'Y', 'Age': 28 }, '@I6000000089090979880@': { 'ID': '@I6000000089090979880@', 'Child': {'@F6000000089090979889@'}, 'Spouse': 'NA', 'Name': 'Jasmine /Smith/', 'Gender': 'F', 'Birthday': '15 AUG 1990', 'Death': 'NA', 'Alive?': 'Y', 'Age': 28 }, '@I6000000089090979877@': { 'ID': '@I6000000089090979877@', 'Child': {'@F6000000089090979889@'}, 'Spouse': 'NA', 'Name': 'Jasmine /Smith/', 'Gender': 'F', 'Birthday': '15 AUG 1990', 'Death': 'NA', 'Alive?': 'Y', 'Age': 28 }, '@I6000000089090979874@': { 'ID': '@I6000000089090979874@', 'Child': {'@F6000000089090979889@'}, 'Spouse': 'NA', 'Name': 'Jamie /Smith/', 'Gender': 'F', 'Birthday': '15 AUG 1990', 'Death': 'NA', 'Alive?': 'Y', 'Age': 28 }, '@I6000000089090979883@': { 'ID': '@I6000000089090979883@', 'Child': {'@F6000000089090979889@'}, 'Spouse': 'NA', 'Name': 'Joel /Smith/', 'Gender': 'M', 'Birthday': '15 AUG 1990', 'Death': 'NA', 'Alive?': 'Y', 'Age': 28 } } } errors = set() errors = FamilyValidation.check_same_name(invalidParsedFile, errors) self.assertEqual( len(errors), 1, msg= 'Failed to check invalid family for multiple children with the same name' )
def test_list_multiple_births(self): print('US32: Testing listing multiple births...') valiParsedFile = { 'family': { '@F6000000089090979889@': { 'Children': { '@I6000000089090979883@', '@I6000000089090979871@', '@I6000000089090979874@', '@I6000000089090979891@', '@I6000000089090979877@' }, 'Married': '4 JUL 1990', 'Spouse 1': '@I6000000089090867827@', 'Spouse 2': '@I6000000089090979886@', 'Spouse 1 Name': 'Brian', 'Spouse 2 Name': 'Jane Lancing /Smith/', 'Divorced': 'NA' } }, 'members': { '@I6000000089090867827@': { 'ID': '@I6000000089090867827@', 'Child': 'NA', 'Spouse': {'@F6000000089090867863@', '@F6000000089090979889@'}, 'Name': 'Brian', 'Gender': 'M', 'Birthday': '21 SEP 1756', 'Death': 'NA', 'Alive?': 'Y', 'Age': 262 }, '@I6000000089090979886@': { 'ID': '@I6000000089090979886@', 'Child': 'NA', 'Spouse': {'@F6000000089090979889@'}, 'Name': 'Jane Lancing /Smith/', 'Gender': 'F', 'Birthday': '12 APR 1959', 'Death': 'NA', 'Alive?': 'Y', 'Age': 59 }, '@I6000000089090979891@': { 'ID': '@I6000000089090979891@', 'Child': {'@F6000000089090979889@'}, 'Spouse': 'NA', 'Name': 'Jason /Smith/', 'Gender': 'M', 'Birthday': '15 AUG 1990', 'Death': 'NA', 'Alive?': 'Y', 'Age': 28 }, '@I6000000089090979871@': { 'ID': '@I6000000089090979871@', 'Child': {'@F6000000089090979889@'}, 'Spouse': 'NA', 'Name': 'Jackson /Smith/', 'Gender': 'M', 'Birthday': '15 AUG 1990', 'Death': 'NA', 'Alive?': 'Y', 'Age': 28 }, '@I6000000089090979877@': { 'ID': '@I6000000089090979877@', 'Child': {'@F6000000089090979889@'}, 'Spouse': 'NA', 'Name': 'Jasmine /Smith/', 'Gender': 'F', 'Birthday': '15 AUG 1990', 'Death': 'NA', 'Alive?': 'Y', 'Age': 28 }, '@I6000000089090979874@': { 'ID': '@I6000000089090979874@', 'Child': {'@F6000000089090979889@'}, 'Spouse': 'NA', 'Name': 'Jamie /Smith/', 'Gender': 'F', 'Birthday': '15 AUG 1990', 'Death': 'NA', 'Alive?': 'Y', 'Age': 28 }, '@I6000000089090979883@': { 'ID': '@I6000000089090979883@', 'Child': {'@F6000000089090979889@'}, 'Spouse': 'NA', 'Name': 'Joel /Smith/', 'Gender': 'M', 'Birthday': '15 AUG 1990', 'Death': 'NA', 'Alive?': 'Y', 'Age': 28 } } } expectedMultipleList = [{ 'Birthday': '15 AUG 1990', 'ID': '@I6000000089090979871@', 'Name': 'Jackson /Smith/' }, { 'Birthday': '15 AUG 1990', 'ID': '@I6000000089090979891@', 'Name': 'Jason /Smith/' }, { 'Birthday': '15 AUG 1990', 'ID': '@I6000000089090979877@', 'Name': 'Jasmine /Smith/' }, { 'Birthday': '15 AUG 1990', 'ID': '@I6000000089090979874@', 'Name': 'Jamie /Smith/' }, { 'Birthday': '15 AUG 1990', 'ID': '@I6000000089090979883@', 'Name': 'Joel /Smith/' }] valiParsedFile = FamilyValidation.list_multiple_births(valiParsedFile) multiplesList = valiParsedFile['multiples']['@F6000000089090979889@'] self.assertEqual(len(expectedMultipleList), len(multiplesList), msg='Error: multiples lists sizes do not match')
def test_order_siblings_by_age(self): print('US28: Testing sorting siblings by age...') validParsedFile = { 'family': { '@F6000000089090979889@': { 'Children': { '@I6000000089090979883@', '@I6000000089090979871@', '@I6000000089090979874@', '@I6000000089090979891@', '@I6000000089090979877@', '@I6000000089090979880@' }, 'Married': '4 JUL 1990', 'Spouse 1': '@I6000000089090867827@', 'Spouse 2': '@I6000000089090979886@', 'Spouse 1 Name': 'Brian', 'Spouse 2 Name': 'Jane Lancing /Smith/', 'Divorced': 'NA' } }, 'members': { '@I6000000089090867827@': { 'ID': '@I6000000089090867827@', 'Child': 'NA', 'Spouse': {'@F6000000089090867863@', '@F6000000089090979889@'}, 'Name': 'Brian', 'Gender': 'M', 'Birthday': '21 SEP 1956', 'Death': 'NA', 'Alive?': 'Y', 'Age': 62 }, '@I6000000089090979886@': { 'ID': '@I6000000089090979886@', 'Child': 'NA', 'Spouse': {'@F6000000089090979889@'}, 'Name': 'Jane Lancing /Smith/', 'Gender': 'F', 'Birthday': '12 APR 1959', 'Death': 'NA', 'Alive?': 'Y', 'Age': 59 }, '@I6000000089090979891@': { 'ID': '@I6000000089090979891@', 'Child': {'@F6000000089090979889@'}, 'Spouse': 'NA', 'Name': 'Jason /Smith/', 'Gender': 'M', 'Birthday': '15 MAR 1990', 'Death': 'NA', 'Alive?': 'Y', 'Age': 28 }, '@I6000000089090979871@': { 'ID': '@I6000000089090979871@', 'Child': {'@F6000000089090979889@'}, 'Spouse': 'NA', 'Name': 'Jackson /Smith/', 'Gender': 'M', 'Birthday': '12 JUL 1989', 'Death': 'NA', 'Alive?': 'Y', 'Age': 29 }, '@I6000000089090979880@': { 'ID': '@I6000000089090979880@', 'Child': {'@F6000000089090979889@'}, 'Spouse': 'NA', 'Name': 'Janet /Smith/', 'Gender': 'F', 'Birthday': '2 APR 1993', 'Death': 'NA', 'Alive?': 'Y', 'Age': 26 }, '@I6000000089090979877@': { 'ID': '@I6000000089090979877@', 'Child': {'@F6000000089090979889@'}, 'Spouse': 'NA', 'Name': 'Jasmine /Smith/', 'Gender': 'F', 'Birthday': '30 NOV 1997', 'Death': 'NA', 'Alive?': 'Y', 'Age': 22 }, '@I6000000089090979874@': { 'ID': '@I6000000089090979874@', 'Child': {'@F6000000089090979889@'}, 'Spouse': 'NA', 'Name': 'Jamie /Smith/', 'Gender': 'F', 'Birthday': '12 JAN 2000', 'Death': 'NA', 'Alive?': 'Y', 'Age': 19 }, '@I6000000089090979883@': { 'ID': '@I6000000089090979883@', 'Child': {'@F6000000089090979889@'}, 'Spouse': 'NA', 'Name': 'Joel /Smith/', 'Gender': 'M', 'Birthday': '?? AUG 2018', 'Death': 'NA', 'Alive?': 'Y', 'Age': 'Unknown' } } } expectedSiblingsList = [{ 'ID': '@I6000000089090979871@', 'Name': 'Jackson /Smith/', 'Birthday': '12 JUL 1989', 'Age': 29 }, { 'ID': '@I6000000089090979891@', 'Name': 'Jason /Smith/', 'Birthday': '15 MAR 1990', 'Age': 28 }, { 'ID': '@I6000000089090979880@', 'Name': 'Janet /Smith/', 'Birthday': '2 APR 1993', 'Age': 26 }, { 'ID': '@I6000000089090979877@', 'Name': 'Jasmine /Smith/', 'Birthday': '30 NOV 1997', 'Age': 22 }, { 'ID': '@I6000000089090979874@', 'Name': 'Jamie /Smith/', 'Birthday': '12 JAN 2000', 'Age': 19 }, { 'ID': '@I6000000089090979883@', 'Name': 'Joel /Smith/', 'Birthday': '?? AUG 2018', 'Age': 'Unknown' }] sortedSiblingsList = FamilyValidation.order_siblings_by_age( validParsedFile) self.assertEqual( len(expectedSiblingsList), len(sortedSiblingsList['siblings']['@F6000000089090979889@']), msg='Error: sorted siblings list size does not match expected') for index in range(0, len(expectedSiblingsList)): self.assertEqual(expectedSiblingsList[index]['Age'], sortedSiblingsList['siblings'] ['@F6000000089090979889@'][index]['Age'], msg='Error: siblings lists do not match')
def pretty_table(parsed_file_dict): # Set up PrettyTable # List individuals: US27 include ages individuals = PrettyTable() individuals.field_names = [ 'ID', 'Name', 'Gender', 'Birthday', 'Age', 'Alive?', 'Death', 'Child', 'Spouse' ] print('== Individuals ==') for k in parsed_file_dict['members'].keys(): individuals.add_row([ parsed_file_dict['members'][k]['ID'], parsed_file_dict['members'][k]['Name'], parsed_file_dict['members'][k]['Gender'], parsed_file_dict['members'][k]['Birthday'], parsed_file_dict['members'][k]['Age'], parsed_file_dict['members'][k]['Alive?'], parsed_file_dict['members'][k]['Death'], parsed_file_dict['members'][k]['Child'], parsed_file_dict['members'][k]['Spouse'] ]) print(individuals) # List Families family = PrettyTable() family.field_names = [ 'ID', 'Married', 'Divorced', 'Spouse 1 ID', 'Spouse 1 Name', 'Spouse 2 ID', 'Spouse 2 Name', 'Children' ] print('\n== Families ==') for k in parsed_file_dict['family'].keys(): family.add_row([ k, parsed_file_dict['family'][k]['Married'], parsed_file_dict['family'][k]['Divorced'], parsed_file_dict['family'][k]['Spouse 1'], parsed_file_dict['family'][k]['Spouse 1 Name'], parsed_file_dict['family'][k]['Spouse 2'], parsed_file_dict['family'][k]['Spouse 2 Name'], parsed_file_dict['family'][k]['Children'] ]) print(family) # US28 - List siblings by age parsed_file_dict = FamilyValidation.order_siblings_by_age(parsed_file_dict) siblings = PrettyTable() siblings.field_names = [ 'Family ID', 'Individual ID', 'Name', 'Birthday', 'Age' ] print('\nUS28') print('== Siblings ==') for k in parsed_file_dict['siblings'].keys(): for sibling in parsed_file_dict['siblings'][k]: siblings.add_row([ k, sibling['ID'], sibling['Name'], sibling['Birthday'], sibling['Age'] ]) siblings.add_row(['--', '--', '--', '--', '--']) print(siblings) # US32 - List multiple births parsed_file_dict = FamilyValidation.list_multiple_births(parsed_file_dict) multiples = PrettyTable() multiples.field_names = ['Family ID', 'Birthday', 'Individual ID', 'Name'] print('\nUS32') print('== Multiple Births ==') for k in parsed_file_dict['multiples'].keys(): for person in parsed_file_dict['multiples'][k]: multiples.add_row( [k, person['Birthday'], person['ID'], person['Name']]) multiples.add_row(['--', '--', '--', '--']) print(multiples) # US 30 & 31 - List living married & List living single marital_status = LivingMaritalStatus.list_living_married(parsed_file_dict) married = PrettyTable() married.field_names = ['Individual ID', 'Name'] singles = PrettyTable() singles.field_names = ['Individual ID', 'Name'] print('\nUS 30') print('== Living Married ==') for k in marital_status['married'].keys(): married.add_row([ marital_status['married'][k]['ID'], marital_status['married'][k]['Name'] ]) print(married) print('\nUS 31') print('== Living Single ==') for k in marital_status['singles'].keys(): singles.add_row([ marital_status['singles'][k]['ID'], marital_status['singles'][k]['Name'] ]) print(singles) print('\n') #US29 - List all deseased individuals parsed_file_dict = DeseasedIndividuals.list_deseased_individuals( parsed_file_dict) deseased = PrettyTable() deseased.field_names = ['ID', 'Name', 'Birthday', 'Death Date', 'Age'] print('US29') print('== Deseased Individuals ==') for key in parsed_file_dict['deseased'].keys(): deseased.add_row([ key, parsed_file_dict['deseased'][key]['Name'], parsed_file_dict['deseased'][key]['Birthday'], parsed_file_dict['deseased'][key]['Death'], parsed_file_dict['deseased'][key]['Age'] ]) print(deseased) print('\n')
if fileExtension != '.ged': print('Error input file must be in .ged format') quit() fileName += fileExtension parsed_file = parse_file(fileName) # US11 - Check for bigamy if not MarriageValidation.bigamy_check(parsed_file): us11Err = Error.Error(Error.ErrorEnum.US11) errors.add(us11Err) # US14 - Check for multiple births errors = FamilyValidation.check_multiple_births(parsed_file, errors) # US18 - Siblings should not marry one another errors = siblings_not_marry.siblings_not_marry(parsed_file, errors) # US16 - Male last names errors = male_last_names.check_all_male_last_names(parsed_file, errors) # US17 - No marriage to children errors = no_marriage_to_children.no_marriage_to_children( parsed_file, errors) # US23 - No more than one individual with the same name and birth date errors = unique_name_birth.unique_name_and_birth(parsed_file, errors) # US24 - No more than one family with the same spouses by name and the same marriage date