def y_domain_spline(spline_function, x_domain_spline):
    """
    Calculate a y domain based on a function.

    Parameters
    ----------
    spline_function : function
        The spline function.
    x_domain_spline : ndarray
        The (n, 1)-shaped ndarray.

    Returns
    -------
    ndarray
        The spline_function(x_domain_spline) vector.
    """
    return spline_function(x_domain_spline)


def _checksubrepostate(pushop):
    """Ensure all outgoing referenced subrepo revisions are present locally"""
    for n in pushop.outgoing.missing:
        ctx = pushop.repo[n]
        if b'.hgsub' in ctx.manifest() and b'.hgsubstate' in ctx.files():
            for subpath in sorted(ctx.substate):
                sub = ctx.sub(subpath)
                sub.verify(onpush=True)


def assert_batch(enode, commands, replace=None, shell=None):
    """
    Execute a batch of return-less template commands in the enode shell.

    :param enode:
    :type: topology.platforms.node.BaseNode
    :param str commands: Multiline docstring template with the return-less
     commnads to execute and assert.
    :param dict replace: Namespace to replace tokens in commands.
    :param str shell: Shell name to execute the batch.
    """
    assert commands
    if replace is not None:
        assert isinstance(replace, dict)
        commands = commands.format(**replace)
    for cmd in commands.splitlines():
        cmd = cmd.strip()
        if not cmd:
            continue
        response = enode(cmd, shell=shell)
        assert not response


def nvlist_to_dict(nvlist):
    """Convert a CORBA namevalue list into a dictionary."""
    result = {}
    for item in nvlist:
        result[item.name] = item.value.value()
    return result


def whitespace_tokenize(text):
    """Runs basic whitespace cleaning and splitting on a piece of text."""
    text = text.strip()
    if not text:
        return []
    tokens = text.split()
    return tokens


def display(message):
    """Display a message to the screen.

    This is a stub implementation, to centralize all calls to ``print()``.
    """
    print(message)


@classmethod
def get_conversion_time(cls, conversion_time):
    """Gets the conversion time for the given constant

        :param conversion_time: constant to fetch time for
        :type conversion_time: int
        :return: conversion time
        :rtype: float
        """
    return cls.times[conversion_time]


@staticmethod
def __check_config(config):
    """Check whether the configuration information is valid.

        :param config: The configuration information, including 11 configuration fields.
        :return: None.
        """
    keys = ['capacity', 'dimension', 'sequence', 'nodes', 'connections',
        'depths', 'batch_size', 'epoch', 'middle_layer']
    for item in keys:
        if item not in config:
            raise Exception('Invalid configuration.')
    if 'evolution' not in config:
        config['evolution'] = 0
    if 'verbose' not in config:
        config['verbose'] = False


def get_model_dna(page_dna, thing_name, elio_role):
    """Find the details of a model of the current page/role in the SITE_DNA."""
    if not isinstance(page_dna, dict):
        return {}
    if thing_name in list(page_dna.get(elio_role, {})):
        if isinstance(page_dna[elio_role], dict):
            return page_dna[elio_role].get(thing_name, {})
    return {}


def provides(base):
    """Returns whether or not this extension can provide for the
        server."""
    version = base.basic_rfc.server_version[0]
    if version is None:
        return False
    elif version.startswith('ircd-ratbox'):
        return True
    return False


def _isnamedtuple(obj):
    """Named tuples are identified via duck typing:
       <http://www.gossamer-threads.com/lists/python/dev/1142178>
    """
    return isinstance(obj, tuple) and hasattr(obj, '_fields')


def action_sanitize():
    """Make action suitable for use as a Pose Library

    """
    pass


def getAddress(user):
    """Turn a User-name string into a valid email address. Either return
        a string (with an @ in it), None (to indicate that the user cannot
        be reached by email), or a Deferred which will fire with the same."""


@staticmethod
def make_search(search: str) ->str:
    """
        给定字典，返回fields 和 values
        :param info: dict
        :return:
        """
    field = list()
    if len(search):
        for kv in search.split(','):
            k, v = kv.split('=')
            field.append("`{}` like '%%{}%%' ".format(k, v))
    return ' and '.join(field)


