Skip to content

Commit 3fdeb35

Browse files
committed
embedded log is now being used
1 parent cb68264 commit 3fdeb35

File tree

2 files changed

+34
-15
lines changed

2 files changed

+34
-15
lines changed

src/sas/qtgui/Calculators/Shape2SAS/Constraints.py

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,15 @@ def __init__(self, parent=None):
5454
defaultText = "<span><b>Shape2SAS plugin constraints log</b></p></span>"
5555
self.textEdit_2.append(defaultText)
5656

57+
def log_embedded_error(self, message: str):
58+
"""Log an error message in the embedded logbook."""
59+
self.textEdit_2.append(f"<span style='color: red;'>{message}</span>")
60+
self.textEdit_2.verticalScrollBar().setValue(self.textEdit_2.verticalScrollBar().maximum())
61+
62+
def log_embedded(self, message: str):
63+
"""Log a message in the embedded logbook."""
64+
self.textEdit_2.append(f"<span style='color: black;'>{message}</span>")
65+
self.textEdit_2.verticalScrollBar().setValue(self.textEdit_2.verticalScrollBar().maximum())
5766

5867
def getConstraintText(self, fit_params: str) -> str:
5968
"""Get the default text for the constraints editor"""
@@ -118,7 +127,8 @@ def merge_text(current_text: str, parameter_text: str):
118127
# create new list of parameters, replacing existing old lines in the new list
119128
for i, name in enumerate(new_names):
120129
if name in old_names:
121-
new_lines[i+2] = old_lines[old_names.index(name)+2]
130+
entry = old_lines[old_names.index(name)+2]
131+
new_lines[i+2] = entry + ',' if entry[-1] != ',' else entry
122132

123133
# remove old lines from the current text and insert the new ones in the middle
124134
current_text = "\n".join(current_text_lines[:start+1] + new_lines[2:-1] + current_text_lines[start+end:])
@@ -129,8 +139,7 @@ def merge_text(current_text: str, parameter_text: str):
129139
self.constraintTextEditor.txtEditor.setPlainText(text)
130140
self.createPlugin.setEnabled(True)
131141

