# person.py # Walker M. White (wmw2) # October 15, 2015 """Class to rerpresent a genealogical tree""" import sys # Allow us to go really deep sys.setrecursionlimit(999999999) # We will cover this NEXT lecture class Person(object): """Instance represents a person in a genealogical tree. Attributes: fname: First Name [str] lname: Last Name [str] parent1: First parent [Person, None if not known] parent2: Second parent [Person, None if not known]""" def __init__(self,fname,lname,parent1=None,parent2=None): """Creates a new instance of person Parameter fname: The first name Precondition: fname is a string Parameter lname: The last name Precondition: lname is a string Parameter parent1: The first parent of this person (optional) Precondition: parent1 is a Person or None Parameter parent2: The second parent of this person (optional) Precondition: parent2 is a Person or None""" self.fname = fname self.lname = lname self.parent1 = parent1 self.parent2 = parent2 def __str__(self): """Returns: a string representation of this person""" result = '(Person: '+self.name() if not self.parent1 is None: result += '; parent1: '+self.parent1.name() if not self.parent2 is None: result += '; parent2: '+self.parent2.name() return result+')' def __repr__(self): """Returns: an unambigious string representation of this person""" return str(self) def name(self): """Returns: the full name of this person""" return self.fname+' '+self.lname # Recursive functions def num_ancestors(p): """Returns: number of known ancestors of p Does not include p, so the answer might be 0. Parameter p: The initial family member Precondition: p is a Person (and not None)""" # base case # break up data ancestors = 0 if p.parent1 != None: ancestors = 1 + num_ancestors(p.parent1) if p.parent2 != None: ancestors = ancestors + 1 + num_ancestors(p.parent2) # combine return ancestors def all_ancestors(p): # break up data ancestors = [] if p.parent1 != None: ancestors.append(p.parent1) ancestors = ancestors + all_ancestors(p.parent1) if p.parent2 != None: ancestors.append(p.parent2) ancestors = ancestors + all_ancestors(p.parent2) # combine return ancestors def greatest_grandparent_at(p, generation): if p.parent1 == None and p.parent2 == None: return (p, generation) if p.parent1 != None: parent1s = greatest_grandparent_at(p.parent1, generation+1) if p.parent2 != None: parent2s = greatest_grandparent_at(p.parent2, generation+1) if p.parent1 == None: return parent2s elif p.parent2 == None: return parent1s if parent2s[1] > parent1s[1]: return parent2s else: return parent1s def greatest_grandparent(p): return greatest_grandparent_at(p, 1)