def add_cs_varvals(self, cs_varvals, pv): """ Adds to self.values the variables and values in the specified comma-separated variable:value pairs ("var1:val1, var2:val2, ..."). """ err = "A @VARIABLES line should have the form '@VARIABLES var1:val1, var2:val2, ...'." varvals = ParseUtil.comma_split(cs_varvals) for varval in varvals: if varval.count(':') == 1 or varval.count('=') == 1: if varval.count('=') == 1: sep = '=' else: sep = ':' var, val_str = varval.split(sep) var = var.strip() val_str = val_str.strip() if var not in self.values: # Otherwise overwrite previous value var_err = is_valid_name(var, pv, kw) if var_err: return var_err val, val_err = self._is_valid_value(val_str) if val_err: return val_err else: self.values[var] = val else: return err return None
def _parse_stimulus_values(self, NAME, stimulus_values, variables, to_be_continued, is_appending): if not self.val[kw.STIMULUS_ELEMENTS]: return f"The parameter 'stimulus_elements' must be assigned before the parameter '{NAME}'." # Create and populate the struct with None values if not is_appending: self.val[NAME] = dict() for e in self.val[kw.STIMULUS_ELEMENTS]: self.val[NAME][e] = None self.val[NAME][kw.DEFAULT] = None single_w, _ = ParseUtil.evaluate(stimulus_values, variables) if single_w is not None: if is_appending: return "A single value for '{}' cannot follow other values.".format( NAME) elif to_be_continued: return "A single value for '{}' cannot be followed by other values.".format( NAME) else: for key in self.val[NAME]: self.val[NAME][key] = single_w self.val[NAME].pop(kw.DEFAULT) else: ws = ParseUtil.comma_split(stimulus_values) ws = [x.strip() for x in ws] for e_w_str in ws: # eb_w_str is 'e:value' or 'default:value' if e_w_str.count(':') != 1: return "Expected 'element:value' or 'default:value' in '{}', got '{}'.".format( NAME, e_w_str) e, w_str = e_w_str.split(':') e = e.strip() w_str = w_str.strip() w, err = ParseUtil.evaluate(w_str, variables) if err: return "Invalid value '{}' for '{}' in parameter '{}'.".format( w_str, e, NAME) if e == kw.DEFAULT: if self.val[NAME][kw.DEFAULT] is not None: return "Default value for '{}' can only be stated once.".format( NAME) elif e not in self.val[kw.STIMULUS_ELEMENTS]: return f"Error in parameter '{NAME}': '{e}' is an invalid stimulus element." if self.val[NAME][e] is not None: return "Duplicate of {} in '{}'.".format(e, NAME) self.val[NAME][e] = w if not to_be_continued: # Set the default value for non-set stimulus elements err = self._set_default_values(NAME) if err: return err return None # No error
def _parse_behavior_cost(self, behavior_cost_str, variables, to_be_continued, is_appending): if not self.val[kw.BEHAVIORS]: return f"The parameter 'behaviors' must be assigned before the parameter '{kw.BEHAVIOR_COST}'." # Create and populate the struct with None values if not is_appending: self.val[kw.BEHAVIOR_COST] = dict() for e in self.val[kw.BEHAVIORS]: self.val[kw.BEHAVIOR_COST][e] = None self.val[kw.BEHAVIOR_COST][kw.DEFAULT] = None single_c, _ = ParseUtil.evaluate(behavior_cost_str, variables) if single_c is not None: if is_appending: return "A single value for '{}' cannot follow other values.".format( kw.BEHAVIOR_COST) elif to_be_continued: return "A single value for '{}' cannot be followed by other values.".format( kw.BEHAVIOR_COST) else: for key in self.val[kw.BEHAVIOR_COST]: self.val[kw.BEHAVIOR_COST][key] = single_c self.val[kw.BEHAVIOR_COST].pop(kw.DEFAULT) else: cs = ParseUtil.comma_split(behavior_cost_str) cs = [x.strip() for x in cs] for bc_str in cs: # bc_str is 'e:value' or 'default:value' if bc_str.count(':') != 1: return "Expected 'element:value' or 'default:value' in '{}', got '{}'.".format( kw.BEHAVIOR_COST, bc_str) b, c_str = bc_str.split(':') b = b.strip() c_str = c_str.strip() c, err = ParseUtil.evaluate(c_str, variables) if err: return f"Invalid value '{c_str}' for '{b}' in parameter '{kw.BEHAVIOR_COST}'." if b == kw.DEFAULT: if self.val[kw.BEHAVIOR_COST][kw.DEFAULT] is not None: return "Default value for '{}' can only be stated once.".format( kw.BEHAVIOR_COST) elif b not in self.val[kw.BEHAVIORS]: return f"Error in parameter '{kw.BEHAVIOR_COST}': '{b}' is an invalid behavior name." if self.val[kw.BEHAVIOR_COST][b] is not None: return "Duplicate of {} in '{}'.".format( b, kw.BEHAVIOR_COST) self.val[kw.BEHAVIOR_COST][b] = c if not to_be_continued: # Set the default value for non-set behaviors err = self._set_default_values(kw.BEHAVIOR_COST) if err: return err return None # No error
def _parse_alphastart_vss(self, NAME, vss_str, variables, to_be_continued, is_appending): """ Parse the string vss_str with a start_vss/alpha_vss specification. Example: "S1->S2: 1.23, S2->S1:3.45, default:1" sets the parameter to {('S1','S2'):1.23, ('S2','S1'):3.45, ('S1','S1'):1, ('S2','S2'):1} under the assumption that stimulus_elements = {'S1', 'S2'} """ if not self.val[kw.STIMULUS_ELEMENTS]: return f"The parameter 'stimulus_elements' must be assigned before the parameter '{NAME}'." # Create and populate the struct with None values if not is_appending: self.val[NAME] = dict() for e1 in self.val[kw.STIMULUS_ELEMENTS]: for e2 in self.val[kw.STIMULUS_ELEMENTS]: self.val[NAME][(e1, e2)] = None self.val[NAME][kw.DEFAULT] = None single_vss, _ = ParseUtil.evaluate(vss_str, variables) if single_vss is not None: if is_appending: return f"A single value for '{NAME}' cannot follow other values." elif to_be_continued: return f"A single value for '{NAME}' cannot be followed by other values." else: for key in self.val[NAME]: self.val[NAME][key] = single_vss self.val[NAME].pop(kw.DEFAULT) else: vs = ParseUtil.comma_split(vss_str) vs = [x.strip() for x in vs] for ee_str in vs: # eb_v_str is 'e1->e2:value' or 'default:value' if ee_str.count(':') != 1: return f"Expected 'x->y:value' or 'default:value' in '{NAME}', got '{ee_str}'." ee, v_str = ee_str.split(':') ee = ee.strip() v_str = v_str.strip() v, err = ParseUtil.evaluate(v_str, variables) if err: return f"Invalid value '{v_str}' for '{ee}' in parameter '{NAME}'." if ee == kw.DEFAULT: if self.val[NAME][kw.DEFAULT] is not None: return f"Default value for '{NAME}' can only be stated once." self.val[NAME][kw.DEFAULT] = v elif ee.count('->') == 1: e1, e2 = ee.split('->') if e1 not in self.val[kw.STIMULUS_ELEMENTS]: return f"Error in parameter '{NAME}': '{e1}' is an invalid stimulus element." if e2 not in self.val[kw.STIMULUS_ELEMENTS]: return f"Error in parameter '{NAME}': '{e2}' is an invalid stimulus element." if self.val[NAME][(e1, e2)] is not None: return f"Duplicate of {e1}->{e2} in '{NAME}'." self.val[NAME][(e1, e2)] = v else: return f"Invalid string '{ee}' in parameter '{NAME}'." if not to_be_continued: # Set the default value for non-set stimulus-stimulus pairs err = self._set_default_values(NAME) if err: return err return None # No error
def _parse_stimulus_response_values(self, NAME, sr_str, variables, to_be_continued, is_appending): """ Parse the string sr_str with a value for stimulus-response pairs. Example: "S1->R1: 1.23, S2->R1:3.45, default:1" sets the parameter to {('S1','R1'):1.23, ('S1','R2'):1, ('S2','R1'):3.45, ('S2','R2'):1} under the assumption that behaviors = {'R1', 'R2'} and stimulus_elements = {'S1', 'S2'} """ if not self.val[kw.STIMULUS_ELEMENTS]: return f"The parameter 'stimulus_elements' must be assigned before the parameter '{NAME}'." if not self.val[kw.BEHAVIORS]: return f"The parameter 'behaviors' must be assigned before the parameter '{NAME}'." # Create and populate the struct with None values if not is_appending: self.val[NAME] = dict() for e in self.val[kw.STIMULUS_ELEMENTS]: for b in self.val[kw.BEHAVIORS]: self.val[NAME][(e, b)] = None self.val[NAME][kw.DEFAULT] = None single_v, _ = ParseUtil.evaluate(sr_str, variables) if single_v is not None: if is_appending: return f"A single value for '{NAME}' cannot follow other values." elif to_be_continued: return f"A single value for '{NAME}' cannot be followed by other values." else: for key in self.val[NAME]: self.val[NAME][key] = single_v self.val[NAME].pop(kw.DEFAULT) else: vs = ParseUtil.comma_split(sr_str) vs = [x.strip() for x in vs] for eb_v_str in vs: # eb_v_str is 'e->b:value' or 'default:value' if eb_v_str.count(':') != 1: return f"Expected 'x->y:value' or 'default:value' in '{NAME}', got '{eb_v_str}'." eb, v_str = eb_v_str.split(':') eb = eb.strip() v_str = v_str.strip() v, err = ParseUtil.evaluate(v_str, variables) if err: return f"Invalid value '{v_str}' for '{eb}' in parameter '{NAME}'." if eb == kw.DEFAULT: if self.val[NAME][kw.DEFAULT] is not None: return f"Default value for '{NAME}' can only be stated once." self.val[NAME][kw.DEFAULT] = v elif eb.count('->') == 1: e, b = eb.split('->') if e not in self.val[kw.STIMULUS_ELEMENTS]: return f"Error in parameter '{NAME}': '{e}' is an invalid stimulus element." if b not in self.val[kw.BEHAVIORS]: return f"Error in parameter '{NAME}': '{b}' is an invalid behavior name." if self.val[NAME][(e, b)] is not None: return f"Duplicate of {e}->{b} in '{NAME}'." self.val[NAME][(e, b)] = v else: return f"Invalid string '{eb}' in parameter '{NAME}'." if not to_be_continued: # Set the default value for non-set stimulus-behavior pairs err = self._set_default_values(NAME) if err: return err return None # No error