def check_credentials(context): # Checks if the context has syntactically valid credentials. The context # has valid credentials when it has an `url` and a `key` fields and that # both fields are string. # # If the credentials are not defined, `message` contains a message describing # the cause. # # Returns: # (has_credentials, message): has_credentials` - True if the context contains syntactical credentials. # and `message` - contains a message if applicable. has_credentials = True message = None if not context.url or not context.key: has_credentials = False elif not is_string(context.url): message = "DOcplexcloud: URL is not a string: {0!s}".format( context.url) has_credentials = False elif not is_string(context.key): message = "API key is not a string: {0!s}".format(context.key) has_credentials = False if context.key and has_credentials: has_credentials = isinstance(context.key, six.string_types) return has_credentials, message
def compile_naming_function(keys, user_name, dimension=1, key_format=None, _default_key_format='_%s', stringifier=str_flatten_tuple): # INTERNAL # builds a naming rule from an input , a dimension, and an optional meta-format # Makes sure the format string does contain the right number of format slots assert user_name is not None if is_string(user_name): if key_format is None: used_key_format = _default_key_format elif is_string(key_format): # -- make sure some %s is inside, otherwise add it if '%s' in key_format: used_key_format = key_format else: used_key_format = key_format + '%s' else: # pragma: no cover raise DOcplexException( "key format expects string format or None, got: {0!r}".format( key_format)) fixed_format_string = fix_format_string(user_name, dimension, used_key_format) if 1 == dimension: return lambda k: fixed_format_string % stringifier(k) else: # here keys are tuples of size >= 2 return lambda key_tuple: fixed_format_string % key_tuple elif is_function(user_name): return user_name elif is_iterable(user_name): # check that the iterable has same len as keys, # otherwise thereis no more default naming and None cannot appear in CPLEX name arrays list_names = list(user_name) if len(list_names) < len(keys): raise DOcplexException( "An array of names should have same len as keys, expecting: {0}, go: {1}" .format(len(keys), len(list_names))) key_to_names_dict = {k: nm for k, nm in izip(keys, list_names)} # use a closure return lambda k: key_to_names_dict[ k] # if k in key_to_names_dict else default_fn() else: raise DOcplexException( 'Cannot use this for naming variables: {0!r} - expecting string, function or iterable' .format(user_name))
def _new_constraint_block2(self, cts, ctnames): posted_cts = [] prepfn = self._model._prepare_constraint checker = self._checker check_trivials = checker.check_trivial_constraints() if is_string(ctnames): from docplex.mp.utils import _AutomaticSymbolGenerator # no separator added, use a terminal "_" if need be ctnames = _AutomaticSymbolGenerator(ctnames) for ct, ctname in izip_longest( cts, ctnames): # use izip_longest so as not to forget any ct if ct is None: # izip stops break checker.typecheck_linear_constraint(ct, accept_range=False) checker.typecheck_string(ctname, accept_none=True, accept_empty=False, caller="Model.add_constraints()") if prepfn(ct, ctname, check_for_trivial_ct=check_trivials): posted_cts.append(ct) self._post_constraint_block(posted_cts) return posted_cts
def _get_engine_from_agent(self, agent, default_engine, default_engine_name): if agent is None: return default_engine elif is_string(agent): agent_key = agent.lower() engine_type = self._engine_types_by_agent.get(agent_key) if engine_type: return engine_type elif 'cplex' == agent_key: print( '* warning: CPLEX DLL not found in path, using {0} instead' .format(default_engine_name)) else: print( '* warning: unrecognized solver agent value: {0!r}'.format( agent)) else: print( '* warning: incorrect solver agent value: {0!r} -expecting string or None' .format(agent)) return default_engine
def _lazy_compute_name_string(self): if self._name_str is not None: return self._name_str else: raw_name = self._name if is_string(raw_name): # drop opl-style formats s_name = raw_name.replace("({%s})", "") # purge fields pos_pct = raw_name.find('%') if pos_pct >= 0: s_name = raw_name[:pos_pct - 1] elif raw_name.find('{') > 0: pos = raw_name.find('{') s_name = raw_name[:pos - 1] elif is_iterable(raw_name): from os.path import commonprefix s_name = commonprefix(raw_name) else: # try a function from os.path import commonprefix namefn = raw_name try: all_names = [namefn(k) for k in self.iter_keys()] s_name = commonprefix(all_names) except TypeError: s_name = '' self._name_str = s_name return s_name
def parse(arg, logger=None, default_sense=None): if isinstance(arg, ObjectiveSense): return arg elif is_string(arg): lower_text = arg.lower() if lower_text in {"minimize", "min"}: return ObjectiveSense.Minimize elif lower_text in {"maximize", "max"}: return ObjectiveSense.Maximize elif default_sense: logger.error( "Text is not recognized as objective sense: {0}, expecting \"min\" or \"max\" - using default {1:s}", (arg, default_sense)) return default_sense elif logger: logger.fatal("Text is not recognized as objective sense: {0}, expecting ""min"" or ""max", (arg,)) else: docplex_fatal("Text is not recognized as objective sense: {0}, expecting ""min"" or ""max".format(arg)) elif is_int(arg): if arg == 1: return ObjectiveSense.Minimize elif -1 == arg: return ObjectiveSense.Maximize else: logger.fatal("cannot convert: <{}> to objective sense", (arg,)) elif arg is None: return default_sense elif logger: logger.fatal("cannot convert: <{}> to objective sense", (arg,)) else: docplex_fatal("cannot convert: <{}> to objective sense".format(arg))
def get_value(self, arg): """ Gets the value of a variable or an expression in a solution. If the variable is not mentioned in the solution, the method returns 0 and does not raise an exception. Note that this method can also be used as :func:`solution[arg]` because the :func:`__getitem__` method has been overloaded. Args: arg: A decision variable (:class:`docplex.mp.linear.Var`), a variable name (a string), or an expression. Returns: float: The value of the variable in the solution. """ if is_string(arg): var = self._get_var_by_name(arg) if var is None: self.model.fatal("No variable with name: {0}", arg) else: return self._get_var_value(var) elif isinstance(arg, Var): return self._get_var_value(arg) else: try: v = arg._get_solution_value(self) return v except AttributeError: self.__model.fatal( "Expecting variable, variable name or expression, {0!r} was passed", arg)
def check_lp_name(self, new_name): #ModelingObject.check_name(self, new_name) if not is_string(new_name) or not new_name: self.fatal("Variable name accepts only non-empty strings, {0!r} was passed", new_name) elif new_name.find(' ') >= 0: self.warning("Variable name contains blank space, var: {0!s}, name: \'{1!s}\'", self, new_name) elif not LP_format.is_lp_compliant(new_name): self.warning("Candidate variable name is not LP-compliant: '{1}', old_name was: {0} (name will be changed to x<nn>)", self.name, new_name)
def typecheck_string(self, arg, accept_empty=False, accept_none=False, caller=''): if is_string(arg): if not accept_empty and 0 == len(arg): s_caller = resolve_caller_as_string(caller) self.fatal("{0}Expecting a non-empty string", s_caller) elif not (arg is None and accept_none): s_caller = resolve_caller_as_string(caller) self.fatal("{0}Expecting string, got: {1!r}", s_caller, arg)
def __init__(self, model, var_value_map=None, obj=None, blended_obj_by_priority=None, name=None, solved_by=None, keep_zeros=True): """ SolveSolution(model, var_value_map, obj, name) Creates a new solution object, associated to a a model. Args: model: The model to which the solution is associated. This model cannot be changed. obj: The value of the objective in the solution. A value of None means the objective is not defined at the time the solution is created, and will be set later. blended_obj_by_priority: For multi-objective models: the value of sub-problems' objectives (each sub-problem groups objectives having same priority). var_value_map: a Python dictionary containing associations of variables to values. name: a name for the solution. The default is None, in which case the solution is named after the model name. :return: A solution object. """ assert model is not None assert solved_by is None or is_string(solved_by) assert obj is None or is_number(obj) or is_indexable(obj) assert blended_obj_by_priority is None or is_indexable( blended_obj_by_priority) self._model = model self._name = name self._problem_objective_expr = model.objective_expr if model.has_objective( ) else None self._objective = self.NO_OBJECTIVE_VALUE if obj is None else obj self._blended_objective_by_priority = [self.NO_OBJECTIVE_VALUE] if blended_obj_by_priority is None else \ blended_obj_by_priority self._solved_by = solved_by self._var_value_map = {} # attributes self._reduced_costs = None self._dual_values = None self._slack_values = None self._infeasibilities = {} self._basis_statuses = None self._solve_status = None self._keep_zeros = keep_zeros self._solve_details = None if var_value_map is not None: self._store_var_value_map(var_value_map, keep_zeros=keep_zeros)
def typecheck_string_seq(self, arg, accept_empty=False, accept_none=False, caller=''): checked_strings = list(arg) # do not accept a string if is_string(arg): s_caller = resolve_caller_as_string(caller) self.fatal("{0}Expecting list of strings, a string was passed: '{1}'", s_caller, arg) for s in checked_strings: self.typecheck_string(s, accept_empty=accept_empty, accept_none=accept_none, caller=caller) return checked_strings
def typecheck_string(self, arg, accept_empty=False, accept_none=False, header=''): if is_string(arg): if not accept_empty and 0 == len(arg): self.fatal("A nonempty string is not allowed here") elif not (arg is None and accept_none): self.fatal("{0}Expecting string, got: {1!r}", header, arg)
def parse(arg): # INTERNAL # noinspection PyTypeChecker for m in RelaxationMode: if arg == m or arg == m.value: return m elif is_string(arg): if arg == str(m.value) or arg.lower() == m.name.lower(): return m docplex_fatal('cannot parse this as a relaxation mode: {0!r}'.format(arg))
def make_modeler(modeler_name): if is_string(modeler_name): mkey = modeler_name.lower() if mkey == "cplex": return CpxModeler() elif mkey in {"docplex", "model"}: return DOcplexModeler() else: pass raise ValueError( "expecting cplex|docplex, {0!r} was passed".format(modeler_name))
def find_parameter(self, key): if is_int(key): pred = lambda p: p.cpx_id == key elif is_string(key): # eliminate initial '.' pred = lambda p: p.get_qualified_name(include_root=False) == key else: docplex_fatal('Parameters.find() accepts either integer code or path-like name, got: {0!r}'.format(key)) for p in self: if pred(p): return p else: return None
def parse(cls, arg): if isinstance(arg, ProgressClock): return arg else: # int value for fl in cls: if arg == fl.value: return fl elif is_string(arg) and arg.lower() == fl.name.lower(): return fl else: # pragma: no cover raise ValueError('Expecting filter level, {0!r} was passed'.format(arg))
def parse(cls, level): if level is None: return cls.Auto elif isinstance(level, cls): return level else: for wl in cls: if wl.value == level: return wl elif is_string(level) and wl.name.lower() == level.lower(): return wl else: return cls.Auto
def parse(cls, arg, do_raise=True): # INTERNAL # noinspection PyTypeChecker for m in cls: if arg == m or arg == m.value: return m elif is_string(arg): if arg == str(m.value) or arg.lower() == m.name.lower(): return m if do_raise: docplex_fatal('cannot convert this to a solve attribute: {0!r}'.format(arg)) else: return None
def parse(cls, arg): fallback = cls.Auto if arg is None: return fallback elif isinstance(arg, EffortLevel): return arg else: for eff in EffortLevel: if eff.value == arg: return eff elif is_string(arg) and arg.lower() == eff.name.lower(): return eff else: return fallback
def parse(cls, level): if level is None: return cls.Auto elif isinstance(level, cls): return level else: for wl in cls: if wl.value == level: return wl elif is_string(level): llevel = level.lower() if llevel == wl.name.lower() or llevel == wl.short_name: return wl return cls.Auto
def _convert_to_bool(value): if value is None: return None elif is_string(value): svalue = str(value).lower() if svalue == "none": return None else: bvalue = _boolean_map.get(svalue) if bvalue is not None: return bvalue else: raise ValueError('Not a boolean: {0}'.format(value)) else: raise ValueError('Not a boolean: {0}'.format(value))
def parse(cls, arg, do_raise=True): # INTERNAL # noinspection PyTypeChecker for op in cls: if arg in (op, op.value): return op elif is_string(arg): if arg == op._cplex_code \ or arg == str(op.value) \ or arg.lower() == op.name.lower(): return op # not found if do_raise: docplex_fatal('cannot convert this to a comparison type: {0!r}'.format(arg)) else: return None
def __init__(self, model, var_value_map=None, obj=None, name=None, solved_by=None, keep_zeros=True, rounding=False): """ SolveSolution(model, var_value_map, obj, name) Creates a new solution object, associated to a a model. Args: model: The model to which the solution is associated. This model cannot be changed. obj: The value of the objective in the solution. A value of None means the objective is not defined at the time the solution is created, and will be set later. var_value_map: a Python dictionary containing associations of variables to values. name: a name for the solution. The default is None, in which case the solution is named after the model name. :return: A solution object. """ assert model is not None assert solved_by is None or is_string(solved_by) assert obj is None or is_number(obj) self.__model = model self._checker = model._checker self._name = name self._problem_name = model.name self._problem_objective_expr = model.objective_expr if model.has_objective( ) else None self._objective = self.NO_OBJECTIVE_VALUE if obj is None else obj self._solved_by = solved_by self.__var_value_map = {} self._attribute_map = defaultdict(dict) self.__round_discrete = rounding self._solve_status = None self._keep_zeros = keep_zeros if var_value_map is not None: self._store_var_value_map(var_value_map, keep_zeros=keep_zeros, rounding=rounding)
def parse(arg, sos1_tokens=frozenset(['1', 'sos1']), sos2_tokens=frozenset(['2', 'sos2'])): if isinstance(arg, SOSType): return arg elif 1 == arg: return SOSType.SOS1 elif 2 == arg: return SOSType.SOS2 elif is_string(arg): arg_lower = arg.lower() if arg_lower in sos1_tokens: return SOSType.SOS1 elif arg_lower in sos2_tokens: return SOSType.SOS2 docplex_fatal("Cannot convert to SOS type: {0!s} - expecting 1|2|'sos1'|'sos2'", arg)
def _get_engine_type_from_agent(self, agent, default_engine, default_engine_name): if agent is None: return default_engine elif is_string(agent): agent_key = agent.lower() engine_type = self._engine_types_by_agent.get(agent_key) if engine_type: return engine_type elif 'cplex' == agent_key: print( '* warning: CPLEX DLL not found in path, using {0} instead' .format(default_engine_name)) return self._engine_types_by_agent.get(default_engine_name) elif '.' in agent: # assuming a qualified name, e.g. com.ibm.docplex.quantum.QuantumEngine from docplex.mp.internal.mloader import import_class try: agent_class = import_class(agent) return agent_class except ValueError as ve: print( "Cannot load agent class {0}, expecting 'cplex', 'docloud' or valid class path, error: {1}" .format(agent, str(ve))) raise ve else: docplex_fatal( "Unexpected agent name: {0}, expecting 'cplex', 'docloud' or valid class path", agent) else: # try a class type try: # noinspection PyUnresolvedReferences from inspect import isclass if isclass(agent): return agent except ImportError: if type(agent) == type: return agent # agent cannot be mapped to any class. docplex_fatal( "* unexpected agent: {0!r} -expecting 'cplex', 'docloud', class or class name", agent)
def _resolve_var(self, var_key, do_raise): # INTERNAL: accepts either strings or variable objects # returns a variable or None if isinstance(var_key, Var): return var_key elif is_string(var_key): var = self._get_var_by_name(var_key) # var might be None here if the name is unknown if var is not None: return var # var is None hereafter elif do_raise: self.model.fatal("No variable with named {0}", var_key) else: self.model.warning("No variable with named {0}", var_key) return None else: # pragma: no cover self.model.fatal("Expecting variable or name, got: {0!r}", var_key)
def create_cpx_vartype_string(cls, vartypes, size): if vartypes is None: return "" else: if not is_string(vartypes): raise ValueError( "Expecting a string for variable types with [BICSN]*, {0!r} was passed".format(vartypes)) else: vtl = len(vartypes) if vtl > 1 and vtl != size: raise ValueError( "Expecting a string for variable types with len 0, 1 or #vars={0}, size: {1} was passed" .format(size, vtl)) # check each char alltypes = "BICNS" for i, c in enumerate(vartypes): if c not in alltypes: raise ValueError("Incorrect character in types: {0}, pos: {1}".format(c, i)) return vartypes * size if vtl == 1 else vartypes
def _resolve_var(self, var_key, do_raise): # INTERNAL: accepts either strings or variable objects # returns a variable or None if isinstance(var_key, Var): var = var_key elif is_string(var_key): var = self._get_var_by_name(var_key) # var might be None here if the name is unknown else: var = None # -- if var is None: if do_raise: self.model.fatal("Expecting variable or name, got: {0!r}", var_key) else: self.model.warning( "Expecting variable or name, got: {0!r} - ignored", var_key) return var
def check_lp_name(cls, logger, qualifier, obj, new_name, accept_empty, accept_none): from docplex.mp.format import LP_format if accept_none and new_name is None: pass elif not is_string(new_name): logger.fatal("{0} name expects a string, {1!r} was passed", qualifier, new_name) elif not accept_empty and not new_name: logger.fatal( "{0} name expects a non-empty string, {0!r} was passed", qualifier, new_name) elif new_name.find(' ') >= 0: logger.warning( "{0} name contains blank space, var: {0!s}, name: \'{1!s}\'", qualifier, obj, new_name) elif not LP_format.is_lp_compliant(new_name): logger.warning( "{0} name is not LP-compliant: '{2}', old_name was: {1} (name will be changed to x<nn>)", qualifier, obj.name, new_name)
def parse(cls, arg, logger, accept_none=True, do_raise=True): ''' Converts its argument to a ``Priority`` object. Returns `default_priority` if the text is not a string, empty, or does not match. Args; arg: The argument to convert. logger: An error logger accept_none: True if None is a possible value. Typically, Constraint.set_priority accepts None as a way to remove the constraint's own priority. do_raise: A Boolean flag indicating if an exception is to be raised if the value is not recognized. Returns: A Priority enumerated object. ''' if isinstance(arg, cls): return arg elif is_string(arg): key = arg.lower() # noinspection PyTypeChecker for p in cls: if key == p.name.lower() or key == str(p.value): return p else: if do_raise: logger.fatal('String does not match priority type: {}', arg) else: logger.error('String does not match priority type: {}', arg) return None return None elif accept_none and arg is None: return None else: logger.fatal('Cannot convert to a priority: {0!s}'.format(arg))