@@ -97,8 +97,9 @@ def __init__(self, name, splitter=None, combiner=None, other_states=None):
97
97
self .other_states = other_states
98
98
self .splitter = splitter
99
99
# if missing_connections, we can't continue, should wait for updates
100
+ # TODO: should find a better way, so it's not in the init, but combiner complicates
100
101
if not self .missing_connections :
101
- self .connect_splitters ()
102
+ self ._connect_splitters ()
102
103
self .combiner = combiner
103
104
self .inner_inputs = {}
104
105
for name , (st , inp ) in self .other_states .items ():
@@ -193,21 +194,15 @@ def combiner(self, combiner):
193
194
self ._left_combiner = []
194
195
self ._right_combiner = []
195
196
196
- def connect_splitters (self ):
197
+ def _connect_splitters (self ):
197
198
"""
198
199
Connect splitters from previous nodes.
199
200
200
201
Evaluates Left (the part from previous states) and Right (current state) parts.
201
202
202
203
"""
203
204
if self .other_states :
204
- (
205
- self .splitter ,
206
- self ._left_splitter ,
207
- self ._right_splitter ,
208
- ) = hlpst .connect_splitters (
209
- splitter = self .splitter , other_states = self .other_states
210
- )
205
+ self ._merge_splitters ()
211
206
# left rpn part, but keeping the names of the nodes, e.g. [_NA, _NB, *]
212
207
self ._left_splitter_rpn_compact = hlpst .splitter2rpn (
213
208
deepcopy (self ._left_splitter ),
@@ -219,13 +214,99 @@ def connect_splitters(self):
219
214
)
220
215
else : # if other_states is empty there is only Right part
221
216
self ._left_splitter = None
222
- self ._left_splitter_rpn_compact = []
223
- self ._left_splitter_rpn = []
217
+ self ._left_splitter_rpn_compact , self ._left_splitter_rpn = [], []
224
218
self ._right_splitter = self .splitter
225
219
self ._right_splitter_rpn = hlpst .splitter2rpn (
226
220
deepcopy (self ._right_splitter ), other_states = self .other_states
227
221
)
228
222
223
+ def _merge_splitters (self ):
224
+ """
225
+ Merging current splitter with the ones from other states.
226
+
227
+ If left splitter is not provided the splitter has to be completed.
228
+
229
+ """
230
+ if self .splitter :
231
+ # if splitter is string, have to check if this is Left or Right part (Left is required)
232
+ if isinstance (self .splitter , str ):
233
+ # so this is the Left part
234
+ if self .splitter .startswith ("_" ):
235
+ self ._left_splitter = self ._complete_left (left = self .splitter )
236
+ self ._right_splitter = None
237
+ else : # this is Right part
238
+ self ._left_splitter = self ._complete_left ()
239
+ self ._right_splitter = self .splitter
240
+ elif isinstance (self .splitter , (tuple , list )):
241
+ lr_flag = self ._left_right_check (self .splitter )
242
+ if lr_flag == "Left" :
243
+ self ._left_splitter = self ._complete_left (left = self .splitter )
244
+ self ._right_splitter = None
245
+ elif lr_flag == "Right" :
246
+ self ._left_splitter = self ._complete_left ()
247
+ self ._right_splitter = self .splitter
248
+ elif lr_flag == "[Left, Right]" :
249
+ self ._left_splitter = self ._complete_left (left = self .splitter [0 ])
250
+ self ._right_splitter = self .splitter [1 ]
251
+ else :
252
+ # if there is no splitter, I create the Left part
253
+ self ._left_splitter = self ._complete_left ()
254
+ self ._right_splitter = None
255
+
256
+ if self ._right_splitter :
257
+ self .splitter = [
258
+ deepcopy (self ._left_splitter ),
259
+ deepcopy (self ._right_splitter ),
260
+ ]
261
+ else :
262
+ self .splitter = deepcopy (self ._left_splitter )
263
+
264
+ def _complete_left (self , left = None ):
265
+ """Add all splitters from previous nodes (completing left part)."""
266
+ if left :
267
+ rpn_left = hlpst .splitter2rpn (
268
+ left , other_states = self .other_states , state_fields = False
269
+ )
270
+ for name , (st , inp ) in list (self .other_states .items ())[::- 1 ]:
271
+ if "_{}" .format (name ) not in rpn_left and st .splitter_final :
272
+ left = ["_{}" .format (name ), left ]
273
+ else :
274
+ left = ["_{}" .format (name ) for name in self .other_states ]
275
+ if len (left ) == 1 :
276
+ left = left [0 ]
277
+ return left
278
+
279
+ def _left_right_check (self , splitter_part , rec_lev = 0 ):
280
+ """
281
+ Check if splitter_part is purely Left, Right
282
+ or [Left, Right] if the splitter_part is a list (outer splitter)
283
+
284
+ String is returned.
285
+
286
+ If the splitter_part is mixed exception is raised.
287
+
288
+ """
289
+ rpn_part = hlpst .splitter2rpn (
290
+ splitter_part , other_states = self .other_states , state_fields = False
291
+ )
292
+ inputs_in_splitter = [i for i in rpn_part if i not in ["*" , "." ]]
293
+ others_in_splitter = [
294
+ True if el .startswith ("_" ) else False for el in inputs_in_splitter
295
+ ]
296
+ if all (others_in_splitter ):
297
+ return "Left"
298
+ elif (not all (others_in_splitter )) and (not any (others_in_splitter )):
299
+ return "Right"
300
+ elif (
301
+ isinstance (self .splitter , list )
302
+ and rec_lev == 0
303
+ and self ._left_right_check (self .splitter [0 ], rec_lev = 1 ) == "Left"
304
+ and self ._left_right_check (self .splitter [1 ], rec_lev = 1 ) == "Right"
305
+ ):
306
+ return "[Left, Right]" # Left and Right parts separated in outer scalar
307
+ else :
308
+ raise Exception ("Left and Right splitters are mixed - splitter invalid" )
309
+
229
310
def set_splitter_final (self ):
230
311
"""Evaluate a final splitter after combining."""
231
312
_splitter_rpn_final = hlpst .remove_inp_from_splitter_rpn (
@@ -309,7 +390,8 @@ def merge_previous_states(self):
309
390
else :
310
391
# if no element from st.splitter is in the current combiner,
311
392
# using st attributes without changes
312
- self .keys_final += st .keys_final
393
+ if st .keys_final :
394
+ self .keys_final += st .keys_final
313
395
group_for_inputs = st .group_for_inputs_final
314
396
groups_stack = st .groups_stack_final
315
397
0 commit comments