Person

Represents an individual with attributes like age, gender, household status, etc.

A person object consists of demographic attributes such as age, sex, household type, and primary status (studying, working or inactive) and a unique identifier. Further, the person object is equipped with relational attributes such as a household identifier, the origin of the building they belong to, a parent identifier and a work location.

Attributes:

Name Type Description
uuid UUID

Unique identifier for the person.

household_uuid Optional[UUID]

Identifier for the person's household.

parent_uuid List[UUID]

Identifiers for the person's parents.

age int

Age of the person.

sex str

Gender of the person.

household_type str

Type of household the person belongs to.

household Optional[Household]

Household instance the person is part of.

has_car bool

Whether the person owns a car.

child_count int

Number of children the person has.

is_head bool

If the person is the head of the household.

is_child bool

If the person is a child in the household.

origin Optional[Point]

Origin of the person.

activity_sequence Optional[ActivitySequence]

Activity sequence associated with the person.

instances list[Person]

Class attribute to track all person instances.

Source code in tripsender\person.py
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
class Person:
    """
    Represents an individual with attributes like age, gender, household status, etc.

    A person object consists of demographic attributes such as age, sex, household type, and primary status (studying, working or inactive) and a unique identifier.
    Further, the person object is equipped with relational attributes such as a household identifier, the origin of the building they belong to, a parent identifier and a work location.

    Attributes:
        uuid (uuid.UUID): Unique identifier for the person.
        household_uuid (Optional[uuid.UUID]): Identifier for the person's household.
        parent_uuid (List[uuid.UUID]): Identifiers for the person's parents.
        age (int): Age of the person.
        sex (str): Gender of the person.
        household_type (str): Type of household the person belongs to.
        household (Optional[Household]): Household instance the person is part of.
        has_car (bool): Whether the person owns a car.
        child_count (int): Number of children the person has.
        is_head (bool): If the person is the head of the household.
        is_child (bool): If the person is a child in the household.
        origin (Optional[Point]): Origin of the person.
        activity_sequence (Optional[ActivitySequence]): Activity sequence associated with the person.
        instances (list[Person]): Class attribute to track all person instances.
    """

    instances: List['Person'] = []
    def __init__(self, age: str, sex: str, household_type: str):
        """Initialize the Person with given attributes."""
        self.uuid: uuid.UUID = uuid.uuid4()
        self.household_uuid: Optional[uuid.UUID] = None 
        self.parent_uuid: List[uuid.UUID] = []
        self.age: int = self.sample_from_bounds(age)
        self.sex: str = sex
        self.household_type: str = household_type  # TODO: Rename to household_status?
        self.household: Optional[Household] = None
        self.has_car: bool = False  # TODO: Check car logic
        self.child_count: int = 0  # TODO: Verify child count logic
        self.is_head: bool = False
        self.is_child: bool = False
        self.origin: Optional[Point] = None
        self.activity_sequence: Optional[ActivitySequence] = None
        self.primary_status: Optional[str] = None
        self.instances.append(self)
        self.age_group = age_group_from_age(self.age)
        self.work_location: Optional[Point] = None
        self.house_type = None
        self.has_child = False
        self.location_mapping = None

    def __repr__(self):
        """Representation of the Person instance."""
        return f"A {self.age} year old {self.sex} with {self.household_type} household status."

    def __str__(self):
        """String representation of the Person instance."""
        sex = "Male" if self.sex =="Män" else "Female"
        return f"A {self.age} year old {sex}."

    def info(self):
        """Retrieve a dictionary containing information about the person."""
        info_dict = {
            "UUID": self.uuid,
            "Household UUID": self.household_uuid,
            "Parent UUID": self.parent_uuid,
            "Age": self.age,
            "Sex": self.sex,
            "Household Type": self.household_type,
            "Household": self.household.uuid if self.household else None,
            "Is Head of household": self.is_head,
            "Has Car": self.has_car,
            "Has Child": self.has_child,
            "Child Count": self.child_count,
            "Origin": self.origin
        }
        return info_dict


    @classmethod
    def clear_instances(cls):
        """Class method to clear all instances stored in the class."""
        cls.instances = []

    @classmethod
    def get_adults(cls):
        """Class method to get all persons above 17 years of age."""
        return [person for person in cls.instances if person.age >= 17]    

    @classmethod
    def return_adults_df(cls):
        """Class method to return a dataframe of all Person instances."""
        adult_df = pd.DataFrame([vars(person) for person in cls.get_adults()])
        # Create a column called Person that contains the Person instance
        adult_df['Person'] = cls.get_adults()
        return adult_df

    @classmethod
    def get_female(cls):
        """Class method to get all female instances of the class."""
        return [person for person in cls.instances if person.sex == "Kvinnor"]

    @classmethod
    def get_male(cls):
        """Class method to get all male instances of the class."""
        return [person for person in cls.instances if person.sex == "Män"]

    @classmethod
    def return_dataframe(cls):
        """Class method to return a dataframe of all Person instances."""
        return pd.DataFrame([vars(person) for person in cls.instances])

    @staticmethod
    def sample_from_bounds(bounds: str) -> int:
        """
        Static method to sample an age from a given range.

        Parameters:
        -----------
        bounds : str
            A string representing the age range (e.g., '20-30').

        Returns:
        --------
        int
            A random age sampled from the given range.
        """
        numbers = re.findall(r'\d+', bounds)
        if not numbers:
            raise ValueError(f"Invalid age bounds: {bounds}")

        lower_bound = int(numbers[0])
        upper_bound = int(numbers[1]) if len(numbers) > 1 else 100

        return np.random.randint(lower_bound, upper_bound + 1)

