@@ -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 } " )
0 commit comments