def __init__(self, i_range, j_range): """Initialize a Catalog2D. Args: i_range: A range which can generate all and only valid i indexes. j_range: A range which can generate all and only valid j indexes. Raises: ValueError: If either i_range or j_range are not totally sorted. """ if not is_sorted(i_range, distinct=True): raise ValueError("i indexes must be sorted and unique") if not is_sorted(j_range, distinct=True): raise ValueError("j indexes must be sorted and unique") self._i_range = i_range self._j_range = j_range
def make_sorted_ranges(self): i_sorted = make_sorted_distinct_sequence(i for (i, _), _ in self._catalog) j_sorted = make_sorted_distinct_sequence(j for (_, j), _ in self._catalog) if len(i_sorted) * len(j_sorted) != len(self._catalog): # The do not match so use a dictionary-based mapping return None vs = [v for (_, _), v in self._catalog] # Are the values unique and in ascending or descending order? if not (is_sorted(vs, reverse=False, distinct=True) or is_sorted(vs, reverse=True, distinct=True)): # The values are not both unique and sorted, so use a dictionary-based mapping return None v_sorted = make_sorted_distinct_sequence(vs, sense=None) i_is_regular = isinstance(i_sorted, range) j_is_regular = isinstance(j_sorted, range) v_is_regular = isinstance(v_sorted, range) if not (i_is_regular and j_is_regular and v_is_regular): # The i, j and v values are not regularly spaced, so use a dictionary-based mapping return None return i_sorted, j_sorted, v_sorted
def test_is_sequence_sorted_descending_positive_duplicates(self, r): s = sorted(r + r, reverse=True) assert is_sorted(s, reverse=True)
def test_is_sequence_sorted_descending_negative(self, r): s = sorted(r, reverse=False) assert not is_sorted(s, reverse=True, distinct=True)
def test_sequence_sense_is_preserved(self, r, b): s = sorted(r, reverse=b) seq = make_sorted_distinct_sequence(s, sense=None) ascending = is_sorted(seq, reverse=False, distinct=True) descending = is_sorted(seq, reverse=True, distinct=True) assert b == descending != ascending
def test_range_of_one_is_sorted_descending(self, r): assert is_sorted(r, reverse=True, distinct=True)
def test_is_range_sorted_descending_negative(self, r): assert not is_sorted(r, reverse=True, distinct=True)
def test_sequence_of_one_is_sorted_ascending(self, r): assert is_sorted(r, reverse=False, distinct=True)
def test_sequence_of_one_is_sorted_descending(self, r): assert is_sorted(r, reverse=True, distinct=True)
def test_empty_sequence_is_sorted_descending(self): assert is_sorted([], reverse=True, distinct=True)
def test_is_sequence_sorted_descending_negative_duplicates(self, r): s = sorted(r + r, reverse=False) assert not is_sorted(s, reverse=True)
def test_is_sequence_sorted_descending_positive(self, r): s = sorted(r, reverse=True) assert is_sorted(s, reverse=True, distinct=True)
def test_is_range_sorted_ascending_negative(self, r): assert not is_sorted(r, reverse=False, distinct=True)
def test_is_range_sorted_ascending_positive(self, r): assert is_sorted(r, reverse=False, distinct=True)
def test_is_range_sorted_descending_positive(self, r): assert is_sorted(r, reverse=True, distinct=True)
def test_empty_range_is_sorted_ascending(self, r): assert is_sorted(r, reverse=False, distinct=True)
def test_descending_sequence_result_is_descending(self, r): s = sorted(r, reverse=True) seq = make_sorted_distinct_sequence(s, sense=SortSense.descending) assert is_sorted(seq, reverse=True, distinct=True)
def test_unsorted_jrange_raises_value_error(self, i_range, j_range, items): assume(not is_sorted(j_range)) with raises(ValueError): DictionaryCatalog2D(i_range, j_range, items)