Commit c338ce4d authored by Temujin's avatar Temujin

finished some familytree functions

parent 5ea24a8b
...@@ -2,12 +2,10 @@ ...@@ -2,12 +2,10 @@
""" """
TODO: TODO:
Don't initialize with root.
Find a way to get root afterwards.
Find a way to get isolated nodes. Find a way to get isolated nodes.
current structure: current structure:
bin tree inside a dict bin tree, nodes in a dict
Problems to consider -- Problems to consider --
...@@ -22,30 +20,24 @@ Problems taken care of(?) -- ...@@ -22,30 +20,24 @@ Problems taken care of(?) --
Adding child to someone who already has two children. Adding child to someone who already has two children.
Questions: Questions:
How does a dict compare object keys?
How to deal with multiple trees?
Is there only one root? Is there only one root?
Total nodes of the tree? Total nodes of the tree?
11 generations = 2^11 - 1 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.
Attributes --
family_tree: a dict containing the nodes of the familytree
root: the root of the tree
Family Tree dict format -- Family Tree dict format --
key = name of the person key = name of the person
value = a Person object value = a Person object, acting as the node
""" """
def __init__(self): def __init__(self):
...@@ -56,19 +48,19 @@ class FamilyTree: ...@@ -56,19 +48,19 @@ class FamilyTree:
def find_root(self): def find_root(self):
"""Find the root of the tree. """Find the root of the tree.
note: work in progress Start from arbitrary node, then move upwards.
Start from arbitrary node,
then move upwards. (doesn't check for multiple roots)
or ?????
go through every object in the dictionary Note: Will not work if there's more than one node without a parent
and check if it has a parent (slow)
""" """
return arbitrary_node = next(iter(self.family_tree.values()))
while arbitrary_node.get_parent() is not None:
arbitrary_node = arbitrary_node.get_parent()
self.root = arbitrary_node
def set_root(self, person): def set_root(self, person):
"""Set the root node.""" """Set the root node manually."""
self.root = person.get_name() self.root = person.get_name()
def insert_person(self, person): def insert_person(self, person):
...@@ -91,23 +83,46 @@ class FamilyTree: ...@@ -91,23 +83,46 @@ class FamilyTree:
def get_descendants(self, name): def get_descendants(self, name):
"""Return a sorted list of a person's descendants.""" """Return a sorted list of a person's descendants."""
def get_preorder(person): def get_postorder(person):
"""Get the inorder traversal given a person as the root.""" """Get the postorder traversal given the root node."""
res = [] res = []
if person is not None: if person is not None:
lc, rc = person.get_children() lc, rc = person.get_children()
res += get_postorder(lc)
res += get_postorder(rc)
res.append(person.get_name()) res.append(person.get_name())
res += get_preorder(lc)
res += get_preorder(rc)
return res return res
descendants = get_preorder(self.family_tree[name])[1:] descendants = get_postorder(self.family_tree[name])
descendants.pop()
descendants.sort() descendants.sort()
return descendants return descendants
def __str__(self): def compute_generations(self):
"""Return the name.""" """DFS to find and set the generation of each node."""
return self.name if self.root is None:
self.find_root()
# TODO
return
def slow_find_lca(self, a, b):
"""Find the lca slowly.
two pointer method
"""
return
def fast_find_lca(self, a, b):
"""Find the lca fast.
Reduction to range min. query
"""
return
def dfs(A):
"""Depth first search."""
pass
class Person: class Person:
...@@ -117,8 +132,9 @@ class Person: ...@@ -117,8 +132,9 @@ class Person:
name: a string indicating the name name: a string indicating the name
age: an 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 children: a list of the children nodes
parent: the parent parent: the parent node
generation: an integer indicating the generation (level)
""" """
def __init__(self, name, age, sex): def __init__(self, name, age, sex):
...@@ -128,6 +144,7 @@ class Person: ...@@ -128,6 +144,7 @@ class Person:
self.sex = sex self.sex = sex
self.children = [None, None] self.children = [None, None]
self.parent = None self.parent = None
self.generation = None
def set_parent(self, parent): def set_parent(self, parent):
"""Set parent. """Set parent.
...@@ -157,6 +174,10 @@ class Person: ...@@ -157,6 +174,10 @@ class Person:
"""Return a list of the children.""" """Return a list of the children."""
return self.children return self.children
def get_name(self):
"""Get name."""
return self.name
def set_name(self, name): def set_name(self, name):
"""Set name.""" """Set name."""
self.name = name self.name = name
...@@ -165,24 +186,33 @@ class Person: ...@@ -165,24 +186,33 @@ class Person:
"""Set age.""" """Set age."""
self.age = age self.age = age
def set_sex(self, sex):
"""Set sex (bool)."""
self.sex = sex
def get_name(self):
"""Get name."""
return self.name
def get_age(self): def get_age(self):
"""Get age.""" """Get age."""
return self.age return self.age
def set_sex(self, sex):
"""Set sex (bool)."""
self.sex = sex
def get_sex(self): def get_sex(self):
"""Get sex (bool).""" """Get sex (bool)."""
return self.sex return self.sex
def get_generation(self):
"""Get generation."""
return self.generation
if __name__ == "__main__": def set_generation(self, generation):
"""Set generation."""
self.generation = generation
def __str__(self):
"""Return the name."""
return self.name
def main():
"""For testing."""
ftree = FamilyTree() ftree = FamilyTree()
A = Person("A", 69, True) A = Person("A", 69, True)
B = Person("B", 69, True) B = Person("B", 69, True)
...@@ -192,6 +222,13 @@ if __name__ == "__main__": ...@@ -192,6 +222,13 @@ if __name__ == "__main__":
ftree.insert_person(A) ftree.insert_person(A)
ftree.insert_person(B) ftree.insert_person(B)
ftree.insert_person(C) ftree.insert_person(C)
ftree.set_root(A) ftree.find_root()
print(ftree.get_ancestors(C.get_name())) ancestors = ftree.get_ancestors(C.get_name())
print(ftree.get_descendants(A.get_name())) descendants = ftree.get_descendants(A.get_name())
print("The root of the tree is {}.".format(ftree.root))
print("ancestors of {}: {}".format("C", ancestors))
print("descendants of {}: {}".format("A", descendants))
if __name__ == "__main__":
main()
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