Skip to content

Use wildcards to indicate sets of TREATMENT_IDS when over-riding consumables. #1642

@tbhallett

Description

@tbhallett

We could do this to enable use of wildcards to indicate sets of TREATMENT_IDS efficiently, including all:

def is_treatment_id_ovrridden(treatment_id: str, cons_avail_override_treatment_ids: list[str]) -> bool:
    """Determine if a treatment_id (specified as a string) can is subject to consumables availability overriding (i.e., is with the allowable set of treatments, given by `cons_avail_override_treatment_ids`. The rules are as follows:
          * An empty list means nothing is subject to overriding.
          * A list that contains only an asterisk ['*'] means EVERYTHING is subject to overriding
          * An entry in the list of the form "A_B_C" means a treatment_id that matches exactly is allowed
          * An entry in the list of the form "A_B_*" means that a treatment_id that begins "A_B_" or "A_B" is allowed"""

    def _treatment_matches_pattern(_treatment_id, _service_availability):
        """Check if treatment_id matches any services specified with wildcard * patterns"""

            def _matches_this_pattern(_treatment_id, _s):
                """Returns True if this `treatment_id` is consistent with this component of `cons_avail_override_treatment_ids`"""
                if '*' in _s:
                    assert _s[-1] == '*', f"Component of service_availability has an asteriks not at the end: {_s}"
                    _s_split = _s.split('_')  # split the matching pattern at '_' knowing that the last component is '*'
                    _treatment_id_split = _treatment_id.split('_', len(_s_split) - 1)  # split treatment_id at '_' into
                    # as many component as there as non-asteriks component of _s.
                    # Check if all the components (that are not asteriks) are the same:
                    return all(
                        [(a == b) or (b == "*") for a, b in itertools.zip_longest(_treatment_id_split, _s_split)]
                    )
                else:
                    # If not "*", comparison is ordinary match between strings
                    return _treatment_id == _s

                for _t in cons_avail_override_treatment_ids:
                    if _matches_this_pattern(_treatment_id, _t):
                        return True
                    else:
                        return False


        if not cons_avail_override_treatment_ids:
            # Empty list --> nothing is subject to overriding
            return False

        elif cons_avail_override_treatment_ids == ['*']:
            # Wildcard --> everything is subject to overriding
            return True
        
        elif treatment_id in cons_avail_override_treatment_ids:
            # Explicit inclusion of this treatment_id --> subject to overriding
            return True
        
        else:
            if _treatment_matches_pattern(treatment_id, service_availability):
                return True
        
        return False

Originally posted by @tbhallett in #1633 (comment)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions