def pseudorandom(n, p, random_state=None):
    """ Pseudorandom array of integer indexes

    >>> pseudorandom(5, [0.5, 0.5], random_state=123)
    array([1, 0, 0, 1, 1], dtype=int8)

    >>> pseudorandom(10, [0.5, 0.2, 0.2, 0.1], random_state=5)
    array([0, 2, 0, 3, 0, 1, 2, 1, 0, 0], dtype=int8)
    """
    import numpy as np
    p = list(p)
    cp = np.cumsum([0] + p)
    assert np.allclose(1, cp[-1])
    assert len(p) < 256
    if not isinstance(random_state, np.random.RandomState):
        random_state = np.random.RandomState(random_state)
    x = random_state.random_sample(n)
    out = np.empty(n, dtype='i1')
    for i, (low, high) in enumerate(zip(cp[:-1], cp[1:])):
        out[(x >= low) & (x < high)] = i
    return out


def gen_write_file(out_filepath, generator_source):
    """
    Writes generator output to a file.
    :param out_filepath: File to write
    :param generator_source: Generator to consume from
    :return: None
    """
    with open(out_filepath, 'w') as f:
        for item in generator_source:
            f.write(str(item))


def is_in_range(val, range_min, range_max):
    """
    Checks if the specified value is within the given range.
    :param (int, float) val: Value to be evaluated.
    :param (int, float) range_min: Range lower value.
    :param (int, float) range_max: Range higher value.
    :return: Returns true if the value is within the range and false otherwise.
    :rtype: bool
    """
    return True if range_min <= val <= range_max else False


def _seasonID(x):
    """takes in 4-digit years and returns API formatted seasonID

    Input Values: YYYY

    Used in:

    """
    if len(str(x)) == 4:
        try:
            return ''.join(['2', str(x)])
        except ValueError:
            raise ValueError(
                'Enter the four digit year for the first half of the desired season'
                )
    else:
        raise ValueError(
            'Enter the four digit year for the first half of the desired season'
            )


@staticmethod
def judge_postag(netag):
    """根据命名实体识别结果判断该连接实体的词性标注
        Args:
            netag: string，该词的词性标注
        Returns:
            entity_postag: string，判别得到的该连接实体的词性
        """
    entity_postag = ''
    if '-Ns' in netag:
        entity_postag = 'ns'
    elif '-Ni' in netag:
        entity_postag = 'ni'
    elif '-Nh' in netag:
        entity_postag = 'nh'
    return entity_postag


@staticmethod
def set_node_vertical_alignment_property(node_properties, valign):
    """Set the vertical alignment of label in node_properties.

		Args:
			node_properties (dict): Dictionary of node attributes. Key-value pairs will be used to set data associated with the node.
			valign (str): Vertical alignment of text.

		Returns:
			dict: Dictionary of node attributes.
		"""
    node_properties.update({'text-valign': valign})
    return node_properties


@classmethod
def addch(cls, c, x=None, y=None, attr=None):
    """
        Add a character to a position on the screen or at cursor.

        :param c: the character to insert
        :param x: optional x value, or current x position
        :param y: optional y value, or current y position
        :param attr: optional attribute, like 'bold'
        """
    attr = cls._fix_attr(attr)
    x, y = cls._fix_xy(x, y)
    if isinstance(c, int):
        c = chr(c)
    if attr is None:
        return cls.WINDOW.addch(y, x, c)
    else:
        return cls.WINDOW.addch(y, x, c, attr)


@classmethod
def to_yaml(cls, instance):
    """Serialize release to an YAML node."""
    return instance.name


def transposer(L):
    """
    L est une liste de liste, comme une matrice NxM. On prend la transposée.
    Ex : L=[[a,b,c],[1,2,3]]. Retourne la liste [[a,1],[b,2],[c,3]]

    Arguments:
        L (list) : une liste de listes
    """
    n = len(L[0])
    for i in range(len(L)):
        if n != len(L[i]):
            print("Les listes n'ont pas la même taille !")
    return list(map(list, zip(*L)))


def send(r, stream=False):
    """Just sends the request using its send method and returns its response.  """
    r.send(stream=stream)
    return r.response


def shortest_path_pick():
    """Select shortest path between two selections

    """
    pass


def getSearchSchema():
    """Return the default search schema for all query.
        """


def adoptDatagramPort(fileDescriptor, addressFamily, protocol,
    maxPacketSize=8192):
    """
        Add an existing listening I{SOCK_DGRAM} socket to the reactor to
        monitor for read and write readiness.

        @param fileDescriptor: A file descriptor associated with a socket which
            is already bound to an address and marked as listening.  The socket
            must be set non-blocking.  Any additional flags (for example,
            close-on-exec) must also be set by application code.  Application
            code is responsible for closing the file descriptor, which may be
            done as soon as C{adoptDatagramPort} returns.
        @type fileDescriptor: C{int}

        @param addressFamily: The address family (or I{domain}) of the socket.
            For example, L{socket.AF_INET6}.
        @type addressFamily: C{int}

        @param protocol: A L{DatagramProtocol} instance to connect to
            a UDP transport.
        @type protocol: L{DatagramProtocol}

        @param maxPacketSize: The maximum packet size to accept.
        @type maxPacketSize: C{int}

        @return: An object providing L{IListeningPort}.

        @raise L{UnsupportedAddressFamily}: If the given address family is not
            supported by this reactor, or not supported with the given socket
            type.

        @raise UnsupportedSocketType: If the given socket type is not supported
            by this reactor, or not supported with the given socket type.
        """


def vivizconfig(server, dataset, **kwargs):
    """Create ViViz configuration catalog"""
    import os
    import json
    import shutil
    from hapiclient.hapi import hapi, server2dirname
    indexjs = kwargs['cachedir'] + '/viviz/index.js'
    fname = server2dirname(server) + '_' + dataset + '.json'
    catalogabs = kwargs['cachedir'] + '/viviz/catalogs/' + fname
    catalogrel = 'catalogs/' + fname
    meta = hapi(server, dataset)
    gallery = {'id': server, 'aboutlink': server, 'strftime':
        'time.min=$Y-$m-$dT00:00:00.000Z&time.max=$Y-$m-$dT23:59:59.999Z',
        'start': meta['startDate'], 'stop': meta['stopDate'], 'fulldir': ''}
    galleries = []
    for parameter in meta['parameters']:
        p = parameter['name']
        fulldir = ('/?server=' + server + '&id=' + dataset + '&parameters=' +
            p + '&usecache=' + str(kwargs['usecache']).lower() + '&format=png&'
            )
        thumbdir = ('/?server=' + server + '&id=' + dataset +
            '&parameters=' + p + '&usecache=' + str(kwargs['usecache']).
            lower() + '&format=png&dpi=72&')
        galleryc = gallery.copy()
        galleryc['fulldir'] = fulldir
        galleryc['thumbdir'] = thumbdir
        galleryc['id'] = p
        galleryc['aboutlink'] = server + '/info?id=' + dataset
        galleries.append(galleryc)
    indexjs_original = indexjs.replace('.js', '-original.js')
    if not os.path.isfile(indexjs_original):
        shutil.copyfile(indexjs, indexjs_original)
    else:
        shutil.copyfile(indexjs_original, indexjs)
    dname = os.path.dirname(catalogabs)
    if not os.path.exists(dname):
        os.makedirs(dname)
    if kwargs['loglevel'] == 'debug':
        print('hapiplotserver.catalog(): Writing ' + catalogabs)
    with open(catalogabs, 'w') as f:
        json.dump(galleries, f, indent=4)
    if kwargs['loglevel'] == 'debug':
        print('hapiplotserver.catalog(): Appending to ' + indexjs)
    with open(indexjs, 'a') as f:
        f.write('\nVIVIZ["config"]["catalogs"]["%s"] = {};\n' % server)
    with open(indexjs, 'a') as f:
        f.write('VIVIZ["config"]["catalogs"]["%s"]["URL"] = "%s";\n' % (
            server, catalogrel))


def anchor_pattern(patt):
    """
    anchors a regex in order to force matching against an entire string.
    """
    if not patt.endswith('\\Z'):
        patt = patt + '\\Z'
    if not patt.startswith('\\A'):
        patt = '\\A' + patt
    return patt


def _parsems(value):
    """Parse a I[.F] seconds value into (seconds, microseconds)."""
    if '.' not in value:
        return int(value), 0
    else:
        i, f = value.split('.')
        return int(i), int(f.ljust(6, '0')[:6])


def exponent_to_amount(exponent: int, number_of_decimals: int) ->float:
    """exponent to integer to be written on the chain"""
    return exponent / 10 ** number_of_decimals


def get_tab(size=5):
    """
    Get a tab composed of a given number of spaces.

    Parameters
    ----------
    size : int, default 5
        The number of spaces to use for a tab.

    Returns
    -------
    tab_str : str
        The provided tab to a given number of spaces.
    """
    return ' ' * size


def sumdiffsquared(x, y):
    """
Takes pairwise differences of the values in lists x and y, squares
these differences, and returns the sum of these squares.

Usage:   lsumdiffsquared(x,y)
Returns: sum[(x[i]-y[i])**2]
"""
    sds = 0
    for i in range(len(x)):
        sds = sds + (x[i] - y[i]) ** 2
    return sds


@classmethod
def factory(cls, global_config, **local_config):
    """Used for paste app factories in paste.deploy config files.
        Any local configuration (that is, values under the [app:APPNAME]
        section of the paste config) will be passed into the `__init__` method
        as kwargs.
        A hypothetical configuration would look like:
            [app:wadl]
            latest_version = 1.3
            paste.app_factory = nova.api.fancy_api:Wadl.factory
        which would result in a call to the `Wadl` class as
            import nova.api.fancy_api
            fancy_api.Wadl(latest_version='1.3')
        You could of course re-implement the `factory` method in subclasses,
        but using the kwarg passing it shouldn't be necessary.
        """
    return cls(**local_config)


def split_params(params):
    """Returns a list of values from a given string of comma-separated values.
    """
    return params.split(',')


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

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

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


@staticmethod
def get_assignment(course, activity):
    """If doesn't use quiz report, we need the activity_inviting_to_complete"""
    return course.get_assignment(activity.id)


def stringint(k, n):
    """ returns string of k by placing zeros before to have n characters
    ex: 1 -> '0001'
    15 -> '0015'

    TODO to be replace by 0 padding format:  %04d for instance
    """
    strint = str(k)
    res = '0' * (n - len(strint)) + strint
    return res


def is_mo_spec(mo):
    """Checks if :literal:`mo` is of :literal:`mo_spec` type.
  (See :ref:`Central Variables` for details.)"""
    from orbkit.orbitals import MOClass
    if not isinstance(mo, MOClass):
        return False
    return_val = True
    for i in mo:
        try:
            return_val = return_val and 'coeffs' in i.keys()
        except:
            return_val = False
    return return_val


