def no_intersections(nodes1, degree1, nodes2, degree2):
    """Determine if one triangle is in the other.

    Helper for :func:`combine_intersections` that handles the case
    of no points of intersection. In this case, either the triangles
    are disjoint or one is fully contained in the other.

    To check containment, it's enough to check if one of the corners
    is contained in the other triangle.

    Args:
        nodes1 (numpy.ndarray): The nodes defining the first triangle in
            the intersection (assumed in :math:\\mathbf{R}^2`).
        degree1 (int): The degree of the triangle given by ``nodes1``.
        nodes2 (numpy.ndarray): The nodes defining the second triangle in
            the intersection (assumed in :math:\\mathbf{R}^2`).
        degree2 (int): The degree of the triangle given by ``nodes2``.

    Returns:
        Tuple[Optional[list], Optional[bool]]: Pair (2-tuple) of

        * Edges info list; will be empty or :data:`None`
        * "Contained" boolean. If not :data:`None`, indicates
          that one of the triangles is contained in the other.
    """
    from bezier import _py_triangle_intersection
    located = _py_triangle_intersection.locate_point(nodes2, degree2,
        nodes1[0, 0], nodes1[1, 0])
    if located is not None:
        return None, True
    located = _py_triangle_intersection.locate_point(nodes1, degree1,
        nodes2[0, 0], nodes2[1, 0])
    if located is not None:
        return None, False
    return [], None


@staticmethod
def convert_csv_to_json(csv_report: str):
    """
        Convert a CSV string to a json file by parsing the first row as keys, and the rows as values
        :param csv_report: a csv string, delimited with "," and rows split with "
"
        :return: The csv as a json array
        """
    json_report = []
    rows = csv_report.split('\n')
    headers = rows[0].split(',')
    for row in rows[1:]:
        values = row.split(',')
        entity = {}
        for i in range(len(values)):
            if values[i] != 'N/A':
                entity[headers[i]] = values[i]
        json_report.append(entity)
    return json_report


def replace_bigrams(textdict, bigrams):
    """
    replace bigrams in the texts
    Input:
        - textdict: a dict with {docid: preprocessed_text}
        - bigrams: for bigrams scores
    Returns:
        - textdict: the same texts but preprocessed and with all bigrams joined as "word1_word2"
    """
    docids = set(textdict.keys())
    for did in docids:
        text = textdict[did]
        for bigram in bigrams:
            if bigram in text:
                text = text.replace(bigram, '%s_%s' % tuple(bigram.split()))
        textdict[did] = text
    return textdict


def get_query_string(arg):
    """
    Based on given options, generate query string from Genbank.
    """
    condition = []
    if arg.group is not None:
        condition.append('{}[filter]'.format(arg.group))
    if arg.query is not None:
        condition.append(arg.query)
    if arg.gene is not None:
        if ' ' in arg.gene:
            condition.append('"{}"[gene]'.format(arg.gene))
        else:
            condition.append('{}[gene]'.format(arg.gene))
    if arg.molecular is not None:
        d = {'DNA': 'biomol_genomic[PROP]', 'RNA': 'biomol_mrna[PROP]'}
        condition.append(d[arg.molecular])
    if arg.taxon is not None:
        condition.append('{}[ORGANISM]'.format(arg.taxon))
    if arg.organelle is not None:
        if arg.organelle in ('mt', 'mitochondrion'):
            condition.append('{mitochondrion}[filter]')
        else:
            condition.append('(plastid[filter] OR chloroplast[filter])')
    if arg.refseq:
        condition.append('refseq[filter]')
    if len(condition) > 0 and (arg.min_len is not None and arg.max_len is not
        None):
        condition.append('("{}"[SLEN] : "{}"[SLEN])'.format(arg.min_len,
            arg.max_len))
    if arg.exclude is not None:
        condition.append('NOT ({})'.format(arg.exclude))
    if not condition:
        return None
    else:
        string = ' AND '.join(condition)
        string = string.replace('AND NOT', 'NOT')
        return string


@classmethod
def axesNames(cls):
    """ The names of the axes that this inspector visualizes.
            See the parent class documentation for a more detailed explanation.

            Returns an empty tuple; the data under inspection is zero-dimensional.
        """
    return tuple()


@classmethod
def to_yaml(cls, representer, data):
    """Required by :mod:`ruamel.yaml.constructor` """
    return representer.represent_scalar('!' + cls.__name__, str(data))


@classmethod
def where(cls, *expressions):
    """
        Creates and returns a query object, used for further chaining functions like sorting and pagination;
        :param expressions: the query filter expressions used to narrow the result-set
        :return: a query object preconfigured with the
        :rtype: Query
        """
    raise NotImplemented('abstract method')


@classmethod
def disable(cls):
    """Disables console domain, prevents further console messages from being reported to the client.
        """
    return cls.build_send_payload('disable', {}), None


def piggify(fspec, target_fspec, opts, data):
    """Sample file processor."""
    pass


def __call__(event, bubbled=False, rule_filter=None):
    """Execute all rules applicable in the current context

        event is the triggering event. bubbled should be True if the rules
        are being executed as part of a bubbling up of events (i.e. this
        is a parent of the context where the event was triggered). filter,
        if given, is a callable that will be passed each rule in turn and
        can vote on whether it should be executed by returning True or
        False. It should take the arguments (context, rule, event).
        """


def _get_all_scopes(blocks):
    """Get all block-local scopes from an IR.
    """
    all_scopes = []
    for label, block in blocks.items():
        if not block.scope in all_scopes:
            all_scopes.append(block.scope)
    return all_scopes


def render_git_describe(pieces):
    """TAG[-DISTANCE-gHEX][-dirty].

    Like 'git describe --tags --dirty --always'.

    Exceptions:
    1: no tags. HEX[-dirty]  (note: no 'g' prefix)
    """
    if pieces['closest-tag']:
        rendered = pieces['closest-tag']
        if pieces['distance']:
            rendered += '-%d-g%s' % (pieces['distance'], pieces['short'])
    else:
        rendered = pieces['short']
    if pieces['dirty']:
        rendered += '-dirty'
    return rendered


def get_pyfile_pair(filename):
    """ Given the filename of a Python source or byte compiled filename,
  returns a pair of the source and byte compiled filename. """
    if filename.endswith('.py'):
        filename = filename[:-3]
    elif filename.endswith('.pyc'):
        filename = filename[:-4]
    else:
        raise ValueError('filename does not end with .py or .pyc')
    return filename + '.py', filename + '.pyc'


@classmethod
def get(cls, project_id, rating_table_id):
    """Retrieve a single rating table

        Parameters
        ----------
        project_id : str
            The ID of the project the rating table is associated with.
        rating_table_id : str
            The ID of the rating table

        Returns
        -------
        rating_table : RatingTable
            The queried instance
        """
    path = 'projects/{}/ratingTables/{}/'.format(project_id, rating_table_id)
    rating_table = cls.from_location(path)
    return rating_table


def get_minimum_role():
    """Get the minimum role needed to access the content here.
        """


@classmethod
def _add_decorators(cls, func, get_attribute):
    """
        Adds the custom route decorators from the `decorators` class attribute to the route.

        Arguments:
            func: The decorated request handler function.
            get_attribute: Attribute getter function to use.
        """
    decorators = get_attribute(cls, 'decorators', None)
    if decorators is not None:
        for decorator in reversed(decorators):
            func = decorator(func)
    return func


def getPeer():
    """
        Returns L{UNIXAddress}.
        """


def is_float(s):
    """Test if a string represents a float."""
    try:
        float(s)
        return True
    except ValueError:
        return False


def pre_solve(instance, outputs_dir=None):
    """
    Call pre-solve function (if present) in all modules used to compose this model.
    This function can be used to adjust the instance after it is created and before it is solved.
    """
    for module in instance.get_modules():
        if hasattr(module, 'pre_solve'):
            module.pre_solve(instance)


def _fixSlist(slist):
    """ Guarantees that a signed list has exactly four elements. """
    slist.extend([0] * (4 - len(slist)))
    return slist[:4]


@classmethod
def get_task_family(cls):
    """
        The task family for the given class.

        If ``task_namespace`` is not set, then it's simply the name of the
        class.  Otherwise, ``<task_namespace>.`` is prefixed to the class name.

        Note: You normally don't want to override this.
        """
    if not cls.get_task_namespace():
        return cls.__name__
    else:
        return '{}.{}'.format(cls.get_task_namespace(), cls.__name__)


@classmethod
def convert_days_to_time_unit(cls, days, time_unit=None):
    """
        Converts an amount of days to the specified time unit, as the ORM returns differences in days.
        """
    from ..models import SystemParameter
    from ..constants import TimeUnitType, FieldDataType
    from django.utils.translation import ugettext as _
    if isinstance(str, time_unit):
        time_unit = TimeUnitType.to_enum(time_unit)
    if time_unit is None:
        time_unit = TimeUnitType.to_enum(SystemParameter.find_one(
            'DEFAULT_TIME_UNIT', FieldDataType.STRING, TimeUnitType.HOUR))
    if time_unit == TimeUnitType.YEAR:
        return days / 365
    if time_unit == TimeUnitType.MONTH:
        return days / 30
    if time_unit == TimeUnitType.DAY:
        return days
    if time_unit == TimeUnitType.HOUR:
        return days * 24
    if time_unit == TimeUnitType.MINUTE:
        return days * 24 * 60
    if time_unit == TimeUnitType.SECOND:
        return days * 24 * 60 * 60
    raise ValueError(_(__name__ + '.exceptions.invalid_time_unit'))


def extract_entities(seq: list, x=None) ->list:
    """Extract entities from a sequences

    ---
    input: ['B', 'I', 'I', 'O', 'B', 'I']
    output: [(0, 3, ''), (4, 6, '')]
    ---
    input: ['B-loc', 'I-loc', 'I-loc', 'O', 'B-per', 'I-per']
    output: [(0, 3, '-loc'), (4, 6, '-per')]
    ---
    input:
        seq=['B-loc', 'I-loc', 'I-loc', 'O', 'B-per', 'I-per']
        x='我爱你欧巴桑'
    output:
        [(0, 3, '-loc', '我爱你'), (4, 6, '-per', '巴桑')]
    """
    ret = []
    start_ind, start_type = -1, None
    for i, tag in enumerate(seq):
        if tag.startswith('S'):
            if x is not None:
                ret.append((i, i + 1, tag[1:], x[i:i + 1]))
            else:
                ret.append((i, i + 1, tag[1:]))
            start_ind, start_type = -1, None
        if tag.startswith('B') or tag.startswith('O'):
            if start_ind >= 0:
                if x is not None:
                    ret.append((start_ind, i, start_type, x[start_ind:i]))
                else:
                    ret.append((start_ind, i, start_type))
                start_ind, start_type = -1, None
        if tag.startswith('B'):
            start_ind = i
            start_type = tag[1:]
    if start_ind >= 0:
        if x is not None:
            ret.append((start_ind, len(seq), start_type, x[start_ind:]))
        else:
            ret.append((start_ind, len(seq), start_type))
        start_ind, start_type = -1, None
    return ret


def watch_for_pystol_timeouts(stop):
    """
    Watch for action with timeouts.

    This method will listen for custom objects
    that times out.
    """
    while True:
        return True


def mule_msg(message, mule_farm=None):
    """Sends a message to a mule(s)/farm.

    :param str|unicode message:

    :param mule_farm: Mule ID, or farm name.

    :rtype: bool

    :raises ValueError: If no mules, or mule ID or farm name is not recognized.
    """
    return False


