コード例 #1
0
def are_equal(*sequences, easy_types=(sequence_tools.CuteRange,)):
    '''
    Are the given sequences equal?
    
    This tries to make a cheap comparison between the sequences if possible,
    but if not, it goes over the sequences in parallel item-by-item and checks
    whether the items are all equal. A cheap comparison is attempted only if
    the sequences are all of the same type, and that type is in `easy_types`.
    (It's important to restrict `easy_types` only to types where equality
    between the sequences is the same as equality between every item in the
    sequences.)
    '''
    from python_toolbox import logic_tools
    sequence_types = set(map(type, sequences))
    
    # Trying cheap comparison:
    if len(sequence_types) == 1 and issubclass(
                                get_single_if_any(sequence_types), easy_types):
        return logic_tools.all_equivalent(sequences)
    
    # If cheap comparison didn't work, trying item-by-item comparison:
    zipped = itertools.zip_longest(*sequences,
                                   fillvalue=_EMPTY_SENTINEL)
    for values in zipped:
        # No need to explicitly check for `_EMPTY_SENTINEL`, it would just make
        # the following condition `False`, because it's impossible for all
        # values to be the sentinel.
        if not logic_tools.all_equivalent(values):
            return False
    else:
        return True
コード例 #2
0
def are_equal(*sequences, **kwargs):
    '''
    Are the given sequences equal?
    
    This tries to make a cheap comparison between the sequences if possible,
    but if not, it goes over the sequences in parallel item-by-item and checks
    whether the items are all equal. A cheap comparison is attempted only if
    the sequences are all of the same type, and that type is in `easy_types`.
    (It's important to restrict `easy_types` only to types where equality
    between the sequences is the same as equality between every item in the
    sequences.)
    '''
    from python_toolbox import logic_tools
    sequence_types = set(map(type, sequences))

    easy_types = kwargs.get('easy_types', (sequence_tools.CuteRange, ))

    # Trying cheap comparison:
    if len(sequence_types) == 1 and issubclass(
            get_single_if_any(sequence_types), easy_types):
        return logic_tools.all_equivalent(sequences)

    # If cheap comparison didn't work, trying item-by-item comparison:
    zipped = itertools.izip_longest(*sequences, fillvalue=_EMPTY_SENTINEL)
    for values in zipped:
        # No need to explicitly check for `_EMPTY_SENTINEL`, it would just make
        # the following condition `False`, because it's impossible for all
        # values to be the sentinel.
        if not logic_tools.all_equivalent(values):
            return False
    else:
        return True
コード例 #3
0
def test_assume_transitive_false():
    '''
    Test `all_equivalent` in cases where `assume_transitive=False` is relevant.
    '''
    class FunkyFloat(float):
        def __eq__(self, other):
            return (abs(self - other) <= 2)

    funky_floats = [FunkyFloat(1), FunkyFloat(2), FunkyFloat(3), FunkyFloat(4)]

    assert all_equivalent(funky_floats)
    assert not all_equivalent(funky_floats, assume_transitive=False)
コード例 #4
0
def cute_equal(*items):
    # For testing purposes, we need `nan == nan`, so we use `cute_equal`.
    if all(isinstance(item, numbers.Number) for item in items):
        if all(map(math.isnan, items)): return True
        else: return logic_tools.all_equivalent(items)
    else:
        assert all(isinstance(item, tuple) for item in items)
        return all(cute_equal(*sub_items) for sub_items in zip(*items))
コード例 #5
0
def cute_equal(*items):
    # For testing purposes, we need `nan == nan`, so we use `cute_equal`.
    if all(isinstance(item, numbers.Number) for item in items):
        if all(map(math.isnan, items)): return True
        else: return logic_tools.all_equivalent(items)
    else:
        assert all(isinstance(item, tuple) for item in items)
        return all(cute_equal(*sub_items) for sub_items in zip(*items))