132-
@staticmethod
133-
def parseConstraintsText(
142+
def parseConstraintsText(self,
134143
text: str, fitPar: list[str], modelPars: list[list[str]], modelVals: list[list[float]], checkedPars: list[list[bool]]
135144
) -> tuple[list[str], str, str, list[list[bool]]]:
136145
"""Parse the text in the constraints editor and return a dictionary of parameters"""
@@ -151,6 +160,7 @@ def as_ast(text: str):
151160
last_lines = all_lines[-1:]
152161
traceback_to_show = '\n'.join(last_lines)
153162
logger.error(traceback_to_show)
163+
self.log_embedded_error(f"Error parsing constraints text: {e}")
154164
return None
155165

156166
def expand_center_of_mass_pars(constraint: ast.Assign) -> list[ast.Assign]:
@@ -178,7 +188,6 @@ def expand_center_of_mass_pars(constraint: ast.Assign) -> list[ast.Assign]:
178188

179189
new_targets, new_values = [], []
180190
if rhs_base.startswith("COM") and rhs_base[3:].isdigit():
181-
print("CASE DOUBLE COM")
182191
# rhs is also a COM parameter: COM2 = COM1 -> COMX2, COMY2, COMZ2 =COMX1, COMY1, COMZ1
183192
lhs_shape_num = lhs_base[3:]
184193
rhs_shape_num = rhs_base[3:]
@@ -190,7 +199,6 @@ def expand_center_of_mass_pars(constraint: ast.Assign) -> list[ast.Assign]:
190199
new_values.append(ast.Name(id=rhs_full, ctx=ast.Load()))
191200

192201
else:
193-
print("CASE SINGLE COM")
194202
# rhs is a regular parameter: COM2 = X -> COMX2, COMY2, COMZ2 = X, X, X
195203
lhs_shape_num = lhs_base[3:]
196204
rhs_full = f"{'d' if rhs_is_delta else ''}{rhs_base}"
@@ -220,8 +228,6 @@ def parse_ast(tree: ast.AST):
220228
constraints.append(expand_center_of_mass_pars(node))
221229
else:
222230
constraints.append(node)
223-
224-
print(f"Parsed constraints: {constraints}")
225231
return params, imports, constraints
226232

227233
def extract_symbols(constraints: list[ast.AST]) -> tuple[list[str], list[str]]:
@@ -249,31 +255,43 @@ def extract_symbols(constraints: list[ast.AST]) -> tuple[list[str], list[str]]:
249255
rhs.add(elt.id)
250256

251257
return lhs, rhs
252-
258+
253259
def validate_params(params: ast.AST):
254260
if params is None:
255261
logger.error("No parameters found in constraints text.")
262+
self.log_embedded_error("No parameters found in constraints text.")
256263
raise ValueError("No parameters found in constraints text.")
257264

258265
def validate_symbols(lhs: list[str], rhs: list[str], fitPars: list[str]):
259266
"""Check if all symbols in lhs and rhs are valid parameters."""
260267
# lhs is not allowed to contain fit parameters
261268
for symbol in lhs:
262269
if symbol in fitPars or symbol[1:] in fitPars:
263-
logger.error(f"Symbol '{symbol}' is a fit parameter and cannot be used in constraints.")
270+
logger.error(f"Symbol '{symbol}' is a fit parameter and cannot be assigned to.")
271+
self.log_embedded_error(f"Symbol '{symbol}' is a fit parameter and cannot be assigned to.")
264272
raise ValueError(f"Symbol '{symbol}' is a fit parameter and cannot be assigned to.")
265-
273+
274+
for symbol in rhs:
275+
is_fit_par = symbol in fitPars or symbol[1:] in fitPars
276+
is_defined = symbol in lhs
277+
if not is_fit_par and not is_defined:
278+
logger.error(f"Symbol '{symbol}' is undefined.")
279+
self.log_embedded_error(f"Symbol '{symbol}' is undefined.")
280+
raise ValueError(f"Symbol '{symbol}' is undefined.")
281+
266282
def validate_imports(imports: list[ast.ImportFrom | ast.Import]):
267283
"""Check if all imports are valid."""
268284
for imp in imports:
269285
if isinstance(imp, ast.ImportFrom):
270286
if not importlib.util.find_spec(imp.module):
271287
logger.error(f"Module '{imp.module}' not found.")
288+
self.log_embedded_error(f"Module '{imp.module}' not found.")
272289
raise ModuleNotFoundError(f"No module named {imp.module}")
273290
elif isinstance(imp, ast.Import):
274291
for name in imp.names:
275292
if not importlib.util.find_spec(name.name):
276293
logger.error(f"Module '{name.name}' not found.")
294+
self.log_embedded_error(f"Module '{name.name}' not found.")
277295
raise ModuleNotFoundError(f"No module named {name.name}")
278296

279297
def mark_named_parameters(checkedPars: list[list[bool]], modelPars: list[str], symbols: set[str]):
@@ -302,7 +320,7 @@ def in_symbols(par: str):
302320
constraints = [ast.unparse(constraint) for constraint in constraints]
303321
symbols = (lhs, rhs)
304322

305-
print("Finished parsing constraints text.")
323+
self.log_embedded("Successfully parsed user text. Generating plugin model...")
306324
print(f"Parsed parameters: {params}")
307325
print(f"Parsed imports: {imports}")
308326
print(f"Parsed constraints: {constraints}")

src/sas/qtgui/Calculators/Shape2SAS/DesignWindow.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -260,21 +260,21 @@ def checkStateOfConstraints(self, fitPar: list[str], modelPars: list[list[str]],
260260

261261
#Has anything been written to the text editor
262262
if constraintsStr:
263-
#TODO: print to GUI output texteditor
263+
self.constraint.log_embedded("Parsing constraints...")
264264
return self.constraint.parseConstraintsText(constraintsStr, fitPar, modelPars, modelVals, checkedPars)
265-
265+
266266
#Did the user only check parameters and click generate plugin
267267
elif fitPar:
268268
#Get default constraints
269269
fitParLists = self.getConstraintsToTextEditor()
270270
defaultConstraintsStr = self.constraint.getConstraintText(fitParLists)
271-
#TODO: print to GUI output texteditor
271+
self.constraint.log_embedded("No constraints text found. Creating unconstrained model")
272272
return self.constraint.getConstraints(defaultConstraintsStr, fitPar, modelPars, modelVals, checkedPars)
273273

274274
#If not, return empty
275275
else:
276276
#all parameters are constant
277-
#TODO: print to GUI output texteditor
277+
self.constraint.log_embedded("Creating unconstrained model.")
278278
return "", "", "", checkedPars
279279

280280
def enableButtons(self, toggle: bool):
@@ -666,6 +666,7 @@ def getPluginModel(self):
666666
TabbedModelEditor.writeFile(full_path, model_str)
667667
self.communicator.customModelDirectoryChanged.emit()
668668
logger.info(f"Successfully generated model {modelName}!")
669+
self.constraint.log_embedded(f"Plugin model {modelName} has been generated and is now available in the Fit panel.")
669670
self.constraint.createPlugin.setEnabled(False)
670671

671672
def onCheckingInput(self, input: str, default: str) -> str:

0 commit comments

Comments
 (0)