def make_sorted_distinct_sequence(iterable, sense=SortSense.ascending): """Create a sorted immutable sequence from an iterable series. The resulting collected will be sorted ascending. Args: iterable: An iterable series of comparable values. sense: If None, the any original sense of the data is preserved, so ascending data remains ascending, and descending data remains descending. If the original data was unsorted, the result will be ascending. Force a particular sense by specifying SortSense.ascending or SortSense.descending. Returns: An immutable collection which supports the Sized, Iterable, Container and Sequence protocols. """ if isinstance(iterable, range): if sense is None: return iterable elif sense == SortSense.ascending: if iterable.step > 0: return iterable else: return reversed_range(iterable) elif sense == SortSense.descending: if iterable.step < 0: return iterable else: return reversed_range(iterable) else: raise TypeError( "sense {} is neither a SortSense nor None".format(sense)) if sense == SortSense.ascending: sorted_seq = SortedFrozenSet(iterable) elif sense == SortSense.descending: sorted_seq = ReversedSequenceView(SortedFrozenSet(iterable)) elif sense is None: items = list(iterable) if is_sorted(items, reverse=True, distinct=True): sorted_seq = ReversedSequenceView(SortedFrozenSet(iterable)) else: sorted_seq = SortedFrozenSet(iterable) else: raise TypeError( "sense {} is neither a SortSense nor None".format(sense)) return compress_sorted_sequence_to_range(sorted_seq)
def test_repr(seq): rev = ReversedSequenceView(seq) r = repr(rev) assert r.startswith('ReversedSequenceView') assert check_balanced(r)
def test_negative_out_of_range_indexes_raise_value_error(seq): rev = ReversedSequenceView(seq) with raises(IndexError): _ = rev[-len(rev) - 1]
def test_negative_indexing(seq): rev = ReversedSequenceView(seq) assert all(rev[index] == a for index, a in zip(range(-1, -len(seq), -1), seq))
def test_index_not_found_raises_value_error(seq, data): missing = data.draw(integers()) assume(missing not in seq) rev = ReversedSequenceView(seq) with raises(ValueError): rev.index(missing)
def test_index(seq): rev = ReversedSequenceView(seq) assert all(rev.index(a) == list(reversed(seq)).index(a) for a in seq)
def test_reversed(seq): rev = ReversedSequenceView(seq) assert all(a == b for a, b in zip(seq, reversed(rev)))
def test_count(seq): rev = ReversedSequenceView(seq) assert all(seq.count(a) == rev.count(a) for a in seq)
def test_get_item(seq): rev = ReversedSequenceView(seq) assert all(rev[i] == b for i, b in enumerate(reversed(seq)))
def test_iteration(seq): rev = ReversedSequenceView(seq) assert all(a == b for a, b in zip(rev, reversed(seq)))
def test_length(seq): rev = ReversedSequenceView(seq) assert len(rev) == len(seq)
def test_contains(seq): rev = ReversedSequenceView(seq) assert all(item in rev for item in seq)
def test_index_not_found_raises_value_error(seq, data): missing = data.draw(integers()) assume(missing not in seq) rev = ReversedSequenceView(seq) with raises(ValueError): rev.index(missing)
def test_index(seq): rev = ReversedSequenceView(seq) assert all(rev.index(a) == list(reversed(seq)).index(a) for a in seq)
def test_count(seq): rev = ReversedSequenceView(seq) assert all(seq.count(a) == rev.count(a) for a in seq)