Skip to content

Commit

Permalink
Added US22 and 23, also added a sort to the print for errors method
Browse files Browse the repository at this point in the history
The sort just makes it so we do not have to call the user stories in order in the future.
  • Loading branch information
Mike-Alecci committed Oct 18, 2018
1 parent 49b70ce commit b669e00
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 6 deletions.
13 changes: 13 additions & 0 deletions Bad_GEDCOM_test_data.ged
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,7 @@
1 BIRT
2 DATE 9 SEP 1994
1 FAMS @F17@
0 @I52@ INDI
0 @I53@ INDI
1 NAME Marsha /Tolen/
1 SEX F
Expand Down Expand Up @@ -414,12 +415,24 @@
2 DATE 1 JAN 1961
1 FAMC @F20@
1 FAMS @F21@
0 NOTE US23 the following two individuals have the same names and birthdays as the previous two individuals
0 @I66@ INDI
1 NAME Ava /Leffe/
1 SEX F
1 BIRT
2 DATE 1 JAN 1961
0 @I67@ INDI
1 NAME Allen /Leffe/
1 SEX M
1 BIRT
2 DATE 10 MAR 1961
0 NOTE -----------------Start of the Families-------------------
0 @F1@ FAM
1 HUSB @I1@
1 WIFE @I2@
1 MARR
2 DATE 2 APR 1993
0 @F1@ FAM
0 @F2@ FAM
1 HUSB @I3@
1 WIFE @I4@
Expand Down
29 changes: 23 additions & 6 deletions GedcomProject.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,13 @@ def __init__(self, file_name, create_tables = True, print_errors = True):
self.file_name = file_name
self.family = dict() #dictionary with Key = FamID Value = Family class object
self.individuals = dict() #dictionary with Key = IndiID Value = Individual class object
self.errors = []
self.fam_table = PrettyTable(field_names = ["ID", "Married", "Divorced", "Husband ID", "Husband Name", "Wife ID", "Wife Name", "Children"])
self.indi_table = PrettyTable(field_names = ["ID", "Name", "Gender", "Birthday", "Age", "Alive", "Death", "Child", "Spouse"])
self.analyze()
if create_tables: #allows to easily toggle the print of the pretty table on and off
self.create_pretty_tables()
self.all_errors = CheckForErrors(self.individuals, self.family, print_errors).all_errors
self.all_errors = CheckForErrors(self.individuals, self.family, self.errors, print_errors).all_errors

def analyze(self):
"""This method reads in each line and determines if a new family or individual need to be made, if not then it sends the line
Expand All @@ -28,12 +29,18 @@ def analyze(self):
elif line[0] == '0' and line [2] == "INDI":
current_type = 1 #Marker used to ensure following lines are analyzed as individual
indiv = line[1].replace("@", "") #The GEDCOM file from online has @ID@ format, this replaces it
self.individuals[indiv] = Individual() #The instance of a Individual class object is created
if indiv in self.individuals.keys(): #If there is a duplicate ID report it
self.errors += ["US22: The individual ID: {}, already exists, this ID is not unique".format(indiv)]
else:
self.individuals[indiv] = Individual() #The instance of a Individual class object is created
continue
elif line[0] == '0' and line[2] == "FAM":
current_type = 2 #Marker used to ensure following lines are analyzed as family
fam = line[1].replace("@", "")
self.family[fam] = Family() #The instance of a Family class object is created
if fam in self.family.keys(): #If there is a duplicate ID report it
self.errors += ["US22: The family ID: {}, already exists, this ID is not unique".format(fam)]
else:
self.family[fam] = Family() #The instance of a Family class object is created
continue
if current_type in [1,2]: #No new Individual or Family was created, analyze line further
self.analyze_info(line, previous_line, indiv, fam, current_type)
Expand Down Expand Up @@ -143,12 +150,12 @@ def update_age(self):

class CheckForErrors:
"""This class runs through all the user stories and looks for possible errors in the GEDCOM data"""
def __init__(self, ind_dict, fam_dict, print_errors):
def __init__(self, ind_dict, fam_dict, errors, print_errors):
"""This instantiates variables in this class to the dictionaries of families and individuals from
the AnalyzeGEDCOM class, it also calls all US methods while providing an option to print all errors"""
self.individuals = ind_dict
self.family = fam_dict
self.all_errors = list()
self.all_errors = errors
self.dates_before_curr() #US01
self.indi_birth_before_marriage() #US02
self.birth_before_death() #US03
Expand All @@ -164,6 +171,7 @@ def __init__(self, ind_dict, fam_dict, print_errors):
self.too_many_births()
self.too_many_siblings() #US15
self.no_marriage_to_descendants()
self.unique_names_and_bdays() #US23

if print_errors == True:
self.print_errors()
Expand Down Expand Up @@ -405,6 +413,15 @@ def no_marriage_to_descendants(self):
for child in self.family[fam].chil:
self.descendants_help(person,self.individuals[child])

def unique_names_and_bdays(self):
"""US23: Tests to ensure there are no individuals with the same name and birthdate"""
names_and_bdays = []
for person in self.individuals.values():
if (person.name, person.birt) in names_and_bdays:
self.all_errors += ["US23: An idividual with the name: {}, and birthday: {}, already exists!".format(person.name, person.birt)]
else:
names_and_bdays += [(person.name, person.birt)]

def add_errors_if_new(self, error):
"""This method is here to add errors to the error list if they do not occur, in order to ensure no duplicates.
Some user stories may flag duplicate errors and this method eliminates the issue."""
Expand All @@ -416,7 +433,7 @@ def print_errors(self):
if len(self.all_errors) == 0:
print("Congratulations this GEDCOM file has no known errors!")
else:
for error in self.all_errors:
for error in sorted(self.all_errors):
print(error)

def main():
Expand Down
14 changes: 14 additions & 0 deletions Unit_Test_Proj.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,5 +145,19 @@ def test_no_marriage_to_descendents(self):
for error in list_of_known_errors:
self.assertIn(error, self.all_errors)

def test_unique_ids(self):
"""US22: Tests to ensure that all IDS are unique"""
list_of_known_errors = ["US22: The individual ID: I52, already exists, this ID is not unique",
"US22: The family ID: F1, already exists, this ID is not unique"]
for error in list_of_known_errors:
self.assertIn(error, self.all_errors)

def test_unique_names_and_bdays(self):
"""US23: Tests to ensure there are no individuals with the same name and birthdate"""
list_of_known_errors = ["US23: An idividual with the name: Ava /Leffe/, and birthday: 1961-01-01, already exists!",
"US23: An idividual with the name: Allen /Leffe/, and birthday: 1961-03-10, already exists!"]
for error in list_of_known_errors:
self.assertIn(error, self.all_errors)

if __name__ == '__main__':
unittest.main(exit=False, verbosity=2)

0 comments on commit b669e00

Please sign in to comment.