Skip to content

Commit 77ca48e

Browse files
committed
update family tree thing
1 parent cef05e8 commit 77ca48e

File tree

2 files changed

+83
-22
lines changed

2 files changed

+83
-22
lines changed

task_4.py

+23-22
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
"""Task 4: Practice with recursion."""
2+
import datetime
23
from pathlib import Path
34
from typing import Callable, Dict, Optional, Set
45

@@ -8,8 +9,9 @@
89
# --- models for family data
910

1011

11-
class Individual(pydantic.BaseModel):
12-
"""An individual model.
12+
class Individual(pydantic.BaseModel, frozen=True):
13+
"""
14+
A model of an individual.
1315
1416
Parents, children, and spouses are keys to other
1517
individual ids.
@@ -25,18 +27,16 @@ class Individual(pydantic.BaseModel):
2527
children: Set[str] = set()
2628
spouses: Set[str] = set()
2729

28-
@classmethod
29-
def from_element(cls, el):
30-
"""Populate Family from element."""
31-
data = dict(
32-
id=el.get_pointer(),
33-
name=" ".join(el.get_name()),
34-
surname=el.get_name()[-1],
35-
gender=el.get_gender(),
36-
birth_year=el.get_birth_year(),
37-
death_year=el.get_death_year(),
38-
)
39-
return cls(**data)
30+
@property
31+
def age(self) -> Optional[int]:
32+
"""Return the estimated age of the person."""
33+
birth_year = self.birth_year
34+
if birth_year is None or birth_year < 0:
35+
raise ValueError(f"Unknown Age of {self.name}: {self.id}")
36+
end_year = self.death_year
37+
if end_year is None or end_year < 0:
38+
end_year = datetime.datetime.now().year
39+
return end_year - birth_year
4040

4141

4242
class Group(pydantic.BaseModel):
@@ -56,17 +56,17 @@ def load_data(path=None):
5656

5757

5858
def count_people(
59-
person: Individual,
59+
individual: Individual,
6060
group: Group,
61-
direction: Literal["children", "parents"] = "children",
61+
direction: Literal["children", "parents"] = "parents",
6262
predicate: Callable[[Individual], bool] = lambda x: True,
63-
):
63+
) -> int:
6464
"""
6565
Count people in an individuals family tree which meet some requirement.
6666
6767
Parameters
6868
----------
69-
person
69+
individual
7070
The person with which to start.
7171
group
7272
The group to which the person belongs.
@@ -83,8 +83,9 @@ def count_people(
8383
>>> # Count direct descendants with more than two children.
8484
>>> person = data[random.choice(list(data))]
8585
>>> count = count_people(person, predicate=lambda x: len(x.children) > 2)
86-
"""
8786
88-
89-
if __name__ == "__main__":
90-
data = load_data()
87+
Notes
88+
-----
89+
This function will also count the initial individual if they pass the
90+
predicate.
91+
"""

test_task_4.py

+60
Original file line numberDiff line numberDiff line change
@@ -1 +1,61 @@
11
"""Tests for task 4's recursive tasks."""
2+
3+
import pytest
4+
5+
import task_4 as t4
6+
7+
8+
@pytest.fixture(scope="session")
9+
def group():
10+
"""Load family data."""
11+
return t4.load_data()
12+
13+
14+
@pytest.fixture(scope="session")
15+
def obama(group):
16+
"""Return Barack Obama from Group. Thanks Obama..."""
17+
return group["@I2194@"]
18+
19+
20+
@pytest.fixture(scope="session")
21+
def lincoln(group):
22+
"""Get ol' Honest Abe."""
23+
return group["@I317@"]
24+
25+
26+
class TestCountPeople:
27+
"""Tests for counting people."""
28+
29+
def test_count_obama_ancestors(self, group, obama):
30+
"""Ensure we can count a person's known ancestors with default params."""
31+
out = t4.count_people(obama, group)
32+
# In this test data, there are 5 known ancestors of Barack Obama.
33+
assert out == 5
34+
35+
def test_count_childless_parents(self, group, lincoln):
36+
"""Check that a persons parents all have children (predicate check)."""
37+
out = t4.count_people(
38+
lincoln,
39+
group,
40+
direction="parents",
41+
predicate=lambda x: len(x.children) == 0,
42+
)
43+
assert out == 0
44+
45+
def test_lincoln_old_ancestors(self, group, lincoln):
46+
"""Check the number of old ancestors Lincoln had."""
47+
48+
def is_old(person):
49+
try:
50+
return person.age > 70
51+
except ValueError:
52+
return False
53+
54+
out = t4.count_people(
55+
lincoln,
56+
group,
57+
direction="parents",
58+
predicate=is_old,
59+
)
60+
# There are 18 people older than 70 in Lincoln's tree.
61+
assert out == 18

0 commit comments

Comments
 (0)