def get_contained_bags(self): ''' Get all bags that are subsets of this bag. This means all bags that have counts identical or smaller for each key. ''' from python_toolbox import combi keys, amounts = zip(*((key, amount) for key, amount in self.items())) return combi.MapSpace( lambda amounts_tuple: type(self) (self._dict_type(zip(keys, amounts_tuple))), combi.ProductSpace(map(lambda amount: range(amount + 1), amounts)))
def test_perm_type(): class Suit(nifty_collections.CuteEnum): club = 'club' diamond = 'diamond' heart = 'heart' spade = 'spade' @functools.total_ordering class Card(): def __init__(self, number_and_suit): number, suit = number_and_suit assert number in range(1, 14) assert isinstance(suit, Suit) self.number = number self.suit = suit _sequence = \ caching.CachedProperty(lambda self: (self.number, self.suit)) _reduced = \ caching.CachedProperty(lambda self: (type(self), self._sequence)) def __lt__(self, other): if not isinstance(other, Card): return NotImplemented return self._sequence < other._sequence def __eq__(self, other): return type(self) == type(other) and \ self._sequence == other._sequence __hash__ = lambda self: hash(self._reduced) __repr__ = lambda self: '%s%s' % (self.number if self.number <= 10 else 'jqk'[self.number - 11], str(self.suit.name)[0].capitalize()) card_space = combi.MapSpace(Card, combi.ProductSpace((range(1, 14), Suit))) class PokerHandSpace(combi.CombSpace): def __init__(self): super().__init__(card_space, 5, perm_type=PokerHand) class PokerHand(combi.Comb): @caching.CachedProperty def stupid_score(self): return tuple( zip(*nifty_collections.Bag(card.number for card in self).most_common()))[1] poker_hand_space = PokerHandSpace() assert isinstance(poker_hand_space[0], PokerHand) some_poker_hands = MapSpace(poker_hand_space.__getitem__, range(1000000, 2000000, 17060)) some_poker_hand_scores = set(poker_hand.stupid_score for poker_hand in some_poker_hands) assert (1, 1, 1, 1, 1) in some_poker_hand_scores assert (2, 1, 1, 1) in some_poker_hand_scores assert (2, 2, 1) in some_poker_hand_scores assert (3, 1, 1) in some_poker_hand_scores card_comb_sequence = (Card((1, Suit.club)), Card( (2, Suit.diamond)), Card((3, Suit.heart)), Card( (4, Suit.spade)), Card((5, Suit.club))) assert cute_iter_tools.is_sorted(card_comb_sequence) assert card_comb_sequence in poker_hand_space assert PokerHand(card_comb_sequence, poker_hand_space) in poker_hand_space assert card_comb_sequence[::-1] not in poker_hand_space assert PokerHand(card_comb_sequence[::-1], poker_hand_space) \ not in poker_hand_space assert PokerHand(card_comb_sequence, poker_hand_space).stupid_score == \ (1, 1, 1, 1, 1)