range_complex_constraints#

This module defines a dictionary range_complex_constraints.

The range_complex_constraints dictionary outlines the instructions to create specific constraints. Its primary purpose is to formulate constraints for tags associated with many machines executing the same process. A case in point would be disk rotation tags, which range_complex_constraints sets restrictions for. These tags pertain to a pelletizing plant with 12 disks; hence, the process includes 12 tag sets. Despite minor differences in their names, the tags convey the same meaning. The dictionary is hence structured to enable simultaneous specification of similar constraints.

Dictionary Structure#

The dictionary adopts the following structure:

  • Keys represent the restriction names. Each key needs to define a string placeholder to be replaced by the ID of each tag from the specific process.

  • The values are lists of dictionaries, with each dictionary in the list representing a different part of the constraint. The last element in each list specifies the constraint operator and constant. Each inner dictionary mandates the definition of the following keys:

    • “type”: Requires the value “range”, which determines the constraint type.

    • “feature”: Denotes the tag name to be treated as a variable.

    • “start”: Denotes the ID of the first tag from the specific process to which a restriction is applied.

    • “end”: Denotes the ID of the last tag from the specific process to which a restriction is applied.

    • “coef”: Specifies the coefficient that multiplies the variable to create a constraint equation element.

    The following keys are optional but important for specific use-cases:

    • “operator”: When present, its value should be “norm”, indicating the need for normalization.

    • “norm_feature”: Identifies the tag scaler used for normalization.

    • “limit”: Determines the value to be normalized.

    These optional keys are crucial when a specific part requires pre-normalization. In such instances, the "limit" key identifies the value that’ll undergo normalization, while the "norm_feature" key indicates the feature used to normalize "limit".

Developer Notes#

While the concept of driving this module is logical, the implementation is more complex than necessary for its intended purpose. The dictionary keys traverse several functions, leading to a significant increase in code lines and complexity compared to the straightforward alternative of individually specifying the constraints. The problem is further exacerbated by lack of documentation and suboptimal namespace choices.

A recurring pattern in the codebase is the unnecessary complication of simple tasks and the lack of enough documentation. This issue poses a significant problem as it makes unconventional code-indistinguishable from actual bugs. It escalates the risk of new developers unintentionally introducing more bugs, thereby adding to the codebase complexity and confusion.

New in version 0.1.2: Added the function validate_range_complex_constraints that validates the range_complex_constraints dictionary during this module’s import.

wip.files.range_complex_constraints.validate_range_complex_constraints(_range_complex_constraints: Dict[str, List[Dict[str, object]]])[source]#

Validate the structure of the _range_complex_constraints dictionary.

This function checks whether all required keys are present in each element of the given dictionary. It also validates the optional keys if an “operator” key is present, indicating normalization is required.

Parameters

_range_complex_constraints (Dict[str, List[Dict[str, object]]]) – Dictionary where each key corresponds to a constraint name and the associated value is a list of dictionaries representing the constraints. Each dictionary in the list must have all keys defined in the OBLIGATORY_KEYS and, in case an “operator” key is present, it must also contain all keys defined in the OPTIONAL_KEYS.

Raises

KeyError – If any dictionary in the list of constraints associated with a constraint name is missing one of the obligatory keys, a KeyError is raised. The same exception is raised if an “operator” key is present, but one of the optional keys is missing.

See also

OBLIGATORY_KEYS

List[str] List of keys that must be present in each dictionary representing a constraint.

OPTIONAL_KEYS

List[str] List of keys that must be present in each dictionary representing a constraint when an “operator” key is present.

Examples

Here is an example of how to use this function:

>>> test_range_complex_constraints = {
...     "constraint1": [{"key1": "value1", "key2": "value2"}],
...     "constraint2": [
...         {"key1": "value1", "operator": "value3",
...         "limit": "value4", "norm_feature": "value5"}
...     ]
... }
>>> validate_range_complex_constraints(test_range_complex_constraints)

The above code won’t raise any exception as all dictionary values contain a list with a single dictionary. The function skips the last element that should represent the RHS of the inequality constraint, that in the above example also represents the only element in each list.