예제 #1
0
def test_person_add_leg():
    plan = Plan()
    act = Activity(1, 'home', 1)
    plan.add(act)
    leg = Leg(1, 'car', start_area=1, end_area=2)
    plan.add(leg)
    assert len(plan.day) == 2
예제 #2
0
def test_plan():
    plan = Plan()
    plan.add(
        Activity(seq=1,
                 act='home',
                 area='a',
                 start_time=mtdt(0),
                 end_time=mtdt(180)))
    plan.add(
        Leg(seq=1,
            mode='car',
            start_area='a',
            end_area='b',
            start_time=mtdt(180),
            end_time=mtdt(190)))
    plan.add(
        Activity(seq=2,
                 act='work',
                 area='b',
                 start_time=mtdt(190),
                 end_time=mtdt(200)))
    plan.add(
        Leg(seq=1,
            mode='car',
            start_area='b',
            end_area='a',
            start_time=mtdt(200),
            end_time=mtdt(390)))
    plan.add(
        Activity(seq=3,
                 act='home',
                 area='b',
                 start_time=mtdt(390),
                 end_time=END_OF_DAY))
    return plan
예제 #3
0
def test_person_add_activity_activity_raise_error():
    plan = Plan()
    act = Activity(1, 'home', 1)
    plan.add(act)
    act = Activity(2, 'work', 1)
    with pytest.raises(PAMSequenceValidationError):
        plan.add(act)
예제 #4
0
def test_leg_duration():
    plan = Plan('a')
    plan.add(
        Activity(seq=1,
                 act='home',
                 area='a',
                 start_time=mtdt(0),
                 end_time=mtdt(60)))
    plan.add(
        Leg(seq=1,
            mode='car',
            start_area='a',
            end_area='b',
            start_time=mtdt(60),
            end_time=mtdt(90)))
    plan.add(
        Activity(seq=2,
                 act='work',
                 area='b',
                 start_time=mtdt(90),
                 end_time=mtdt(120)))
    plan.add(
        Leg(seq=2,
            mode='car',
            start_area='b',
            end_area='a',
            start_time=mtdt(120),
            end_time=mtdt(180)))

    plan.add(
        Activity(seq=3,
                 act='home',
                 area='a',
                 start_time=mtdt(180),
                 end_time=mtdt(24 * 60 - 1)))

    plan.mode_shift(3,
                    'rail',
                    mode_speed={
                        'car': 37,
                        'bus': 10,
                        'walk': 4,
                        'cycle': 14,
                        'pt': 23,
                        'rail': 37
                    },
                    update_duration=True)

    assert [act.duration for act in plan] == [
        timedelta(seconds=3603),
        timedelta(seconds=1800),
        timedelta(seconds=1800),
        timedelta(seconds=3600),
        timedelta(seconds=75597)
    ]
예제 #5
0
def test_move_activity_with_home_default():
    plan = Plan('a')
    plan.add(Activity(1, 'home', area='a'))
    plan.add(Leg(1))
    plan.add(Activity(2, 'shop', area='b'))
    plan.add(Leg(2))
    plan.add(Activity(3, 'home', area='a'))

    plan.move_activity(2)

    assert plan[2].location == 'a'
예제 #6
0
def test_move_activity_with_home_default_updates_legs():
    plan = Plan('a')
    plan.add(Activity(1, 'home', area='a'))
    plan.add(Leg(1))
    plan.add(Activity(2, 'shop', area='b'))
    plan.add(Leg(2))
    plan.add(Activity(3, 'home', area='a'))

    plan.move_activity(2)

    assert plan[1].end_location == 'a'
    assert plan[3].start_location == 'a'
예제 #7
0
def test_move_activity_with_different_default():
    plan = Plan('a')
    plan.add(Activity(1, 'home', area='a'))
    plan.add(Leg(1))
    plan.add(Activity(2, 'shop', area='b'))
    plan.add(Leg(2))
    plan.add(Activity(3, 'home', area='a'))

    new_loc = Location(area='heyooo')
    plan.move_activity(2, default=new_loc)

    assert plan[2].location == new_loc
예제 #8
0
def test_move_activity_with_different_default_updates_legs():
    plan = Plan('a')
    plan.add(Activity(1, 'home', area='a'))
    plan.add(Leg(1))
    plan.add(Activity(2, 'shop', area='b'))
    plan.add(Leg(2))
    plan.add(Activity(3, 'home', area='a'))

    new_loc = Location(area='heyooo')
    plan.move_activity(2, default=new_loc)

    assert plan[1].end_location == new_loc
    assert plan[3].start_location == new_loc
예제 #9
0
def test_activity_tours_segments_home_to_other_act_nonhome_looped_plan(
        activities_and_tour):
    other_act = Activity(8, 'other', 'e')

    plan = Plan(1)
    plan.add(other_act)
    plan.add(Leg(1))
    for i in range(len(activities_and_tour['activities'])):
        plan.add(activities_and_tour['activities'][i])
        plan.add(Leg(1))
    plan.add(other_act)

    assert plan[0].act == plan[-1].act
    assert plan.activity_tours(
    ) == [[other_act]] + activities_and_tour['tours'] + [[other_act]]
예제 #10
0
def test_mode_shift_single_tour():
    plan = Plan('a')
    plan.add(Activity(1, 'home', 'a', start_time=mtdt(0), end_time=mtdt(60)))
    plan.add(Leg(1, mode='car', start_time=mtdt(60), end_time=mtdt(90)))
    plan.add(Activity(2, 'shop', 'b', start_time=mtdt(90), end_time=mtdt(500)))
    plan.add(Leg(2, mode='car', start_time=mtdt(500), end_time=mtdt(400)))
    plan.add(
        Activity(3,
                 'home',
                 'a',
                 start_time=mtdt(400),
                 end_time=mtdt(24 * 60 - 1)))

    plan.mode_shift(1, 'pt')

    assert [leg.mode for leg in plan.legs] == ['pt', 'pt']
예제 #11
0
def test_activity_tours_segments_home_to_home_looped_plan(activities_and_tour):
    plan = Plan(1)
    for i in range(len(activities_and_tour['activities']) - 1):
        plan.add(activities_and_tour['activities'][i])
        plan.add(Leg(1))
    plan.add(activities_and_tour['activities'][-1])
    assert plan.activity_tours() == activities_and_tour['tours']
예제 #12
0
def test_plan_fix():
    plan = Plan()
    plan.add(
        Activity(seq=1,
                 act='home',
                 area='A',
                 start_time=mtdt(0),
                 end_time=mtdt(600)))
    plan.add(
        Leg(seq=2,
            mode='car',
            start_area='B',
            end_area='B',
            start_time=mtdt(610),
            end_time=mtdt(620)))
    plan.add(
        Activity(seq=3,
                 act='work',
                 area='B',
                 start_time=mtdt(620),
                 end_time=mtdt(12000)))
    plan.add(
        Leg(seq=2,
            mode='car',
            start_area='B',
            end_area='A',
            start_time=mtdt(12000),
            end_time=mtdt(11000)))
    plan.add(
        Activity(seq=1,
                 act='home',
                 area='A',
                 start_time=mtdt(11000),
                 end_time=END_OF_DAY))
    plan.fix()
    assert plan.length == 3
    assert plan.day[-1].end_time == END_OF_DAY
    assert plan[1].start_time == mtdt(600)
    assert plan[1].start_location.area == 'A'
예제 #13
0
def test_move_activity_at_start_of_plan_updates_leg():
    plan = Plan('a')
    plan.add(Activity(1, 'shop', 'b'))
    plan.add(Leg(1))
    plan.add(Activity(2, 'home', 'a'))

    plan.move_activity(0)

    assert plan[1].start_location == 'a'
예제 #14
0
def test_person_add_leg_leg_raise_error():
    plan = Plan()
    act = Activity(1, 'home', 1)
    plan.add(act)
    leg = Leg(1, 'car', start_area=1, end_area=2)
    plan.add(leg)
    leg = Leg(2, 'car', start_area=2, end_area=1)
    with pytest.raises(PAMSequenceValidationError):
        plan.add(leg)