def getAdmin():
    """Return a string with the worker admin's contact data."""


def convert_content(req, mimetype, content, key):
    """Convert the given content from mimetype to the output MIME type
        represented by key. Returns a tuple in the form (content,
        output_mime_type) or None if conversion is not possible.

        content must be a `str` instance or an iterable instance which
        iterates `str` instances."""


def fix_multi_T1w_source_name(in_files):
    """
    Make up a generic source name when there are multiple T1s

    >>> fix_multi_T1w_source_name([
    ...     '/path/to/sub-045_ses-test_T1w.nii.gz',
    ...     '/path/to/sub-045_ses-retest_T1w.nii.gz'])
    '/path/to/sub-045_T1w.nii.gz'

    """
    import os
    from nipype.utils.filemanip import filename_to_list
    base, in_file = os.path.split(filename_to_list(in_files)[0])
    subject_label = in_file.split('_', 1)[0].split('-')[1]
    return os.path.join(base, 'sub-%s_T1w.nii.gz' % subject_label)


def auto_fill_queue(module, input_queue, prefix='test_'):
    """
    Scans the specified module for methods beginning with prefix and puts them into the input_queue
    :param module: module whose test methods are to be added to the queue
    :param input_queue: queue to add tests to
    :param prefix: string prefix to identify tests
    :return:
    """
    test_func_names = []
    for x in dir(module):
        if x.startswith(prefix):
            test_func_names.append(x)
    for test_func_name in test_func_names:
        func = getattr(module, test_func_name)
        if callable(func):
            input_queue.put(func)


def compile_wrfnnrp_raw_Salathe2014_locations(maptable):
    """
    Compile a list of file URLs for Salathe et al., 2014 raw WRF NNRP data

    maptable: (dataframe) a dataframe that contains the FID, LAT, LONG_, and ELEV for each interpolated data file
    """
    locations = []
    for ind, row in maptable.iterrows():
        basename = '_'.join(['data', str(row['LAT']), str(row['LONG_'])])
        url = [
            'http://cses.washington.edu/rocinante/WRF/NNRP/vic_16d/WWA_1950_2010/raw/forcings_ascii/'
            , basename]
        locations.append(''.join(url))
    return locations


def rename_nfa_states(nfa: dict, suffix: str):
    """ Side effect on input! Renames all the states of the NFA
    adding a **suffix**.

    It is an utility function to be used to avoid automata to have
    states with names in common.

    Avoid suffix that can lead to special name like "as", "and",...

    :param dict nfa: input NFA.
    :param str suffix: string to be added at beginning of each state name.
    """
    conversion_dict = {}
    new_states = set()
    new_initials = set()
    new_accepting = set()
    for state in nfa['states']:
        conversion_dict[state] = '' + suffix + state
        new_states.add('' + suffix + state)
        if state in nfa['initial_states']:
            new_initials.add('' + suffix + state)
        if state in nfa['accepting_states']:
            new_accepting.add('' + suffix + state)
    nfa['states'] = new_states
    nfa['initial_states'] = new_initials
    nfa['accepting_states'] = new_accepting
    new_transitions = {}
    for transition in nfa['transitions']:
        new_arrival = set()
        for arrival in nfa['transitions'][transition]:
            new_arrival.add(conversion_dict[arrival])
        new_transitions[conversion_dict[transition[0]], transition[1]
            ] = new_arrival
    nfa['transitions'] = new_transitions
    return nfa


def hexadecimal(x):
    """
    Retorna a representação hexadecimal de um inteiro.

    Examples
    --------

    >>> hex(6745)
    '0x1a59'
    """
    return hex(x)


def import_c_accel(globs, cname):
    """
    Import the C-accelerator for the __name__
    and copy its globals.
    """
    name = globs.get('__name__')
    if not name or name == cname:
        return
    from gevent._compat import PURE_PYTHON
    if PURE_PYTHON:
        return
    import importlib
    import warnings
    with warnings.catch_warnings():
        warnings.simplefilter('ignore', ImportWarning)
        mod = importlib.import_module(cname)
    globs.clear()
    globs.update(mod.__dict__)
    if 'import_c_accel' in globs:
        del globs['import_c_accel']


def funcToMethod(f, theClass, name=None):
    """
    From the Python Cookbook...

    The following method allows you to add a function as a method of
    any class. That is, it converts the function to a method of the
    class. The method just added is available instantly to all
    existing instances of the class, and to all instances created in
    the future.

    The function's first argument should be self.

    The newly created method has the same name as the function unless
    the optional name argument is supplied, in which case that name is
    used as the method name.
    """
    setattr(theClass, name or f.__name__, f)


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 crop(image, pt1, pt2):
    """Crops image based on based on top left and bottom right corner"""
    cropped = image[pt1[1]:pt2[1], pt1[0]:pt2[0]]
    return cropped


def clamp01(x: float) ->float:
    """
    Clamp input value to ［0.0, 1.0］
    """
    return max(0.0, min(x, 1.0))


def get_regex_first_group(regex):
    """
    >>> get_regex_first_group(re.match('In order to (.+)', 'In order to avoid duplication'))
    'avoid duplication'
    """
    if regex:
        return regex.group(1)
    return None


def domain():
    """
        This should be a domain name.  For example, if you were mocking an API
        typically present at ``https://api.foo.example.com/v2/``, this should
        return ``u"api.foo.example.com"``.

        :return: the domain name for this top-level mock.
        :rtype: :obj:`six.text_type`
        """


def geom_each(geojson, callback):
    """
    Iterate over each geometry in any GeoJSON object, similar to Array.forEach()
    :param geojson: Point|Polygon|MultiPolygon|MultiPoint|LineString|MultiLineString|FeatureCollection|Feature geojson any GeoJSON object
    :param callback:
    :return:
    """
    feature_index = 0
    is_feature_collection = geojson['type'] == 'FeatureCollection'
    is_feature = geojson['type'] == 'Feature'
    stop = len(geojson['features']) if is_feature_collection else 1
    for i in range(0, stop):
        if is_feature_collection:
            geometry_maybe_collection = geojson['features'][i]['geometry']
            feature_properties = geojson['features'][i].get('properties')
            feature_b_box = geojson['features'][i].get('bbox')
            feature_id = geojson['features'][i].get('id')
        elif is_feature:
            geometry_maybe_collection = geojson['geometry']
            feature_properties = geojson.get('properties')
            feature_b_box = geojson.get('bbox')
            feature_id = geojson.get('id')
        else:
            geometry_maybe_collection = geojson
            feature_properties = {}
            feature_b_box = None
            feature_id = None
        if geometry_maybe_collection:
            if geometry_maybe_collection['type'] == 'GeometryCollection':
                is_geometry_collection = True
            else:
                is_geometry_collection = False
        stop_g = len(geometry_maybe_collection['geometries']
            ) if is_geometry_collection else 1
        for g in range(0, stop_g):
            geometry = geometry_maybe_collection['geometries'][g
                ] if is_geometry_collection else geometry_maybe_collection
            if not geometry:
                if not callback(None, feature_index, feature_properties,
                    feature_b_box, feature_id):
                    return False
                continue
            if geometry['type'] == 'Point' or geometry['type'
                ] == 'LineString' or geometry['type'
                ] == 'MultiPoint' or geometry['type'] == 'Polygon' or geometry[
                'type'] == 'MultiLineString' or geometry['type'
                ] == 'MultiPolygon':
                if not callback(geometry, feature_index, feature_properties,
                    feature_b_box, feature_id):
                    return False
                break
            elif geometry['type'] == 'GeometryCollection':
                for j in range(0, len(geometry['geometries'])):
                    if not callback(geometry['geometries'][j],
                        feature_index, feature_properties, feature_b_box,
                        feature_id):
                        return False
                break
            else:
                raise Exception('Unknown Geometry Type')
        feature_index += feature_index + 1


@staticmethod
def getJavaPackage():
    """ Returns package name String. """
    return 'com.microsoft.ml.spark.recommendation.RankingAdapterModel'


def parse_number(string):
    """
    Retrieve a number from the string.

    Parameters
    ----------
    string : str
        the string to parse

    Returns
    -------
    number : float
        the number contained in the string
    """
    num_str = string.split(None, 1)[0]
    number = float(num_str)
    return number


def truncate_exception(e, n=10000):
    """ Truncate exception to be about a certain length """
    if len(str(e)) > n:
        try:
            return type(e)('Long error message', str(e)[:n])
        except Exception:
            return Exception('Long error message', type(e), str(e)[:n])
    else:
        return e


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

        :param SaveUrlError val:
        :rtype: SaveUrlJobStatus
        """
    return cls('failed', val)


def get_coverage(odorant_indices, space, sigma=2):
    """This function will be used to compute coverage of odorant space during
    optimization. We want non-selected odorants to be 'covered' as much as
    possible by selected ones"""
    ind = list(odorant_indices)
    return space.iloc[ind].max(axis=0).mean()


def get_id_from_ns_name(ns_name):
    """Parses identifier from prefix-identifier

    :param ns_name: The name of a namespace
    :returns: Identifier or None if there is no - to end the prefix
    """
    dash_index = ns_name.find('-')
    if 0 <= dash_index:
        return ns_name[dash_index + 1:]


def hclust_linearize(U):
    """Sorts the rows of a matrix by hierarchical clustering.

    Parameters:
        U (ndarray) : matrix of data

    Returns:
        prm (ndarray) : permutation of the rows
    """
    from scipy.cluster import hierarchy
    Z = hierarchy.ward(U)
    return hierarchy.leaves_list(hierarchy.optimal_leaf_ordering(Z, U))


@staticmethod
def find_compiled_layer_by_name(model, layer_name):
    """ Returns the Keras tensor associated with a given name.

			# Arguments

			model: Model instance. The Kur model. It must be compiled.
			layer_name: str. The name of the layer to find, or one of its
				aliases.

			# Return value

			The Keras tensor
		"""
    if model.compiled is None or 'raw' not in model.compiled:
        raise ValueError('The model must be compiled first.')
    if layer_name in model.output_aliases:
        target = model.output_aliases[layer_name]
    elif layer_name in model.input_aliases:
        target = model.input_aliases[layer_name]
    else:
        raise ValueError('Failed to find a layer named "{}"'.format(layer_name)
            )
    for keras_layer, kur_layer in zip(model.compiled['raw'].outputs, model.
        outputs):
        if kur_layer == target:
            return keras_layer
    raise ValueError('Did not find expected layer. This is a bug.')


def mark_sharp(clear: bool=False, use_verts: bool=False):
    """(Un)mark selected edges as sharp

    :param clear: Clear
    :type clear: bool
    :param use_verts: Vertices, Consider vertices instead of edges to select which edges to (un)tag as sharp
    :type use_verts: bool
    """
    pass


def label_strip_fanout(label):
    """Assume the d+$ in a given label to be fanout and return
    the stripped version of the label.
    """
    while label[-1].isdigit():
        label = label[:-1]
    return label


def write_solution_src(f, data):
    """
    Preallocate solution vectors
    """
    f.write('// Define solution\n')
    f.write('c_float xsolution[%d];\n' % data['n'])
    f.write('c_float ysolution[%d];\n\n' % data['m'])
    f.write('OSQPSolution solution = {xsolution, ysolution};\n\n')


def parse_args():
    """Parse CLI arguments."""
    import argparse
    parser = argparse.ArgumentParser('parse_main_dependencies_from_lock')
    parser.add_argument('pipfile_lock_path', type=argparse.FileType('r'),
        help='Path to Pipfile.lock.')
    parser.add_argument('-o', '--output', type=argparse.FileType('w'),
        default=None)
    return parser.parse_args()


def extract_repo(link):
    """ Extract repository slug from a GitHub link

    >>> extract_repo("/org/repo/blabla?something=foo")
    'org/repo'
    >>> extract_repo("org/repo")
    'org/repo'
    """
    return '/'.join(link.strip('/').split('/', 2)[:2])


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

        :param PaperContentAddMemberType val:
        :rtype: EventType
        """
    return cls('paper_content_add_member', val)