コード例 #6
0
def test_assume_transitive_false():
    '''
    Test `all_equivalent` in cases where `assume_transitive=False` is relevant.
    '''
    
    class FunkyFloat(float):
        def __eq__(self, other):
            return (abs(self - other) <= 2)
        
    funky_floats = [
        FunkyFloat(1),
        FunkyFloat(2),
        FunkyFloat(3),
        FunkyFloat(4)
    ]
    
    assert all_equivalent(funky_floats)
    assert not all_equivalent(funky_floats, assume_transitive=False)
コード例 #7
0
 def get_pairs_for_options(**kwargs):
     assert EquivalenceChecker.pairs_checked == []
     # Testing with an iterator instead of the tuple to ensure it works and that
     # the function doesn't try to exhaust it twice.
     assert all_equivalent(iter(things), EquivalenceChecker.is_equivalent,
                           **kwargs) is True
     try:
         return tuple((a.tag, b.tag) for (a, b) in
                      EquivalenceChecker.pairs_checked)
     finally:
         EquivalenceChecker.pairs_checked = []
コード例 #8
0
 def get_pairs_for_options(**kwargs):
     assert EquivalenceChecker.pairs_checked == []
     # Testing with an iterator instead of the tuple to ensure it works and that
     # the function doesn't try to exhaust it twice.
     assert all_equivalent(iter(things), EquivalenceChecker.is_equivalent,
                           **kwargs) is True
     try:
         return tuple(
             (a.tag, b.tag) for (a, b) in EquivalenceChecker.pairs_checked)
     finally:
         EquivalenceChecker.pairs_checked = []
コード例 #9
0
def zip_non_equal(iterables, lazy_tuple=False):
    '''
    Zip the iterables, but only yield the tuples where the items aren't equal.
    '''
    from python_toolbox import logic_tools
    iterator = (items for items in zip(*iterables)
                if not logic_tools.all_equivalent(items))

    if lazy_tuple:
        from python_toolbox import nifty_collections
        return nifty_collections.LazyTuple(iterator)
    else:
        return iterator
コード例 #10
0
def zip_non_equal(iterables, lazy_tuple=False):
    '''
    Zip the iterables, but only yield the tuples where the items aren't equal.
    '''
    from python_toolbox import logic_tools
    iterator = (items for items in zip(*iterables)
                if not logic_tools.all_equivalent(items))

    if lazy_tuple:
        from python_toolbox import nifty_collections
        return nifty_collections.LazyTuple(iterator)
    else:
        return iterator
コード例 #11
0
def test_illegal_cases():
    illegal_cases = ((4, 0), (infinity, 0), (-infinity, 0))
    for illegal_case in illegal_cases:
        with cute_testing.RaiseAssertor() as raise_assertor_0:
            cute_divmod(*illegal_case)
        with cute_testing.RaiseAssertor() as raise_assertor_1:
            divmod(*illegal_case)
        with cute_testing.RaiseAssertor() as raise_assertor_2:
            cute_floor_div(*illegal_case)
        assert logic_tools.all_equivalent((
            type(raise_assertor_0.exception),
            type(raise_assertor_1.exception),
            type(raise_assertor_2.exception),
        ))
コード例 #12
0
def test_illegal_cases():
    illegal_cases = (
        (4, 0), (infinity, 0), (-infinity, 0)
    )
    for illegal_case in illegal_cases:
        with cute_testing.RaiseAssertor() as raise_assertor_0:
            cute_divmod(*illegal_case)
        with cute_testing.RaiseAssertor() as raise_assertor_1:
            divmod(*illegal_case)
        with cute_testing.RaiseAssertor() as raise_assertor_2:
            cute_floor_div(*illegal_case)
        assert logic_tools.all_equivalent((
            type(raise_assertor_0.exception),
            type(raise_assertor_1.exception),
            type(raise_assertor_2.exception),
        ))
コード例 #13
0
ファイル: shared.py プロジェクト: gluttony47/python_toolbox
def call_and_check_if_profiled(f):
    '''Call the function `f` and return whether it profiled itself.'''

    with OutputCapturer() as output_capturer:
        f()

    output = output_capturer.output

    segments_found = [(segment in output) for segment in segments]

    if not logic_tools.all_equivalent(segments_found):
        raise Exception("Some segments were found, but some weren't; can't "
                        "know if this was a profiled call or not. Possibly "
                        "some of our segments are wrong.")

    return segments_found[0]
