def __eq__(self, other): return type(self) == type(other) and \ self.nominal_perm_space == other.nominal_perm_space and \ cute_iter_tools.are_equal(self._perm_sequence, other._perm_sequence)
def __init__(self, iterable_or_length, n_elements=None, *, domain=None, fixed_map=None, degrees=None, is_combination=False, slice_=None, perm_type=None): ### Making basic argument checks: ##################################### # # assert isinstance(iterable_or_length, (collections.abc.Iterable, numbers.Integral)) if isinstance(iterable_or_length, numbers.Integral): assert iterable_or_length >= 0 if slice_ is not None: assert isinstance(slice_, (slice, sequence_tools.CanonicalSlice)) if slice_.step not in (1, None): raise NotImplementedError assert isinstance(n_elements, numbers.Integral) or n_elements is None assert isinstance(is_combination, bool) # # ### Finished making basic argument checks. ############################ ### Figuring out sequence and whether space is rapplied: ############## # # if isinstance(iterable_or_length, numbers.Integral): self.is_rapplied = False self.sequence = sequence_tools.CuteRange(iterable_or_length) self.sequence_length = iterable_or_length else: assert isinstance(iterable_or_length, collections.abc.Iterable) self.sequence = sequence_tools. \ ensure_iterable_is_immutable_sequence(iterable_or_length) range_candidate = sequence_tools.CuteRange(len(self.sequence)) self.is_rapplied = not (cute_iter_tools.are_equal( self.sequence, range_candidate)) self.sequence_length = len(self.sequence) if not self.is_rapplied: self.sequence = sequence_tools.CuteRange(self.sequence_length) # # ### Finished figuring out sequence and whether space is rapplied. ##### ### Figuring out whether sequence is recurrent: ####################### # # if self.is_rapplied: self.is_recurrent = any( count >= 2 for count in self._frozen_ordered_bag.values()) else: self.is_recurrent = False # # ### Finished figuring out whether sequence is recurrent. ############## ### Figuring out number of elements: ################################## # # self.n_elements = self.sequence_length if (n_elements is None) \ else n_elements if not isinstance(self.n_elements, int): raise TypeError('`n_elements` must be an `int`.') if not self.n_elements >= 0: raise TypeError('`n_elements` must be positive or zero.') self.is_partial = (self.n_elements != self.sequence_length) self.indices = sequence_tools.CuteRange(self.n_elements) # # ### Finished figuring out number of elements. ######################### ### Figuring out whether it's a combination: ########################## # # self.is_combination = is_combination # Well that was quick. # # ### Finished figuring out whether it's a combination. ################# ### Figuring out whether space is dapplied: ########################### # # if domain is None: domain = self.indices domain = \ sequence_tools.ensure_iterable_is_immutable_sequence(domain) if self.is_partial: domain = domain[:self.n_elements] self.is_dapplied = not cute_iter_tools.are_equal(domain, self.indices) if self.is_dapplied: if self.is_combination: raise UnallowedVariationSelectionException({ variations.Variation.DAPPLIED: True, variations.Variation.COMBINATION: True, }) self.domain = domain if len(set(self.domain)) < len(self.domain): raise Exception('The domain must not have repeating elements.') else: self.domain = self.indices self.undapplied = self # # ### Finished figuring out whether space is dapplied. ################## ### Figuring out fixed map: ########################################### # # if fixed_map is None: fixed_map = {} if not isinstance(fixed_map, dict): if isinstance(fixed_map, collections.abc.Callable): fixed_map = {item: fixed_map(item) for item in self.sequence} else: fixed_map = dict(fixed_map) if fixed_map: self.fixed_map = { key: value for (key, value) in fixed_map.items() if (key in self.domain) and (value in self.sequence) } else: (self.fixed_map, self.free_indices, self.free_keys, self.free_values) = ({}, self.indices, self.domain, self.sequence) self.is_fixed = bool(self.fixed_map) if self.is_fixed: if not (self.is_dapplied or self.is_rapplied or degrees or slice_ or (n_elements is not None) or self.is_combination): self._just_fixed = self else: self._get_just_fixed = lambda: PermSpace( len(self.sequence), fixed_map=self._undapplied_unrapplied_fixed_map, ) else: if not (self.is_dapplied or self.is_rapplied or degrees or slice_ or (n_elements is not None) or self.is_combination): self._just_fixed = self else: self._get_just_fixed = lambda: PermSpace(len(self.sequence)) # # ### Finished figuring out fixed map. ################################## ### Figuring out degrees: ############################################# # # all_degrees = sequence_tools.CuteRange(self.sequence_length) if degrees is None: degrees = () degrees = sequence_tools.to_tuple(degrees, item_type=int) if (not degrees) or cute_iter_tools.are_equal(degrees, all_degrees): self.is_degreed = False self.degrees = all_degrees else: self.is_degreed = True if self.is_combination: raise UnallowedVariationSelectionException({ variations.Variation.DEGREED: True, variations.Variation.COMBINATION: True, }) if self.is_partial: raise UnallowedVariationSelectionException({ variations.Variation.DEGREED: True, variations.Variation.PARTIAL: True, }) if self.is_recurrent: raise UnallowedVariationSelectionException({ variations.Variation.DEGREED: True, variations.Variation.RECURRENT: True, }) # The space is degreed; we canonicalize `degrees` into a sorted # tuple. self.degrees = tuple( sorted(degree for degree in degrees if degree in all_degrees)) # # ### Finished figuring out degrees. #################################### ### Figuring out slice and length: #################################### # # self.slice_ = slice_ self.canonical_slice = sequence_tools.CanonicalSlice( slice_ or slice(float('inf')), self._unsliced_length) self.length = max( self.canonical_slice.stop - self.canonical_slice.start, 0) self.is_sliced = (self.length != self._unsliced_length) # # ### Finished figuring out slice and length. ########################### ### Figuring out perm type: ########################################### # # self.is_typed = perm_type not in (None, self.default_perm_type) self.perm_type = perm_type if self.is_typed else self.default_perm_type assert issubclass(self.perm_type, Perm) # # ### Finished figuring out perm type. ################################## self.is_pure = not (self.is_rapplied or self.is_fixed or self.is_sliced or self.is_degreed or self.is_partial or self.is_combination or self.is_typed) if self.is_pure: self.purified = self if not self.is_rapplied: self.unrapplied = self if not self.is_recurrent: self.unrecurrented = self if not self.is_partial: self.unpartialled = self if not self.is_combination: self.uncombinationed = self # No need do this for `undapplied`, it's already done above. if not self.is_fixed: self.unfixed = self if not self.is_degreed: self.undegreed = self if not self.is_sliced: self.unsliced = self if not self.is_typed: self.untyped = self
def test_perm_spaces(): pure_0a = PermSpace(4) pure_0b = PermSpace(range(4)) pure_0c = PermSpace(list(range(4))) pure_0d = PermSpace(iter(range(4))) assert pure_0a == pure_0b == pure_0c == pure_0d assert len(pure_0a) == len(pure_0b) == len(pure_0c) == len(pure_0d) assert repr(pure_0a) == repr(pure_0b) == repr(pure_0c) == \ repr(pure_0d) == '<PermSpace: 0..3>' assert repr(PermSpace(sequence_tools.CuteRange(3, 7))) == \ '<PermSpace: 3..6>' assert repr(PermSpace(sequence_tools.CuteRange(3, 7, 2))) == \ '<PermSpace: CuteRange(3, 7, 2)>' assert repr(PermSpace(tuple(sequence_tools.CuteRange(3, 7, 2)))) == \ '<PermSpace: (3, 5)>' assert cute_iter_tools.are_equal(pure_0a, pure_0b, pure_0c, pure_0d) assert set(map(bool, (pure_0a, pure_0b, pure_0c, pure_0d))) == set((True,)) pure_perm_space = pure_0a assert pure_0a.is_pure assert not pure_0a.is_rapplied assert not pure_0a.is_dapplied assert not pure_0a.is_fixed assert not pure_0a.is_sliced first_perm = pure_0a[0] some_perm = pure_0a[7] last_perm = pure_0a[-1] assert first_perm.index(2) == 2 assert first_perm.index(0) == 0 with cute_testing.RaiseAssertor(ValueError): first_perm.index(5) assert last_perm.apply('meow') == 'woem' assert last_perm.apply('meow', str) == 'woem' assert last_perm.apply('meow', tuple) == tuple('woem') with cute_testing.RaiseAssertor(IndexError): pure_0a[- pure_0a.length - 1] with cute_testing.RaiseAssertor(IndexError): pure_0a[- pure_0a.length - 2] with cute_testing.RaiseAssertor(IndexError): pure_0a[- pure_0a.length - 30] with cute_testing.RaiseAssertor(IndexError): pure_0a[pure_0a.length] with cute_testing.RaiseAssertor(IndexError): pure_0a[pure_0a.length + 1] with cute_testing.RaiseAssertor(IndexError): pure_0a[pure_0a.length + 2] with cute_testing.RaiseAssertor(IndexError): pure_0a[pure_0a.length + 300] with cute_testing.RaiseAssertor(): pure_0a[24] assert pure_0a.take_random() in pure_0c # Testing hashing: pure_perm_space_dict = {pure_0a: 'a', pure_0b: 'b', pure_0c: 'c', pure_0d: 'd',} (single_value,) = pure_perm_space_dict.values() assert len(pure_perm_space_dict) == 1 # They're all the same assert pure_perm_space_dict[pure_0a] == pure_perm_space_dict[pure_0b] == \ pure_perm_space_dict[pure_0c] == pure_perm_space_dict[pure_0d] == \ single_value assert None not in pure_0a # Because, damn. assert PermSpace('meow')[0] not in pure_0a assert type(first_perm) == type(some_perm) == type(last_perm) == Perm assert set(some_perm) == set(range(4)) assert tuple(first_perm) == (0, 1, 2, 3) assert tuple(last_perm) == (3, 2, 1, 0) assert Perm.coerce(first_perm) == first_perm assert Perm.coerce(first_perm, pure_0b) == first_perm assert Perm.coerce(tuple(first_perm)) == first_perm assert Perm.coerce(list(first_perm)) == first_perm assert Perm.coerce(tuple(first_perm), pure_0a) == first_perm assert Perm.coerce(list(first_perm), pure_0b) == first_perm assert Perm.coerce(tuple(first_perm), PermSpace(5, n_elements=4)) != \ first_perm assert isinstance(first_perm.items, combi.perming.perm.PermItems) assert first_perm.items[2] == (2, 2) assert repr(first_perm.items) == '<PermItems: %s>' % repr(first_perm) assert isinstance(first_perm.as_dictoid, combi.perming.perm.PermAsDictoid) assert first_perm.as_dictoid[2] == 2 assert dict(first_perm.as_dictoid) == {0: 0, 1: 1, 2: 2, 3: 3} assert not (first_perm != first_perm) assert first_perm == first_perm assert first_perm assert tuple({pure_0a[4]: 1, pure_0b[4]: 2, pure_0c[4]: 3,}.keys()) == \ (pure_0d[4], ) assert some_perm.inverse == ~ some_perm assert ~ ~ some_perm == some_perm assert first_perm in pure_perm_space assert set(first_perm) not in pure_perm_space # No order? Not contained. assert some_perm in pure_perm_space assert last_perm in pure_perm_space assert tuple(first_perm) in pure_perm_space assert list(some_perm) in pure_perm_space assert iter(last_perm) in pure_perm_space assert 'meow' not in pure_perm_space assert (0, 1, 2, 3, 3) not in pure_perm_space assert pure_perm_space.index(first_perm) == 0 assert pure_perm_space.index(last_perm) == \ len(pure_perm_space) - 1 assert pure_perm_space.index(some_perm) == 7 assert 'meow' * Perm((1, 3, 2, 0)) == 'ewom' assert Perm('meow', 'meow') * Perm((1, 3, 2, 0)) == Perm('ewom', 'meow') assert [0, 1, 2, 3] * Perm((0, 1, 2, 3)) == (0, 1, 2, 3) assert Perm((0, 1, 2, 3)) * Perm((0, 1, 2, 3)) == Perm((0, 1, 2, 3)) assert Perm((2, 0, 1, 3)) * Perm((0, 1, 3, 2)) == Perm((2, 0, 3, 1)) assert (Perm((0, 1, 2, 3)) ** (- 2)) == (Perm((0, 1, 2, 3)) ** (- 1)) == \ (Perm((0, 1, 2, 3)) ** (0)) == (Perm((0, 1, 2, 3)) ** (1)) == \ (Perm((0, 1, 2, 3)) ** 2) == (Perm((0, 1, 2, 3)) ** 3) assert set(map(bool, (pure_0a[4:4], pure_0a[3:2]))) == set((False,)) assert pure_0a[2:6][1:-1] == pure_0a[3:5] assert tuple(pure_0a[2:6][1:-1]) == tuple(pure_0a[3:5]) assert pure_0a[2:6][1:-1][1] == pure_0a[3:5][1] assert pure_0a[2:5][1:-1] != pure_0a[3:5] big_perm_space = PermSpace(range(150), fixed_map={1: 5, 70: 3,}, degrees=(3, 5)) assert big_perm_space == PermSpace(range(150), fixed_map={1: 5, 70: 3,}.items(), degrees=(3, 5)) for i in [10**10, 3*11**9-344, 4*12**8-5, 5*3**20+4]: perm = big_perm_space[i] assert big_perm_space.index(perm) == i repr_of_big_perm_space = repr(PermSpace(tuple(range(100, 0, -1)))) assert '...' in repr_of_big_perm_space assert len(repr_of_big_perm_space) <= 100 fixed_perm_space = pure_perm_space.get_fixed({0: 3,}) assert fixed_perm_space.length == 6 assert fixed_perm_space.is_fixed assert not fixed_perm_space.is_pure assert fixed_perm_space.unfixed.is_pure assert fixed_perm_space.unfixed == pure_perm_space assert pickle.loads(pickle.dumps(pure_perm_space)) == pure_perm_space assert pickle.loads(pickle.dumps(pure_0b[2])) == pure_0c[2] assert pickle.loads(pickle.dumps(pure_0b[3])) != pure_0b[4]
def test_perm_spaces(): pure_0a = PermSpace(4) pure_0b = PermSpace(range(4)) pure_0c = PermSpace(list(range(4))) pure_0d = PermSpace(iter(range(4))) assert pure_0a == pure_0b == pure_0c == pure_0d assert len(pure_0a) == len(pure_0b) == len(pure_0c) == len(pure_0d) assert repr(pure_0a) == repr(pure_0b) == repr(pure_0c) == \ repr(pure_0d) == '<PermSpace: 0..3>' assert repr(PermSpace(sequence_tools.CuteRange(3, 7))) == \ '<PermSpace: 3..6>' assert repr(PermSpace(sequence_tools.CuteRange(3, 7, 2))) == \ '<PermSpace: CuteRange(3, 7, 2)>' assert repr(PermSpace(tuple(sequence_tools.CuteRange(3, 7, 2)))) == \ '<PermSpace: (3, 5)>' assert cute_iter_tools.are_equal(pure_0a, pure_0b, pure_0c, pure_0d) assert set(map(bool, (pure_0a, pure_0b, pure_0c, pure_0d))) == {True} pure_perm_space = pure_0a assert pure_0a.is_pure assert not pure_0a.is_rapplied assert not pure_0a.is_dapplied assert not pure_0a.is_fixed assert not pure_0a.is_sliced first_perm = pure_0a[0] some_perm = pure_0a[7] last_perm = pure_0a[-1] assert first_perm.index(2) == 2 assert first_perm.index(0) == 0 with cute_testing.RaiseAssertor(ValueError): first_perm.index(5) assert last_perm.apply('meow') == 'woem' assert last_perm.apply('meow', str) == 'woem' assert last_perm.apply('meow', tuple) == tuple('woem') with cute_testing.RaiseAssertor(IndexError): pure_0a[-pure_0a.length - 1] with cute_testing.RaiseAssertor(IndexError): pure_0a[-pure_0a.length - 2] with cute_testing.RaiseAssertor(IndexError): pure_0a[-pure_0a.length - 30] with cute_testing.RaiseAssertor(IndexError): pure_0a[pure_0a.length] with cute_testing.RaiseAssertor(IndexError): pure_0a[pure_0a.length + 1] with cute_testing.RaiseAssertor(IndexError): pure_0a[pure_0a.length + 2] with cute_testing.RaiseAssertor(IndexError): pure_0a[pure_0a.length + 300] with cute_testing.RaiseAssertor(): pure_0a[24] assert pure_0a.take_random() in pure_0c # Testing hashing: pure_perm_space_dict = { pure_0a: 'a', pure_0b: 'b', pure_0c: 'c', pure_0d: 'd', } assert len(pure_perm_space_dict) == 1 # They're all the same assert pure_perm_space_dict[pure_0a] == pure_perm_space_dict[pure_0b] == \ pure_perm_space_dict[pure_0c] == pure_perm_space_dict[pure_0d] == 'd' assert None not in pure_0a # Because, damn. assert PermSpace('meow')[0] not in pure_0a assert type(first_perm) == type(some_perm) == type(last_perm) == Perm assert set(some_perm) == set(range(4)) assert tuple(first_perm) == (0, 1, 2, 3) assert tuple(last_perm) == (3, 2, 1, 0) assert Perm.coerce(first_perm) == first_perm assert Perm.coerce(first_perm, pure_0b) == first_perm assert Perm.coerce(tuple(first_perm)) == first_perm assert Perm.coerce(list(first_perm)) == first_perm assert Perm.coerce(tuple(first_perm), pure_0a) == first_perm assert Perm.coerce(list(first_perm), pure_0b) == first_perm assert Perm.coerce(tuple(first_perm), PermSpace(5, n_elements=4)) != \ first_perm assert isinstance(first_perm.items, combi.perming.perm.PermItems) assert first_perm.items[2] == (2, 2) assert repr(first_perm.items) == '<PermItems: %s>' % repr(first_perm) assert isinstance(first_perm.as_dictoid, combi.perming.perm.PermAsDictoid) assert first_perm.as_dictoid[2] == 2 assert dict(first_perm.as_dictoid) == {0: 0, 1: 1, 2: 2, 3: 3} assert not (first_perm != first_perm) assert first_perm == first_perm assert first_perm assert { pure_0a[4]: 1, pure_0b[4]: 2, pure_0c[4]: 3, } == { pure_0d[4]: 3, } assert some_perm.inverse == ~some_perm assert ~~some_perm == some_perm assert first_perm in pure_perm_space assert set(first_perm) not in pure_perm_space # No order? Not contained. assert some_perm in pure_perm_space assert last_perm in pure_perm_space assert tuple(first_perm) in pure_perm_space assert list(some_perm) in pure_perm_space assert iter(last_perm) in pure_perm_space assert 'meow' not in pure_perm_space assert (0, 1, 2, 3, 3) not in pure_perm_space assert pure_perm_space.index(first_perm) == 0 assert pure_perm_space.index(last_perm) == \ len(pure_perm_space) - 1 assert pure_perm_space.index(some_perm) == 7 assert 'meow' * Perm((1, 3, 2, 0)) == 'ewom' assert Perm('meow', 'meow') * Perm((1, 3, 2, 0)) == Perm('ewom', 'meow') assert [0, 1, 2, 3] * Perm((0, 1, 2, 3)) == (0, 1, 2, 3) assert Perm((0, 1, 2, 3)) * Perm((0, 1, 2, 3)) == Perm((0, 1, 2, 3)) assert Perm((2, 0, 1, 3)) * Perm((0, 1, 3, 2)) == Perm((2, 0, 3, 1)) assert (Perm((0, 1, 2, 3)) ** (- 2)) == (Perm((0, 1, 2, 3)) ** (- 1)) == \ (Perm((0, 1, 2, 3)) ** (0)) == (Perm((0, 1, 2, 3)) ** (1)) == \ (Perm((0, 1, 2, 3)) ** 2) == (Perm((0, 1, 2, 3)) ** 3) assert set(map(bool, (pure_0a[4:4], pure_0a[3:2]))) == {False} assert pure_0a[2:6][1:-1] == pure_0a[3:5] assert tuple(pure_0a[2:6][1:-1]) == tuple(pure_0a[3:5]) assert pure_0a[2:6][1:-1][1] == pure_0a[3:5][1] assert pure_0a[2:5][1:-1] != pure_0a[3:5] big_perm_space = PermSpace(range(150), fixed_map={ 1: 5, 70: 3, }, degrees=(3, 5)) assert big_perm_space == PermSpace(range(150), fixed_map={ 1: 5, 70: 3, }.items(), degrees=(3, 5)) for i in [10**10, 3 * 11**9 - 344, 4 * 12**8 - 5, 5 * 3**20 + 4]: perm = big_perm_space[i] assert big_perm_space.index(perm) == i repr_of_big_perm_space = repr(PermSpace(tuple(range(100, 0, -1)))) assert '...' in repr_of_big_perm_space assert len(repr_of_big_perm_space) <= 100 fixed_perm_space = pure_perm_space.get_fixed({ 0: 3, }) assert fixed_perm_space.length == 6 assert fixed_perm_space.is_fixed assert not fixed_perm_space.is_pure assert fixed_perm_space.unfixed.is_pure assert fixed_perm_space.unfixed == pure_perm_space assert pickle.loads(pickle.dumps(pure_perm_space)) == pure_perm_space assert pickle.loads(pickle.dumps(pure_0b[2])) == pure_0c[2] assert pickle.loads(pickle.dumps(pure_0b[3])) != pure_0b[4]
def __init__(self, iterable_or_length, n_elements=None, *, domain=None, fixed_map=None, degrees=None, is_combination=False, slice_=None, perm_type=None): ### Making basic argument checks: ##################################### # # assert isinstance( iterable_or_length, (collections.Iterable, numbers.Integral) ) if isinstance(iterable_or_length, numbers.Integral): assert iterable_or_length >= 0 if slice_ is not None: assert isinstance(slice_, (slice, sequence_tools.CanonicalSlice)) if slice_.step not in (1, None): raise NotImplementedError assert isinstance(n_elements, numbers.Integral) or n_elements is None assert isinstance(is_combination, bool) # # ### Finished making basic argument checks. ############################ ### Figuring out sequence and whether space is rapplied: ############## # # if isinstance(iterable_or_length, numbers.Integral): self.is_rapplied = False self.sequence = sequence_tools.CuteRange(iterable_or_length) self.sequence_length = iterable_or_length else: assert isinstance(iterable_or_length, collections.Iterable) self.sequence = sequence_tools. \ ensure_iterable_is_immutable_sequence(iterable_or_length) range_candidate = sequence_tools.CuteRange(len(self.sequence)) self.is_rapplied = not ( cute_iter_tools.are_equal(self.sequence, range_candidate) ) self.sequence_length = len(self.sequence) if not self.is_rapplied: self.sequence = sequence_tools.CuteRange(self.sequence_length) # # ### Finished figuring out sequence and whether space is rapplied. ##### ### Figuring out whether sequence is recurrent: ####################### # # if self.is_rapplied: self.is_recurrent = any(count >= 2 for count in self._frozen_ordered_bag.values()) else: self.is_recurrent = False # # ### Finished figuring out whether sequence is recurrent. ############## ### Figuring out number of elements: ################################## # # self.n_elements = self.sequence_length if (n_elements is None) \ else n_elements if not isinstance(self.n_elements, int): raise TypeError('`n_elements` must be an `int`.') if not self.n_elements >= 0: raise TypeError('`n_elements` must be positive or zero.') self.is_partial = (self.n_elements != self.sequence_length) self.indices = sequence_tools.CuteRange(self.n_elements) # # ### Finished figuring out number of elements. ######################### ### Figuring out whether it's a combination: ########################## # # self.is_combination = is_combination # Well that was quick. # # ### Finished figuring out whether it's a combination. ################# ### Figuring out whether space is dapplied: ########################### # # if domain is None: domain = self.indices domain = \ sequence_tools.ensure_iterable_is_immutable_sequence(domain) if self.is_partial: domain = domain[:self.n_elements] self.is_dapplied = not cute_iter_tools.are_equal( domain, self.indices ) if self.is_dapplied: if self.is_combination: raise UnallowedVariationSelectionException( {variations.Variation.DAPPLIED: True, variations.Variation.COMBINATION: True,} ) self.domain = domain if len(set(self.domain)) < len(self.domain): raise Exception('The domain must not have repeating elements.') else: self.domain = self.indices self.undapplied = self # # ### Finished figuring out whether space is dapplied. ################## ### Figuring out fixed map: ########################################### # # if fixed_map is None: fixed_map = {} if not isinstance(fixed_map, dict): if isinstance(fixed_map, collections.Callable): fixed_map = {item: fixed_map(item) for item in self.sequence} else: fixed_map = dict(fixed_map) if fixed_map: self.fixed_map = {key: value for (key, value) in fixed_map.items() if (key in self.domain) and (value in self.sequence)} else: (self.fixed_map, self.free_indices, self.free_keys, self.free_values) = ( {}, self.indices, self.domain, self.sequence ) self.is_fixed = bool(self.fixed_map) if self.is_fixed: if not (self.is_dapplied or self.is_rapplied or degrees or slice_ or (n_elements is not None) or self.is_combination): self._just_fixed = self else: self._get_just_fixed = lambda: PermSpace( len(self.sequence), fixed_map=self._undapplied_unrapplied_fixed_map, ) else: if not (self.is_dapplied or self.is_rapplied or degrees or slice_ or (n_elements is not None) or self.is_combination): self._just_fixed = self else: self._get_just_fixed = lambda: PermSpace(len(self.sequence)) # # ### Finished figuring out fixed map. ################################## ### Figuring out degrees: ############################################# # # all_degrees = sequence_tools.CuteRange(self.sequence_length) if degrees is None: degrees = () degrees = sequence_tools.to_tuple(degrees, item_type=int) if (not degrees) or cute_iter_tools.are_equal(degrees, all_degrees): self.is_degreed = False self.degrees = all_degrees else: self.is_degreed = True if self.is_combination: raise UnallowedVariationSelectionException( {variations.Variation.DEGREED: True, variations.Variation.COMBINATION: True,} ) if self.is_partial: raise UnallowedVariationSelectionException( {variations.Variation.DEGREED: True, variations.Variation.PARTIAL: True,} ) if self.is_recurrent: raise UnallowedVariationSelectionException( {variations.Variation.DEGREED: True, variations.Variation.RECURRENT: True,} ) # The space is degreed; we canonicalize `degrees` into a sorted # tuple. self.degrees = tuple(sorted( degree for degree in degrees if degree in all_degrees )) # # ### Finished figuring out degrees. #################################### ### Figuring out slice and length: #################################### # # self.slice_ = slice_ self.canonical_slice = sequence_tools.CanonicalSlice( slice_ or slice(float('inf')), self._unsliced_length ) self.length = max( self.canonical_slice.stop - self.canonical_slice.start, 0 ) self.is_sliced = (self.length != self._unsliced_length) # # ### Finished figuring out slice and length. ########################### ### Figuring out perm type: ########################################### # # self.is_typed = perm_type not in (None, self.default_perm_type) self.perm_type = perm_type if self.is_typed else self.default_perm_type assert issubclass(self.perm_type, Perm) # # ### Finished figuring out perm type. ################################## self.is_pure = not (self.is_rapplied or self.is_fixed or self.is_sliced or self.is_degreed or self.is_partial or self.is_combination or self.is_typed) if self.is_pure: self.purified = self if not self.is_rapplied: self.unrapplied = self if not self.is_recurrent: self.unrecurrented = self if not self.is_partial: self.unpartialled = self if not self.is_combination: self.uncombinationed = self # No need do this for `undapplied`, it's already done above. if not self.is_fixed: self.unfixed = self if not self.is_degreed: self.undegreed = self if not self.is_sliced: self.unsliced = self if not self.is_typed: self.untyped = self