def KK_RC17(w, Rs, R_values, t_values):
    """
    Kramers-Kronig Function: -RC-

    Kristian B. Knudsen (kknu@berkeley.edu / kristianbknudsen@gmail.com)
    """
    return Rs + R_values[0] / (1 + w * 1.0j * t_values[0]) + R_values[1] / (
        1 + w * 1.0j * t_values[1]) + R_values[2] / (1 + w * 1.0j * t_values[2]
        ) + R_values[3] / (1 + w * 1.0j * t_values[3]) + R_values[4] / (1 +
        w * 1.0j * t_values[4]) + R_values[5] / (1 + w * 1.0j * t_values[5]
        ) + R_values[6] / (1 + w * 1.0j * t_values[6]) + R_values[7] / (1 +
        w * 1.0j * t_values[7]) + R_values[8] / (1 + w * 1.0j * t_values[8]
        ) + R_values[9] / (1 + w * 1.0j * t_values[9]) + R_values[10] / (1 +
        w * 1.0j * t_values[10]) + R_values[11] / (1 + w * 1.0j * t_values[11]
        ) + R_values[12] / (1 + w * 1.0j * t_values[12]) + R_values[13] / (
        1 + w * 1.0j * t_values[13]) + R_values[14] / (1 + w * 1.0j *
        t_values[14]) + R_values[15] / (1 + w * 1.0j * t_values[15]
        ) + R_values[16] / (1 + w * 1.0j * t_values[16])


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

        :param EmmRemoveExceptionDetails val:
        :rtype: EventDetails
        """
    return cls('emm_remove_exception_details', val)


def parse_list(spec):
    """Convert a string specification like 00-04,07,09-12 into a list [0,1,2,3,4,7,9,10,11,12]

    Args:
        spec (str): string specification

    Returns:
        List[int]

    Example:
        >>> parse_list("00-04,07,09-12")
        [0, 1, 2, 3, 4, 7, 9, 10, 11, 12]
        >>> parse_list("05-04")
        Traceback (most recent call last):
            ...
        ValueError: In specification 05-04, end should not be smaller than begin
    """
    ret_list = []
    for spec_part in spec.split(','):
        if '-' in spec_part:
            begin, end = spec_part.split('-')
            if end < begin:
                raise ValueError(
                    'In specification %s, end should not be smaller than begin'
                     % spec_part)
            ret_list += range(int(begin), int(end) + 1)
        else:
            ret_list += [int(spec_part)]
    return ret_list


def _pad(s, l):
    """
    Pads *s* to length *l*.
    """
    missing = l - len(s)
    return s + ' ' * (missing if missing > 0 else 0)


def parse_vars(args):
    """
    Given variables like ``['a=b', 'c=d']`` turns it into ``{'a':
    'b', 'c': 'd'}``
    """
    result = {}
    for arg in args:
        if '=' not in arg:
            raise ValueError('Variable assignment %r invalid (no "=")' % arg)
        name, value = arg.split('=', 1)
        result[name] = value
    return result


def register_tstz_w_secs(oids=None, conn_or_curs=None):
    """The function used to register an alternate type caster for
    :sql:`TIMESTAMP WITH TIME ZONE` to deal with historical time zones with
    seconds in the UTC offset.

    These are now correctly handled by the default type caster, so currently
    the function doesn't do anything.
    """
    import warnings
    warnings.warn('deprecated', DeprecationWarning)


def isReadOnly():
    """Test whether a storage allows committing new transactions

        For a given storage instance, this method always returns the
        same value.  Read-only-ness is a static property of a storage.
        """


def metadata_isdir(name):
    """Is the named metadata a directory?  (like ``os.path.isdir()``)"""


def bC_Mg_OH_HMW84(T, P):
    """c-a: magnesium hydroxide [HMW84]."""
    b0 = 0.0
    b1 = 0.0
    b2 = 0.0
    C0 = 0
    C1 = 0
    alph1 = 2
    alph2 = -9
    omega = -9
    valid = T == 298.15
    return b0, b1, b2, C0, C1, alph1, alph2, omega, valid


def check_dates_in_range(activity_dates, start_date=None, end_date=None):
    """Check that an activity's dates fall into the allowed range.
    Prefers the planned date over the actual date when available.
    If the activity dates are missing, returns True
    @param activity_dates: the parsed activity dates.
    @param start_date: the start date in ISO 8601 format (YYYY-MM-DD), or None for no start limit.
    @param end_date: the end date in ISO 8601 format (YYYY-MM-DD), or None for no end limit.
    @returns: True if the activity is in range (or can't be determined).
    """
    if start_date:
        if 'end_actual' in activity_dates:
            if start_date is None or activity_dates['end_actual'
                ] <= start_date:
                return False
        elif 'end_planned' in activity_dates:
            if start_date is None or activity_dates['end_planned'
                ] <= start_date:
                return False
    if end_date:
        if 'start_actual' in activity_dates:
            if end_date is None or activity_dates['start_actual'] >= end_date:
                return False
        elif 'start_planned' in activity_dates:
            if end_date is None or activity_dates['start_planned'] >= end_date:
                return False
    return True


def get_header(instream, comment_char='#'):
    """Returns a header from the stream and an the reaminder of the stream
    with the actual data.

    Parameters
    ----------
    instream : a file object
        An input stream.

    comment_char : str
        The character prepended to header lines (use '@' when parsing sams,
        '#' when parsing pairsams).

    Returns
    -------
    header : list
        The header lines, stripped of terminal spaces and newline characters.

    remainder_stream : stream/file-like object
        Stream with the remaining lines.

    """
    header = []
    if not comment_char:
        raise ValueError('Please, provide a comment char!')
    comment_byte = comment_char.encode()
    inbuffer = instream.buffer
    current_peek = inbuffer.peek()
    while current_peek.startswith(comment_byte):
        line = inbuffer.readline()
        header.append(line.decode().strip())
        current_peek = inbuffer.peek()
    return header, instream


@classmethod
def fromdict(cls, mapping):
    """
        Create a new `udict` from the given `mapping` dict.
        The resulting `udict` will be equivalent to the input
        `mapping` dict but with all dict instances (recursively)
        converted to an `udict` instance.  If you don't want
        this behavior (i.e., you want sub-dicts to remain plain dicts),
        use `udict(mapping)` instead.
        """
    ud = cls()
    for k in mapping:
        v = dict.__getitem__(mapping, k)
        if isinstance(v, dict):
            v = cls.fromdict(v)
        dict.__setitem__(ud, k, v)
    return ud


def sweep(start, stop, step=1):
    """Generator function to be used in sweeps.
Advantages towards the range python built-in functions_
    - Supports floating point arguments
    - Supports both up and down sweeps
    - Less memory footprint for large sweeps"""
    inc = 0
    val = start
    if start < stop:
        while val <= stop:
            yield val
            inc += 1
            val = start + inc * step
    elif start > stop:
        while start >= stop:
            yield val
            inc += 1
            val = start + inc * step


def describe_placement_groups(DryRun=None, GroupNames=None, Filters=None):
    """
    Describes one or more of your placement groups. For more information about placement groups and cluster instances, see Cluster Instances in the Amazon Elastic Compute Cloud User Guide .
    See also: AWS API Documentation

    :example: response = client.describe_placement_groups(
        DryRun=True|False,
        GroupNames=[
            'string',
        ],
        Filters=[
            {
                'Name': 'string',
                'Values': [
                    'string',
                ]
            },
        ]
    )

    :type DryRun: boolean
    :param DryRun: Checks whether you have the required permissions for the action, without actually making the request, and provides an error response. If you have the required permissions, the error response is DryRunOperation . Otherwise, it is UnauthorizedOperation .

    :type GroupNames: list
    :param GroupNames: One or more placement group names.
            Default: Describes all your placement groups, or only those otherwise specified.
            (string) --

    :type Filters: list
    :param Filters: One or more filters.
            group-name - The name of the placement group.
            state - The state of the placement group (pending | available | deleting | deleted ).
            strategy - The strategy of the placement group (cluster ).
            (dict) --A filter name and value pair that is used to return a more specific list of results. Filters can be used to match a set of resources by various criteria, such as tags, attributes, or IDs.
            Name (string) --The name of the filter. Filter names are case-sensitive.
            Values (list) --One or more filter values. Filter values are case-sensitive.
            (string) --

    :rtype: dict
    :return: {
        'PlacementGroups': [
            {
                'GroupName': 'string',
                'Strategy': 'cluster',
                'State': 'pending'|'available'|'deleting'|'deleted'
            },
        ]
    }

    """
    pass


@staticmethod
def unmangle_name(name, classname):
    """Remove __ from the end of _name_ if it starts with __classname__
        return the "unmangled" name.
        """
    if name.startswith(classname) and name[-2:] != '__':
        return name[len(classname) - 2:]
    return name


def pretendsents(docsents):
    """
        Shortcut to provide sentence list without copying to new variable
    """
    for doc in docsents:
        for sent in doc:
            yield sent


def volume_of_tri_pyramid(b, h):
    """
    definition: func(b, h) {...}
    objective: returns you the volume of a triungluar pyramid
                V=1/3(1/2bh)h
    """
    volume = 1 / 3 * (1 / 2 * b * h) * h
    return volume


def same_key(key_a, key_b):
    """Comparison function for key ID or fingerprint strings, taking into
    account varying length."""
    if len(key_a) == len(key_b):
        return key_a == key_b
    elif len(key_a) < len(key_b):
        return key_b.endswith(key_a)
    else:
        return key_a.endswith(key_b)


def _get_endpoint(ks_session, **kwargs):
    """Get an endpoint using the provided keystone session."""
    endpoint_type = kwargs.get('endpoint_type') or 'publicURL'
    service_type = kwargs.get('service_type') or 'monitoring'
    endpoint = ks_session.get_endpoint(service_type=service_type, interface
        =endpoint_type, region_name=kwargs.get('region_name'))
    return endpoint


def __repr__(A):
    """For `print` and `pprint`"""
    return A.to_str()


def get_sent_num(text, sent_dict):
    """Return the sentence number stored in the dict.

    The sent_dict is a {text:sent_num} dictionary. If the sentence text
    is not in the dictionary, the function will add it with a sent_num value
    corresponding to the current length of the sent_dict.
    """
    if text not in sent_dict:
        sent_dict[text] = len(sent_dict)
    return sent_dict[text]


def turtle_functions(backend):
    """
    Return a dictionary with all turtle-related functions.
    """
    if backend == 'tk':
        from .turtle.tk import make_turtle_namespace
        ns = make_turtle_namespace()
    elif backend == 'qt':
        from .turtle.qt import make_turtle_namespace
        ns = make_turtle_namespace()
    else:
        raise ValueError('invalid backend: %r' % backend)
    return ns


def get_comparments(list_trans):
    """
    Getting a list of transtions, return the compartments
    """
    l = []
    for trans in list_trans:
        if trans.from_comp not in l:
            l.append(trans.from_comp)
        if trans.to_comp not in l:
            l.append(trans.to_comp)
    return l


def startStream(consumer):
    """start producing the stream

        @return (D): deferred fired when stream is finished
        """
    pass


@staticmethod
def is_token_authenticated(handler):
    """Is the request token-authenticated?"""
    if getattr(handler, '_cached_hub_user', None) is None:
        handler.get_current_user()
    return getattr(handler, '_token_authenticated', False)


def override_optional(func: callable):
    """Decorator used to document that the decorated function can be overridden in derived class, but need not be."""
    return func


@classmethod
def from_dict(cls, data):
    """Build a container object from a dictionary."""
    return cls(data.get('path'), data.get('user'), data.get('name'), data.
        get('version'), data.get('verify'), data.get('prebuild'), data.get(
        'running'), data.get('testing'))


@classmethod
def getTypeAndName(cls, plugin):
    """Accepts a full plugin name 'mod_book' and returns the type and plugin name"""
    if plugin == 'moodle' or plugin == 'core' or plugin == '':
        return 'core', None
    if not '_' in plugin:
        t = 'mod'
        name = plugin
    else:
        t, name = plugin.split('_', 1)
        if t == 'moodle':
            t = 'core'
    return t, name


@classmethod
def get_category_members_titles(cls, name, skip_index=True):
    """
        Generator that obtains a list of article titles in a category.

        Parameters
        ----------
        name: :class:`str`
            The category's name. ``Category:`` prefix is not necessary.
        skip_index: :class:`bool`
            Whether to skip index articles or not.

        Yields
        -------
        :class:`str`
            Titles of articles in this category.
        """
    for member in cls.get_category_members(name, skip_index):
        yield member.title


def _get_palette_bytes(im):
    """
    Gets the palette for inclusion in the gif header

    :param im: Image object
    :returns: Bytes, len<=768 suitable for inclusion in gif header
    """
    return im.palette.palette


def _get_high_res_img_url(img_url):
    """ Returns a modified url pointing to the high resolution version of
    the image
    >>> print(_get_high_res_img_url("https://images-na.ssl-images-amazon.com/images/I/513gErH1dML._AC_SX236_SY340_FMwebp_QL65_.jpg"))
    https://images-na.ssl-images-amazon.com/images/I/513gErH1dML.jpg
    >>> print(_get_high_res_img_url("https://images-na.ssl-images-amazon.com/images/I/51F48HFHq6L._AC_SX118_SY170_QL70_.jpg"))
    https://images-na.ssl-images-amazon.com/images/I/51F48HFHq6L.jpg
    """
    high_res_url = img_url.split('._')[0] + '.jpg'
    return high_res_url


def locate_significant_digit_after_decimal(value):
    """ Get location at which significant digit start after decimal

	Parameters
	----------
	value : float
		Input value

	Returns
	-------
	value : int
		Number of zeros after which digit start in a small decimal number.

	"""
    location = 0
    base = 0
    while base <= 0:
        base = int(abs(value) * 10 ** location)
        location = location + 1
    return location - 1


def rebuild():
    """This method is called, everytime an issue is updated.
        """


@staticmethod
def get_state(block):
    """
        Gets the user state, generally used for syntax highlighting.
        :param block: block to access
        :return: The block state

        """
    if block is None:
        return -1
    state = block.userState()
    if state == -1:
        return state
    return state & 65535


@staticmethod
def can_convert(unit1, unit2):
    """
        Returns true if the given units differ only by a multiplication. For
        example, ``[m/s]`` can be converted to ``[miles/hour]`` but not to
        ``[kg]``.
        """
    return unit1._x == unit2._x


def _omega_sunset(lat, delta):
    """Sunset hour angle (Eq. 59)

    Parameters
    ----------
    lat : ee.Image or ee.Number
        Latitude [radians].
    delta : ee.Image or ee.Number
        Earth declination [radians].

    Returns
    -------
    ee.Image or ee.Number
        Sunset hour angle [radians].

    Notes
    -----
    acos(-tan(lat) * tan(delta))

    """
    return lat.tan().multiply(-1).multiply(delta.tan()).acos()


def SLICE(array, n, position=None):
    """
    Returns a subset of an array.
    See https://docs.mongodb.com/manual/reference/operator/aggregation/slice/
    for more details
    :param array: Any valid expression as long as it resolves to an array.
    :param n: Any valid expression as long as it resolves to an integer.
    :param position: Optional. Any valid expression as long as it resolves to an integer.
    :return: Aggregation operator
    """
    return {'$slice': [array, position, n]} if position is not None else {
        '$slice': [array, n]}


def count(fasta):
    """Count sequences in an open FASTA file handle.

    Iterates each line, and counts header lines (start with `>`). Then, seeks to start
    of the file and returns the count.

    Parameters
    ----------
    fasta : open file handle
        An open file handle corresponding to a FASTA file.

    Returns
    -------
    count : int
        Total number of sequences in the file.
    """
    count = 0
    for line in fasta:
        if line.startswith('>'):
            count += 1
    fasta.seek(0)
    return count


@staticmethod
def name_to_formatted_name(name):
    """
        Returns formatted name of variable (lower case).
        """
    return name.lower()


def raise_for_unexpected_kwargs(method_name, arguments, sig_args,
    sig_kwargs, is_iterable):
    """Raise TypeError if arguments are not in sig_args or sig_kwargs."""
    expected = set(sig_args) | set(sig_kwargs)
    if is_iterable:
        expected |= {'iterator'}
    unexpected = set(arguments.keys()) - expected
    if unexpected:
        msg_fmt = '{}() got an unexpected keyword argument(s) {}'
        raise TypeError(msg_fmt.format(method_name, str(unexpected)))


def allpredecessors(obsstore, nodes, ignoreflags=0):
    """Yield node for every precursors of <nodes>.

    Some precursors may be unknown locally.

    This is a linear yield unsuited to detecting folded changesets. It includes
    initial nodes too."""
    remaining = set(nodes)
    seen = set(remaining)
    prec = obsstore.predecessors.get
    while remaining:
        current = remaining.pop()
        yield current
        for mark in prec(current, ()):
            if mark[2] & ignoreflags:
                continue
            suc = mark[0]
            if suc not in seen:
                seen.add(suc)
                remaining.add(suc)


@classmethod
def create_port_forwarding(cls, fip_id, internal_port_id, internal_port,
    external_port, internal_ip_address=None, protocol='tcp', client=None):
    """Creates a port forwarding.

        Create a port forwarding and schedule it for later deletion.
        If a client is passed, then it is used for deleting the PF too.

        :param fip_id: The ID of the floating IP address.

        :param internal_port_id: The ID of the Neutron port associated to
        the floating IP port forwarding.

        :param internal_port: The TCP/UDP/other protocol port number of the
        Neutron port fixed IP address associated to the floating ip
        port forwarding.

        :param external_port: The TCP/UDP/other protocol port number of
        the port forwarding floating IP address.

        :param internal_ip_address: The fixed IPv4 address of the Neutron
        port associated to the floating IP port forwarding.

        :param protocol: The IP protocol used in the floating IP port
        forwarding.

        :param client: network client to be used for creating and cleaning up
        the floating IP port forwarding.
        """
    client = client or cls.client
    pf = client.create_port_forwarding(fip_id, internal_port_id,
        internal_port, external_port, internal_ip_address, protocol)[
        'port_forwarding']
    pf['floatingip_id'] = fip_id
    pf['client'] = client
    cls.port_forwardings.append(pf)
    return pf


def _interpret_as_minutes(sval, mdict):
    """
    Times like "1:22" are ambiguous; do they represent minutes and seconds
    or hours and minutes?  By default, timeparse assumes the latter.  Call
    this function after parsing out a dictionary to change that assumption.

    >>> import pprint
    >>> pprint.pprint(_interpret_as_minutes('1:24', {'secs': '24', 'mins': '1'}))
    {'hours': '1', 'mins': '24'}
    """
    if sval.count(':') == 1 and '.' not in sval and ('hours' not in mdict or
        mdict['hours'] is None) and ('days' not in mdict or mdict['days'] is
        None) and ('weeks' not in mdict or mdict['weeks'] is None):
        mdict['hours'] = mdict['mins']
        mdict['mins'] = mdict['secs']
        mdict.pop('secs')
        pass
    return mdict


@staticmethod
def __convert__(potentials):
    """
        Converts potentials to a map (dict).

        :param potentials: Potentials.
        :return: Dict where keys are BBN node values and values are likelihoods.
        """
    m = dict()
    for k, v in potentials.items():
        m[k] = v.entries[0].value
    return m


def sort_dict_items(item_list):
    """ sort list of dict items based on update time """
    return sorted(item_list, key=lambda x: x['timestamp'])


@staticmethod
def is_str_hexadecimal(s):
    """Check if a string is a hexadecimal byte string.

        For example, '909090' returns True.

        Note:
            By design, hexadecimal strings with a length of 1 will return
            False. isalnum() will check for operators like + and - that would
            normally successfully validate.
        """
    if s.isalnum():
        if len(s) % 2 == 0:
            try:
                return isinstance(int(s, 16), int)
            except ValueError:
                pass
    return False


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


def _GenerateCRCTable():
    """Generate a CRC-32 table.

        ZIP encryption uses the CRC32 one-byte primitive for scrambling some
        internal keys. We noticed that a direct implementation is faster than
        relying on binascii.crc32().
        """
    poly = 3988292384
    table = [0] * 256
    for i in range(256):
        crc = i
        for j in range(8):
            if crc & 1:
                crc = crc >> 1 & 2147483647 ^ poly
            else:
                crc = crc >> 1 & 2147483647
        table[i] = crc
    return table


def pop_task(tasks, task_id):
    """Remove task with given identifier and return the task handle. The result
    is None if no task with the given identifier exists.

    Parameters
    ----------
    tasks: dict(vizier.engine.base.ExtendedTaskHandle)
        Dictionary of task handles
    task_id: string
        Unique task identifier

    Returns
    -------
    vizier.engine.base.ExtendedTaskHandle
    """
    if not task_id in tasks:
        return None
    task = tasks[task_id]
    del tasks[task_id]
    return task


def uint2ip_str(uint_val):
    """Covert 32-bit integer value to IPv4 string"""
    return '{}.{}.{}.{}'.format(uint_val >> 24 & 255, uint_val >> 16 & 255,
        uint_val >> 8 & 255, uint_val & 255)


@staticmethod
def _segement_daterange(start, end, maxdelta):
    """
        Segments a date range into shorter pieces with 'maxdelta' length.
        :param start: starting datetime
        :param end:  ending datetime
        :param maxdelta: timedelta instance representing max time window
        :return:
        """
    cur = start
    while cur < end:
        yield cur, min(cur + maxdelta, end)
        cur += maxdelta


def _compare_comparables(expected, topic):
    """Asserts the "like"-ness of `topic` and `expected` as comparable objects."""
    try:
        return expected == topic
    except:
        return False


def getModificationDate(history_id, selector=None):
    """ Returns the modification date of the selected version of object
            which has the given history id.

        If selected is None, the most recent version (HEAD) is taken.
        """


def _check_condition(msg, key, value):
    """Check one condition.

    If the value is a list, check that the message element is within the list.
    Example::

        product: [green_snow, overview]

    """
    if isinstance(value, list):
        if msg.data[key] not in value:
            return False
    elif isinstance(value, str) and value[0] in ['<', '>', '=', '!']:
        return eval(str(float(msg.data[key])) + value)
    elif msg.data[key] != value:
        return False
    return True


@staticmethod
def _filename(repo):
    """name of a branchcache file for a given repo or repoview"""
    filename = b'branch2'
    if repo.filtername:
        filename = b'%s-%s' % (filename, repo.filtername)
    return filename


def get_y() ->int:
    """Get the acceleration measurement in the ``y`` axis, as a positive or
    negative integer, depending on the direction.
    """


def getResults():
    """Return a constant describing the results of the build: one of the
        constants in buildbot.status.builder: SUCCESS, WARNINGS,
        FAILURE, SKIPPED or EXCEPTION."""


def data_unlink():
    """Unlink active Annotation data-block

    """
    pass


def KK_RC10_fit(params, w, t_values):
    """
    Kramers-Kronig Function: -RC-

    Kristian B. Knudsen (kknu@berkeley.edu / kristianbknudsen@gmail.com)
    """
    Rs = params['Rs']
    R1 = params['R1']
    R2 = params['R2']
    R3 = params['R3']
    R4 = params['R4']
    R5 = params['R5']
    R6 = params['R6']
    R7 = params['R7']
    R8 = params['R8']
    R9 = params['R9']
    R10 = params['R10']
    return Rs + R1 / (1 + w * 1.0j * t_values[0]) + R2 / (1 + w * 1.0j *
        t_values[1]) + R3 / (1 + w * 1.0j * t_values[2]) + R4 / (1 + w *
        1.0j * t_values[3]) + R5 / (1 + w * 1.0j * t_values[4]) + R6 / (1 +
        w * 1.0j * t_values[5]) + R7 / (1 + w * 1.0j * t_values[6]) + R8 / (
        1 + w * 1.0j * t_values[7]) + R9 / (1 + w * 1.0j * t_values[8]
        ) + R10 / (1 + w * 1.0j * t_values[9])


def abortConnection():
    """
        Close the connection abruptly.

        Discards any buffered data, stops any registered producer,
        and, if possible, notifies the other end of the unclean
        closure.

        @since: 11.1
        """


def requires_to_requires_dist(requirement):
    """Compose the version predicates for requirement in PEP 345 fashion."""
    requires_dist = []
    for op, ver in requirement.specs:
        requires_dist.append(op + ver)
    if not requires_dist:
        return ''
    return ' (%s)' % ','.join(sorted(requires_dist))


def new_ghost(oid, obj):
    """ Add the given (ghost) object to the cache.

        Also, set its _p_jar and _p_oid, and ensure it is in the
        GHOST state.

        If the object doesn't define '_p_oid' / '_p_jar', raise.

        If the object's '_p_oid' is not None, raise.

        If the object's '_p_jar' is not None, raise.

        If 'oid' is already in the cache, raise.
        """


def _rehydrate_skeleton_class(skeleton_class, class_dict):
    """Put attributes from `class_dict` back on `skeleton_class`.

    See CloudPickler.save_dynamic_class for more info.
    """
    registry = None
    for attrname, attr in class_dict.items():
        if attrname == '_abc_impl':
            registry = attr
        else:
            setattr(skeleton_class, attrname, attr)
    if registry is not None:
        for subclass in registry:
            skeleton_class.register(subclass)
    return skeleton_class


def get_int_attr(node, attribute):
    """Cast an element attribute to an int or return None if not present"""
    attr = node.get(attribute)
    return None if attr is None else int(attr)


@classmethod
def _get_doc(cls):
    """Return documentary of class

        By default it returns docstring of class, but it can be overridden
        for example for cases like merging own docstring with parent
        """
    return cls.__doc__


def choose_gender_action(user):
    """Set the avatar's gender to the selected value."""
    return user.avatar.set('gender', user.menu_choices[user.choice])


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 remove_outliers(features, limit, min_size):
    """
    features = remove_outliers(features, limit, min_size)

    """
    nsize = int(limit * len(features))
    if nsize < min_size:
        return features
    normed = features - features.mean(0)
    std = normed.std(0)
    std[std == 0] = 1
    normed /= std
    f2_sum1 = (normed ** 2).mean(1)
    values = f2_sum1.copy()
    values.sort()
    top = values[nsize]
    selected = f2_sum1 < top
    return features[selected]


def delete_remote_storage(sender, instance, **kwargs):
    """Delete media files from remote storage.

    Iterate through all associated remotely stored media and
    trigger a delete. This is handled through a signal so it
    is fired even when performing bulk deletes.

    Signal: pre_delete
    Sender: Media
    """
    from .tasks import delete_media
    for storage in instance.remotestorage_set.all():
        delete_media.delay(storage.id)


def time_to_seconds(time_str):
    """
    Convert a string describing a time duration into seconds. The supported
    formats are: "minutes", "minutes:seconds", "hours:minutes:seconds",
    "days-hours", "days-hours:minutes", "days-hours:minutes:seconds",
    and "days:hours:minutes:seconds"

    >>> time_to_seconds('10')
    600
    >>> time_to_seconds('10:00')
    600
    >>> time_to_seconds('10:30')
    630
    >>> time_to_seconds('1:10:30')
    4230
    >>> time_to_seconds('1-1:10:30')
    90630
    >>> time_to_seconds('1-0')
    86400
    >>> time_to_seconds('1-10')
    122400
    >>> time_to_seconds('1-1:10')
    90600
    >>> time_to_seconds('1-1:10:30')
    90630
    >>> time_to_seconds('1:1:10:30')
    90630
    >>> time_to_seconds('1 1:10:30')
    Traceback (most recent call last):
      ...
    ValueError: '1 1:10:30' has invalid pattern
    """
    import re
    patterns = [re.compile(
        '^(?P<hours>\\d+):(?P<minutes>\\d+):(?P<seconds>\\d+)$'), re.
        compile('^(?P<days>\\d+)-(?P<hours>\\d+)$'), re.compile(
        '^(?P<minutes>\\d+)$'), re.compile(
        '^(?P<minutes>\\d+):(?P<seconds>\\d+)$'), re.compile(
        '^(?P<days>\\d+)-(?P<hours>\\d+):(?P<minutes>\\d+)$'), re.compile(
        '^(?P<days>\\d+)-(?P<hours>\\d+):(?P<minutes>\\d+):(?P<seconds>\\d+)$'
        ), re.compile(
        '^(?P<days>\\d+):(?P<hours>\\d+):(?P<minutes>\\d+):(?P<seconds>\\d+)$')
        ]
    seconds = 0
    for pattern in patterns:
        match = pattern.match(str(time_str).strip())
        if match:
            if 'seconds' in match.groupdict():
                seconds += int(match.group('seconds'))
            if 'minutes' in match.groupdict():
                seconds += 60 * int(match.group('minutes'))
            if 'hours' in match.groupdict():
                seconds += 3600 * int(match.group('hours'))
            if 'days' in match.groupdict():
                seconds += 86400 * int(match.group('days'))
            return seconds
    raise ValueError("'%s' has invalid pattern" % time_str)


@staticmethod
def _union(intervals):
    """Unions sub-intervals of 'intervals' in-place.
        Assumes that 'intervals' sorted by first component of sub-element."""
    while len(intervals) > 0:
        prev = intervals.pop(0)
        if prev[0] == prev[1]:
            continue
        break
    else:
        return intervals
    for _ in range(len(intervals)):
        cur = intervals.pop(0)
        if cur[0] == cur[1]:
            continue
        if prev[1] < cur[0]:
            intervals.append(prev)
            prev = cur
        else:
            prev = prev[0], max(prev[1], cur[1])
    intervals.append(prev)
    return intervals


def format_time(decisecond):
    """
    Convert time in tenths of seconds
    into formatted string m:ss.t

    :param decisecond: int >= 0

    :return: str
    """
    assert isinstance(decisecond, int)
    assert decisecond >= 0
    decisecond, tenths = decisecond // 10, decisecond % 10
    minutes, seconds = decisecond // 60, decisecond % 60
    return '%d:%02d.%d' % (minutes, seconds, tenths)


@staticmethod
def convert(obj, unit, axis):
    """
        Convert *obj* using *unit* for the specified *axis*.

        If *obj* is a sequence, return the converted sequence.  The output must
        be a sequence of scalars that can be used by the numpy array layer.
        """
    return obj


def test():
    """ returns a test string """
    return 'ok'


def FN(target, prediction):
    """
    False negatives.
    :param target: target value
    :param prediction: prediction value
    :return:
    """
    return (target.float() * (prediction.float().round() == 0).float()).sum()


def create_nfs_file_share(ClientToken=None, NFSFileShareDefaults=None,
    GatewayARN=None, KMSEncrypted=None, KMSKey=None, Role=None, LocationARN
    =None, DefaultStorageClass=None, ClientList=None, Squash=None, ReadOnly
    =None):
    """
    Creates a file share on an existing file gateway. In Storage Gateway, a file share is a file system mount point backed by Amazon S3 cloud storage. Storage Gateway exposes file shares using a Network File System (NFS) interface. This operation is only supported in the file gateway architecture.
    See also: AWS API Documentation

    :example: response = client.create_nfs_file_share(
        ClientToken='string',
        NFSFileShareDefaults={
            'FileMode': 'string',
            'DirectoryMode': 'string',
            'GroupId': 123,
            'OwnerId': 123
        },
        GatewayARN='string',
        KMSEncrypted=True|False,
        KMSKey='string',
        Role='string',
        LocationARN='string',
        DefaultStorageClass='string',
        ClientList=[
            'string',
        ],
        Squash='string',
        ReadOnly=True|False
    )

    :type ClientToken: string
    :param ClientToken: [REQUIRED]
            A unique string value that you supply that is used by file gateway to ensure idempotent file share creation.

    :type NFSFileShareDefaults: dict
    :param NFSFileShareDefaults: File share default values. Optional.
            FileMode (string) --The Unix file mode in the form 'nnnn'. For example, '0666' represents the default file mode inside the file share. The default value is 0666.
            DirectoryMode (string) --The Unix directory mode in the form 'nnnn'. For example, '0666' represents the default access mode for all directories inside the file share. The default value is 0777.
            GroupId (integer) --The default group ID for the file share (unless the files have another group ID specified). The default value is nfsnobody.
            OwnerId (integer) --The default owner ID for files in the file share (unless the files have another owner ID specified). The default value is nfsnobody.

    :type GatewayARN: string
    :param GatewayARN: [REQUIRED]
            The Amazon Resource Name (ARN) of the file gateway on which you want to create a file share.

    :type KMSEncrypted: boolean
    :param KMSEncrypted: True to use Amazon S3 server side encryption with your own AWS KMS key, or false to use a key managed by Amazon S3. Optional.

    :type KMSKey: string
    :param KMSKey: The KMS key used for Amazon S3 server side encryption. This value can only be set when KmsEncrypted is true. Optional.

    :type Role: string
    :param Role: [REQUIRED]
            The ARN of the AWS Identity and Access Management (IAM) role that a file gateway assumes when it accesses the underlying storage.

    :type LocationARN: string
    :param LocationARN: [REQUIRED]
            The ARN of the backed storage used for storing file data.

    :type DefaultStorageClass: string
    :param DefaultStorageClass: The default storage class for objects put into an Amazon S3 bucket by file gateway. Possible values are S3_STANDARD or S3_STANDARD_IA. If this field is not populated, the default value S3_STANDARD is used. Optional.

    :type ClientList: list
    :param ClientList: The list of clients that are allowed to access the file gateway. The list must contain either valid IP addresses or valid CIDR blocks.
            (string) --

    :type Squash: string
    :param Squash: Maps a user to anonymous user. Valid options are the following:
            'RootSquash' - Only root is mapped to anonymous user.
            'NoSquash' - No one is mapped to anonymous user.
            'AllSquash' - Everyone is mapped to anonymous user.

    :type ReadOnly: boolean
    :param ReadOnly: Sets the write status of a file share: 'true' if the write status is read-only, and otherwise 'false'.

    :rtype: dict
    :return: {
        'FileShareARN': 'string'
    }

    """
    pass


def vertex_group_remove(all: bool=False):
    """Delete the active or all vertex groups from the active object

    :param all: All, Remove all vertex groups
    :type all: bool
    """
    pass


def select_more():
    """Select more spline points connected to initial selection

    """
    pass


def _store_OpenSSH(key, public_file=None, private_file=None, comment=None):
    """
    Store the public and private key into a file like object using
    OpenSSH format.
    """
    if public_file:
        public_openssh = key.public().toString(type='openssh')
        if comment:
            public_content = '%s %s' % (public_openssh, comment.encode('utf-8')
                )
        else:
            public_content = public_openssh
        public_file.write(public_content)
    if private_file:
        private_file.write(key.toString(type='openssh'))


def decode_request(data):
    """Decode a turnip-proto-request.

    turnip-proto-request is a superset of git-proto-request, supporting
    multiple named parameters. A turnip-proto-request with no parameters
    other than 'host' is also a git-proto-request.
    """
    if b' ' not in data:
        raise ValueError('Invalid git-proto-request')
    command, rest = data.split(b' ', 1)
    bits = rest.split(b'\x00')
    if len(bits) < 2 or bits[-1] != b'':
        raise ValueError('Invalid git-proto-request')
    pathname = bits[0]
    params = {}
    for param in bits[1:-1]:
        if b'=' not in param:
            raise ValueError('Parameters must have values')
        name, value = param.split(b'=', 1)
        if name in params:
            raise ValueError('Parameters must not be repeated')
        params[name] = value
    return command, pathname, params


def load_gtk__gtk(finder, module):
    """the gtk._gtk module has a number of implicit imports"""
    finder.IncludeModule('atk')
    finder.IncludeModule('cairo')
    finder.IncludeModule('gio')
    finder.IncludeModule('pango')
    finder.IncludeModule('pangocairo')


@classmethod
def from_args(cls, target_url, default_url, test_url):
    """Return an UploadToDeprecatedPyPIDetected instance."""
    return cls(
        """You're trying to upload to the legacy PyPI site '{}'. Uploading to those sites is deprecated.
 The new sites are pypi.org and test.pypi.org. Try using {} (or {}) to upload your packages instead. These are the default URLs for Twine now.
 More at https://packaging.python.org/guides/migrating-to-pypi-org/ ."""
        .format(target_url, default_url, test_url))


@staticmethod
def p_pgm_optional(p):
    """pgm_optional : sector
                        | generic_parameter_list"""
    p[0] = p.slice[1].type, p[1]


@classmethod
def _create_payload(cls, name, description, table_definitions,
    relationships, time_unit, feature_derivation_window_start,
    feature_derivation_window_end, is_draft):
    """
        Create the payload to create feature engineering graph

        Parameters
        ----------
        name: str
            name of the feature engineering graph
        description: str
            description of the fearture engineering graph
        table_definitions: list
            each element is a table_definition for a table.
        relationships: list
            each element is a relationship between two tables
        time_unit: str or None
            time unit of the feature derivation window. Supported
            values are MILLISECOND, SECOND, MINUTE, HOUR, DAY, WEEK, MONTH, QUARTER, YEAR.
            If present, the feature engineering Graph will perform time-aware joins.
        feature_derivation_window_start: int, or None
            how many time_units of each table's primary temporal key into the past relative
            to the datetimePartitionColumn the feature derivation window should begin.
            Will be a negative integer,
            If present, the feature engineering Graph will perform time-aware joins.
        feature_derivation_window_end: int, or None
            how many timeUnits of each table's record
            primary temporal key into the past relative to the datetimePartitionColumn the feature
            derivation window should end.  Will be a non-positive integer, if present.
            If present, the feature engineering Graph will perform time-aware joins.
        is_draft: bool (default=True)
            a draft (is_draft=True) feature engineering graph can be updated,
            while a non-draft(is_draft=False) feature engineering graph is immutable
        Returns
        -------
        payload: dict
            payload for the feature engineering graph
        """
    payload = {'name': name, 'description': description, 'tableDefinitions':
        table_definitions, 'relationships': relationships}
    if time_unit is not None:
        payload['timeUnit'] = time_unit
    if feature_derivation_window_start is not None:
        payload['featureDerivationWindowStart'
            ] = feature_derivation_window_start
    if feature_derivation_window_end is not None:
        payload['featureDerivationWindowEnd'] = feature_derivation_window_end
    payload['isDraft'] = is_draft
    return payload


@staticmethod
def save(file_path, model):
    """
        Save the model onto the file identified by file_path.

        Parameters
        ----------
        file_path : str
            The path to the filename where the model has to be saved
        model : RTEnsemble
            The model RTEnsemble model to save on file

        Returns
        -------
        status : bool
            Returns true if the save is successful, false otherwise
        """
    raise NotImplementedError('Feature not implemented!')


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

        :param str val:
        :rtype: AddSecondaryEmailResult
        """
    return cls('unavailable', val)


def _get_field_value(field_to_get, object_to_search):
    """
    Gets the value of a nested object, for example, if we search
    'address.city.neighborhood' in the object:
    {'address':
        {'city':
            {'neighborhood': 'shapira'}
        }
    }
    The returned value will be 'shapira'

    :param field_to_get:
    :param object_to_search:
    :return (string): The value of the field that needs to be searched
    """
    field_parts = field_to_get.split('.')
    while len(field_parts) > 0:
        field_part = field_parts.pop(0)
        object_to_search = object_to_search.get(field_part, '')
    return object_to_search


def assign_role_to_principal(role_id, principal_id):
    """Assign the role to the principal."""


def list_pipelines(Ascending=None, PageToken=None):
    """
    The ListPipelines operation gets a list of the pipelines associated with the current AWS account.
    See also: AWS API Documentation

    :example: response = client.list_pipelines(
        Ascending='string',
        PageToken='string'
    )

    :type Ascending: string
    :param Ascending: To list pipelines in chronological order by the date and time that they were created, enter true . To list pipelines in reverse chronological order, enter false .

    :type PageToken: string
    :param PageToken: When Elastic Transcoder returns more than one page of results, use pageToken in subsequent GET requests to get each successive page of results.

    :rtype: dict
    :return: {
        'Pipelines': [
            {
                'Id': 'string',
                'Arn': 'string',
                'Name': 'string',
                'Status': 'string',
                'InputBucket': 'string',
                'OutputBucket': 'string',
                'Role': 'string',
                'AwsKmsKeyArn': 'string',
                'Notifications': {
                    'Progressing': 'string',
                    'Completed': 'string',
                    'Warning': 'string',
                    'Error': 'string'
                },
                'ContentConfig': {
                    'Bucket': 'string',
                    'StorageClass': 'string',
                    'Permissions': [
                        {
                            'GranteeType': 'string',
                            'Grantee': 'string',
                            'Access': [
                                'string',
                            ]
                        },
                    ]
                },
                'ThumbnailConfig': {
                    'Bucket': 'string',
                    'StorageClass': 'string',
                    'Permissions': [
                        {
                            'GranteeType': 'string',
                            'Grantee': 'string',
                            'Access': [
                                'string',
                            ]
                        },
                    ]
                }
            },
        ],
        'NextPageToken': 'string'
    }

    :returns:
    Active : The pipeline is processing jobs.
    Paused : The pipeline is not currently processing jobs.

    """
    pass


def parse_boolean(value):
    """
    if value is None returns None.

    if value is boolean, it is returned as it is.
    if value is str and value is equals ignoring case to "True", True is returned.
    if value is str and value is equals ignoring case to "False", False is returned.

    For every other value, the answer is undefined.

    :param value:
    :return:
    """
    if value is None:
        return None
    if value in (True, False):
        return value
    try:
        return {'true': True, 'false': False}[value.casefold()]
    except (AttributeError, KeyError):
        raise ValueError(f'unknown string for bool: {value!r}')


def sizeof_fmt(num):
    """
    Format file sizes for a humans beings.
    http://stackoverflow.com/questions/1094841/reusable-library-to-get-human-readable-version-of-file-size
    """
    for x in ['bytes', 'KB', 'MB', 'GB']:
        if num < 1024.0 and num > -1024.0:
            return '%3.1f %s' % (num, x)
        num /= 1024.0
    return '%3.1f %s' % (num, 'TB')


def chunks(l, n):
    """Yield n successive chunks from l
    """
    newn = int(len(l) / n)
    for i in range(0, n - 1):
        yield l[i * newn:i * newn + newn]
    yield l[n * newn - newn:]


def validate_path_element(elem):
    """Check if a single path element is valid.

    :param elem: (str) A part of an dotted path (no dots allowed)
    :raises: ValueError if invalid.
    """
    if len(elem) is 0:
        raise ValueError('Path elements may not be empty')
    if '.' in elem:
        raise ValueError('Path elements should contain no dot')


def get_tag_link_attribute(xml, sddf_tag):
    """
    根据SDDF_Tag获取对应的TagLink节点
    获取金邦达DGI的TagLink节点属性，并返回
    对应的标准DGI分组和数据格式(TLV或者V)
    """
    tag_link_nodes = xml.get_nodes(xml.root_element, 'TagLink')
    for node in tag_link_nodes:
        tag = xml.get_attribute(node, 'SDDFTag')
        if sddf_tag[0:4] == tag[0:4] and sddf_tag[5:8] == tag[5:8]:
            node_dgi = xml.get_attribute(node, 'EMVTag')
            value_format = xml.get_attribute(node, 'ValueFormat')
            return node_dgi, value_format
    return '', ''


@classmethod
def like(cls, arr, beta=0.9, correct_bias=True):
    """Creates a new EWMA object with its shape and dtype like the specified NumPy array.

        :param arr: The array to take the shape and data type from.
        :type arr: numpy.ndarray
        :param beta: The smoothing factor to use. Must be between 0 and 1.
        :type beta: float
        :param correct_bias: Whether to correct the running average's initialization bias.
        :type correct_bias: bool
        :returns: The new exponentially weighted moving average object.
        :rtype: average.EWMA
        """
    return cls(arr.shape, arr.dtype, beta, correct_bias)


def flatten(lst):
    """For an iterable of sub-iterables, generate each member of each
    sub-iterable in turn, i.e. a flattened version of that super-iterable.

    Example: Turn [[a,b,c],[d,e,f]] into [a,b,c,d,e,f].
    """
    for sublist in lst:
        for j in sublist:
            yield j


@classmethod
def from_str(cls, value: str) ->'TEmployee':
    """
        Construct from a JSON string (eg. a POST payload).

        Returns:
            Model instance based on the JSON string.

        """
    ...


@staticmethod
def getidx(lmax, l, m):
    """Returns index corresponding to (l,m) in an array describing alm up to lmax.

        In HEALPix C++ and healpy, :math:`a_{lm}` coefficients are stored ordered by
        :math:`m`. I.e. if :math:`\\ell_{max}` is 16, the first 16 elements are
        :math:`m=0, \\ell=0-16`, then the following 15 elements are :math:`m=1, \\ell=1-16`,
        then :math:`m=2, \\ell=2-16` and so on until the last element, the 153th, is
        :math:`m=16, \\ell=16`.

        Parameters
        ----------
        lmax : int
          The maximum l, defines the alm layout
        l : int
          The l for which to get the index
        m : int
          The m for which to get the index

        Returns
        -------
        idx : int
          The index corresponding to (l,m)
        """
    return m * (2 * lmax + 1 - m) // 2 + l


def upsert(module):
    """Saves or updates a module

    Args:
        module:

    Returns:

    """
    return module.save()


@staticmethod
def _next_cursor_is_present(data):
    """Determine if the response contains 'next_cursor'
        and 'next_cursor' is not empty.

        Returns:
            A boolean value.
        """
    present = 'response_metadata' in data and 'next_cursor' in data[
        'response_metadata'] and data['response_metadata']['next_cursor'] != ''
    return present


@task
def get_tasks():
    """Get all paver-defined tasks."""
    from paver.tasks import environment
    for task in environment.get_tasks():
        print(task.shortname)


def columns_interval_df(discrete, weighted, keys=[]):
    """Obtain the columns of dataframe according with the time-signature, the keys and the weighting."""
    cols = ['ts', 'tf']
    if not discrete:
        cols.extend(['s', 'f'])
    if weighted:
        cols.append('w')
    return keys + cols


def should_skip_request(pin, request):
    """Helper to determine if the provided request should be traced"""
    if not pin or not pin.enabled():
        return True
    api = pin.tracer.writer.api
    return request.host == api.hostname and request.port == api.port


def modification_date():
    """
            Returns a DateTime indicating the time  a thread was last updated.
        """


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 assert_genexpr(g):
    """
    Raise a `TypeError` if an object is not a generator expression.

    Args:
        g: The object to check.
    """
    if g.__name__ != '<genexpr>':
        raise TypeError(f"'{type(g)}' object is not a generator expression")


@classmethod
def fix_non_manifold(cls, context, sides):
    """naive iterate-until-no-more approach for fixing manifolds"""
    total_non_manifold = cls.count_non_manifold_verts(context)
    if not total_non_manifold:
        return
    bm_states = set()
    bm_key = cls.elem_count(context)
    bm_states.add(bm_key)
    while True:
        cls.fill_non_manifold(sides)
        cls.delete_newly_generated_non_manifold_verts()
        bm_key = cls.elem_count(context)
        if bm_key in bm_states:
            break
        else:
            bm_states.add(bm_key)


def get_func_description_from_docstring(docstring):
    """
    Get the string of the function's description in docstring.

    Parameters
    ----------
    docstring : str
        Target docstring.

    Returns
    ----------
    func_description : str
        Description of the function in docstring.
    """
    if docstring == '':
        return ''
    last_line_num = 0
    line_splitted_list = docstring.split('\n')
    for line_str in line_splitted_list:
        is_hyphen_line = '----' in line_str
        if is_hyphen_line:
            last_line_num -= 1
            break
        last_line_num += 1
    if last_line_num <= 0:
        return ''
    func_description = '\n'.join(line_splitted_list[:last_line_num])
    func_description = func_description.strip()
    if func_description.replace(' ', '') == '':
        return ''
    if not func_description.startswith('    '):
        func_description = '    %s' % func_description
    return func_description


def length_hint(obj, default=0):
    """
    Return an estimate of the number of items in obj.
    This is useful for presizing containers when building from an iterable.

    If the object supports len(), the result will be exact. Otherwise, it may
    over- or under-estimate by an arbitrary amount. The result will be an
    integer >= 0.
    """
    if not isinstance(default, int):
        msg = "'%s' object cannot be interpreted as an integer" % type(default
            ).__name__
        raise TypeError(msg)
    try:
        return len(obj)
    except TypeError:
        pass
    try:
        hint = type(obj).__length_hint__
    except AttributeError:
        return default
    try:
        val = hint(obj)
    except TypeError:
        return default
    if val is NotImplemented:
        return default
    if not isinstance(val, int):
        msg = '__length_hint__ must be integer, not %s' % type(val).__name__
        raise TypeError(msg)
    if val < 0:
        msg = '__length_hint__() should return >= 0'
        raise ValueError(msg)
    return val


@classmethod
def stopLoading(cls):
    """Force the page stop all navigations and pending resource fetches.
        """
    return cls.build_send_payload('stopLoading', {}), None


def all_results():
    """
    Returns a list of all available/possible results
    Subject to change in the future
    """
    results_list = ['SPP', 'DownholeECD', 'FlowRateOut', 'HookLoad',
        'SurfaceTorque', 'BitDepth', 'TD', 'ChokeOpening',
        'DownholePressure', 'ChokePressure', 'FluidTemperatureOut', 'WOB',
        'InstantaneousROP', 'BopChokeOpening', 'FlowRateIn',
        'TopOfStringVelocity', 'SurfaceRPM', 'ChokePumpFlowRateIn',
        'DrillstringTemperature', 'TotalInfluxMass',
        'CalculatedPressureBottomHole', 'CuttingsMassFractionTransient',
        'GasVolumeFraction', 'DrillstringBucklingLimit',
        'FluidTemperatureIn', 'AnnulusECD', 'DrillstringTorqueLimit',
        'AnnulusTemperature', 'DrillstringTension', 'AnnulusFluidVelocity',
        'DrillstringFluidVelocity', 'CuttingsBedHeight', 'AnnulusDensity',
        'DrillstringTorque', 'TotalMudLossMass', 'Connection',
        'TopOfStringPosition', 'ActivePitVolume', 'ActivePitDensity',
        'ActivePitTemperature', 'MainPitVolume', 'MainPitDensity',
        'MainPitTemperature', 'ReservePitVolume', 'ReservePitDensity',
        'ReservePitTemperature', 'GasFlowRateOut', 'DrillstringDensity']
    return results_list


def has_traits(cls, ignore=('config', 'parent')):
    """True if cls has any traits apart from the usual ones

    all our components have at least 'config' and 'parent' as traitlets
    this is inherited from `traitlets.config.Configurable` so we ignore them
    here.
    """
    return bool(set(cls.class_trait_names()) - set(ignore))


def getPattern():
    """
        returns the pattern used to parse a single entry
        """


def _weakbound_for_json(value):
    """
    Simply call `for_json` on the underlying value if it exists; otherwise, return the underlying
    value.
    """
    return value.for_json() if hasattr(value, 'for_json') else value


def half_area(ia, max_bound=0, tol=0.5):
    """
	Find bound of peak by summing intensities until change in sum is less than
	'tol' percent of the current area.

	:param ia: List of intensities from Peak apex for a given mass
	:type ia: list
	:param max_bound: Optional value to limit size of detected bound, default 0
	:type max_bound: int, optional
	:param tol: Percentage tolerance of added area to current area, default 0.5
	:type tol: float, optional

	:return: Half peak area, boundary offset, shared (True if shared ion)
	:rtype: tuple

	:authors: Andrew Isaac, Dominic Davis-Foster (type assertions)
	"""
    if not isinstance(ia, list) or not isinstance(ia[0], (int, float)):
        raise TypeError("'ia' must be a list of numbers")
    if not isinstance(max_bound, int):
        raise TypeError("'max_bound' must be an integer")
    if not isinstance(tol, float):
        raise TypeError("'tol' must be a float")
    tol = tol / 200.0
    wide = 3
    shared = False
    area = ia[0]
    edge = float(sum(ia[0:wide])) / wide
    old_edge = 2 * edge
    index = 1
    if max_bound < 1:
        limit = len(ia)
    else:
        limit = min(max_bound + 1, len(ia))
    while area * tol < edge < old_edge and index < limit:
        old_edge = edge
        area += ia[index]
        edge = float(sum(ia[index:index + wide])) / wide
        index += 1
    if edge >= old_edge:
        shared = True
    index -= 1
    return area, index, shared


def belongs(outSequence, group, minMatches):
    """
    Returns True if there's at least 'minMatches' matches between outSequence and any sequence
    from 'group'; False otherwise.
    Size of all sequences is assumed to be equal.
    """
    for inSequence in group:
        matches = 0
        for i in range(len(outSequence)):
            if outSequence[i] == inSequence[i]:
                matches += 1
            if matches >= minMatches:
                return True
    return False


def _evaluate_term_fwd(term, eta0, eps0, deps, eta_derivs,
    eval_directional_derivative, validate=False):
    """Evaluate the DerivativeTerm in forward mode.

    Parameters
    ----------------------
    term: `DerivativeTerm`
        A `DerivativeTerm` object to evaluate.
    eta0, eps0 : `numpy.ndarray`
        Where to evaluate the derivative.
    deps : `numpy.ndarray`
        The direction in which to evaluate the derivative.
    eta_derivs : `list` of `numpy.ndarray`
        A list where ``eta_derivs[i]`` contains
        :math:`d\\eta^i / d\\epsilon^i \\Delta \\epsilon^i`.
    eval_directional_derivative:
        A function matching `eval_directional_derivative` in
        ForwardModeDerivativeArray.
    validate: optional `bool`
        If `True`, run checks for the appropriate sizes of arguments and
        produce helpful error messages if necessary.
        Default is `False`.
    """
    if validate:
        if len(eta_derivs) < term.order() - 1:
            raise ValueError('Not enough derivatives in ``eta_derivs``.')
    vec_args = []
    eta_directions = []
    for i in range(len(term.eta_orders)):
        eta_order = term.eta_orders[i]
        if eta_order > 0:
            for j in range(eta_order):
                eta_directions.append(eta_derivs[i])
    eps_directions = []
    for i in range(term.eps_order):
        eps_directions.append(deps)
    return term.prefactor * eval_directional_derivative(eta0, eps0,
        eta_directions, eps_directions, validate=validate)


def _truncate(text, limit=200):
    """Truncate text to given number of characters"""
    if len(text) > limit + 40:
        return text[:limit] + '... (truncated)'
    return text


def _in_qtconsole() ->bool:
    """
    A small utility function which determines if we're running in QTConsole's context.
    """
    try:
        from IPython import get_ipython
        try:
            from ipykernel.zmqshell import ZMQInteractiveShell
            shell_object = ZMQInteractiveShell
        except ImportError:
            from IPython.kernel.zmq import zmqshell
            shell_object = zmqshell.ZMQInteractiveShell
        return isinstance(get_ipython(), shell_object)
    except Exception:
        return False


def filectx(path, changeid=None, fileid=None):
    """Obtain a filectx for the given file revision."""


def compute_bytes_per_voxel(element_type):
    """Returns number of bytes required to store one voxel for the given
    metaIO ElementType """
    switcher = {'MET_CHAR': 1, 'MET_UCHAR': 1, 'MET_SHORT': 2, 'MET_USHORT':
        2, 'MET_INT': 4, 'MET_UINT': 4, 'MET_LONG': 4, 'MET_ULONG': 4,
        'MET_LONG_LONG': 8, 'MET_ULONG_LONG': 8, 'MET_FLOAT': 4,
        'MET_DOUBLE': 8}
    return switcher.get(element_type, 2)


def bool_to_str(value: bool) ->str:
    """Converts boolean to 'ON' or 'OFF' string."""
    if type(value) is bool:
        return 'ON' if value is True else 'OFF'
    else:
        raise Exception(
            f"bool_to_str: unsupported variable type '{type(value)}', value '{value}'. Only boolean values are supported."
            )


def insert_cell_below(content, type_='code'):
    """
    Inserts a cell in the current Jupyter Notebook below the currently
    activated cell
    """
    from IPython.display import Javascript, display
    javascript = (
        """
    var cell;
    cell = Jupyter.notebook.insert_cell_below('{}');
    cell.set_text("{}");
    """
        .format(type_, content))
    if type_ == 'markdown':
        javascript += """
        cell.execute();
        """
    display(Javascript(javascript))


@classmethod
def get_polymorphic_model_for_type(cls, obj_type):
    """
        Return the polymorphic model associated with the given type.
        Raise `NotImplementedError` if no model is found for the given type. This usually
        means that a serializer is missing in the class's `polymorphic_serializers` attribute.
        """
    return cls.get_polymorphic_model_for_serializer(cls.
        get_polymorphic_serializer_for_type(obj_type))


def space_tokenizer(sequence):
    """ Splits sequence based on spaces. """
    if sequence:
        return sequence.split(' ')


def units(comp_sum, uncomp_sum):
    """Calculate package size
    """
    compressed = round(sum(map(float, comp_sum)) / 1024, 2)
    uncompressed = round(sum(map(float, uncomp_sum)) / 1024, 2)
    comp_unit = uncomp_unit = 'Mb'
    if compressed > 1024:
        compressed = round(compressed / 1024, 2)
        comp_unit = 'Gb'
    if uncompressed > 1024:
        uncompressed = round(uncompressed / 1024, 2)
        uncomp_unit = 'Gb'
    if compressed < 1:
        compressed = sum(map(int, comp_sum))
        comp_unit = 'Kb'
    if uncompressed < 1:
        uncompressed = sum(map(int, uncomp_sum))
        uncomp_unit = 'Kb'
    return [comp_unit, uncomp_unit], [compressed, uncompressed]


def nearest_start(s, od, flank=1):
    """nearest start in ORF dict from s
  """
    if s in od:
        return s
    for i in range(1, flank + 1):
        if s + i in od:
            return s + i
        if s - i in od:
            return s - i
    return None


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 single_day(stats, day):
    """skip day-1 days then return only results from the next day"""
    days_seen = set()
    for ping in stats:
        days_seen.add(ping.date)
        if len(days_seen) == day:
            yield ping
        if len(days_seen) > day:
            return


@staticmethod
def parse_config(contents):
    """ Parses the configuration data

        :param contents: list[str] List of lines from the configuration file
        :return: dict[str,str]
        """
    config = {}
    for line in contents:
        line = line.lstrip().rstrip('\r\n')
        if line.startswith('#'):
            continue
        if '=' not in line:
            continue
        key, _, value = line.partition('=')
        config[key.strip()] = value.lstrip()
    return config


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 NATR(df, n):
    """
    Normalized Average True Range
    """


@classmethod
def join(cls):
    """Equal to Thread.join"""
    from timeit import default_timer
    temp = default_timer()
    for i in cls.threads:
        i.wait()
    return temp - default_timer()


def ifnot(if_, else_, transform=None):
    """Returns the condition ``if_`` iff it evaluates to ``True``, or if a transformation is
    specified, ``transform(if_)``. Returns ``else_`` if the condition is ``False``.
    ``transform`` can be any callable, which will be passed ``if_`` in case ``if_`` is not ``False``."""
    if not bool(if_):
        return else_
    elif transform is not None:
        return transform(if_)
    else:
        return if_


def _pluralize_granularity(granularity):
    """Pluralize the given granularity"""
    if 'century' == granularity:
        return 'centuries'
    return granularity + 's'


def describe_protection(ProtectionId=None):
    """
    Lists the details of a  Protection object.
    See also: AWS API Documentation

    :example: response = client.describe_protection(
        ProtectionId='string'
    )

    :type ProtectionId: string
    :param ProtectionId: [REQUIRED]
            The unique identifier (ID) for the Protection object that is described.

    :rtype: dict
    :return: {
        'Protection': {
            'Id': 'string',
            'Name': 'string',
            'ResourceArn': 'string'
        }
    }

    """
    pass


def get_public_version_expiration_datetime():
    """Get the expiration datetime of the public version, or
        None if this version never expires.
        """


def type_of(char):
    """ Determines whether a character is alpha, a fish hook, or other """
    if char.isalpha():
        return 'alpha'
    elif char == '<' or char == '>':
        return 'hook'
    else:
        return 'other'


def pairname(insym, outsym):
    """Convert a pair of symbols into a single label

    insym -- input symbol as a string
    outsym -- output symbol as a string

    Returns a string notation of the pair, eg.

    >>> pairname ('a', 'a')
    a
    >>> pairname('i','j')
    i:j

    """
    if insym == outsym:
        return insym
    else:
        return insym + ':' + outsym


def get_realms():
    """ Must return list or tuple of realms provided. """
    pass


def format_product_types(product_types):
    """Format product_types

    :param list product_types: A list of EODAG product types as returned by the core api
    """
    result = []
    for pt in product_types:
        result.append('* *__{ID}__*: {abstract}'.format(**pt))
    return '\n'.join(sorted(result))


def function_with_disk_stuff():
    """A sample function that might take a long time to test."""
    return False


def list_get(l, idx, default=None):
    """
    Get from a list with an optional default value.
    """
    try:
        if l[idx]:
            return l[idx]
        else:
            return default
    except IndexError:
        return default


@staticmethod
def _internal_aft_hash(aft):
    """A has function representing two 'internal'.

        :class:`pydent.models.AllowableFieldType` models (i.e. an operation)
        """
    return '{operation_type}'.format(operation_type=aft.field_type.
        parent_id, routing=aft.field_type.routing, sample_type=aft.
        sample_type_id)


@classmethod
def detect_mode(cls, **params):
    """Detect which listing mode of the given params.

        :params kwargs params: the params
        :return: one of the available modes
        :rtype: str
        :raises ValueError: if multiple modes are detected
        """
    modes = []
    for mode in cls.modes:
        if params.get(mode) is not None:
            modes.append(mode)
    if len(modes) > 1:
        error_message = 'ambiguous mode, must be one of {}'
        modes_csv = ', '.join(list(cls.modes))
        raise ValueError(error_message.format(modes_csv))
    return modes[0] if modes else cls.default_mode


@staticmethod
def p_memory_layout_prg_type(p):
    """memory_layout_prg_type : PRG_CODE
                                  | PRG_DATA
                                  | PRG_RESERVED"""
    p[0] = p[1]


def hasProperty(name):
    """Return true if the named property exists.

        @param name: property name
        @type name: string
        @returns: boolean
        """


def supplements(parms, countrate=None):
    u"""Supplementary parameters:
        [7]  n₁ = n*F₁     Particle number of species 1
        [8]  n₂ = n*(1-F₁) Particle number of species 2
    """
    n = parms[0]
    F1 = parms[3]
    Info = list()
    Info.append([u'n₁', n * F1])
    Info.append([u'n₂', n * (1.0 - F1)])
    if countrate is not None:
        cpp = countrate / n
        Info.append(['cpp [kHz]', cpp])
    return Info


def get_metadata(session, name):
    """
    Gets meta data from pypi for the given package.
    :param session: requests Session instance
    :param name: str, package
    :return: dict, meta data
    """
    resp = session.get('https://rubygems.org/api/v1/gems/{}.json'.format(name))
    if resp.status_code == 200:
        return resp.json()
    return {}


def extract_between(source: str, start: str, end: str) ->str:
    """Extract all of the characters between start and end.

    :param source: The input string from which to extract a substring.
    :param start: The substring that marks the extraction starting place.
    :param end: The substring that marks the place where extraction will end.
    :param return: A substring that is extracted from ``source``.
    :note: The ``start`` and ``end`` strings are not include in the result.
    """
    return source[source.find(start) + len(start):source.find(end)]


def _clitable_to_dict(cli_table):
    """Convert TextFSM cli_table object to list of dictionaries."""
    objs = []
    for row in cli_table:
        temp_dict = {}
        for index, element in enumerate(row):
            temp_dict[cli_table.header[index].lower()] = element
        objs.append(temp_dict)
    return objs


def discarded_file(filename):
    """
    # The __conan pattern is to be prepared for the future, in case we want to manage our
    own files that shouldn't be uploaded
    """
    return filename == '.DS_Store' or filename.endswith('.pyc'
        ) or filename.endswith('.pyo'
        ) or filename == '__pycache__' or filename.startswith('__conan')


def group_tag(group_name):
    """Marks this field as belonging to a group"""
    tag = 'group:%s' % group_name
    return tag


def create_bgp_peer(virtualInterfaceId=None, newBGPPeer=None):
    """
    Creates a new BGP peer on a specified virtual interface. The BGP peer cannot be in the same address family (IPv4/IPv6) of an existing BGP peer on the virtual interface.
    You must create a BGP peer for the corresponding address family in order to access AWS resources that also use that address family.
    When creating a IPv6 BGP peer, the Amazon address and customer address fields must be left blank. IPv6 addresses are automatically assigned from Amazon's pool of IPv6 addresses; you cannot specify custom IPv6 addresses.
    For a public virtual interface, the Autonomous System Number (ASN) must be private or already whitelisted for the virtual interface.
    See also: AWS API Documentation

    :example: response = client.create_bgp_peer(
        virtualInterfaceId='string',
        newBGPPeer={
            'asn': 123,
            'authKey': 'string',
            'addressFamily': 'ipv4'|'ipv6',
            'amazonAddress': 'string',
            'customerAddress': 'string'
        }
    )

    :type virtualInterfaceId: string
    :param virtualInterfaceId: The ID of the virtual interface on which the BGP peer will be provisioned.
            Example: dxvif-456abc78
            Default: None

    :type newBGPPeer: dict
    :param newBGPPeer: Detailed information for the BGP peer to be created.
            Default: None
            asn (integer) --The autonomous system (AS) number for Border Gateway Protocol (BGP) configuration.
            Example: 65000
            authKey (string) --The authentication key for BGP configuration.
            Example: asdf34example
            addressFamily (string) --Indicates the address family for the BGP peer.
            ipv4 : IPv4 address family
            ipv6 : IPv6 address family
            amazonAddress (string) --IP address assigned to the Amazon interface.
            Example: 192.168.1.1/30 or 2001:db8::1/125
            customerAddress (string) --IP address assigned to the customer interface.
            Example: 192.168.1.2/30 or 2001:db8::2/125

    :rtype: dict
    :return: {
        'virtualInterface': {
            'ownerAccount': 'string',
            'virtualInterfaceId': 'string',
            'location': 'string',
            'connectionId': 'string',
            'virtualInterfaceType': 'string',
            'virtualInterfaceName': 'string',
            'vlan': 123,
            'asn': 123,
            'authKey': 'string',
            'amazonAddress': 'string',
            'customerAddress': 'string',
            'addressFamily': 'ipv4'|'ipv6',
            'virtualInterfaceState': 'confirming'|'verifying'|'pending'|'available'|'down'|'deleting'|'deleted'|'rejected',
            'customerRouterConfig': 'string',
            'virtualGatewayId': 'string',
            'routeFilterPrefixes': [
                {
                    'cidr': 'string'
                },
            ],
            'bgpPeers': [
                {
                    'asn': 123,
                    'authKey': 'string',
                    'addressFamily': 'ipv4'|'ipv6',
                    'amazonAddress': 'string',
                    'customerAddress': 'string',
                    'bgpPeerState': 'verifying'|'pending'|'available'|'deleting'|'deleted',
                    'bgpStatus': 'up'|'down'
                },
            ]
        }
    }

    :returns:
    ipv4 : IPv4 address family
    ipv6 : IPv6 address family

    """
    pass


@classmethod
def get_options(cls):
    """Return the list of parameters associated with the auth plugin.

        This list may be used to generate CLI or config arguments.

        :returns: A list of Param objects describing available plugin
                  parameters.
        :rtype: List
        """
    return []


def _grp2mathmode(matchobj):
    """Helper function to latex-ify the units for plotting"""
    unitstr = matchobj.group()
    unitstr = unitstr[0] + '{' + unitstr[1:]
    return '$' + unitstr + '}$'


def take_away_from(y):
    """take_away_from(y)(x) = y - x

    Be careful with this because subtraction is not commutative.
    The flipped version of this is 'take_away'

    >>> list(map(take_away_from(2), [1,2,3,4,5]))
    [1, 0, -1, -2, -3]
    """
    return lambda x: y - x


def _warn_if_string(iterable):
    """Helper for the response objects to check if the iterable returned
    to the WSGI server is not a string.
    """
    if isinstance(iterable, str):
        from warnings import warn
        warn(Warning(
            'response iterable was set to a string.  This appears to work but means that the server will send the data to the client char, by char.  This is almost never intended behavior, use response.data to assign strings to the response object.'
            ), stacklevel=2)


@staticmethod
def get_data_table_label(parent):
    """
        Get the name of the reference for the table listing all data for the parent

        :param parent: String with the name of the parent neurodata_type
        :return: String with label of the table
        """
    return 'table-' + parent + '-data'


def zipdict(keys, vals):
    """Creates a dict with keys mapped to the corresponding vals."""
    return dict(zip(keys, vals))


def colors(theme=None):
    """
Return dictionary of colors.

.. code-block:: python

  {
    'selection' : '...',
    'queued'    : '...',
  }

:options:

  **theme** ([``'dark'``] | ``<str>``)
    Select color-theme.
  """
    if theme == 'dark':
        return {'selection': '1;32;40', 'queued': '0;37'}
    return {'selection': '', 'queued': ''}


def _clean_dataframe(df):
    """Clean response list of pandas dataframes to query results table"""
    cleaned = df[3]
    del cleaned['Unnamed: 0']
    del cleaned['Unnamed: 23']
    return cleaned


def psi_K_HCO3_OH_HMW84(T, P):
    """c-a-a': potassium bicarbonate hydroxide [HMW84]."""
    psi = 0.0
    valid = T == 298.15
    return psi, valid


@classmethod
def add_common_opts(cls, parser):
    """Add options that are common for several plugins."""
    for opt in cls.common_opt_names:
        cls._parser_add_opt(parser, opt)


def make_lower(arg):
    """helper function to make lowercase or return original"""
    if arg is not None:
        if isinstance(arg, str):
            arg = arg.tolower()
    return arg


def digitsum(n):
    """ Use for numbers with more than 6 digits. """
    return sum(map(int, str(n)))


def sig_key(s, order):
    """
    Key for comparing two signatures.

    s = (m, k), t = (n, l)

    s < t iff [k > l] or [k == l and m < n]
    s > t otherwise

    """
    return -s[1], order(s[0])


@classmethod
def from_sdl(cls, s, d, length):
    """Initialize a line segment from a start point, direction, and length.

        Args:
            s: A Point3D representing the start point of the line segment.
            d: A Vector3D representing the direction of the line segment.
            length: A number representing the length of the line segment.
        """
    return cls(s, d * length / d.magnitude)


def should_delete_branch(branch):
    """
  Checks if the given branch should be deleted.
  """
    return branch and branch != 'master' and not branch.startswith('*')


@staticmethod
def migration(cell, *args, **kwargs):
    """Migrate to a neighboring cell."""
    next_site = cell.site.random_neighbor()
    cell.site.remove_guest(cell)
    next_site.add_guest(cell)
    cell.site = next_site
    return cell


def _content_matches(element_def, element):
    """ Checks for match of content (if provided), must partially match one of the text items in the element. """
    if not element_def.content:
        return True
    for string in element.strings:
        if string and element_def.content in string:
            return True
    return False


@staticmethod
def to_reaumur(romer):
    """ Convert romer to reaumur """
    return (romer - 7.5) * 32 / 21


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 __call__(cls, *args, **kwds):
    """Instantiate cls after preprocessing its token definitions."""
    if '_tokens' not in cls.__dict__:
        cls._all_tokens = {}
        cls._tmpname = 0
        if hasattr(cls, 'token_variants') and cls.token_variants:
            pass
        else:
            cls._tokens = cls.process_tokendef('', cls.get_tokendefs())
    return type.__call__(cls, *args, **kwds)


def _calc_pad(oldnum, newnum):
    """ Calculate the proper padding for fft_pad

    We have three cases:
    old number even new number even
    >>> _calc_pad(10, 16)
    (3, 3)

    old number odd new number even
    >>> _calc_pad(11, 16)
    (3, 2)

    old number odd new number odd
    >>> _calc_pad(11, 17)
    (3, 3)

    old number even new number odd
    >>> _calc_pad(10, 17)
    (4, 3)

    same numbers
    >>> _calc_pad(17, 17)
    (0, 0)

    from larger to smaller.
    >>> _calc_pad(17, 10)
    (-4, -3)
    """
    width = newnum - oldnum
    pad_s = width // 2
    pad_b = width - pad_s
    pad1, pad2 = pad_b, pad_s
    return pad1, pad2


def box():
    """Define the effective cells."""
    box = []
    for i in range(9):
        for j in range(9):
            b = [0] * 81
            for i2 in range(9):
                b[i2 * 9 + j] = 1
            for j2 in range(9):
                b[i * 9 + j2] = 1
            begin = i // 3 * 27 + j // 3 * 3
            for i2 in [0, 1, 2]:
                for j2 in [0, 1, 2]:
                    b[begin + i2 * 9 + j2] = 1
            b[i * 9 + j] = 0
            bb = []
            for i2 in range(81):
                if b[i2] == 1:
                    bb = bb + [i2]
            box = box + [bb]
    return box


def selectCiphers(availableCiphers):
    """
        Choose which ciphers to allow to be negotiated on a TLS connection.

        @param availableCiphers: A L{list} of L{ICipher} which gives the names
            of all ciphers supported by the TLS implementation in use.

        @return: A L{list} of L{ICipher} which represents the ciphers
            which may be negotiated on the TLS connection.  The result is
            ordered by preference with more preferred ciphers appearing
            earlier.
        """


def unaryOperator(op):
    """
    Returns a function which performs unary (not) operation
    """
    if op == 'not':
        return lambda x: not x
    raise Exception('operator %s not found' % op)


def _get_branching(container, index):
    """ Returns the nearest valid element from an interable container.

    This helper function returns an element from an iterable container.
    If the given `index` is not valid within the `container`,
    the function returns the closest element instead.

    Parameter
    ---------
        container:
            A non-empty iterable object.
        index:
            The index of an element that should be returned.

    Returns
    -------
        object
            The closest possible element from `container` for `index`.

    Example
    -------
    The `container` can be an arbitrary iterable object such as a list::

        l = ['a', 'b', 'c']
        c1 = _get_clamped_index(l, 5)
        c2 = _get_clamped_index(l, 1)
        c3 = _get_clamped_index(l, -4)

    The first call of the function using an index of 5 will return element 'c',
    the second call will return 'b' and the third call will return 'a'.
    """
    maximal_index = len(container) - 1
    minimal_index = 0
    clamped_index = min(maximal_index, index)
    clamped_index = max(minimal_index, clamped_index)
    return container[clamped_index]


def move_detach_links(NODE_OT_links_detach=None, TRANSFORM_OT_translate=
    None, NODE_OT_insert_offset=None):
    """Move a node to detach links

    :param NODE_OT_links_detach: Detach Links, Remove all links to selected nodes, and try to connect neighbor nodes together
    :param TRANSFORM_OT_translate: Translate, Translate (move) selected items
    :param NODE_OT_insert_offset: Insert Offset, Automatically offset nodes on insertion
    """
    pass


def area(polygon):
    """
    Calculate the area of a polygon. Can be positive (clockwise) or negative (anticlockwise)

    Input

    polygon   [ (r1, z1), (r2, z2), ... ]
    """
    nvert = len(polygon)
    area = 0.0
    for i in range(nvert):
        r1, z1 = polygon[i]
        r2, z2 = polygon[(i + 1) % nvert]
        area += (r2 - r1) * (z1 + z2)
    return 0.5 * area


def clean_col_names(columns):
    """Standardise all column labels"""
    return columns.str.strip().str.lower().str.replace(' ', '_').str.replace(
        '(', '').str.replace(')', '')


@classmethod
def from_json(cls, service_dict):
    """Create a service object from a JSON string."""
    service_endpoint, _type, _index, _attributes, sd = cls._parse_json(
        service_dict)
    return cls(service_endpoint, _type, _attributes, sd, _index)


def prepare_form_entry_export_data(form_entry, form_element_entries=None,
    form_handler_entries=None):
    """Prepare form entry export data.

    :param fobi.modes.FormEntry form_entry: Instance of.
    :param django.db.models.QuerySet form_element_entries: QuerySet of
        FormElementEntry instances.
    :param django.db.models.QuerySet form_handler_entries: QuerySet of
        FormHandlerEntry instances.
    :return str:
    """
    data = {'name': form_entry.name, 'slug': form_entry.slug, 'is_public':
        False, 'active_date_from': form_entry.active_date_from,
        'active_date_to': form_entry.active_date_to, 'inactive_page_title':
        form_entry.inactive_page_title, 'inactive_page_message': form_entry
        .inactive_page_message, 'is_cloneable': False, 'success_page_title':
        form_entry.success_page_title, 'success_page_message': form_entry.
        success_page_message, 'action': form_entry.action, 'form_elements':
        [], 'form_handlers': []}
    if not form_element_entries:
        form_element_entries = form_entry.formelemententry_set.all()[:]
    if not form_handler_entries:
        form_handler_entries = form_entry.formhandlerentry_set.all()[:]
    for form_element_entry in form_element_entries:
        data['form_elements'].append({'plugin_uid': form_element_entry.
            plugin_uid, 'position': form_element_entry.position,
            'plugin_data': form_element_entry.plugin_data})
    for form_handler_entry in form_handler_entries:
        data['form_handlers'].append({'plugin_uid': form_handler_entry.
            plugin_uid, 'plugin_data': form_handler_entry.plugin_data})
    return data


@classmethod
def find_meta_tags(cls, page_html):
    """Returns the content of the meta tag if found inside of the provided HTML."""
    return cls._META_IMPORT_REGEX.findall(page_html)


@staticmethod
def nextChild(hotmap, index):
    """ Return the next sibling of the node indicated by index. """
    nextChildIndex = min(index + 1, len(hotmap) - 1)
    return hotmap[nextChildIndex][1]


def valiate_input(playvals, type, module):
    """
    Helper method to validate playbook values for destination groups
    """
    if type == 'destination_groups':
        if not playvals.get('id'):
            msg = 'Invalid playbook value: {0}.'.format(playvals)
            msg += ' Parameter <id> under <destination_groups> is required'
            module.fail_json(msg=msg)
        if playvals.get('destination') and not isinstance(playvals[
            'destination'], dict):
            msg = 'Invalid playbook value: {0}.'.format(playvals)
            msg += (
                ' Parameter <destination> under <destination_groups> must be a dict'
                )
            module.fail_json(msg=msg)
        if not playvals.get('destination') and len(playvals) > 1:
            msg = 'Invalid playbook value: {0}.'.format(playvals)
            msg += ' Playbook entry contains unrecongnized parameters.'
            msg += (
                ' Make sure <destination> keys under <destination_groups> are specified as follows:'
                )
            msg += (
                ' destination: {ip: <ip>, port: <port>, protocol: <prot>, encoding: <enc>}}'
                )
            module.fail_json(msg=msg)
    if type == 'sensor_groups':
        if not playvals.get('id'):
            msg = 'Invalid playbook value: {0}.'.format(playvals)
            msg += ' Parameter <id> under <sensor_groups> is required'
            module.fail_json(msg=msg)
        if playvals.get('path') and 'name' not in playvals['path'].keys():
            msg = 'Invalid playbook value: {0}.'.format(playvals)
            msg += (
                ' Parameter <path> under <sensor_groups> requires <name> key')
            module.fail_json(msg=msg)


def core_mass_L(MH):
    """
    Core-mass luminosity relationship from Bloecker (1993).

    Parameters
    ----------
    MH : float
        Core mass in Msun.

    Returns
    -------
    L
        Luminosity in Lsun

    """
    return 62200 * (MH - 0.487)


def _format_offset(off):
    """
    Format a timedelta into "[+-]HH:MM" format or "" for None
    """
    if off is None:
        return ''
    mins = off.days * 24 * 60 + off.seconds // 60
    sign = '-' if mins < 0 else '+'
    return sign + '%02d:%02d' % divmod(abs(mins), 60)


def cigar_join(initial, value, wasinsert):
    """ adds a value to a list

    Args:
        initial: list to be added to
        value: data point to be added. This is either a string or an integer
        wasinsert: whether the previous position contained an insertion

    Returns:
        list with value added appropriately
    """
    if not wasinsert:
        initial.append(value)
        return initial
    try:
        initial[-1] += value
    except TypeError:
        initial[-1].append(value)
    return initial


def import_attribute(name):
    """Import attribute using string reference.

    Example::

      import_attribute('a.b.c.foo')

    Throws ImportError or AttributeError if module or attribute do not exist.
    """
    path, attr = name.rsplit('.', 1)
    module = __import__(path, globals(), locals(), [attr])
    return getattr(module, attr)


@staticmethod
def _update_last_batch(batch, *new_captions):
    """Given a batch of captions, sets their end time equal to the start
        time of the first caption in *new_captions

        The start time of the first caption in new_captions should never be 0.
        This means an invalid SCC file.

        :type batch: tuple[Caption]
        :type new_captions: tuple[Caption]
        """
    if not new_captions:
        return
    if not new_captions[0]:
        return
    if not new_captions[0].nodes:
        return
    new_caption = new_captions[0]
    if batch and batch[-1].end == 0:
        for caption in batch:
            caption.end = new_caption.start


def windows_default_tools_list():
    """
    returns a list of tools to install

    @return     list of tools
    """
    return ['7z', 'scite', 'putty', 'mingw', 'SQLiteSpy', 'r', 'vs',
        'julia', 'graphviz', 'tdm', 'pandoc', 'jdk', 'jenkins', 'miktex',
        'inkscape', 'git', 'python']


def quoting_types():
    """Returns a list of the supported quoting modes"""
    return ['QUOTE_MINIMAL', 'QUOTE_ALL', 'QUOTE_NONE']


def isosurface(im, isovalue=None, step=1, useClassic=False, useValues=False):
    """ isosurface(vol, isovalue=None, step=1, useClassic=False, useValues=False)

    Uses scikit-image to calculate the isosurface for the given 3D image.
    Returns a vv.BaseMesh object.

    Parameters
    ----------
    vol : 3D numpy array
        The volume for which to calculate the isosurface.
    isovalue : float
        The value at which the surface should be created. If not given or None,
        the average of the min and max of vol is used.
    step : int
        The stepsize for stepping through the volume. Larger steps yield
        faster but coarser results. The result shall always be topologically
        correct though.
    useClassic : bool
        If True, uses the classic marching cubes by Lorensen (1987) is used.
        This algorithm has many ambiguities and is not guaranteed to produce
        a topologically correct result.
    useValues : bool
        If True, the returned BaseMesh object will also have a value for
        each vertex, which is related to the maximum value in a local region
        near the isosurface.

    """
    from visvis.utils.iso import isosurface as _isosurface
    return _isosurface(im, isovalue, step, useClassic, useValues)


def _show_leading_zeros(spinbutton):
    """Adds leading zeros to the given gtk spinbutton"""
    adjustment = spinbutton.get_adjustment()
    value = int(adjustment.get_value())
    spinbutton.set_text(f'{value:02d}')
    return True


@classmethod
def cleanuptags(cls, text):
    """ delete critical chars
        """
    t1 = ''
    for i in text:
        if (i in
            '0123456789abcdefghijklmnopqrstuvwxyz.ABCDEFGHIJKLMNOPQRSTUVWXYZ-'
            ):
            t1 += i
        else:
            t1 += u'-'
    return t1


@classmethod
def native_model_factory(cls):
    """
        Native Model Factory.

        :return: instance native model
        """
    raise NotImplementedError()


def Dict(**entries):
    """Create a dict out of the argument=value arguments"""
    return entries


def print_numbered_items(items, ctx):
    """Convenience function to print a numbered list of items."""
    for i, item in enumerate(items):
        hrf = item.human_readable_form(ctx)
        pos = hrf[1]
        print('{} : {}'.format(i + 1, hrf))


def aq_acquire(name, filter=None, extra=None, explicit=True, default=0,
    containment=0):
    """Get an attribute, acquiring it if necessary.
        """


def constraint_to_fcurve():
    """Create F-Curves for object which will copy object’s movement caused by this constraint

    """
    pass