def __ipow__(self, other, modulo=None): '''Raise each count in this bag to the power of `other`.''' if not math_tools.is_integer(other): return NotImplemented for key in tuple(self): self[key] = pow(self[key], other, modulo) return self
def __divmod__(self, other): ''' Get `(self // other, self % other)`. If `other` is an integer, the first item of the result will be the biggest bag possible so that `result * other <= self`. The second item will be a bag with `% other` done on the count of every item from `self`, or you can also think of it as `self - (self // other)`, which happens to be the same bag. If `other` is a bag, the first item of the result will be the maximum number of times you can put `other` inside of `self` without having it surpass `self` for any key. (Or in other words, the biggest integer possible so that `result * other <= self`.) The second item will be the result of the first item subtracted from `self`. ''' if math_tools.is_integer(other): return ( type(self)(self._dict_type( (key, count // other) for key, count in self.items())), type(self)(self._dict_type( (key, count % other) for key, count in self.items())), ) elif isinstance(other, _BaseBagMixin): floordiv_result = self // other mod_result = type(self)(self._dict_type( (key, count - other[key] * floordiv_result) for key, count in self.items())) return (floordiv_result, mod_result) else: return NotImplemented
def __imul__(self, other): '''Multiply all the counts in this bag by the integer `other`.''' if not math_tools.is_integer(other): return NotImplemented for key in tuple(self): self[key] *= other return self
def __floordiv__(self, other): ''' Do a floor-division `self // other`. `other` can be either an integer or a bag. If `other` is an integer, the result will be the biggest bag possible so that `result * other <= self`. If `other` is a bag, the result will be the maximum number of times you can put `other` inside of `self` without having it surpass `self` for any key. (Or in other words, the biggest integer possible so that `result * other <= self`.) ''' if math_tools.is_integer(other): return (type(self)(self._dict_type( (key, count // other) for key, count in self.items()))) elif isinstance(other, _BaseBagMixin): for key in other: if key not in self: assert other[key] >= 1 return 0 division_results = [] for key in self: if other[key] >= 1: division_results.append(self[key] // other[key]) if division_results: return min(division_results) else: raise ZeroDivisionError else: return NotImplemented
def __imod__(self, other): ''' Make this bag int a modulo `self % other`. `other` can be either an integer or a bag. If `other` is an integer, the result will have all its counts modulo-ed by `other`. Or you can also think of it as becoming the bag `self - (self // other)`, which happens to be the same bag. If `other` is a bag, the result will be the bag that's left when you subtract as many copies of `other` from this bag, until you can't subtract without truncating some keys. Or in other words, it's `self - (self // other)`. Since this result is an integer rather than a bug, the result variable will be set to it but this bag wouldn't really be modified. ''' if math_tools.is_integer(other): for key in tuple(self): self[key] %= other return self elif isinstance(other, _BaseBagMixin): floordiv_result = self // other self %= floordiv_result return self else: return NotImplemented
def __floordiv__(self, other): ''' Do a floor-division `self // other`. `other` can be either an integer or a bag. If `other` is an integer, the result will be the biggest bag possible so that `result * other <= self`. If `other` is a bag, the result will be the maximum number of times you can put `other` inside of `self` without having it surpass `self` for any key. (Or in other words, the biggest integer possible so that `result * other <= self`.) ''' if math_tools.is_integer(other): return ( type(self)(self._dict_type((key, count // other) for key, count in self.items())) ) elif isinstance(other, _BaseBagMixin): for key in other: if key not in self: assert other[key] >= 1 return 0 division_results = [] for key in self: if other[key] >= 1: division_results.append(self[key] // other[key]) if division_results: return min(division_results) else: raise ZeroDivisionError else: return NotImplemented
def __divmod__(self, other): ''' Get `(self // other, self % other)`. If `other` is an integer, the first item of the result will be the biggest bag possible so that `result * other <= self`. The second item will be a bag with `% other` done on the count of every item from `self`, or you can also think of it as `self - (self // other)`, which happens to be the same bag. If `other` is a bag, the first item of the result will be the maximum number of times you can put `other` inside of `self` without having it surpass `self` for any key. (Or in other words, the biggest integer possible so that `result * other <= self`.) The second item will be the result of the first item subtracted from `self`. ''' if math_tools.is_integer(other): return ( type(self)(self._dict_type((key, count // other) for key, count in self.items())), type(self)(self._dict_type((key, count % other) for key, count in self.items())), ) elif isinstance(other, _BaseBagMixin): floordiv_result = self // other mod_result = type(self)( self._dict_type((key, count - other[key] * floordiv_result) for key, count in self.items()) ) return (floordiv_result, mod_result) else: return NotImplemented
def __pow__(self, other, modulo=None): '''Get a new bag with every item raised to the power of `other`.''' if not math_tools.is_integer(other): return NotImplemented if modulo is None: return type(self)(self._dict_type( (key, count**other) for key, count in self.items())) else: return type(self)(self._dict_type((key, pow(count, other, modulo)) for key, count in self.items()))
def __pow__(self, other, modulo=None): '''Get a new bag with every item raised to the power of `other`.''' if not math_tools.is_integer(other): return NotImplemented if modulo is None: return type(self)(self._dict_type((key, count ** other) for key, count in self.items())) else: return type(self)(self._dict_type( (key, pow(count, other, modulo)) for key, count in self.items()) )
def _process_count(count): '''Process a count of an item to ensure it's a positive `int`.''' if not math_tools.is_integer(count): raise TypeError( 'You passed %s as a count, while a `Bag` can only handle integer ' 'counts.' % repr(count)) if count < 0: raise TypeError( "You passed %s as a count, while `Bag` doesn't support negative " "amounts." % repr(count)) if count == 0: raise _ZeroCountAttempted return int(count)
def _process_count(count): '''Process a count of an item to ensure it's a positive `int`.''' if not math_tools.is_integer(count): raise TypeError( 'You passed %s as a count, while a `Bag` can only handle integer ' 'counts.' % repr(count) ) if count < 0: raise TypeError( "You passed %s as a count, while `Bag` doesn't support negative " "amounts." % repr(count) ) if count == 0: raise _ZeroCountAttempted return int(count)
def __mod__(self, other): ''' Do a modulo `self % other`. `other` can be either an integer or a bag. If `other` is an integer, the result will be a bag with `% other` done on the count of every item from `self`. Or you can also think of it as `self - (self // other)`, which happens to be the same bag. If `other` is a bag, the result will be the bag that's left when you subtract as many copies of `other` from this bag, until you can't subtract without truncating some keys. Or in other words, it's `self - (self // other)`. ''' if math_tools.is_integer(other): return (type(self)(self._dict_type( (key, count % other) for key, count in self.items()))) elif isinstance(other, _BaseBagMixin): return divmod(self, other)[1] else: return NotImplemented
def __ifloordiv__(self, other): ''' Make this bag into a floor-division `self // other`. `other` can be either an integer or a bag. If `other` is an integer, this bag will have all its counts floor-divided by `other`. (You can also think of it as: This bag will become the biggest bag possible so that if you multiply it by `other`, it'll still be smaller or equal to its old `self`.) If `other` is a bag, the result will be the maximum number of times you can put `other` inside of `self` without having it surpass `self` for any key. (Or in other words, the biggest integer possible so that `result * other <= self`.) Since this result is an integer rather than a bug, the result variable will be set to it but this bag wouldn't really be modified. ''' if not math_tools.is_integer(other): return NotImplemented for key in tuple(self): self[key] //= other return self
def __mod__(self, other): ''' Do a modulo `self % other`. `other` can be either an integer or a bag. If `other` is an integer, the result will be a bag with `% other` done on the count of every item from `self`. Or you can also think of it as `self - (self // other)`, which happens to be the same bag. If `other` is a bag, the result will be the bag that's left when you subtract as many copies of `other` from this bag, until you can't subtract without truncating some keys. Or in other words, it's `self - (self // other)`. ''' if math_tools.is_integer(other): return ( type(self)(self._dict_type((key, count % other) for key, count in self.items())) ) elif isinstance(other, _BaseBagMixin): return divmod(self, other)[1] else: return NotImplemented
def __mul__(self, other): '''Get a new bag that has all counts multiplied by the integer `other`.''' if not math_tools.is_integer(other): return NotImplemented return type(self)(self._dict_type( (key, count * other) for key, count in self.items()))
def __mul__(self, other): '''Get a new bag that has all counts multiplied by the integer `other`.''' if not math_tools.is_integer(other): return NotImplemented return type(self)(self._dict_type((key, count * other) for key, count in self.items()))