File size: 4,336 Bytes
8f3b56b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
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
import json
import os
import pickle as pkl
from collections import defaultdict


def schedule_to_str(schedule, show_at_home=False):
    schedule_str = ''
    for event in schedule:
        schedule_str += f'Activity: {event["activity"]}, start_time: {event["start_time"].strftime("%H:%M")}, ' \
                        f'end_time: {event["end_time"].strftime("%H:%M")}'
        if show_at_home:
            schedule_str += f', at_home: {str(event["at_home"])}'
        schedule_str += '\n'
    return schedule_str


class Person:
    def __init__(self, persona):
        meta_data = persona
        self.meta_data = persona
        self.family = None
        self.family_info = None
        self.event_base = None
        self.primary_activity_set = set()
        self.activity_alias = dict()
        # activity_set = full name list, including aliases
        # However, event base only include primary keys, i.e., len(activity_set) >= len(event_base)
        self.schedules = defaultdict(dict)
        self.general_plans = defaultdict(dict)

        self.name = meta_data['name']
        self.first_name = meta_data['name'].split(' ')[0]
        self.age = meta_data['age']
        self.gender = meta_data.get('gender', 'Unknown')
        self.routine = meta_data['routine']

        self.personality = meta_data['personality']
        self.occupation = meta_data['occupation']
        self.thoughts = meta_data['thoughts']
        self.lifestyle = meta_data['lifestyle']

        self.default_keys = ['Name', 'Age', 'Gender', 'Routine', 'Family Info', 'Personality', 'Occupation', 'Thoughts',
                             'Lifestyle']
        self.public_keys = ['Name', 'Age', 'Gender', 'Routine', 'Family Info']

        self.init_event_base()

    def set_family(self, family, family_info=None):
        self.family = family
        self.family_info = family_info

    def init_event_base(self):
        '''
        Event base is a hierarchical dict.
            activity: room: {
                'room_prob': prob,
                'object_effect': [
                    object: {
                        'object_prob': prob,
                        'receptacles': [[receptacle, prob]]
                    }
                ]
            }
        '''
        self.event_base = defaultdict(dict)

    def update_event(self, event_base):
        self.event_base.update(event_base)
        self.primary_activity_set.update(set(self.event_base.keys()))

    def filter_event(self, events):
        # find out events that are not analysed
        new_events = [e for e in events if e not in self.event_base and e not in self.activity_alias]
        return new_events

    def update_schedule(self, schedule, date, schedule_key='default'):
        self.schedules[schedule_key][date] = schedule.copy()

    def update_general_plan(self, general_plan, date, schedule_key='default'):
        self.general_plans[schedule_key][date] = general_plan.copy()

    def update_alias(self, alias_pairs, verbose=False):
        # new activities join primary_activity_set, then will be filtered out to gen prob,
        # then into event base, then done as a primary key
        # when outside code try to merge, should use primary_activity_set as reference
        for new_act, old_act in alias_pairs.items():
            if old_act is not None and old_act != new_act:
                # self.activity_alias[old_act].add(new_act)
                self.activity_alias[new_act] = old_act
            else:
                self.primary_activity_set.add(new_act)
                if old_act is None and verbose:
                    print(f"New activity: {new_act}")

        return self.activity_alias

    def get_public_information(self):
        return self.get_all_information(self.public_keys)

    def get_all_information(self, keys=None):
        if keys is None:
            keys = self.default_keys
        person_info = ''
        for key in keys:
            if self.family is None and key == 'Family Info':
                continue
            person_info += f'{key}: {eval("self." + key.lower().replace(" ", "_"))}\n'

        return person_info

    def get_character_dict(self):
        res = {
            'event_base':self.event_base,
            'persona':self.meta_data,
            'schedule':self.schedules
        }
        return res