Skip to content

Commit 8d19d26

Browse files
committed
[ModelicaSystem] add type hints for set*() functions and rename arguments
* fix some type hint issues in setInput() * prepare for definition via dictionary replacing 'a=b' and '[a=b, c=d]' style
1 parent 3e9c55b commit 8d19d26

1 file changed

Lines changed: 125 additions & 61 deletions

File tree

OMPython/ModelicaSystem.py

Lines changed: 125 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1126,106 +1126,164 @@ def _strip_space(name):
11261126

11271127
raise ModelicaSystemError("Unhandled input for strip_space()")
11281128

1129-
def _setMethodHelper(self, args1, args2, args3, args4=None):
1130-
"""Helper function for setters.
1129+
def _setMethodHelper(
1130+
self,
1131+
inputdata: str | list[str] | dict[str, str | int | float],
1132+
classdata: dict[str, Any],
1133+
datatype: str,
1134+
overwritedata: Optional[dict[str, str]] = None,
1135+
) -> bool:
1136+
"""
1137+
Helper function for setters.
11311138
11321139
args1 - string or list of string given by user
11331140
args2 - dict() containing the values of different variables(eg:, parameter,continuous,simulation parameters)
11341141
args3 - function name (eg; continuous, parameter, simulation, linearization,optimization)
11351142
args4 - dict() which stores the new override variables list,
11361143
"""
1137-
def apply_single(args1):
1138-
args1 = self._strip_space(args1)
1139-
value = args1.split("=")
1140-
if value[0] in args2:
1141-
if args3 == "parameter" and self.isParameterChangeable(value[0], value[1]):
1142-
args2[value[0]] = value[1]
1143-
if args4 is not None:
1144-
args4[value[0]] = value[1]
1145-
elif args3 != "parameter":
1146-
args2[value[0]] = value[1]
1147-
if args4 is not None:
1148-
args4[value[0]] = value[1]
1144+
1145+
# TODO: cleanup / data handling / ...
1146+
# (1) args1: Optional[str | list[str]] -> convert to dict
1147+
# (2) work on dict! inputs: dict[str, str | int | float | ?numbers.number?]
1148+
# (3) handle function
1149+
# (4) use it also for other functions with such an input, i.e. 'key=value' | ['key=value']
1150+
# (5) include setInputs()
1151+
1152+
def apply_single(key_val: str):
1153+
key_val_list = key_val.split("=")
1154+
if len(key_val_list) != 2:
1155+
raise ModelicaSystemError(f"Invalid key = value pair: {key_val}")
1156+
1157+
name = self._strip_space(key_val_list[0])
1158+
value = self._strip_space(key_val_list[1])
1159+
1160+
if name in classdata:
1161+
if datatype == "parameter" and not self.isParameterChangeable(name):
1162+
logger.debug(f"It is not possible to set the parameter {repr(name)}. It seems to be "
1163+
"structural, final, protected, evaluated or has a non-constant binding. "
1164+
"Use sendExpression(...) and rebuild the model using buildModel() API; example: "
1165+
"sendExpression(\"setParameterValue("
1166+
f"{self.modelName}, {name}, {value if value is not None else '<?value?>'}"
1167+
")\") ")
1168+
return False
1169+
1170+
classdata[name] = value
1171+
if overwritedata is not None:
1172+
overwritedata[name] = value
11491173

11501174
return True
11511175

11521176
else:
1153-
raise ModelicaSystemError("Unhandled case in _setMethodHelper.apply_single() - "
1154-
f"{repr(value[0])} is not a {repr(args3)} variable")
1177+
raise ModelicaSystemError("Unhandled case in setMethodHelper.apply_single() - "
1178+
f"{repr(name)} is not a {repr(datatype)} variable")
11551179

11561180
result = []
1157-
if isinstance(args1, str):
1158-
result = [apply_single(args1)]
1181+
if isinstance(inputdata, str):
1182+
result = [apply_single(inputdata)]
11591183

1160-
elif isinstance(args1, list):
1184+
elif isinstance(inputdata, list):
11611185
result = []
1162-
args1 = self._strip_space(args1)
1163-
for var in args1:
1186+
inputdata = self._strip_space(inputdata)
1187+
for var in inputdata:
11641188
result.append(apply_single(var))
11651189

11661190
return all(result)
11671191

1168-
def setContinuous(self, cvals): # 13
1192+
def isParameterChangeable(
1193+
self,
1194+
name: str,
1195+
):
1196+
q = self.getQuantities(name)
1197+
if q[0]["changeable"] == "false":
1198+
return False
1199+
return True
1200+
1201+
def setContinuous(
1202+
self,
1203+
cvals: str | list[str] | dict[str, str | int | float],
1204+
) -> bool:
11691205
"""
11701206
This method is used to set continuous values. It can be called:
11711207
with a sequence of continuous name and assigning corresponding values as arguments as show in the example below:
11721208
usage
11731209
>>> setContinuous("Name=value")
11741210
>>> setContinuous(["Name1=value1","Name2=value2"])
11751211
"""
1176-
return self._setMethodHelper(cvals, self._continuous, "continuous", self._override_variables)
1212+
return self._setMethodHelper(
1213+
inputdata=cvals,
1214+
classdata=self.continuouslist,
1215+
datatype="continuous",
1216+
overwritedata=self.overridevariables)
11771217

1178-
def setParameters(self, pvals): # 14
1218+
def setParameters(
1219+
self,
1220+
pvals: str | list[str] | dict[str, str | int | float],
1221+
) -> bool:
11791222
"""
11801223
This method is used to set parameter values. It can be called:
11811224
with a sequence of parameter name and assigning corresponding value as arguments as show in the example below:
11821225
usage
11831226
>>> setParameters("Name=value")
11841227
>>> setParameters(["Name1=value1","Name2=value2"])
11851228
"""
1186-
return self._setMethodHelper(pvals, self._params, "parameter", self._override_variables)
1229+
return self._setMethodHelper(
1230+
inputdata=pvals,
1231+
classdata=self.paramlist,
1232+
datatype="parameter",
1233+
overwritedata=self.overridevariables)
11871234

1188-
def isParameterChangeable(self, name, value):
1189-
q = self.getQuantities(name)
1190-
if q[0]["changeable"] == "false":
1191-
logger.debug(f"setParameters() failed : It is not possible to set the following signal {repr(name)}. "
1192-
"It seems to be structural, final, protected or evaluated or has a non-constant binding, "
1193-
f"use sendExpression(\"setParameterValue({self._model_name}, {name}, {value})\") "
1194-
"and rebuild the model using buildModel() API")
1195-
return False
1196-
return True
1197-
1198-
def setSimulationOptions(self, simOptions): # 16
1235+
def setSimulationOptions(
1236+
self,
1237+
simOptions: str | list[str] | dict[str, str | int | float],
1238+
) -> bool:
11991239
"""
12001240
This method is used to set simulation options. It can be called:
12011241
with a sequence of simulation options name and assigning corresponding values as arguments as show in the example below:
12021242
usage
12031243
>>> setSimulationOptions("Name=value")
12041244
>>> setSimulationOptions(["Name1=value1","Name2=value2"])
12051245
"""
1206-
return self._setMethodHelper(simOptions, self._simulate_options, "simulation-option", self._simulate_options_override)
1246+
return _self.setMethodHelper(
1247+
inputdata=simOptions,
1248+
classdata=self.simulateOptions,
1249+
datatype="simulation-option",
1250+
overwritedata=self.simoptionsoverride)
12071251

1208-
def setLinearizationOptions(self, linearizationOptions): # 18
1252+
def setLinearizationOptions(
1253+
self,
1254+
linearizationOptions: str | list[str] | dict[str, str | int | float],
1255+
) -> bool:
12091256
"""
12101257
This method is used to set linearization options. It can be called:
12111258
with a sequence of linearization options name and assigning corresponding value as arguments as show in the example below
12121259
usage
12131260
>>> setLinearizationOptions("Name=value")
12141261
>>> setLinearizationOptions(["Name1=value1","Name2=value2"])
12151262
"""
1216-
return self._setMethodHelper(linearizationOptions, self._linearization_options, "Linearization-option", None)
1263+
return self._setMethodHelper(
1264+
inputdata=linearizationOptions,
1265+
classdata=self.linearOptions,
1266+
datatype="Linearization-option",
1267+
overwritedata=None)
12171268

1218-
def setOptimizationOptions(self, optimizationOptions): # 17
1269+
def setOptimizationOptions(self, optimizationOptions: str | list[str] | dict[str, str | int | float]) -> bool:
12191270
"""
12201271
This method is used to set optimization options. It can be called:
12211272
with a sequence of optimization options name and assigning corresponding values as arguments as show in the example below:
12221273
usage
12231274
>>> setOptimizationOptions("Name=value")
12241275
>>> setOptimizationOptions(["Name1=value1","Name2=value2"])
12251276
"""
1226-
return self._setMethodHelper(optimizationOptions, self._optimization_options, "optimization-option", None)
1277+
return self._setMethodHelper(
1278+
inputdata=optimizationOptions,
1279+
classdata=self.optimizeOptions,
1280+
datatype="optimization-option",
1281+
overwritedata=None)
12271282

1228-
def setInputs(self, name): # 15
1283+
def setInputs(
1284+
self,
1285+
name: str | list[str] | dict[str, str | int | float],
1286+
) -> bool:
12291287
"""
12301288
This method is used to set input values. It can be called:
12311289
with a sequence of input name and assigning corresponding values as arguments as show in the example below:
@@ -1234,34 +1292,40 @@ def setInputs(self, name): # 15
12341292
>>> setInputs(["Name1=value1","Name2=value2"])
12351293
"""
12361294
if isinstance(name, str):
1237-
name = self._strip_space(name)
1238-
value = name.split("=")
1239-
if value[0] in self._inputs:
1240-
tmpvalue = eval(value[1])
1295+
name1: str = name
1296+
name1 = name1.replace(" ", "")
1297+
value1 = name1.split("=")
1298+
if value1[0] in self.inputlist:
1299+
tmpvalue = eval(value1[1])
12411300
if isinstance(tmpvalue, (int, float)):
1242-
self._inputs[value[0]] = [(float(self._simulate_options["startTime"]), float(value[1])),
1243-
(float(self._simulate_options["stopTime"]), float(value[1]))]
1301+
self.inputlist[value1[0]] = [(float(self._simulateOptions["startTime"]), float(value1[1])),
1302+
(float(self._simulateOptions["stopTime"]), float(value1[1]))]
12441303
elif isinstance(tmpvalue, list):
12451304
self._checkValidInputs(tmpvalue)
1246-
self._inputs[value[0]] = tmpvalue
1247-
self._has_inputs = True
1305+
self._inputs[value1[0]] = tmpvalue
1306+
self._inputFlag = True
12481307
else:
1249-
raise ModelicaSystemError(f"{value[0]} is not an input")
1308+
raise ModelicaSystemError(f"{value1[0]} is not an input")
12501309
elif isinstance(name, list):
1251-
name = self._strip_space(name)
1252-
for var in name:
1253-
value = var.split("=")
1254-
if value[0] in self._inputs:
1255-
tmpvalue = eval(value[1])
1310+
name_list: list[str] = name
1311+
for name2 in name_list:
1312+
name2 = name2.replace(" ", "")
1313+
value2 = name2.split("=")
1314+
if value2[0] in self.inputlist:
1315+
tmpvalue = eval(value2[1])
12561316
if isinstance(tmpvalue, (int, float)):
1257-
self._inputs[value[0]] = [(float(self._simulate_options["startTime"]), float(value[1])),
1258-
(float(self._simulate_options["stopTime"]), float(value[1]))]
1317+
self.inputlist[value2[0]] = [(float(self._simulateOptions["startTime"]), float(value2[1])),
1318+
(float(self.:simulateOptions["stopTime"]), float(value2[1]))]
12591319
elif isinstance(tmpvalue, list):
12601320
self._checkValidInputs(tmpvalue)
1261-
self._inputs[value[0]] = tmpvalue
1262-
self._has_inputs = True
1321+
self._inputs[value2[0]] = tmpvalue
1322+
self._inputFlag = True
12631323
else:
1264-
raise ModelicaSystemError(f"{value[0]} is not an input!")
1324+
raise ModelicaSystemError(f"{value2[0]} is not an input!")
1325+
elif isinstance(name, dict):
1326+
raise NotImplementedError("Must be defined!")
1327+
1328+
return True
12651329

12661330
def _checkValidInputs(self, name):
12671331
if name != sorted(name, key=lambda x: x[0]):

0 commit comments

Comments
 (0)