1
1
"""Task 4: Practice with recursion."""
2
+ import datetime
2
3
from pathlib import Path
3
4
from typing import Callable , Dict , Optional , Set
4
5
8
9
# --- models for family data
9
10
10
11
11
- class Individual (pydantic .BaseModel ):
12
- """An individual model.
12
+ class Individual (pydantic .BaseModel , frozen = True ):
13
+ """
14
+ A model of an individual.
13
15
14
16
Parents, children, and spouses are keys to other
15
17
individual ids.
@@ -25,18 +27,16 @@ class Individual(pydantic.BaseModel):
25
27
children : Set [str ] = set ()
26
28
spouses : Set [str ] = set ()
27
29
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
40
40
41
41
42
42
class Group (pydantic .BaseModel ):
@@ -56,17 +56,17 @@ def load_data(path=None):
56
56
57
57
58
58
def count_people (
59
- person : Individual ,
59
+ individual : Individual ,
60
60
group : Group ,
61
- direction : Literal ["children" , "parents" ] = "children " ,
61
+ direction : Literal ["children" , "parents" ] = "parents " ,
62
62
predicate : Callable [[Individual ], bool ] = lambda x : True ,
63
- ):
63
+ ) -> int :
64
64
"""
65
65
Count people in an individuals family tree which meet some requirement.
66
66
67
67
Parameters
68
68
----------
69
- person
69
+ individual
70
70
The person with which to start.
71
71
group
72
72
The group to which the person belongs.
@@ -83,8 +83,9 @@ def count_people(
83
83
>>> # Count direct descendants with more than two children.
84
84
>>> person = data[random.choice(list(data))]
85
85
>>> count = count_people(person, predicate=lambda x: len(x.children) > 2)
86
- """
87
86
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
+ """
0 commit comments