def test_andnot():
    lm1 = matching.ListMatcher([1, 4, 10, 20, 90])
    lm2 = matching.ListMatcher([0, 4, 20])
    anm = matching.AndNotMatcher(lm1, lm2)
    ls = []
    while anm.is_active():
        ls.append((anm.id(), anm.score()))
        anm.next()
    assert ls == [(1, 1.0), (10, 1.0), (90, 1.0)]

    echo_lm = matching.ListMatcher([0, 1, 2, 3, 4])
    bravo_lm = matching.ListMatcher([0, 1])
    anm = matching.AndNotMatcher(echo_lm, bravo_lm)
    assert list(anm.all_ids()) == [2, 3, 4]

    lm1 = matching.ListMatcher([1, 4, 10, 20, 90])
    lm2 = matching.ListMatcher([0, 4, 20])
    anm = matching.AndNotMatcher(lm1, lm2)
    assert list(anm.all_ids()) == [1, 10, 90]

    lm1 = matching.ListMatcher([1, 4, 10, 20, 90])
    lm2 = matching.ListMatcher([0, 4, 20])
    anm = matching.AndNotMatcher(lm1, lm2)
    anm.next()
    anm.next()
    anm = anm.copy()
    ls = []
    while anm.is_active():
        ls.append(anm.id())
        anm.next()
    assert ls == [90]
def test_empty_andnot():
    pos = matching.NullMatcher()
    neg = matching.NullMatcher()
    anm = matching.AndNotMatcher(pos, neg)
    assert not anm.is_active()
    assert not list(anm.all_ids())

    pos = matching.ListMatcher([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
    neg = matching.NullMatcher()
    ans = matching.AndNotMatcher(pos, neg)
    ids = list(ans.all_ids())
    assert ids == [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
def test_random_andnot():
    testcount = 100
    rangesize = 100

    rng = list(range(rangesize))

    for _ in xrange(testcount):
        negs = sorted(sample(rng, randint(0, rangesize - 1)))
        negset = frozenset(negs)
        matched = [n for n in rng if n not in negset]

        pos = matching.ListMatcher(rng)
        neg = matching.ListMatcher(negs)

        anm = matching.AndNotMatcher(pos, neg)
        ids = list(anm.all_ids())
        assert ids == matched
예제 #4
0
파일: nary.py 프로젝트: skrieder/microblog
    def _matcher(self, matchercls, q_weight_fn, searcher, weighting=None,
                 **kwargs):
        # q_weight_fn is a function which is called on each query and returns a
        # "weight" value which is used to build a huffman-like matcher tree. If
        # q_weight_fn is None, an order-preserving binary tree is used instead.

        # Pull any queries inside a Not() out into their own list
        subs, nots = self._split_queries()

        if not subs:
            return matching.NullMatcher()

        # Create a matcher from the list of subqueries
        subms = [q.matcher(searcher, weighting=weighting) for q in subs]
        if len(subms) == 1:
            m = subms[0]
        elif q_weight_fn is None:
            m = make_binary_tree(matchercls, subms)
        else:
            w_subms = [(q_weight_fn(q), m) for q, m in zip(subs, subms)]
            m = make_weighted_tree(matchercls, w_subms)

        # If there were queries inside Not(), make a matcher for them and
        # wrap the matchers in an AndNotMatcher
        if nots:
            if len(nots) == 1:
                notm = nots[0].matcher(searcher)
            else:
                r = searcher.reader()
                notms = [(q.estimate_size(r), q.matcher(searcher))
                         for q in nots]
                notm = make_weighted_tree(matching.UnionMatcher, notms)

            if notm.is_active():
                m = matching.AndNotMatcher(m, notm)

        # If this query had a boost, add a wrapping matcher to apply the boost
        if self.boost != 1.0:
            m = matching.WrappingMatcher(m, self.boost)

        return m
예제 #5
0
 def matcher(self, searcher, context=None):
     scoredm = self.a.matcher(searcher, context)
     requiredm = self.b.matcher(searcher, searcher.boolean_context())
     return matching.AndNotMatcher(scoredm, requiredm)