def expand_relationship(self, relative): distances = self._ancestor_distances() relative_distances = relative._ancestor_distances() if self in relative_distances: root = self elif relative in distances: root = relative else: (root, _, _) = closest_common_ancestor(distances, relative_distances) ancestors = [] person = root while person != self: ancestors.append(person) for child in person.children(): if child == self or child in distances: person = child break ancestors.append(person) relative_ancestors = [] person = root while person != relative: relative_ancestors.append(person) for child in person.children(): if child == relative or child in relative_distances: person = child break relative_ancestors.append(person) return (ancestors, relative_ancestors)
def annotated_relatives(self): '''Returns a list of all of this person's blood relatives. The first item in each tuple is the person, the second is the relationship, and the third is the distance between the two individuals.''' ancestor_distances = self._ancestor_distances() distances = ancestor_distances.copy() distances.update(self._descendant_distances()) annotated = [] for relative in self.relatives(): distance = distances.get(relative, None) relative_distances = relative._ancestor_distances() if not distance: (_, d1, d2) = closest_common_ancestor(ancestor_distances, relative_distances) distance = max(d1, d2) relationship = describe_relative(self, relative, ancestor_distances, relative_distances) annotated.append((relative, relationship, distance)) annotated.sort(key=lambda x: (x[2], x[1], x[0].surname)) return annotated