@@ -29,7 +29,6 @@ def syntheize_modules(data: dict, zipfile: InMemoryZip) -> Tuple[InMemoryZip, Di
2929 Blocks, parameters and the connections (wires) between the blocks stored in a
3030 JSON file.
3131 '''
32- # Initialize an empty dictionary for tracking dependencies, blocks, parameters, synhronize_frequency, optional_files
3332 dependencies = {}
3433 blocks = {}
3534 parameters = {}
@@ -157,103 +156,155 @@ def process_dependency(dep, zipfile, synhronize_frequency, optional_files, dep_n
157156 # Add the wire to the valid_wires list
158157 valid_wires .append (wire )
159158
160- # Function to process wires and handle absent blocks
161- def process_wires (valid_wires ):
162- # Initialize dictionaries to track source and target ports
163- wire_check_source = {}
164- wire_check_target = {}
165159
166- # Initialize a counter for iteration
167- count = 0
168- # Set a flag to detect changes
169- changes_detected = True
160+ def process_wires (valid_wires ):
161+ count = 0 # Initialize a counter for processing iterations
162+ changes_detected = True # Boolean flag to track if changes were made in the current iteration
170163
171- # Continue processing while changes are detected
164+ # Loop until no changes are detected
172165 while changes_detected :
173- changes_detected = False
166+ wire_check_source = {} # Dictionary to store wires' source info where 'ob' is absent
167+ wire_check_target = {}
168+ changes_detected = False # Reset changes_detected to False before processing wires
169+
170+ new_wires = [] # List to store newly created wires
174171
175- # Iterate over valid wires in reverse order
172+ # Iterate through valid_wires in reverse order
176173 for i in range (len (valid_wires ) - 1 , - 1 , - 1 ):
177- wire = valid_wires [i ]
178- remove_wire = False # Flag to determine if the wire should be removed
179-
180- count += 1 # Increment the counter
174+ wire = valid_wires [i ] # Access the current wire from valid_wires
175+ remove_wire = False # Flag to mark whether the current wire should be removed
176+
177+ count += 1 # Increment the processing counter
181178
182179 # Check if the source port is 'input-out'
183180 if wire ['source' ]['port' ] == 'input-out' :
184- port_name = wire ['source' ]['block' ]
185- # Check if the target is marked 'absent'
181+ port_name = wire ['source' ]['block' ] # Get the block name of the source port
182+
183+ # If the target has 'ob' and it's 'absent', track it for processing later
186184 if 'ob' in wire ['target' ] and wire ['target' ]['ob' ] == 'absent' :
187- # Add target details to wire_check_source with 'input-out' port
188- wire_check_source [port_name ] = wire ['target' ].copy ()
189- wire_check_source [port_name ]['port' ] = port_name
185+ if port_name not in wire_check_source :
186+ wire_check_source [port_name ] = [] # Initialize list if it's not present
187+ wire_check_source [port_name ].append (wire ['target' ].copy ()) # Append a copy of the target
188+ wire_check_source [port_name ][- 1 ]['port' ] = port_name # Set the port name for the new entry
190189 else :
191- # Add target details to wire_check_source
192- wire_check_source [port_name ] = wire ['target' ]
193- # Mark the wire for removal
194- remove_wire = True
190+ # Otherwise, add the target to wire_check_source and mark for removal
191+ if port_name not in wire_check_source :
192+ wire_check_source [port_name ] = []
193+ wire_check_source [port_name ].append (wire ['target' ]) # Add target to the dictionary
194+ remove_wire = True # Mark the wire for removal later
195195
196196 # Check if the target port is 'output-in'
197197 if wire ['target' ]['port' ] == 'output-in' :
198- port_name = wire ['target' ]['block' ]
199- # Check if the source is marked 'absent'
198+ port_name = wire ['target' ]['block' ] # Get the block name of the target port
199+
200+ # If the source has 'ob' and it's 'absent', track it for processing later
200201 if 'ob' in wire ['source' ] and wire ['source' ]['ob' ] == 'absent' :
201- # Add source details to wire_check_target with 'output-in' port
202- wire_check_target [port_name ] = wire ['source' ].copy ()
203- wire_check_target [port_name ]['port' ] = port_name
202+ if port_name not in wire_check_target :
203+ wire_check_target [port_name ] = [] # Initialize list if it's not present
204+ wire_check_target [port_name ].append (wire ['source' ].copy ()) # Append a copy of the source
205+ wire_check_target [port_name ][- 1 ]['port' ] = port_name # Set the port name for the new entry
204206 else :
205- # Add source details to wire_check_target
206- wire_check_target [port_name ] = wire ['source' ]
207- # Mark the wire for removal
208- remove_wire = True
207+ # Otherwise, add the source to wire_check_target and mark for removal
208+ if port_name not in wire_check_target :
209+ wire_check_target [port_name ] = []
210+ wire_check_target [port_name ].append (wire ['source' ]) # Add source to the dictionary
211+ remove_wire = True # Mark the wire for removal later
209212
210- # Remove the wire from valid_wires if marked for removal
213+ # Remove the wire if it was marked for removal
211214 if remove_wire :
212- del valid_wires [i ]
213- changes_detected = True # Set flag to true since changes were made
215+ del valid_wires [i ] # Remove the wire from valid_wires
216+ changes_detected = True # Set changes_detected to True as wires were modified
217+
218+ i = 0 # Initialize counter for iterating through valid_wires
219+ new_wires = [] # Reset the list to store any newly created wires
220+
221+ # Iterate through valid_wires starting from the beginning
222+ while i < len (valid_wires ):
223+ wire = valid_wires [i ] # Access the current wire
214224
215- # Iterate over the valid wires to update ports
216- for i , wire in enumerate (valid_wires ):
217- # Check if the source port name has 36 characters
225+ # Check if the source port is exactly 36 characters (for specific port length)
218226 if len (wire ['source' ].get ('port' , '' )) == 36 :
219- port_name = wire ['source' ]['port' ]
220- # Update source with wire_check_target details if present
221- if port_name in wire_check_target :
222- valid_wires [i ]['source' ] = wire_check_target [port_name ]
223- # Update port name if 'absent' flag is present
224- if 'ob' in valid_wires [i ]['source' ]:
227+ port_name = wire ['source' ]['port' ] # Get the port name of the source
228+
229+ # If the port name exists in wire_check_target, process the sources
230+ if port_name in wire_check_target and wire_check_target [port_name ]:
231+ new_sources = wire_check_target [port_name ] # Get the list of sources for the port
232+
233+ # Replace the source of the current wire with the first new source
234+ valid_wires [i ]['source' ] = new_sources [0 ]
235+ if 'ob' in valid_wires [i ]['source' ]: # If 'ob' exists, set the port name
225236 valid_wires [i ]['source' ]['port' ] = port_name
226-
227- # Check if the target port name has 36 characters
237+
238+ # For remaining sources, create new wires
239+ for new_source in new_sources [1 :]:
240+ new_wire = wire .copy () # Copy the current wire
241+ new_wire ['source' ] = new_source # Set the new source for the copied wire
242+ if 'ob' in new_wire ['source' ]: # If 'ob' exists, set the port name
243+ new_wire ['source' ]['port' ] = port_name
244+ new_wires .append (new_wire ) # Add the new wire to new_wires
245+
246+ # Check if the target port is exactly 36 characters (for specific port length)
228247 if len (wire ['target' ].get ('port' , '' )) == 36 :
229- port_name = wire ['target' ]['port' ]
230- # Update target with wire_check_source details if present
231- if port_name in wire_check_source :
232- valid_wires [i ]['target' ] = wire_check_source [port_name ]
233- # Update port name if 'absent' flag is present
234- if 'ob' in valid_wires [i ]['target' ]:
248+ port_name = wire ['target' ]['port' ] # Get the port name of the target
249+
250+ # If the port name exists in wire_check_source, process the targets
251+ if port_name in wire_check_source and wire_check_source [port_name ]:
252+ new_targets = wire_check_source [port_name ] # Get the list of targets for the port
253+
254+ # Replace the target of the current wire with the first new target
255+ valid_wires [i ]['target' ] = new_targets [0 ]
256+ if 'ob' in valid_wires [i ]['target' ]: # If 'ob' exists, set the port name
235257 valid_wires [i ]['target' ]['port' ] = port_name
258+
259+ # For remaining targets, create new wires
260+ for new_target in new_targets [1 :]:
261+ new_wire = wire .copy () # Copy the current wire
262+ new_wire ['target' ] = new_target # Set the new target for the copied wire
263+ if 'ob' in new_wire ['target' ]: # If 'ob' exists, set the port name
264+ new_wire ['target' ]['port' ] = port_name
265+ new_wires .append (new_wire ) # Add the new wire to new_wires
266+
267+ i += 1 # Move to the next wire in the valid_wires list
268+
269+ # Append newly created wires to the valid_wires list
270+ valid_wires .extend (new_wires )
271+
272+ # Remove duplicate wires by checking for uniqueness
273+ unique_wires = [] # List to store unique wires
274+ seen_wires = set () # Set to track already seen wires
275+
276+ # Iterate over valid_wires to remove duplicates
277+ for wire in valid_wires :
278+ # Convert the wire dictionary to a frozenset for hashability (so it can be added to a set)
279+ wire_tuple = frozenset ((key , frozenset (value .items ())) if isinstance (value , dict ) else (key , value ) for key , value in wire .items ())
280+
281+ # Only add unique wires to unique_wires
282+ if wire_tuple not in seen_wires :
283+ seen_wires .add (wire_tuple ) # Add the wire to the set of seen wires
284+ unique_wires .append (wire ) # Append the wire to unique_wires
285+
286+ valid_wires = unique_wires # Assign the unique wires back to valid_wires
236287
237- # Return the processed list of valid wires
238- return valid_wires
288+ return valid_wires # Return the processed valid_wires
239289
240- # Process the wires to handle 'absent' blocks
290+
291+ # Call the process_wires function to process the wires
241292 processed_wires = process_wires (valid_wires )
242293
243- # Create a final data dictionary with blocks, parameters, frequencies, and wires
294+ # Package processed data into a JSON file for saving or further use
244295 data = {
245- 'blocks' : blocks ,
246- 'parameters' : parameters ,
247- 'synchronize_frequency' : synhronize_frequency ,
248- 'wires' : processed_wires
296+ 'blocks' : blocks , # Block-related data
297+ 'parameters' : parameters , # Parameter-related data
298+ 'synchronize_frequency' : synhronize_frequency , # Synchronization frequency information
299+ 'wires' : processed_wires # The processed wire data
249300 }
250- # Add the data dictionary as a JSON file in the zipfile
251- zipfile .append ('data.json' , json .dumps (data ))
252301
253- # Return the updated zipfile and optional files dictionary
302+ # Add data to a zipfile (the zipfile object must be defined elsewhere in the code)
303+ zipfile .append ('data.json' , json .dumps (data )) # Append the JSON data to the zipfile
304+
305+
254306 return zipfile , optional_files
255307
256-
257308def synthesize_executioner (zipfile : InMemoryZip , optional_files : Dict [str , bool ]) -> InMemoryZip :
258309 '''Synthesize python code necessary to run the blocks.
259310 All these files are present in django static directory.
0 commit comments