def preparse_address(addr_spec):
    """
    Preparses email addresses. Used to handle odd behavior by ESPs.
    """
    parts = addr_spec.split('@')
    if len(parts) < 2:
        return None
    if parts[1] == 'gmail.com' or parts[1] == 'googlemail.com':
        parts[0] = parts[0].replace('.', '')
    return parts


def with_metaclass(meta, *bases):
    """Create a base class with a metaclass."""
    return meta('NewBase', bases, {})


def normalize_slice(e, n):
    """
    Return the slice tuple normalized for an ``n``-element object.

    :param e: a slice object representing a selector
    :param n: number of elements in a sequence to which ``e`` is applied
    :returns: tuple ``(start, count, step)`` derived from ``e``.
    """
    if n == 0:
        return 0, 0, 1
    step = e.step
    if step is None:
        step = 1
    if step == 0:
        start = e.start
        count = e.stop
        if isinstance(start, int) and isinstance(count, int) and count >= 0:
            if start < 0:
                start += n
            if start < 0:
                return 0, 0, 0
            return start, count, 0
        else:
            raise ValueError('Invalid slice %r' % e)
    assert isinstance(step, int) and step != 0
    if e.start is None:
        start = 0 if step > 0 else n - 1
    else:
        start = e.start
        if start < 0:
            start += n
        if start < 0 and step < 0 or start >= n and step > 0:
            return 0, 0, 0
        start = min(max(0, start), n - 1)
    assert isinstance(start, int
        ) and 0 <= start < n, 'Invalid start: %r' % start
    if e.stop is None:
        if step > 0:
            count = (n - 1 - start) // step + 1
        else:
            count = start // -step + 1
    else:
        stop = e.stop
        if stop < 0:
            stop += n
        if step > 0:
            if stop > start:
                count = (min(n, stop) - 1 - start) // step + 1
            else:
                count = 0
        elif stop < start:
            count = (start - max(stop, -1) - 1) // -step + 1
        else:
            count = 0
    assert isinstance(count, int) and count >= 0
    assert count == 0 or 0 <= start + step * (count - 1
        ) < n, 'Wrong tuple: (%d, %d, %d)' % (start, count, step)
    return start, count, step