@staticmethod
def _ensure_list(attr):
    """Always returns a list with the provided value. Returns the value if a list."""
    if isinstance(attr, str):
        return [attr]
    elif isinstance(attr, tuple):
        return list(attr)
    else:
        return attr


@staticmethod
def construct_default_dict():
    """Construct default predicate definition as it would be written in the configuration file."""
    return {'name': 'alwaysTrue'}


def get_http_path(http_request):
    """Given a HTTP request, return the resource path."""
    return http_request.split('\n')[0].split(' ')[1]


def _assemble_channel(name):
    """Assemble a channel body item (for `send_message`)."""
    return {'kind': 'channel', 'args': {'channel_name': name}}


@classmethod
def _serialize_keys(cls, hash_key, range_key=None):
    """
        Serializes the hash and range keys

        :param hash_key: The hash key value
        :param range_key: The range key value
        """
    hash_key = cls._hash_key_attribute().serialize(hash_key)
    if range_key is not None:
        range_key = cls._range_key_attribute().serialize(range_key)
    return hash_key, range_key


def template_to_dict_iter_debug(elm):
    """
    Print expanded element on stdout for debugging
    """
    if elm.text is not None:
        print('    <%s>%s</%s>' % (elm.tag, elm.text, elm.tag), end='')
        if elm.tail is not None:
            print(elm.tail)
        else:
            print()
    elif elm.tail is not None:
        print('    <%s>%s' % (elm.tag, elm.tail))
    else:
        print('    <%s>' % elm.tag)


def safe_filename(name):
    """Utility function to make a source short-name safe as a
    filename."""
    name = name.replace('/', '-')
    return name


def indx_where_ngram_ends(st_indx, ngram_toks, sent_toks):
    """

        Case 1: where sent_toks contains stopwords making it hard to match ngram that already has stopwords removed:
            Given st_index = 2 (sent_toks index where ngram_toks starts)
            Given ngram_toks: ['orange', 'new', 'black']
            Given sent_toks: ['best', 'is', 'orange', 'is', 'the', 'new', 'black']

            The goal of this function is return 5: length of substring (['orange', 'is', 'the', 'new', 'black']) with stopwords that encompass ngram_toks

        Negative Case 1:
            Given st_index = 5 (sent_toks index where ngram_toks starts)
            Given ngram_toks: ['convention', 'center']
            Given sent_toks: ['it', 'is', 'the', 'brown', 'r.', 'convention', 'center']

            The goal of this function is return 2: length of substring ([convention', 'center']) without stopwords that encompass ngram_toks
    """
    j = st_indx
    length = 0
    start = -1
    match_count = 0
    for i in range(len(ngram_toks)):
        while j < len(sent_toks):
            length += 1
            ngram_tok = ngram_toks[i].strip().lower()
            sent_tok = sent_toks[j].strip().lower()
            if sent_tok.find(ngram_tok) != -1:
                if start == -1:
                    start = j
                j += 1
                match_count += 1
                break
            j += 1
    if match_count == len(ngram_toks):
        return start, length
    else:
        return start, -1


def _validate_label_map(label_map):
    """Checks if a label map is valid.

    Args:
      label_map: StringIntLabelMap to validate.

    Raises:
      ValueError: if label map is invalid.
    """
    for item in label_map.item:
        if item.id < 0:
            raise ValueError('Label map ids should be >= 0.')
        if (item.id == 0 and item.name != 'background' and item.
            display_name != 'background'):
            raise ValueError(
                'Label map id 0 is reserved for the background label')


@staticmethod
def is_inactive():
    """
        Verify if the interface state is Inactive
        """
    return True


def mpl_get_cb_bound_below_plot(ax):
    """ Return the coordinates for a colorbar axes below the provided axes
    object. Take into account the changes of the axes due to aspect ratio
    settings.

    Important: Use only AFTER fig.subplots_adjust(...)

    """
    position = ax.get_position()
    figW, figH = ax.get_figure().get_size_inches()
    fig_aspect = figH / figW
    box_aspect = ax.get_data_ratio()
    pb = position.frozen()
    pb1 = pb.shrunk_to_aspect(box_aspect, pb, fig_aspect).bounds
    ax_size = ax.get_position().bounds
    sizes = [ax_size[0], ax_size[1], pb1[2], 0.03]
    return sizes


@staticmethod
def set_windows_target_version(context, node):
    """ Sets windows target version(SDK version) into context from node text """
    context.target_windows_version = node.text


@classmethod
def push_message(cls, message):
    """Push a new message for the public messages stack"""
    return cls.animation.messages.append(message)


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

    The ".dev0" means dirty.

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


def get_root_sequence(root_node, ref=None, translations=None):
    """
    create a json structure that contains the sequence of the root, both as
    nucleotide and as translations. This allows look-up of the sequence for
    all states, including those that are not variable.

    Parameters
    ----------
    root_node : dict
    	data associated with the node
    ref : str, optional
        filename of the root sequence
    translations : str, optional
        file name of translations

    Returns
    -------
    dict
        dict of nucleotide sequence and translations
    """
    root_sequence = {}
    if ref and translations:
        from Bio import SeqIO
        refseq = SeqIO.read(ref, 'fasta')
        root_sequence['nuc'] = str(refseq.seq)
        for gene in SeqIO.parse(translations, 'fasta'):
            root_sequence[gene.id] = str(gene.seq)
    else:
        root_sequence['nuc'] = root_node['sequence']
        root_sequence.update(root_node['aa_sequences'])
    return root_sequence


def extend(target, element):
    """
    Extend the given list with the given element. If element is a scalar, it is
    appended to target; if element is a list, target is extended with it.
    >>> extend([1, 2], 4)
    [1, 2, 4]
    >>> extend([1, 2], (1, 2,))
    [1, 2, 1, 2]
    >>> extend([1, 2], {1: 2, 3: 4})
    [1, 2, {1: 2, 3: 4}]
    >>> extend([1, 2], [0, 1])
    [1, 2, 0, 1]

    :param target:
    :type target: list
    :param element:
    :rtype: list

    """
    assert isinstance(target, list)
    if isinstance(element, (list, tuple)):
        target.extend(element)
    else:
        target.append(element)
    return target


@staticmethod
def get_elastic_mappings(es_major):
    """Get Elasticsearch mapping.

        :param es_major: major version of Elasticsearch, as string
        :returns:        dictionary with a key, 'items', with the mapping
        """
    mapping = """
         {
            "dynamic":true,
                "properties": {
                    "data": {
                        "properties": {
                            "notes_data": {
                                "dynamic":false,
                                "properties": {
                                    "body": {
                                        "type": "text",
                                        "index": true
                                    }
                                }
                            },
                            "description": {
                                "type": "text",
                                "index": true
                            },
                            "versions_data": {
                                "dynamic":false,
                                "properties": {}
                            }
                        }
                    }
                }
        }
        """
    return {'items': mapping}


def isMedlineFile(infile, checkedLines=2):
    """Determines if _infile_ is the path to a Medline file. A file is considerd to be a Medline file if it has the correct encoding (`latin-1`) and within the first _checkedLines_ a line starts with `"PMID- "`.

    # Parameters

    _infile_ : `str`

    > The path to the targets file

    _checkedLines_ : `optional [int]`

    > default 2, the number of lines to check for the header

    # Returns

    `bool`

    > `True` if the file is a Medline file
    """
    try:
        with open(infile, 'r', encoding='latin-1') as openfile:
            f = enumerate(openfile, start=0)
            for i in range(checkedLines):
                if f.__next__()[1].startswith('PMID- '):
                    return True
    except (StopIteration, UnicodeDecodeError):
        return False
    else:
        return False


def pytest_sessionstart(session):
    """ called after the ``Session`` object has been created and before performing collection
    and entering the run test loop.

    :param _pytest.main.Session session: the pytest session object
    """


def options(_):
    """
    Implementation for wscript.options
    It's called by Waf as method where cmdline options can be added/removed
    """


def to_toml(value):
    """
    Returns a string of the TOML representation for the data structure given.
    Examples:
    >>> import six
    >>> to_toml({'key': [1, 2]}) == six.text_type("key = [ 1, 2,]\\n")
    True
    """
    from toml import dumps
    return dumps(value)


def _spans(dates):
    """Get the consecutive spans from the given dates."""
    spans = []
    current_span = []
    prev = 0
    for date in dates:
        if date == prev + 1:
            current_span.append(date)
        else:
            spans.append(list(current_span))
            current_span.clear()
            current_span.append(date)
        prev = date
    spans.append(current_span)
    return list(filter(None, spans))


def uncomment():
    """Convert selected comment to text

    """
    pass


def change_header_pointing(header, ra_ref=0.0, dec_ref=0.0, pa_v3=0.0):
    """
    Update a FITS header for a new pointing (center + roll).

    Parameters
    ----------
    header : `~astropy.io.fits.Header`
        Parent header (must contain `V2_REF`, `V3_REF` keywords).

    ra_ref, dec_ref : float
        Pointing center, in decimal degrees, at reference the pixel defined
        in.

    pa_v3 : float
        Position angle of the telescope V3 axis, degrees.

    .. warning::

    Doesn't update PC keywords based on pa_v3, which would rather have to
    be computed from the new `gwcs`.

    """
    from jwst.lib.set_telescope_pointing import compute_local_roll
    v2_ref = header['V2_REF']
    v3_ref = header['V3_REF']
    args = []
    for v in (pa_v3, ra_ref, dec_ref, v2_ref, v3_ref):
        if hasattr(v, 'value'):
            args.append(v.value)
        else:
            args.append(v)
    roll_ref = compute_local_roll(*tuple(args))
    new_header = header.copy()
    new_header['XPA_V3'] = args[0]
    new_header['CRVAL1'] = new_header['RA_REF'] = args[1]
    new_header['CRVAL2'] = new_header['DEC_REF'] = args[2]
    new_header['ROLL_REF'] = roll_ref
    return new_header


