From 8e046a9b50f5553880feca9dec545ad2a87d5c60 Mon Sep 17 00:00:00 2001 From: Jean-Luc Auge Date: Mon, 9 Apr 2018 11:44:25 +0200 Subject: [PATCH] Implement default values in xls parser for empty cells *namedtuple default values are only applied if the cell is not read *if the cell is read but is empty '', there is a need to provide default values: which is what this fix does *sanity checks are reinforced : -node_type is replaced by ROADM if degree <> 2: notify user (print) -check that node type is in ('ILA','ROADM','FUSED') Signed-off-by: Jean-Luc Auge --- examples/convert.py | 37 +++++++++++++++++++++++++++++-------- gnpy/core/equipment.py | 10 +++++----- gnpy/core/node.py | 4 ++-- 3 files changed, 36 insertions(+), 15 deletions(-) diff --git a/examples/convert.py b/examples/convert.py index 86a01a76..0465489f 100644 --- a/examples/convert.py +++ b/examples/convert.py @@ -20,7 +20,11 @@ parser.add_argument('-f', '--filter-region', action='append', default=[]) all_rows = lambda sh, start=0: (sh.row(x) for x in range(start, sh.nrows)) class Node(namedtuple('Node', 'city state country region latitude longitude node_type')): - def __new__(cls, city, state, country, region, latitude, longitude, node_type='ROADM'): + def __new__(cls, city, state='', country='', region='', latitude=0, longitude=0, node_type='ILA'): + values = [latitude, longitude, node_type] + default_values = [0, 0, 'ILA'] + [latitude, longitude, node_type] \ + = [x[0] if x[0] != '' else x[1] for x in zip(values,default_values)] return super().__new__(cls, city, state, country, region, latitude, longitude, node_type) class Link(namedtuple('Link', 'from_city to_city \ @@ -33,8 +37,17 @@ class Link(namedtuple('Link', 'from_city to_city \ west_distance=-100, west_fiber='SSMF', west_lineic=0.2, west_con_in=0.5, west_con_out=0.5, west_pmd=0.1, west_cable='', distance_units='km'): - if west_distance == -100: - west_distance = east_distance + values = [from_city, to_city, + east_distance, east_fiber, east_lineic, east_con_in, east_con_out, east_pmd, east_cable, + west_distance, west_fiber, west_lineic, west_con_in, west_con_out, west_pmd, west_cable] + default_values = ['','',0,'SSMF',0.2,0.5,0.5,0.1,'',-100,'SSMF',0.2,0.5,0.5,0.1,''] + [from_city, to_city, + east_distance, east_fiber, east_lineic, east_con_in, east_con_out, east_pmd, east_cable, + west_distance, west_fiber, west_lineic, west_con_in, west_con_out, west_pmd, west_cable]\ + = [x[0] if x[0] != '' else x[1] for x in zip(values,default_values)] + + west_distance = east_distance if west_distance == -100 else west_distance + return super().__new__(cls, from_city, to_city, east_distance, east_fiber, east_lineic, east_con_in, east_con_out, east_pmd, east_cable, west_distance, west_fiber, west_lineic, west_con_in, west_con_out, west_pmd, west_cable, @@ -60,14 +73,18 @@ def convert_file(input_filename, filter_region=[]): if nodes_by_city[l.to_city].node_type.lower() == 'ila': links_by_city[f'{l.to_city}'].append(l) repeat = False - for city,link in links_by_city.items(): + + for city,link in list(links_by_city.items()): if len(link) != 2: #wrong input: ILA sites can only be Degree 2 # => correct to make it a ROADM and remove entry in links_by_city - nodes_by_city[city].node_type = 'ROADM' + #TODO : put in log rather than print + print(f'invalid node type ({nodes_by_city[city].node_type})\ + specified in {city}, replaced by ROADM') + nodes_by_city[city] = nodes_by_city[city]._replace(node_type='ROADM') + nodes = [n._replace(node_type='ROADM') if n.city==city else n for n in nodes] del links_by_city[city] - data = { 'elements': [{'uid': f'trx {x.city}', @@ -143,17 +160,21 @@ def parse_excel(input_filename): nodes_sheet = wb.sheet_by_name('Nodes') links_sheet = wb.sheet_by_name('Links') - """ # sanity check + """ header = [x.value.strip() for x in nodes_sheet.row(4)] expected = ['City', 'State', 'Country', 'Region', 'Latitude', 'Longitude'] if header != expected: raise ValueError(f'Malformed header on Nodes sheet: {header} != {expected}') """ - + nodes = [] for row in all_rows(nodes_sheet, start=5): nodes.append(Node(*(x.value for x in row))) + #check input + expected_node_types = ('ROADM', 'ILA', 'FUSED') + nodes = [n._replace(node_type='ILA') + if not (n.node_type in expected_node_types) else n for n in nodes] # sanity check """ diff --git a/gnpy/core/equipment.py b/gnpy/core/equipment.py index 4df2efcb..f7d9dc35 100644 --- a/gnpy/core/equipment.py +++ b/gnpy/core/equipment.py @@ -100,8 +100,8 @@ def read_eqpt_library(filename): eqpt_library['Edfa'][i] = {**el, **json_data, **dict_nf_model} -def get_eqpt_config(eqpt_name): - """returns the config of an Edfa or Fiber +def get_eqpt_params(eqpt_name): + """returns the params attributs of an Edfa or Fiber by finding it in the eqpt_library input parameter eqpt_name = type_variety of the eqpt """ @@ -113,7 +113,7 @@ def get_eqpt_config(eqpt_name): if eqpt.get('type_variety','') == eqpt_name) eqpt_config = dict(eqpt) del eqpt_config['type_variety'] - except: - pass + except StopIteration as e: + print(f'cannot find eqpt {eqpt_name} in eqpt library') + #TODO log it return eqpt_config - diff --git a/gnpy/core/node.py b/gnpy/core/node.py index 6af4a311..30eced9c 100644 --- a/gnpy/core/node.py +++ b/gnpy/core/node.py @@ -20,7 +20,7 @@ via subclassing. from uuid import uuid4 from gnpy.core.utils import load_json -from gnpy.core.equipment import get_eqpt_config +from gnpy.core.equipment import get_eqpt_params class ConfigStruct: @@ -31,7 +31,7 @@ class ConfigStruct: if 'type_variety' in config: #print('avant',config['type_variety'], config) config['params'] = {**config.get('params',{}), - **get_eqpt_config(config['type_variety'])} + **get_eqpt_params(config['type_variety'])} #print('apres', config) self.set_config_attr(config)