From ef9f36f1b0e3e85419035631ab0940e33b43e880 Mon Sep 17 00:00:00 2001 From: Daniel Rojas Date: Sat, 24 Oct 2020 01:45:01 +0200 Subject: [PATCH] Component generation seems to work --- src/wireviz/temp.py | 36 +++++++ src/wireviz/wireviz.py | 222 ++++++++++++++++++++++++++++++++--------- 2 files changed, 210 insertions(+), 48 deletions(-) create mode 100644 src/wireviz/temp.py diff --git a/src/wireviz/temp.py b/src/wireviz/temp.py new file mode 100644 index 0000000..40e0d76 --- /dev/null +++ b/src/wireviz/temp.py @@ -0,0 +1,36 @@ + # check which section the first item belongs to + # first_item = get_first_item_in_entry(connection_set[0]) + # print('first item:', first_item) + # + # if designators_and_templates[first_item] in template_connectors: + # expected_index = 0 + # print('Set starts with con') + # elif designators_and_templates[first_item] in template_cables: + # expected_index = 1 + # print('Set starts with cable') + # else: + # raise Exception('What') + + # check that all entries alternate between cables and connectors + # TODO + # for entry in connection_set: + # for item in get_item_list(entry): + # if + + + + + + # for index, section in enumerate(alternating_sections): + # if first_item in yaml_data[section]: + # expected_index = index + # break + # else: + # raise Exception('First item not found anywhere.') + # expected_index = 1 - expected_index # flip once since it is flipped back at the *beginning* of every loop + # for entry in connection_set: + # pass + + # generate items + + # connect items diff --git a/src/wireviz/wireviz.py b/src/wireviz/wireviz.py index e25650a..8b63d8e 100755 --- a/src/wireviz/wireviz.py +++ b/src/wireviz/wireviz.py @@ -34,9 +34,16 @@ def parse(yaml_input: str, file_out: (str, Path) = None, return_types: (None, st yaml_data = yaml.safe_load(yaml_input) - # templates = Harness() # store templates from YAML `connectors` and `cables` sections template_connectors = {} - template_cables = {} + template_connector_names = [] + template_cables = {} + template_cable_names = [] + + designators_and_templates = {} + autogenerated_designators = {} + alternating_sections = ['connectors','cables'] + + harness = Harness() # add items sections = ['connectors', 'cables', 'connections'] @@ -46,17 +53,18 @@ def parse(yaml_input: str, file_out: (str, Path) = None, return_types: (None, st if len(yaml_data[sec]) > 0: if ty == dict: for key, attribs in yaml_data[sec].items(): + # TODO: take care of this image thing # The Image dataclass might need to open an image file with a relative path. - image = attribs.get('image') - if isinstance(image, dict): - image['gv_dir'] = Path(file_out if file_out else '').parent # Inject context + # image = attribs.get('image') + # if isinstance(image, dict): + # image['gv_dir'] = Path(file_out if file_out else '').parent # Inject context if sec == 'connectors': - print(key, 'con') template_connectors[key] = attribs + template_connector_names.append(key) elif sec == 'cables': - print(key, 'cbl') template_cables[key] = attribs + template_cable_names.append(key) else: pass # section exists but is empty else: # section does not exist, create empty section @@ -65,32 +73,167 @@ def parse(yaml_input: str, file_out: (str, Path) = None, return_types: (None, st elif ty == list: yaml_data[sec] = [] - # add connections + print('Conector templates:', template_connector_names) + print('Cable templates: ', template_cable_names) - harness = Harness() # populate actual harness with instances generated in `connections` section - template_connector_names = list(template_connectors.keys()) - template_cable_names = list(template_cables.keys()) + def get_item_list(entry): # returns a list of components + if isinstance(entry, list): + return entry # return list as-is + elif isinstance(entry, dict): + return [list(entry.keys())[0]] # return key + elif isinstance(entry, str): + return [entry] # return str inside a list - print('template connectors: ', template_connector_names) - print('template cables: ', template_cable_names) + def get_first_item_in_entry(entry): + if isinstance(entry, list): + return entry[0] + elif isinstance(entry, dict): + return list(entry.keys())[0] + elif isinstance(entry, str): + return entry - # print(template_connectors) + def get_template_name(inp): + return [x.split('.')[0] for x in inp] + + def resolve_designator(inp): + if '.' in inp: # generate a new instance of an item + template, designator = inp.split('.') # TODO: handle more than one `.` + if designator == '': + autogenerated_designators[template] = autogenerated_designators.get(template, 0) + 1 + designator = f'_{template}_{autogenerated_designators[template]}' + # check if contradiction + if designator in designators_and_templates: + if designators_and_templates[designator] != template: + raise Exception(f'Trying to redefine {designator} from {designators_and_templates[designator]} to {template}') + else: + designators_and_templates[designator] = template + else: + template = inp + designator = inp + if designator in designators_and_templates: + pass # referencing an exiting connector, no need to add again + else: + designators_and_templates[designator] = template + return (template, designator) + + connection_sets = yaml_data['connections'] + for connection_set in connection_sets: + print('') + + print('connection set @0:', connection_set) + + # figure out number of parallel connections within this set + connectioncount = [] + for entry in connection_set: + if isinstance(entry, list): + connectioncount.append(len(entry)) + elif isinstance(entry, dict): + connectioncount.append(len(expand(list(entry.values())[0]))) # - X1: [1-4,6] yields 5 + else: + connectioncount.append(None) # strings do not reveal connectioncount + + if not any(connectioncount): + raise Exception('No item in connection set revealed number of connections') + print(f'Connection count: {connectioncount}') + + # check that all entries are the same length + if len(set(filter(None, connectioncount))) > 1: + raise Exception('All items in connection set must reference the same number of connections') + + connectioncount = connectioncount[0] + + # expand string entries to list entries of correct length + for index, entry in enumerate(connection_set): + if isinstance(entry, str): + connection_set[index] = [entry] * connectioncount + + print('connection set @1:', connection_set) + print('des_temp @1:', designators_and_templates) + + # resolve all designators + for index, entry in enumerate(connection_set): + # print(index, ':') + if isinstance(entry, list): + for subindex, item in enumerate(entry): + template, designator = resolve_designator(item) + # print('list', index, subindex, item, template, designator) + connection_set[index][subindex] = designator + elif isinstance(entry, dict): + key = list(entry.keys())[0] + template, designator = resolve_designator(key) + value = entry[key] + # print('dict', key, template, designator, value) + connection_set[index] = {designator: value} + else: + pass # string entries have been expanded in previous step + + print('connection set @2:', connection_set) + print('des_temp @2:', designators_and_templates) + + # expand all pin lists + for index, entry in enumerate(connection_set): + if isinstance(entry, list): + connection_set[index] = [{designator: 1} for designator in entry] + elif isinstance(entry, dict): + designator = list(entry.keys())[0] + pinlist = expand(entry[designator]) + connection_set[index] = [{designator: pin} for pin in pinlist] + + print('connection set @3:', connection_set) + + # TODO: check alternating cable/connector + + # generate items + for entry in connection_set: + for item in entry: + designator = list(item.keys())[0] + template = designators_and_templates[designator] + if designator in harness.connectors: + print(' ', designator, 'is an existing connector instance') + elif template in template_connector_names: + print(' ', designator, 'is a new connector instance of type', template) + # print(template_connectors[template]) + harness.add_connector(name = designator, **template_connectors[template]) + # harness.connectors[designator] = templates.connectors[template] + # harness.connectors[designator].name = designator + + elif designator in harness.cables: + print(' ', designator, 'is an existing cable instance') + elif template in template_cable_names: + print(' ', designator, 'is a new cable instance of type', template) + harness.add_cable(name = designator, **template_cables[template]) + # harness.cables[designator] = templates.cables[template] + # harness.cables[designator].name = designator + + else: + print(f' Template {template} not found, neither in connectors nor in cables') + + + + + + + + + quit() - autogenerated_ids = {} connections = [] for yaml_connection in yaml_data['connections']: print('connection set:') - connectionset = [] + connection = [] for entry in yaml_connection: if isinstance(entry, list): itemlist = entry + entrytype = 'list' elif isinstance(entry, dict): itemlist = [list(entry.keys())[0]] + entrytype = 'dict' elif isinstance(entry, str): itemlist = [entry] + entrytype = 'str' print(' ', itemlist) @@ -105,8 +248,8 @@ def parse(yaml_input: str, file_out: (str, Path) = None, return_types: (None, st if '.' in item: # generate a new instance of an item template, designator = item.split('.') # TODO: handle more than one `.` if designator =='': - autogenerated_ids[template] = autogenerated_ids.get(template, 0) + 1 - designator = f'_{template}_{autogenerated_ids[template]}' + autogenerated_designators[template] = autogenerated_designators.get(template, 0) + 1 + designator = f'_{template}_{autogenerated_designators[template]}' print('new autogen id', designator, 'for', template) print(' ', template, '-->', designator) else: # use the item directly @@ -137,36 +280,19 @@ def parse(yaml_input: str, file_out: (str, Path) = None, return_types: (None, st outputlist.append(designator) if not itemlist[0] in arrows: - if isinstance(entry, list): - connectionset_entry = outputlist - elif isinstance(entry, dict): - connectionset_entry = {outputlist[0]: list(entry.values())[0]} - elif isinstance(entry, str): - connectionset_entry = outputlist[0] - print(connectionset_entry) + if entrytype == 'list': + connection_entry = outputlist + elif entrytype == 'dict': + connection_entry = {outputlist[0]: list(entry.values())[0]} + elif entrytype == 'str': + connection_entry = outputlist[0] + print(connection_entry) - connectionset.append(connectionset_entry) + connection.append(connection_entry) - connections.append(connectionset) + print('connection', connection) - print('--- Done building connection list ---') - print(connections) - - print('') - - for connection in connections: - - print('conset', connection) - - # find first component (potentially nested inside list or dict) - first_item = connection[0] - if isinstance(first_item, list): - first_item = first_item[0] - elif isinstance(first_item, dict): - first_item = list(first_item.keys())[0] - elif isinstance(first_item, str): - pass # check which section the first item belongs to alternating_sections = ['connectors','cables'] @@ -218,8 +344,8 @@ def parse(yaml_input: str, file_out: (str, Path) = None, return_types: (None, st sublist = [] for i in range(1, itemcount + 1): # if yaml_data['connectors'][item].get('autogenerate'): - # autogenerated_ids[item] = autogenerated_ids.get(item, 0) + 1 - # new_id = f'_{item}_{autogenerated_ids[item]}' + # autogenerated_designators[item] = autogenerated_designators.get(item, 0) + 1 + # new_id = f'_{item}_{autogenerated_designators[item]}' # harness.add_connector(new_id, **yaml_data['connectors'][item]) # sublist.append([new_id, 1]) # else: @@ -229,8 +355,8 @@ def parse(yaml_input: str, file_out: (str, Path) = None, return_types: (None, st sublist = [] for subitem in item: # if yaml_data['connectors'][subitem].get('autogenerate'): - # autogenerated_ids[subitem] = autogenerated_ids.get(subitem, 0) + 1 - # new_id = f'_{subitem}_{autogenerated_ids[subitem]}' + # autogenerated_designators[subitem] = autogenerated_designators.get(subitem, 0) + 1 + # new_id = f'_{subitem}_{autogenerated_designators[subitem]}' # harness.add_connector(new_id, **yaml_data['connectors'][subitem]) # sublist.append([new_id, 1]) # else: