design a Condition class

bruno at modulix onurb at xiludom.gro
Fri May 12 14:55:28 CEST 2006


joh12005 at yahoo.fr wrote:
> Hello,
> 
> i posted for suggestions a little idea even if it still needs further
> thoughts but as i'm sure you could help :)
> 
> if would like to implement some kind of Condition class which i coud
> use to build bricks of more complex condition, conditions are based on
> fields by using regexp
> 
> class Condition:

Do yourself a favor and use newstyle classes:
class Condition(object):
> 	def __init__(self, field0, field1, field2):
> 		self.field0 = field0
> 		self.field1 = field1
> 		self.field2 = field2
> 	def match(self, against):
> 		w, t, l = against
> 		f0 = False
> 		if self.field0 is None:
> 			f0 = True
> 		else:
> 			f0 = self.field0.search(w)
> 		if self.field1 is None:
> 			f1 = True
> 		else:
> 			f1 = self.field1.search(t)
> 		if self.field2 is None:
> 			f2 = True
> 		else:
> 			f2 = self.field2.search(l)
> 		return f0 and f1 and f2

> c0 = Condition(re.compile("something"), None,
> re.compile("somethingelse"))
> c1 = Condition(re.compile("another"), None, None)
> 
> i can use
> 
> if c0.search(myitem)

Have you actually tested this ?-)
(hint : the method name is 'match', not 'search')


> 
> but i would like to be able to have composition such as :
> 
> c2 = c0 | c1
> 
> which should be understood as defining a new c2 which is able to match
> (c0 or c1) from c0 and c1 already defined.
> 
> actually i can imagine a
> 
> def OR(c0, c1):
>      # here => missing None support 'a or None' is 'a'
>      return Condition(re.compile("|".join((c0.field0.pattern,
> c1.field0.pattern)),
>               re.compile("|".join((c0.field1.pattern,
> c1.field1.pattern)),
>               re.compile("|".join((c0.field2.pattern,
> c1.field2.pattern))
> 
> the idea is to build c2 = Condition(re.compile("something|another"),
> None, re.compile("somethingelse"))
> c2 = OR(c0, c1)
>
> but maybe have you clever suggestions ?

use the __or__(self, other) special method.
http://www.python.org/doc/2.4.2/ref/numeric-types.html


Here is a somewhat rewritten, hopefully more pythonic version - will
need some more works, specially wrt/ error handling :

class Condition(object):
    def __init__(self, *exps):
        self._exps = exps

    def match(self, *targets):
        # don't know how you want to handle this case
        assert len(targets) == len(self._exps), \
            "expected %d args, got %d" % (len(self._exps), len(targets))

        for exp, target in zip(self._exps, targets):
            # takes care of None in the expression list
            if not (exp is None or exp.search(target)):
                return False
        return True

    def __or__(self, other):
        """ cf http://www.python.org/doc/2.4.2/ref/numeric-types.html

        """
        # I let you take care of all error handling...
        # take care of what happens if
        # len(other._exps) != len(self._exps)
        # NB : itertools might be of some help here
        exps = [re.compile("(%s)|(%s)" % (e1.pattern, e2.pattern)) \
                for e1, e2 in zip(self._exps, other._exps)]
        return self.__class__(*exps)


HTH
-- 
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'onurb at xiludom.gro'.split('@')])"



More information about the Python-list mailing list