1
2
3
4
5
6 import sys
7
8 from rdkit.VLib.Node import VLibNode
9 from rdkit import six
10
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
72
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
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
106
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