Commit 5ea24a8b authored by Temujin's avatar Temujin

rewrote family tree and person classes

parent 1d86bec5
"""Family Tree project for CSCI 30.""" """Family Tree project for CSCI 30."""
"""
TODO:
Don't initialize with root.
Find a way to get root afterwards.
Find a way to get isolated nodes.
current structure:
bin tree inside a dict
Problems to consider --
What to do if not rooted?
Multiple roots?
What if the file describes two separate trees at once?
Handling value errors.
Incest and cycles:
> Adding someone already in the tree as a child
Problems taken care of(?) --
Adding child to someone who already has two children.
Questions:
How does a dict compare object keys?
How to deal with multiple trees?
Is there only one root?
Total nodes of the tree?
11 generations = 2^11 - 1
KEY = NAME????
MAKE THE KEY ONLY THE PERSON'S NAME
MAKE HELPER FUNC
REWRITE EVERYTHING
How do class variables work?
"""
class FamilyTree: class FamilyTree:
"""A family tree. """A family tree.
Family Tree dict format -- Family Tree dict format --
key = person key = name of the person
value = [name of child1, name of child2, name of parent] value = a Person object
""" """
""" def __init__(self):
TODO: """Initialize the family tree."""
Don't initialize with root. self.family_tree = dict()
Find a way to get root afterwards. self.root = None
Find a way to get isolated nodes.
Problems to consider --
What to do if not rooted?
Multiple roots?
What if the file describes two separate trees at once?
Handling value errors.
Incest and cycles:
> Adding someone already in the tree as a child
Problems taken care of(?) -- def find_root(self):
Adding child to someone who already has two children. """Find the root of the tree.
Questions: note: work in progress
How does a dict compare object keys? Start from arbitrary node,
How to deal with multiple trees? then move upwards. (doesn't check for multiple roots)
Is there only one root?
or ?????
go through every object in the dictionary
and check if it has a parent (slow)
""" """
return
def __init__(self, root): def set_root(self, person):
"""Initialize the family tree. """Set the root node."""
self.root = person.get_name()
root: the name of the first generation person. def insert_person(self, person):
""" """Add a Person object to the dict with the name as the key."""
self.family_tree = dict() self.family_tree[person.get_name()] = person
self.root = root
self.family_tree[root] = [None, None, None] def get_person(self, name):
"""Get the named Person object from the dict."""
def insert_person(self, person, parent): return self.family_tree[name]
"""Add a person as a child to some parent."""
try:
parent_list = self.family_tree[parent]
except KeyError:
raise KeyError("Error: The parent is not in the tree.")
if parent_list[1] is None:
parent_list[1] = person
parent_list[person] = [None, None, parent]
elif parent_list[2] is None:
parent_list[2] = person
parent_list[person] = [None, None, parent]
else:
raise ValueError("Error: That parent already has two children.")
def get_ancestors(self, name): def get_ancestors(self, name):
"""Return a list of all the ancestors of a person.""" """Return a sorted list of the person's ancestors."""
person = self.family_tree[name]
parent = person.get_parent()
ancestors = [] ancestors = []
parent = self.family_tree[name][2]
while parent is not None: while parent is not None:
ancestors += parent ancestors.append(parent.get_name())
parent = self.family_tree[parent][2] parent = parent.get_parent()
ancestors.sort()
return ancestors return ancestors
def get_descendants(self, name): def get_descendants(self, name):
"""Return a list of a person's descendants.""" """Return a sorted list of a person's descendants."""
def get_preorder(person):
"""Get the inorder traversal given a person as the root."""
res = []
if person is not None:
lc, rc = person.get_children()
res.append(person.get_name())
res += get_preorder(lc)
res += get_preorder(rc)
return res
descendants = get_preorder(self.family_tree[name])[1:]
descendants.sort()
return descendants
def __str__(self):
"""Return the name."""
return self.name
class Person: class Person:
"""A person. """The nodes of the family tree.
Attributes -- Attributes --
Name: a string indicating the name name: a string indicating the name
Age: a integer indicating the age age: an integer indicating the age
Sex: a boolean, male = True, female = False sex: a boolean; male = True, female = False
children: a list of the children
parent: the parent
""" """
def __init__(self, name, age, sex): def __init__(self, name, age, sex):
"""Initialize the Person class.""" """Initialize the Person object."""
self.name = name self.name = name
self.age = age self.age = age
self.sex = sex self.sex = sex
self.children = [None, None]
self.parent = None
def set_parent(self, parent):
"""Set parent.
Also sets the current node as the parent's child.
"""
self.parent = parent
self.parent.add_child(self)
def get_parent(self):
"""Get parent."""
return self.parent
def add_child(self, child):
"""Add a child.
If there are already 2 children, raises error.
"""
if self.children[0] is None:
self.children[0] = child
elif self.children[1] is None:
self.children[1] = child
else:
raise Exception("This node already has two children.")
def get_children(self):
"""Return a list of the children."""
return self.children
def set_name(self, name): def set_name(self, name):
"""Set name.""" """Set name."""
...@@ -109,3 +180,18 @@ class Person: ...@@ -109,3 +180,18 @@ class Person:
def get_sex(self): def get_sex(self):
"""Get sex (bool).""" """Get sex (bool)."""
return self.sex return self.sex
if __name__ == "__main__":
ftree = FamilyTree()
A = Person("A", 69, True)
B = Person("B", 69, True)
C = Person("C", 69, True)
B.set_parent(A)
C.set_parent(A)
ftree.insert_person(A)
ftree.insert_person(B)
ftree.insert_person(C)
ftree.set_root(A)
print(ftree.get_ancestors(C.get_name()))
print(ftree.get_descendants(A.get_name()))
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment