def remove_tz_if_return_naive(dt, return_naive):
    """
    A helper function to strip tzinfo objects if return_naive is True.

    Returns a naive datetime object if return_naive is True.

    :type dt: datetime
    :param dt: The datetime

    :type return_naive: bool
    :param return_naive: Make datetime naive if True

    :rtype: datetime
    :returns: A naive dt if return_naive is True.
    """
    return dt.replace(tzinfo=None) if return_naive else dt


@classmethod
def from_rhinomesh(cls, guid):
    """Class method for constructing a block from a Rhino mesh.

        Parameters
        ----------
        guid : str
            The GUID of the mesh.

        Returns
        -------
        Block
            The block corresponding to the Rhino mesh.

        """
    from compas_rhino.helpers import mesh_from_guid
    return mesh_from_guid(cls, guid)


def addition(a, b):
    """ Demonstration function.
    """
    return a + b


def validate_maximum(value, maximum):
    """Validate that ``value`` is at most ``maximum``

    Normally called in :meth:`~mopidy.config.types.ConfigValue.deserialize`.
    """
    if maximum is not None and value > maximum:
        raise ValueError(f'{value!r} must be smaller than {maximum!r}.')


def formula(foyer_fiscal, period, parameters):
    """
        Attention : Pour les années avant 2013, cette formule n'est pas entièrement correcte car le taux de la CSG n'était pas unique (distinction revenus du patrimoine et revenus de placement)
        """
    assiette_csg_revenus_capital = foyer_fiscal('assiette_csg_revenus_capital',
        period)
    P = parameters(period)
    return (-assiette_csg_revenus_capital * P.prelevements_sociaux.
        contributions.csg.capital.glob)


def get_message_by_id(message_id):
    """Return the message with a matching Message-ID.

        :param message_id: The Message-ID header contents to search for.
        :returns: The message, or None if no matching message was found.
        """


@classmethod
def supports_from_pcm(cls):
    """returns True if all necessary components are available
        to support the .from_pcm() classmethod"""
    try:
        from audiotools.encoders import encode_opus
        return True
    except ImportError:
        return False


def mesh_to_dataset(mesh):
    """
        Generates an xarray dataset out of the mesh attributes; useful for
        merging this with other datarrays to attach mesh information to a
        dataset
        """


def microseconds(h, m, s, f):
    """
    Returns an integer representing a number of microseconds
    :rtype: int
    """
    return (int(h) * 3600 + int(m) * 60 + int(s)) * 1000000 + int(f) * 1000


def decode_html(string):
    """decode common html/xml entities"""
    new_string = string
    decoded = ['>', '<', '"', '&', "'"]
    encoded = ['>', '<', '"', '&', ''']
    for e, d in zip(encoded, decoded):
        new_string = new_string.replace(e, d)
    for e, d in zip(encoded[::-1], decoded[::-1]):
        new_string = new_string.replace(e, d)
    return new_string


def createNavTree():
    """Build the actual tree"""


def describe_user_profile(userArn=None):
    """
    Describes a user in AWS CodeStar and the user attributes across all projects.
    See also: AWS API Documentation

    :example: response = client.describe_user_profile(
        userArn='string'
    )

    :type userArn: string
    :param userArn: [REQUIRED]
            The Amazon Resource Name (ARN) of the user.

    :rtype: dict
    :return: {
        'userArn': 'string',
        'displayName': 'string',
        'emailAddress': 'string',
        'sshPublicKey': 'string',
        'createdTimestamp': datetime(2015, 1, 1),
        'lastModifiedTimestamp': datetime(2015, 1, 1)
    }

    """
    pass


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 plural(items, word):
    """Return number of items followed by the right form  of ``word``.

    ``items`` can either be an int or an object whose cardinality can be
    discovered via `len(items)`.

    The plural of ``word`` is assumed to be made by adding an ``s``.

    """
    item_count = items if isinstance(items, int) else len(items)
    word = word if item_count == 1 else word + 's'
    return '{0} {1}'.format(item_count, word)


def children_tax(tax_off, tax_tab, ctax_buff):
    """
	collect direct children of a taxon
	"""
    tax_ent = tax_tab[tax_off]
    ctax_off = tax_ent['ChildrenOff']
    return ctax_buff[ctax_off:ctax_off + tax_ent['ChildrenNum']]


@staticmethod
def get_for_t_or_latest(w, t):
    """
        Extract values from dict for given time point.
        """
    if t not in w:
        t = max(w)
    return w[t]


def supportinternal(repo):
    """True if the internal phase can be used on a repository"""
    return b'internal-phase' in repo.requirements


def if_no_repeat(event):
    """ Callable that returns True when the previous event was delivered to
    another handler. """
    return not event.is_repeat


def timedelta_total_seconds(delta):
    """Helper method to determine the total number of seconds
    from a timedelta.

    Args:
        delta (timedelta): A timedelta to convert to seconds.
    """
    return delta.days * 24 * 60 * 60 + delta.seconds


@staticmethod
def configure_locales(connection, config):
    """
        Generate and configure locales in recently installed server.
        """
    connection.sudo('locale-gen en_US.UTF-8', warn=True, hide='both')
    connection.sudo('dpkg-reconfigure locales', warn=True, hide='both')


def _evalfact(lcs, c):
    """Input: a list of variable-bracketed strings, the known LCS
       Output: number of variables needed and the variables themselves in a list."""
    allbreaks = []
    for w in c:
        breaks = [0] * len(lcs)
        p = 0
        inside = 0
        for pos in w:
            if pos == u'[':
                inside = 1
            elif pos == u']':
                inside = 0
                breaks[p - 1] = 1
            elif inside:
                p += 1
        allbreaks.append(breaks)
    finalbreaks = [0] * len(lcs)
    for br in allbreaks:
        for idx, val in enumerate(br):
            if val == 1:
                finalbreaks[idx] = 1
    variables = []
    currvar = u''
    for idx, val in enumerate(lcs):
        currvar += lcs[idx]
        if finalbreaks[idx] == 1:
            variables.append(currvar)
            currvar = u''
    numvars = sum(finalbreaks)
    return numvars, variables


def mel_to_freq(mel):
    """Convert a value in mel to a value in Hertz.

    Parameters
    ----------
    mel : numeric
        Frequency value in mel to convert.

    Returns
    -------
    float
        Frequency value in Hertz.

    """
    return 700 * (10 ** (mel / 2595.0) - 1)


@classmethod
def check_properties(mcs, attributes):
    """Check whether intersections exist.

        :type attributes: dict
        """
    include, exclude = mcs.get_prepared_include_exclude(attributes)
    properties = mcs.get_properties(attributes)
    intersections = list(set(properties).intersection(include if include else
        exclude))
    if not intersections:
        return None
    attr_name = '__include__' if include else '__exclude__'
    raise AttributeError(
        'It is not allowed to mention already defined properties: {0} in {1} attributes.'
        .format(', '.join(intersections), attr_name))


def wait(zelf, sec=None):
    """ Wait for this object's ready flag. """
    zelf._ready.wait(sec)
    for thr in zelf._thrs:
        thr.join()


def haiku_is_ipv6(word_array):
    """Weather haiku is converted from IPv6 or not, return True if it is"""
    if word_array[0] == 'the' and len(word_array) in [12, 13, 14]:
        is_ipv6 = False
    elif len(word_array) == 17:
        is_ipv6 = True
    else:
        raise ValueError('Illegal haiku')
    return is_ipv6


def is_validated(user):
    """Is this user record validated?"""
    return user.get('validated', True)


def __exit__(exctype, excvalue, exctb):
    """Called when cacher is no longer used.

        This can be used by implementations to perform cleanup actions (e.g.
        disconnecting network sockets, aborting a partially cached response.
        """


def t_USE_LEASE_ADDR_FOR_DEFAULT_ROUTE(t):
    """use-lease-addr-for-default-route"""
    return t


def get_axis_limits(ax, scale=0.85, position='upper-right'):
    """Used to position the identifier labels in the corner of images.
    e.g. '(a)' etc.

    An example use with this definition is as follows:

        ax1.annotate("("+d[i+1-10]+")", xy=get_axis_limits(ax1))

    This will place an annotation in the top right corner of our subplot,
    ax1. Specifically this is used for labelling multiple plots using
    letters. The function d[i] is a dictionary function which converts
    numbers to letters.

    Parameters
    ----------
    ax : plot/subplot function
        The plot or subplot that you want to scale accordingly
    scale : float, optional
        A scale function that determines as a fractional percentage the
        position from the edge of the plot (e.g. scale = 1 is at the
        edge and scale = 0.5 is centred).
    position : string, optional
        Determines the prefered location of interest releative to the
        four corners of the plot. string selections are ('upper-right',
        'upper-left', 'lower-right', 'lower-left')

    Returns
    -------
    x : float
        coordinate reference relative to the input plot ax in the x axis
    y: float
        coordinate reference relative to the input plot ax in the y axis

    """
    if position == 'upper-right':
        try:
            return ax.get_xlim()[1] * 0.95 * scale, ax.get_ylim()[1] * 0.9
        except AttributeError:
            return ax.xlim()[1] * 0.95 * scale, ax.ylim()[1] * 0.9
    elif position == 'upper-left':
        try:
            return ax.get_xlim()[1] * 0.95 * (1 - scale), ax.get_ylim()[1
                ] * 0.9
        except AttributeError:
            return ax.xlim()[1] * 0.95 * (1 - scale), ax.ylim()[1] * 0.9
    elif position == 'lower-right':
        try:
            return ax.get_xlim()[1] * 0.95, ax.get_ylim()[1] * (1 - scale)
        except AttributeError:
            return ax.xlim()[1] * 0.95, ax.ylim()[1] * (1 - scale)
    elif position == 'lower-left':
        try:
            return ax.get_xlim()[1] * 0.95, ax.get_ylim()[1] * 0.95 * (1 -
                scale)
        except AttributeError:
            return ax.xlim()[1] * 0.95, ax.ylim()[1] * 0.95 * (1 - scale)


def clean_fullname(val):
    """Remove special characters from user full name."""
    if not val:
        return val
    val = val.strip()
    for i in range(32):
        val = val.replace(chr(i), '')
    return val


def SetDOMImplementation(dom_implementation):
    """Override the default DOMImplementation object."""
    global __DOMImplementation
    __DOMImplementation = dom_implementation
    return __DOMImplementation


def set_predef_parse_reply(reply):
    """Sets reply which _parse is to return whenever called"""
    global _predef_parse_reply
    _predef_parse_reply = reply


@staticmethod
def supportedViews():
    """Overrides :meth:`.ControlMixin.supportedViews`. The
        ``OrthoEditActionToolBar`` is only intended to be added to
        :class:`.OrthoPanel` views.
        """
    from fsleyes.views.orthopanel import OrthoPanel
    return [OrthoPanel]


def partition():
    """
        split incoming things into `True` and `False` things based on results
        of call
        """


def normalize(path, isknown=False, ignoremissing=False):
    """
        normalize the case of a pathname when on a casefolding filesystem

        isknown specifies whether the filename came from walking the
        disk, to avoid extra filesystem access.

        If ignoremissing is True, missing path are returned
        unchanged. Otherwise, we try harder to normalize possibly
        existing path components.

        The normalized case is determined based on the following precedence:

        - version of name already stored in the dirstate
        - version of name stored on disk
        - version provided via command arguments
        """


def cleanup():
    """Clean up all resources that may be left over.

        ZODB iterators keep the database file and read from it when
        you access various bits of data.  When you're done doing all that,
        be sure to invoke `cleanup()` so those files can be closed.
        """


def asc_peaks(iterable):
    """ Yields ascending peaks from `iterable`. """
    it = iter(iterable)
    try:
        cur = next(it)
    except StopIteration:
        return
    for x in it:
        if x < cur:
            yield cur
        cur = x
    yield cur


def upsert(data_structure_element):
    """ Save or update the Data Structure Element

    Args:
        data_structure_element:

    Returns:

    """
    return data_structure_element.save()


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

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

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


def view_ndof():
    """Use a 3D mouse device to pan/zoom the view

    """
    pass


def _verify_parsed_docstring(parameters, param_dict):
    """
    Verification of consistency of the parameters extracted from docstring and
    dictionary of parameters (probably default parameters). There must be one-to-one
    match between the entries of the list of the parameters extracted from the docstring
    and the parameter dictionary.

    Parameters
    ----------

    parameters : list(tuple)
        The list of ``(parameter_name, parameter_description)`` tuples.
        Descriptions are not analyzed by this function.

    param_dict : dict
        The dictionary of parameters: key - parameter name, value - default value.
        Values are not analyized by this function.

    Returns
    -------

    Raises exception if there is mismatch between the parameter sets.
    """
    pd = param_dict.copy()
    missing_param_list = []
    for p_name, _ in parameters:
        if p_name in pd:
            del pd[p_name]
        else:
            missing_param_list.append(p_name)
    extra_param_list = pd.keys()
    err_msg_list = []
    if missing_param_list:
        err_msg_list.append(
            f'parameters that are in docstring, but not in the dictionary {missing_param_list}'
            )
    if extra_param_list:
        err_msg_list.append(
            f'dictionary parameters that are not found in the docstring: {extra_param_list}'
            )
    if err_msg_list:
        err_msg = (
            'Parsed parameter verification failed: parameter set is inconsistent:\n'
            )
        err_msg += ', '.join(err_msg_list)
        assert False, err_msg


def is_shift_character(character):
    """
    Returns True if the key character is uppercase or shifted.
    """
    return character.isupper() or character in '~!@#$%^&*()_+{}|:"<>?'


def delete_policy(PolicyArn=None):
    """
    Deletes the specified managed policy.
    Before you can delete a managed policy, you must first detach the policy from all users, groups, and roles that it is attached to, and you must delete all of the policy's versions. The following steps describe the process for deleting a managed policy:
    For information about managed policies, see Managed Policies and Inline Policies in the IAM User Guide .
    See also: AWS API Documentation

    :example: response = client.delete_policy(
        PolicyArn='string'
    )

    :type PolicyArn: string
    :param PolicyArn: [REQUIRED]
            The Amazon Resource Name (ARN) of the IAM policy you want to delete.
            For more information about ARNs, see Amazon Resource Names (ARNs) and AWS Service Namespaces in the AWS General Reference .

    """
    pass


def disable():
    """Disable middleware.

    This is the alternative way to disable middleware. It will be used to be
    able to disable middleware via oslo.config.
    """
    global _ENABLED
    _ENABLED = False


@staticmethod
def _jaccard_similarity(a, b):
    """Compute the jaccard similarity between two lists."""
    sa = set(a)
    sb = set(b)
    return len(sa.intersection(sb)) / len(sa.union(sb))


@classmethod
def AtmosCorrBRDFFromReflectance(cls, reflectance):
    """Set 6S to perform atmospheric correction using a fully BRDF-represented surface, using a given reflectance value.

        Arguments:
        * ``reflectance`` -- Reflectance of the surface.

        """
    return '1 BRDF\n%f reflectance\n' % (reflectance * -1)


@classmethod
def get_transit_from(cls, state, auto_inverse=False):
    """
        Return a set with the states having a transition to given `state`.

        If `auto_inverse` is set to True then a tuple is returned containing the smallest set from:

        * (States allowed to transit to given `state`, True)
        * (States not allowed to transit to given `state`, False)
        """
    valid = cls.INVERSE_TRANSITIONS[state]
    if not auto_inverse:
        return valid
    not_valid = cls.ALL_STATES - valid
    return (not_valid, False) if len(valid) > len(not_valid) else (valid, True)


def equivalent_viscous_damping(mu, mtype='concrete', btype='frame'):
    """
    Calculate the equivalent viscous damping based on the ductility and structural type.
    :param mu: Displacement ductility
    :param mtype: material type
    :param btype: building type (e.g. frame or wall)
    :return:
    """
    pie = 3.141
    if mu < 1:
        return 0.05
    if mtype == 'concrete':
        if btype == 'frame':
            return 0.05 + 0.565 * (mu - 1) / (mu * pie)
        if btype == 'wall':
            return 0.05 + 0.444 * (mu - 1) / (mu * pie)


@classmethod
def add_arguments(cls, parser, sys_arg_list=None):
    """
        Callback to add command line options for this plugin to the argparse
        parser.

        """
    parser.add_argument('--fixed_cidr', dest='fixed_cidr', required=True,
        help='specify the route CIDR (only in fixedconf mode)')
    parser.add_argument('--fixed_hosts', dest='fixed_hosts', required=True,
        help="list of host IPs, separated by ':' (only in fixedconf mode)")
    return ['fixed_cidr', 'fixed_hosts']


def _has_effective_handler(logger):
    """
    Checks if a logger has a handler that will catch its messages in its logger hierarchy.
    :param `logging.Logger` logger: The logger to be checked.
    :return: True if a handler is found for the logger, False otherwise.
    :rtype: bool
    """
    while True:
        if logger.handlers:
            return True
        if not logger.parent:
            return False
        logger = logger.parent


def phraser(text, bigram):
    """ Given gensim's phraser.Phraser instance, coalesce found bigrams in text """
    return ' '.join(bigram[text.split()])


@classmethod
def _flatten_task_chunk(cls, nested_task_chunk: list) ->list:
    """Recursively converts a nested task list to a flat list."""
    flat_task_chunk = []
    for elem in nested_task_chunk:
        if isinstance(elem, list):
            flat_task_chunk.extend(cls._flatten_task_chunk(elem))
        else:
            flat_task_chunk.append(elem)
    return flat_task_chunk


def set_encrypted_communication(value: bool):
    """Allows to deactivate encrypted communication."""
    global ENCRYPTED_COMMUNICATION
    ENCRYPTED_COMMUNICATION = value


def split_list(iterable, condition):
    """
    Split list items into `(matching, non_matching)` by `cond(item)` callable.
    """
    matching = []
    non_matching = []
    for item in iterable:
        if condition(item):
            matching.append(item)
        else:
            non_matching.append(item)
    return matching, non_matching


def read_renderlayers():
    """Read all the current scene’s render layers from cache, as needed

    """
    pass


def loaded():
    """return if this feed is in a loaded state"""


@classmethod
def delete_where_user_id(cls, user_id):
    """ delete by email """
    result = cls.where_user_id(user_id)
    if result is None:
        return None
    result.delete()
    return True


@staticmethod
def get_file_path_from_link(link):
    """
        Returns the file_path for a file in a <link> in HTML
        :param link: <link> from HTML
        :type link: str
        :returns: file_path provided in the <link>
        :rtype: str
        """
    if link == '':
        print('getFilePathFromLink: No link provided')
        return
    file_path = ''
    if link.find('href=') > 0:
        file_path = link[link.find('href="') + 6:link.rfind('"')]
    elif link.find('src=') > 0:
        file_path = link[link.find('src="') + 5:link.rfind('"')]
    else:
        print('getFilePathFromLink: Unrecognized pattern :' + link)
        return
    return file_path


def __contains__(value):
    """Return whether the value is available in this source
        """


def p_SingleType(p):
    """SingleType : NonAnyType"""
    p[0] = p[1]


@classmethod
def checkRequiredInputFields(cls, dframe, requiredFields):
    """
        Checks that dframe has the fields in the array requiredFields. Also checks that there are
        no duplicate fields Returns True on success. Raises a ValueError on failure.
        :params dframe: The DataFrame that is being checked.
        :paras requiredFields: The fields that are required.
        """
    actualFields = dframe.columns
    if len(actualFields) != len(set(actualFields)):
        err = 'Your DataFrame has duplicate columns'
        raise ValueError(err)
    if set(requiredFields) <= set(actualFields):
        return True
    else:
        err = (
            '\n\nYour DataFrame is missing some required fields ... Including:\n     '
            )
        err += str(set(requiredFields) - set(actualFields))
        if 'Date' in str(set(requiredFields) - set(actualFields)):
            err += (
                '\nNote that DAS exports lack a Date field and it must be supplied. \n'
                )
        raise ValueError(err)


@staticmethod
def _apply_color(code, content):
    """
        Apply a color code to text
        """
    normal = u'\x1b[0m'
    seq = u'\x1b[%sm' % code
    return seq + (normal + seq).join(content.split(normal)) + normal


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 _ovsdb_result_pending(result):
    """Return True if ovsdb indicates the result is still pending."""
    return result == []


@classmethod
def _load_java(cls, sc, path):
    """
        Load a Java model from the given path.
        """
    java_class = cls._java_loader_class()
    java_obj = sc._jvm
    for name in java_class.split('.'):
        java_obj = getattr(java_obj, name)
    return java_obj.load(sc._jsc.sc(), path)


def encode_helper(obj, to_builtin):
    """Encode an object into a two element dict using a function
    that can convert it to a builtin data type.
    """
    return dict(__class_name__=str(obj.__class__), __dumped_obj__=
        to_builtin(obj))


def Check_SNP(vcf):
    """Checks whether input variant is a SNP and returns either 0 or 1

    Parameters
    ----------
    vcf : DataFrame
        vcf file with variants of interest

    Returns
    -------
    int
        an integer representation of whether or not a variant is a SNP
    """
    if ',' in vcf['ALT']:
        if len(vcf['REF']) == 1 and (len(vcf['ALT'].split(',')[0]) == 1 or
            len(vcf['ALT'].split(',')[1]) == 1):
            return 1
        else:
            return 0
    elif len(vcf['REF']) == 1 and len(vcf['ALT']) == 1:
        return 1
    else:
        return 0


def delete_files(remove_list):
    """
    # File Deletion Function

    # Description
    Use with caution - will delete certain files

    # Arguments
    # Examples
    """
    import os
    for file in remove_list:
        os.remove(file)


def most_common_words_without_stopwords(text, top=50):
    """
    Returns the frequency of the documents top n words in the text
    :type text: Text
    :param text: The text to be analysed
    :type text: Text
    :param top: int
    :type top: Top n n-grams to evaluate
    :returns Returns list of frequencies
    """
    top_max = min([text.document.words_without_stopwords_frequency.N(), top])
    doc_n_grams = text.document.words_without_stopwords_frequency.most_common(
        top_max)
    n_freq = text.words_without_stopwords_frequency
    feature_vector = []
    for n_gram, freq in doc_n_grams:
        feature_vector.append(0.0 if n_freq.N() == 0 else n_freq[n_gram] /
            n_freq.N())
    if len(feature_vector) != top:
        feature_vector += [0.0] * (top - len(feature_vector))
    return feature_vector


def searchUsersByRequest(request, sort_by=None):
    """Search for users matching a set of criteria found in a request.

        This method will look remove any obvious values from the request
        which are not search criteria. It will also remove any fields
        which have an empty string value.
        Duplicate results returned by PAS are filtered so only the first
        result remains in the result set. The results can be sorted on
        sort_by (case insensitive).
        """


def palettecolor_reveal():
    """Unhide all hidden Grease Pencil palette colors

    """
    pass


def stroke_simplify_fixed(step: int=1):
    """Simplify selected stroked reducing number of points using fixed algorithm

    :param step: Steps, Number of simplify steps
    :type step: int
    """
    pass


def make_map(config):
    """Create, configure and return the routes Mapper."""
    rmap = config['routes.map']
    rmap.connect('oauth2callback', '/oauth2callback', controller=
        'kallithea_auth_google.controllers:GoogleAuthController', action=
        'oauth2callback', condition=dict(method=['GET']))


def allocate(reservations, total=1.0):
    """
    Allocate resources among slices with specified and unspecified reservations.

    Returns a new list of values with the following properties:
    - Every value is >= the corresponding input value.
    - The result sums to `total`.

    Examples:
    allocate([0.25, None, None]) -> [0.5, 0.25, 0.25]
    allocate([0.4, None, None]) -> [0.6, 0.2, 0.2]
    allocate([0.2, 0.2, 0.2]) -> [0.33, 0.33, 0.33]
    allocate([None, None, None]) -> [0.33, 0.33, 0.33]
    allocate([0.5, 0.5, 0.5]) -> ERROR
    """
    n = len(reservations)
    if n <= 0:
        return []
    remaining = total
    for r in reservations:
        if r is not None:
            remaining -= r
    result = list(reservations)
    if remaining > 0:
        share = float(remaining) / n
        for i in range(n):
            if result[i] is None:
                result[i] = share
            else:
                result[i] += share
    elif remaining < 0:
        raise Exception('Resource allocation is infeasible (total {} > {})'
            .format(sum(result), total))
    return result


def _attr_key(attr):
    """Return an appropriate key for an attribute for sorting

    Attributes have a namespace that can be either ``None`` or a string. We
    can't compare the two because they're different types, so we convert
    ``None`` to an empty string first.

    """
    return attr[0][0] or '', attr[0][1]


def find_in_enum_members(item, enum_members: list):
    """Matches a string in the provided list of member strings.
	The item must be not fully matched.
	Rules:
	- If the member string starts with underscore, it is cut out before the matching continues.
	- The item is matched if a member string starts with the item (item is a prefix of the member)."""
    found = None
    for x in enum_members:
        if x.startswith(item):
            found = x
            break
        if x.startswith('_'):
            if x.strip('_').startswith(item):
                found = x
                break
    return found


def viewer_border(xmin: int=0, xmax: int=0, ymin: int=0, ymax: int=0,
    wait_for_input: bool=True, deselect: bool=False, extend: bool=True):
    """Set the boundaries for viewer operations

    :param xmin: X Min
    :type xmin: int
    :param xmax: X Max
    :type xmax: int
    :param ymin: Y Min
    :type ymin: int
    :param ymax: Y Max
    :type ymax: int
    :param wait_for_input: Wait for Input
    :type wait_for_input: bool
    :param deselect: Deselect, Deselect rather than select items
    :type deselect: bool
    :param extend: Extend, Extend selection instead of deselecting everything first
    :type extend: bool
    """
    pass


@classmethod
def register_model(cls, model):
    """
        Register data model.

        :param model: Data model
        :type model: class
        """
    cls.models.add(model)


def repeat(output_m3u, video, times):
    """
    repeat OUT.M3U VIDEO N-TIMES: create playlist consisting of video repeated
    """
    buf = ''
    for i in range(0, int(times)):
        buf += '#EXTINF:0,{}\n'.format(video)
        buf += '{}\n'.format(video)
    with open(output_m3u, 'w') as f:
        f.write('#EXTM3U\n')
        f.write(buf)


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

        :param FileRollbackChangesType val:
        :rtype: EventType
        """
    return cls('file_rollback_changes', val)


@classmethod
def get_from_sale_item(cls, store, sale_item):
    """Get the |workorderitem| given one |saleitem|

        :param store: a store
        :param sale_item: a |saleitem|
        :returns: The |workorderitem| related to the |saleitem|
        :rtype: |workorderitem|
        """
    return store.find(cls, cls.sale_item_id == sale_item.id).one()


def get_major_version():
    """    The major version should always reside within the repository and should
    be incremended when major releases are made.
    """
    major_version = 0
    with open('configs/.major_version', 'a+b') as f:
        try:
            major_version = int(f.read())
        except:
            major_version = 0
            f.seek(0)
            f.write(str(major_version))
            f.truncate()
    return major_version


def create_prefix(nick, user, host):
    """ Builds a prefix based on the nick, user, and host provided. This is essentially the
    opposite to parse_prefix().

        >>> create_prefix("Jack", "~jack", "000-000-000-000.example.com")
        'Jack!~jack@000-000-000-000.example.com'
    """
    return '{0}!{1}@{2}'.format(nick, user, host)


def simulate_principal_policy(actions, resource_arns, role_arn, iam_client):
    """This returns an EvaluationResults object"""
    spp = iam_client.simulate_principal_policy(ActionNames=actions,
        ResourceArns=resource_arns, PolicySourceArn=role_arn)[
        'EvaluationResults']
    return spp


def brush_presets_create():
    """Create a set of predefined Grease Pencil drawing brushes

    """
    pass


@staticmethod
def metadata_id(item):
    """Extracts the identifier from a Bugzilla item."""
    return str(item['id'])


def __init_subclass__(cls, **kwargs):
    """Checks that "type_" is defined and that name of the argument in subclasses __init__ method is the name of
        the "type_" in lowercase. It assures that error in __init__ function of BaseSerializer has a correct message.
        """
    if cls.type_ is None:
        raise AssertionError(
            'Subclass of BaseSerializer has to define class "type_" that is being serialized.'
            )
    if cls.__init__.__code__.co_varnames != ('self', cls.type_.__name__.lower()
        ):
        raise AssertionError(
            'Argument of the __init__ method has to have a name "{}".'.
            format(cls.type_.__name__.lower()))


def logical_and(image1, image2):
    """Logical AND between two images.

    .. code-block:: python

        out = ((image1 and image2) % MAX)

    :rtype: :py:class:`~PIL.Image.Image`
    """
    image1.load()
    image2.load()
    return image1._new(image1.im.chop_and(image2.im))


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

        :param LegalHoldsActivateAHoldDetails val:
        :rtype: EventDetails
        """
    return cls('legal_holds_activate_a_hold_details', val)


@classmethod
def from_x_rotation(cls, theta, dtype=None):
    """Creates a Matrix with a rotation around the X-axis.
        """
    return cls(cls._module.create_from_x_rotation(theta, dtype=dtype))


def write_matrix_to_tsv(net, filename=None, df=None):
    """
  This will export the matrix in net.dat or a dataframe (optional df in
  arguments) as a tsv file. Row/column categories will be saved as tuples in
  tsv, which can be read back into the network object.
  """
    import pandas as pd
    if df is None:
        df = net.dat_to_df()
    return df['mat'].to_csv(filename, sep='\t')


def dbh_triggerlog(path, contenttype, extension, roottag, nsurl):
    """ Generic XML Handler - Returns xml_generic for all XML files """
    if extension == 'tgl':
        return 'db_triggerlog'
    else:
        return False


def find_duplicates(l: list) ->[]:
    """
    Finds duplicate entries in the given list
    :param l: the list to check
    :return: map of (value -> list of indexes)
    """
    if not len(l) != len(set(l)):
        return []
    tmp = {}
    for i, v in enumerate(l):
        if v in tmp.keys():
            tmp[v].append(i)
        else:
            tmp[v] = [i]
    result = {}
    for k, v in tmp.items():
        if len(v) > 1:
            result[k] = v
    return result


@classmethod
def from_json(cls, val):
    """ Create journal reference from JSON

        Args:
            val (:obj:`dict`)

        Returns:
            :obj:`JournalReference`
        """
    return cls(authors=val.get('authors', None), title=val.get('title',
        None), journal=val.get('journal', None), volume=val.get('volume',
        None), issue=val.get('issue', None), pages=val.get('pages', None),
        year=val.get('year', None), doi=val.get('doi', None))


def wasserstein_distance_disc(outb, yb):
    """Assumes you sample a pair of real & fake each time."""
    return (outb - yb).mean()


def __contains__(key):
    """Is the key in the cache?"""


def mule_id():
    """Returns current mule ID. 0 if not a mule (e.g. worker).

    :rtype: int
    """
    return 0


def _set_columns(x, columns):
    """ set the columns attribute of something it is possible

    if columns is None, or x doesn't have an columns attribute it won't do anything

    """
    if columns is None:
        return x
    if hasattr(x, 'columns'):
        x.columns = columns
    return x


def int_addr(addr):
    """Gets the integer representation of an address"""
    return int(addr[1:])


def clean(elementText):
    """
    Given some text from an XML element (which might be None)
        return a stripped value and with internal CRLF characters replaced by spaces.
    """
    if elementText is not None:
        return elementText.strip().replace('\r\n', ' ').replace('\n', ' '
            ).replace('\r', ' ')


@classmethod
def ClearIter(cls):
    """Sets the color iterator to None."""
    cls.color_iter = None
    cls.current_figure = None


def read_len(f):
    """Read a 'LEN' file and return a mapping from chromosome to length"""
    mapping = dict()
    for line in f:
        fields = line.split()
        mapping[fields[0]] = int(fields[1])
    return mapping


def describe_assessment_templates(assessmentTemplateArns=None):
    """
    Describes the assessment templates that are specified by the ARNs of the assessment templates.
    See also: AWS API Documentation

    Examples
    Describes the assessment templates that are specified by the ARNs of the assessment templates.
    Expected Output:

    :example: response = client.describe_assessment_templates(
        assessmentTemplateArns=[
            'string',
        ]
    )

    :type assessmentTemplateArns: list
    :param assessmentTemplateArns: [REQUIRED]
            (string) --

    :rtype: dict
    :return: {
        'assessmentTemplates': [
            {
                'arn': 'string',
                'name': 'string',
                'assessmentTargetArn': 'string',
                'durationInSeconds': 123,
                'rulesPackageArns': [
                    'string',
                ],
                'userAttributesForFindings': [
                    {
                        'key': 'string',
                        'value': 'string'
                    },
                ],
                'createdAt': datetime(2015, 1, 1)
            },
        ],
        'failedItems': {
            'string': {
                'failureCode': 'INVALID_ARN'|'DUPLICATE_ARN'|'ITEM_DOES_NOT_EXIST'|'ACCESS_DENIED'|'LIMIT_EXCEEDED'|'INTERNAL_ERROR',
                'retryable': True|False
            }
        }
    }

    :returns:
    (string) --

    """
    pass


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

        :param SharedLinkSettingsAddExpirationDetails val:
        :rtype: EventDetails
        """
    return cls('shared_link_settings_add_expiration_details', val)


def p_expression_list_empty(p):
    """
    list_of_expressions :
    """
    p[0] = []


def vtk_image_import(*args, **kwargs):
    """Procedural interface for VTKImageImport"""
    import itk
    instance = itk.VTKImageImport.New(*args, **kwargs)
    return instance.__internal_call__()


@staticmethod
def _broadcast(destination, message, **kwargs):
    """Broadcast a message.
        :param destination: Topic name to send to
        :param message: A string to be broadcast
        :param **kwargs: Further parameters for the transport layer. For example
               headers: Optional dictionary of header entries
               expiration: Optional expiration time, relative to sending time
               transaction: Transaction ID if message should be part of a
                            transaction
        """
    raise NotImplementedError('Transport interface not implemented')


def merge_two_dicts(x, y):
    """
    Given two dicts, merge them into a new dict as a shallow copy
    """
    z = x.copy()
    z.update(y)
    return z


def state_add():
    """Add a boid state to the particle system

    """
    pass


@classmethod
def parse(cls, name: str) ->'TaskType':
    """
        Converts JSON string into enum value.

        Parameters
        ----------
        name : str
            JSON string.

        Returns
        -------
        TaskType
            Enum value.
        """
    return cls.get_map()[name]


@classmethod
def from_filename(klass, filename, *, mmap=True, keep_file_open=None):
    """Class method to create image from filename `filename`

        .. deprecated:: 2.4.1
            ``keep_file_open='auto'`` is redundant with `False` and has
            been deprecated. It raises an error as of nibabel 3.0.

        Parameters
        ----------
        filename : str
            Filename of image to load
        mmap : {True, False, 'c', 'r'}, optional, keyword only
            `mmap` controls the use of numpy memory mapping for reading image
            array data.  If False, do not try numpy ``memmap`` for data array.
            If one of {'c', 'r'}, try numpy memmap with ``mode=mmap``.  A
            `mmap` value of True gives the same behavior as ``mmap='c'``.  If
            image data file cannot be memory-mapped, ignore `mmap` value and
            read array from file.
        keep_file_open : { None, True, False }, optional, keyword only
            `keep_file_open` controls whether a new file handle is created
            every time the image is accessed, or a single file handle is
            created and used for the lifetime of this ``ArrayProxy``. If
            ``True``, a single file handle is created and used. If ``False``,
            a new file handle is created every time the image is accessed.
            The default value (``None``) will result in the value of
            ``nibabel.arrayproxy.KEEP_FILE_OPEN_DEFAULT`` being used.

        Returns
        -------
        img : DataobjImage instance
        """
    if mmap not in (True, False, 'c', 'r'):
        raise ValueError("mmap should be one of {True, False, 'c', 'r'}")
    file_map = klass.filespec_to_file_map(filename)
    return klass.from_file_map(file_map, mmap=mmap, keep_file_open=
        keep_file_open)


@staticmethod
def get_attributes(operation, **kwargs):
    """ Get the operation attributes. """
    if operation:
        command = operation.command
        input_obj = operation.input_obj
        context = operation.context
        params = operation.params
    else:
        command = kwargs.pop('command', None)
        input_obj = kwargs.pop('input_obj', None)
        context = kwargs.pop('context', None)
        params = kwargs.pop('params', kwargs)
    return command, input_obj, params, context


def __subclasscheck__(cls, subclass):
    """``issubclass(subclass, cls)``"""
    if cls is subclass:
        return True
    try:
        template = subclass.template
    except AttributeError:
        return False
    else:
        if template == cls.template:
            if cls.specialisations is None:
                return True
            else:
                return cls._subclasscheck_specialisation(subclass)
        return False


def truncate(string, length, ellipsis='…'):
    """ Truncate a string to a length, ending with '...' if it overflows """
    if len(string) > length:
        return string[:length - len(ellipsis)] + ellipsis
    return string


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 populate_vsphere_list(vcs):
    """Populate the gloabl variable holding info on vCenter servers.

    This method must be called before a call to get_vsphere.

    :param list vcs: list of dictionaries, where each dictionary hold the name,
    admin username and password of a vCenter server.
    """
    global vsphere_list
    vsphere_list = vcs


def generate_presigned_url(ClientMethod=None, Params=None, ExpiresIn=None,
    HttpMethod=None):
    """
    Generate a presigned url given a client, its method, and arguments

    :type ClientMethod: string
    :param ClientMethod: The client method to presign for

    :type Params: dict
    :param Params: The parameters normally passed to
            ClientMethod.

    :type ExpiresIn: int
    :param ExpiresIn: The number of seconds the presigned url is valid
            for. By default it expires in an hour (3600 seconds)

    :type HttpMethod: string
    :param HttpMethod: The http method to use on the generated url. By
            default, the http method is whatever is used in the method's model.

    """
    pass


def enum_hook(obj):
    """Hook function passed to json-deserializer as "object_hook".
        EnumEncoder in runhistory/runhistory.
        """
    if '__enum__' in obj:
        name, member = obj['__enum__'].split('.')
        if name == 'StatusType':
            return getattr(globals()[name], member)
    return obj


def _set_static_play_at_home(params, name: str, index: int, value: float):
    """Adjust the Parameters.static_play_at_home parameter"""
    if index is not None:
        raise IndexError('You cannot index the static_play_at_home parameter')
    params.static_play_at_home = value


@classmethod
def get_by_auth_token(cls, user_id, token):
    """Returns a user object based on a user ID and token.

        :param user_id:
            The user_id of the requesting user.
        :param token:
            The token string to be verified.
        :returns:
            A tuple ``(User, timestamp)``, with a user object and
            the token timestamp, or ``(None, None)`` if both were not found.
        """


def is_mutable():
    """Return True if this file or directory is mutable (by *somebody*,
        not necessarily you), False if it is is immutable. Note that a file
        might be mutable overall, but your reference to it might be
        read-only. On the other hand, all references to an immutable file
        will be read-only; there are no read-write references to an immutable
        file.
        """


def linear(t: float) ->float:
    """
    linear easing function

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


def __getattr__(name):
    """Call __getitem__ on context.
        """


@classmethod
def supported(cls, typ):
    """Return True if the type is supported by the field type."""
    return cls.check_type(typ) or cls.check_obj(typ)


def extend_realign_region(row, read_cigar):
    """
    This part is separated from the original modify_realign_region.

    Because minimap use bonus strategy on the splice site, There might be a long deletion or insertion beside the
    splice site. In case to make sure that the realign start do not begin with a deletion or the realign end do not
    end with a insertion and deletion, we need to extend the boundary of the realign region when the case happen.

    Shown as follows:

    Deletion:
    Start:  ... End:
      # @         @ #
    ATGCA       GCTTC
    AT--A       GC--C
        @           @

    Insertion:
    Start:  ... End:
        @           @
    AT--A       GC--C
    ATGCA       GCTTC
      # @         @ #

    The symbol '@' means the original position of ref_start/end (above the sequence) and query_start/end (below the
    sequence); The symbol '#' means the position after modification.
    """
    try:
        left_slice_group = read_cigar.cslice(end_ci=row['realign_start_ci'])[-1
            ]
        if left_slice_group[1] in {'D', 'I'}:
            if left_slice_group[1] == 'D':
                row['realign_start'] -= left_slice_group[0]
            else:
                row['realign_start_rdp'] -= left_slice_group[0]
            if row['realign_start_ci'][1] == 0:
                row['realign_start_ci'] = row['realign_start_ci'][0] - 1, 0
            else:
                row['realign_start_ci'] = row['realign_start_ci'][0], 0
    except IndexError:
        pass
    try:
        right_slice_group = read_cigar.cslice(start_ci=row['realign_end_ci'])[0
            ]
        if right_slice_group[1] in {'D', 'I'}:
            if right_slice_group[1] == 'D':
                row['realign_end'] += right_slice_group[0]
            else:
                row['realign_end_rdp'] += right_slice_group[0]
            row['realign_end_ci'] = row['realign_end_ci'][0] + 1, 0
    except IndexError:
        pass
    return row


def get_user_ack():
    """
    Get the user's acknowledgement to continue.

    Returns: bool
    """
    ack = input('\nContinue [Y/N]? ')
    return ack in ('y', 'Y')


def find_channel(channel_name, source):
    """
    Search for channel by name on the given object
    """
    name = channel_name.lower()
    for channel in source.channels:
        if channel.name.lower() == name:
            return channel
    return None


def outdebug(ui, message):
    """debug regarding output stream (bundling)"""
    if ui.configbool(b'devel', b'bundle2.debug'):
        ui.debug(b'bundle2-output: %s\n' % message)


def write(data):
    """
        The producer will write data by calling this method.

        The implementation must be non-blocking and perform whatever
        buffering is necessary.  If the producer has provided enough data
        for now and it is a L{IPushProducer}, the consumer may call its
        C{pauseProducing} method.
        """


def handle_failure(task_func, task, err):
    """Decide whether to retry a failed task.
    """
    if task.retries >= task_func.retries or not task_func.match_exceptions(err
        ):
        task.failure(err)
    else:
        task.failure(err, retry=True)


def split_training(names_gt, path_train, path_val):
    """Split training and validation images"""
    set_gt = set(names_gt)
    set_train = set()
    set_val = set()
    with open(path_train, 'r') as f_train:
        for line in f_train:
            set_train.add(line[:-1] + '.txt')
    with open(path_val, 'r') as f_val:
        for line in f_val:
            set_val.add(line[:-1] + '.txt')
    set_train = tuple(set_gt.intersection(set_train))
    set_val = tuple(set_gt.intersection(set_val))
    assert set_train and set_val, 'No validation or training annotations'
    return set_train, set_val


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

        :param list of [str] val:
        :rtype: GroupsSelector
        """
    return cls('group_external_ids', val)


def string2list_of_integers(s, separator=', '):
    """Convers a string of integer separated by comma, into a list of integer"""
    arr = []
    if s != '':
        arrs = s.split(separator)
        for a in arrs:
            arr.append(int(a))
    return arr


def roundup2nearestN(x, N=1):
    """Round number :math:`x` up to nearest :math:`N`.

    Parameters
    ----------
    x : int or float
        number to round.
    N : int or float
        number to round :math:`x` up to.

    Returns
    -------
    int or float
        :math:`x` rounded up to nearest :math:`N`.

    """
    from math import ceil
    if isinstance(N, int):
        return int(N * ceil(float(x) / N))
    else:
        return N * ceil(float(x) / N)


def valid_sample(sample):
    """Check whether the sample is valid (not empty and not None).

    :param sample: sample, should be a dict
    """
    return sample is not None and sample != {}


def joinWheres(wone, wtwo, joiner='AND'):
    """
    Take two wheres (of the same format as the C{where} parameter in the function
    L{DBObject.find}) and join them.

    @param wone: First where C{list}

    @param wone: Second where C{list}

    @param joiner: Optional text for joining the two wheres.

    @return: A joined version of the two given wheres.
    """
    statement = ['(%s) %s (%s)' % (wone[0], joiner, wtwo[0])]
    args = wone[1:] + wtwo[1:]
    return statement + args


def interpret_hits(arpA, chu, yjaA, TspE4):
    """ Given boolian int values for these alleles, call basic clermont type
    """
    clermont_key = {'A': [[1, 0, 0, 0]], 'B1': [[1, 0, 0, 1]], 'B2': [[0, 1,
        1, 0], [0, 1, 1, 1]], 'A/C': [[1, 0, 1, 0]], 'D/E': [[1, 1, 0, 0],
        [1, 1, 0, 1]], 'F/G': [[0, 1, 0, 0]], 'B2/G': [[0, 1, 0, 1]],
        'E/cryptic': [[1, 1, 1, 0]], 'cryptic': [[0, 0, 1, 0]], 'U/cryptic':
        [[0, 0, 0, 0]], 'U': [[0, 0, 0, 1], [0, 0, 1, 1], [1, 0, 1, 1], [1,
        1, 1, 1]]}
    isolate_profile = [arpA, chu, yjaA, TspE4]
    for key, value in clermont_key.items():
        for profile in value:
            if profile == isolate_profile:
                return key
    raise ValueError('results profile could not be interpretted! Exiting')


def lookupSenderPolicy(name, timeout=10):
    """
        Perform a SPF record lookup.

        @type name: C{str}
        @param name: DNS name to resolve.

        @type timeout: Sequence of C{int}
        @param timeout: Number of seconds after which to reissue the query.
            When the last timeout expires, the query is considered failed.

        @rtype: L{Deferred}
        @return: A L{Deferred} which fires with a three-tuple of lists of
            L{twisted.names.dns.RRHeader} instances.  The first element of the
            tuple gives answers.  The second element of the tuple gives
            authorities.  The third element of the tuple gives additional
            information.  The L{Deferred} may instead fail with one of the
            exceptions defined in L{twisted.names.error} or with
            C{NotImplementedError}.
        """


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

        :param TfaChangeBackupPhoneDetails val:
        :rtype: EventDetails
        """
    return cls('tfa_change_backup_phone_details', val)


def _flash_encryption_tweak_range(flash_crypt_config=15):
    """ Return a list of the bit indexes that the "key tweak" applies to,
    as determined by the FLASH_CRYPT_CONFIG 4 bit efuse value.
    """
    tweak_range = []
    if flash_crypt_config & 1 != 0:
        tweak_range += range(67)
    if flash_crypt_config & 2 != 0:
        tweak_range += range(67, 132)
    if flash_crypt_config & 4 != 0:
        tweak_range += range(132, 195)
    if flash_crypt_config & 8 != 0:
        tweak_range += range(195, 256)
    return tweak_range


@staticmethod
def apply_zoom(bsca, dval):
    """
        Apply a zoom action to CA class.

        :param bsca:
            :class:`xentica.core.CellularAutomaton` instance.
        :param dval:
            Delta by which the field is zoomed.

        """
    bsca.zoom = max(1, bsca.zoom + dval)


@classmethod
def serialize(cls, value, writer=None):
    """
        Serialize a python object to GraphSON.

        e.g 'P42DT10H5M37S'
        e.g. {'key': value}

        :param value: The python object to serialize.
        :param writer: A graphson serializer for recursive types (Optional)
        """
    serializer = cls.get_serializer(value)
    if serializer:
        return serializer.serialize(value, writer or cls)
    return value


def _del(isamAppliance, uuid):
    """
    Remove all UUIDs - should be everything pertaining to an advanced tuning parameter "key"

    :param isamAppliance:
    :param uuid:
    :return:
    """
    ret_obj = isamAppliance.create_return_object()
    ret_obj['data'] = []
    for u in uuid:
        r = isamAppliance.invoke_delete(
            'Deleting existing advanced tuning parameter',
            '/core/adv_params/{0}'.format(u))
        ret_obj['changed'] = ret_obj['changed'] or r['changed']
        ret_obj['data'].append(r['data'])
        ret_obj['warnings'].extend(r['warnings'])
        ret_obj['rc'] += r['rc']
    return ret_obj


@classmethod
def configure_arggroup(cls, parser):
    """Configure argument parser."""
    pass


def splitLeafletCustomIconType(iconType):
    """
	If iconPrefix is 'custom', iconType is expected to be a string of the form '[marker size]-[font color]-[font size]' or '[marker size]-none'.  This function returns a list of size 3, containing the 3 elements separated by '-'.  Missing elements default to be None.
	"""
    if iconType is None:
        return [None, None, None]
    iconType = str(iconType)
    try:
        iconType = iconType.lower()
    except:
        pass
    iconType.replace(' ', '')
    if '-' in iconType:
        parts = iconType.split('-')
        try:
            parts[0] = float(parts[0])
        except:
            pass
        if len(parts) >= 2:
            if parts[1] == 'none':
                parts[1] = None
        if len(parts) >= 3:
            if parts[2] == 'none':
                parts[2] = None
            else:
                try:
                    parts[2] = float(parts[2])
                except:
                    pass
        else:
            parts.append(None)
        return parts[0:3]
    else:
        try:
            iconType = float(iconType)
        except:
            pass
        return [iconType, None, None]


def _trim_data(ref_data, fields):
    """Trim only fields in dict and return errors."""
    data = {}
    for key in fields:
        data[key] = ref_data[key]
    return data


def root():
    """Return the root of the source tree."""
    raise EnvironmentError('dk.utils.root no longer does anything useful.')


@classmethod
def core_factory(cls, packet_dir=None):
    """Return a MetaSUBTableFactory over core samples."""
    return cls.factory(packet_dir, core=True)


def replace_strings(file_path, replace):
    """
    replace strings in a file

    :param file_path:
    path to file
    :param replace:
    dict of strings to replace. e.g:
    replace = {
        'dummy_app': 'new_app',
        'DummyApp': 'NewApp',
        'dummy-app': 'new-app',
    }
    """
    with open(file_path, 'r') as f:
        s = f.read()
        for item in replace.items():
            s = s.replace(item[0], item[1])
    with open(file_path, 'w') as f:
        f.write(s)


@classmethod
def _create_column_info(cls, name: str, data_type: str) ->dict:
    """
        Create column info object
        :param name: column name
        :param data_type: column data type
        :return: column info object
        """
    return {'name': name, 'type': f'{data_type}'}


def _build_simple_row(padded_cells, rowfmt):
    """Format row according to DataRow format without padding."""
    begin, sep, end = rowfmt
    return (begin + sep.join(padded_cells) + end).rstrip()


def cholesky(u):
    """
    Like :func:`torch.cholesky` but uses sqrt for scalar matrices.
    Works around https://github.com/pytorch/pytorch/issues/24403 often.
    """
    if u.size(-1) == 1:
        return u.sqrt()
    return u.cholesky()


def _populate_style_dict_pce(condition, condition_styles, style_name,
    style_dict, cmap):
    """Transfer styles into condition_styles dict for plot_compare_evokeds."""
    defaults = dict(color='gray', linestyle=(0, ()))
    if condition_styles.get(style_name, None) is None:
        try:
            condition_styles[style_name] = style_dict[condition]
        except KeyError:
            for tag in condition.split('/'):
                try:
                    condition_styles[style_name] = style_dict[tag]
                except KeyError:
                    condition_styles[style_name] = defaults[style_name]
                else:
                    if style_name == 'color' and cmap is not None:
                        condition_styles['cmap_label'] = tag
                    break
    return condition_styles


def hare(votes, seats):
    """Calculate the Hare quota.

    :math:`\\frac{votes}{seats}`

    :param int votes: the number of votes
    :param int seats: the number of seats
    """
    return 1.0 * votes / seats


@staticmethod
def include_is_header(config_file, file_name, include_name):
    """Return True if include name has header extension.

        Keyword arguments:
        config_file -- Config object
        file_name -- file name string
        include_name -- include name string

        Returns true if include name is a header.
        """
    if not config_file.is_header_file(include_name):
        print('Error: ' + file_name + ": include '" + include_name +
            "' has extension not in header list")
        return False
    else:
        return True


def __str__():
    """For a date d, str(d) is equivalent to d.isoformat()."""


def renderCells(item):
    """Render the cells--the contents of a row--for the given item.

        Uses renderCell."""


def nessus_portscan_loopy(var1, reporthost, var2):
    """ Specific Nessus loop to add N open ports to the same address """
    for reportitem in reporthost.findall('ReportItem'):
        if reportitem.get('pluginName') == 'Nessus SYN scanner':
            if var1 == 'addr':
                var2.append(reporthost.get('name'))
            elif var1 == 'port':
                var2.append(reportitem.get('port'))


@classmethod
def table_name(cls, table):
    """
        Produces the sql for a table's name, taking into account aliases.
        """
    name = cls.identifier(table.name)
    if table.alias:
        return cls.format('{} as {}', name, cls.identifier(table.alias))
    return name


def make_regular():
    """Set UVW control points a uniform distance apart

    """
    pass


def csvify_list(list):
    """
    Given a list as an argument, convert it into a CSV line. The list given as
    an argument should be well formatted (the strings should be quoted),
    otherwise, this might end up producing an ambiguous string because of the
    commas
    """
    csv_line = ''
    for item in list:
        csv_line = csv_line + item + ','
    csv_line = csv_line[:-1]
    return csv_line


@staticmethod
def from_dict(source):
    """
        Converts from a dictionary data.
        """
    try:
        return float(source)
    except ValueError:
        return None


@staticmethod
def _log_format_con(window):
    """
        Create an informatinal string for logging leaves.

        Returns:
            str: '<Con: class="{}" instance="{}" title="{}" id={}>'
        """
    return '<Con: class="{}" instance="{}" title="{}" id={}>'.format(window
        .window_class, window.window_instance, window.name, window.id)


def _geometric_mean(phred_values):
    """in case I want geometric mean in the future, can calculate it like this"""
    pass


def is_pickup(df):
    """Return if vehicle is a pickup truck, per NHTSA convention."""
    yr = df['YEAR']
    body = df['BODY_TYP']
    return yr.between(1975, 1981) & (body == 50) | yr.between(1982, 1990
        ) & body.isin([50, 51]) | (1991 <= yr) & body.between(30, 39)


@staticmethod
def translate_rating(rating):
    """
        The workings are obvious
        """
    return rating.replace('>>', '»')


def diff_to_text(_missing_left, _missing_right, _different):
    """Creates a textual representation of the differences

        .. note::
            Not implemented.

    """
    _diff_text = ''
    raise Exception('diff_to_text is not implemented')


def close_workbook(wb, save):
    """
    provides a few conveniences that the client may not want to deal with
        1) if Workbook is the only one in the Excel application, closes the application as well
        2) correctly releases the com pointer for the workbook
    """
    if save and wb.ReadOnly:
        raise AssertionError("'{}' is open as read-only, cannot save and close"
            .format(wb.Name))
    excel_app = wb.Application
    display_alerts = excel_app.DisplayAlerts
    if save:
        wb.Save()
    excel_app.DisplayAlerts = False
    wb.Close()
    wb = None
    if excel_app.Workbooks.Count == 0:
        excel_app.Quit()
        excel_app = None
    else:
        excel_app.DisplayAlerts = display_alerts


def _set_netcdf_grid_mapping_variable(root, grid_mapping):
    """Create grid mapping variable, if necessary."""
    name = grid_mapping.pop('name')
    var = root.createVariable(name, 'S1', dimensions=())
    for attr in grid_mapping.keys():
        setattr(var, attr, grid_mapping[attr])


@staticmethod
def _units_from_X(X):
    """
        Get unit_ids from bst X, or generate them from ndarray X.

        Returns
        -------
        n_units :
        unit_ids :
        """
    raise NotImplementedError


def strip_it(out, rst):
    """clumsy way to strip at start at end, including color resets"""
    sc = {' ': 1, rst: len(rst), '\n': 1}
    while 1:
        m = False
        for k in sc:
            if out.startswith(k):
                out = out[sc[k]:]
                m = True
            if out.endswith(k):
                out = out[:-sc[k]]
                m = True
            if m:
                break
        if not m:
            break
    return out


def moving_avg(xyw, avg_len):
    """
    Calculate a moving average for a given averaging length
    :param xyw: output from collapse_into_single_dates
    :type xyw: dict
    :param avg_len: average of these number of points, i.e., look-back window
    :type avg_len: int
    :return: list of x values, list of y values
    :rtype: tuple
    """
    cumsum, moving_aves, x_final = [0], [], []
    for i, y in enumerate(xyw['y'], 1):
        cumsum.append(cumsum[i - 1] + y / xyw['w'][i - 1])
        if i >= avg_len:
            moving_ave = (cumsum[i] - cumsum[i - avg_len]) / avg_len
            moving_aves.append(moving_ave)
    x_final = [xyw['x'][i] for i in range(avg_len - 1, len(xyw['x']))]
    return x_final, moving_aves


def pre_hook():
    """A plugin hook called in the first initialization step.

        This is called before the database is initialized.
        """


def hour_minute(v):
    """Convert 7.5 (hours) to (7, 30) i.e. 7 hours and 30 minutes."""
    h = int(v)
    m = int((v - h) * 60)
    return h, m


def _write_device(out, device):
    """Write a single device to file."""
    attributes = []
    if device.name is not None:
        attributes.append(f'name: {device.name}')
    if device.tracking_device_id is not None:
        attributes.append(f'tracking_device_id: {device.tracking_device_id}')
    if device.disabled:
        attributes.append('disabled: True')
    out.write(device.push_id)
    out.write(': {')
    if attributes:
        separator = ', '
        out.write(separator.join(attributes))
    out.write('}\n')


def build_url(port, host):
    """
    Returns full url combining host(if not specified will use the output of :func:`python:socket.gethostname`) & port

    :param port: integer string for the port to be used by the :class:`flask:flask.Flask` process
    :type port: str
    :param host: hostname, can start with 'http://', 'https://' or just the hostname itself
    :type host: str, optional
    :return: str
    """
    final_port = ':{}'.format(port) if port is not None else ''
    if (host or '').startswith('http'):
        return '{}{}'.format(host, final_port)
    return 'http://{}{}'.format(host, final_port)


@classmethod
def enable(cls):
    """Enables the accessibility domain which causes `AXNodeId`s to remain consistent between method calls.
This turns on accessibility for the page, which can impact performance until accessibility is disabled.
        """
    return cls.build_send_payload('enable', {}), None


@staticmethod
def _from_db_object(nodegroup, db_nodegroup):
    """Converts a database entity to a formal object."""
    for field in nodegroup.fields:
        nodegroup[field] = db_nodegroup[field]
    nodegroup.obj_reset_changes()
    return nodegroup


@classmethod
def register(cls, request_handler, name, apptable_name):
    """Register a datatable with an app table

        :param request_handler:
        :param name:
        :param apptable_name:
        :return: bool
        """
    data = request_handler.make_request('POST',
        '/datatables/register/{}/{}'.format(name, apptable_name))
    return data['resourceIdentifier'] == name


def _select_closest(to_search_df, target_series):
    """
    Find row in ``to_search_df`` that is closest to the target array.

    Here, 'closest' is in the root-mean squared sense. In the event that multiple rows
    are equally close, returns first row.

    Parameters
    ----------
    to_search_df : :obj:`pd.DataFrame`
        The rows of this dataframe are the candidate closest vectors

    target_series : :obj:`pd.Series`
        The vector to which we want to be close

    Returns
    -------
    dict
        Metadata of the closest row.
    """
    if len(target_series.shape) != 1:
        raise ValueError('Target array is multidimensional')
    if target_series.shape[0] != to_search_df.shape[1]:
        raise ValueError(
            'Target array does not match the size of the searchable arrays')
    closeness = []
    for label, row in to_search_df.iterrows():
        rms = ((target_series - row) ** 2).mean() ** 0.5
        closeness.append((label, rms))
    labels, rmss = list(zip(*closeness))
    to_return = rmss.index(min(rmss))
    return dict(zip(to_search_df.index.names, labels[to_return]))


def _calculate_chi_squared(source_freq, target_prob, source_len):
    """A measure of the observed frequency of the symbol versus the expected frequency.
    If the value is 0 then the texts are exactly alike for that symbol.
    """
    expected = source_len * target_prob
    return (source_freq - expected) ** 2 / expected


@classmethod
def calculate_energy_loss_function(cls, dielectric):
    """ Calculate energy loss function for a complex spectrum image

        :type  dielectric: np.ndarray
        :param dielectric: the complex dielectric matrix

        :returns: the energy loss matrix
        """
    return dielectric.imag / (dielectric.real ** 2 + dielectric.imag ** 2)


@staticmethod
def getBinDir(virtualenvDirectory):
    """
            getBinDir - Gets the "bin" dir of a virtualenv
                i.e. the directory that contains executables.

            NOTE: This is overridden on import with the platform-specific version.

            @param virtualenvDirectory <str> - The path to the root directory of the virtualenv

            @return <str> - Path to the "bin" directory of the virtualenv
        """
    raise NotImplementedError(
        'getBinDir should have been overridden by platform-specific version.')


@staticmethod
def _parseChangesFile(linesIter):
    """A generator that iterates over files listed in a changes file.

        :param linesIter: an iterable of lines in a changes file.
        """
    seenfiles = False
    for line in linesIter:
        if line.endswith('\n'):
            line = line[:-1]
        if not seenfiles and line.startswith('Files:'):
            seenfiles = True
        elif seenfiles:
            if not line.startswith(' '):
                break
            filename = line.split(' ')[-1]
            yield filename


def _joinregexes(regexps):
    """gather multiple regular expressions into a single one"""
    return b'|'.join(regexps)


def matrix_to_phylip(filename, leaves, matrix):
    """Write the distance matrix in phylip format."""
    with open(filename, 'w') as f:
        f.write(str(len(leaves)))
        for i in range(len(leaves)):
            f.write('\n' + str(leaves[i].ID))
            for j in range(len(leaves)):
                f.write('\t' + str(matrix[i, j]))


@classmethod
def available(cls):
    """returns True if OSS output is available on the system"""
    try:
        import ossaudiodev
        ossaudiodev.open('w').close()
        return True
    except (ImportError, IOError):
        return False


def aggregate(table, metrics=None, by=None, having=None, **kwds):
    """
    Aggregate a table with a given set of reductions, with grouping
    expressions, and post-aggregation filters.

    Parameters
    ----------
    table : table expression
    metrics : expression or expression list
    by : optional, default None
      Grouping expressions
    having : optional, default None
      Post-aggregation filters

    Returns
    -------
    agg_expr : TableExpr
    """
    if metrics is None:
        metrics = []
    for k, v in sorted(kwds.items()):
        v = table._ensure_expr(v)
        metrics.append(v.name(k))
    op = table.op().aggregate(table, metrics, by=by, having=having)
    return op.to_expr()


def calculate_parent_daughter_ratio(morphology, node_types, root=None):
    """
        Compute the average ratio of parent node to daughter node at
        each branch point.

        Parameters
        ----------

        morphology: Morphology object

        node_types: list (AXON, BASAL_DENDRITE, APICAL_DENDRITE)
        Type to restrict search to

        root: dict
        This is the node from which to analyze parent-daughter ratio under.
        When root=None, the soma is used.

        Returns
        -------

        Scalar value

    """
    nodes = morphology.get_node_by_types(node_types)
    if root is None:
        root = morphology.get_root()
    ratio_sum = 0.0
    n = 0
    try:
        for parent in nodes:
            if len(morphology.children_of(parent)) > 1:
                for daughter in morphology.children_of(parent):
                    ratio = daughter['radius'] / parent['radius']
                    ratio_sum += ratio
                    n += 1
    except ZeroDivisionError:
        n = 0
    if n == 0:
        return float('nan')
    return 1.0 * ratio_sum / n


@staticmethod
def convert_cli_output_to_wsapi_format(cli_output):
    """Convert CLI output into a response that looks the WS-API would.

        Use the first line as coma-separated headers.
        Build dictionaries for the remaining lines using the headers as keys.
        Return a dictionary with total and members (the dictionaries).

        If there isn't enough data for headers and data then
        total is 0 and members is an empty list.

        If you need more validity checking, you might want to do it before this
        generic routine.  It does minimal checking.

        :param cli_output: The result from the CLI (i.e. from ssh.run(cmd)).
                           The first row is headers. Following rows are data.
        :type cli_output: list

        .. code-block:: python

            # Example 1: Typical CLI output with header row and data rows.
            cli_output =
                [
                    'InstallTime,Id,Package,Version',
                    '2013-08-21 18:06:45 PDT,MU2,Complete,3.1.2.422',
                    '2013-10-10 15:20:05 PDT,MU3,Complete,3.1.2.484',
                    '2014-01-30 11:34:20 PST,DEVEL,Complete,3.1.3.170',
                    '2014-03-26 13:59:42 PDT,GA,Complete,3.1.3.202',
                    '2014-06-06 14:46:56 PDT,MU1,Complete,3.1.3.230'
                ]

            # Example 2: Example CLI output for an empty result.
            cli_output = ['No patch is applied to the system.']

        :returns: dict with total and members. members is list of dicts using
                  header for keys and data for values.
        :rtype: dict

        .. code-block:: python

            # Example 1: Converted to total and members list of dictionaries.
            ret = {
                'total': 5,
                'members': [
                    {
                        'Package': 'Complete',
                        'Version': '3.1.2.422',
                        'InstallTime': '2013-08-21 18:06:45 PDT',
                        'Id': 'MU2'
                    },
                    {
                        'Package': 'Complete',
                        'Version': '3.1.2.484',
                        'InstallTime': '2013-10-10 15:20:05 PDT',
                        'Id': 'MU3'
                    },
                    {
                        'Package': 'Complete',
                        'Version': '3.1.3.170',
                        'InstallTime': '2014-01-30 11:34:20 PST',
                        'Id': 'DEVEL'
                    },
                    {
                        'Package': 'Complete',
                        'Version': '3.1.3.202',
                        'InstallTime': '2014-03-26 13:59:42 PDT',
                        'Id': 'GA'
                    },
                    {
                        'Package': 'Complete',
                        'Version': '3.1.3.230',
                        'InstallTime': '2014-06-06 14:46:56 PDT',
                        'Id': 'MU1'
                    }
                ]
            }

            # Example 2: No data rows, so zero members.
            ret = {'total': 0, 'members': []}

        """
    members = []
    if cli_output and len(cli_output) >= 2:
        for index, line in enumerate(cli_output):
            if index == 0:
                headers = line.split(',')
            else:
                split = line.split(',')
                member = {}
                for i, header in enumerate(headers):
                    try:
                        member[header] = split[i]
                    except IndexError:
                        member[header] = None
                members.append(member)
    return {'total': len(members), 'members': members}


def parse_args():
    """Parse arguments."""
    import argparse
    parser = argparse.ArgumentParser('check_copyright_notice')
    parser.add_argument('--directory', type=str, default='.', help=
        'The path to the repository root.')


def stringified_dict_contains_value(key, value, str_dict):
    """Checks if dict in for of string like "{'test': 5}" contains
    key/value pair. This works faster, then creating actual dict
    from string since this operation is called for each task in case
    of kwargs search."""
    value = str(value)
    try:
        key_index = str_dict.index(key) + len(key) + 3
    except ValueError:
        return False
    try:
        comma_index = str_dict.index(',', key_index)
    except ValueError:
        comma_index = str_dict.index('}', key_index)
    return str(value) == str_dict[key_index:comma_index].strip('"\'')


@staticmethod
def get_or_create_dict(d: dict, inner_dict_key):
    """
        Checks if another dictionary inside the dictionary exists or not. If does not exist it creates one. In either
        case it returns the dict
        """
    if inner_dict_key not in d:
        d[inner_dict_key] = dict()
    return d[inner_dict_key]


@staticmethod
def _filter(data_array):
    """
        Basic filter. Not a filter. Just a generator for the given data.
        """
    i = 0
    while True:
        try:
            yield data_array[i]
        except IndexError:
            break
        i += 1


def _format_ipv6(a):
    """
        Format IPv6 address (from tuple of 16 bytes) compressing sequence of
        zero bytes to '::'. Ideally we would use the ipaddress module in
        Python3.3 but can't rely on having this.

        >>> _format_ipv6([0]*16)
        '::'
        >>> _format_ipv6(_parse_ipv6("::0012:5678"))
        '::12:5678'
        >>> _format_ipv6(_parse_ipv6("1234:0:5678::ff:0:1"))
        '1234:0:5678::ff:0:1'
    """
    left = []
    right = []
    current = 'left'
    for i in range(0, 16, 2):
        group = (a[i] << 8) + a[i + 1]
        if current == 'left':
            if group == 0 and i < 14:
                if (a[i + 2] << 8) + a[i + 3] == 0:
                    current = 'right'
                else:
                    left.append('0')
            else:
                left.append('%x' % group)
        elif group == 0 and len(right) == 0:
            pass
        else:
            right.append('%x' % group)
    if len(left) < 8:
        return ':'.join(left) + '::' + ':'.join(right)
    else:
        return ':'.join(left)


def get_feature_size_by_class(df, class_col, features, normalize='class'):
    """
    Given pandas.DataFrame, class column name, and feature column
    name, return:

        - pd.crosstab(df.class_col, df.feature).stack()

    Works differently from `pandas.crosstab` if multiple features passed.
    Note that this function makes the most sense for categorical
    features.

    Parameters
    ----------

    df : pandas.DataFrame
        DataFrame on which this function will operate.

    class_col : str
        Column name for the class / target.

    features : str or list
        Column name(s) for the feature.

    normalize : str, "class" or "all" or None (default="class")
        Whether to normalize counts. "class" means normalize counts within a
        class value by the total counts in that group. "all" means normalize
        by the length of `df`. `None` means do not normalize.

    Return
    ------

    pandas.DataFrame of size figures.
    """
    if isinstance(features, str):
        features = [features]
    elif not isinstance(features, list):
        raise TypeError('Must pass str or list for `features`.')
    to_group_by = [class_col] + features
    to_return = df[to_group_by].groupby(to_group_by).size().rename('cnt'
        ).to_frame()
    if normalize == 'all':
        to_return = (to_return / len(df)).rename(columns={'cnt': 'ratio'})
    elif normalize == 'class':
        denominators = to_return.groupby(level=0).sum().rename(columns={
            'cnt': 'cnt_cls_val'}).reset_index()
        to_return = to_return.reset_index().merge(denominators, on=class_col
            ).set_index(to_group_by)
        to_return = to_return.cnt.divide(to_return.cnt_cls_val).rename('ratio'
            ).to_frame()
    elif normalize is None:
        pass
    else:
        raise ValueError('Improper value passed for `normalize`.')
    return to_return


def normalize(a):
    """Normalize a distribution.

    Args:
        a (np.ndarray): The array to normalize.

    Returns:
        np.ndarray: ``a`` normalized so that the sum of its entries is 1.
    """
    sum_a = a.sum()
    if sum_a == 0:
        return a
    return a / sum_a


@staticmethod
def is_freshen_test(test):
    """
        checks for tell tale signs of being a fresher test
        """
    return test.address()[1] == 'fresher.noseplugin'


def remote_shortname(socket):
    """
    Obtains remote hostname of the socket and cuts off the domain part
    of its FQDN.
    """
    return socket.gethostname().split('.', 1)[0]


def unique_sequence_list(bio_record):
    """checks a biopython seq list for dublicates"""
    unique_seq_list = []
    unique_rec_list = []
    for rec in bio_record:
        if rec.seq in unique_seq_list:
            print(rec.id + rec.name + rec.description +
                ' sequence is a dublicate and thefore discarded')
        else:
            unique_seq_list.append(rec.seq)
            unique_rec_list.append(rec)
    return unique_rec_list


def view_all_preview():
    """Zoom preview to fit in the area

    """
    pass


def unique(items):
    """Yield items from *item* in order, skipping duplicates."""
    seen = set()
    for item in items:
        if item in seen:
            continue
        else:
            yield item
            seen.add(item)


def _get_keywords():
    """Returns a list of the currently valid keywords for the AFLUX API.
    """
    from six.moves import urllib
    import json
    urlopen = urllib.request.urlopen
    url = 'http://aflowlib.duke.edu/search/API/?schema'
    r = urlopen(url).read().decode('utf-8')
    return json.loads(r)


def last(element):
    """
    A wrapper around element[-1].

    params:
        element: an element that implements __getitem__
    """
    return element[-1]


@classmethod
def get_allowed_carriers_domain(cls):
    """This method returns domain to seach allowed carriers

        Downstream modules can inherit and update customize this domain.
        """
    return []


@staticmethod
def _change_entity_name(tree, elem_map, name):
    """
        Adds numbering to identical element names where their odml.Section
        or odml.Property parents reside on the same level in the tree.

        :param tree: The element tree containing the 'name' element.
        :param elem_map: lxml path to occurrence maps of named Sections or Properties.
        :param name: lxml element containing the name text of a Section or Property.
        """
    named_path = '%s:%s' % (tree.getpath(name.getparent().getparent()),
        name.text)
    if named_path not in elem_map:
        elem_map[named_path] = 1
    else:
        elem_map[named_path] += 1
        name.text += '-' + str(elem_map[named_path])


def func_eq_all(parser, x, *args):
    """
    Return True if all string are equal.
    $eq_all(a,b,c ...) is functionally equivalent to $and($eq(a,b),$eq(a,c) ...)
    Example: $if($eq_all(%albumartist%,%artist%,Justin Bieber),$set(engineer,Meat Loaf))
    """
    for i in args:
        if x != i:
            return ''
    return '1'


def get_raw_sequence(alignment: bytes, len_read_name: int,
    number_cigar_operations: int, len_sequence: int) ->bytes:
    """Extract the raw sequence from a BAM alignment bytestring

    Parameters
    ----------
    alignment : bytes
        A byte string of a bam alignment entry in raw binary format

    len_read_name : int
        The length of the readname string
        eg from pylazybam.bam.get_len_read_name()

    number_cigar_operations : int
        The number of cigar operations
        eg from pylazybam.bam.get_number_cigar_operations()

    len_sequence : int
        The length of the sequence and quality score strings
        eg from pylazybam.bam.get_len_sequence

    Returns
    -------
    bytes
        The raw sequence in BAM format as a binary bytestring

    """
    start = 36 + len_read_name + 4 * number_cigar_operations
    end = start + (len_sequence + 1) // 2
    return alignment[start:end]


def p_error(p):
    """Error rule for syntax errors"""
    print('Syntax error at input! {0}'.format(str(p)))


def create_uniform_prior_for(parameter):
    """
	Use for location variables (position)
	The uniform prior gives equal weight in non-logarithmic scale.

	:param parameter: Parameter to create a prior for. E.g. xspowerlaw.mypowerlaw.PhoIndex
	"""
    spread = parameter.max - parameter.min
    low = parameter.min
    return lambda x: x * spread + low


@classmethod
def get_default_timeout(cls):
    """
        Configuration classmethod: returns the time in seconds for Selenium to wait for
        the browser to respond. Default so ``default_timeout`` attribute.
        """
    return cls.default_timeout


def dict_to_sequence(d):
    """Returns an internal sequence dictionary update."""
    if hasattr(d, 'items'):
        d = d.items()
    return d


@classmethod
def reset(cls):
    """Reset the signal logs and return last signal `(signum, frame, time)`.
        """
    res = None
    with cls._lock:
        if hasattr(cls, '_last_signal'):
            res = cls._last_signal
            del cls._last_signal
        cls._signals_raised = {}
    return res


def extract_repeated_attr(param, field):
    """
    Extract a particular field defined as a RepeatedContainer

    Parameters
    ----------
    param : parameter object
       Various parameter objects defined by Google messages.
    field : string
       Parameter field.

    Notes
    -----
    Only the first value is returned.

    Returns
    -------
    string or None
        Field value or None if parameter or field doesn't exist.

    """
    tmpval = getattr(param, field, None)
    if tmpval is not None:
        if isinstance(tmpval, (float, int, bool)):
            y = tmpval
        elif len(tmpval) > 0:
            y = tmpval[0]
        else:
            y = None
        return y
    else:
        return None


def apply_if_valid(name, trial, callback=None, raise_if_not=True):
    """Detect a parameter in trial and call a callback on it if provided

    Parameters
    ----------
    name: str
        Name of the param to look for
    trial: `orion.core.worker.trial.Trial`
        Instance of trial to investigate
    callback: None of callable
        Function to call with (trial, param) with a parameter is found.
        Defaults to None
    raise_if_not: bool
        raises RuntimeError if no parameter is found.
        Defaults to True.

    Returns
    -------
    bool
        False if parameter is not found and `raise_if_not is False`.
        True if parameter is found and callback is None.
        Else, output of callback(trial, item).

    """
    for param in trial.params:
        if param.name == name:
            return callback is None or callback(trial, param)
    if raise_if_not:
        raise RuntimeError(
            """Provided trial does not have a compatible configuration. A dimension named '%s' should be present.
 %s"""
             % (name, trial))
    return False


def select_linked():
    """Select all control points linked to active one

    """
    pass


@staticmethod
def _needed_packages():
    """
        List of needed packages
        :return:
        """
    return []


@classmethod
def has_resuming(cls):
    """Returns whether it supports to resume the fetch process.

        :returns: this backend supports items resuming
        """
    return True


def pairwise(iterable):
    """
    break a list (or other iterable) into pairs

    ::

		s -> (s0, s1), (s2, s3), (s4, s5), ...

		In [71]: for item in pairwise("a b c d e fg".split()):
			...:     print(item)
			...:
		('a', 'b')
		('c', 'd')
		('e', 'fg')

    """
    a = iter(iterable)
    return zip(a, a)


def julian(mon, day, year):
    """
    returns julian day
    """
    ig = 15 + 31 * (10 + 12 * 1582)
    if year == 0:
        print('Julian no can do')
        return
    if year < 0:
        year = year + 1
    if mon > 2:
        julian_year = year
        julian_month = mon + 1
    else:
        julian_year = year - 1
        julian_month = mon + 13
    j1 = int(365.25 * julian_year)
    j2 = int(30.6001 * julian_month)
    j3 = day + 1720995
    julian_day = j1 + j2 + j3
    if day + 31 * (mon + 12 * year) >= ig:
        jadj = int(0.01 * julian_year)
        julian_day = julian_day + 2 - jadj + int(0.25 * jadj)
    return julian_day


def remove(object):
    """Remove a relationship from the container"""


def clean_first_markers(res):
    """
    In the event that a ToC was found, this will remove every first entry in the values of res. That means that all the
    location related to the titles in the ToC will be removed.

    :param res: dict, keys are sections to parse and contain the locations where the titles were found in the text.
    :return: Filtered version of res without the ToC locations
    """
    sections = list(res.keys())
    for idx in range(len(sections) - 1):
        counter_delete = 0
        for markers in res[sections[idx + 1]]:
            if markers[0] < res[sections[idx]][0][1]:
                counter_delete += 1
            else:
                break
        for _ in range(counter_delete):
            del res[sections[idx + 1]][0]
    return res


def edge_split():
    """Split selected edges so that each neighbor face gets its own copy

    """
    pass


def get_type(h_node):
    """ Helper function to return the py_type for a HDF node """
    py_type = h_node.attrs['type'][0]
    return py_type


def enable_lazy():
    """Convenience function for configuring _() to use lazy gettext

    Call this at the start of execution to enable the gettextutils._
    function to use lazy gettext functionality. This is useful if
    your project is importing _ directly instead of using the
    gettextutils.install() way of importing the _ function.
    """
    global USE_LAZY
    USE_LAZY = True


def flip_y_coord(zoom, y):
    """Flips y (int) coordinate for given zoom (int).

    >>> flip_y_coord(12, 3281)
    814
    >>> flip_y_coord(12, 814)
    3281
    """
    return 2 ** zoom - 1 - y


def p_object_property(p):
    """object_property : variable_name object_dim_list
                       | variable_without_objects"""
    if len(p) == 3:
        p[0] = p[1], p[2]
    else:
        p[0] = p[1], []


def find_dividend_by_unit(time):
    """Finds whether time best corresponds to a value in
    days, hours, minutes, or seconds.
    """
    for dividend in [86400, 3600, 60]:
        div = time / dividend
        if round(div) == div:
            return dividend
    return 1


@staticmethod
def get_status(instance):
    """
        Returns the status of a VM instance
        provisioning | staging | running | stopping |
        stopped | suspending | suspended | terminated
        """
    return instance['status'].lower()


def newTransaction(transaction):
    """Hook that is called at the start of a transaction.

        This hook is called when, and only when, a transaction manager's
        `~ITransactionManager.begin` method is called explicitly.
        """


def BoundaryToCentre(bin_bounds):
    """
    BoundaryToCentre - converts coordinates for edges of bins to centre of bin coordinates

    Parameters
    ----------
        bin_bounds: 1d np array
                    Edge coordinates of each bin

    Returns
    -------
        bin_centres: 1d np narray of length 1 less than bin_bounds
                    Coordinates at centre of bin
    """
    half_width = (bin_bounds[1] - bin_bounds[0]) / 2
    bin_centers = bin_bounds[:len(bin_bounds) - 1] + half_width
    return bin_centers


def grammarJoin(l, sep=', ', lastSep=' and '):
    """Joins list p_l with p_sep, excepted the last 2 elements that are joined
       with p_lastSep. grammarJoin(["a", "b", "c"]) produces "a, b and c"."""
    r = ''
    i = 0
    last = len(l) - 1
    for elem in l:
        if i == last:
            curSep = ''
        elif i == last - 1:
            curSep = lastSep
        else:
            curSep = sep
        r += elem + curSep
        i += 1
    return r


def string_bool(argument):
    """
    Converts True, true, False, False in python boolean values
    """
    if argument is None:
        msg = (
            'argument required but none supplied; choose from "True" or "False"'
            )
        raise ValueError(msg)
    elif argument.lower() == 'true':
        return True
    elif argument.lower() == 'false':
        return False
    else:
        raise ValueError('"%s" unknown; choose from "True" or "False"' %
            argument)


def inDS(s):
    """ chooses a dataset we'll call inDS; others will become secondaryDS """
    if s.primaryds:
        return s.primaryds
    else:
        return s.input_datasets()[0]


def remove_illegal_characters(src):
    """
        remove_illegal_characters()
        ________________________________________________________________________

        Replace some illegal characters by the underscore character. Use this function
        to create files on various plateforms.
        ________________________________________________________________________

        PARAMETER
                o src   : (str) the source string

        RETURNED VALUE
                the expected string, i.e. <src> without illegal characters.
    """
    res = src
    for char in ('*', '/', '\\', '.', '[', ']', ':', ';', '|', '=', ',',
        '?', '<', '>', '-', ' '):
        res = res.replace(char, '_')
    return res


def getRecordListUnzipped(vcf_reader, prev_last_rec, region=None, chrom=
    None, start=None, end=None, add_chr=False):
    """Method for getting record list from unzipped VCF file.

    This method will sequentially look through a VCF file until it finds
    the given `start` position on `chrom`, then add all records to a list
    until the `end` position has been reached. Note that `prev_last_rec`
    must be kept track of externally to ensure that if consecutive regions
    are called, the record of the first variant outside the first region
    is not lost.

    Parameters
    ----------
    vcf_reader : pysam VariantFile object
        VCF reader initialized from other function
    region : region object
        Region object with start and end coordinates of region of interest.
    prev_last_rec : VariantRecord object
        Variable with last record read from VcfReader. Stored here so that
        if two adjacent regions are called, the overflow record from the
        first region is still included in the next region

    Returns
    -------
    lst : list
        List of records in given gene region
    prev_last_rec : VariantRecord object
        First record after target region, for use in next call

    """
    lst = []
    if region is None:
        for rec in vcf_reader:
            lst.append(rec)
        return lst, lst[-1]
    if prev_last_rec is not None and region.containsRecord(prev_last_rec
        ) == 'in':
        lst.append(prev_last_rec)
    elif prev_last_rec is not None and region.containsRecord(prev_last_rec
        ) == 'after':
        return []
    rec = next(vcf_reader, None)
    if rec is None:
        return lst, None
    place = region.containsRecord(rec)
    while rec is not None and place != 'after':
        if place == 'in':
            lst.append(rec)
        rec = next(vcf_reader, None)
        if rec is None:
            break
        place = region.containsRecord(rec)
    prev_last_rec = rec
    return lst, prev_last_rec


def explain_all_succ(fsm, state, sat):
    """
    Give all the successors of state belonging to sat.
    The returned value is a set of tuples (action, successor)
    where successor is a successor of state through action belonging to sat.

    fsm -- the fsm;
    state -- a state of fsm able to reach sat in one step;
    sat -- a BDD representing a set of states of fsm.
    """
    successors = set()
    for next in fsm.pick_all_states(fsm.post(state) & sat):
        inputs = fsm.pick_one_inputs(fsm.get_inputs_between_states(state, next)
            )
        successors.add((inputs, next))
    return successors


def _join_str(d, k, v):
    """Add a string value to env dict"""
    d[k] = str(v)


def safe_issubclass(*args):
    """Like issubclass, but will just return False if not a class."""
    try:
        if issubclass(*args):
            return True
    except TypeError:
        pass
    return False


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

    The ".dev0" means dirty.

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


@classmethod
def copy(cls, other):
    """Create a copy of another shape."""
    result = cls(**other._attributes)
    return result


def compress_dataset(ds):
    """
    Apply internal netCDF4 compression
    """
    for var in ds.data_vars:
        ds[var].encoding['zlib'] = True
    return ds


def _gutter(idx, offset, max_val):
    """
    When deleting rows and columns are deleted we rely on overwriting.
    This may not be the case for a large offset on small set of cells:
    range(cells_to_delete) > range(cell_to_be_moved)
    """
    gutter = range(max(max_val + 1 - offset, idx), min(idx + offset,
        max_val) + 1)
    return gutter


def next_run_iso_format(next_run):
    """
    Convert next run timestamp object to the ISO format
    """
    if isinstance(next_run, bool):
        next_run = None
    else:
        next_run = next_run.isoformat()


def echo_command(*inp):
    """Print all the words that were passed on the command line

	This is just a simple echo command.
	"""
    print(' '.join(inp))