def test_validate_marraige_before_divorce_day(self): print("US04: Testing marriage before divorce (invalid day)...") marraige = date(2001, 2, 14) invalid_divorce = date(2001, 2, 13) valid_divorce = date(2001, 2, 15) self.assertEqual(DateValidation.validate_marraige_before_divorce( marraige, invalid_divorce), False, msg='should be False, day error') self.assertEqual(DateValidation.validate_marraige_before_divorce( marraige, valid_divorce), True, msg='correct')
def test_validate_birth_before_death_month(self): print("US03: Testing birth before death (invalid month)...") birth = date(1995, 2, 3) invalid_death = date(1955, 1, 3) valid_death = date(1995, 3, 3) self.assertEqual(DateValidation.validate_birth_before_death( birth, invalid_death), False, msg='should be False, month error') self.assertEqual(DateValidation.validate_birth_before_death( birth, valid_death), True, msg='correct')
def test_validate_birth_before_death_year(self): print("US03: Testing birth before death (invalid year)...") birth = date(1955, 2, 3) invalid_death = date(1954, 2, 3) valid_death = date(1956, 2, 3) self.assertEqual(DateValidation.validate_birth_before_death( birth, invalid_death), False, msg='should be False, year error.') self.assertEqual(DateValidation.validate_birth_before_death( birth, valid_death), True, msg='correct')
def test_validateDate_invalid_year(self): print("US01: Testing an invalid date with invalid year...") today = date.today() invalid_year = date((today.year + 5), today.month, today.day) self.assertEqual(DateValidation.validateDate(invalid_year), False, msg='Date should be invalid: year error')
def test_createValidDate_Invalid_Aug(self): print( "US42: Testing creating a valid date from string (invalid days in month)..." ) invalidDateAug = '33 AUG 2019' self.assertRaises( ValueError, lambda: DateValidation.createValidDate(invalidDateAug))
def test_validateDate_invalid_month(self): print("US01: Testing an invalid date with invalid month...") today = date.today() invalid_month = date(today.year, (today.month + 3), today.day) self.assertEqual(DateValidation.validateDate(invalid_month), False, msg='Date should be invalid: month error')
def test_partial_date_check_missing_month_day(self): print( "US41: Testing creating a valid date from an incomplete date string (missing day and month)..." ) partial_date = '2019' self.assertEqual(DateValidation.partial_date_check(partial_date), '?? ??? 2019', True)
def test_validateDate_invalid_day(self): print("US01: Testing an invalid date with invalid day...") today = date.today() invalid_day = date(today.year, today.month, (today.day + 1)) self.assertEqual(DateValidation.validateDate(invalid_day), False, msg='Date should be invalid: day error')
def test_createValidDate_invalid_Feb(self): print( "US42: Testing creating a valid date from string (invalid days in month)..." ) invalidFebStr = '30 FEB 2020' self.assertRaises( ValueError, lambda: DateValidation.createValidDate(invalidFebStr))
def test_partial_date_check_full_date(self): print( "US41: Testing creating a valid date from an incomplete date string (full date)..." ) full_date = '14 MAR 2019' self.assertEqual(DateValidation.partial_date_check(full_date), full_date, True)
def test_createValidDate_valid(self): print("US42: Testing creating a valid date from string (valid)...") validDateStr = '10 OCT 2020' validDate = date(2020, 10, 10) self.assertEqual(DateValidation.createValidDate(validDateStr), validDate, msg='Error: Date is valid')
def test_validateMarraigeDate_invalid_day(self): print("US02: Testing an invalid marriage date with invalid day...") validBirthdate = date(1990, 12, 28) invalidMarraigeDate_day = date(1990, 12, 21) self.assertEqual(DateValidation.validateMarraigeDate( validBirthdate, invalidMarraigeDate_day), False, msg='Marraige date should be invalid: day error')
def test_validateMarraigeDate_invalid_year(self): print("US02: Testing an invalid marriage date with invalid year...") validBirthdate = date(1990, 12, 28) invalidMarraigeDate_year = date(1919, 3, 21) self.assertEqual(DateValidation.validateMarraigeDate( validBirthdate, invalidMarraigeDate_year), False, msg='Marraige date should be invalid: year error')
def test_validateMarraigeDate_valid(self): print("US02: Testing a valid marriage date...") validBirthdate = date(1990, 12, 28) validMarraigeDate = date(2019, 1, 1) self.assertEqual(DateValidation.validateMarraigeDate( validBirthdate, validMarraigeDate), True, msg='Valid: marraige date after birthdate')
def test_validate_birth_before_death_valid(self): print("US03: Testing birth before death (valid)...") birth = date(1995, 2, 3) valid_death = date(2011, 11, 19) self.assertEqual(DateValidation.validate_birth_before_death( birth, valid_death), True, msg='correct')
def test_createValidDate_invalid_Sept(self): print( "US42: Testing creating a valid date from string (invalid days in month)..." ) invalidDateSept = '31 SEP 2019' self.assertRaises( ValueError, lambda: DateValidation.createValidDate(invalidDateSept))
def test_validate_marraige_before_divorce_valid(self): print("US04: Testing marriage before divorce (valid)...") marraige = date(2001, 2, 14) valid_divorce = date(2013, 7, 9) self.assertEqual(DateValidation.validate_marraige_before_divorce( marraige, valid_divorce), True, msg='correct')
def test_validateDate_valid(self): print("US01: Testing a valid date...") valid_date = date(1990, 4, 21) self.assertEqual(DateValidation.validateDate(valid_date), True, msg='Date is valid')
def parse_file(filename): try: with open(filename) as gedFile: # Initialize dicts for working with an individual, tracking members of the family, and grouping families family = {} individual = {} members = {} duplicate_increment = 1 # Tracking where we are in the hierarchy currentFam, currentTag = '', '' line = gedFile.readline() # Parse the file while line: gedLine = GEDCOM_Line() gedLine.Parse(line) gedLine.Validate() line = line.rstrip() line = line.split(' ', 2) if line[0] == '0' and len( line) == 3: # If line is an INDI or FAM line if individual: # If an individual has been completed members[individual[ 'ID']] = individual # Add them to the members dict individual = {} # Empty the dict to start over if gedLine.Valid == 'Y': if line[2] == 'INDI': if not UniqueIds.UniqueIndividualIds( line[1], members ): # Ensure we're not duplicating people individual['ID'] = line[1] individual['Child'] = set() individual['Spouse'] = set() currentTag = line[2] line = gedFile.readline( ) # Move to the next line continue else: # US22 - flag the error and mark the ID as duplicate us22iErr = Error.Error(Error.ErrorEnum.US22i) us22iErr.alterErrMsg(line[1]) errors.add(us22iErr) individual['ID'] = line[1] + '_' + str( duplicate_increment) + ' DUPLICATE ID' duplicate_increment += 1 individual['Child'] = set() individual['Spouse'] = set() currentTag = line[2] line = gedFile.readline( ) # Move to the next line continue if line[2] == 'FAM': if not UniqueIds.UniqueFamilyIds( line[1], family ): # Ensure we're not duplicating families family[line[1]] = { 'Children': set() } # Add a new family currentTag = line[2] currentFam = line[1] line = gedFile.readline() continue else: us22fErr = Error.Error(Error.ErrorEnum.US22f) us22fErr.alterErrMsg(line[1]) errors.add(us22fErr) family[line[1] + '_' + str(duplicate_increment) + ' DUPLICATE ID'] = { 'Children': set() } # Add a new family currentTag = line[2] currentFam = line[1] + '_' + str( duplicate_increment) + ' DUPLICATE ID' duplicate_increment += 1 line = gedFile.readline( ) # Move to the next line continue elif len(line) == 2: if gedLine.Valid == 'Y': currentTag = line[1] line = gedFile.readline() continue elif 'DEAT' in line: if gedLine.Valid == 'Y': currentTag = 'DEAT' line = gedFile.readline() continue elif line[1] == 'HUSB' or line[1] == 'WIFE' or line[ 1] == 'CHIL': if gedLine.Valid == 'Y': currentTag = line[1] # Logic for adding information to individuals based on where we are in the hierarchy if currentTag == 'INDI': if line[0] != 0 and len(line) == 3: if gedLine.Valid == 'Y': if line[1] == 'NAME': individual['Name'] = line[2] elif line[1] == 'SEX': individual['Gender'] = line[2] elif line[1] == 'FAMC': individual['Child'].add(line[2]) elif line[1] == 'FAMS': individual['Spouse'].add(line[2]) line = gedFile.readline() continue if currentTag == 'BIRT': if line[0] != 0 and len(line) == 3: if gedLine.Valid == 'Y': if line[1] == 'DATE': targetDate = DateValidation.partial_date_check( line[2]) if '?' in targetDate: individual['Birthday'] = targetDate warnings.add( 'WARNING US41: ' + individual['ID'] + ' only has partial birthday: ' + targetDate + '. Date verifications cannot run using this date.' ) currentTag = 'INDI' else: try: testDate = DateValidation.createValidDate( line[2]) if DateValidation.validateDate( testDate): individual['Birthday'] = line[2] currentTag = 'INDI' else: today = date.today() us01Err = Error.Error( Error.ErrorEnum.US01) us01Err.alterErrMsg( testDate, today) errors.add(us01Err) individual['Birthday'] = line[2] currentTag = 'INDI' except ValueError as err: us42Err = Error.Error( Error.ErrorEnum.US42) us42Err.alterErrMsg(err) errors.add(us42Err) individual['Birthday'] = line[2] finally: currentTag = 'INDI' if currentTag == 'DEAT': if line[0] != 0 and len(line) == 3: if gedLine.Valid == 'Y': if line[1] == 'DATE': targetDate = DateValidation.partial_date_check( line[2]) if '?' in targetDate: individual['Death'] = targetDate warnings.add( 'WARNING US41: ' + individual['ID'] + ' only has partial death date: ' + targetDate + '. Date verifications cannot run using this date.' ) currentTag = 'INDI' else: try: testDate = DateValidation.createValidDate( line[2]) if DateValidation.validateDate( testDate): individual['Death'] = line[2] else: today = date.today() us01Err = Error.Error( Error.ErrorEnum.US01) us01Err.alterErrMsg( testDate, today) errors.add(us01Err) individual['Death'] = line[2] except ValueError as err: us42Err = Error.Error( Error.ErrorEnum.US42) us42Err.alterErrMsg(err) errors.add(us42Err) individual['Death'] = line[2] finally: currentTag = 'INDI' if currentTag == 'MARR': if line[0] != 0 and len(line) == 3: if gedLine.Valid == 'Y': if line[1] == 'DATE': targetDate = DateValidation.partial_date_check( line[2]) if '?' in targetDate: family[currentFam]['Married'] = targetDate warnings.add( 'WARNING US41: ' + currentFam + ' only has partial marriage date: ' + targetDate + '. Date verifications cannot run using this date.' ) else: try: testDate = DateValidation.createValidDate( line[2]) if DateValidation.validateDate( testDate): family[currentFam][ 'Married'] = line[2] else: today = date.today() us01Err = Error.Error( Error.ErrorEnum.US01) us01Err.alterErrMsg( testDate, today) errors.add(us01Err) except ValueError as err: us42Err = Error.Error( Error.ErrorEnum.US42) us42Err.alterErrMsg(err) errors.add(us42Err) family[currentFam]['Married'] = line[2] if currentTag == 'DIV': if line[0] != 0 and len(line) == 3: if gedLine.Valid == 'Y': if line[1] == 'DATE': targetDate = DateValidation.partial_date_check( line[2]) if '?' in targetDate: family[currentFam]['Divorced'] = targetDate warnings.add( 'WARNING US41: ' + currentFam + ' only has partial divorce date: ' + targetDate + '. Date verifications cannot run using this date.' ) else: try: testDate = DateValidation.createValidDate( line[2]) if DateValidation.validateDate( testDate): family[currentFam][ 'Divorced'] = line[2] else: today = date.today() us01Err = Error.Error( Error.ErrorEnum.US01) us01Err.alterErrMsg( testDate, today) errors.add(us01Err) except ValueError as err: us42Err = Error.Error( Error.ErrorEnum.US42) us42Err.alterErrMsg(err) errors.add(us42Err) family[currentFam]['Divorced'] = line[ 2] if currentTag == 'HUSB': if line[0] != 0 and len(line) == 3: if gedLine.Valid == 'Y': if 'Spouse 1' in family[currentFam].keys(): family[currentFam]['Spouse 2'] = line[2] else: family[currentFam]['Spouse 1'] = line[2] if currentTag == 'WIFE': if line[0] != 0 and len(line) == 3: if gedLine.Valid == 'Y': if 'Spouse 1' in family[currentFam].keys(): family[currentFam]['Spouse 2'] = line[2] else: family[currentFam]['Spouse 1'] = line[2] if currentTag == 'CHIL': if line[0] != 0 and len(line) == 3: if gedLine.Valid == 'Y': family[currentFam]['Children'].add(line[2]) if currentTag != 'INDI': currentTag = '' line = gedFile.readline() except IOError as e: print('Error opening ' + sys.argv[1] + ': ' + str(e)) finally: for k in family.keys(): # Add name of Spouse based on ID family[k]['Spouse 1 Name'] = members[family[k]['Spouse 1']]['Name'] family[k]['Spouse 2 Name'] = members[family[k]['Spouse 2']]['Name'] if 'Divorced' not in family[k].keys(): # 'NA' if not divorced family[k]['Divorced'] = 'NA' if len(family[k]['Children']) == 0: # 'NA' if no children family[k]['Children'] = 'NA' for k, v in members.items(): # For each member, check if died if 'Death' in members[k].keys( ): # If died, set 'N' for Alive and calculate age at death members[k]['Alive?'] = 'N' if '?' in members[k]['Birthday']: members[k]['Age'] = 'Unknown' else: text_birthday = members[k]['Birthday'].split(' ', 2) try: birthday = DateValidation.createValidDate( members[k]['Birthday']) death_day = DateValidation.createValidDate( members[k]['Death']) if not DateValidation.validate_birth_before_death( birthday, death_day): us03Err = Error.Error(Error.ErrorEnum.US03) us03Err.alterErrMsg(death_day, birthday) errors.add(us03Err) members[k]['Age'] = date_difference( birthday, death_day) else: members[k]['Age'] = date_difference( birthday, death_day) except ValueError as err: us42Err = Error.Error(Error.ErrorEnum.US42) us42Err.alterErrMsg(err) errors.add(us42Err) birthday = date(int(text_birthday[2]), months[text_birthday[1]], 1) members[k]['Age'] = date_difference( birthday, death_day) else: members[k]['Death'] = 'NA' members[k]['Alive?'] = 'Y' if '??' in members[k]['Birthday']: members[k]['Age'] = 'Unknown' else: text_birthday = members[k]['Birthday'].split(' ', 2) try: birthday = DateValidation.createValidDate( members[k]['Birthday']) members[k]['Age'] = date_difference(birthday) except ValueError as err: us42Err = Error.Error(Error.ErrorEnum.US42) us42Err.alterErrMsg(err) errors.add(us42Err) birthday = date(int(text_birthday[2]), months[text_birthday[1]], 1) members[k]['Age'] = date_difference(birthday) if len(members[k]['Child']) == 0: # if no children, 'NA' members[k]['Child'] = 'NA' if len(members[k]['Spouse']) == 0: # if no spouse, 'NA' members[k]['Spouse'] = 'NA' for k in members.keys(): member = members[k] lessthan_150.less_than_150(member, errors) gedFile.close() #US15 siblings_not_too_many.siblings_not_too_many(family, errors) for f in family.keys(): marriage_date_text = family[f]['Married'].split(' ', 2) if '??' in marriage_date_text: spouses = [family[f]['Spouse 1'], family[f]['Spouse 2']] divorce_date_text = '' else: marriage_date = date(int(marriage_date_text[2]), months[marriage_date_text[1]], int(marriage_date_text[0])) spouses = [family[f]['Spouse 1'], family[f]['Spouse 2']] divorce_date_text = '' if members[family[f]['Spouse 1']]['Death'] != 'NA': if '??' in marriage_date_text: pass else: died_on = members[family[f]['Spouse 1']]['Death'].split( ' ', 2) died_on_date = date(int(died_on[2]), int(months[died_on[1]]), int(died_on[0])) if not MarriageBeforeDeathValidation.marr_before_death( marriage_date, died_on_date): us05Err = Error.Error(Error.ErrorEnum.US05) us05Err.alterErrMsg(f) errors.add(us05Err) if members[family[f]['Spouse 2']]['Death'] != 'NA': if '??' in marriage_date_text: pass else: died_on = members[family[f]['Spouse 2']]['Death'].split( ' ', 2) died_on_date = date(int(died_on[2]), int(months[died_on[1]]), int(died_on[0])) if not MarriageBeforeDeathValidation.marr_before_death( marriage_date, died_on_date): us05Err = Error.Error(Error.ErrorEnum.US05) us05Err.alterErrMsg(f) errors.add(us05Err) if family[f]['Divorced'] != 'NA': divorce_date_text = family[f]['Divorced'].split(' ', 2) if '??' in divorce_date_text: pass else: divorce_date = date(int(divorce_date_text[2]), months[divorce_date_text[1]], int(divorce_date_text[0])) if members[family[f]['Spouse 1']]['Death'] != 'NA': if '??' in divorce_date_text: pass else: died_on = members[family[f] ['Spouse 1']]['Death'].split(' ', 2) died_on_date = date(int(died_on[2]), int(months[died_on[1]]), int(died_on[0])) if not DivorceBeforeDeathValidation.div_before_death( divorce_date, died_on_date): us06Err = Error.Error(Error.ErrorEnum.US06) us06Err.alterErrMsg(f) errors.add(us06Err) if members[family[f]['Spouse 2']]['Death'] != 'NA': if '??' in divorce_date_text: pass else: died_on = members[family[f] ['Spouse 2']]['Death'].split(' ', 2) died_on_date = date(int(died_on[2]), int(months[died_on[1]]), int(died_on[0])) if not DivorceBeforeDeathValidation.div_before_death( divorce_date, died_on_date): us06Err = Error.Error(Error.ErrorEnum.US06) us06Err.alterErrMsg(f) errors.add(us06Err) for s in spouses: text_birthday = members[s]['Birthday'].split(' ', 2) if '??' in text_birthday: pass else: try: birthdate = date(int(text_birthday[2]), months[text_birthday[1]], int(text_birthday[0])) except ValueError as err: birthdate = date(int(text_birthday[2]), months[text_birthday[1]], 1) finally: if DateValidation.validateMarraigeDate( birthdate, marriage_date) is False: us02Err = Error.Error(Error.ErrorEnum.US02) us02Err.alterErrMsg(marriage_date, birthdate) errors.add(us02Err) if divorce_date_text != '': if DateValidation.validate_marraige_before_divorce( marriage_date, divorce_date) is False: us04Err = Error.Error(Error.ErrorEnum.US04) us04Err.alterErrMsg(divorce_date, marriage_date) errors.add(us04Err) if not MarriageValidation.valid_age_at_marriage( birthdate, marriage_date): us10Err = Error.Error(Error.ErrorEnum.US10) us10Err.alterErrMsg(s, f) errors.add(us10Err) siblings = [ v['Children'] for v in family.values() if len(v['Children']) > 1 and v['Children'] != 'NA' ] for s in siblings: sibBirths = [] for i in s: if '??' in members[i]['Birthday']: continue else: sibBirths.append(members[i]['Birthday']) # print(sibBirths) sibBirths = sorted(sibBirths) for d in sibBirths: if sibBirths.index(d) == len(sibBirths) - 1: break else: if SiblingSpacing.valid_sibling_spacing( d, sibBirths[sibBirths.index(d) + 1]) is False: us13Err = Error.Error(Error.ErrorEnum.US13) us13Err.alterErrMsg(d, sibBirths[sibBirths.index(d) + 1]) errors.add(us13Err) # print(family) for f in family.keys(): parent_marriage_date = family[f]['Married'] parent_divorce_date = family[f]['Divorced'] if family[f]['Children'] == 'NA': continue else: children = family[f]['Children'] # print(f) # print(len(children)) for child_id in children: # print('child_id:' + child_id) child = members[child_id] birth_date = child['Birthday'] birth_before_parent_marriage.birth_before_parent_marriage( birth_date, parent_marriage_date, parent_divorce_date, errors) for f in family.keys(): parent1_id = family[f]['Spouse 1'] parent2_id = family[f]['Spouse 2'] children = family[f]['Children'] if members[parent1_id]['Death'] == 'NA' and members[parent2_id][ 'Death'] == 'NA': continue else: for c in children: if '??' in members[c]['Birthday']: continue else: if '??' not in members[parent1_id]['Death'] and members[ parent1_id]['Death'] != 'NA': if BirthBeforeDeath.birth_before_death( members[parent1_id]['Death'], members[c]['Birthday']) is False: us9Err = Error.Error(Error.ErrorEnum.US09) us9Err.alterErrMsg(c) errors.add(us9Err) if '??' not in members[parent2_id]['Death'] and members[ parent2_id]['Death'] != 'NA': if BirthBeforeDeath.birth_before_death( members[parent2_id]['Death'], members[c]['Birthday']) is False: us9Err = Error.Error(Error.ErrorEnum.US09) us9Err.alterErrMsg(c) errors.add(us9Err) if '??' in members[parent1_id]['Birthday'] and '??' in members[ parent2_id]['Birthday']: continue else: for c in children: if '??' in members[c]['Birthday']: continue else: if '??' not in members[parent1_id]['Birthday']: if ParentsNotTooOld.parent_age_check( 80, members[parent1_id]['Birthday'], members[c]['Birthday']) is False: us12Err = Error.Error(Error.ErrorEnum.US12) us12Err.alterErrMsg(c, parent1_id) errors.add(us12Err) if '??' not in members[parent2_id]['Birthday']: if ParentsNotTooOld.parent_age_check( 60, members[parent2_id]['Birthday'], members[c]['Birthday']) is False: us12Err = Error.Error(Error.ErrorEnum.US12) us12Err.alterErrMsg(c, parent2_id) errors.add(us12Err) # print(family) # print('\n') # print(members) return {'family': family, 'members': members}
ask = input('> ') ## Main Menu - Create Transaction if ask == str(1): selectionnav1 = False while selectionnav1 == False: print() selection1 = input( 'Is this an Expense or Deposit? \n1 - Expense\n2 - Income\n3 - Return to Previous Menu\n> ' ) ### Menu 1 Sub-Menu 1 - Input Expense if selection1 == str(1): selectionnav1 == True print('Please Input Transaction Information:') print() date = DateValidation() i_merchant = input('Enter Merchant Name > ') i_description = input('Enter Transaction Description > ') i_amount = IsNumber() ### Function to Load the Selection of Expense Categories expense_selection = Categories.ExpenseSelection() InsertToTable(date, i_merchant, i_description, (i_amount * -1), expense_selection, current_user) ### Menu 1 Sub-Menu 2 - Input Income elif selection1 == str(2): selectionnav1 == True print('Please Input Transaction Information:') print() date = DateValidation() i_merchant = input('Enter Merchant Name > ')