def test_finalise(): plan = Plan() act = Activity(1, 'home', 1, start_time=mtdt(0)) plan.add(act) leg = Leg(1, 'car', start_area=1, end_area=2, start_time=mtdt(900), end_time=mtdt(930)) plan.add(leg) act = Activity(2, 'work', 1, start_time=mtdt(930)) plan.add(act) plan.finalise() assert plan.day[0].end_time == mtdt(900) assert plan.day[-1].end_time == END_OF_DAY
def test_duration(): plan = Plan() act = Activity(1, 'home', 1, start_time=mtdt(0)) plan.add(act) leg = Leg(1, 'car', start_area=1, end_area=2, start_time=mtdt(900), end_time=mtdt(930)) plan.add(leg) act = Activity(2, 'work', 1, start_time=mtdt(930)) plan.add(act) plan.finalise() assert plan.day[0].duration == timedelta(minutes=900) assert plan.day[1].duration == timedelta(minutes=30) assert plan.day[-1].duration == timedelta(seconds=(24*60-930)*60)
class Person: logger = logging.getLogger(__name__) def __init__(self, pid, freq=1, attributes=None, home_area=None): self.pid = str(pid) self.freq = freq self.attributes = attributes self.plan = Plan(home_area=home_area) self.home_area = home_area @property def home(self): if self.plan: return self.plan.home @property def activities(self): if self.plan: for act in self.plan.activities: yield act @property def legs(self): if self.plan: for leg in self.plan.legs: yield leg @property def length(self): return len(self.plan) def __len__(self): return self.length def __getitem__(self, val): return self.plan[val] def __iter__(self): for component in self.plan: yield component @property def has_valid_plan(self): """ Check sequence of Activities and Legs. :return: True """ return self.plan.is_valid @property def closed_plan(self): """ Check if plan starts and stops at the same facility (based on activity and location) :return: Bool """ return self.plan.closed @property def first_activity(self): return self.plan.first @property def home_based(self): return self.plan.home_based def add(self, p): """ Safely add a new component to the plan. :param p: :return: """ self.plan.add(p) def finalise(self): """ Add activity end times based on start time of next activity. """ self.plan.finalise() def clear_plan(self): self.plan.clear() def print(self): print(self) print(self.attributes) self.plan.print() def plot(self): plot_person(self) def __str__(self): return f"Person: {self.pid}" def remove_activity(self, seq): """ Remove an activity from plan at given seq. Check for wrapped removal. Return (adjusted) idx of previous and subsequent activities as a tuple :param seq: :return: tuple """ return self.plan.remove_activity(seq) def move_activity(self, seq, default='home'): """ Move an activity from plan at given seq to default location :param seq: :param default: 'home' or pam.activity.Location :return: None """ return self.plan.move_activity(seq, default) def fill_plan(self, p_idx, s_idx, default='home'): """ Fill a plan after Activity has been removed. :param p_idx: location of previous Activity :param s_idx: location of subsequent Activity :param default: :return: bool """ return self.plan.fill_plan(p_idx, s_idx, default=default) def stay_at_home(self): self.plan.stay_at_home() def pickle(self, path): with open(path, 'wb') as file: pickle.dump(self, file)