@classmethod
def get(cls, project_id, feature_name):
    """Retrieve a single modeling feature

        Parameters
        ----------
        project_id : str
            The ID of the project the feature is associated with.
        feature_name : str
            The name of the feature to retrieve

        Returns
        -------
        feature : ModelingFeature
            The requested feature
        """
    path = cls._build_url(project_id, feature_name)
    return cls.from_location(path)


def _parse_passwd_line(line, entries):
    """
    Parses a line from /etc/passwd and returns the information as a
    dictionary.
    """
    result = dict(zip(entries, line.strip().split(':')))
    result['full_name'] = result['gecos'].split(',')[0]
    return result


def join_path(path, file_name):
    """ Joins path with short file name. If file name is full file name -
		returns just it. """
    full_name = file_name
    sep = '/'
    if path != None and path != '' and not sep in file_name:
        if path.endswith(sep):
            sep = ''
        full_name = path + sep + file_name
    return full_name


def expand_series(ser, columns):
    """
    Helper function to quickly expand a series to a dataframe with according
    column axis and every single column being the equal to the given series.
    """
    return ser.to_frame(columns[0]).reindex(columns=columns).ffill(axis=1)


@classmethod
def flat_bind(cls, executor, fn):
    """Bind an asynchronous callable to an executor.

        This convenience method should be used in preference to :meth:`bind`
        when the bound callable returns a future, in order to avoid a nested
        future in the returned value. It is equivalent to:

        >>> bind(fn).with_flat_map(lambda future: future)

        Arguments:
            executor (~concurrent.futures.Executor): an executor
            fn (callable): any function or callable which returns a future

        Returns:
            callable:
                A new callable which, when invoked, will submit `fn` to `executor` and return
                the resulting (flattened) future.

                This returned callable provides the `Executors.with_*` methods, which may be
                chained to further customize the behavior of the callable.

        .. versionadded:: 1.16.0
        """
    return cls.bind(executor, fn).with_flat_map(lambda f: f)


@classmethod
def from_csv(cls, connection, path, header=0, sep=',', index_col=0,
    parse_dates=True, tupleize_cols=False, infer_datetime_format=False,
    casout=None, **kwargs):
    """ Create a CASColumn from a CSV file """
    return connection.read_csv(path, header=header, sep=sep, index_col=
        index_col, parse_dates=parse_dates, tupleize_cols=tupleize_cols,
        infer_datetime_format=infer_datetime_format, casout=casout, **kwargs
        )._to_column()


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 _static_folder_path(static_url, static_folder, static_asset, prefix=''):
    """
    Returns a path to a file based on the static folder, and not on the
    filesystem holding the file.

    Returns a path relative to static_url for static_asset
    """
    if not static_asset.startswith(static_folder):
        raise ValueError('%s startic asset must be under %s static folder' %
            (static_asset, static_folder))
    rel_asset = static_asset[len(static_folder):]
    key = u'%s/%s' % (static_url.rstrip('/'), rel_asset.lstrip('/'))
    if prefix:
        key = u'%s/%s' % (prefix, key)
    return key


@classmethod
def fromstring(cls, data, checksum=False, ignore_missing_end=False, **kwargs):
    """
        Creates a new HDU object of the appropriate type from a string
        containing the HDU's entire header and, optionally, its data.

        Note: When creating a new HDU from a string without a backing file
        object, the data of that HDU may be read-only.  It depends on whether
        the underlying string was an immutable Python str/bytes object, or some
        kind of read-write memory buffer such as a `memoryview`.

        Parameters
        ----------
        data : str, bytearray, memoryview, ndarray
           A byte string containing the HDU's header and data.

        checksum : bool, optional
           Check the HDU's checksum and/or datasum.

        ignore_missing_end : bool, optional
           Ignore a missing end card in the header data.  Note that without the
           end card the end of the header may be ambiguous and resulted in a
           corrupt HDU.  In this case the assumption is that the first 2880
           block that does not begin with valid FITS header data is the
           beginning of the data.

        kwargs : optional
           May consist of additional keyword arguments specific to an HDU
           type--these correspond to keywords recognized by the constructors of
           different HDU classes such as `PrimaryHDU`, `ImageHDU`, or
           `BinTableHDU`.  Any unrecognized keyword arguments are simply
           ignored.
        """
    return cls._readfrom_internal(data, checksum=checksum,
        ignore_missing_end=ignore_missing_end, **kwargs)


@staticmethod
def _ImageDataGenerator_config():
    """Returns the configs for the `tensorflow.keras.preprocessing.image.ImageDataGenerator`,
    used for the random augmentation of the dataset, following the implementation of
    https://github.com/chleibig/disease-detection/blob/f3401b26aa9b832ff77afe93e3faa342f7d088e5/scripts/inspect_data_augmentation.py."""
    augmentation_config = dict(featurewise_center=False, samplewise_center=
        False, featurewise_std_normalization=False,
        samplewise_std_normalization=False, zca_whitening=False,
        rotation_range=180.0, width_shift_range=0.05, height_shift_range=
        0.05, shear_range=0.0, zoom_range=0.1, channel_shift_range=0.0,
        fill_mode='constant', cval=0.0, horizontal_flip=True, vertical_flip
        =True, data_format='channels_last')
    no_augmentation_config = dict(featurewise_center=False,
        samplewise_center=False, featurewise_std_normalization=False,
        samplewise_std_normalization=False, zca_whitening=False,
        rotation_range=0.0, width_shift_range=0.0, height_shift_range=0.0,
        shear_range=0.0, zoom_range=0.0, channel_shift_range=0.0, fill_mode
        ='nearest', cval=0.0, horizontal_flip=False, vertical_flip=False,
        data_format='channels_last')
    return augmentation_config, no_augmentation_config


@staticmethod
def _get_custom_artifact_details(custom_artifact_types):
    """Return a List of all Custom Incident Artifact Types which are Dictionaries with
        the attributes: api_name, display_name and description"""
    return_list = []
    for artifact_type in custom_artifact_types:
        the_artifact_type = {}
        the_artifact_type['api_name'] = artifact_type.get('programmatic_name')
        the_artifact_type['display_name'] = artifact_type.get('name')
        the_artifact_type['description'] = artifact_type.get('desc')
        return_list.append(the_artifact_type)
    return return_list


def log(args):
    """Receive piped log output and beautify the log"""
    from ..logging.pipe import PipeLogger
    PipeLogger(args).start()


def format_time(t):
    """Format `t` (in seconds) to (h):mm:ss"""
    t = int(t)
    h, m, s = t // 3600, t // 60 % 60, t % 60
    if h != 0:
        return f'{h}:{m:02d}:{s:02d}'
    else:
        return f'{m:02d}:{s:02d}'


def get_instance_metric_data(instanceName=None, metricName=None, period=
    None, startTime=None, endTime=None, unit=None, statistics=None):
    """
    Returns the data points for the specified Amazon Lightsail instance metric, given an instance name.
    See also: AWS API Documentation

    :example: response = client.get_instance_metric_data(
        instanceName='string',
        metricName='CPUUtilization'|'NetworkIn'|'NetworkOut'|'StatusCheckFailed'|'StatusCheckFailed_Instance'|'StatusCheckFailed_System',
        period=123,
        startTime=datetime(2015, 1, 1),
        endTime=datetime(2015, 1, 1),
        unit='Seconds'|'Microseconds'|'Milliseconds'|'Bytes'|'Kilobytes'|'Megabytes'|'Gigabytes'|'Terabytes'|'Bits'|'Kilobits'|'Megabits'|'Gigabits'|'Terabits'|'Percent'|'Count'|'Bytes/Second'|'Kilobytes/Second'|'Megabytes/Second'|'Gigabytes/Second'|'Terabytes/Second'|'Bits/Second'|'Kilobits/Second'|'Megabits/Second'|'Gigabits/Second'|'Terabits/Second'|'Count/Second'|'None',
        statistics=[
            'Minimum'|'Maximum'|'Sum'|'Average'|'SampleCount',
        ]
    )

    :type instanceName: string
    :param instanceName: [REQUIRED]
            The name of the instance for which you want to get metrics data.

    :type metricName: string
    :param metricName: [REQUIRED]
            The metric name to get data about.

    :type period: integer
    :param period: [REQUIRED]
            The time period for which you are requesting data.

    :type startTime: datetime
    :param startTime: [REQUIRED]
            The start time of the time period.

    :type endTime: datetime
    :param endTime: [REQUIRED]
            The end time of the time period.

    :type unit: string
    :param unit: [REQUIRED]
            The unit. The list of valid values is below.

    :type statistics: list
    :param statistics: [REQUIRED]
            The instance statistics.
            (string) --

    :rtype: dict
    :return: {
        'metricName': 'CPUUtilization'|'NetworkIn'|'NetworkOut'|'StatusCheckFailed'|'StatusCheckFailed_Instance'|'StatusCheckFailed_System',
        'metricData': [
            {
                'average': 123.0,
                'maximum': 123.0,
                'minimum': 123.0,
                'sampleCount': 123.0,
                'sum': 123.0,
                'timestamp': datetime(2015, 1, 1),
                'unit': 'Seconds'|'Microseconds'|'Milliseconds'|'Bytes'|'Kilobytes'|'Megabytes'|'Gigabytes'|'Terabytes'|'Bits'|'Kilobits'|'Megabits'|'Gigabits'|'Terabits'|'Percent'|'Count'|'Bytes/Second'|'Kilobytes/Second'|'Megabytes/Second'|'Gigabytes/Second'|'Terabytes/Second'|'Bits/Second'|'Kilobits/Second'|'Megabits/Second'|'Gigabits/Second'|'Terabits/Second'|'Count/Second'|'None'
            },
        ]
    }

    """
    pass


@classmethod
def index(cls, value):
    """Return an index into the Enum given a value."""
    return cls.ALL.index(value)


def truncate_string_from_end(string: str, max_len: int) ->str:
    """If the string len is below the max_len, the function returns the same string.
	If the string is above the max len, the function returns only the last max_len characters plus '...' at the beginning."""
    if len(string) <= max_len:
        return string
    return f'Last {max_len} chars: "...{string[-max_len:]}"'


def find_machine_by_ip(machines, ip):
    """
    From a list of machines, returns the matching machine id.

    Example:

    >>> machines = [
        {
            "id": "abc",
            "primaryIP": "1.1.1.1"
        },
        {
            "id": "xyz",
            "primaryIP": "2.2.2.2"
        }
    ]
    >>> find_machine_by_ip(machine_id, "2.2.2.2")
    "xyz"
    """
    for machine in machines:
        if machine['primaryIP'] == ip:
            return machine


@classmethod
def _seconds_to_days(cls, val, **kwargs):
    """
        converts a number of seconds to days
        """
    zero_value = kwargs.get('zero_value', 0)
    if val is not None:
        if val == zero_value:
            return 0
        return val / 86400
    else:
        return 'Not Defined'


@staticmethod
def _valid_packet(raw_packet):
    """Validate incoming packet."""
    if raw_packet[0:1] != b'\xcc':
        return False
    if len(raw_packet) != 19:
        return False
    checksum = 0
    for i in range(1, 17):
        checksum += raw_packet[i]
    if checksum != raw_packet[18]:
        return False
    return True


@classmethod
def get(cls, consistent=False, **kwargs):
    """Get an item from the table

        Example::

            Thing.get(hash_key="three")

        :param bool consistent: If set to True the get will be a consistent read
        :param \\*\\*kwargs: You must supply your hash key, and range key if used
        """
    kwargs = cls._normalize_keys_in_kwargs(kwargs)
    item = cls.Table.get(consistent=consistent, **kwargs)
    return cls.new_from_raw(item)


def recover_last_session():
    """Open the last closed file (“quit.blend”)

    """
    pass


def extract_partial_chunks(iterator, chunks):
    """
    For a given partition, we now know the start and end row numbers, so use that along with the new chunk size
    to break the rows into new (partial) chunks that are labelled with the new index number. Partial chunks will
    be shuffled using the new index number as key to bring together all the partial chunks for a given new index
    number.
    """
    c = chunks[0]
    key, val = list(iterator)
    k_i, k_i_next = key
    tuples = []
    for x in range(k_i - k_i % c, k_i_next, c):
        start, end = max(k_i, x), min(k_i_next, x + c)
        start_offset, end_offset = start - k_i, end - k_i
        partial_chunk = val[start_offset:end_offset]
        new_index = start // c
        new_start_offset, new_end_offset = (start - new_index * c, end -
            new_index * c)
        tuples.append((new_index, ((new_start_offset, new_end_offset),
            partial_chunk)))
    return tuples


def get_bss_load(_, data):
    """http://git.kernel.org/cgit/linux/kernel/git/jberg/iw.git/tree/scan.c?id=v3.17#n935

    Positional arguments:
    data -- bytearray data to read.

    Returns:
    Dict.
    """
    answers = {'station count': data[1] << 8 | data[0],
        'channel utilisation': data[2] / 255.0,
        'available admission capacity': data[4] << 8 | data[3]}
    return answers


def scale_spectrum(s, c):
    """Multiple spectrum by constant c"""
    for l in s:
        l[1] *= c
    return


@staticmethod
def extract_values(fingerprint: str):
    """Return the original values from the passed fingerprint
           or filename. This assumes that the fingerprint
           was created using the 'fingerprint' function, namely
           that any integers are actually 0.INTEGER

           Parameters
           ----------
           fingerprint: str
             The fingerprint (or filename) to decode

           Returns
           -------
           (values, repeat): (List[float], int)
             The list of values of the variables and the repeat
             index. The repeat index is None if it wasn't included
             in the fingerprint
        """
    from pathlib import Path
    fingerprint = Path(Path(fingerprint).name)
    for suffix in fingerprint.suffixes:
        fingerprint = str(fingerprint).replace(suffix, '')
    fingerprint = str(fingerprint)
    parts = fingerprint.split('@')
    if len(parts) > 1:
        repeat_index = int(parts[-1])
        fingerprint = '@'.join(parts[0:-1])
    else:
        repeat_index = None
    values = []
    for part in fingerprint.split(':'):
        try:
            values.append(float(part.replace('_', '.')))
        except Exception:
            pass
    return values, repeat_index


@staticmethod
def gain_int_to_db_string(intval):
    """Substract 96 and return the signed value as a string
        """
    if intval - 96 >= 0:
        return '+' + str(intval - 96)
    return str(intval - 96)


def percent_finder(data, p):
    """Level finder for percentage contours

	This function is a base-level function used by plots_2d.sigma_cont to define the level which contains the requested
	percentage of the data points.

	Parameters
	----------
	data : ndarray
		Describes the n-dimensional position of each data point.
	p : float
		Fraction of the data points to be encircled by the contour.

	Returns
	-------
	min_value : float
		Level for the contour.
	"""
    from numpy import cumsum, ravel, sort
    from numpy import min as np_min
    from numpy import sum as np_sum
    data_sorted = sort(ravel(data))[::-1]
    data_fraction = cumsum(data_sorted)
    data_fraction /= np_sum(data_sorted)
    try:
        min_value = np_min(data_sorted[data_fraction < p])
    except ValueError:
        min_value = np_min(data_sorted)
    return min_value


def is_medium_truck(df):
    """Return if vehicle is a medium truck, per NHTSA convention."""
    yr = df['YEAR']
    body = df['BODY_TYP']
    return yr.between(1975, 1981) & body.isin([53, 54, 56]) | yr.between(
        1982, 1990) & body.isin([70, 71, 75, 78]) | (1991 <= yr) & body.isin([
        60, 61, 62, 64, 67, 71])


def check_numeric(value_string):
    """
    This function tries to determine if a string would be better represented
    with a numeric type, either int or float.  If neither works, for example
    ``10 Mb``, it will simply return the same string provided

    :param value_string: input string to be parsed.

    :return: the input string, an int, or a float
    """
    if type(value_string) in ('int', 'long', 'float'):
        return value_string
    try:
        if '.' in value_string:
            return float(value_string)
    except (TypeError, ValueError):
        pass
    try:
        return int(value_string)
    except (TypeError, ValueError):
        pass
    return value_string


def removeGroup(segments, group):
    """
        Remove group from file/folder acl.

        On Unix it will only remove the group from extended acl.
        """


def saferead(path):
    """
    Read a file with detect encoding

    :returns: text and its encoding
    """
    import chardet
    import sys
    if sys.version_info.major == 3:
        enc = 'utf-8'
        try:
            with open(path, 'r', encoding=enc) as fo:
                data = fo.read()
        except:
            with open(path, 'rb') as fo:
                data = fo.read().decode('utf-8', errors='ignore')
        return data, enc
    else:
        with open(path, 'r') as fo:
            data = fo.read()
        try:
            enc = 'utf-8'
            data = data.decode(enc)
        except UnicodeDecodeError:
            enc = chardet.detect(data)['encoding']
            data = data.decode(enc, errors='ignore')
        return data, enc


def is_greater_than(field, notgreaterthanthis):
    """Validates that a field length is not greater than the notgreaterthanthis value.

    Args:
        field:str
        notgreaterthanthis: int
    Returns:
        returns Boolean
    """
    if len(field) > notgreaterthanthis:
        return False
    else:
        return True


def ip2Long(ip):
    """Returns IP in Int format from Octet form"""
    octs = list(map(int, ip.split('.')))
    return octs[0] * 2 ** 24 + octs[1] * 2 ** 16 + octs[2] * 2 ** 8 + octs[3]


@classmethod
def alias_key(cls, name):
    """Sort key function to order aliases in source order, but with short
        forms(one dash) first."""
    return len(name) - len(name.lstrip('-')), next(cls.__key_count)


def glScale(x, y, z):
    """Multiply the current matrix by a general scaling matrix

    :param z: Specify scale factors along the x, y, and z axes, respectively.
    """
    pass


def health(transport, request, callback=None):
    """Check the health of web head for load balancing

    :param transport: Transport instance to use
    :type transport: `transport.base.Transport`
    :param request: Request instance ready to be sent.
    :type request: `transport.request.Request`
    :param callback: Optional callable to use as callback.
        If specified, this request will be sent asynchronously.
        (IGNORED UNTIL ASYNC SUPPORT IS COMPLETE)
    :type callback: Callable object.
    """
    request.operation = 'health'
    resp = transport.send(request)
    return resp.deserialized_content


def intersect_intervals(int1, int2):
    """ Computes the intersections of two sets of datetime 2-tuples, each of which
    represents the overlap between the two tuples.
    """
    intersect = []
    for start1, end1 in int1:
        for start2, end2 in int2:
            start0 = max(start1, start2)
            end0 = min(end1, end2)
            if start0 < end0:
                intersect.append((start0, end0))
    return intersect


def delete_attributes(cluster=None, attributes=None):
    """
    Deletes one or more custom attributes from an Amazon ECS resource.
    See also: AWS API Documentation

    :example: response = client.delete_attributes(
        cluster='string',
        attributes=[
            {
                'name': 'string',
                'value': 'string',
                'targetType': 'container-instance',
                'targetId': 'string'
            },
        ]
    )

    :type cluster: string
    :param cluster: The short name or full Amazon Resource Name (ARN) of the cluster that contains the resource to delete attributes. If you do not specify a cluster, the default cluster is assumed.

    :type attributes: list
    :param attributes: [REQUIRED]
            The attributes to delete from your resource. You can specify up to 10 attributes per request. For custom attributes, specify the attribute name and target ID, but do not specify the value. If you specify the target ID using the short form, you must also specify the target type.
            (dict) --An attribute is a name-value pair associated with an Amazon ECS object. Attributes enable you to extend the Amazon ECS data model by adding custom metadata to your resources. For more information, see Attributes in the Amazon EC2 Container Service Developer Guide .
            name (string) -- [REQUIRED]The name of the attribute. Up to 128 letters (uppercase and lowercase), numbers, hyphens, underscores, and periods are allowed.
            value (string) --The value of the attribute. Up to 128 letters (uppercase and lowercase), numbers, hyphens, underscores, periods, at signs (@), forward slashes, colons, and spaces are allowed.
            targetType (string) --The type of the target with which to attach the attribute. This parameter is required if you use the short form ID for a resource instead of the full Amazon Resource Name (ARN).
            targetId (string) --The ID of the target. You can specify the short form ID for a resource or the full Amazon Resource Name (ARN).

    :rtype: dict
    :return: {
        'attributes': [
            {
                'name': 'string',
                'value': 'string',
                'targetType': 'container-instance',
                'targetId': 'string'
            },
        ]
    }

    """
    pass


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 shorten(s, width=80):
    """
    >>> shorten('a very very very very long sentence', 20)
    'a very very ..(23)..'
    """
    if not isinstance(s, str):
        s = str(s)
    length = len(s)
    if length < width:
        return s
    cut_length = length - width + 6
    x = len(str(cut_length))
    cut_length += x
    if x != len(str(cut_length)):
        cut_length += 1
    end_pos = length - cut_length
    return s[:end_pos] + '..(%d)..' % cut_length


@classmethod
def add_predefine(cls, template):
    """Add a template that should be run prior to running any other templates.
        This is useful for predefining types, etc.

        :param basestring template: The template text (unicode is also fine here)
        """
    cls._predefines.append(template)


def SECOND(expression):
    """
    Returns the second portion of a date as a number between 0 and 59, but can be 60 to account for leap seconds.
    See https://docs.mongodb.com/manual/reference/operator/aggregation/minute/
    for more details
    :param expression: expression or variable of a Date, a Timestamp, or an ObjectID
    :return: Aggregation operator
    """
    return {'$second': expression}


def _within(p1, p2, d):
    """Determines whether 2 points are within a distance of each other

    Parameters
    ---------
    p1 : Position
        The first point
    p2 : Position
        The second point
    d : int or float
        The distance

    Returns
    ----------
    bool
        Whether the distance between the points is less than d
    """
    return (p1.x - p2.x) ** 2 + (p1.y - p2.y) ** 2 < d ** 2


def replace_dict_value(dictionary, old_value, new_value):
    """ Selectively replaces values in a dictionary

    Parameters:
        :dictionary(dict): input dictionary
        :old_value: value to be replaced
        :new_value: value to replace

    Returns:
        :output_dictionary (dict): dictionary with replaced values"""
    for key, value in dictionary.items():
        if value == old_value:
            dictionary[key] = new_value
    return dictionary


def _to_list(var):
    """
    Make variable to list.

    >>> _to_list(None)
    []
    >>> _to_list('whee')
    ['whee']
    >>> _to_list([None])
    [None]
    >>> _to_list((1, 2, 3))
    [1, 2, 3]

    :param var: variable of any type
    :return:    list
    """
    if isinstance(var, list):
        return var
    elif var is None:
        return []
    elif isinstance(var, str) or isinstance(var, dict):
        return [var]
    else:
        try:
            return list(var)
        except TypeError:
            return [var]


@staticmethod
def _initialise_states():
    """
        This function initialises the model states before starting the simulations.
        If a warm-up run is used, this initialisation happens before the start of the warm-up run.
        If no warm-up is used, this initialisation happens before the start of the actual simulation run.
        """
    return {}


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

    Like 'git describe --tags --dirty --always -long'.
    The distance/hash is unconditional.

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


def rfc2822_date_string(timetuple, zone='-0000'):
    """Accepts a timetuple and optional zone which defaults to ``-0000``
    and returns a date string as specified by RFC 2822, e.g.:

    Fri, 09 Nov 2001 01:08:47 -0000

    Copied from email.utils.formatdate and modified for separate use
    """
    return '%s, %02d %s %04d %02d:%02d:%02d %s' % (['Mon', 'Tue', 'Wed',
        'Thu', 'Fri', 'Sat', 'Sun'][timetuple[6]], timetuple[2], ['Jan',
        'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct',
        'Nov', 'Dec'][timetuple[1] - 1], timetuple[0], timetuple[3],
        timetuple[4], timetuple[5], zone)


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


@staticmethod
def normalise_list(value=None):
    """Return value as list."""
    value = value if value is not None else []
    if not isinstance(value, list) and not isinstance(value, tuple):
        value = [value]
    return value


def number(input):
    """Convert the given input to a floating point or integer value.

    In cases of ambiguity, integers will be prefered to floating point.

    :param input: the value to convert to a number
    :type input: any

    :returns: converted integer value
    :rtype: float or int
    """
    try:
        return int(input)
    except (TypeError, ValueError):
        pass
    try:
        return float(input)
    except (TypeError, ValueError):
        raise ValueError('Unable to convert {0!r} to a number.'.format(input))


def __call__():
    """Generate transformed lxml trees (and return thoses).
        """


def boolean_value(value):
    """get bolean value"""
    if value == 'true':
        ret = True
    elif value == 'false':
        ret = False
    else:
        ret = value
    return ret


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

        :param PaperContentArchiveType val:
        :rtype: EventType
        """
    return cls('paper_content_archive', val)


def compute_sign(permutation):
    """Compute sign by sorting."""
    sign = 1
    n = len(permutation)
    p = [p for p in permutation]
    for i in range(n - 1):
        for j in range(n - 1):
            if p[j] > p[j + 1]:
                p[j], p[j + 1] = p[j + 1], p[j]
                sign = -sign
            elif p[j] == p[j + 1]:
                return 0
    return sign


def fibonacci_range(limit):
    """Returns a list of Fibonacci numbers less than limit"""
    result = [0, 1]
    done = False
    while not done:
        next_fibo = result[-1] + result[-2]
        if next_fibo < limit:
            result.append(next_fibo)
        else:
            done = True
    return result


def list_notebooks(library_db, query_start, query_end):
    """lists all loaded notebooks"""
    from src.praxxis.sqlite import connection
    conn = connection.create_connection(library_db)
    cur = conn.cursor()
    list_libraries = (
        'SELECT Notebook, Path, Library, RawUrl FROM "Notebooks" LIMIT ?, ?')
    cur.execute(list_libraries, (query_start, query_end))
    rows = cur.fetchall()
    conn.close()
    return rows


@classmethod
def add_loader(cls, loader):
    """append a Loader object to this classes list of known loaders"""
    cls._loaders.append(loader)


@classmethod
def loads(cls, buf):
    """create a Model object from a JSON-encoded string"""
    obj = cls.__schema__().loads(buf)
    return cls.create(**obj.data)


def add_media_to_track(proj, track_index, media_id, start, duration=None):
    """Add a track reference to media-bin media.

    Raises:
        KeyError: Specified track or media can't be found.
        ValueError: Media overlaps existing track media.
    """
    track = proj.timeline.tracks[track_index]
    media = proj.media_bin[media_id]
    track.add_media(media, start, duration)


def environment_created():
    """Called when a new Trac environment is created."""


def is_named_tuple(obj) ->bool:
    """
    Check if the object is a named tuple.

    Parameters
    ----------
    obj : The object to check

    Returns
    -------
    is_named_tuple : bool
        Whether `obj` is a named tuple.

    Examples
    --------
    >>> from collections import namedtuple
    >>> Point = namedtuple("Point", ["x", "y"])
    >>> p = Point(1, 2)
    >>>
    >>> is_named_tuple(p)
    True
    >>> is_named_tuple((1, 2))
    False
    """
    return isinstance(obj, tuple) and hasattr(obj, '_fields')


def animator(progbar, count, tot_string=False, linenum=False, terminal=
    False, init=False, length=False, quiet=False, **kwargs):
    """
    Animates progress bar in unique position in terminal
    Multiple progress bars not supported in jupyter yet.
    """
    welcome_message = kwargs.pop('welcome_message', '')
    if welcome_message:
        welcome_message = welcome_message.replace('Interrogating corpus ... \n'
            , '')
        welcome_message = welcome_message.replace('Concordancing corpus ... \n'
            , '')
        welcome_message = welcome_message.replace('\n', '<br>').replace(' ' *
            17, ' ' * 17)
    else:
        welcome_message = ''
    if init:
        from traitlets import TraitError
        try:
            from ipywidgets import IntProgress, HTML, VBox
            from IPython.display import display
            progress = IntProgress(min=0, max=length, value=1)
            using_notebook = True
            progress.bar_style = 'info'
            label = HTML()
            label.font_family = 'monospace'
            gblabel = HTML()
            gblabel.font_family = 'monospace'
            box = VBox(children=[label, progress, gblabel])
            display(box)
            return box
        except TraitError:
            pass
        except ImportError:
            pass
        except AttributeError:
            pass
    if not init:
        try:
            from ipywidgets.widgets.widget_box import Box
            if isinstance(progbar, Box):
                label, progress, goodbye = progbar.children
                progress.value = count
                if count == length:
                    progress.bar_style = 'success'
                else:
                    label.value = '%s\nInterrogating: %s ...' % (
                        welcome_message, tot_string)
                return
        except:
            pass
    start_at = kwargs.get('startnum', 0)
    if start_at is None:
        start_at = 0.0
    denominator = kwargs.get('denom', 1)
    if kwargs.get('note'):
        if count is None:
            perc_done = 0.0
        else:
            perc_done = count * 100.0 / float(length) / float(denominator)
        kwargs['note'].progvar.set(start_at + perc_done)
        kwargs['root'].update()
        return
    if init:
        from corpkit.textprogressbar import TextProgressBar
        return TextProgressBar(length, dirname=tot_string)
    try:
        with terminal.location(0, terminal.height - (linenum + 1)):
            if tot_string:
                progbar.animate(count, tot_string, quiet=quiet)
            else:
                progbar.animate(count, quiet=quiet)
    except:
        if tot_string:
            progbar.animate(count, tot_string, quiet=quiet)
        else:
            progbar.animate(count, quiet=quiet)


def multirate_padding(used_bytes, align_bytes):
    """
    The Keccak padding function.
    """
    padlen = align_bytes - used_bytes
    if padlen == 0:
        padlen = align_bytes
    if padlen == 1:
        return [129]
    else:
        return [1] + [0] * (padlen - 2) + [128]


def _get_object(g, s, p):
    """
    Retrieve the (first) object of a relation. This is mainly to be used where
    we expect only one relation of the specified type.

    Parameters
    ----------
    g : rdflib.Graph
    s : rdflib.term.URIRef
        The subject of the relation.
    p : rdflib.term.URIRef
        The predicate of the relation.

    Returns
    -------
    rdflib.term.URIRef
    """
    try:
        return list(g.objects(s, p))[0]
    except IndexError:
        return None


@staticmethod
def get_jenkins_plugin_name():
    """Gets the name of the Jenkins plugin associated with this PyJen plugin

        This static method is used by the PyJen plugin API to associate this
        class with a specific Jenkins plugin, as it is encoded in the config.xml

        :rtype: :class:`str`
        """
    return 'org.jenkins_ci.plugins.flexible_publish.FlexiblePublisher'


def provider_parser(subparser):
    """Generate subparser for exoscale"""
    subparser.add_argument('--auth-key', help=
        'specify API key for authentication')
    subparser.add_argument('--auth-secret', help=
        'specify API secret for authentication')


@staticmethod
def _extract_bdm(block_device_info):
    """Returns the block device mapping out of the block device info.

        The block device mapping is a list of instances of block device
        classes from nova.virt.block_device.  Each block device
        represents one volume connection.

        An example string representation of a DriverVolumeBlockDevice
        from the early Liberty time frame is:
        {'guest_format': None,
        'boot_index': 0,
        'mount_device': u'/dev/sda',
        'connection_info': {u'driver_volume_type': u'fibre_channel',
                            u'serial': u'e11765ea-dd14-4aa9-a953-4fd6b4999635',
                            u'data': {u'initiator_target_map':
                                        {u'21000024ff747e59':
                                            [u'500507680220E522',
                                            u'500507680210E522'],
                                        u'21000024ff747e58':
                                            [u'500507680220E522',
                                            u'500507680210E522']},
                                        u'vendor': u'IBM',
                                        u'target_discovered':False,
                                        u'target_UID': u'600507680282...',
                                        u'qos_specs': None,
                                        u'volume_id': u'e11765ea-...',
                                        u'target_lun': u'2',
                                        u'access_mode': u'rw',
                                        u'target_wwn': u'500507680220E522'}
                            },
        'disk_bus': None,
        'device_type': u'disk',
        'delete_on_termination': True}
        """
    if block_device_info is None:
        return []
    return block_device_info.get('block_device_mapping', [])


def set_monitor():
    """Sets up a following call to daemonize() to fork a supervisory process to
    monitor the daemon and restart it if it dies due to an error signal."""
    global _monitor
    _monitor = True


def ask_for(question: str, answers: list):
    """ Given a question and a list of answers it will return the answer. If the list of answers has only 2 elements then
        if the answer is equal to the first element it will return True and False otherwise
    """
    answer = str(input(question + ' ' + str(answers) + ': ')).lower()
    while answer not in answers:
        print("Don't understand that input")
        answer = str(input(question + ' ' + str(answers))).lower()
    return answer if len(answers) > 2 else answers[0] == answer


@classmethod
def descriptionHtml(cls):
    """ A long description that will be displayed as help in the inspector-open dialog box.
        """
    return ''


@classmethod
def WithData(cls, original_exc, model, fk, field_value):
    """
        Factory method for creating a deserialization error which has a more
        explanatory message.
        """
    return cls("%s: (%s:pk=%s) field_value was '%s'" % (original_exc, model,
        fk, field_value))


def translate_matrix(m, v):
    """Translates a matrix by (x, y)."""
    a, b, c, d, e, f = m
    x, y = v
    return a, b, c, d, x * a + y * c + e, x * b + y * d + f


def enable_debugging(args):
    """
    Enables interactive debugging

    :param:

     - `args`: A namespace with pudb and pdb attributes
    """
    if args.pudb:
        import pudb
        pudb.set_trace()
        return
    if args.pdb:
        import pdb
        pdb.set_trace()
    return


def copyfileobj(fsrc, fdst, length=16 * 1024):
    """copy data from file-like object fsrc to file-like object fdst"""
    while 1:
        buf = fsrc.read(length)
        if not buf:
            break
        fdst.write(buf)


def pop(key, d):
    """D.pop(k[, d]) -> v, remove key and return the corresponding value.

        If key is not found, d is returned if given, otherwise :class:`KeyError` is
        raised.
        """


def backwards(apps, schema_editor):
    """Delete Peers group."""
    Group = apps.get_model('auth', 'Group')
    Group.objects.filter(name='Moderators').delete()


def AsList(arg):
    """return the given argument unchanged if already a list or tuple, otherwise return a single
    element list"""
    return arg if isinstance(arg, (tuple, list)) else [arg]


def _content_type_is_json(kwargs):
    """Check whether the content-type in ``kwargs`` is 'application/json'.

    :param kwargs: A ``dict``. The keyword args supplied to :func:`request` or
        one of the convenience functions like it.
    :returns: ``True`` or ``False``

    """
    if 'headers' in kwargs and 'content-type' in kwargs['headers']:
        return kwargs['headers']['content-type'].lower() == 'application/json'
    else:
        return False


def __new__(cls, *args, **kargs):
    """Maintain only a single instance of this object
        @return: instance of this class

        """
    if not cls.instance:
        cls.instance = object.__new__(cls, *args, **kargs)
    return cls.instance


def cull_uninformative_rates(rates, inform):
    """Zeroes out rates which are uninformative"""
    return rates * inform


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 is_content(fieldname):
    """Return True if the `fieldname` represents an XML content selector."""
    return fieldname == 'text()'


def dolly(mx: int=0, my: int=0, delta: int=0, use_cursor_init: bool=True):
    """Dolly in/out in the view

    :param mx: Region Position X
    :type mx: int
    :param my: Region Position Y
    :type my: int
    :param delta: Delta
    :type delta: int
    :param use_cursor_init: Use Mouse Position, Allow the initial mouse position to be used
    :type use_cursor_init: bool
    """
    pass


def arcsinh(x):
    """The hyperbolic arcsin or the arcsinh"""
    raise NotImplementedError


def remove_bracketed(test_str):
    """ Remove bracketed text from string. """
    ret = ''
    skip1c = 0
    skip2c = 0
    for i in test_str:
        if i == '[':
            skip1c += 1
        elif i == '(':
            skip2c += 1
        elif i == ']' and skip1c > 0:
            skip1c -= 1
        elif i == ')' and skip2c > 0:
            skip2c -= 1
        elif skip1c == 0 and skip2c == 0:
            ret += i
    return ret


def _img_fname(img_url: str) ->str:
    """Return image file name including the extension given its url."""
    return img_url.split('/')[-1]


@staticmethod
def _download_files(uploads, outdir, overwrite):
    """
        Downloads uploaded file from list of :class:`Upload` models.

        :param uploads: list of Uploads
        :type uploads: list
        :param outdir: output path for downloaded files (default: CWD)
        :type outdir: str
        :param overwrite: overwrite existing files if True (default: True)
        :type overwrite: bool
        :return: list of filepaths
        :rtype: list
        """
    filepaths = []
    for upload in uploads:
        filepath = upload.download(outdir=outdir, overwrite=overwrite)
        filepaths.append(filepath)
    return filepaths


def _boolean(sstr):
    """Coerce a string to a boolean following the same convention as
    :meth:`configparser.ConfigParser.getboolean`:
     - '1', 'yes', 'true' and 'on' cause this function to return ``True``
     - '0', 'no', 'false' and 'off' cause this function to return ``False``

    :param sstr: String representation of a boolean
    :return: ``True`` or ``False``
    :raise: ``ValueError`` if ``sstr`` is not a valid string representation
        of a boolean
    """
    if sstr.lower() in ['1', 'yes', 'true', 'on']:
        return True
    if sstr.lower() in ['0', 'no', 'false', 'off']:
        return False
    msg = "Cannot coerce string '%s' to a boolean value. " % sstr
    msg += "Valid boolean strings: '1', 'yes', 'true', 'on',  "
    msg += "'0', 'no', 'false', 'off'"
    raise ValueError(msg)


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

        :param SmartSyncChangePolicyDetails val:
        :rtype: EventDetails
        """
    return cls('smart_sync_change_policy_details', val)


