design a Condition class

J

joh12005

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:
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)

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 ?

best regards.
 
C

Carl J. Van Arsdall

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
I just wanted to make the comment that there already exists a
Condition() class in the threading module. If you plan on using your
class with the threading module you might wish to use another name.

-carl


--

Carl J. Van Arsdall
(e-mail address removed)
Build and Release
MontaVista Software
 
P

Paul McGuire

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:
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)

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 ?

best regards.

Your composition of expressions to match is very similar to the definition
of grammars in pyparsing. Here's a small example, to parse "Hello,
World!"-type strings.


from pyparsing import Word, alphas

# define grammar
greet = Word( alphas ) + "," + Word( alphas ) + "!"

# input string
hello = "Hello, World!"

# parse input string
print hello, "->", greet.parseString( hello )


The Word class matches any group of characters composed of the letters in
the string passed to the constructor. alphas is a string constant of the
upper and lower case letters A thru Z. This sample program prints out:

Hello, World! -> ['Hello', ',', 'World', '!']

pyparsing has many more expression types, including Literal,
CaselessLiteral, Optional, ZeroOrMore, and OneOrMore. There are also
combining forms, And, Or, MatchFirst, and Each. The handy part of these
combining forms is that there are operator short-cuts:
a + b is the same as And([a,b]) (that is, a followed by b)
a | b is the same as MatchFirst([a,b]) (if not match a, then try to match b)
a ^ b is the same as Or([a,b]) (try matching a and b, choose longest match)
a @ b is the same as Each([a,b]) (match a and b in any order - good for
matching options that can be specified in any order)

The resulting grammar expressions are fairly readable. The greet expression
above translates to

greet is a word group of alphabetic characters, followed by a ",", followed
by another word group of alphabetic characters, followed by a "!". Note
that there is no explicit specification of whitespace - whitespace will
terminate a word group, but is not necessary if the grammar is unambiguous
without it. For instance, this expression will match any of:

Hello,World!
Hello , World !
Hello ,World !
.... and so on.

Of course it will also match:
Howdy, pardner!
Greetings, Earthling!
Aloha, wahini!

The matched results are returned as an object of type ParseResults, which
can be accessed like a list, a dictionary, or an object with attributes (if
you associated names with individual elements of the parse expression).

You can get more info and download info at pyparsing.wikispaces.com. Even
if you choose not to use pyparsing, you might get some ideas on your own
implementation.

-- Paul
 
B

bruno at modulix

Carl J. Van Arsdall wrote:
(snip)
I just wanted to make the comment that there already exists a
Condition() class in the threading module. If you plan on using your
class with the threading module you might wish to use another name.
As far as I remember, Python has namespaces, so I don't see the point
here...
 
B

bruno at modulix

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,297
Messages
2,571,529
Members
48,240
Latest member
เพิ่มไลค์|LikePro

Latest Threads

Top