__init__(age, sex, household_type)

Initialize the Person with given attributes.

Source code in tripsender\person.py
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
def __init__(self, age: str, sex: str, household_type: str):
    """Initialize the Person with given attributes."""
    self.uuid: uuid.UUID = uuid.uuid4()
    self.household_uuid: Optional[uuid.UUID] = None 
    self.parent_uuid: List[uuid.UUID] = []
    self.age: int = self.sample_from_bounds(age)
    self.sex: str = sex
    self.household_type: str = household_type  # TODO: Rename to household_status?
    self.household: Optional[Household] = None
    self.has_car: bool = False  # TODO: Check car logic
    self.child_count: int = 0  # TODO: Verify child count logic
    self.is_head: bool = False
    self.is_child: bool = False
    self.origin: Optional[Point] = None
    self.activity_sequence: Optional[ActivitySequence] = None
    self.primary_status: Optional[str] = None
    self.instances.append(self)
    self.age_group = age_group_from_age(self.age)
    self.work_location: Optional[Point] = None
    self.house_type = None
    self.has_child = False
    self.location_mapping = None

__repr__()

Representation of the Person instance.

Source code in tripsender\person.py
82
83
84
def __repr__(self):
    """Representation of the Person instance."""
    return f"A {self.age} year old {self.sex} with {self.household_type} household status."

__str__()

String representation of the Person instance.

Source code in tripsender\person.py
86
87
88
89
def __str__(self):
    """String representation of the Person instance."""
    sex = "Male" if self.sex =="Män" else "Female"
    return f"A {self.age} year old {sex}."

clear_instances() classmethod

Class method to clear all instances stored in the class.

Source code in tripsender\person.py
110
111
112
113
@classmethod
def clear_instances(cls):
    """Class method to clear all instances stored in the class."""
    cls.instances = []

get_adults() classmethod

Class method to get all persons above 17 years of age.

Source code in tripsender\person.py
115
116
117
118
@classmethod
def get_adults(cls):
    """Class method to get all persons above 17 years of age."""
    return [person for person in cls.instances if person.age >= 17]    

get_female() classmethod

Class method to get all female instances of the class.

Source code in tripsender\person.py
128
129
130
131
@classmethod
def get_female(cls):
    """Class method to get all female instances of the class."""
    return [person for person in cls.instances if person.sex == "Kvinnor"]

get_male() classmethod

Class method to get all male instances of the class.

Source code in tripsender\person.py
133
134
135
136
@classmethod
def get_male(cls):
    """Class method to get all male instances of the class."""
    return [person for person in cls.instances if person.sex == "Män"]

info()

Retrieve a dictionary containing information about the person.

Source code in tripsender\person.py
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
def info(self):
    """Retrieve a dictionary containing information about the person."""
    info_dict = {
        "UUID": self.uuid,
        "Household UUID": self.household_uuid,
        "Parent UUID": self.parent_uuid,
        "Age": self.age,
        "Sex": self.sex,
        "Household Type": self.household_type,
        "Household": self.household.uuid if self.household else None,
        "Is Head of household": self.is_head,
        "Has Car": self.has_car,
        "Has Child": self.has_child,
        "Child Count": self.child_count,
        "Origin": self.origin
    }
    return info_dict

return_adults_df() classmethod

Class method to return a dataframe of all Person instances.

Source code in tripsender\person.py
120
121
122
123
124
125
126
@classmethod
def return_adults_df(cls):
    """Class method to return a dataframe of all Person instances."""
    adult_df = pd.DataFrame([vars(person) for person in cls.get_adults()])
    # Create a column called Person that contains the Person instance
    adult_df['Person'] = cls.get_adults()
    return adult_df

return_dataframe() classmethod

Class method to return a dataframe of all Person instances.

Source code in tripsender\person.py
138
139
140
141
@classmethod
def return_dataframe(cls):
    """Class method to return a dataframe of all Person instances."""
    return pd.DataFrame([vars(person) for person in cls.instances])

sample_from_bounds(bounds) staticmethod

Static method to sample an age from a given range.

Parameters:

bounds : str A string representing the age range (e.g., '20-30').

Returns:

int A random age sampled from the given range.

Source code in tripsender\person.py
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
@staticmethod
def sample_from_bounds(bounds: str) -> int:
    """
    Static method to sample an age from a given range.

    Parameters:
    -----------
    bounds : str
        A string representing the age range (e.g., '20-30').

    Returns:
    --------
    int
        A random age sampled from the given range.
    """
    numbers = re.findall(r'\d+', bounds)
    if not numbers:
        raise ValueError(f"Invalid age bounds: {bounds}")

    lower_bound = int(numbers[0])
    upper_bound = int(numbers[1]) if len(numbers) > 1 else 100

    return np.random.randint(lower_bound, upper_bound + 1)