def get_chunk_slices(ds_dim, chunk_size):
    """
    Create list of chunk slices [(s_i, e_i), ...]

    Parameters
    ----------
    ds_len : 'int'
        Length of dataset axis to chunk
    chunk_size : 'int'
        Size of chunks

    Returns
    -------
    chunks : 'list'
        List of chunk start and end positions
        [(s_i, e_i), (s_i+1, e_i+1), ...]
    """
    chunks = list(range(0, ds_dim, chunk_size))
    if chunks[-1] < ds_dim:
        chunks.append(ds_dim)
    else:
        chunks[-1] = ds_dim
    chunks = list(zip(chunks[:-1], chunks[1:]))
    return chunks


def telco_churn(quantile=0.5):
    """Returns dataset in format x, [y1, y2]. This dataset
    is useful for demonstrating multi-output model or for
    experimenting with reduction strategy creation.

    The data is from hyperparameter optimization experiment with
    Kaggle telco churn dataset.

    x: features
    y1: val_loss
    y2: val_f1score

    quantile is for transforming the otherwise continuous y variables into
    labels so that higher value is stronger. If set to 0 then original
    continuous will be returned."""
    import wrangle
    import pandas as pd
    df = pd.read_csv(
        'https://raw.githubusercontent.com/autonomio/examples/master/telco_churn/telco_churn_for_sensitivity.csv'
        )
    df = df.drop(['val_acc', 'loss', 'f1score', 'acc', 'round_epochs'], 1)
    for col in df.iloc[:, 2:].columns:
        df = wrangle.col_to_multilabel(df, col)
    df = wrangle.df_rename_cols(df)
    if quantile > 0:
        y1 = (df.C0 < df.C0.quantile(quantile)).astype(int).values
        y2 = (df.C1 > df.C1.quantile(quantile)).astype(int).values
    else:
        y1 = df.C0.values
        y2 = df.C1.values
    x = df.drop(['C0', 'C1'], 1).values
    return x, [y1, y2]


def N_(message):
    """
    Dummy function to mark strings as translatable for babel indexing.
    see https://docs.python.org/3.5/library/gettext.html#deferred-translations
    """
    return message


def get(name):
    """Return the named style or None.

        :type name: string
        :param name: A style name.
        :return: the named `IStyle` or None if the style doesn't exist.
        """


def server_error(log_func, log_msg, status_exc):
    """
    Helper function for logging and returning web.HTTPError.

    :param callable log_func: logging function.
    :param str log_msg: log message.
    :param web.HTTPError status_exc: exception class
    :raises: status_exc instance
    :returns: does not return.
    """
    exc = status_exc()
    log_func('{0}: {1}'.format(exc, log_msg))
    raise exc


def changeValue(previous, current):
    """Add the difference in values to the score for the context
        in the index"""


def index_of_layer_containing_tag(stack, tag):
    """
	return zero based index of layer with `tag` or None

	:param stack: Iterable[layer.Layer]
	:param tag: str
	:return: int | None
	"""
    for i, layer in enumerate(reversed(stack)):
        for t in layer.tags:
            if t.closing == tag:
                return len(stack) - i - 1
    return None


def read_bz2(apath, encoding='utf-8', errors='ignore', process_line=None):
    """Read lines from a file in bz2 archive.

    :param process_line: a function that will be invoked to process each file's
                         line. If its result is a list, then it will be
                         returned by lines
    :type process_line: callable
    """
    from bz2 import open as bz2_open
    with bz2_open(apath, mode='rt', encoding=encoding, errors=errors) as f:
        for line in f:
            if process_line:
                line = process_line(line)
                if isinstance(line, list):
                    for line_ in line:
                        yield line_
                    continue
            yield line


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

    The ".dev0" means dirty.

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


def classmethod2display(class_, method_, descriptor_):
    """Convert two strings such as "Lcom/mwr/example/sieve/AddEntryActivity;" and "onCreate"
    into a beautiful :) string to display Xrefs:
    "Lcom/mwr/example/sieve/AddEntryActivity; -> onCreate"
    """
    return '%s -> %s ( %s )' % (class_, method_, descriptor_)


def get_system_info():
    """Yield a sequence of `(name, version)` tuples describing the
        name and version information of external packages used by a
        component.
        """


def get_iface_name(enode, netname):
    """
    Get interface name inside a container

    This function will figure out the interface name inside the container for
    a given docker network.

    :param enode: The platform ("engine") node to get the iface name from.
    :param str netname: The name of the docker network to which the interface
                        we're looking for is connected.
    """
    docker_netconf = enode._client.inspect_container(enode.container_id)[
        'NetworkSettings']['Networks'][netname]
    ifaces_conf = enode._docker_exec('ip -o link list').strip().split('\n')
    for iface_conf in ifaces_conf:
        if docker_netconf['MacAddress'] in iface_conf:
            iface = iface_conf.split(': ')[1].split('@')[0]
            break
    else:
        raise RuntimeError(
            'Unable to find interface with MAC address {docker_netconf[MacAddress]} in netns {netns} in container {enode._container_id} with name {enode._container_name}'
            .format(**locals()))
    return iface


