def test_with_smaller(self): assert P.closed(0, 4) - P.closed(2, 3) == P.closedopen( 0, 2) | P.openclosed(3, 4) assert P.closed(1, 4) - P.closed(1, 3) == P.openclosed(3, 4) assert P.closed(1, 4) - P.closed(2, 4) == P.closedopen(1, 2) assert P.closed(0, 4) - P.open(1, 2) == P.closed(0, 1) | P.closed(2, 4) assert P.closed(0, 2) - P.open(0, 2) == P.singleton(0) | P.singleton(2)
def test_with_gaps(self): assert list(P.iterate(P.closed(0, 1) | P.closed(5, 6), step=1)) == [0, 1, 5, 6] assert list(P.iterate(P.closed(0, 1) | P.closed(2.5, 4), step=1)) == [0, 1, 2.5, 3.5] assert list(P.iterate(P.open(0, 1) | P.open(1, 2), step=1)) == [] assert list(P.iterate(P.open(0.5, 1) | P.open(1, 3), step=1)) == [2]
def step(mover: int, pivot: int, stick_rate: float): # find available places around pivot nears = calc_near(pivot) available = portion.openclosed(-np.pi, np.pi) for near in nears: if near != mover: dist = distance(circles[pivot], circles[near]) angl = angle(circles[pivot], circles[near]) var = np.arccos(dist / 2) left = angl - var right = angl + var if left <= -np.pi: occupied = portion.open(-np.pi, right) | portion.openclosed( left + 2 * np.pi, np.pi) elif right > np.pi: occupied = portion.openclosed(left, np.pi) | portion.open( -np.pi, right - 2 * np.pi) else: occupied = portion.open(left, right) available -= occupied if available.empty: print("Void step. No available space next to the pivot.") return circles[mover] # stick: move mover to a place sticking to an obstacle. Notice when only 1 circle around pivot stick is not doable. if np.random.rand() < stick_rate: stick_angles = [] for interval in available._intervals: stick_angles.append(interval.lower) stick_angles.append(interval.upper) if available.enclosure == portion.openclosed(-np.pi, np.pi): stick_angles.remove(-np.pi) stick_angles.remove(np.pi) if len(stick_angles) == 0: print("Not doable.") return circles[mover] stick_angle = stick_angles[np.random.randint(len(stick_angles))] return circles[pivot][0] + np.cos( stick_angle), circles[pivot][1] + np.sin(stick_angle) # non-stick: uniformly pick angle from all available angle intervals else: # available is 1 interval if available.atomic: stick_angle = available.lower + np.random.rand() * ( available.upper - available.lower) return circles[pivot][0] + np.cos( stick_angle), circles[pivot][1] + np.sin(stick_angle) # available is union of 2 intervals else: stick_angle = available.lower + np.random.rand() * \ (available._intervals[0].upper - available._intervals[0].lower + available._intervals[1].upper - available._intervals[1].lower) if stick_angle > available._intervals[0].upper: stick_angle += (available._intervals[1].lower - available._intervals[0].upper) return circles[pivot][0] + np.cos( stick_angle), circles[pivot][1] + np.sin(stick_angle) pass
def test_nonatomic_interval(self): assert (P.closed(0, 1) | P.closed(2, 3)).adjacent(P.open(1, 2)) assert P.open(1, 2).adjacent(P.closed(0, 1) | P.closed(2, 3)) assert not (P.closed(0, 1) | P.closed(2, 3)).adjacent(P.closed(1, 2)) assert (P.closedopen(0, 1) | P.openclosed( 2, 3)).adjacent(P.open(-1, 0) | P.closed(1, 2) | P.openclosed(3, 4))
def test_replace_bounds(self): i = P.open(-P.inf, P.inf) assert i.replace(lower=lambda v: 1, upper=lambda v: 1) == P.open(-P.inf, P.inf) assert i.replace(lower=lambda v: 1, upper=lambda v: 2, ignore_inf=False) == P.open(1, 2)
def test_combine_nonempty(self): add = lambda x, y: x + y d1 = P.IntervalDict([(P.closed(1, 3) | P.closed(5, 7), 1)]) d2 = P.IntervalDict([(P.closed(2, 4) | P.closed(6, 8), 2)]) assert d1.combine(d2, add) == d2.combine(d1, add) assert d1.combine(d2, add) == P.IntervalDict([ (P.closedopen(1, 2) | P.closedopen(5, 6), 1), (P.closed(2, 3) | P.closed(6, 7), 3), (P.openclosed(3, 4) | P.openclosed(7, 8), 2), ]) d1 = P.IntervalDict({ P.closed(0, 1): 2, P.closed(3, 4): 2 }) d2 = P.IntervalDict({ P.closed(1, 3): 3, P.closed(4, 5): 1 }) assert d1.combine(d2, add) == d2.combine(d1, add) assert d1.combine(d2, add) == P.IntervalDict({ P.closedopen(0, 1): 2, P.singleton(1): 5, P.open(1, 3): 3, P.singleton(3): 5, P.open(3, 4): 2, P.singleton(4): 3, P.openclosed(4, 5): 1, })
def test_apply(self): i = P.closed(0, 1) assert i.apply(lambda s: s) == i assert i.apply(lambda s: (P.OPEN, -1, 2, P.OPEN)) == P.open(-1, 2) assert i.apply( lambda s: P.Interval.from_atomic(P.OPEN, -1, 2, P.OPEN)) == P.open( -1, 2) assert i.apply(lambda s: P.open(-1, 2)) == P.open(-1, 2)
def test_replace_with_empty(self): assert P.empty().replace(left=P.CLOSED, right=P.CLOSED) == P.empty() assert P.empty().replace(lower=1, upper=2) == P.open(1, 2) assert P.empty().replace(lower=lambda v: 1, upper=lambda v: 2) == P.empty() assert P.empty().replace(lower=lambda v: 1, upper=lambda v: 2, ignore_inf=False) == P.open(1, 2)
def test_apply_on_unions(self): i = P.closed(0, 1) | P.closed(2, 3) assert i.apply(lambda s: s) == i assert i.apply(lambda s: (P.OPEN, -1, 2, P.OPEN)) == P.open(-1, 2) assert i.apply(lambda s: (~s.left, s.lower - 1, s.upper - 1, ~s.right)) == P.open(-1, 0) | P.open(1, 2) assert i.apply(lambda s: P.Interval.from_atomic(P.OPEN, -1, 2, P.OPEN)) == P.open(-1, 2) assert i.apply(lambda s: P.open(-1, 2)) == P.open(-1, 2) assert i.apply(lambda s: (s.left, s.lower, s.upper * 2, s.right)) == P.closed(0, 6)
def test_replace_with_union(self): i = P.closed(0, 1) | P.open(2, 3) assert i.replace() == i assert i.replace(P.OPEN, -1, 4, P.OPEN) == P.openclosed(-1, 1) | P.open(2, 4) assert i.replace(lower=2) == P.closedopen(2, 3) assert i.replace(upper=1) == P.closedopen(0, 1) assert i.replace(lower=5) == P.empty() assert i.replace(upper=-5) == P.empty() assert i.replace(left=lambda v: ~v, lower=lambda v: v - 1, upper=lambda v: v + 1, right=lambda v: ~v) == P.openclosed(-1, 1) | P.openclosed(2, 4)
def test_overlapping(self): assert not P.openclosed(0, 2).adjacent(P.closedopen(2, 3)) assert not P.closed(0, 2).adjacent(P.closedopen(2, 3)) assert not P.closed(0, 2).adjacent(P.closed(2, 3)) assert not P.open(0, 2).adjacent(P.open(2, 3)) assert not P.closedopen(2, 3).adjacent(P.openclosed(0, 2)) assert not P.closedopen(2, 3).adjacent(P.closed(0, 2)) assert not P.closed(2, 3).adjacent(P.closed(0, 2)) assert not P.open(2, 3).adjacent(P.open(0, 2))
def test_with_intervals(self): assert P.closed(1, 2) in P.closed(0, 3) assert P.closed(1, 2) in P.closed(1, 2) assert P.open(1, 2) in P.closed(1, 2) assert P.closed(1, 2) not in P.open(1, 2) assert P.closed(0, 1) not in P.closed(1, 2) assert P.closed(0, 2) not in P.closed(1, 3) assert P.closed(-P.inf, P.inf) in P.closed(-P.inf, P.inf) assert P.closed(0, 1) in P.closed(-P.inf, P.inf) assert P.closed(-P.inf, P.inf) not in P.closed(0, 1)
def test_intervals_methods(self): a = I.closed(0, 3) result = a & I.closed(-1, 4) assert not result.is_empty() assert not (I.closed(0, 3) & I.closed(0, 3)).is_empty() assert not (I.closed(0, 3) & I.open(0, 3)).is_empty() assert not (I.closed(0, 3) & I.open(1, 2)).is_empty() assert not (I.closed(0, 3) & I.open(-1, 4)).is_empty() assert (I.closed(0, 3) & I.open(3, 4)).is_empty() assert I.closed(0, 3) in I.closed(-1, 4) assert I.closed(0, 3) in I.closed(0, 3)
def test_with_intervals(self): assert P.closed(1, 2) in P.closed(0, 3) assert P.closed(1, 2) in P.closed(1, 2) assert P.open(1, 2) in P.closed(1, 2) assert P.closed(1, 2) not in P.open(1, 2) assert P.closed(0, 1) not in P.closed(1, 2) assert P.closed(0, 2) not in P.closed(1, 3) assert P.closed(-P.inf, P.inf) in P.closed(-P.inf, P.inf) assert P.closed(0, 1) in P.closed(-P.inf, P.inf) assert P.closed(-P.inf, P.inf) not in P.closed(0, 1) # https://github.com/AlexandreDecan/portion/issues/28 assert P.closed(5, 6) not in P.closed(1, 2) | P.closed(3, 4)
def test_as_dict(self): content = { P.closed(1, 2) | P.closed(4, 5): 1, P.open(7, 8) | P.closed(10, 12): 2, } d = P.IntervalDict(content) assert d.as_dict() == content assert d.as_dict(atomic=False) == content assert d.as_dict(atomic=True) == { P.closed(1, 2): 1, P.closed(4, 5): 1, P.open(7, 8): 2, P.closed(10, 12): 2, }
def test_is_empty(self): assert P.openclosed(1, 1).empty assert P.closedopen(1, 1).empty assert P.open(1, 1).empty assert not P.closed(1, 1).empty assert P.Interval().empty assert P.empty().empty
class TestIntervalComplement: def test_singleton(self): assert ~P.singleton(0) == P.open(-P.inf, 0) | P.open(0, P.inf) assert ~(P.open(-P.inf, 0) | P.open(0, P.inf)) == P.singleton(0) def test_nonempty(self): assert ~P.closed(1, 2) == P.open(-P.inf, 1) | P.open(2, P.inf) assert ~P.open(1, 2) == P.openclosed(-P.inf, 1) | P.closedopen(2, P.inf) def test_union(self): assert ~(P.singleton(0) | P.singleton(5) | P.singleton(10)) == P.open(-P.inf, 0) | P.open(0, 5) | P.open(5, 10) | P.open(10, P.inf) assert ~(P.open(0, 1) | P.closed(2, 3) | P.open(4, 5)) == P.openclosed(-P.inf, 0) | P.closedopen(1, 2) | P.openclosed(3, 4) | P.closedopen(5, P.inf) @pytest.mark.parametrize('i', [P.closed(0, 1), P.open(0, 1), P.openclosed(0, 1), P.closedopen(0, 1)]) def test_identity(self, i): for interval in i: assert ~(~interval) == interval def test_empty(self): assert ~P.open(1, 1) == P.open(-P.inf, P.inf) assert (~P.closed(-P.inf, P.inf)).empty assert ~P.empty() == P.open(-P.inf, P.inf) def test_proxy_method(self): i1, i2 = P.closed(0, 1), P.closed(2, 3) assert ~i1 == i1.complement() assert ~i2 == i2.complement()
def test_with_intervals(self): d = P.IntervalDict([(P.closed(0, 2), 0)]) assert d[P.open(-P.inf, P.inf)].as_dict() == {P.closed(0, 2): 0} assert d[P.closed(0, 2)].as_dict() == {P.closed(0, 2): 0} assert d[P.closed(-1, 0)].as_dict() == {P.singleton(0): 0} assert d[P.closed(-2, -1)].as_dict() == {} assert d.get(P.closed(0, 2)).as_dict() == {P.closed(0, 2): 0} assert d.get(P.closed(-2, -1)).as_dict() == {P.closed(-2, -1): None} assert d.get(P.closed(-1, 0)).as_dict() == { P.closedopen(-1, 0): None, P.singleton(0): 0 } d[P.closed(1, 3)] = 1 assert d.as_dict() == {P.closedopen(0, 1): 0, P.closed(1, 3): 1} assert len(d) == 2 assert d[0] == 0 assert d.get(0, -1) == 0 assert d[1] == 1 assert d.get(1, -1) == 1 assert d[3] == 1 assert d.get(3, -1) == 1 with pytest.raises(KeyError): d[4] assert d.get(4, -1) == -1
def test_parameters(self): i1, i2, i3, i4 = P.closed(0, 1), P.openclosed(0, 1), P.closedopen(0, 1), P.open(0, 1) params = { 'disj': ' or ', 'sep': '-', 'left_open': '<!', 'left_closed': '<', 'right_open': '!>', 'right_closed': '>', 'conv': lambda s: '"{}"'.format(s), 'pinf': '+oo', 'ninf': '-oo', } assert P.to_string(i1, **params) == '<"0"-"1">' assert P.to_string(i2, **params) == '<!"0"-"1">' assert P.to_string(i3, **params) == '<"0"-"1"!>' assert P.to_string(i4, **params) == '<!"0"-"1"!>' assert P.to_string(P.empty(), **params) == '<!!>' assert P.to_string(P.singleton(1), **params) == '<"1">' assert P.to_string(P.openclosed(-P.inf, 1), **params) == '<!-oo-"1">' assert P.to_string(P.closedopen(1, P.inf), **params) == '<"1"-+oo!>' assert P.to_string(P.closed(0, 1) | P.closed(2, 3), **params) == '<"0"-"1"> or <"2"-"3">'
def test_parameters(self): i1, i2, i3, i4 = '<"0"-"1">', '<!"0"-"1">', '<"0"-"1"!>', '<!"0"-"1"!>' params = { 'conv': lambda s: int(s[1:-1]), 'disj': ' or ', 'sep': '-', 'left_open': '<!', 'left_closed': '<', 'right_open': '!>', 'right_closed': '>', 'pinf': r'\+oo', 'ninf': '-oo', } assert P.from_string(i1, **params) == P.closed(0, 1) assert P.from_string(i2, **params) == P.openclosed(0, 1) assert P.from_string(i3, **params) == P.closedopen(0, 1) assert P.from_string(i4, **params) == P.open(0, 1) assert P.from_string('<!!>', **params) == P.empty() assert P.from_string('<"1">', **params) == P.singleton(1) assert P.from_string('<!-oo-"1">', **params) == P.openclosed(-P.inf, 1) assert P.from_string('<"1"-+oo!>', **params) == P.closedopen(1, P.inf) assert P.from_string('<"0"-"1"> or <"2"-"3">', **params) == P.closed(0, 1) | P.closed(2, 3)
def test_identity(self): i1, i2, i3, i4 = P.closed(0, 1), P.openclosed(0, 1), P.closedopen(0, 1), P.open(0, 1) assert P.from_string(P.to_string(i1), int) == i1 assert P.from_string(P.to_string(i2), int) == i2 assert P.from_string(P.to_string(i3), int) == i3 assert P.from_string(P.to_string(i4), int) == i4
def test_identity(self): i1, i2, i3, i4 = P.closed(0, 1), P.openclosed(0, 1), P.closedopen(0, 1), P.open(0, 1) assert P.from_data(P.to_data(i2)) == i2 assert P.from_data(P.to_data(i3)) == i3 assert P.from_data(P.to_data(i4)) == i4 assert P.from_data(P.to_data(i1)) == i1
def test_open_intervals(self): assert P.from_data([(P.OPEN, float('-inf'), float('inf'), P.OPEN) ]) == P.open(-P.inf, P.inf) assert P.from_data([(P.OPEN, float('-inf'), 0, P.CLOSED) ]) == P.openclosed(-P.inf, 0) assert P.from_data([(P.CLOSED, 0, float('inf'), P.OPEN) ]) == P.closedopen(0, P.inf)
def test_open_intervals(self): assert P.to_data(P.open(-P.inf, P.inf)) == [(False, float('-inf'), float('inf'), False)] assert P.to_data(P.openclosed(-P.inf, 0)) == [(False, float('-inf'), 0, True)] assert P.to_data(P.closedopen(0, P.inf)) == [(True, 0, float('inf'), False)]
def test_with_values(self): assert 1 in P.closed(0, 2) assert 1 in P.closed(1, 2) assert 1 in P.closed(0, 1) assert 1 in P.open(0, 2) assert 1 not in P.open(0, 1) assert 1 not in P.open(1, 2) assert 1 in P.closed(0, 2) | P.closed(4, 6) | P.closed(8, 10) assert 5 in P.closed(0, 2) | P.closed(4, 6) | P.closed(8, 10) assert 10 in P.closed(0, 2) | P.closed(4, 6) | P.closed(8, 10) assert -1 not in P.closed(0, 2) | P.closed(4, 6) | P.closed(8, 10) assert 3 not in P.closed(0, 2) | P.closed(4, 6) | P.closed(8, 10) assert 7 not in P.closed(0, 2) | P.closed(4, 6) | P.closed(8, 10) assert 11 not in P.closed(0, 2) | P.closed(4, 6) | P.closed(8, 10)
def test_overlaps_with_edge_cases(self): assert not P.closed(0, 1).overlaps(P.open(1, 2)) assert not P.closed(0, 1).overlaps(P.openclosed(1, 2)) assert not P.closedopen(0, 1).overlaps(P.closed(1, 2)) assert not P.closedopen(0, 1).overlaps(P.closedopen(1, 2)) assert not P.closedopen(0, 1).overlaps(P.openclosed(1, 2)) assert not P.closedopen(0, 1).overlaps(P.open(1, 2)) assert not P.open(0, 1).overlaps(P.open(1, 2)) assert P.open(0, 2).overlaps(P.open(0, 1)) assert P.open(0, 1).overlaps(P.open(0, 2))
def build(self): for i in range(1, self.ap + 1): print("Minimum value nb_ap : " + str(i) + " expected value :" + str(self.maxIter * (i - 1))) print("Maximum value nb_ap : " + str(i) + " expected value :" + str(self.maxIter * i)) self.listOfSegment.append( P.open(self.maxIter * (i - 1), self.maxIter * i)) print(self.listOfSegment)
def test_bounds(self): assert P.closed(0, 1) == P.Interval.from_atomic(P.CLOSED, 0, 1, P.CLOSED) assert P.open(0, 1) == P.Interval.from_atomic(P.OPEN, 0, 1, P.OPEN) assert P.openclosed(0, 1) == P.Interval.from_atomic( P.OPEN, 0, 1, P.CLOSED) assert P.closedopen(0, 1) == P.Interval.from_atomic( P.CLOSED, 0, 1, P.OPEN) assert P.singleton(2) == P.closed(2, 2)
def test_empty(self): assert P.empty() == P.Interval.from_atomic(P.OPEN, P.inf, -P.inf, P.open) assert P.closed(3, -3) == P.empty() assert P.openclosed(0, 0) == P.empty() assert P.closedopen(0, 0) == P.empty() assert P.open(0, 0) == P.empty() assert P.closed(0, 0) != P.empty() assert P.singleton(P.inf) == P.empty() assert P.singleton(-P.inf) == P.empty()
def test_with_adjacent(self): assert P.closed(1, 2) | P.closed(2, 3) == P.closed(1, 3) assert P.closed(1, 2) | P.open(2, 3) == P.closedopen(1, 3) assert P.open(1, 2) | P.closed(2, 3) == P.openclosed(1, 3) assert P.open(1, 3) | P.open(2, 4) == P.open(1, 4) assert P.closedopen(1, 2) | P.closed(2, 3) == P.closed(1, 3) assert P.open(1, 2) | P.closed(2, 4) == P.openclosed(1, 4)