Package rdkit :: Package VLib :: Module Filter

[hide private]
[frames] | no frames]

# Source Code for Module rdkit.VLib.Filter

      1  #  $Id$
      2  #
      3  #  Copyright (C) 2003 Rational Discovery LLC
      4  #     All Rights Reserved
      5  #
      6  import sys
      7
      8  from rdkit.VLib.Node import VLibNode
      9  from rdkit import six
     10
     11 -class FilterNode(VLibNode):
     12    """ base class for nodes which filter their input
     13
     14    Assumptions:
     15
     16      - filter function takes a number of arguments equal to the
     17        number of inputs we have.  It returns a bool
     18
     19      - inputs (parents) can be stepped through in lockstep
     20
     21      - we return a tuple if there's more than one input
     22
     23    Usage Example:
     24      >>> from rdkit.VLib.Supply import SupplyNode
     25      >>> def func(a,b):
     26      ...   return a+b < 5
     27      >>> filt = FilterNode(func=func)
     28      >>> suppl1 = SupplyNode(contents=[1,2,3,3])
     29      >>> suppl2 = SupplyNode(contents=[1,2,3,1])
     30      >>> filt.AddParent(suppl1)
     31      >>> filt.AddParent(suppl2)
     32      >>> v = [x for x in filt]
     33      >>> v
     34      [(1, 1), (2, 2), (3, 1)]
     35      >>> filt.reset()
     36      >>> v = [x for x in filt]
     37      >>> v
     38      [(1, 1), (2, 2), (3, 1)]
     39      >>> filt.Destroy()
     40
     41      Negation is also possible:
     42      >>> filt = FilterNode(func=func,negate=1)
     43      >>> suppl1 = SupplyNode(contents=[1,2,3,3])
     44      >>> suppl2 = SupplyNode(contents=[1,2,3,1])
     45      >>> filt.AddParent(suppl1)
     46      >>> filt.AddParent(suppl2)
     47      >>> v = [x for x in filt]
     48      >>> v
     49      [(3, 3)]
     50      >>> filt.Destroy()
     51
     52      With no function, just return the inputs:
     53      >>> filt = FilterNode()
     54      >>> suppl1 = SupplyNode(contents=[1,2,3,3])
     55      >>> filt.AddParent(suppl1)
     56      >>> v = [x for x in filt]
     57      >>> v
     58      [1, 2, 3, 3]
     59      >>> filt.Destroy()
     60
     61
     62
     63    """
     64 -  def __init__(self,func=None,negate=0,**kwargs):
     65      VLibNode.__init__(self,**kwargs)
     66      self._func = func
     67      self._negate = negate
     68 -  def SetNegate(self,state):
     69      self._negate = state
     70 -  def Negate(self):
     71      return self._negate
     72
     73 -  def next(self):
     74      done = 0
     75      parents = self.GetParents()
     76      while 1:
     77        args = []
     78        try:
     79          for parent in parents:
     80            args.append(next(parent))
     81        except StopIteration:
     82          raise StopIteration
     83        args = tuple(args)
     84        if self._func is not None:
     85          r = self._func(*args)
     86          if self._negate:
     87            r = not r
     88            #sys.stderr.write('\t\tNEGATE -> %d\n'%(r))
     89          if r:
     90            res = args
     91            break
     92        else:
     93          res = args
     94          break
     95      if len(parents)==1:
     96        res = res[0]
     97      return res
     98
     99  if six.PY3:
    100      FilterNode.__next__ = FilterNode.next
    101
    102
    103  #------------------------------------
    104  #
    105  #  doctest boilerplate
    106  #
    107 -def _test():
    108    import doctest,sys
    109    return doctest.testmod(sys.modules["__main__"])
    110
    111  if __name__ == '__main__':
    112    import sys
    113    failed,tried = _test()
    114    sys.exit(failed)
    115