# person_step10.py
#
# ICS 33 Spring 2026
# Code Example
#
# This version of the Person class requires keyword arguments when its objects
# are constructed.  It also adds type annotations to its methods where
# appropriate.

from datetime import date


class Person:

    # The * in the signature is how we enforce that name and birthdate are
    # keyword-only parameters.
    def __init__(self, *, name: str, birthdate: date):
        self._name = name
        self._birthdate = birthdate


    # Nothing else about the class has changed, except for the addition of
    # type annotations.


    @property
    def name(self) -> str:
        return self._name


    @property
    def birthdate(self) -> date:
        return self._birthdate


    def __eq__(self, other) -> bool:
        return isinstance(other, Person) and \
               (self.name, self.birthdate) == (other.name == other.birthdate)


    def __hash__(self) -> int:
        return hash((self.name, self.birthdate))


    def age(self, as_of_date: date) -> int:
        if self.birthdate > as_of_date:
            raise ValueError(f'Person was not born yet on {as_of_date}')

        years_old = as_of_date.year - self.birthdate.year

        if (self.birthdate.month, self.birthdate.day) >= (as_of_date.month, as_of_date.day):
            years_old -= 1

        return years_old
