From 64b72f32717ba00e8522ca3826a40a6586f69139 Mon Sep 17 00:00:00 2001 From: syntron Date: Wed, 23 Apr 2025 19:38:54 +0200 Subject: [PATCH 1/4] [ModelicaSystem] simplify code in xmlparse() --- OMPython/ModelicaSystem.py | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/OMPython/ModelicaSystem.py b/OMPython/ModelicaSystem.py index fbaa5876..3e920a8f 100644 --- a/OMPython/ModelicaSystem.py +++ b/OMPython/ModelicaSystem.py @@ -395,19 +395,11 @@ def xmlparse(self): scalar["changeable"] = sv.get('isValueChangeable') scalar["aliasvariable"] = sv.get('aliasVariable') ch = list(sv) - start = None - min = None - max = None - unit = None for att in ch: - start = att.get('start') - min = att.get('min') - max = att.get('max') - unit = att.get('unit') - scalar["start"] = start - scalar["min"] = min - scalar["max"] = max - scalar["unit"] = unit + scalar["start"] = att.get('start') + scalar["min"] = att.get('min') + scalar["max"] = att.get('max') + scalar["unit"] = att.get('unit') if scalar["variability"] == "parameter": if scalar["name"] in self.overridevariables: From d9643e5ddce7c531ff97e2201e0ffc96c980af8d Mon Sep 17 00:00:00 2001 From: syntron Date: Wed, 23 Apr 2025 20:29:03 +0200 Subject: [PATCH 2/4] [ModelicaSystem] add ModelicaSystemError() for unhandled final else cases there are a lot of functions which check the type of the input; this is done by if ... elif ... - however, invalid input is not catched, i.e. there is *NO* return value define (would be None) if the input is not matching any of the if branches --- OMPython/ModelicaSystem.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/OMPython/ModelicaSystem.py b/OMPython/ModelicaSystem.py index 3e920a8f..1dcde994 100644 --- a/OMPython/ModelicaSystem.py +++ b/OMPython/ModelicaSystem.py @@ -430,6 +430,8 @@ def getQuantities(self, names=None): # 3 elif isinstance(names, list): return [x for y in names for x in self.quantitiesList if x["name"] == y] + raise ModelicaSystemError("Unhandled input for getQuantities()") + def getContinuous(self, names=None): # 4 """ This method returns dict. The key is continuous names and value is corresponding continuous value. @@ -474,6 +476,8 @@ def getContinuous(self, names=None): # 4 raise ModelicaSystemError(f"OM error: {i} is not continuous") return valuelist + raise ModelicaSystemError("Unhandled input for getContinous()") + def getParameters(self, names: Optional[str | list[str]] = None) -> dict[str, str] | list[str]: # 5 """Get parameter values. @@ -503,6 +507,8 @@ def getParameters(self, names: Optional[str | list[str]] = None) -> dict[str, st elif isinstance(names, list): return ([self.paramlist.get(x, "NotExist") for x in names]) + raise ModelicaSystemError("Unhandled input for getParameters()") + def getInputs(self, names: Optional[str | list[str]] = None) -> dict | list: # 6 """Get input values. @@ -537,6 +543,8 @@ def getInputs(self, names: Optional[str | list[str]] = None) -> dict | list: # elif isinstance(names, list): return ([self.inputlist.get(x, "NotExist") for x in names]) + raise ModelicaSystemError("Unhandled input for getInputs()") + def getOutputs(self, names: Optional[str | list[str]] = None): # 7 """Get output values. @@ -605,6 +613,8 @@ def getOutputs(self, names: Optional[str | list[str]] = None): # 7 return (i, "is not Output") return valuelist + raise ModelicaSystemError("Unhandled input for getOutputs()") + def getSimulationOptions(self, names=None): # 8 """ This method returns dict. The key is simulation option names and value is corresponding simulation option value. @@ -621,6 +631,8 @@ def getSimulationOptions(self, names=None): # 8 elif isinstance(names, list): return ([self.simulateOptions.get(x, "NotExist") for x in names]) + raise ModelicaSystemError("Unhandled input for getSimulationOptions()") + def getLinearizationOptions(self, names=None): # 9 """ This method returns dict. The key is linearize option names and value is corresponding linearize option value. @@ -637,6 +649,8 @@ def getLinearizationOptions(self, names=None): # 9 elif isinstance(names, list): return ([self.linearOptions.get(x, "NotExist") for x in names]) + raise ModelicaSystemError("Unhandled input for getLinearizationOptions()") + def getOptimizationOptions(self, names=None): # 10 """ usage: @@ -651,6 +665,8 @@ def getOptimizationOptions(self, names=None): # 10 elif isinstance(names, list): return ([self.optimizeOptions.get(x, "NotExist") for x in names]) + raise ModelicaSystemError("Unhandled input for getOptimizationOptions()") + def get_exe_file(self) -> pathlib.Path: """Get path to model executable.""" if platform.system() == "Windows": @@ -773,12 +789,16 @@ def getSolutions(self, varList=None, resultfile=None): # 12 self.sendExpression("closeSimulationResultFile()") return npRes + raise ModelicaSystemError("Unhandled input for getSolutions()") + def strip_space(self, name): if isinstance(name, str): return name.replace(" ", "") elif isinstance(name, list): return [x.replace(" ", "") for x in name] + raise ModelicaSystemError("Unhandled input for strip_space()") + def setMethodHelper(self, args1, args2, args3, args4=None): """ Helper function for setParameter(),setContinuous(),setSimulationOptions(),setLinearizationOption(),setOptimizationOption() From 41f9876ec43bc961dff0bd5fb5bf96bb68ef0297 Mon Sep 17 00:00:00 2001 From: syntron Date: Wed, 23 Apr 2025 20:33:46 +0200 Subject: [PATCH 3/4] [ModelicaSystem.getSolution()] do not try to continue on error but fail Rule: fail early, fail hard - tell the user that something is wrong! In this case, the user ask for the solution but could get None (= plain 'return') - this would case hard to track errors later (if verbose==False and raiseerrors==False) --- OMPython/ModelicaSystem.py | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/OMPython/ModelicaSystem.py b/OMPython/ModelicaSystem.py index 1dcde994..32a801a6 100644 --- a/OMPython/ModelicaSystem.py +++ b/OMPython/ModelicaSystem.py @@ -760,29 +760,24 @@ def getSolutions(self, varList=None, resultfile=None): # 12 # check for result file exits if not os.path.exists(resFile): - errstr = f"Error: Result file does not exist {resFile}" - self._raise_error(errstr=errstr) - return + raise ModelicaSystemError(f"Result file does not exist {resFile}") resultVars = self.sendExpression(f'readSimulationResultVars("{resFile}")') self.sendExpression("closeSimulationResultFile()") if varList is None: return resultVars elif isinstance(varList, str): if varList not in resultVars and varList != "time": - self._raise_error(errstr=f'!!! {varList} does not exist') - return + raise ModelicaSystemError(f"Requested data {repr(varList)} does not exist") res = self.sendExpression(f'readSimulationResult("{resFile}", {{{varList}}})') npRes = np.array(res) self.sendExpression("closeSimulationResultFile()") return npRes elif isinstance(varList, list): - # varList, = varList - for v in varList: - if v == "time": + for var in varList: + if var == "time": continue - if v not in resultVars: - self._raise_error(errstr=f'!!! {v} does not exist') - return + if var not in resultVars: + raise ModelicaSystemError(f"Requested data {repr(var)} does not exist") variables = ",".join(varList) res = self.sendExpression(f'readSimulationResult("{resFile}",{{{variables}}})') npRes = np.array(res) @@ -823,7 +818,8 @@ def apply_single(args1): return True else: - self._raise_error(errstr=f'"{value[0]}" is not a {args3} variable') + raise ModelicaSystemError("Unhandled case in setMethodHelper.apply_single() - " + f"{repr(value[0])} is not a {repr(args3)} variable") result = [] if isinstance(args1, str): From d0665486628be7242b3d010ad6360bcc60ba1aa1 Mon Sep 17 00:00:00 2001 From: syntron Date: Wed, 23 Apr 2025 20:36:06 +0200 Subject: [PATCH 4/4] [ModelicaSystem] remove redundant parentheses (type hint by PyCharm) --- OMPython/ModelicaSystem.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/OMPython/ModelicaSystem.py b/OMPython/ModelicaSystem.py index 32a801a6..7ef2965e 100644 --- a/OMPython/ModelicaSystem.py +++ b/OMPython/ModelicaSystem.py @@ -505,7 +505,7 @@ def getParameters(self, names: Optional[str | list[str]] = None) -> dict[str, st elif isinstance(names, str): return [self.paramlist.get(names, "NotExist")] elif isinstance(names, list): - return ([self.paramlist.get(x, "NotExist") for x in names]) + return [self.paramlist.get(x, "NotExist") for x in names] raise ModelicaSystemError("Unhandled input for getParameters()") @@ -541,7 +541,7 @@ def getInputs(self, names: Optional[str | list[str]] = None) -> dict | list: # elif isinstance(names, str): return [self.inputlist.get(names, "NotExist")] elif isinstance(names, list): - return ([self.inputlist.get(x, "NotExist") for x in names]) + return [self.inputlist.get(x, "NotExist") for x in names] raise ModelicaSystemError("Unhandled input for getInputs()") @@ -588,7 +588,7 @@ def getOutputs(self, names: Optional[str | list[str]] = None): # 7 elif isinstance(names, str): return [self.outputlist.get(names, "NotExist")] else: - return ([self.outputlist.get(x, "NotExist") for x in names]) + return [self.outputlist.get(x, "NotExist") for x in names] else: if names is None: for i in self.outputlist: @@ -601,7 +601,7 @@ def getOutputs(self, names: Optional[str | list[str]] = None): # 7 self.outputlist[names] = value[0][-1] return [self.outputlist.get(names)] else: - return (names, " is not Output") + return names, " is not Output" elif isinstance(names, list): valuelist = [] for i in names: @@ -610,7 +610,7 @@ def getOutputs(self, names: Optional[str | list[str]] = None): # 7 self.outputlist[i] = value[0][-1] valuelist.append(value[0][-1]) else: - return (i, "is not Output") + return i, "is not Output" return valuelist raise ModelicaSystemError("Unhandled input for getOutputs()") @@ -629,7 +629,7 @@ def getSimulationOptions(self, names=None): # 8 elif isinstance(names, str): return [self.simulateOptions.get(names, "NotExist")] elif isinstance(names, list): - return ([self.simulateOptions.get(x, "NotExist") for x in names]) + return [self.simulateOptions.get(x, "NotExist") for x in names] raise ModelicaSystemError("Unhandled input for getSimulationOptions()") @@ -647,7 +647,7 @@ def getLinearizationOptions(self, names=None): # 9 elif isinstance(names, str): return [self.linearOptions.get(names, "NotExist")] elif isinstance(names, list): - return ([self.linearOptions.get(x, "NotExist") for x in names]) + return [self.linearOptions.get(x, "NotExist") for x in names] raise ModelicaSystemError("Unhandled input for getLinearizationOptions()") @@ -663,7 +663,7 @@ def getOptimizationOptions(self, names=None): # 10 elif isinstance(names, str): return [self.optimizeOptions.get(names, "NotExist")] elif isinstance(names, list): - return ([self.optimizeOptions.get(x, "NotExist") for x in names]) + return [self.optimizeOptions.get(x, "NotExist") for x in names] raise ModelicaSystemError("Unhandled input for getOptimizationOptions()") @@ -855,7 +855,7 @@ def setParameters(self, pvals): # 14 def isParameterChangeable(self, name, value): q = self.getQuantities(name) - if (q[0]["changeable"] == "false"): + if q[0]["changeable"] == "false": if self._verbose: logger.info("setParameters() failed : It is not possible to set " f'the following signal "{name}", It seems to be structural, final, ' @@ -924,10 +924,10 @@ def setInputs(self, name): # 15 value = var.split("=") if value[0] in self.inputlist: tmpvalue = eval(value[1]) - if (isinstance(tmpvalue, int) or isinstance(tmpvalue, float)): + if isinstance(tmpvalue, int) or isinstance(tmpvalue, float): self.inputlist[value[0]] = [(float(self.simulateOptions["startTime"]), float(value[1])), (float(self.simulateOptions["stopTime"]), float(value[1]))] - elif (isinstance(tmpvalue, list)): + elif isinstance(tmpvalue, list): self.checkValidInputs(tmpvalue) self.inputlist[value[0]] = tmpvalue self.inputFlag = True