예제 #15
0
def test_move_activity_at_end_of_plan_updates_leg():
    plan = Plan('a')
    plan.add(Activity(1, 'home', area='a'))
    plan.add(Leg(1))
    plan.add(Activity(2, 'shop', area='b'))

    plan.move_activity(2)

    assert plan[1].end_location == 'a'
예제 #16
0
def test_crop_act_out_of_order():
    plan = Plan()
    plan.add(
        Activity(seq=1,
                 act='home',
                 area='A',
                 start_time=mtdt(0),
                 end_time=mtdt(600)))
    plan.add(
        Leg(seq=2,
            mode='car',
            start_area='A',
            end_area='B',
            start_time=mtdt(600),
            end_time=mtdt(620)))
    plan.add(
        Activity(seq=3,
                 act='work',
                 area='B',
                 start_time=mtdt(620),
                 end_time=mtdt(12000)))
    plan.add(
        Leg(seq=2,
            mode='car',
            start_area='B',
            end_area='A',
            start_time=mtdt(12000),
            end_time=END_OF_DAY))
    plan.add(
        Activity(seq=1,
                 act='home',
                 area='A',
                 start_time=mtdt(0),
                 end_time=mtdt(12030)))
    plan.crop()
    assert plan.length == 3
    assert plan.day[-1].end_time == END_OF_DAY
예제 #17
0
def test_reverse_iter():
    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)
    idxs = list(i for i, c in plan.reversed())
    assert idxs == [2,1,0]
예제 #18
0
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
예제 #19
0
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)
예제 #20
0
def test_return_first_act_as_home_act_if_missing():
    plan = Plan()
    plan.add(
        Activity(seq=1,
                 act='work',
                 area='A',
                 start_time=mtdt(0),
                 end_time=mtdt(600)))
    plan.add(
        Leg(seq=2,
            mode='car',
            start_area='A',
            end_area='B',
            start_time=mtdt(600),
            end_time=mtdt(620)))
    plan.add(
        Activity(seq=3,
                 act='shop',
                 area='B',
                 start_time=mtdt(620),
                 end_time=mtdt(1200)))
    assert plan.home == 'A'
예제 #21
0
def test_fix_time_consistency():
    plan = Plan()
    plan.add(
        Activity(seq=1,
                 act='home',
                 area='A',
                 start_time=mtdt(0),
                 end_time=mtdt(600)))
    plan.add(
        Leg(seq=2,
            mode='car',
            start_area='A',
            end_area='B',
            start_time=mtdt(610),
            end_time=mtdt(620)))
    plan.add(
        Activity(seq=3,
                 act='work',
                 area='B',
                 start_time=mtdt(620),
                 end_time=END_OF_DAY))
    plan.fix_time_consistency()
    assert plan[1].start_time == mtdt(600)
예제 #22
0
def test_compare_plans_not_equal_types():
    plana = Plan()
    plana.add(
        Activity(seq=1,
                 act='work',
                 area='A',
                 start_time=mtdt(0),
                 end_time=mtdt(600)))
    plana.add(
        Leg(seq=2,
            mode='car',
            start_area='A',
            end_area='B',
            start_time=mtdt(600),
            end_time=mtdt(620)))
    plana.add(
        Activity(seq=3,
                 act='shop',
                 area='B',
                 start_time=mtdt(620),
                 end_time=mtdt(1200)))

    with pytest.raises(UserWarning):
        assert not plana == None
예제 #23
0
def test_get_component():
    plan = Plan()
    plan.add(
        Activity(seq=1,
                 act='home',
                 area='A',
                 start_time=mtdt(0),
                 end_time=mtdt(600)))
    plan.add(
        Leg(seq=2,
            mode='car',
            start_area='A',
            end_area='B',
            start_time=mtdt(600),
            end_time=mtdt(620)))
    plan.add(
        Activity(seq=3,
                 act='work',
                 area='B',
                 start_time=mtdt(620),
                 end_time=mtdt(1200)))
    assert plan.get(0).act == 'home'
    assert plan.get(4) is None
    assert plan.get(4, '1') == '1'
예제 #24
0
def test_mode_and_activity_classes():
    plan = Plan()
    plan.add(
        Activity(seq=1,
                 act='home',
                 area='A',
                 start_time=mtdt(0),
                 end_time=mtdt(600)))
    plan.add(
        Leg(seq=2,
            mode='car',
            start_area='A',
            end_area='B',
            start_time=mtdt(600),
            end_time=mtdt(620)))
    plan.add(
        Activity(seq=3,
                 act='work',
                 area='B',
                 start_time=mtdt(620),
                 end_time=mtdt(1200)))

    assert plan.activity_classes == set(['home', 'work'])
    assert plan.mode_classes == set(['car'])
예제 #25
0
def test_mode_shift_multiple_tours():
    plan = Plan('a')
    plan.add(Activity(1, 'home', 'a', start_time=mtdt(0), end_time=mtdt(60)))
    plan.add(Leg(1, mode='car', start_time=mtdt(60), end_time=mtdt(90)))
    plan.add(Activity(2, 'work', 'b', start_time=mtdt(90), end_time=mtdt(500)))
    plan.add(Leg(2, mode='car', start_time=mtdt(500), end_time=mtdt(400)))
    plan.add(Activity(3, 'shop', 'b', start_time=mtdt(400),
                      end_time=mtdt(450)))
    plan.add(Leg(3, mode='car', start_time=mtdt(450), end_time=mtdt(600)))
    plan.add(Activity(4, 'work', 'b', start_time=mtdt(600),
                      end_time=mtdt(660)))
    plan.add(Leg(4, mode='car', start_time=mtdt(660), end_time=mtdt(800)))
    plan.add(Activity(5, 'home', 'a', start_time=mtdt(830),
                      end_time=mtdt(860)))
    plan.add(Leg(5, mode='walk', start_time=mtdt(860), end_time=mtdt(900)))
    plan.add(
        Activity(6, 'other', 'a', start_time=mtdt(900), end_time=mtdt(920)))
    plan.add(Leg(6, mode='walk', start_time=mtdt(920), end_time=mtdt(950)))
    plan.add(
        Activity(7,
                 'home',
                 'a',
                 start_time=mtdt(950),
                 end_time=mtdt(24 * 60 - 1)))

    plan.mode_shift(5, 'pt')

    assert [leg.mode
            for leg in plan.legs] == ['pt', 'pt', 'pt', 'pt', 'walk', 'walk']
예제 #26
0
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)
예제 #27
0
def test_add_wrong_type():
    plan = Plan()
    with pytest.raises(UserWarning):
        plan.add(None)
예제 #28
0
def test_compare_plans_not_equal():
    plana = Plan()
    plana.add(
        Activity(seq=1,
                 act='work',
                 area='A',
                 start_time=mtdt(0),
                 end_time=mtdt(600)))
    plana.add(
        Leg(seq=2,
            mode='car',
            start_area='A',
            end_area='B',
            start_time=mtdt(600),
            end_time=mtdt(620)))
    plana.add(
        Activity(seq=3,
                 act='shop',
                 area='B',
                 start_time=mtdt(620),
                 end_time=mtdt(1200)))

    planb = Plan()
    planb.add(
        Activity(seq=1,
                 act='work',
                 area='A',
                 start_time=mtdt(0),
                 end_time=mtdt(800)))
    planb.add(
        Leg(seq=2,
            mode='car',
            start_area='A',
            end_area='B',
            start_time=mtdt(800),
            end_time=mtdt(620)))
    planb.add(
        Activity(seq=3,
                 act='shop',
                 area='B',
                 start_time=mtdt(620),
                 end_time=mtdt(1200)))

    assert not plana == planb
예제 #29
0
def test_person_add_leg_first_raise_error():
    plan = Plan()
    leg = Leg(1, 'car', start_area=1, end_area=2)
    with pytest.raises(PAMSequenceValidationError):
        plan.add(leg)
예제 #30
0
def test_person_add_activity():
    plan = Plan()
    act = Activity(1, 'home', 1)
    plan.add(act)
    assert len(plan.day) == 1