コード例 #14
0
def test_custom_relations():
    assert all_equivalent(range(4), relation=operator.ne) is True
    assert all_equivalent(range(4), relation=operator.ge) is False
    assert all_equivalent(range(4), relation=operator.le) is True
    assert all_equivalent(
        range(4), relation=operator.le, assume_transitive=True) is True
    # (Always comparing small to big, even on `assume_transitive=False`.)

    assert all_equivalent(range(4), relation=lambda x, y:
                          (x // 10 == y // 10)) is True
    assert all_equivalent(range(4),
                          relation=lambda x, y: (x // 10 == y // 10),
                          assume_transitive=True) is True
    assert all_equivalent(range(8, 12),
                          relation=lambda x, y: (x // 10 == y // 10)) is False
    assert all_equivalent(range(8, 12),
                          relation=lambda x, y: (x // 10 == y // 10),
                          assume_transitive=True) is False
コード例 #15
0
def test_operations_on_different_types():
    x1 = OrderedSet(range(0, 4)) | FrozenOrderedSet(range(2, 6))
    x2 = OrderedSet(range(0, 4)) & FrozenOrderedSet(range(2, 6))
    x3 = FrozenOrderedSet(range(0, 4)) | OrderedSet(range(2, 6))
    x4 = FrozenOrderedSet(range(0, 4)) & OrderedSet(range(2, 6))

    assert type(x1) == OrderedSet
    assert type(x2) == OrderedSet
    assert type(x3) == FrozenOrderedSet
    assert type(x4) == FrozenOrderedSet

    assert x1 == OrderedSet(range(0, 6))
    assert x2 == OrderedSet(range(2, 4))
    assert x3 == FrozenOrderedSet(range(0, 6))
    assert x4 == FrozenOrderedSet(range(2, 4))

    assert logic_tools.all_equivalent((x1, x2, x3, x4), relation=operator.ne)
コード例 #16
0
def test_custom_relations():
    assert all_equivalent(range(4), relation=operator.ne) is True
    assert all_equivalent(range(4), relation=operator.ge) is False
    assert all_equivalent(range(4), relation=operator.le) is True
    assert all_equivalent(range(4), relation=operator.le,
                          assume_transitive=True) is True
    # (Always comparing small to big, even on `assume_transitive=False`.)
    
    assert all_equivalent(range(4),
                          relation=lambda x, y: (x // 10 == y // 10)) is True
    assert all_equivalent(range(4),
                          relation=lambda x, y: (x // 10 == y // 10),
                          assume_transitive=True) is True
    assert all_equivalent(range(8, 12), 
                          relation=lambda x, y: (x // 10 == y // 10)) is False
    assert all_equivalent(range(8, 12),
                          relation=lambda x, y: (x // 10 == y // 10),
                          assume_transitive=True) is False
    
コード例 #17
0
def test_operations_on_different_types():
    x1 = OrderedSet(range(0, 4)) | FrozenOrderedSet(range(2, 6))
    x2 = OrderedSet(range(0, 4)) & FrozenOrderedSet(range(2, 6))
    x3 = FrozenOrderedSet(range(0, 4)) | OrderedSet(range(2, 6))
    x4 = FrozenOrderedSet(range(0, 4)) & OrderedSet(range(2, 6))
    
    assert type(x1) == OrderedSet
    assert type(x2) == OrderedSet
    assert type(x3) == FrozenOrderedSet
    assert type(x4) == FrozenOrderedSet
    
    assert x1 == OrderedSet(range(0, 6))
    assert x2 == OrderedSet(range(2, 4))
    assert x3 == FrozenOrderedSet(range(0, 6))
    assert x4 == FrozenOrderedSet(range(2, 4))
    
    assert logic_tools.all_equivalent((x1, x2, x3, x4),
                                      relation=operator.ne)
コード例 #18
0
ファイル: shared.py プロジェクト: cool-RR/python_toolbox
def call_and_check_if_profiled(f):
    '''Call the function `f` and return whether it profiled itself.'''
    
    with OutputCapturer() as output_capturer:
        f()
    
    output = output_capturer.output
        
    segments_found = [(segment in output) for segment in segments]
    
    if not logic_tools.all_equivalent(segments_found):
        raise Exception("Some segments were found, but some weren't; can't "
                        "know if this was a profiled call or not. Possibly "
                        "some of our segments are wrong.")
    
    return segments_found[0]
    
    
    
コード例 #19
0
def _check(assume_transitive):
    assert all_equivalent([1, 1, 1, 1], assume_transitive=assume_transitive)
    assert all_equivalent([1, 1, 1.0, 1], assume_transitive=assume_transitive)
    assert all_equivalent(((1 + 0j), 1, 1.0, 1),
                          assume_transitive=assume_transitive)
    assert all_equivalent([], assume_transitive=assume_transitive)
    assert all_equivalent(iter([1, 1, 1.0, 1]),
                          assume_transitive=assume_transitive)
    assert all_equivalent(set(('meow',)), assume_transitive=assume_transitive)
    assert all_equivalent(['frr', 'frr', 'frr', 'frr'],
                          assume_transitive=assume_transitive)
    
    assert not all_equivalent([1, 1, 2, 1],
                              assume_transitive=assume_transitive)
    assert not all_equivalent([1, 1, 1.001, 1],
                              assume_transitive=assume_transitive)
    assert not all_equivalent(((1 + 0j), 3, 1.0, 1),
                              assume_transitive=assume_transitive)
    assert not all_equivalent(range(7), assume_transitive=assume_transitive)
    assert not all_equivalent(iter([1, 17, 1.0, 1]),
                              assume_transitive=assume_transitive)
    assert not all_equivalent(set(('meow', 'grr')),
                              assume_transitive=assume_transitive)
    assert not all_equivalent(['frr', 'frr', {}, 'frr', 'frr'],
                              assume_transitive=assume_transitive)
    assert not all_equivalent(itertools.count())
コード例 #20
0
def assert_same_signature(*callables):
    '''Assert that all the `callables` have the same function signature.'''
    arg_specs = [cute_inspect.getargspec(callable_) for callable_ in callables]
    if not logic_tools.all_equivalent(arg_specs, assume_transitive=False):
        raise Failure('Not all the callables have the same signature.')
コード例 #21
0
def assert_same_signature(*callables):
    '''Assert that all the `callables` have the same function signature.'''
    arg_specs = [cute_inspect.getargspec(callable_) for callable_ in callables]
    if not logic_tools.all_equivalent(arg_specs, assume_transitive=False):
        raise Failure('Not all the callables have the same signature.')
コード例 #22
0
def _check(assume_transitive):
    assert all_equivalent([1, 1, 1, 1], assume_transitive=assume_transitive)
    assert all_equivalent([1, 1, 1.0, 1], assume_transitive=assume_transitive)
    assert all_equivalent(((1 + 0j), 1, 1.0, 1),
                          assume_transitive=assume_transitive)
    assert all_equivalent([], assume_transitive=assume_transitive)
    assert all_equivalent(iter([1, 1, 1.0, 1]),
                          assume_transitive=assume_transitive)
    assert all_equivalent(set(('meow', )), assume_transitive=assume_transitive)
    assert all_equivalent(['frr', 'frr', 'frr', 'frr'],
                          assume_transitive=assume_transitive)

    assert not all_equivalent([1, 1, 2, 1],
                              assume_transitive=assume_transitive)
    assert not all_equivalent([1, 1, 1.001, 1],
                              assume_transitive=assume_transitive)
    assert not all_equivalent(
        ((1 + 0j), 3, 1.0, 1), assume_transitive=assume_transitive)
    assert not all_equivalent(range(7), assume_transitive=assume_transitive)
    assert not all_equivalent(iter([1, 17, 1.0, 1]),
                              assume_transitive=assume_transitive)
    assert not all_equivalent(set(('meow', 'grr')),
                              assume_transitive=assume_transitive)
    assert not all_equivalent(['frr', 'frr', {}, 'frr', 'frr'],
                              assume_transitive=assume_transitive)
    assert not all_equivalent(itertools.count())