def drange(v0, v1, d):
    """Returns a discrete range."""
    assert v0 < v1, str((v0, v1, d))
    return list(range(int(v0) // d, int(v1 + d) // d))


def scan_setup_py():
    """Validate the contents of setup.py against Versioneer's expectations."""
    found = set()
    setters = False
    errors = 0
    with open('setup.py', 'r') as f:
        for line in f.readlines():
            if 'import versioneer' in line:
                found.add('import')
            if 'versioneer.get_cmdclass()' in line:
                found.add('cmdclass')
            if 'versioneer.get_version()' in line:
                found.add('get_version')
            if 'versioneer.VCS' in line:
                setters = True
            if 'versioneer.versionfile_source' in line:
                setters = True
    if len(found) != 3:
        print('')
        print('Your setup.py appears to be missing some important items')
        print('(but I might be wrong). Please make sure it has something')
        print('roughly like the following:')
        print('')
        print(' import versioneer')
        print(' setup( version=versioneer.get_version(),')
        print('        cmdclass=versioneer.get_cmdclass(),  ...)')
        print('')
        errors += 1
    if setters:
        print("You should remove lines like 'versioneer.VCS = ' and")
        print("'versioneer.versionfile_source = ' . This configuration")
        print('now lives in setup.cfg, and should be removed from setup.py')
        print('')
        errors += 1
    return errors


def delete_references(content, name=None):
    """Lookup and remove multiple references.
        """


def jaccard_similarity(s1, s2):
    """Compute Jaccard similarity of two sets."""
    s1 = set(s1)
    s2 = set(s2)
    return len(s1 & s2) / len(s1 | s2)


def render_pep440_old(pieces):
    """TAG[.postDISTANCE[.dev0]] .

    The ".dev0" means dirty.

    Eexceptions:
    1: no tags. 0.postDISTANCE[.dev0]
    """
    if pieces['closest-tag']:
        rendered = pieces['closest-tag']
        if pieces['distance'] or pieces['dirty']:
            rendered += '.post%d' % pieces['distance']
            if pieces['dirty']:
                rendered += '.dev0'
    else:
        rendered = '0.post%d' % pieces['distance']
        if pieces['dirty']:
            rendered += '.dev0'
    return rendered


def np_reshape_safe(A, shape, just_warn=False):
    """
    ndarray.reshape has the potential to create a copy. This will will raise an exception or issue
    a warning if a copy would be made.
    """
    import warnings
    res = A.view()
    if just_warn:
        try:
            res.shape = shape
        except AttributeError:
            warnings.warn(
                'Reshape made a copy rather than just returning a view',
                stacklevel=2)
            res = A.reshape(shape)
    else:
        res.shape = shape
    return res


def hide_view_clear():
    """Reveal the object by setting the hide flag

    """
    pass


def _find_contraction(positions, input_sets, output_set):
    """
    Finds the contraction for a given set of input and output sets.

    Parameters
    ----------
    positions : iterable
        Integer positions of terms used in the contraction.
    input_sets : list
        List of sets that represent the lhs side of the einsum subscript
    output_set : set
        Set that represents the rhs side of the overall einsum subscript

    Returns
    -------
    new_result : set
        The indices of the resulting contraction
    remaining : list
        List of sets that have not been contracted, the new set is appended to
        the end of this list
    idx_removed : set
        Indices removed from the entire contraction
    idx_contraction : set
        The indices used in the current contraction

    Examples
    --------

    # A simple dot product test case
    >>> pos = (0, 1)
    >>> isets = [set('ab'), set('bc')]
    >>> oset = set('ac')
    >>> _find_contraction(pos, isets, oset)
    ({'a', 'c'}, [{'a', 'c'}], {'b'}, {'a', 'b', 'c'})

    # A more complex case with additional terms in the contraction
    >>> pos = (0, 2)
    >>> isets = [set('abd'), set('ac'), set('bdc')]
    >>> oset = set('ac')
    >>> _find_contraction(pos, isets, oset)
    ({'a', 'c'}, [{'a', 'c'}, {'a', 'c'}], {'b', 'd'}, {'a', 'b', 'c', 'd'})
    """
    idx_contract = set()
    idx_remain = output_set.copy()
    remaining = []
    for ind, value in enumerate(input_sets):
        if ind in positions:
            idx_contract |= value
        else:
            remaining.append(value)
            idx_remain |= value
    new_result = idx_remain & idx_contract
    idx_removed = idx_contract - new_result
    remaining.append(new_result)
    return new_result, remaining, idx_removed, idx_contract


@staticmethod
def add_space(window):
    """
        Shortcut for adding a single space to a window at the current position
        """
    row, col = window.getyx()
    _, max_cols = window.getmaxyx()
    n_cols = max_cols - col - 1
    if n_cols <= 0:
        return
    window.addstr(row, col, ' ')


def deregister_volume(VolumeId=None):
    """
    Deregisters an Amazon EBS volume. The volume can then be registered by another stack. For more information, see Resource Management .
    See also: AWS API Documentation

    :example: response = client.deregister_volume(
        VolumeId='string'
    )

    :type VolumeId: string
    :param VolumeId: [REQUIRED]
            The AWS OpsWorks Stacks volume ID, which is the GUID that AWS OpsWorks Stacks assigned to the instance when you registered the volume with the stack, not the Amazon EC2 volume ID.

    """
    pass


def m2m_clean_unchanged_fields(dict_diff):
    """
    returns a list of dicts with only the changes
    """
    dict_list = []
    for key in sorted(dict_diff):
        new_dict = {}
        dict_ = dict_diff.get(key)
        for value in sorted(dict_):
            compound_key = '%s.%s' % (key, value)
            if dict_[value][0] == dict_[value][1]:
                del dict_[value]
            else:
                new_dict[compound_key] = dict_[value]
        del dict_diff[key]
        if new_dict:
            dict_list.append(new_dict)
    return dict_list


def fromargskw(argskw, argspecs, slf_or_clsm=False):
    """Turns a linearized list of args into (args, keywords) form
    according to given argspecs (like inspect module provides).
    """
    res_args = argskw
    try:
        kwds = argspecs.keywords
    except AttributeError:
        kwds = argspecs.varkw
    if not kwds is None:
        res_kw = argskw[-1]
        res_args = argskw[:-1]
    else:
        res_kw = None
    if not argspecs.varargs is None:
        vargs_pos = len(argspecs.args) - 1 if slf_or_clsm else len(argspecs
            .args)
        if vargs_pos > 0:
            res_lst = list(argskw[:vargs_pos])
            res_lst.extend(argskw[vargs_pos])
            res_args = tuple(res_lst)
        else:
            res_args = argskw[0]
    try:
        if len(argspecs.kwonlyargs) > 0:
            res_kw = {} if res_kw is None else dict(res_kw)
            ipos = -len(argspecs.kwonlyargs) - (0 if kwds is None else 1)
            for name in argspecs.kwonlyargs:
                res_kw[name] = argskw[ipos]
                ipos += 1
    except AttributeError:
        pass
    if res_kw is None:
        res_kw = {}
    return res_args, res_kw


def Confinement(D, rhol, rhog, sigma, g=g):
    """Calculates Confinement number or `Co` for a fluid in a channel of
    diameter `D` with liquid and gas densities `rhol` and `rhog` and surface
    tension `sigma`, under the influence of gravitational force `g`.

    .. math::
        \\text{Co}=\\frac{\\left[\\frac{\\sigma}{g(\\rho_l-\\rho_g)}\\right]^{0.5}}{D}

    Parameters
    ----------
    D : float
        Diameter of channel, [m]
    rhol : float
        Density of liquid phase, [kg/m^3]
    rhog : float
        Density of gas phase, [kg/m^3]
    sigma : float
        Surface tension between liquid-gas phase, [N/m]
    g : float, optional
        Acceleration due to gravity, [m/s^2]

    Returns
    -------
    Co : float
        Confinement number [-]

    Notes
    -----
    Used in two-phase pressure drop and heat transfer correlations. First used
    in [1]_ according to [3]_.

    .. math::
        \\text{Co} = \\frac{\\frac{\\text{surface tension force}}
        {\\text{buoyancy force}}}{\\text{Channel area}}

    Examples
    --------
    >>> Confinement(0.001, 1077, 76.5, 4.27E-3)
    0.6596978265315191

    References
    ----------
    .. [1] Cornwell, Keith, and Peter A. Kew. "Boiling in Small Parallel
       Channels." In Energy Efficiency in Process Technology, edited by Dr P.
       A. Pilavachi, 624-638. Springer Netherlands, 1993.
       doi:10.1007/978-94-011-1454-7_56.
    .. [2] Kandlikar, Satish G. Heat Transfer and Fluid Flow in Minichannels
       and Microchannels. Elsevier, 2006.
    .. [3] Tran, T. N, M. -C Chyu, M. W Wambsganss, and D. M France. Two-Phase
       Pressure Drop of Refrigerants during Flow Boiling in Small Channels: An
       Experimental Investigation and Correlation Development." International
       Journal of Multiphase Flow 26, no. 11 (November 1, 2000): 1739-54.
       doi:10.1016/S0301-9322(99)00119-6.
    """
    return (sigma / (g * (rhol - rhog))) ** 0.5 / D


def _parse_object_status(status):
    """Parse input status into action and status if possible.

    This function parses a given string (or list of strings) and see if it
    contains the action part. The action part is exacted if found.

    :param status: A string or a list of strings where each string contains
                   a status to be checked.
    :returns: (actions, statuses) tuple, where actions is a set of actions
              extracted from the input status and statuses is a set of pure
              object status.
    """
    if not isinstance(status, list):
        status = [status]
    status_set = set()
    action_set = set()
    for val in status:
        for s in ('COMPLETE', 'FAILED', 'IN_PROGRESS'):
            index = val.rfind(s)
            if index != -1:
                status_set.add(val[index:])
                if index > 1:
                    action_set.add(val[:index - 1])
                break
    return action_set, status_set


def _set_config(c):
    """Set gl configuration for template"""
    raise NotImplementedError


def cache(path):
    """
    Method for setting options during request session.

    Example:
        >>> from faux import requests
        >>> requests.cache('/path/to/local/cache')
        >>> requests.get('http://localhost')
    """
    global CACHE
    if not path:
        raise AssertionError(
            'Invalid path specified for cache directory ("{}")!'.format(path))
    CACHE = path
    return


def _check_mne(name):
    """Helper to check if h5py is installed"""
    try:
        import mne
    except ImportError:
        raise ImportError('Please install MNE-python to use %s.' % name)
    return mne


def isarray(x):
    """Check if variable is an array"""
    if isinstance(x, str):
        return False
    if hasattr(x, '__getitem__'):
        return True
    else:
        return False


def render_pep440_pre(pieces):
    """TAG[.post.devDISTANCE] -- No -dirty.

    Exceptions:
    1: no tags. 0.post.devDISTANCE
    """
    if pieces['closest-tag']:
        rendered = pieces['closest-tag']
        if pieces['distance']:
            rendered += '.post.dev%d' % pieces['distance']
    else:
        rendered = '0.post.dev%d' % pieces['distance']
    return rendered


def add_navigation(app):
    """ Add navigation to app """
    from boiler.feature.navigation import navigation_feature
    navigation_feature(app)


def extract_ini_from_doc(doc):
    """Extracts INI from doc strings."""
    return doc.rsplit('INI')[-1]


def select_component_mass(gx_component):
    """Select the Galactic component mass according to
    McMillan (2011)

    Parameters
    ----------
    gx_component : str
        Choose from: 'ThinDisk', 'Bulge', 'ThickDisk'

    Returns
    -------
    gx_component_mass : float
        Galactic component mass [Msun]
    """
    if gx_component == 'ThinDisk':
        gx_component_mass = 43200000000.0
    elif gx_component == 'Bulge':
        gx_component_mass = 8900000000.0
    elif gx_component == 'ThickDisk':
        gx_component_mass = 14400000000.0
    return gx_component_mass


def roteParser(line, frame, time, value, ref1, ref2, ref3, extra):
    """
    R-OTE sample line ---
        1.00,[17:25:39.3415],2737.8,3897.32,675.3,892.12
    """
    part = line.split(',')
    frame.append(part[0])
    time.append(part[1])
    value.append(part[2])
    if len(part) >= 4:
        if part[3]:
            ref1.append(part[3])
    if len(part) >= 5:
        if part[4]:
            ref2.append(part[4])
    if len(part) >= 6:
        if part[5]:
            ref3.append(part[5])


def meta_separate():
    """Put the contents of a metastrip back in the sequencer

    """
    pass


def set_bit(v, index, x):
    """Set the index:th bit of v to 1 if x is truthy, else to 0, and return the new value."""
    mask = 1 << index
    v &= ~mask
    if x:
        v |= mask
    return v


@classmethod
def get_report_model(cls):
    """
        Problem: During tests, override settings is used, making the report model always returning the model
        'first to be found' not the potentially swapped one ,raising an error. so , it is advised to use this method instead
            of declaring the report model on the module level.
        :return: the Model to use
        """
    return cls.report_model


def response_for_status(cls, status):
    """
        Generate a status string for the status code

        :param int status: the status code to look-up
        :returns: string for the value or an appropriate Unknown value
        """
    if status in cls.status_values:
        return cls.status_values[status]
    elif status >= 100 and status < 200:
        return 'Unknown Informational Status'
    elif status >= 200 and status < 300:
        return 'Unknown Success Status'
    elif status >= 300 and status < 400:
        return 'Unknown Redirection Status'
    elif status >= 400 and status < 500:
        return 'Unknown Client Error'
    elif status >= 500 and status < 600:
        return 'Unknown Server Error'
    else:
        return 'Unknown Status'


def get_resource(restApiId=None, resourceId=None, embed=None):
    """
    Lists information about a resource.
    See also: AWS API Documentation

    :example: response = client.get_resource(
        restApiId='string',
        resourceId='string',
        embed=[
            'string',
        ]
    )

    :type restApiId: string
    :param restApiId: [REQUIRED]
            The RestApi identifier for the resource.

    :type resourceId: string
    :param resourceId: [REQUIRED]
            The identifier for the Resource resource.

    :type embed: list
    :param embed: A query parameter to retrieve the specified resources embedded in the returned Resource representation in the response. This embed parameter value is a list of comma-separated strings. Currently, the request supports only retrieval of the embedded Method resources this way. The query parameter value must be a single-valued list and contain the 'methods' string. For example, GET /restapis/{restapi_id}/resources/{resource_id}?embed=methods .
            (string) --

    :rtype: dict
    :return: {
        'id': 'string',
        'parentId': 'string',
        'pathPart': 'string',
        'path': 'string',
        'resourceMethods': {
            'string': {
                'httpMethod': 'string',
                'authorizationType': 'string',
                'authorizerId': 'string',
                'apiKeyRequired': True|False,
                'requestValidatorId': 'string',
                'operationName': 'string',
                'requestParameters': {
                    'string': True|False
                },
                'requestModels': {
                    'string': 'string'
                },
                'methodResponses': {
                    'string': {
                        'statusCode': 'string',
                        'responseParameters': {
                            'string': True|False
                        },
                        'responseModels': {
                            'string': 'string'
                        }
                    }
                },
                'methodIntegration': {
                    'type': 'HTTP'|'AWS'|'MOCK'|'HTTP_PROXY'|'AWS_PROXY',
                    'httpMethod': 'string',
                    'uri': 'string',
                    'credentials': 'string',
                    'requestParameters': {
                        'string': 'string'
                    },
                    'requestTemplates': {
                        'string': 'string'
                    },
                    'passthroughBehavior': 'string',
                    'contentHandling': 'CONVERT_TO_BINARY'|'CONVERT_TO_TEXT',
                    'cacheNamespace': 'string',
                    'cacheKeyParameters': [
                        'string',
                    ],
                    'integrationResponses': {
                        'string': {
                            'statusCode': 'string',
                            'selectionPattern': 'string',
                            'responseParameters': {
                                'string': 'string'
                            },
                            'responseTemplates': {
                                'string': 'string'
                            },
                            'contentHandling': 'CONVERT_TO_BINARY'|'CONVERT_TO_TEXT'
                        }
                    }
                }
            }
        }
    }

    :returns:
    (string) --
    (boolean) --

    """
    pass


def _format_message(message, args):
    """
    Format a message using the args list. The result will be equivalent to

        message % args

    If args list contains a dictionary as its only element the result will be

        message % args[0]

    :param str message: the template string to be formatted
    :param tuple args: a list of arguments
    :return: the formatted message
    :rtype: str
    """
    if len(args) == 1 and isinstance(args[0], dict):
        return message % args[0]
    elif len(args) > 0:
        return message % args
    else:
        return message


def get_project_milestones(gl, project_id):
    """ Get Project's Milestones
    :param gl: GitLab Object Instance
    :param project_id: Project Identifier (int)
    :return: Milestones (List)
    """
    return False


def get_getmodel_itm_cmd(number_of_samples, gul_threshold,
    use_random_number_file, gul_alloc_rule, item_output, process_id,
    max_process_id, correlated_output, **kwargs):
    """
    Gets the getmodel ktools command (3.1.0+) Gulcalc item stream
    :param number_of_samples: The number of samples to run
    :type number_of_samples: int
    :param gul_threshold: The GUL threshold to use
    :type gul_threshold: float
    :param use_random_number_file: flag to use the random number file
    :type use_random_number_file: bool
    :param gul_alloc_rule: back allocation rule for gulcalc
    :type gul_alloc_rule: int
    :param item_output: The item output
    :type item_output: str
    :return: The generated getmodel command
    """
    cmd = 'eve {0} {1} | getmodel | gulcalc -S{2} -L{3}'.format(process_id,
        max_process_id, number_of_samples, gul_threshold)
    if use_random_number_file:
        cmd = '{} -r'.format(cmd)
    if correlated_output != '':
        cmd = '{} -j {}'.format(cmd, correlated_output)
    cmd = '{} -a{} -i {}'.format(cmd, gul_alloc_rule, item_output)
    return cmd


def p_w_from_rh_p_and_ws(rh, p_ws):
    """
    Calculate water vapor pressure from relative humidity and water vapor saturation pressure
    Eq(6) in "CHAPTER 6 - PSYCHROMETRICS" in "2001 ASHRAE Fundamentals Handbook (SI)"

    :param rh: relative humidity [-]
    :type rh: double
    :param p_ws: water vapor saturation pressure [Pa]
    :type p_ws: double
    :return: water vapor pressure [Pa]
    :rtype: double
    """
    return rh * p_ws


@classmethod
def team_merge_request_canceled_shown_to_primary_team_details(cls, val):
    """
        Create an instance of this class set to the
        ``team_merge_request_canceled_shown_to_primary_team_details`` tag with
        value ``val``.

        :param TeamMergeRequestCanceledShownToPrimaryTeamDetails val:
        :rtype: EventDetails
        """
    return cls('team_merge_request_canceled_shown_to_primary_team_details', val
        )


def neg_edges(data):
    """
    Negate edge half (non-middle) of spectra.
    """
    data[(...), :int(data.shape[-1] * 1.0 / 4)] = -data[(...), :int(data.
        shape[-1] * 1.0 / 4)]
    data[(...), int(data.shape[-1] * 3.0 / 4):] = -data[(...), int(data.
        shape[-1] * 3.0 / 4):]
    return data


def create_file_with_license_notice(path: str, file_extension: str) ->None:
    """utility function to create a new file with license notice included"""
    with open('LICENSE_NOTICE', 'r') as file:
        license_notice: str = file.read()
    if 'c' == file_extension or 'cpp' == file_extension:
        from data.new_file.cpp import FILE_CONTENT
    elif 'java' == file_extension:
        from data.new_file.java import FILE_CONTENT
    elif 'js' == file_extension:
        from data.new_file.js import FILE_CONTENT
    else:
        from data.new_file.py import FILE_CONTENT
    FILE_CONTENT = FILE_CONTENT.replace('[NOTICE]', license_notice)
    with open(path, 'w') as file:
        file.write(FILE_CONTENT)


def GetTargetCBVs(model):
    """
  Returns the design matrix of CBVs for the given target.

  :param model: An instance of the :py:obj:`everest` model for the target

  """
    raise NotImplementedError('This mission is not yet supported.')


@classmethod
def decode(cls, value):
    """
        convert from redis bytes into a boolean value

        :param value: bytes
        :return: bool
        """
    return None if value is None else bool(value)


@classmethod
def import_(cls, config):
    """
        Imports peer from string.
        :param config:
        :return:
        """
    instnace = cls()
    for line in config:
        line = line.strip()
        setattr(instnace, line.split(':')[0].replace(' ', '_'), line.split(
            ':')[1])
    return instnace


def is_multitarget_regressor(clf):
    """
    Return True if a regressor is multitarget
    or False if it predicts a single target.
    """
    return len(clf.coef_.shape) > 1 and clf.coef_.shape[0] > 1


def vector_dot(xyz, vector):
    """
    Take a dot product between an array of vectors, xyz and a vector [x, y, z]

    **Required**

    :param numpy.ndarray xyz: grid (npoints x 3)
    :param numpy.ndarray vector: vector (1 x 3)

    **Returns**

    :returns: dot product between the grid and the (1 x 3) vector, returns an
              (npoints x 1) array
    :rtype: numpy.ndarray
    """
    if len(vector) != 3:
        raise Exception('vector should be length 3, the provided length is {}'
            .format(len(vector)))
    return vector[0] * xyz[:, (0)] + vector[1] * xyz[:, (1)] + vector[2] * xyz[
        :, (2)]


def luma(p):
    """
    Returns brightness of a pixel, based on relative luminance
    This is based on ITU-R BT.709. Note that human eyes are most sensitive to green light.
    :param p: A tuple of (R,G,B) values
    :return: The relative luminance of a pixel (in the range [0, 255]).
    """
    return 0.2126 * p[0] + 0.7152 * p[1] + 0.0722 * p[2]


@classmethod
def parse(cls, data):
    """Parse a JSON object into a model instance."""
    raise NotImplementedError


@classmethod
def fromkeys(cls, *args, verify=True, mutable=True, **kwargs):
    """Initialise a header from keyword values.

        Like fromvalues, but without any interpretation of keywords.

        Note that this just passes kwargs to the class initializer as a dict
        (for compatibility with fits.Header). It is present for compatibility
        with other header classes only.
        """
    return cls(kwargs, *args, verify=verify, mutable=mutable)


def in_p3(t: float) ->float:
    """
    cubic ease-in function

    :param t: input value in range [0,1]
    """
    return t * t * t


@classmethod
def get_buffer_size_in_pages(cls, address, size):
    """
        Get the number of pages in use by the given buffer.

        @type  address: int
        @param address: Aligned memory address.

        @type  size: int
        @param size: Buffer size.

        @rtype:  int
        @return: Buffer size in number of pages.
        """
    if size < 0:
        size = -size
        address = address - size
    begin, end = cls.align_address_range(address, address + size)
    return int(float(end - begin) / float(cls.pageSize))


def _format_vendor_id(vendor_id: str) ->str:
    """Strips vendor name from vendor_id field.

    Example:
        >>> _format_vendor_id("0x1234 (Nice Vendor Inc.)")  # "0x1234"
    """
    return vendor_id.split(maxsplit=1)[0]


def request_echo(request):
    """return request args (see utils.get_args) - for testing"""
    return request.args


@classmethod
def enabled(cls, val):
    """
        Create an instance of this class set to the ``enabled`` tag with value
        ``val``.

        :param bool val:
        :rtype: PaperAsFilesValue
        """
    return cls('enabled', val)


@classmethod
def send_to(cls, host, port, data, **kwargs):
    """
        Initializes a SocketConnector and sends the packet. Deletes the SocketConnector
        afterwards. Alias for:

        SocketConnector(host, port, **kwargs).send(data)
        """
    return cls(host, port, **kwargs).send(data)


def update(obj, values):
    """For given object, add all values in iterable values.

        Object and each value must be adaptable to IKeyReference.  Identical
        values (as determined by IKeyReference) are collapsed to a single
        instance (so, for instance, a set of [A, B, B, C, B] will be
        collapsed to a logical set of A, B, C).
        """


def bump_version_tail(oldver):
    """
    Takes any dot-separated version string and increments the rightmost field
    (which it expects to be an integer).
    """
    head, tail = oldver.rsplit('.', 1)
    return '%s.%d' % (head, int(tail) + 1)


def get_listfirst(item, group):
    """return the first found in a list (group) from a
    dictionary item.
    """
    if not isinstance(group, list):
        group = [group]
    for contender in group:
        if contender in item:
            return item[contender]
    return None


def describe_hapg(HapgArn=None):
    """
    Retrieves information about a high-availability partition group.
    See also: AWS API Documentation

    :example: response = client.describe_hapg(
        HapgArn='string'
    )

    :type HapgArn: string
    :param HapgArn: [REQUIRED]
            The ARN of the high-availability partition group to describe.

    :rtype: dict
    :return: {
        'HapgArn': 'string',
        'HapgSerial': 'string',
        'HsmsLastActionFailed': [
            'string',
        ],
        'HsmsPendingDeletion': [
            'string',
        ],
        'HsmsPendingRegistration': [
            'string',
        ],
        'Label': 'string',
        'LastModifiedTimestamp': 'string',
        'PartitionSerialList': [
            'string',
        ],
        'State': 'READY'|'UPDATING'|'DEGRADED'
    }

    """
    pass


def rmlinenumber(linenumber, infile, dryrun=False):
    """
    Sed-like line deletion function based on given line number..
    Usage: pysed.rmlinenumber(<Unwanted Line Number>, <Text File>)
    Example: pysed.rmlinenumber(10, '/path/to/file.txt')
    Example 'DRYRUN': pysed.rmlinenumber(10, '/path/to/file.txt', dryrun=True)
    #This will dump the output to STDOUT instead of changing the input file.

    """
    linelist = []
    linecounter = 0
    if isinstance(linenumber) != isinstance(linecounter):
        exit("'linenumber' argument must be an integer.")
    with open(infile) as f:
        for item in f:
            linecounter = linecounter + 1
            if linecounter != linenumber:
                linelist.append(item)
    if dryrun is False:
        with open(infile, 'w') as f:
            f.truncate()
            for line in linelist:
                f.writelines(line)
    elif dryrun is True:
        for line in linelist:
            print(line, end='')
    else:
        exit(
            """Unknown option specified to 'dryrun' argument,
              Usage: dryrun=<True|False>."""
            )


def ln(label):
    """Draw a 70-char-wide divider, with label in the middle.

    >>> ln('hello there')
    '---------------------------- hello there -----------------------------'
    """
    label_len = len(label) + 2
    chunk = (70 - label_len) // 2
    out = '%s %s %s' % ('-' * chunk, label, '-' * chunk)
    pad = 70 - len(out)
    if pad > 0:
        out = out + '-' * pad
    return out


def _check_valid(key, val, valid):
    """Helper to check valid options"""
    if val not in valid:
        raise ValueError('%s must be one of %s, not "%s"' % (key, valid, val))


@classmethod
def hexline(cls, data, separator=' ', width=None):
    """
        Dump a line of hexadecimal numbers from binary data.

        @type  data: str
        @param data: Binary data.

        @type  separator: str
        @param separator:
            Separator between the hexadecimal representation of each character.

        @type  width: int
        @param width:
            (Optional) Maximum number of characters to convert per text line.
            This value is also used for padding.

        @rtype:  str
        @return: Multiline output text.
        """
    if width is None:
        fmt = '%s  %s'
    else:
        fmt = '%%-%ds  %%-%ds' % ((len(separator) + 2) * width - 1, width)
    return fmt % (cls.hexadecimal(data, separator), cls.printable(data))


def render_git_describe(pieces):
    """TAG[-DISTANCE-gHEX][-dirty].

    Like 'git describe --tags --dirty --always'.

    Exceptions:
    1: no tags. HEX[-dirty]  (note: no 'g' prefix)
    """
    if pieces['closest-tag']:
        rendered = pieces['closest-tag']
        if pieces['distance']:
            rendered += '-%d-g%s' % (pieces['distance'], pieces['short'])
    else:
        rendered = pieces['short']
    if pieces['dirty']:
        rendered += '-dirty'
    return rendered


@classmethod
def get_options(cls):
    """
        Linux (OpenVZ) and Windows (KVM) pages are slightly different, therefore their pages are parsed by different
        methods. Windows configurations allow a selection of Linux distributions, but not vice-versa.
        :return: possible configurations.
        """
    browser = cls._create_browser()
    browser.open('https://www.2sync.co/vps/ukraine/')
    options = cls._parse_openvz_hosting(browser.get_current_page())
    lst = list(options)
    return lst


def delete_verified_email_address(EmailAddress=None):
    """
    Deletes the specified email address from the list of verified addresses.
    This action is throttled at one request per second.
    See also: AWS API Documentation

    Examples
    The following example deletes an email address from the list of identities that have been submitted for verification with Amazon SES:
    Expected Output:

    :example: response = client.delete_verified_email_address(
        EmailAddress='string'
    )

    :type EmailAddress: string
    :param EmailAddress: [REQUIRED]
            An email address to be removed from the list of verified addresses.

    :return: response = client.delete_verified_email_address(
        EmailAddress='user@example.com',
    )

    print(response)

    """
    pass


def add_time_offset(offset):
    """Adds specified number of microseconds to the offset applied to time() function result."""
    global _time_offset
    _time_offset += int(offset)


def epoch_to_timestamp(records):
    """
    Convert epoch timestamps to ISO 8601 (2015-01-04T09:30:21Z)

    :param records: List (of dictionaries)
    :return: List (of dictionaries)
    """
    from datetime import datetime
    for record in records:
        timestamp_keys = ['time_first', 'time_last']
        for key in timestamp_keys:
            if key in record:
                record[key] = datetime.fromtimestamp(record[key]).isoformat(
                    ) + 'Z'
    return records


def arr2dict(arr, keyname='key', valuename='value'):
    """
    arr2dict -  transform an array to dictionary key:
    """
    res = {}
    for item in arr:
        res[item[keyname]] = item[valuename] if valuename in item else None
    return res


@classmethod
def arg_fft(cls, parser):
    """Add an `~argparse.ArgumentGroup` for FFT options
        """
    group = parser.add_argument_group('Fourier transform options')
    group.add_argument('--secpfft', type=float, default=1.0, help=
        'length of FFT in seconds')
    group.add_argument('--overlap', type=float, help=
        'overlap as fraction of FFT length [0-1)')
    group.add_argument('--window', type=str, default='hann', help=
        'window function to use when overlapping FFTs')
    return group


def deploy_cert(domain, cert_path, key_path, chain_path, fullchain_path):
    """Deploy certificate.

        :param str domain: domain to deploy certificate file
        :param str cert_path: absolute path to the certificate file
        :param str key_path: absolute path to the private key file
        :param str chain_path: absolute path to the certificate chain file
        :param str fullchain_path: absolute path to the certificate fullchain
            file (cert plus chain)

        :raises .PluginError: when cert cannot be deployed

        """


def addon_userpref_show(module: str=''):
    """Show add-on user preferences

    :param module: Module, Module name of the add-on to expand
    :type module: str
    """
    pass


@classmethod
def get_recommended_protein_name(cls, entry):
    """
        get recommended full and short protein name as tuple from XML node

        :param entry: XML node entry
        :return: (str, str) => (full, short)
        """
    query_full = './protein/recommendedName/fullName'
    full_name = entry.find(query_full).text
    short_name = None
    query_short = './protein/recommendedName/shortName'
    short_name_tag = entry.find(query_short)
    if short_name_tag is not None:
        short_name = short_name_tag.text
    return full_name, short_name


@staticmethod
def matcher_strong_literal(token, terminal, m):
    """ Check whether the meaning matches a strong literal terminal,
            i.e. one that is enclosed in double quotes ("dæmi:hk") """
    return terminal.matches_first(m.ordfl, m.stofn, token.t1_lower)


def copy_name(apps, schema_editor):
    """
    Copies the exercise name to the original name field
    """
    Excercise = apps.get_model('exercises', 'Exercise')
    for exercise in Excercise.objects.all():
        exercise.name_original = exercise.name
        exercise.save()


def print_headers(list_headers, list_file_xml, list_file_json, list_file_csv):
    """
    File creation function - Print header into output file

    :param list_headers: List of headers
    :param list_file_xml: Different parts of xml file.
    :param list_file_json: Different parts of json file.
    :param list_file_csv: Different parts of csv file.
    """
    list_particular_header_csv = list()
    list_particular_header_json = list()
    list_particular_header_xml = ['\t<Item ']
    list_file_json.append(3 * '\t' + '{\r\n')
    for header in list_headers:
        if header['key'] is not None:
            if 'title' in header:
                if header['key'] != '#title':
                    list_particular_header_csv.append('_'.join((header[
                        'title'], header['key'], str(header['value']))))
                    list_particular_header_json.append(': '.join(('"-' +
                        str(header['title']) + '_' + str(header['key']).
                        replace('@', '', 1) + '"', '"' + str(header['value'
                        ]) + '"')))
                    list_particular_header_xml.append('='.join((str(header[
                        'title']) + '_' + str(header['key']).replace('@',
                        '', 1), '"' + str(header['value']) + '"')))
            elif header['key'] != '#title':
                list_particular_header_csv.append('_'.join((str(header[
                    'key']), str(header['value']))))
                list_particular_header_json.append(': '.join(('"-' + str(
                    header['key']).replace('@', '', 1) + '"', '"' + str(
                    header['value']) + '"')))
                list_particular_header_xml.append('='.join((str(header[
                    'key']).replace('@', '', 1), '"' + str(header['value']) +
                    '"')))
        else:
            list_particular_header_csv.append(str(header['title']))
    list_file_csv.append(', '.join(list_particular_header_csv) + '\r\n')
    list_file_json.append('\t\t\t\t' + ',\r\n\t\t\t\t'.join(
        list_particular_header_json) + ',\r\n')
    list_file_xml.append(' '.join(list_particular_header_xml) + '>\r\n')


def vector_dot(xyz, vector):
    """
    Take a dot product between an array of vectors, xyz and a vector [x, y, z]

    **Required**

    :param numpy.ndarray xyz: grid (npoints x 3)
    :param numpy.ndarray vector: vector (1 x 3)

    **Returns**

    :returns: dot product between the grid and the (1 x 3) vector, returns an
              (npoints x 1) array
    :rtype: numpy.ndarray
    """
    if len(vector) != 3:
        raise Exception('vector should be length 3, the provided length is {}'
            .format(len(vector)))
    return vector[0] * xyz[:, (0)] + vector[1] * xyz[:, (1)] + vector[2] * xyz[
        :, (2)]


def clean_bibtex_str(s):
    """Clean BibTeX string and escape TOML special characters"""
    s = s.replace('\\', '')
    s = s.replace('"', '\\"')
    s = s.replace('{', '').replace('}', '')
    s = s.replace('\t', ' ').replace('\n', ' ').replace('\r', '')
    return s


def theta_Cs_K_PK74(T, P):
    """c-c': caesium potassium [PK74]."""
    theta = 0.0
    valid = T == 298.15
    return theta, valid


def get(cls, reactor, source='graphite', **options):
    """Get Alert Class by source."""
    acls = cls.alerts[source]
    return acls(reactor, **options)


@classmethod
def repo_list(cls, *options):
    """
        List repositories in the registry.
        """
    repomgr = cls._ocean.RepoManager(cls._ocean)
    return repomgr.list_repos()


def islink():
    """
        Check if this file path refers to a symbolic ("soft") link.

        @return: C{True} if the file at this file path is a symbolic link, or
            C{False} otherwise.
        """


def create_load_balancer(Name=None, Subnets=None, SecurityGroups=None,
    Scheme=None, Tags=None, IpAddressType=None):
    """
    Creates an Application Load Balancer.
    When you create a load balancer, you can specify security groups, subnets, IP address type, and tags. Otherwise, you could do so later using  SetSecurityGroups ,  SetSubnets ,  SetIpAddressType , and  AddTags .
    To create listeners for your load balancer, use  CreateListener . To describe your current load balancers, see  DescribeLoadBalancers . When you are finished with a load balancer, you can delete it using  DeleteLoadBalancer .
    You can create up to 20 load balancers per region per account. You can request an increase for the number of load balancers for your account. For more information, see Limits for Your Application Load Balancer in the Application Load Balancers Guide .
    For more information, see Application Load Balancers in the Application Load Balancers Guide .
    See also: AWS API Documentation

    Examples
    This example creates an Internet-facing load balancer and enables the Availability Zones for the specified subnets.
    Expected Output:
    This example creates an internal load balancer and enables the Availability Zones for the specified subnets.
    Expected Output:

    :example: response = client.create_load_balancer(
        Name='string',
        Subnets=[
            'string',
        ],
        SecurityGroups=[
            'string',
        ],
        Scheme='internet-facing'|'internal',
        Tags=[
            {
                'Key': 'string',
                'Value': 'string'
            },
        ],
        IpAddressType='ipv4'|'dualstack'
    )

    :type Name: string
    :param Name: [REQUIRED]
            The name of the load balancer.
            This name must be unique per region per account, can have a maximum of 32 characters, must contain only alphanumeric characters or hyphens, and must not begin or end with a hyphen.

    :type Subnets: list
    :param Subnets: [REQUIRED]
            The IDs of the subnets to attach to the load balancer. You can specify only one subnet per Availability Zone. You must specify subnets from at least two Availability Zones.
            (string) --

    :type SecurityGroups: list
    :param SecurityGroups: The IDs of the security groups to assign to the load balancer.
            (string) --

    :type Scheme: string
    :param Scheme: The nodes of an Internet-facing load balancer have public IP addresses. The DNS name of an Internet-facing load balancer is publicly resolvable to the public IP addresses of the nodes. Therefore, Internet-facing load balancers can route requests from clients over the Internet.
            The nodes of an internal load balancer have only private IP addresses. The DNS name of an internal load balancer is publicly resolvable to the private IP addresses of the nodes. Therefore, internal load balancers can only route requests from clients with access to the VPC for the load balancer.
            The default is an Internet-facing load balancer.

    :type Tags: list
    :param Tags: One or more tags to assign to the load balancer.
            (dict) --Information about a tag.
            Key (string) -- [REQUIRED]The key of the tag.
            Value (string) --The value of the tag.

    :type IpAddressType: string
    :param IpAddressType: The type of IP addresses used by the subnets for your load balancer. The possible values are ipv4 (for IPv4 addresses) and dualstack (for IPv4 and IPv6 addresses). Internal load balancers must use ipv4 .

    :rtype: dict
    :return: {
        'LoadBalancers': [
            {
                'LoadBalancerArn': 'string',
                'DNSName': 'string',
                'CanonicalHostedZoneId': 'string',
                'CreatedTime': datetime(2015, 1, 1),
                'LoadBalancerName': 'string',
                'Scheme': 'internet-facing'|'internal',
                'VpcId': 'string',
                'State': {
                    'Code': 'active'|'provisioning'|'failed',
                    'Reason': 'string'
                },
                'Type': 'application',
                'AvailabilityZones': [
                    {
                        'ZoneName': 'string',
                        'SubnetId': 'string'
                    },
                ],
                'SecurityGroups': [
                    'string',
                ],
                'IpAddressType': 'ipv4'|'dualstack'
            },
        ]
    }

    :returns:
    (string) --

    """
    pass


def _getBitsForLength(length):
    """
    Return the number of bits required to obtain a random digit
    of a given length.
    """
    SLOPE = 0.3010142116935483
    OFFSET = 0.0701126088709696
    return int((length - OFFSET) / SLOPE)


@classmethod
def build_scheduler(cls, config):
    """ Create a scheduler of the expected type, using configuration to
        parameterize it.

        Parameters
        ----------
        config: Configuration
            configuration object instance
        """
    raise Exception('Scheduler is an abstract class!')


@classmethod
def si_unit_names(cls):
    """
        Returns an iterator over the predefined unit names.
        """
    return cls._si_units.keys()


def parse_zgp(response):
    """Parse the json response for a ZGPSWITCH Hue Tap."""
    TAP_BUTTONS = {(34): '1_click', (16): '2_click', (17): '3_click', (18):
        '4_click'}
    press = response['state']['buttonevent']
    if press is None:
        button = 'No data'
    else:
        button = TAP_BUTTONS[press]
    data = {'model': 'ZGP', 'name': response['name'], 'state': button,
        'last_updated': response['state']['lastupdated'].split('T')}
    return data


@classmethod
def darker_grey(cls):
    """A factory method that returns a :class:`Colour` with a value of ``0x546e7a``."""
    return cls(5533306)


def same_residue(at1, at2):
    """
    Checks whether atoms belong to the same residue
    """
    return at1.get_parent() == at2.get_parent()


def SAMflags(x):
    """
    Explains a SAM flag.

    :param x: flag

    :returns: complete SAM flag explanaition
    """
    flags = []
    if x & 1:
        l = '1: Read paired'
    else:
        l = '0: Read unpaired'
    flags.append(l)
    if x & 2:
        l = '1: Read mapped in proper pair'
    else:
        l = '0: Read not mapped in proper pair'
    flags.append(l)
    if x & 4:
        l = '1: Read unmapped'
    else:
        l = '0: Read mapped'
    flags.append(l)
    if x & 8:
        l = '1: Mate unmapped'
    else:
        l = '0: Mate mapped'
    flags.append(l)
    if x & 16:
        l = '1: Read reverse strand'
    else:
        l = '0: Read direct strand'
    flags.append(l)
    if x & 32:
        l = '1: Mate reverse strand'
    else:
        l = '0: Mate direct strand'
    flags.append(l)
    if x & 64:
        l = '1: First in pair'
    else:
        l = '0: Second in pair'
    flags.append(l)
    if x & 128:
        l = '1: Second in pair'
    else:
        l = '0: First in pair'
    flags.append(l)
    if x & 256:
        l = '1: Not primary alignment'
    else:
        l = '0: Primary alignment'
    flags.append(l)
    if x & 512:
        l = '1: Read fails platform/vendor quality checks'
    else:
        l = '0: Read passes platform/vendor quality checks'
    flags.append(l)
    if x & 1024:
        l = '1: Read is PCR or optical duplicate'
    else:
        l = '0: Read is not PCR or optical duplicate'
    flags.append(l)
    if x & 2048:
        l = '1: Supplementary alignment'
    else:
        l = '0: Not supplementary alignment'
    flags.append(l)
    return flags


@classmethod
def factory(cls, response):
    """
        Factory event from response.

        :returns: SpeakerPlayerShuffleChangedEvent instance or None if response is unsupported
        """
    if response.name != 'ShuffleMode':
        return None
    return cls(response.data['shuffle'] == 'on')


def x_in_y(x, y):
    """Check to see if the second argument is named in the first
    argument's unit placement spec.

    Both arguments provided are services with unit placement directives.
    If the first service appears in the second service's unit placement,
    either colocated on a default unit, colocated with a specific unit,
    or containerized alongside that service, then True is returned, False
    otherwise.
    """
    for placement in y.unit_placement:
        if ':' in placement:
            _, placement = placement.split(':')
        if '/' in placement:
            placement, _ = placement.split('/')
        if x.name == placement:
            return True
    return False


def _days_before_year(year):
    """year -> number of days before January 1st of year."""
    y = year - 1
    return y * 365 + y // 4 - y // 100 + y // 400


def schema_input_type(schema):
    """Input type from schema

    :param schema:
    :return: simple/list
    """
    if isinstance(schema, list):
        return 'list'
    return 'simple'


def unlock():
    """Unlock strips so they can be transformed

    """
    pass


def parse_bed(fn):
    """(internal) Parses a BED6+ file.
    """
    regions = []
    with open(fn) as fh:
        for line in fh:
            fields = line.strip().split('\t')
            fields[1:3] = map(int, fields[1:3])
            bed6 = fields[:6]
            if fields[1] < 0:
                continue
            regions.append(bed6)
    return regions


def get_pg_tc(links_table_name, links_table_input_field,
    links_table_output_field, closure_table_name,
    closure_table_parent_field, closure_table_child_field):
    """
    Return the transitive closure table template
    """
    from string import Template
    pg_tc = Template(
        """

DROP TRIGGER IF EXISTS autoupdate_tc ON $links_table_name;
DROP FUNCTION IF EXISTS update_tc();

CREATE OR REPLACE FUNCTION update_tc()
  RETURNS trigger AS
$$BODY$$
DECLARE

    new_id INTEGER;
    old_id INTEGER;
    num_rows INTEGER;

BEGIN

  IF tg_op = 'INSERT' THEN

    IF EXISTS (
      SELECT Id FROM $closure_table_name
      WHERE $closure_table_parent_field = new.$links_table_input_field
         AND $closure_table_child_field = new.$links_table_output_field
         AND depth = 0
         )
    THEN
      RETURN null;
    END IF;

    IF new.$links_table_input_field = new.$links_table_output_field
    OR EXISTS (
      SELECT id FROM $closure_table_name
        WHERE $closure_table_parent_field = new.$links_table_output_field
        AND $closure_table_child_field = new.$links_table_input_field
        )
    THEN
      RETURN null;
    END IF;

    INSERT INTO $closure_table_name (
         $closure_table_parent_field,
         $closure_table_child_field,
         depth)
      VALUES (
         new.$links_table_input_field,
         new.$links_table_output_field,
         0);

    new_id := lastval();

    UPDATE $closure_table_name
      SET entry_edge_id = new_id
        , exit_edge_id = new_id
        , direct_edge_id = new_id
      WHERE id = new_id;

    INSERT INTO $closure_table_name (
      entry_edge_id,
      direct_edge_id,
      exit_edge_id,
      $closure_table_parent_field,
      $closure_table_child_field,
      depth)
      SELECT id
         , new_id
         , new_id
         , $closure_table_parent_field
         , new.$links_table_output_field
         , depth + 1
        FROM $closure_table_name
        WHERE $closure_table_child_field = new.$links_table_input_field;

    INSERT INTO $closure_table_name (
      entry_edge_id,
      direct_edge_id,
      exit_edge_id,
      $closure_table_parent_field,
      $closure_table_child_field,
      depth)
      SELECT new_id
        , new_id
        , id
        , new.$links_table_input_field
        , $closure_table_child_field
        , depth + 1
        FROM $closure_table_name
        WHERE $closure_table_parent_field = new.$links_table_output_field;

    INSERT INTO $closure_table_name (
      entry_edge_id,
      direct_edge_id,
      exit_edge_id,
      $closure_table_parent_field,
      $closure_table_child_field,
      depth)
      SELECT A.id
        , new_id
        , B.id
        , A.$closure_table_parent_field
        , B.$closure_table_child_field
        , A.depth + B.depth + 2
     FROM $closure_table_name A
        CROSS JOIN $closure_table_name B
     WHERE A.$closure_table_child_field = new.$links_table_input_field
       AND B.$closure_table_parent_field = new.$links_table_output_field;

  END IF;

  IF tg_op = 'DELETE' THEN

    IF NOT EXISTS(
        SELECT id FROM $closure_table_name
        WHERE $closure_table_parent_field = old.$links_table_input_field
        AND $closure_table_child_field = old.$links_table_output_field AND
        depth = 0 )
    THEN
        RETURN NULL;
    END IF;

    CREATE TABLE PurgeList (Id int);

    INSERT INTO PurgeList
      SELECT id FROM $closure_table_name
          WHERE $closure_table_parent_field = old.$links_table_input_field
        AND $closure_table_child_field = old.$links_table_output_field AND
        depth = 0;

    WHILE (1 = 1)
    loop

      INSERT INTO PurgeList
        SELECT id FROM $closure_table_name
          WHERE depth > 0
          AND ( entry_edge_id IN ( SELECT Id FROM PurgeList )
          OR direct_edge_id IN ( SELECT Id FROM PurgeList )
          OR exit_edge_id IN ( SELECT Id FROM PurgeList ) )
          AND Id NOT IN (SELECT Id FROM PurgeList );

      GET DIAGNOSTICS num_rows = ROW_COUNT;
      if (num_rows = 0) THEN
        EXIT;
      END IF;
    end loop;

    DELETE FROM $closure_table_name WHERE Id IN ( SELECT Id FROM PurgeList);
    DROP TABLE PurgeList;

  END IF;

  RETURN NULL;

END
$$BODY$$
  LANGUAGE plpgsql VOLATILE
  COST 100;

CREATE TRIGGER autoupdate_tc
  AFTER INSERT OR DELETE OR UPDATE
  ON $links_table_name FOR each ROW
  EXECUTE PROCEDURE update_tc();

"""
        )
    return pg_tc.substitute(links_table_name=links_table_name,
        links_table_input_field=links_table_input_field,
        links_table_output_field=links_table_output_field,
        closure_table_name=closure_table_name, closure_table_parent_field=
        closure_table_parent_field, closure_table_child_field=
        closure_table_child_field)


def shape_key_insert():
    """Insert mask shape keyframe for active mask layer at the current frame

    """
    pass


@classmethod
def _get_binary_operator(cls, op, inv=False):
    """ Must return a method used by binary operator """
    raise NotImplementedError


def provide_handler(handler, adapts=None):
    """Register a handler

        Handlers are subscription adapter factories that don't produce
        anything.  They do all of their work when called.  Handlers
        are typically used to handle events.

        If the handler has an adapts declaration, then the adapts
        argument can be omitted and the declaration will be used.  (An
        adapts argument can be provided to override the declaration.)

        CAUTION: This API should only be used from test or
        application-setup code. This API shouldn't be used by regular
        library modules, as component registration is a configuration
        activity.
        """


def check_generator_arguments(y=None, sample_weight=None, validation_split=None
    ):
    """Validates arguments passed when using a generator."""
    if y is not None:
        raise ValueError(
            '`y` argument is not supported when data isa generator or Sequence instance. Instead pass targets as the second element of the generator.'
            )
    if sample_weight is not None:
        raise ValueError(
            '`sample_weight` argument is not supported when data isa generator or Sequence instance. Instead pass sample weights as the third element of the generator.'
            )
    if validation_split:
        raise ValueError(
            'If your data is in the form of a Python generator, you cannot use `validation_split`.'
            )


def proportional_change_gdp(calc1, calc2, elasticity=0.0):
    """
    This function harnesses econometric estimates of the historic relationship
    between tax policy and the macroeconomy to predict the effect of tax
    reforms on growth.

    In particular, this model relies on estimates of how GDP responds to
    changes in the average after tax rate on wage income across all taxpayers
    (one minus the average marginal tax rate, or 1-AMTR). These estimates are
    derived from calculations of income-weighted marginal tax rates under the
    baseline and reform.

    Evidence for this parameter can be found in Barro and Redlick's
    "Macroeconomic Effects from Government Purchases and Taxes." In particular,
    Barro and Redlick find that from a 1 percentage point increase in the AMTR
    leads to a 0.54 percent increase in GDP. Evaluated at the sample mean,
    this translates to an elasticity of GDP with respect to the average after
    tax rate of 0.36.

    Karel Mertens' "Marginal Tax Rates and Income: New Time Series Evidence"
    contains additional evidence, focussed on tax cuts affecting the upper part
    of the income distribution.

    Both Mertens and Karel tentatively conclude that the effect stems from
    marginal rather than average tax rates.

    Parameters
    ----------
    calc1 : Calculator object for the pre-reform baseline
    calc2 : Calculator object for the policy reform
    elasticity: Float estimate of elasticity of GDP wrt 1-AMTR

    Returns
    -------
    Float estimate of proportional GDP impact of the reform.
    """
    _, _, mtr_combined1 = calc1.mtr()
    _, _, mtr_combined2 = calc2.mtr()
    avg_one_mtr1 = 1.0 - (mtr_combined1 * calc1.records.c00100 * calc1.
        records.s006).sum() / (calc1.records.c00100 * calc1.records.s006).sum()
    avg_one_mtr2 = 1.0 - (mtr_combined2 * calc2.records.c00100 * calc2.
        records.s006).sum() / (calc2.records.c00100 * calc2.records.s006).sum()
    diff_avg_one_mtr = avg_one_mtr2 - avg_one_mtr1
    proportional_diff_mtr = diff_avg_one_mtr / avg_one_mtr1
    gdp_effect_of_reform = proportional_diff_mtr * elasticity
    print('{:.5f}'.format(gdp_effect_of_reform))
    return gdp_effect_of_reform


def plus_or_dot(pieces):
    """Return a + if we don't already have one, else return a ."""
    if '+' in pieces.get('closest-tag', ''):
        return '.'
    return '+'


def has_ttfa_table(tt):
    """Tests for the presence of a TTFA table in a TrueType font."""
    return 'TTFA' in tt


def created():
    """ Return the DateTime form of CreationDate.

        o Permission:  View
        """


def get_option(option):
    """ get_option returns the type of option (if any) applied
    to that year's salary

    @param **option** (*str*): Sting of color indicators that
        correspond to yearly options.

    Returns:

        **option** (*list*): One of '', 'Team',
        'Qualifying', 'Two-Way', 'Player'
    """
    if option == 'color:black':
        option = ''
    elif option == 'color:rgb(255, 0, 0)':
        option = 'Team'
    elif option == 'color:rgb(0, 153, 0)':
        option = 'Qualifying'
    elif option == 'color:rgb(168, 0, 212)':
        option = 'Two-Way'
    elif option == 'color:rgb(4, 134, 176)':
        option = 'Player'
    else:
        option = ''
    return option


def get_input_op_table_args(ipa):
    """Creates an input operator from an Input Pipeline Analyzer proto.

  Args:
    ipa: An input_pipeline_pb2.InputPipelineAnalysisResult.

  Returns:
    Returns a gviz_api.DataTable
  """
    table_description = [('opName', 'string', 'Input Op'), ('count',
        'number', 'Count'), ('timeInMs', 'number', 'Total Time (in ms)'), (
        'timeInPercent', 'number',
        'Total Time (as % of total input-processing time)'), (
        'selfTimeInMs', 'number', 'Total Self Time (in ms)'), (
        'selfTimeInPercent', 'number',
        'Total Self Time (as % of total input-processing time)'), (
        'category', 'string', 'Category')]
    data = []
    for details in ipa.input_op_details:
        row = [details.op_name, details.count, details.time_in_ms, details.
            time_in_percent / 100.0, details.self_time_in_ms, details.
            self_time_in_percent / 100.0, details.category]
        data.append(row)
    enqueue_us = '{:.3f}'.format(ipa.input_time_breakdown.enqueue_us)
    demanded_file_read_us = '{:.3f}'.format(ipa.input_time_breakdown.
        demanded_file_read_us)
    advanced_file_read_us = '{:.3f}'.format(ipa.input_time_breakdown.
        advanced_file_read_us)
    preprocessing_us = '{:.3f}'.format(ipa.input_time_breakdown.
        preprocessing_us)
    unclassified_non_enqueue_us = '{:.3f}'.format(ipa.input_time_breakdown.
        unclassified_non_enqueue_us)
    custom_properties = {'enqueue_us': enqueue_us, 'demanded_file_read_us':
        demanded_file_read_us, 'advanced_file_read_us':
        advanced_file_read_us, 'preprocessing_us': preprocessing_us,
        'unclassified_nonequeue_us': unclassified_non_enqueue_us}
    return table_description, data, custom_properties


def reset_tar_mtime(tarinfo):
    """Reset the mtime on the the tarball for reproducibility.

    :param tarinfo: the tarball var
    :returns: tarinfo: the modified tar ball
    """
    tarinfo.mtime = 0
    return tarinfo


def freestyle_lineset_add():
    """Add a line set into the list of line sets

    """
    pass


def clean_multiple_whitespaces(uncleaned_string):
    """Clean a string from multiple consecutive white spaces."""
    return ' '.join(uncleaned_string.split())


def render_pep440_old(pieces):
    """TAG[.postDISTANCE[.dev0]] .

    The ".dev0" means dirty.

    Eexceptions:
    1: no tags. 0.postDISTANCE[.dev0]
    """
    if pieces['closest-tag']:
        rendered = pieces['closest-tag']
        if pieces['distance'] or pieces['dirty']:
            rendered += '.post%d' % pieces['distance']
            if pieces['dirty']:
                rendered += '.dev0'
    else:
        rendered = '0.post%d' % pieces['distance']
        if pieces['dirty']:
            rendered += '.dev0'
    return rendered


def associate_hosted_connection(connectionId=None, parentConnectionId=None):
    """
    Associates a hosted connection and its virtual interfaces with a link aggregation group (LAG) or interconnect. If the target interconnect or LAG has an existing hosted connection with a conflicting VLAN number or IP address, the operation fails. This action temporarily interrupts the hosted connection's connectivity to AWS as it is being migrated.
    See also: AWS API Documentation

    :example: response = client.associate_hosted_connection(
        connectionId='string',
        parentConnectionId='string'
    )

    :type connectionId: string
    :param connectionId: [REQUIRED]
            The ID of the hosted connection.
            Example: dxcon-abc123
            Default: None

    :type parentConnectionId: string
    :param parentConnectionId: [REQUIRED]
            The ID of the interconnect or the LAG.
            Example: dxcon-abc123 or dxlag-abc123
            Default: None

    :rtype: dict
    :return: {
        'ownerAccount': 'string',
        'connectionId': 'string',
        'connectionName': 'string',
        'connectionState': 'ordering'|'requested'|'pending'|'available'|'down'|'deleting'|'deleted'|'rejected',
        'region': 'string',
        'location': 'string',
        'bandwidth': 'string',
        'vlan': 123,
        'partnerName': 'string',
        'loaIssueTime': datetime(2015, 1, 1),
        'lagId': 'string',
        'awsDevice': 'string'
    }

    :returns:
    Ordering : The initial state of a hosted connection provisioned on an interconnect. The connection stays in the ordering state until the owner of the hosted connection confirms or declines the connection order.
    Requested : The initial state of a standard connection. The connection stays in the requested state until the Letter of Authorization (LOA) is sent to the customer.
    Pending : The connection has been approved, and is being initialized.
    Available : The network link is up, and the connection is ready for use.
    Down : The network link is down.
    Deleting : The connection is in the process of being deleted.
    Deleted : The connection has been deleted.
    Rejected : A hosted connection in the 'Ordering' state will enter the 'Rejected' state if it is deleted by the end customer.

    """
    pass


def monitored(fn):
    """Provides monitoring capabilities for task methods."""
    return fn


@classmethod
def paper_folder_change_subscription(cls, val):
    """
        Create an instance of this class set to the
        ``paper_folder_change_subscription`` tag with value ``val``.

        :param PaperFolderChangeSubscriptionType val:
        :rtype: EventType
        """
    return cls('paper_folder_change_subscription', val)


def remove(mail_host):
    """Remove the domain.

        :param mail_host: The email host name of the domain to remove.
        :type mail_host: string
        :raises KeyError: if the named domain does not exist.
        """


def normalise_number(v):
    """Attempt to convert a value to a number.
    Will convert to int type if it has no decimal places.
    @param v: the value (string, int, float, etc) to convert.
    @returns: an int or float value
    @exception ValueError: if the value cannot be converted
    @see: L{is_number}
    """
    try:
        n = float(v)
        if n == int(n):
            return int(n)
        else:
            return n
    except:
        raise ValueError('Cannot convert to number: {}'.format(v))


def __iter__():
    """Return an interator in the widgets, in order
        """


@classmethod
def get_icon(klass):
    """
        Default getter function - returns the `icon` proprety
        """
    return klass.icon


@classmethod
def from_dict(cls, d: dict) ->'Response':
    """Recreate the response from a received :py:class:`dict`."""
    del d['type']
    return cls(**d)


def delete_lines(corpus, annotation, dry_run=True, colour={}):
    """
    Show or delete the necessary lines
    """
    from corpkit.constants import OPENER, PYTHON_VERSION
    import re
    import os
    tagmode = True
    no_can_do = ['sent_id', 'parse']
    if isinstance(annotation, dict):
        tagmode = False
        for k, v in annotation.items():
            if k in no_can_do:
                print("You aren't allowed to delete '%s', sorry." % k)
                return
            if not v:
                v = '.*?'
            regex = re.compile('(# %s=%s)\\n' % (k, v), re.MULTILINE)
    else:
        if annotation in no_can_do:
            print("You aren't allowed to delete '%s', sorry." % k)
            return
        regex = re.compile('((# tags=.*?)%s;?(.*?))\\n' % annotation, re.
            MULTILINE)
    fs = []
    for root, dirs, fls in os.walk(corpus):
        for f in fls:
            fs.append(os.path.join(root, f))
    for f in fs:
        if PYTHON_VERSION == 2:
            from corpkit.process import saferead
            data = saferead(f)[0]
        else:
            with open(f, 'rb') as fo:
                data = fo.read().decode('utf-8', errors='ignore')
        if dry_run:
            if tagmode:
                repl_str = '\\1 <=======\\n%s\\2\\3 <=======\\n' % colour.get(
                    'green', '')
            else:
                repl_str = '\\1 <=======\\n'
            try:
                repl_str = colour['red'] + repl_str + colour['reset']
            except:
                pass
            data, n = re.subn(regex, repl_str, data)
            nspl = 100 if tagmode else 50
            delim = '<======='
            data = re.split(delim, data, maxsplit=nspl)
            toshow = delim.join(data[:nspl + 1])
            toshow = toshow.rsplit('\n\n', 1)[0]
            print(toshow)
            if n > 50:
                n = n - 50
                print('\n... and %d more changes ... ' % n)
        else:
            if tagmode:
                repl_str = '\\2\\3\\n'
            else:
                repl_str = ''
            data = re.sub(regex, repl_str, data)
            with OPENER(f, 'w') as fo:
                from corpkit.constants import PYTHON_VERSION
                if PYTHON_VERSION == 2:
                    data = data.encode('utf-8', errors='ignore')
                fo.write(data)


def is_array(obj):
    """Return True if object implements necessary attributes to be
    considered similar to a numpy array.

    Attributes needed are "shape", "dtype", "__getitem__"
    and "__array__".

    :param obj: Array-like object (numpy array, h5py dataset...)
    :return: boolean
    """
    for attr in ('shape', 'dtype', '__array__', '__getitem__'):
        if not hasattr(obj, attr):
            return False
    return True


@staticmethod
def _uri_parse_error(reason):
    """uri parsing helper -- creates preformatted error message"""
    return ValueError('Invalid otpauth uri: %s' % (reason,))


def classification_tex(f, weblog, threshold_requests_per_session,
    classification_wanted_transaction, weblog_columns_dict):
    """
    Write on latex file information variables on classification

    Parameters
    ----------
        f: file

        weblog: pandas dataframe of requests

        threshold_requests_per_session: int for filter number of requests per session

        classification_wanted_transaction: list of items wanted to analyse corresponding to the ones given in
                    classification_diversity

        weblog_columns_dict: dict recupered with function of 'file_function'

    Returns
    -------
        File (Optionnal)
    """
    classification_wanted_transaction = list(set(
        classification_wanted_transaction) - {'social', 'search', 'other'})
    requests_per_session = weblog.groupby('session_id').size()
    sessions_requests_over_threshold = list(requests_per_session[
        requests_per_session > threshold_requests_per_session].index)
    divpat_log = weblog[weblog.session_id.isin(
        sessions_requests_over_threshold)]
    num_reqs_inside = divpat_log.shape[0]
    divpat_log = divpat_log[~divpat_log.requested_category.isin(['social',
        'search', 'other'])]
    divpat_log = divpat_log[~divpat_log.referrer_category.isin(['social',
        'search', 'other'])]
    num_reqs_selected_cats = divpat_log.shape[0]
    f.write('\n% 5. Diversifying patterns according to classification')
    f.write('\n\\newcommand{\\%s}{%.1f}' % ('PCDivPatTotalSelectedCat',
        100.0 * num_reqs_selected_cats / num_reqs_inside))
    f.write('\n\\newcommand{\\%s}{%d}' % ('DivPatTotalNumberRequests',
        divpat_log.shape[0]))
    f.write('\n\\newcommand{\\%s}{%d}' % ('DivPatTotalNumberUsers', len(
        divpat_log.userID.unique())))
    f.write('\n\\newcommand{\\%s}{%d}' % ('DivPatTotalNumberSessions', len(
        divpat_log.session_id.unique())))
    f.write('\n\\newcommand{\\%s}{%d}' % ('DivPatTotalNumberPages', len(
        list(set(divpat_log[weblog_columns_dict['requested_page_column']].
        unique()) | set(divpat_log[weblog_columns_dict[
        'referrer_page_column']].unique())))))
    return f


@classmethod
def initialize(cls, locales: 'typing.Dict[str, str]', initial_lang: str):
    """Initialize LocaleBorg.

        locales: dict with custom locale name overrides.
        """
    if not initial_lang:
        raise ValueError('Unknown initial language {0}'.format(initial_lang))
    cls.reset()
    cls.locales = locales
    cls.__initial_lang = initial_lang
    cls.initialized = True


@classmethod
def _stop_running_process(cls):
    """stop self generated DS9 windows when user quits python window."""
    while cls._process_list:
        process = cls._process_list.pop()
        if process.poll() is None:
            process.terminate()


def update():
    """Override this method in subclasses if required"""


def get_table_rows(page):
    """
    return a list of relevant <tr> bs4 Tags

    page: a BeautifulSoup with a <table> with interesting rows
    """
    return page.find_all('tr')[2:]


@classmethod
def open_from_path(cls, path: str) ->'VdirStore':
    """Open a VdirStore from a path.

        :param path: Path
        :return: A `VdirStore`
        """
    return cls(path)


def summarize_evaluation(metrics, model=None):
    """
    Summary of model evaluation metrics from Keras "evaluate" method;
    the evaluation is typically performed for test dataset.
    Metrics include: loss and accuracy

    # Arguments
        metrics: metrics return by the Keras evaluate() method
        model: the model evaluated;
            if provided the attribute "metrics_names" will be used to
            obtain the metric names

    # Returns
        None

    # Raise
        None
    """
    print('\nSummary - Model Evaluation:')
    print('-' * 30)
    if model:
        no_metrics = len(model.metrics_names)
        for i in range(no_metrics):
            print('  {} = {:.3f}'.format(model.metrics_names[i], metrics[i]))
    else:
        loss = metrics[0]
        acc = metrics[1] * 100
        print('  (Loss, Accuracy) = ({:.3f}, {:.3f}%)'.format(loss, acc))


@classmethod
def close_registry_entry(cls, value):
    """Close a registry entry."""
    out = False
    if not value.closed:
        value.close(linger=0)
        out = True
    return out


@classmethod
def run(cls, gen_fpath, rev_summary, reg_cols, gid_col='gen_gids', cf_dset=
    'cf_profile', rep_method='meanoid', err_method='rmse', weight=
    'gid_counts', n_profiles=1, fout=None, save_rev_summary=True,
    scaled_precision=False, max_workers=None):
    """Run representative profiles by finding the closest single profile
        to the weighted meanoid for each SC region.

        Parameters
        ----------
        gen_fpath : str
            Filepath to reV gen output file to extract "cf_profile" from.
        rev_summary : str | pd.DataFrame
            Aggregated rev supply curve summary file. Str filepath or full df.
        reg_cols : str | list | None
            Label(s) for a categorical region column(s) to extract profiles
            for. e.g. "state" will extract a rep profile for each unique entry
            in the "state" column in rev_summary.
        gid_col : str
            Column label in rev_summary that contains the generation gids
            (data index in gen_fpath).
        cf_dset : str
            Dataset name to pull generation profiles from.
        rep_method : str
            Method identifier for calculation of the representative profile.
        err_method : str
            Method identifier for calculation of error from the representative
            profile.
        weight : str | None
            Column in rev_summary used to apply weighted mean to profiles.
            The supply curve table data in the weight column should have
            weight values corresponding to the gid_col in the same row.
        n_profiles : int
            Number of representative profiles to save to fout.
        fout : str, optional
            filepath to output h5 file, by default None
        save_rev_summary : bool, optional
            Flag to save full reV SC table to rep profile output.,
            by default True
        scaled_precision : bool, optional
            Flag to scale cf_profiles by 1000 and save as uint16.,
            by default False
        max_workers : int, optional
            Number of parallel workers. 1 will run serial, None will use all
            available., by default None

        Returns
        -------
        profiles : dict
            dict of n_profile-keyed arrays with shape (time, n) for the
            representative profiles for each region.
        meta : pd.DataFrame
            Meta dataframes recording the regions and the selected rep profile
            gid.
        time_index : pd.DatatimeIndex
            Datetime Index for represntative profiles
        """
    rp = cls(gen_fpath, rev_summary, reg_cols, gid_col=gid_col, cf_dset=
        cf_dset, rep_method=rep_method, err_method=err_method, n_profiles=
        n_profiles, weight=weight)
    rp._run(fout=fout, save_rev_summary=save_rev_summary, scaled_precision=
        scaled_precision, max_workers=max_workers)
    return rp._profiles, rp._meta, rp._time_index


def ebs(dic, data):
    """
    EBS Reconstruction
    """
    raise NotImplementedError


def delete():
    """Remove constraint from constraint stack

    """
    pass


@classmethod
def non_trusted_team_details(cls, val):
    """
        Create an instance of this class set to the ``non_trusted_team_details``
        tag with value ``val``.

        :param NonTrustedTeamDetails val:
        :rtype: FederationStatusChangeAdditionalInfo
        """
    return cls('non_trusted_team_details', val)


def enumerate_edges(graph):
    """Return the ordered list of edges of `graph`

    Parameters
    ----------
    graph : input graph
    """
    if hasattr(graph, 'ordered_edges'):
        assert set(graph.edges()) == set(graph.ordered_edges)
        return graph.ordered_edges
    else:
        setattr(graph, 'ordered_edges', sorted(graph.edges()))
        return graph.ordered_edges


def translate_month(key):
    """The month value can take weird forms. Sometimes, it's given as an int, sometimes
    as a string representing an int, and sometimes the name of the month is spelled out.
    Try to handle most of this here.
    """
    months = ['jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', 'aug', 'sep',
        'oct', 'nov', 'dec']
    try:
        return months[int(key) - 1]
    except (TypeError, ValueError):
        pass
    strings = []
    for k in key.split('-'):
        month = k[:3].lower()
        if month in months:
            strings.append(month)
        else:
            print("Unknown month value '{}'. Skipping.".format(key))
            return None
    return ' # "-" # '.join(strings)


def first_element_or_none(element_list):
    """
    Return the first element or None from an lxml selector result.
    :param element_list: lxml selector result
    :return:
    """
    if element_list:
        return element_list[0]
    return


@classmethod
def from_path(cls, path):
    """Load a yolo.yaml file given a path to the file."""
    with open(path) as fp:
        return cls.from_file(fp)


def render_pep440_old(pieces):
    """TAG[.postDISTANCE[.dev0]] .

    The ".dev0" means dirty.

    Eexceptions:
    1: no tags. 0.postDISTANCE[.dev0]
    """
    if pieces['closest-tag']:
        rendered = pieces['closest-tag']
        if pieces['distance'] or pieces['dirty']:
            rendered += '.post%d' % pieces['distance']
            if pieces['dirty']:
                rendered += '.dev0'
    else:
        rendered = '0.post%d' % pieces['distance']
        if pieces['dirty']:
            rendered += '.dev0'
    return rendered


@classmethod
def get_field_types(cls):
    """
        Returns the names of the subclasses of Field.

        Returns
        -------
        List
            The names of available field types.
        """
    return cls.__subclasses__()


def get_dx(x1, x2, y1, y2, L=1.0, periodic=True):
    """
    Compute difference of vectors [x1 - x2, y1 - y2] while
    checking for periodicity if necessary
    L:          boxsize
    periodic:   whether to assume periodic boundaries
    """
    dx = x1 - x2
    dy = y1 - y2
    if periodic:
        if hasattr(L, '__len__'):
            Lxhalf = L[0] / 2.0
            Lyhalf = L[1] / 2.0
        else:
            Lxhalf = L / 2.0
            Lyhalf = L / 2.0
            L = [L, L]
        if dx > Lxhalf:
            dx -= L[0]
        elif dx < -Lxhalf:
            dx += L[0]
        if dy > Lyhalf:
            dy -= L[1]
        elif dy < -Lyhalf:
            dy += L[1]
    return dx, dy


def check_infos(data, infos, required_infos=None):
    """Implement infos verification logic."""
    if required_infos is False or required_infos is None:
        return data
    if required_infos is True:
        return data, infos
    if not isinstance(required_infos, (tuple, list)):
        raise ValueError('required_infos must be tuple or list')
    for required, actual in zip(required_infos, infos):
        raise ValueError(
            f"actual info {actual} doesn't match required info {required}")
    return data


@classmethod
def merge(cls, trees):
    """
        Merge a collection of AttrTree objects.
        """
    first = trees[0]
    for tree in trees:
        first.update(tree)
    return first


@classmethod
def has_archiving(cls):
    """Returns whether it supports archiving items on the fetch process.

        :returns: this backend does not support items archive
        """
    return False


def daily_std_dev(merged_data):
    """Calculates daily seasonal standard deviation of the timeseries data in a DataFrame

    Parameters
    ----------

    merged_data: DataFrame
        A pandas DataFrame with a datetime index and columns containing float type values.

    Returns
    -------
    DataFrame
        A pandas dataframe with a string type index of date representations and the daily seasonal standard deviation as
        float values in the columns.

    Examples
    --------

    >>> import hydrostats.data as hd
    >>> import pandas as pd
    >>> pd.options.display.max_rows = 15

    The data URLs contain streamflow data from two different models, and are provided from the Hydrostats Github page

    >>> sfpt_url = r'https://github.com/waderoberts123/Hydrostats/raw/master/Sample_data/sfpt_data/magdalena-calamar_interim_data.csv'
    >>> glofas_url = r'https://github.com/waderoberts123/Hydrostats/raw/master/Sample_data/GLOFAS_Data/magdalena-calamar_ECMWF_data.csv'
    >>> merged_df = hd.merge_data(sfpt_url, glofas_url, column_names=('Streamflow Prediction Tool', 'GLOFAS'))

    >>> hd.daily_std_dev(merged_df)
           Streamflow Prediction Tool       GLOFAS
    01/01                 3349.139373  2969.748253
    01/02                 3273.308852  2617.851437
    01/03                 3165.117397  2556.319898
    01/04                 3043.888685  2501.999235
    01/05                 2894.662206  2436.603046
    01/06                 2741.049485  2372.487729
    01/07                 2612.931931  2341.011275
                               ...          ...
    12/25                 3631.744428  3352.464257
    12/26                 3487.081980  3355.480036
    12/27                 3448.825041  3300.770870
    12/28                 3439.995086  3194.812751
    12/29                 3395.528078  3061.536706
    12/30                 3318.884936  2928.699478
    12/31                 3235.528520  2808.611992
    [366 rows x 2 columns]

    """
    a = merged_data.groupby(merged_data.index.strftime('%m/%d'))
    return a.std()


def postgresql_h():
    '\n    \r\n    PostgreSQL Help Menu\n\n    Usage:\n        sg-cli postgresql <command> [<args>...]\n\n    Options:\n        -v, --verbose  Increase verbosity\n        -h, --help     Show this menu\n        -V --version   Show version\n\n    Commands:\n        postgresql commands\n    '


def escape_pg_identifier(engine, name):
    """
    Escape identifiers (tables, fields, roles, etc) for inclusion in SQL statements.

    psycopg2 can safely merge query arguments, but cannot do the same for dynamically
    generating queries.

    See http://initd.org/psycopg/docs/sql.html for more information.
    """
    return engine.execute('select quote_ident(%s)', name).scalar()


def get_handler_name(message):
    """
    Looks at a message, checks it has a sensible type, and returns the
    handler name for that type.
    """
    if 'type' not in message:
        raise ValueError("Incoming message has no 'type' attribute")
    if message['type'].startswith('_'):
        raise ValueError('Malformed type in message (leading underscore)')
    return message['type'].replace('.', '_')


def separate():
    """Separate selected points from connected unselected points into a new object

    """
    pass


def mass_fmg(force, gravitational_field_strength):
    """Usage: Find mass using force of gravity and a gravitational constant """
    return force / gravitational_field_strength


def float_(value):
    """
    Returns float of a value, or None
    """
    if value:
        return float(value)
    else:
        return None


def render_pep440_pre(pieces):
    """TAG[.post.devDISTANCE] -- No -dirty.

    Exceptions:
    1: no tags. 0.post.devDISTANCE
    """
    if pieces['closest-tag']:
        rendered = pieces['closest-tag']
        if pieces['distance']:
            rendered += '.post.dev%d' % pieces['distance']
    else:
        rendered = '0.post.dev%d' % pieces['distance']
    return rendered


def two_sided_f(count1, count2, sum1, sum2):
    """computes an F score like measure"""
    if not (sum1 and sum2):
        print('got empty sums for F scores')
        return 0
    if sum1 < count1 or sum2 < count2:
        print('got empty sums for F scores')
        return 0
    precision = count2 / sum2
    recall = count1 / sum1
    if precision + recall == 0:
        return 0
    return 2 * (precision * recall) / (precision + recall)


def unsafe(f):
    """Marks a function or method as unsafe.

    ::

        @unsafe
        def delete(self):
            pass
    """
    f.unsafe_callable = True
    return f


def xfrange(start, stop=None, step=1):
    """
	Iterate through an arithmetic progression.

	:param start: Starting number.
	:type start: float, int, long
	:param stop: Stopping number.
	:type stop: float, int, long
	:param step: Stepping size.
	:type step: float, int, long
	"""
    if stop is None:
        stop = start
        start = 0.0
    start = float(start)
    while start < stop:
        yield start
        start += step