예제 #1
0
 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
예제 #2
0
 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
예제 #3
0
 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
예제 #4
0
 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
예제 #5
0
    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
예제 #6
0
 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
예제 #7
0
 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
예제 #8
0
 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
예제 #9
0
 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
예제 #10
0
    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
예제 #11
0
 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()))
예제 #12
0
 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())
         )
예제 #13
0
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(
            f'You passed {repr(count)} as a count, while a `Bag` can only '
            f'handle integer counts.')
    if count < 0:
        raise TypeError(
            f"You passed {repr(count)} as a count, while `Bag` doesn't support"
            f"negative amounts.")

    if count == 0:
        raise _ZeroCountAttempted

    return int(count)
예제 #14
0
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)
예제 #15
0
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)
예제 #16
0
 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
예제 #17
0
 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
예제 #18
0
 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
예제 #19
0
 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
예제 #20
0
 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()))
예제 #21
0
 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()))