Source code for futile.Inputvars

"""Handle the input variable specifications.

This module is the python complement to the specification of the input variables of a 
file as provided by the :f:mod:`f_input_file` module. It uses the same syntax as defined there 
and make possible the interplay between a python-based serialization of the input dictionary 
and the construction of 

"""

[docs]class InputVariable(): """ Define a input variable of a library. Such object can be initialized and inspected from the dictionary used by futile and then initialized according to the provided specification. """ def __init__(self,name,spec): """ Define a specification of the input variable, according to the conventions employed in the :f:mod:`f_input_file` module. Args: name (str): the name of the input variable spec (dict): dictionary describing the specification of the variables Todo: Extensively specify the conventions somewhere """ from futile.Utils import kw_pop if 'default' not in spec or 'COMMENT' not in spec: raise ValueError("Invalid specification of the variable '"+name+"'") self.name=name self.spec,self.valid_range=kw_pop('RANGE',None,**spec) self.spec,self.valid_values=kw_pop('EXCLUSIVE',None,**self.spec) self.spec,desc=kw_pop('DESCRIPTION','None',**self.spec) self.spec,self.profile_from=kw_pop('PROFILE_FROM',None,**self.spec) self.spec,self.condition=kw_pop('CONDITION',None,**self.spec) self.impose_profile_to=[] self._val_from_profile('default') self.__doc__=self.name+":\n"+self.spec.pop("COMMENT")+"\nDescription:\n"+desc def _val(self,val): if self.valid_range and (val < self.valid_range[0] or val > self.valid_range[1]): raise ValueError("Variable '"+ str(val)+ "' not in allowed range " + str(self.valid_range)) if self.valid_values and (val not in self.valid_values): raise ValueError("Variable '" + str(val) + "' not in allowed values " + str(self.valid_values)) self.value=val def _val_from_profile(self,profile): self.profile=profile val=self.spec[profile] if type(val) == str and val in self.spec: val=self.spec[val] self._val(val) #if the profile chosen is also present in the input variables that #depends from that then impose it for name,var in self.impose_profile_to: if self.profile in var.spec: var.set(self.profile)
[docs] def is_valid(self): if self.condition is not None and "VARIABLE" in self.condition: #raise ValueError("Variable '"+self.name+"' requires to be bound with master_key '"+\ # self.condition["MASTER_KEY"]+"';\n use the set_master_variable method") var=self.condition["VARIABLE"] when=self.condition.get("WHEN") if when and (var.profile not in when and var.value not in when): return False #raise ValueError("Variable '"+self.name+"' cannot be set as master key '"+\ self.condition["MASTER_KEY"]+"' does not have the allowed values") when_not=self.condition.get("WHEN_NOT") if when_not and (var.profile in when_not or var.value in when_not): return False #raise ValueError("Variable '"+self.name+"' cannot be set as master key '"+self.condition["MASTER_KEY"]+"' has incompatible values") return True
def _val_from_user(self,val): self.profile='__USER__' #search if some profile corresponds to a value for profile,value in self.spec.items(): if value == val: self._val_from_profile(profile) return self._val(val)
[docs] def set(self,val): """Set the value of the input variable""" if val in self.spec: self._val_from_profile(profile=val) else: self._val_from_user(val)
[docs] def set_dependent_variable(self,var): """Set the dependent variable from which impose the profile""" self.impose_profile_to.append((var.name,var))
[docs] def set_master_variable(self,var): """Set the variable which is activated when the present has suitable values or profiles""" if self.condition: if var.name != self.condition["MASTER_KEY"]: raise ValueError("Variable '"+self.name+"' requires to be bound with '"+ self.condition["MASTER_KEY"]+"', whereas '"+ var.name+"' has been provided") self.condition["VARIABLE"]=var
def __repr__(self): if self.profile != '__USER__': return self.profile else: return str(self.value)