Source code for cosapp.utils.parsing

from typing import Optional, Tuple, List
from collections.abc import Collection

import numpy

from .helpers import check_arg


# TODO should we reintegrate it as Boundary method as it is now the only used place
[docs]def get_indices( syst: "cosapp.core.module.Module", name: str, ) -> Tuple[str, Optional[numpy.ndarray]]: """Decompose a variable specification into its name and its mask. Parameters ---------- syst : Module Module to which belong the variable name : str Variable specification Returns ------- Tuple[str, Optional[numpy.ndarray[bool]]] Tuple (variable name, variable mask or None) """ check_arg(name, 'name', str) if "[" in name: # User want to use a part of a sequence var_name, selector = name.split("[", maxsplit=1) selector = "[" + selector else: var_name = name selector = None if var_name not in syst: raise AttributeError( f"Variable {var_name!r} is not known in system {syst.name!r}." ) value = syst[var_name] if selector: # Check value is an array if not ( isinstance(value, numpy.ndarray) and numpy.issubdtype(value.dtype, numpy.number) and value.size > 1 ): raise TypeError( f"Only non-empty numpy array can be partially selected; got '{syst.name}.{name}'." ) mask = numpy.zeros(value.shape, dtype=bool) # Set the mask using the selector try: exec(f"mask{selector} = True", {}, {"mask": mask}) except (SyntaxError, IndexError) as err: raise type(err)( "Selection {!r} for variable '{}.{}' is not valid: {!s}".format( selector, syst.name, var_name, err ) ) else: mask = None if isinstance(value, Collection) and not isinstance(value, str): mask = numpy.ones_like(value, dtype=bool) return var_name, mask
[docs]def multi_split(expression: str, separators: List[str]) -> Tuple[List[str], List[str]]: """Extension of `str.split`, accounting for more than one split separators. Parameters: ----------- - expression [str]: Expression to be split. - separators [List[str]]: List of separators. Returns: -------- - expressions [List[str]]: List of n split expressions. - separators [List[str]]: Sequence of (n - 1) separators between split expressions. Examples: --------- >>> multi_split('a+b-c-d+e', list('+-')) ['a', 'b', 'c', 'd', 'e'], ['+', '-', '-', '+'] """ expressions = [expression] sep_list = [] for separator in set(separators): new_list = [] shift = 0 for i, expression in enumerate(expressions): sublist = expression.split(separator) n_hits = len(sublist) - 1 new_list.extend(sublist) if n_hits > 0: j = i + shift shift += n_hits sep_list = sep_list[:j] + [separator] * n_hits + sep_list[j:] expressions = list(map(str.strip, new_list)) return expressions, sep_list