def iunique(iterable):
    """Return an iterable of unique items ordered by first occurrence"""
    seen = set()
    for item in iterable:
        if item not in seen:
            seen.add(item)
            yield item


def total_seconds(delta):
    """Return the total seconds of datetime.timedelta object.

    Compute total seconds of datetime.timedelta, datetime.timedelta
    doesn't have method total_seconds in Python2.6, calculate it manually.
    """
    try:
        return delta.total_seconds()
    except AttributeError:
        return delta.days * 24 * 3600 + delta.seconds + float(delta.
            microseconds) / 10 ** 6


def gcd(p, q):
    """Returns the greatest common divisor of p and q

    >>> gcd(48, 180)
    12
    """
    while q != 0:
        p, q = q, p % q
    return p


def find(key):
    """Calls self.read().find(key)``.

        Returns a 2-tuple of ``(node, flags)`` or raises ``KeyError``.
        """


@staticmethod
def p_new_symbols_value(p):
    """
        new_symbols_value : CM_
                          | BA_DEF_
                          | BA_
                          | VAL_
                          | CAT_DEF_
                          | CAT_
                          | FILTER_
                          | BA_DEF_DEF_
                          | EV_DATA_
                          | ENVVAR_DATA_
                          | SGTYPE_
                          | SGTYPE_VAL_
                          | BA_DEF_SGTYPE_
                          | BA_SGTYPE_
                          | SIG_TYPE_REF_
                          | VAL_TABLE_
                          | SIG_GROUP_
                          | SIG_VALTYPE_
                          | SIGTYPE_VALTYPE_
                          | BO_TX_BU_
                          | BA_DEF_REL_
                          | BA_REL_
                          | BA_DEF_DEF_REL_
                          | BU_SG_REL_
                          | BU_EV_REL_
                          | BU_BO_REL_
                          | NS_DESC_
                          | FILTER
                          | SG_MUL_VAL_
        """
    p[0] = p[1]


def convert_timestamp(timestamp):
    """Convert an srt timestamp into seconds."""
    timestamp = timestamp.strip()
    chunk, millis = timestamp.split(',')
    hours, minutes, seconds = chunk.split(':')
    hours = int(hours)
    minutes = int(minutes)
    seconds = int(seconds)
    seconds = seconds + hours * 60 * 60 + minutes * 60 + float(millis) / 1000
    return seconds


def precheck():
    """
    Pre-execution Dependency Check
    """
    return True


def p_quantifier_at_least_x_times(p):
    """quantifier : K_AT K_LEAST NUMBER K_TIMES"""
    p[0] = [('at_least', (p[3],))]


def _is_controlled(gate):
    """Determine if a gate is controlled.

    Args:
        gate (pyquil.quil.Gate): The gate that should be checked

    Returns:
        bool: True if the gate is controlled, False otherwise
    """
    return 'CONTROLLED' in gate.modifiers


def pizza():
    """
    Open browser loaded with pizza options near you.

    *Disclaimers: Payments not included. Astropy is not
    responsible for any liability from using this function.*

    .. note:: Accuracy depends on your browser settings.

    """
    import webbrowser
    webbrowser.open('https://www.google.com/search?q=pizza+near+me')


def false():
    """
    Always returns False.

    Complexity: O(1)
    returns: False
    """
    return False


@classmethod
def from_tuple(cls, data):
    """
        Create circle instance from tuple of three elements.
        """
    if len(data) == 2:
        return cls(data[0], data[1])
    elif len(data) == 3:
        return cls(data[:2], data[2])
    raise ValueError('Incorrect length of data parameter')


def sanatize_file_name(filename):
    """ replace illegal Windows file name characters with '-'

    (there's an additional set of path characters that are
     illegal only for Windows' .zip compression)
    """
    invalid_chrs = {'\\': '-', '/': '-', ':': '-', '*': '-', '?': '-', '<':
        '-', '>': '-', '|': '-', '"': '-'}
    for k, v in invalid_chrs.items():
        filename = filename.replace(k, v)
    return filename


def split_ons_coda_prob(string, onsets, codas):
    """
    Guesses the split between onset and coda in a string

    Parameters
    ----------
    string : iterable
        the phones to search through
    onsets : iterable
        an iterable of possible onsets
    codas : iterable
        an iterable of possible codas

    Returns
    -------
    int
        best guess for the index in the string where the onset ends and coda begins
    """
    if len(string) == 0:
        return None
    max_prob = -10000
    best = None
    for i in range(len(string) + 1):
        prob = 0
        cod = tuple(string[:i])
        ons = tuple(string[i:])
        if ons not in onsets:
            prob += onsets[None]
        else:
            prob += onsets[ons]
        if cod not in codas:
            prob += codas[None]
        else:
            prob += codas[cod]
        if prob > max_prob:
            max_prob = prob
            best = i
    return best


def delete_cache_security_group(CacheSecurityGroupName=None):
    """
    Deletes a cache security group.
    See also: AWS API Documentation

    :example: response = client.delete_cache_security_group(
        CacheSecurityGroupName='string'
    )

    :type CacheSecurityGroupName: string
    :param CacheSecurityGroupName: [REQUIRED]
            The name of the cache security group to delete.
            Note
            You cannot delete the default security group.

    """
    pass


@classmethod
def lazy(cls, cls_dict, func):
    """Put a LazyOnClass object in *cls_dict* with the same name as *func*"""
    cls_dict[func.__name__] = cls(func)


def get_node_at_path(tree, path):
    """
    `tree` is a lxml etree.
    `path` is either a list of indices (integer) or
    a single integer.
    It returns the lxml node of the tree at path `path`.
    """
    assert isinstance(path, list) or isinstance(path, int)
    if isinstance(path, int):
        path = [path]
    node = tree
    for d in path:
        try:
            node = node[d]
        except IndexError:
            raise (IndexError,
                'Attempted to index subtree {0} with path {1}'.format(tree.
                get('id'), path))
    return node


def _plus(lhs=None, rhs=None, name=None, attr=None, out=None, **kwargs):
    """Adds arguments element-wise.

    The storage type of ``elemwise_add`` output depends on storage types of inputs

       - elemwise_add(row_sparse, row_sparse) = row_sparse
       - elemwise_add(csr, csr) = csr
       - elemwise_add(default, csr) = default
       - elemwise_add(csr, default) = default
       - elemwise_add(default, rsp) = default
       - elemwise_add(rsp, default) = default
       - otherwise, ``elemwise_add`` generates output with default storage

    Parameters
    ----------
    lhs : Symbol
        first input
    rhs : Symbol
        second input

    name : string, optional.
        Name of the resulting symbol.

    Returns
    -------
    Symbol
        The result symbol.
    """
    return 0,


def update_rho(rho, rnorm, snorm, iteration=None, mu=10, tau_inc=2, tau_dec=2):
    """See Boyd pag 20-21 for details.

    Parameters
    ----------
    rho : float
    """
    if rnorm > mu * snorm:
        return tau_inc * rho
    elif snorm > mu * rnorm:
        return rho / tau_dec
    return rho


def setGlobalPrintFullStrings(enabled=False):
    """
    When enabled, Container __str__ produces full content of bytes and unicode strings, otherwise and by default, it produces truncated output (16 bytes and 32 characters).

    :param enabled: bool
    """
    global globalPrintFullStrings
    globalPrintFullStrings = enabled


def assert_called_with(_mock_self, *args, **kwargs):
    """assert that the mock was called with the specified arguments.

        Raises an AssertionError if the args and keyword args passed in are
        different to the last call to the mock."""
    self = _mock_self
    if self.call_args is None:
        expected = self._format_mock_call_signature(args, kwargs)
        raise AssertionError('Expected call: %s\nNot called' % (expected,))
    if self.call_args != (args, kwargs):
        msg = self._format_mock_failure_message(args, kwargs)
        raise AssertionError(msg)


@classmethod
def expm(cls, mx):
    """Return matrix exponential of matrix `mx` """
    raise NotImplementedError


def pad(text, block_size, zero=False):
    """
    Given a text string and a block size, pads the text with bytes of the same value
    as the number of padding bytes. This is the recommended method, and the one used
    by pgcrypto. See http://www.di-mgt.com.au/cryptopad.html for more information.
    """
    num = block_size - len(text) % block_size
    ch = b'\x00' if zero else chr(num).encode('latin-1')
    return text + ch * num


@classmethod
def is_windows(cls):
    """
        Checks if the current platform is in our windows list.

        :rtype: bool
        """
    return cls.get() in cls.WINDOWS


def prod_spec_names(sensortype, subversion, config):
    """
    Get specific names for sensortype version

    Parameters
    ----------
    sensortype str
        Product type: active, passive, combined
    subversion : str
        Subversion identifier. eg. '02'
    config : configparser.configparser
        config parser to replace values in

    Returns
    -------
    config : configparser.configparser
        The updated configuration parser
    """
    sensor_abbr = {'ACTIVE': 'SSMS', 'PASSIVE': 'SSMV', 'COMBINED': 'SSMV'}
    sm_units_dict = {'ACTIVE': 'percentage (%)', 'PASSIVE': 'm3 m-3',
        'COMBINED': 'm3 m-3'}
    sm_full_name_dict = {'ACTIVE': 'Percent of Saturation Soil Moisture',
        'PASSIVE': 'Volumetric Soil Moisture', 'COMBINED':
        'Volumetric Soil Moisture'}
    sm_uncertainty_full_name_dict = {'ACTIVE':
        'Percent of Saturation Soil Moisture Uncertainty', 'PASSIVE':
        'Volumetric Soil Moisture Uncertainty', 'COMBINED':
        'Volumetric Soil Moisture Uncertainty'}
    sensortype = sensortype.upper()
    product = config.get('GLOBAL', 'product').format(sensor_abbr=
        sensor_abbr[sensortype], sensortype=sensortype, subversion=subversion)
    config.set('GLOBAL', 'product', product)
    config.set('SM', 'full_name', sm_full_name_dict[sensortype])
    config.set('SM', 'units', sm_units_dict[sensortype])
    config.set('SM_UNCERTAINTY', 'full_name', sm_uncertainty_full_name_dict
        [sensortype])
    config.set('SM_UNCERTAINTY', 'units', sm_units_dict[sensortype])
    return config


def get_files(extension='.pck'):
    """Like the 'files' attribute, but accepts an alternative extension.

        Only the files in the queue directory that have a matching extension
        are returned.  Like 'files', the base names of the matching files are
        returned.
        """