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


@classmethod
def from_values(cls, *args, **kwargs):
    """Create a new request object based on the values provided.  If
        environ is given missing values are filled from there.  This method is
        useful for small scripts when you need to simulate a request from an URL.
        Do not use this method for unittesting, there is a full featured client
        object (:class:`Client`) that allows to create multipart requests,
        support for cookies etc.

        This accepts the same options as the
        :class:`~werkzeug.test.EnvironBuilder`.

        .. versionchanged:: 0.5
           This method now accepts the same arguments as
           :class:`~werkzeug.test.EnvironBuilder`.  Because of this the
           `environ` parameter is now called `environ_overrides`.

        :return: request object
        """
    from ..test import EnvironBuilder
    charset = kwargs.pop('charset', cls.charset)
    kwargs['charset'] = charset
    builder = EnvironBuilder(*args, **kwargs)
    try:
        return builder.get_request(cls)
    finally:
        builder.close()


def display_string_output(obj):
    """
    Display a string
        :param obj:
    """
    print(obj)


def make_callable(funcname):
    """
    Return a callable object from a string.

    This function resolves a name into a callable object. It automatically
    loads the required modules. If there is no module path, it considers the
    callable is a builtin.

    :param funcname: name of the callable.
    :type  funcname: str.

    :returns:
        :rtype: callable.

    Examples
    --------

    Loading a function from a library:

    >>> func = make_callable('itertools.chain')
    >>> list(func(range(3), range(4)))
    [0, 1, 2, 0, 1, 2, 3]

    Loading a builtin:

    >>> func = make_callable('map')
    >>> list(func(lambda x: x + 1, range(4)))
    [1, 2, 3, 4]

    """
    if '.' not in funcname:
        module_name = 'builtins'
        object_name = funcname
    else:
        module_name, object_name = funcname.rsplit('.', 1)
    module = __import__(module_name, fromlist=['*'])
    try:
        callable_ = getattr(module, object_name)
    except AttributeError:
        raise AttributeError('module {} has no attribute {}'.format(module.
            __name__, object_name))
    return callable_


def arrstatmask(im, mask):
    """ Basic statistics for a masked array. dont wanna use numpy.ma """
    import numpy as N
    ind = N.where(~mask)
    im1 = im[ind]
    av = N.mean(im1)
    std = N.std(im1)
    maxv = N.max(im1)
    x, y = N.where(im == maxv)
    xmax = x[0]
    ymax = y[0]
    minv = N.min(im1)
    x, y = N.where(im == minv)
    xmin = x[0]
    ymin = y[0]
    return av, std, maxv, (xmax, ymax), minv, (xmin, ymin)


def _get_annotations(generator):
    """ Get the ground truth annotations from the generator.

    The result is a list of lists such that the size is:
        all_detections[num_images][num_classes] = annotations[num_detections, 5]

    # Arguments
        generator : The generator used to retrieve ground truth annotations.
    # Returns
        A list of lists containing the annotations for each image in the generator.
    """
    all_annotations = [[None for i in range(generator.num_classes())] for j in
        range(generator.size())]
    for i in range(generator.size()):
        annotations = generator.load_annotations(i)
        for label in range(generator.num_classes()):
            all_annotations[i][label] = annotations[(annotations[:, (4)] ==
                label), :4].copy()
        print('{}/{}'.format(i + 1, generator.size()), end='\r')
    return all_annotations


def load_email(finder, module):
    """the email package has a bunch of aliases as the submodule names were
       all changed to lowercase in Python 2.5; mimic that here."""
    for name in ('Charset', 'Encoders', 'Errors', 'FeedParser', 'Generator',
        'Header', 'Iterators', 'Message', 'Parser', 'Utils', 'base64MIME',
        'quopriMIME'):
        finder.AddAlias('email.%s' % name, 'email.%s' % name.lower())


def arrow_formatter(view, arrow_time):
    """
        Return human-friendly string of the time relative to now.
        see https://arrow.readthedocs.io/

        :param arrow_time:
            Arrow object for handling datetimes
    """
    return arrow_time.humanize()


@staticmethod
def supports_site(url):
    """
        Recursive Crawler are supported by every site!

        Determines if this crawler works on the given url.

        :param str url: The url to test
        :return bool: Determines wether this crawler work on the given url
        """
    return True


def reflect(data, width):
    """Ceflect a data word, means revert the bit order."""
    reflected = data & 1
    for _ in range(width - 1):
        data >>= 1
        reflected = reflected << 1 | data & 1
    return reflected


@classmethod
def update(cls, status_dir):
    """Update all job statuses and dump to json.

        Parameters
        ----------
        status_dir : str
            Directory containing json status file.
        """
    obj = cls(status_dir)
    for module in obj.data.keys():
        for job_name in obj.data[module].keys():
            if job_name != 'pipeline_index':
                obj._update_job_status(module, job_name)
    obj._check_all_job_files(status_dir)
    obj._dump()


def dupliob_move_up():
    """Move dupli object up in the list

    """
    pass


@classmethod
def ParseVHDLSeverityLevel(cls, severity, fallback=None):
    """Translate a VHDL severity level into logging severity level."""
    return cls.__VHDL_SEVERITY_LEVEL_MAP__.get(severity, fallback)


def PolsOther(t):
    """Number of policies: Other benefits"""
    return 0


@property
def challenge(cls):
    """
        Retrieve and cache the related challenge.

        :return: The challenge that is related to this device
        :rtype: type of rest_multi_factor.models.mixins.ChallengeMixin
        """
    if hasattr(cls, '_challenge'):
        return getattr(cls, '_challenge')
    relations = getattr(cls, '_meta').related_objects
    challenge = cls._get_challenge(relations)
    setattr(cls, '_challenge', challenge)
    return challenge


def is_pc(note):
    """check if note has the same format as pc, return boolean"""
    return note in range(12)


def weight_generator():
    """ Used for weight generation by calculate_731_checksum
    """
    while True:
        yield 7
        yield 3
        yield 1


def listDictToHtmlTable(listDict):
    """return string containing html code for table"""
    result = '
'
    if len(listDict) > 0:
        result += '

'
        for key in listDict[0]:
            result += '' + str(key) + '	'
        result += '

'
        for item in listDict:
            result += '
'
            for key in item:
                result += '' + str(item[key]) + '	'
            result += '
'
        result += '
'
    result += '
'
    return result


def _gm(x):
    """Returns the geometric means of the rows in `x`.

    Parameters
    ----------
    x : NumPy array, shape (k,n)
        The k compositions whose geometric means are to be computed.

    Returns
    -------
    x_gm : NumPy array, shape (k,)
        The geometric means for the k compositions in `x`.

    """
    last_axis = -1
    x_gm = x.prod(axis=last_axis) ** (1 / x.shape[last_axis])
    return x_gm


def format_interval(t):
    """
    Formats a number of seconds as a clock time, [H:]MM:SS

    Parameters
    ----------
    t  : int
        Number of seconds.
    Returns
    -------
    out  : str
        [H:]MM:SS
    """
    mins, s = divmod(int(t), 60)
    h, m = divmod(mins, 60)
    if h:
        return '{0:d}:{1:02d}:{2:02d}'.format(h, m, s)
    else:
        return '{0:02d}:{1:02d}'.format(m, s)


def getTrivialMapping(target, chain):
    """Returns lists of matching residues (map based on residue number)."""
    target_list = []
    chain_list = []
    n_match = 0
    n_mapped = 0
    chain_dict_get = chain._dict.get
    append = target_list.append
    for target_residue in target:
        append(target_residue.getResidue())
        chain_residue = chain_dict_get((target_residue.getResnum(),
            target_residue.getIcode()))
        if chain_residue is None:
            chain_list.append(chain_residue)
        else:
            if target_residue.getResname() == chain_residue.getResname():
                n_match += 1
            chain_list.append(chain_residue.getResidue())
            n_mapped += 1
    return target_list, chain_list, n_match, n_mapped


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

        :param EmmChangePolicyDetails val:
        :rtype: EventDetails
        """
    return cls('emm_change_policy_details', val)


def pairwise(iterable):
    """s -> (s0,s1), (s1,s2), (s2, s3), ..."""
    from itertools import tee
    a, b = tee(iterable)
    next(b, None)
    return zip(a, b)


def get_header(title, symbol, size):
    """
    Display a header of the given size, filled with the given symbol
    with the title in the center
    """
    title_len = len(title)
    symbol_nb = (size - title_len) // 2
    return symbol * symbol_nb + title + symbol * symbol_nb


def stripnull(string, null=b'\x00'):
    """Return string truncated at first null character.

    Clean NULL terminated C strings. For unicode strings use null='\\0'.

    >>> stripnull(b'string\\x00')
    b'string'
    >>> stripnull('string\\x00', null='\\0')
    'string'

    """
    i = string.find(null)
    return string if i < 0 else string[:i]


def _to_flat_ndarray(data, copy=True):
    """
    Convert a (possibly masked) numpy array into its flat equivalent, with or without copying it.

    :param data:
    :param copy:
    :return:
    """
    import numpy as np
    if isinstance(data, np.ma.MaskedArray):
        if not copy:
            raise ValueError('Masked arrays must always be copied.')
        ndarr = data.astype(np.float64).filled(np.NaN).flatten()
    elif copy:
        ndarr = data.flatten()
    else:
        ndarr = data.ravel()
    return ndarr


def write_subuid_file(filename, subuids, mode='w'):
    """Writes out the given list of subuids to the filename"""
    with open(filename, mode) as f:
        for subuid in subuids:
            f.write('%s\n' % subuid)


def none_to_empty_list(*args):
    """Replaces None inputs with an empty list

    Examples
    --------
    Single input case

    >>> none_to_empty_list(None)
    []

    Multiple input case

    >>> a, b, c = None, 'woo', 34
    >>> none_to_empty_list(a, b, c)
    [[], 'woo', 34]
    """
    outputs = []
    for arg in args:
        outputs.append(arg if arg is not None else [])
    if len(outputs) == 1:
        return outputs[0]
    else:
        return outputs


def extended_gcd(a, b):
    """Returns a tuple (r, i, j) such that r = gcd(a, b) = ia + jb
    """
    x = 0
    y = 1
    lx = 1
    ly = 0
    oa = a
    ob = b
    while b != 0:
        q = a // b
        a, b = b, a % b
        x, lx = lx - q * x, x
        y, ly = ly - q * y, y
    if lx < 0:
        lx += ob
    if ly < 0:
        ly += oa
    return a, lx, ly


def _parse_codeargs(argstr):
    """
    Parse and clean up argument to user code; separate *args from
    **kwargs.
    """
    args = []
    kwargs = {}
    if isinstance(argstr, str):
        for a in argstr.split():
            if '=' in a:
                k, attr = a.split('=')
                kwargs[k] = attr
            else:
                args.append(a)
    rd = {'args': args, 'kwargs': kwargs}
    return rd


def define(hub):
    """
    Return the definition used by the runtime to insert the conditions of the
    given requisite
    """
    return {'result': [True, None], 'resolver': 'any'}


def ema(data, period=10):
    """
        [Description] : Utility method to calculate exponential moving averages over a period.
    """
    result = [0] * len(data)
    for i, j in enumerate(data):
        if i < period - 1:
            result[i] = 0
        elif i == period - 1:
            result[i] = sum(data[:period]) / period
        else:
            result[i] = j * 2 / (period + 1) + result[i - 1] * (1 - 2 / (
                period + 1))
    return result


def slurp(path):
    """Read the specified file into a string."""
    with open(path) as f:
        return f.read()


@classmethod
def modify_url_for_impersonation(cls, url, impersonate_user, username):
    """
        Modify the SQL Alchemy URL object with the user to impersonate if applicable.
        :param url: SQLAlchemy URL object
        :param impersonate_user: Bool indicating if impersonation is enabled
        :param username: Effective username
        """
    pass


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

        :param PrimaryTeamRequestReminderDetails val:
        :rtype: TeamMergeRequestReminderExtraDetails
        """
    return cls('primary_team', val)


def _chao1_var_no_doubletons(s, chao1):
    """Calculates chao1 variance in absence of doubletons.

    From EstimateS manual, equation 7.

    `s` is the number of singletons, and `chao1` is the estimate of the mean of
    Chao1 from the same dataset.

    """
    return s * (s - 1) / 2 + s * (2 * s - 1) ** 2 / 4 - s ** 4 / (4 * chao1)


def write_pdb(ofile, c):
    """ Write the Crys in .pdb file format"""
    print(
        'CRYST1{0:>9.3f}{1:>9.3f}{2:>9.3f}{3:>7.2f}{4:>7.2f}{5:>7.2f} P 1           1'
        .format(c.length[0], c.length[1], c.length[2], c.angle_deg[0], c.
        angle_deg[1], c.angle_deg[2]), file=ofile)
    for i in range(c.natom):
        print(
            '%-6s%5d %4s%1s%3s %1s%4d%1s   %8.5f%8.5f%8.5f%6.2f%6.2f          %2s%2s'
             % ('ATOM', i + 1, c.atom_element[i], '', 'XXX', 'X', 1, '', c.
            atom_fract[i][0], c.atom_fract[i][1], c.atom_fract[i][2], 1.0,
            0.0, c.atom_element[i], ''), file=ofile)
    return


def None2NULL(o, d):
    """Convert None to NULL."""
    return b'NULL'


def is_dataframe(obj):
    """
    Returns True if the given object is a Pandas Data Frame.

    Parameters
    ----------
    obj: instance
        The object to test whether or not is a Pandas DataFrame.
    """
    try:
        from pandas import DataFrame
        return isinstance(obj, DataFrame)
    except ImportError:
        return obj.__class__.__name__ == 'DataFrame'


@classmethod
def getInitialDisplayRange(cls):
    """This class method returns a tuple containing ``(low, high)``
        percentile values which are used to set the initial values for the
        :attr:`.ColourMapOpts.displayRange` and
        :attr:`.ColourMapOpts.clippingRange` properties. If the initial
        display range has not yet been set (via the
        :meth:`setInitialDisplayRange` method), ``None`` is returned.
        """
    try:
        return cls.__initialDisplayRange
    except AttributeError:
        return None


def time_for_json(value):
    """
    Return a Python ``datetime``, and rely on the JSON encoder in
    :mod:`da.protocols.ser_json` to do the appropriate conversion.
    """
    return value


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


def sum_(*args):
    """first argument: ``iterable``.

    second argument: ``start`` (default: 0)

    A drop-in replacement of ``sum`` with arbitrary type.
    The only requirement is the type of elements in ``iterable``
    has `__iadd__` method and is compatible with each other.
    ``start`` is not used except for empty iterable in which case it
    is returned.
    """
    from copy import deepcopy
    iterable = iter(args[0])
    start = args[1] if len(args) > 1 else 0
    try:
        result = deepcopy(next(iterable))
        for i in iterable:
            result += i
        return result
    except StopIteration:
        return start


@classmethod
def all(cls, name, range_key):
    """ Create an index that projects all attributes """
    return cls(cls.ALL, name, range_key)


def localview(frame_selected: bool=True):
    """Toggle display of selected object(s) separately and centered in view

    :param frame_selected: Frame Selected, Move the view to frame the selected objects
    :type frame_selected: bool
    """
    pass


def get_type(bind):
    """ Detect the ideal type for the data, either using the explicit type
    definition or the format (for date, date-time, not supported by JSON). """
    types = bind.types + [bind.schema.get('format')]
    for type_name in ('date-time', 'date', 'decimal', 'integer', 'boolean',
        'number', 'string'):
        if type_name in types:
            return type_name
    return 'string'


def add(image1, image2, scale=1.0, offset=0):
    """
    Adds two images, dividing the result by scale and adding the
    offset. If omitted, scale defaults to 1.0, and offset to 0.0.
    At least one of the images must have mode "1".

    .. code-block:: python

        out = ((image1 + image2) / scale + offset)

    :rtype: :py:class:`~PIL.Image.Image`
    """
    image1.load()
    image2.load()
    return image1._new(image1.im.chop_add(image2.im, scale, offset))


@classmethod
def export_to_hdf5(cls, h5_file, model, nids):
    """exports the nodes in a vectorized way"""
    comments = []
    cp = []
    xyz = []
    cd = []
    ps = []
    seid = []
    for nid in nids:
        node = model.nodes[nid]
        xyz.append(node.xyz)
        cp.append(node.cp)
        cd.append(node.cd)
        psi = 0 if node.ps == '' else int(node.ps)
        ps.append(psi)
        seid.append(node.seid)
    h5_file.create_dataset('nid', data=nids)
    h5_file.create_dataset('xyz', data=xyz)
    h5_file.create_dataset('cp', data=cp)
    h5_file.create_dataset('cd', data=cd)
    h5_file.create_dataset('ps', data=ps)
    h5_file.create_dataset('seid', data=seid)


@staticmethod
def set_options(options, parameters):
    """ set attributes for create or modify """
    if parameters.get('home_port') is not None:
        options['home-port'] = parameters['home_port']
    if parameters.get('subnet_name') is not None:
        options['subnet-name'] = parameters['subnet_name']
    if parameters.get('address') is not None:
        options['address'] = parameters['address']
    if parameters.get('netmask') is not None:
        options['netmask'] = parameters['netmask']
    if parameters.get('failover_policy') is not None:
        options['failover-policy'] = parameters['failover_policy']
    if parameters.get('firewall_policy') is not None:
        options['firewall-policy'] = parameters['firewall_policy']
    if parameters.get('is_auto_revert') is not None:
        options['is-auto-revert'] = 'true' if parameters['is_auto_revert'
            ] is True else 'false'
    if parameters.get('admin_status') is not None:
        options['administrative-status'] = parameters['admin_status']
    if parameters.get('force_subnet_association') is not None:
        options['force-subnet-association'] = 'true' if parameters[
            'force_subnet_association'] else 'false'
    if parameters.get('dns_domain_name') is not None:
        options['dns-domain-name'] = parameters['dns_domain_name']
    if parameters.get('listen_for_dns_query') is not None:
        options['listen-for-dns-query'] = str(parameters[
            'listen_for_dns_query'])
    if parameters.get('is_dns_update_enabled') is not None:
        options['is-dns-update-enabled'] = str(parameters[
            'is_dns_update_enabled'])


def guess_url(web_dir, host, user):
    """Guess the base url from the host name

    Parameters
    ----------
    web_dir: str
        path to the web directory where you want the data to be saved
    host: str
        the host name of the machine where the python interpreter is currently
        executing
    user: str
        the user that is current executing the python interpreter
    """
    ligo_data_grid = False
    if 'public_html' in web_dir:
        ligo_data_grid = True
    if ligo_data_grid:
        path = web_dir.split('public_html')[1]
        if 'raven' in host or 'arcca' in host:
            url = 'https://geo2.arcca.cf.ac.uk/~{}'.format(user)
        elif 'ligo-wa' in host:
            url = 'https://ldas-jobs.ligo-wa.caltech.edu/~{}'.format(user)
        elif 'ligo-la' in host:
            url = 'https://ldas-jobs.ligo-la.caltech.edu/~{}'.format(user)
        elif 'cit' in host or 'caltech' in host:
            url = 'https://ldas-jobs.ligo.caltech.edu/~{}'.format(user)
        elif 'uwm' in host or 'nemo' in host:
            url = 'https://ldas-jobs.phys.uwm.edu/~{}'.format(user)
        elif 'phy.syr.edu' in host:
            url = 'https://sugar-jobs.phy.syr.edu/~{}'.format(user)
        elif 'vulcan' in host:
            url = 'https://galahad.aei.mpg.de/~{}'.format(user)
        elif 'atlas' in host:
            url = 'https://atlas1.atlas.aei.uni-hannover.de/~{}'.format(user)
        elif 'iucca' in host:
            url = 'https://ldas-jobs.gw.iucaa.in/~{}'.format(user)
        elif 'hawk' in host:
            url = 'https://ligo.gravity.cf.ac.uk/~{}'.format(user)
        else:
            url = 'https://{}/~{}'.format(host, user)
        url += path
    else:
        url = 'https://{}'.format(web_dir)
    return url


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


def stop_process(modeladmin, request, queryset):
    """
    restarts a dedicated process
    :return:
    """
    for process in queryset:
        process.stop()


@classmethod
def is_datasource_for(cls, **kwargs):
    """
        Determines if the file corresponds to a RHESSI X-ray Summary
        `~sunpy.timeseries.TimeSeries`.
        """
    if 'source' in kwargs.keys():
        if kwargs.get('source', ''):
            return kwargs.get('source', '').lower().startswith(cls._source)
    if 'meta' in kwargs.keys():
        return kwargs['meta'].get('telescop', '').startswith('HESSI')


def mallow(y, y_pred, y_sub, k, p):
    """
    Return an mallows Cp score for a model.

    Input:
    y: array-like of shape = (n_samples) including values of observed y
    y_pred: vector including values of predicted y
    k: int number of predictive variable(s) used in the model
    p: int number of predictive variable(s) used in the sub model

    Output:
    mallow_score: int or float Mallows Cp score of the model and sub model

    Raise InputError if k is less than p.
    Raise InputError if y , y_sub and y_pred are not in same length.
    Raise InputError if length(y) <= 1, length(y_sub)<=1, or length(y_pred) <= 1.
    Raise TypeError if y , y_sub and y_pred are not vector.
    Raise TypeError if p is not int.
    Raise InputError if p < 0.
    Raise TypeError if k is not int.
    Raise InputError if k < 0.
    """
    import numpy as np
    import pandas as pd
    if k < p:
        raise ValueError(
            'number of predictive variable(s) used in the model must larger than in subset model'
            )
    if len(y) != len(y_sub) or len(y_sub) != len(y_pred) or len(y) != len(
        y_pred):
        raise ValueError(
            'The length of observed y, predicted y, and predicted y in subset model must be same'
            )
    if len(y) <= 1 or len(y_sub) <= 1 or len(y) <= 1:
        raise ValueError(
            'The length of observed y, predicted y, and predicted y in subset model must be larger than 1'
            )
    if isinstance(y, (np.ndarray, list, tuple, pd.core.series.Series)
        ) == False or isinstance(y_pred, (np.ndarray, list, tuple, pd.core.
        series.Series)) == False:
        raise TypeError(
            'The observed y, predicted y, and predicted y in subset model must be array-like shape (e.g. array, list, tuple, data column)'
            )
    else:
        for i in y:
            for j in y_pred:
                if isinstance(i, (int, float)) != True or isinstance(j, (
                    int, float)) != True:
                    raise TypeError(
                        'The observed y, predicted y, and predicted y in subset model must be numeric elements'
                        )
    if isinstance(p, int) != True or isinstance(k, int) != True:
        raise TypeError(
            'The number of predictive variable(s) used in the sub model must be integer'
            )
    if p <= 0 or k <= 0:
        raise Exception(
            'The number of predictive variable(s) used in the sub model must be positive'
            )
    if isinstance(y, list) == True:
        y = np.array(y)
    if isinstance(y_sub, list) == True:
        y_sub = np.array(y_sub)
    if isinstance(y_pred, list) == True:
        y_pred = np.array(y_pred)
    SSE_p = np.sum((y - y_sub) ** 2)
    MSE = np.sum((y - y_pred) ** 2) / (len(y) - k)
    mallowcp = SSE_p / MSE - len(y) + 2 * p
    return mallowcp


def click_select(wait_to_deselect_others: bool=False, mouse_x: int=0,
    mouse_y: int=0, extend: bool=False, deselect_all: bool=False):
    """Handle clicks to select NLA Strips

    :param wait_to_deselect_others: Wait to Deselect Others
    :type wait_to_deselect_others: bool
    :param mouse_x: Mouse X
    :type mouse_x: int
    :param mouse_y: Mouse Y
    :type mouse_y: int
    :param extend: Extend Select
    :type extend: bool
    :param deselect_all: Deselect On Nothing, Deselect all when nothing under the cursor
    :type deselect_all: bool
    """
    pass


def _flow_priority_offset_from_conj_id(conj_id):
    """Return a flow priority offset encoded in a conj_id."""
    return conj_id % 8 // 2


def set_termination_protection(JobFlowIds=None, TerminationProtected=None):
    """
    SetTerminationProtection locks a cluster (job flow) so the EC2 instances in the cluster cannot be terminated by user intervention, an API call, or in the event of a job-flow error. The cluster still terminates upon successful completion of the job flow. Calling SetTerminationProtection on a cluster is similar to calling the Amazon EC2 DisableAPITermination API on all EC2 instances in a cluster.
    To terminate a cluster that has been locked by setting SetTerminationProtection to true , you must first unlock the job flow by a subsequent call to SetTerminationProtection in which you set the value to false .
    For more information, see`Managing Cluster Termination`_ in the Amazon EMR Management Guide .
    See also: AWS API Documentation

    :example: response = client.set_termination_protection(
        JobFlowIds=[
            'string',
        ],
        TerminationProtected=True|False
    )

    :type JobFlowIds: list
    :param JobFlowIds: [REQUIRED]
            A list of strings that uniquely identify the clusters to protect. This identifier is returned by RunJobFlow and can also be obtained from DescribeJobFlows .
            (string) --

    :type TerminationProtected: boolean
    :param TerminationProtected: [REQUIRED]
            A Boolean that indicates whether to protect the cluster and prevent the Amazon EC2 instances in the cluster from shutting down due to API calls, user intervention, or job-flow error.

    """
    pass


def context(input):
    """Return the context/device of the input tensor.

    Parameters
    ----------
    input : Tensor
        The input tensor.

    Returns
    -------
    Context object
        A framework-specific context object.
    """
    pass


def compute_constants(params):
    """ compute_constants parameters

    Parameters :
    ------------
    params : dict of setup parameters

    Returns :
    ---------
    const : dict of constant parameters
    """
    const = {}
    const['h_ratio'] = params['h_cold'] / params['h_hot']
    const['biot'] = params['h_hot'] * params['width'] / params['lambda']
    const['t_ref'] = params['t_cold'] + (params['t_hot'] - params['t_cold']
        ) * (1.0 / (1.0 + const['h_ratio']))
    const['dx'] = params['typ_size'] / params['res']
    const['lam_ov_rhocp'] = params['lambda'] / (params['rho'] * params['cp'])
    const['dt'] = params['fourier'] * const['dx'] ** 2 / const['lam_ov_rhocp']
    const['total_time'] = params['typ_size'] ** 2 / const['lam_ov_rhocp']
    const['exp_iterations'] = const['total_time'] / const['dt']
    for key in const:
        print(key + ':' + str(const[key]))
    return const


def create_policy_version(PolicyArn=None, PolicyDocument=None, SetAsDefault
    =None):
    """
    Creates a new version of the specified managed policy. To update a managed policy, you create a new policy version. A managed policy can have up to five versions. If the policy has five versions, you must delete an existing version using  DeletePolicyVersion before you create a new version.
    Optionally, you can set the new version as the policy's default version. The default version is the version that is in effect for the IAM users, groups, and roles to which the policy is attached.
    For more information about managed policy versions, see Versioning for Managed Policies in the IAM User Guide .
    See also: AWS API Documentation

    :example: response = client.create_policy_version(
        PolicyArn='string',
        PolicyDocument='string',
        SetAsDefault=True|False
    )

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

    :type PolicyDocument: string
    :param PolicyDocument: [REQUIRED]
            The JSON policy document that you want to use as the content for this new version of the policy.
            The regex pattern used to validate this parameter is a string of characters consisting of any printable ASCII character ranging from the space character (u0020) through end of the ASCII character range as well as the printable characters in the Basic Latin and Latin-1 Supplement character set (through u00FF). It also includes the special characters tab (u0009), line feed (u000A), and carriage return (u000D).

    :type SetAsDefault: boolean
    :param SetAsDefault: Specifies whether to set this version as the policy's default version.
            When this parameter is true , the new policy version becomes the operative version; that is, the version that is in effect for the IAM users, groups, and roles that the policy is attached to.
            For more information about managed policy versions, see Versioning for Managed Policies in the IAM User Guide .

    :rtype: dict
    :return: {
        'PolicyVersion': {
            'Document': 'string',
            'VersionId': 'string',
            'IsDefaultVersion': True|False,
            'CreateDate': datetime(2015, 1, 1)
        }
    }

    """
    pass


@staticmethod
def tag_end(tag):
    """Build closed tag info.

        :param tag: tag name
        :rtype: str
        """
    return '</{}>'.format(tag)


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

        :param FolderOverviewItemUnpinnedType val:
        :rtype: EventType
        """
    return cls('folder_overview_item_unpinned', val)


def clamp(x, low, high):
    """Clamps a number between two numbers

    Args:
        x: the number to clamp
        low: the minimum value the number can have
        high: the maximum value the number can have
    Returns:
        the value of x clamped between low and high
    """
    if x < low:
        return low
    elif x > high:
        return high
    else:
        return x


def create(title='Untitled object', layout='tile', retJson=True):
    """ Create 'Anz Dashboard' instance

        @param title
        title of the new instance( default 'Untitled object' )

        @param layout
        layout of dashboard pages, one of 'tab' and 'tile'( default 'tile' )

        @retJson
        format return value to json format or not( default True )

        @return status of create process
        json data:
        {
            success: True,
            msg: 'Create "Anz Dashboard" instance success.',
            id: 'id1',
            title: 'title',
            url: 'url',
            path: 'path'
        }

        """


@classmethod
def list_by_node_id(cls, context, node_id, limit=None, marker=None,
    sort_key=None, sort_dir=None):
    """Return a list of VolumeConnector objects related to a given node ID.

        :param context: security context
        :param node_id: the integer ID of the node
        :param limit: maximum number of resources to return in a single result
        :param marker: pagination marker for large data sets
        :param sort_key: column to sort results by
        :param sort_dir: direction to sort. "asc" or "desc".
        :returns: a list of :class:`VolumeConnector` objects
        :raises: InvalidParameterValue if sort_key does not exist
        """
    db_connectors = cls.dbapi.get_volume_connectors_by_node_id(node_id,
        limit=limit, marker=marker, sort_key=sort_key, sort_dir=sort_dir)
    return cls._from_db_object_list(context, db_connectors)


def calc_radii_sep_from_seps(sep_proj_ext, sep_proj_int):
    """Calculate the radii of both binary stars from projections of star separations
    at external and internal tangencies. Method is independent of any inclination assumptions.

    Parameters
    ----------
    sep_proj_ext : float
        Projected separation of star centers at external tangencies.
        (e.g. begin ingress, end egress). Unit is star-star separation distance.
    sep_proj_int : float
        Projected separation of star centers at internal tangencies.
        (e.g. end ingress, begin egress). Unit is star-star separation distance.

    Returns
    -------
    radius_sep_s : float
        Radius of smaller-sized star. Unit is star-star separation distance.
    radius_sep_g : float
        Radius of greater-sized star. Unit is star-star separation distance.

    See Also
    --------
    calc_radii_ratio_from_light, calc_radius_from_velrs_times

    Notes
    -----
    Note: Radii are returned as a tuple: (rs, rg)
    Note: Method does not assume an inclination.
    radii_ratio = radius_sep_s / radius_sep_g
    sep_proj_ext = radius_sep_g * (1 + radii_ratio)
    sep_proj_int = radius_sep_g * (1 - radii_ratio)
    => sep_proj_ext - sep_proj_int = 2 * radius_sep_g * radii_ratio = 2 * radius_sep_s
       radius_sep_s = (sep_proj_ext - sep_proj_int) / 2
    => sep_proj_ext + sep_proj_int = 2 * radius_sep_g
       radius_sep_g = (sep_proj_ext + sep_proj_int) / 2
    From equations 7.8, 7.9, 7.10 in section 7.3 of [1]_.

    References
    ----------
    .. [1] Budding, 2007, Introduction to Astronomical Photometry

    """
    radius_sep_s = (sep_proj_ext - sep_proj_int) / 2.0
    radius_sep_g = (sep_proj_ext + sep_proj_int) / 2.0
    return radius_sep_s, radius_sep_g


def _escape(txt):
    """Basic html escaping."""
    txt = txt.replace('&', '&')
    txt = txt.replace('<', '<')
    txt = txt.replace('>', '>')
    return txt


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


def shift_data(x):
    """Shifts the data under the median.

    Function that takes in a list of data, and shifts all values
    below the median value of the data by the max difference,
    effectively shifting parts of the data periodically in order to
    give clusters for visualization.

    Parameters
    ----------
    x : list
        Floats, data values

    Returns
    -------
    xnorm : list
        Floats where some values are shifted values of x,
        and some are left unchanged.

    """
    xmin, xmax = min(x), max(x)
    xnorm = []
    dx = xmax - xmin
    medix = xmin + 0.5 * dx
    for i in x:
        if i < medix:
            xnorm.append(i + dx)
        else:
            xnorm.append(i)
    return xnorm


def tensor_has_all_integers(tnsr):
    """
    Given a PyTorch tensor (usually floats), returns True if all entries are
    integers, false otherwise
    """
    return bool((tnsr % 1 == 0).all())


def cog_defuzzify(type1_set):
    """
	Centre of gravity defuzzification method

	References:
	-----------
	Pedrycz, Witold. Fuzzy control and fuzzy systems (2nd. Research Studies Press Ltd., 1993.

	Arguments:
	----------
	type1_set   -- Type1FuzzySet, the set whose centroid is to be computed

	Returns:
	--------
	centroid    -- float, the centroid of this set

	Raises:
	-------
	Exception if the denominator of the calculation is zero

	"""
    numerator = 0
    denominator = 0
    for domain_element in type1_set.domain_elements():
        numerator = numerator + domain_element * type1_set[domain_element]
        denominator = denominator + type1_set[domain_element]
    centroid = 0
    if denominator == 0:
        raise Exception('Cannot determine centroid')
    else:
        centroid = numerator / denominator
    return centroid


@staticmethod
def is_valid_wordfreq(word, freq):
    """Validate word and frequency."""
    if not isinstance(word, str):
        raise ValueError(f'word {word} must be a string')
    if not (freq is not None and isinstance(freq, int) and freq != 0):
        raise ValueError(
            f'The frequency {freq} for {word} must be an integer and cannot be zero'
            )
    return True


def set_logger_factory(factory):
    """Set a factory object for creating loggers.  This object must
    publish a method or class named 'get_logger' that takes a string
    parameter naming the logger instance to retrieve.  Logger objects
    returned by this factory must, at a minimum, expose the methods
    'isEnabledFor' and 'debug'.
    """
    global _logger_factory
    _logger_factory = factory


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


def reslice(in_file, new_zooms=None, order=3, out_file=''):
    """
    Performs regridding of an image to set isotropic voxel sizes using dipy.
    """
    import os
    import nibabel as nib
    from neuro_pypes.preproc import reslice_img
    from neuro_pypes.utils import rename
    img = reslice_img(nib.load(in_file), new_zooms=new_zooms, order=order)
    if not out_file:
        out_file = rename(in_file, '_resliced')
    img.to_filename(out_file)
    return os.path.abspath(out_file)


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


def get_hosted_zone_count():
    """
    Retrieves the number of hosted zones that are associated with the current AWS account.
    See also: AWS API Documentation

    :example: response = client.get_hosted_zone_count()

    :rtype: dict
    :return: {
        'HostedZoneCount': 123
    }

    """
    pass


@staticmethod
def long_name_type():
    """
        Returns the long name type for this port.

        :returns: string
        """
    return 'Ethernet'


def track_event(track_events_to, event, sequence):
    """Writes all details necessary to generate event to a file.

    Called each time an event occurs if the track_events_to variable of the CircuitEditor is not None.

    Example contents of the file:
    '<Motion>', serial = 329, state = 8, x = 643, y = 10
    '<Control-MouseWheel>', serial = 335, state = 12, x = 292, y = 239, delta = -120

    Parameters
    ----------
    track_events_to:    string
                        name (or path) of the folder to write to
    event:              Tkinter event
    sequence:           string
                        For example '<ButtonRelease-1>' or 'c'
    """
    to_exclude = ['<Enter>', '<Leave>']
    if sequence not in to_exclude:
        event_string = "'" + sequence + "'"
        for key, value in event.__dict__.items():
            if key in ['when', 'above', 'borderwidth', 'button', 'count',
                'data', 'detail', 'focus', 'height', 'keycode', 'keysym',
                'mode', 'override', 'place', 'root', 'rootx', 'rooty',
                'sendevent', 'serial', 'state', 'subwindow', 'warp',
                'width', 'window', 'x', 'y'
                ] or key == 'delta' and 'MouseWheel' in sequence:
                if value != '??':
                    event_string += ', ' + key + ' = ' + repr(value)
        with open(track_events_to, 'a+') as event_tracking_file:
            event_tracking_file.write(event_string + '\n')


def _split_meta(obj, cols):
    """
    Split out meta fields from core columns.
    """
    meta = obj.pop('meta', {})
    for k in obj.keys():
        if k not in cols:
            meta[k] = obj.pop(k)
    obj['meta'] = meta
    return obj


def file_ipynb(file_name: str) ->bool:
    """
    return True iff file_name ends in .ipynb (i.e., is a Jupyter notebook).
    """
    return file_name[-6:] == '.ipynb'


def add_value(cookie, name, value, lifespan, secure):
    """add a value to a cookie"""
    cookie[name] = value
    cookie[name]['httponly'] = True
    cookie[name]['path'] = '/'
    cookie[name]['expires'] = lifespan
    if secure:
        cookie[name]['secure'] = True


def get_query_without_page(get_params):
    """
    This is used so we can show the pagination properly keeping the search results.
    """
    query_string_without_page = get_params.copy()
    if 'page' in query_string_without_page:
        del query_string_without_page['page']
    return query_string_without_page.urlencode()


def uvs_reverse():
    """Flip direction of UV coordinates inside faces

    """
    pass


def __call__(relchain, query, index, cache):
    """return iterable of queries to search further from given relchain.
        last relationship token in relchain is the most recent.
        query is original query that started the search."""


def coef_inventory(adata, n=10):
    """
    return highest and lowest coefficient values from logistic regression model,
    along with sparsity

    Parameters:
        adata (anndata.AnnData): object generated from dropkick
        n (int): number of genes to show at top and bottom of coefficient list

    Returns:
        prints top and bottom n genes by their coefficient values
    """
    print('\nTop HVGs by coefficient value (good cells):')
    print(adata.var.loc[-adata.var.dropkick_coef.isna(), 'dropkick_coef'].
        nlargest(n))
    print('\nBottom HVGs by coefficient value (bad droplets):')
    print(adata.var.loc[-adata.var.dropkick_coef.isna(), 'dropkick_coef'].
        nsmallest(n))
    n_zero = (adata.var.dropkick_coef == 0).sum()
    n_coef = (-adata.var.dropkick_coef.isna()).sum()
    sparsity = round(n_zero / n_coef * 100, 3)
    print('\n{} coefficients equal to zero. Model sparsity: {} %\n'.format(
        n_zero, sparsity))


def Lower(v):
    """Transform a string to lower case.

    >>> s = Schema(Lower)
    >>> s('HI')
    'hi'
    """
    return str(v).lower()


def is_subscribed(email):
    """Return true if the given email is suscribed at this level.
        """


def my_range(start, end, step):
    """Iterable `range` adapted for fractions.

    Parameters
    ----------
    start : Number
        Start value (included).
    end : Number
        End value (excluded).
    step : Number
        Increment of the counter.

    Examples
    --------
        >>> for x in my_range(0, 1, Fraction(1, 3)):
        ...     print(x)
        0
        1/3
        2/3

        >>> for x in my_range(1, 0, - Fraction(1, 3)):
        ...     print(x)
        1
        2/3
        1/3
    """
    val = start
    if step > 0:
        while val < end:
            yield val
            val += step
    else:
        while val > end:
            yield val
            val += step


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

        :param TeamMergeRequestCanceledType val:
        :rtype: EventType
        """
    return cls('team_merge_request_canceled', val)


def preview(problem, view=None):
    """
    Show the problem plots and parameters.
    """
    import pylab
    problem.show()
    problem.plot(view=view)
    pylab.show()


def gaps_iterator(seq):
    """
    Iterate on the gaps between elements of the sequence. Each time a new item
    is requested a tuple with the next two sequential elements is returned.

    Example:
     [3,4,5,6] -> [(3,4), (4,5), (5,6)]
    """
    it = iter(seq)
    try:
        previous = next(it)
    except StopIteration:
        return
    while True:
        try:
            current = next(it)
            yield previous, current
            previous = current
        except StopIteration:
            return


def p_definition(t):
    """definition : constant_def
                  | type_def
                  | program_def"""


@classmethod
def fromhexstring(cls, hexstring):
    """
        Construct BitMap from hex string
        """
    bitstring = format(int(hexstring, 16), '0' + str(len(hexstring) / 4) + 'b')
    return cls.fromstring(bitstring)


def remove_keys(_dict, keys):
    """Remove keys from a dictionary."""
    if not _dict:
        return None
    new = dict(_dict)
    for key in keys:
        new.pop(key, None)
    return new


def workspace():
    """
        Return containing project or team workspace for context or None.
        If there is a team context, return that in preference to outer
        containing project.
        """


def for_stmt_defines_one_name(for_stmt):
    """
    Returns True if only one name is returned: ``for x in y``.
    Returns False if the for loop is more complicated: ``for x, z in y``.

    :returns: bool
    """
    return for_stmt.children[1].type == 'name'


def send(conn, data):
    """Send data blob to connection socket."""
    conn.sendall(data)


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 configure_template_filters(app):
    """Configure custom Jinja2 template filters."""

    @app.template_filter()
    def isnuc(x):
        return str(x).upper() in ['A', 'C', 'G', 'T']


def is_error(o):
    """True if o is an instance of a swagger Error model or a flask Response of
    an error model"""
    if hasattr(o, 'error') and hasattr(o, 'error_description') and hasattr(o,
        'status'):
        return True
    return False


def dump_pickle(obj, path):
    """Save object as picked file"""
    import pickle
    with open(path, 'wb') as handle:
        pickle.dump(obj, handle)


@classmethod
def getwh(cls):
    """
        Get the width and height of a window.

        :return: (width, height)
        """
    h, w = cls.WINDOW.getmaxyx()
    return w, h


def get_iteration(conn, config, **kwargs):
    """Get data from every interation of each method for each instance

    Parameter:
        - conn (object): mysql connection
        - config (dict): configuration of experiment
        - kwargs:
            + method_id
            + instance_id
    """
    cur = conn.cursor()
    values = []
    for key in kwargs:
        values.append('%s=%d' % (key, kwargs[key]))
    query = 'SELECT * FROM iteration WHERE %s ' % ' AND '.join(values)
    cur.execute(query)
    for _ in cur.fetchall():
        yield _


def make_activations_model(model, idx_layers_to_show=None, verbose=True):
    """Accepts a Keras image convolution model and exports a new model,
    with just the intermediate activations to plot with plot_activations()."""
    import keras
    import matplotlib.pyplot as plt
    from keras import models
    import numpy as np
    if idx_layers_to_show == None:
        layers_to_show = []
        for l, layer in enumerate(model.layers):
            check_type = type(layer)
            if check_type in [keras.layers.convolutional.Conv2D, keras.
                layers.pooling.MaxPooling2D]:
                layers_to_show.append(layer)
        layer_outputs = [layer.output for layer in layers_to_show]
    else:
        check_dims = np.shape(idx_layers_to_show)
        if check_dims == 2:
            idx_start = idx_layers_to_show[0]
            idx_end = idx_layers_to_show[1]
            layer_outputs = [layer.output for layer in model.layers[
                idx_start:idx_end]]
        elif check_dims == 1:
            layer_outputs = [layer.output for layer in model.layers[
                idx_layers_to_show]]
    activation_model = models.Model(inputs=model.input, outputs=layer_outputs)
    if verbose == True:
        print(activation_model.summary())
    return activation_model


def cycles_sampling_preset_add(name: str='', remove_active: bool=False):
    """Add a Sampling Preset

    :param name: Name, Name of the preset, used to make the path name
    :type name: str
    :param remove_active: remove_active
    :type remove_active: bool
    """
    pass


def parse_categories(dataframe, **parse_args):
    """
    A function to parse out categories from sequence IDs

    parse_arguments can be:
    - delimiter: character vector to split ID
    - field: field number in 0-index designating which field to keep
    OR
    - regex: a regex expression with a single capture group
    OR
    - callback: a function that takes the seqid and returns the
        category
    """
    if 'delimiter' in parse_args.keys():
        delimiter = parse_args['delimiter']
        field = int(parse_args['field'])
        dataframe['category'] = dataframe.seqid.str.split(delimiter).str.get(
            field)
    elif 'regex' in parse_args.keys():
        regex = parse_args['regex']
        dataframe['category'] = dataframe.seqid.str.extract(regex, expand=False
            )
    elif 'callback' in parse_args.keys():
        callback = parse_args['callback']
        dataframe['category'] = dataframe.seqid.apply(lambda s: callback(s))
    else:
        raise Exception('Not sure how to parse categories.')
    return dataframe


def supported_enhancements():
    """Returns a `collections.Iterable` of supported enhancements.

        :returns: supported enhancements which should be a subset of
            :const:`~certbot.plugins.enhancements.ENHANCEMENTS`
        :rtype: :class:`collections.Iterable` of :class:`str`

        """


@classmethod
def flatten(cls, change):
    """
        This method will flatten changes and return a list of TaskChange
        """
    changes = list()
    if not change:
        return changes
    changes.append(change)
    for related in change.related_changes:
        changes.extend(cls.flatten(related))
    return changes


@classmethod
def strip_off_end(cls, s: str, suf: str):
    """
		Strips the full string `suf` from the end of `str`.
		See `Tools.strip_off` for more info.
		"""
    assert isinstance(suf, str), '{} is not a string'.format(suf)
    if s.endswith(suf):
        s = s[:-len(suf)]
    return s


@staticmethod
def method():
    """method returns an associated ID for the Juju API call.
        """
    return 'scale'


def FindNextMultiLineCommentStart(lines, lineix):
    """Find the beginning marker for a multiline comment."""
    while lineix < len(lines):
        if lines[lineix].strip().startswith('/*'):
            if lines[lineix].strip().find('*/', 2) < 0:
                return lineix
        lineix += 1
    return len(lines)


def edge_type_to_class(edge_type):
    """Return the edge class for layout purposes based on the edge type"""
    if 'Amount' in edge_type:
        return 'amount'
    if edge_type in ('Activation', 'Inhibition'):
        return 'activity'
    if edge_type == 'Complex':
        return 'complex'
    else:
        return 'modification'


def FindAtomIndexByIDs(atomData, loc, IDs, Draw=True):
    """finds the set of atom array indices for a list of atom IDs. Will search
    either the Atom table or the drawAtom table.

    :param list atomData: Atom or drawAtom table containting coordinates, etc.
    :param int loc: location of atom id in atomData record
    :param list IDs: atom IDs to be found
    :param bool Draw: True if drawAtom table to be searched; False if Atom table
      is searched

    :returns: list indx: atom (or drawAtom) indices

    """
    indx = []
    for i, atom in enumerate(atomData):
        if Draw and atom[loc] in IDs:
            indx.append(i)
        elif atom[loc] in IDs:
            indx.append(i)
    return indx


def make_alloc(loop_orders, dtype, sub, fortran='0'):
    """Generate C code to allocate outputs.

    Parameters
    ----------
    fortran : str
        A string included in the generated code. If it
        evaluate to non-zero, an ndarray in fortran order will be
        created, otherwise it will be c order.

    """
    type = dtype.upper()
    if type.startswith('THEANO_COMPLEX'):
        type = type.replace('THEANO_COMPLEX', 'NPY_COMPLEX')
    nd = len(loop_orders[0])
    init_dims = ''
    for i, candidates in enumerate(zip(*loop_orders)):
        for j, candidate in enumerate(candidates):
            if candidate != 'x':
                var = sub['lv%i' % j]
                init_dims += ('dims[%(i)s] = %(var)s_n%(candidate)s;\n' %
                    locals())
                break
        else:
            init_dims += 'dims[%(i)s] = 1;\n' % locals()
    return (
        """
    {
        npy_intp dims[%(nd)s];
        //npy_intp* dims = (npy_intp*)malloc(%(nd)s * sizeof(npy_intp));
        %(init_dims)s
        if (!%(olv)s) {
            %(olv)s = (PyArrayObject*)PyArray_EMPTY(%(nd)s, dims,
                                                    %(type)s,
                                                    %(fortran)s);
        }
        else {
            PyArray_Dims new_dims;
            new_dims.len = %(nd)s;
            new_dims.ptr = dims;
            PyObject* success = PyArray_Resize(%(olv)s, &new_dims, 0, NPY_CORDER);
            if (!success) {
                // If we can't resize the ndarray we have we can allocate a new one.
                PyErr_Clear();
                Py_XDECREF(%(olv)s);
                %(olv)s = (PyArrayObject*)PyArray_EMPTY(%(nd)s, dims, %(type)s, 0);
            } else {
                Py_DECREF(success);
            }
        }
        if (!%(olv)s) {
            %(fail)s
        }
    }
    """
         % dict(locals(), **sub))


@classmethod
def _unescape_dict_keys(cls, data: dict) ->dict:
    """Recursively unescape all keys in a dict."""
    ret = {}
    for key, value in data.items():
        key = cls._unescape_key(key)
        if isinstance(value, dict):
            value = cls._unescape_dict_keys(value)
        ret[key] = value
    return ret


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

        :param PaperDocChangeMemberRoleDetails val:
        :rtype: EventDetails
        """
    return cls('paper_doc_change_member_role_details', val)


def iter_fields(node):
    """
    Yield a tuple of ``(fieldname, value)`` for each field in ``node._fields``
    that is present on *node*.
    """
    for field in node._fields:
        try:
            yield field, getattr(node, field)
        except AttributeError:
            pass


@staticmethod
def countLumis(runs):
    """
        Count up the number of lumi sections in a runs object
        :param runs:
        :return count:
        """
    count = 0
    for runLumi in runs:
        count += len(runLumi.lumis)
    return count


def potential_cloud_shadow_layer(nir, swir1, water):
    """Find low NIR/SWIR1 that is not classified as water

    This differs from the Zhu Woodcock algorithm
    but produces decent results without requiring a flood-fill

    Parameters
    ----------
    nir: ndarray
    swir1: ndarray
    water: ndarray

    Output
    ------
    ndarray
        boolean, potential cloud shadows
    """
    return (nir < 0.1) & (swir1 < 0.1) & ~water


def area(p):
    """Area of a polygone

    :param p: list of the points taken in any orientation,
              p[0] can differ from p[-1]
    :returns: area
    :complexity: linear
    """
    A = 0
    for i in range(len(p)):
        A += p[i - 1][0] * p[i][1] - p[i][0] * p[i - 1][1]
    return A / 2.0


@staticmethod
def is_multivalue(field_name):
    """
        Check, if given form field is a multivalue field.

        :param str field_name: Name of the form field.
        :return: ``True``, if the field can contain multiple values, ``False`` otherwise.
        :rtype: bool
        """
    if field_name in ('authors', 'operations'):
        return True
    return False


def getrepopath(cvspath):
    """Return the repository path from a CVS path.

    >>> getrepopath(b'/foo/bar')
    '/foo/bar'
    >>> getrepopath(b'c:/foo/bar')
    '/foo/bar'
    >>> getrepopath(b':pserver:10/foo/bar')
    '/foo/bar'
    >>> getrepopath(b':pserver:10c:/foo/bar')
    '/foo/bar'
    >>> getrepopath(b':pserver:/foo/bar')
    '/foo/bar'
    >>> getrepopath(b':pserver:c:/foo/bar')
    '/foo/bar'
    >>> getrepopath(b':pserver:truc@foo.bar:/foo/bar')
    '/foo/bar'
    >>> getrepopath(b':pserver:truc@foo.bar:c:/foo/bar')
    '/foo/bar'
    >>> getrepopath(b'user@server/path/to/repository')
    '/path/to/repository'
    """
    parts = cvspath.split(b':')
    atposition = parts[-1].find(b'@')
    start = 0
    if atposition != -1:
        start = atposition
    repopath = parts[-1][parts[-1].find(b'/', start):]
    return repopath


def rgb_to_ansi(r, g, b):
    """
    Convert RGB to ANSI
    """
    r, g, b = int(r), int(g), int(b)
    if r == g & g == b:
        if r < 8:
            return int(16)
        if r > 248:
            return int(230)
        return int(round((r - 8) / 247 * 24) + 232)
    to_ansi_range = lambda a: int(round(a / 51.0))
    r_in_range = to_ansi_range(r)
    g_in_range = to_ansi_range(g)
    b_in_range = to_ansi_range(b)
    ansi = 16 + 36 * r_in_range + 6 * g_in_range + b_in_range
    return int(ansi)


def p_do_stmt(p):
    """do_stmt : do_stmt_head suite """
    p[0] = p[1] + [p[2]]


def prefix_spaces(s: str) ->int:
    """Count number of prefix spaces in a string."""
    count = 0
    for x in s:
        if x != ' ':
            return count
        count += 1
    return count


@classmethod
def get(cls, value, default=None):
    """
        Dict `.get()` like to return a default value.

        Args:
            cls (Enum): Enum class.
            value: Value to get inside Enum.
            default: Value to return in case of error. Default is None.
        """
    try:
        return cls(value)
    except Exception:
        return default


def integerify(B, r):
    """A bijection from ({0, 1} ** k) to {0, ..., (2 ** k) - 1"""
    Bi = (2 * r - 1) * 16
    return B[Bi]


@staticmethod
def customer_id_field():
    """
        Title of Customer ID field, which can be overridden.
        """
    return 'Customer ID'


def GetVersion(header):
    """

    gets the version of the header

    """
    pass


def check_mesh(dim, x, y, z, mesh_type):
    """Do a basic check of the shapes of the input arrays."""
    if dim >= 2:
        if y is None:
            raise ValueError('The y-component is missing for {0} dimensions'
                .format(dim))
    if dim == 3:
        if z is None:
            raise ValueError('The z-component is missing for {0} dimensions'
                .format(dim))
    if mesh_type == 'unstructured':
        if dim >= 2:
            try:
                if len(x) != len(y):
                    raise ValueError(
                        'len(x) = {0} != len(y) = {1} for unstructured grids'
                        .format(len(x), len(y)))
            except TypeError:
                pass
            if dim == 3:
                try:
                    if len(x) != len(z):
                        raise ValueError(
                            'len(x) = {0} != len(z) = {1} for unstructured grids'
                            .format(len(x), len(z)))
                except TypeError:
                    pass
    elif mesh_type == 'structured':
        pass
    else:
        raise ValueError('Unknown mesh type {0}'.format(mesh_type))


def p_track(t):
    """track : TRACK track_mode track_flags
             | TRACK track_mode sub_channel_mode track_flags"""
    from audiotools.toc import TOCTrack
    if len(t) == 4:
        t[0] = TOCTrack(mode=t[2], flags=t[3])
    else:
        t[0] = TOCTrack(mode=t[2], flags=t[4], sub_channel_mode=t[3])


def _write_two_arrays(file_name, id_values, bound_id_code=None):
    """Write two arrays: cell_id-value pairs and bound_id-bound_code pairs
    Inputs:
        file_name :  the full file name including path
        id_values: valid cell ID - value pair
        bound_id_code: boundary cell ID - codes pair. If bound_id_code is not
            given, then the second part of the file won't be written (only
            the case for precipitatin_mask.dat)
    """
    if not file_name.endswith('.dat'):
        file_name = file_name + '.dat'
    if id_values.shape[1] == 3:
        fmt = ['%d %g %g']
    elif id_values.shape[1] == 2:
        fmt = ['%d %g']
    else:
        raise ValueError('Please check the shape of the 1st array: id_values')
    fmt = '\n'.join(fmt * id_values.shape[0])
    id_values_str = fmt % tuple(id_values.ravel())
    if bound_id_code is not None:
        fmt = ['%-12d %2d %2d %2d']
        fmt = '\n'.join(fmt * bound_id_code.shape[0])
        bound_id_code_str = fmt % tuple(bound_id_code.ravel())
    with open(file_name, 'w') as file2write:
        file2write.write('$Element Number\n')
        file2write.write('%d\n' % id_values.shape[0])
        file2write.write('$Element_id  Value\n')
        file2write.write(id_values_str)
        if bound_id_code is not None:
            file2write.write('\n$Boundary Numbers\n')
            file2write.write('%d\n' % bound_id_code.shape[0])
            file2write.write('$Element_id  Value\n')
            file2write.write(bound_id_code_str)


def _get_uri_from_request(request):
    """
    The uri returned from request.uri is not properly urlencoded
    (sometimes it's partially urldecoded) This is a weird hack to get
    sanic to return the proper urlencoded string uri
    """
    uri = request._parsed_url.path
    if request._parsed_url.query:
        uri = uri + b'?' + request._parsed_url.query
    try:
        server_name = request.server_name
        server_port = request.server_port
        scheme = request.scheme
    except (AttributeError, NotImplementedError):
        override_server_name = request.app.config.get('SERVER_NAME', False)
        requested_host = request.host
        server_name = override_server_name or request.headers.get(
            'x-forwarded-host') or requested_host.split(':')[0]
        forwarded_port = (override_server_name.split(':')[1] if
            override_server_name and ':' in override_server_name else None
            ) or request.headers.get('x-forwarded-port') or (requested_host
            .split(':')[1] if ':' in requested_host else None)
        try:
            server_port = (int(forwarded_port) if forwarded_port else None
                ) or request._parsed_url.port or request.transport.get_extra_info(
                'sockname')[1]
        except NotImplementedError:
            server_port = 80
        scheme = request.headers.get('x-forwarded-proto') or request.scheme
    if ':' in server_name:
        server_name, server_port = server_name.split(':', 1)
    include_port = True
    if scheme == 'https' and server_port == 443:
        include_port = False
    elif scheme == 'http' and server_port == 80:
        include_port = False
    if include_port:
        return scheme + '://' + server_name + ':' + str(server_port
            ) + uri.decode('utf-8')
    return scheme + '://' + server_name + uri.decode('utf-8')


def put_event_stream(ApplicationId=None, WriteEventStream=None):
    """
    Use to create or update the event stream for an app.

    :example: response = client.put_event_stream(
        ApplicationId='string',
        WriteEventStream={
            'DestinationStreamArn': 'string',
            'ExternalId': 'string',
            'RoleArn': 'string'
        }
    )

    :type ApplicationId: string
    :param ApplicationId: [REQUIRED] ApplicationId

    :type WriteEventStream: dict
    :param WriteEventStream: [REQUIRED] EventStream to write.
            DestinationStreamArn (string) -- The Amazon Resource Name (ARN) of the Amazon Kinesis stream or Firehose delivery stream to which you want to publish events. Firehose ARN: arn:aws:firehose:REGION:ACCOUNT_ID:deliverystream/STREAM_NAME Kinesis ARN: arn:aws:kinesis:REGION:ACCOUNT_ID:stream/STREAM_NAME
            ExternalId (string) -- The external ID assigned the IAM role that authorizes Amazon Pinpoint to publish to the stream.
            RoleArn (string) -- The IAM role that authorizes Amazon Pinpoint to publish events to the stream in your account.

    :rtype: dict
    :return: {
        'EventStream': {
            'ApplicationId': 'string',
            'DestinationStreamArn': 'string',
            'ExternalId': 'string',
            'LastModifiedDate': 'string',
            'LastUpdatedBy': 'string',
            'RoleArn': 'string'
        }
    }

    :returns:
    (dict) -- PutEventStream Response
    EventStream (dict) -- Model for an event publishing subscription export.
    ApplicationId (string) -- The ID of the application from which events should be published.
    DestinationStreamArn (string) -- The Amazon Resource Name (ARN) of the Amazon Kinesis stream or Firehose delivery stream to which you want to publish events. Firehose ARN: arn:aws:firehose:REGION:ACCOUNT_ID:deliverystream/STREAM_NAME Kinesis ARN: arn:aws:kinesis:REGION:ACCOUNT_ID:stream/STREAM_NAME
    ExternalId (string) -- The external ID assigned the IAM role that authorizes Amazon Pinpoint to publish to the stream.
    LastModifiedDate (string) -- The date the event stream was last updated in ISO 8601 format.
    LastUpdatedBy (string) -- The IAM user who last modified the event stream.
    RoleArn (string) -- The IAM role that authorizes Amazon Pinpoint to publish events to the stream in your account.

    """
    pass


def ids():
    """return a BTrees.IFBTree data structure of the document ids in the
        index--the ones that have values to be indexed.  All document ids
        should produce at least one value given a call of
        IIndexValues.values(doc_id=id).
        """


def next_pow_two(n):
    """Returns the next power of two greater than or equal to `n`"""
    i = 1
    while i < n:
        i = i << 1
    return i


def perform_fft(signal, rate, add_zeros=True):
    """Perform a fast fournier transformation on a given signal."""
    import numpy as np
    import scipy
    chn = len(signal.shape)
    if chn >= 2:
        signal = signal.sum(axis=1) / 2
    N = int(signal.shape[0])
    secs = N / float(rate)
    if add_zeros:
        signal = np.concatenate((signal, np.zeros(len(signal))), axis=None)
    trans_fft = abs(scipy.fft(signal))
    return N, secs, trans_fft


@classmethod
def _fromJSON(cls, jsonobject):
    """Generates a new instance of :class:`maspy.proteindb.ProteinSequence`
        from a decoded JSON object (as generated by
        :func:`maspy.proteindb.ProteinSequence._reprJSON()`).

        :param jsonobject: decoded JSON object

        :returns: a new instance of :class:`ProteinSequence`
        """
    newInstance = cls(None, None)
    newInstance.__dict__.update(jsonobject)
    newInstance.uniquePeptides = set(newInstance.uniquePeptides)
    newInstance.sharedPeptides = set(newInstance.sharedPeptides)
    return newInstance


def points2htmlfontsize(points):
    """
    Approximate font size converter, converts from Points to HTML ``<font>`` tag font sizes.

    Note that this method is very inaccurate, since there are only seven possible output values that represent at least 25 input values.
    When in doubt, this function always rounds down, e.g. every input value less than eight is converted to HTML size 1.
    """
    if points <= 8:
        return 1
    elif points <= 10:
        return 2
    elif points <= 12:
        return 3
    elif points <= 14:
        return 4
    elif points <= 18:
        return 5
    elif points <= 24:
        return 6
    else:
        return 7


@staticmethod
def __unpackUCS2(encoded_data):
    """Decode hexa byte encoded with extended encoding (UTF-16 / UCS2)

    Keyword arguments:
      encoded_data -- (bytes) Content to decode

    return: (bytes) Decoded content
    """
    return encoded_data.decode('utf-16be')


def _must_split_flat_key_val(must):
    """
    Splits the flat and key:val tags apart

    :returns: the flat set tags and the key:val tags
    :rtype: tuple(set, dict)
    """
    key_val = {}
    flat = set()
    for i in must:
        if ':' in i:
            k, v = i.split(':', 1)
            key_val[k] = v
        else:
            flat.add(i)
    return flat, key_val


def FormatDescriptorToPython(i):
    """
    Format a descriptor into a form which can be used as a python attribute

    example::

        >>> FormatDescriptorToPython('(Ljava/lang/Long; Ljava/lang/Long; Z Z)V')
        'Ljava_lang_LongLjava_lang_LongZZV

    :param i: name to transform
    :rtype: str
    """
    i = i.replace('/', '_')
    i = i.replace(';', '')
    i = i.replace('[', '')
    i = i.replace('(', '')
    i = i.replace(')', '')
    i = i.replace(' ', '')
    i = i.replace('$', '')
    return i


def create_or_update_row(model, lookup_values, new_values):
    """
    Update a single existing row that can be found using param: lookup values, with new_values.
    If one doesn't exist, instantiates, full_cleans, saves and returns a database object
    """
    try:
        o = model.objects.get(**lookup_values)
        for attr, value in new_values.items():
            setattr(o, attr, value)
    except model.DoesNotExist:
        o = model(**new_values)
    o.full_clean()
    o.save()
    return o


def pageBreak(md):
    """
	Converts '~' paragraphs to HTML5 page breaks.

	Arguments:
	md		--	A Markdown string.

	Returns:
	A processed Markdown string.
	"""
    return md.replace(u'\n~\n',
        u"\n

\n")


def path_shift(script_name, path_info, shift=1):
    """ Shift path fragments from PATH_INFO to SCRIPT_NAME and vice versa.

        :return: The modified paths.
        :param script_name: The SCRIPT_NAME path.
        :param script_name: The PATH_INFO path.
        :param shift: The number of path fragments to shift. May be negative to
          change the shift direction. (default: 1)
    """
    if shift == 0:
        return script_name, path_info
    pathlist = path_info.strip('/').split('/')
    scriptlist = script_name.strip('/').split('/')
    if pathlist and pathlist[0] == '':
        pathlist = []
    if scriptlist and scriptlist[0] == '':
        scriptlist = []
    if 0 < shift <= len(pathlist):
        moved = pathlist[:shift]
        scriptlist = scriptlist + moved
        pathlist = pathlist[shift:]
    elif 0 > shift >= -len(scriptlist):
        moved = scriptlist[shift:]
        pathlist = moved + pathlist
        scriptlist = scriptlist[:shift]
    else:
        empty = 'SCRIPT_NAME' if shift < 0 else 'PATH_INFO'
        raise AssertionError('Cannot shift. Nothing left from %s' % empty)
    new_script_name = '/' + '/'.join(scriptlist)
    new_path_info = '/' + '/'.join(pathlist)
    if path_info.endswith('/') and pathlist:
        new_path_info += '/'
    return new_script_name, new_path_info


@staticmethod
def _parse_lsb_release_content(lines):
    """
        Parse the output of the lsb_release command.

        Parameters:

        * lines: Iterable through the lines of the lsb_release output.
                 Each line must be a unicode string or a UTF-8 encoded byte
                 string.

        Returns:
            A dictionary containing all information items.
        """
    props = {}
    for line in lines:
        kv = line.strip('\n').split(':', 1)
        if len(kv) != 2:
            continue
        k, v = kv
        props.update({k.replace(' ', '_').lower(): v.strip()})
    return props


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 clear_caches():
    """Jinja keeps internal caches for environments and lexers.  These are
    used so that Jinja doesn't have to recreate environments and lexers all
    the time.  Normally you don't have to care about that but if you are
    measuring memory consumption you may want to clean the caches.
    """
    from .environment import _spontaneous_environments
    from .lexer import _lexer_cache
    _spontaneous_environments.clear()
    _lexer_cache.clear()


@classmethod
def DoublePrecision(cls):
    """Postgres DoublePrecision Type"""
    return cls(float, 'DOUBLE PRECISION')


@classmethod
def set_idle_ttl(cls, pid, ttl):
    """Set the idle TTL for a pool, after which it will be destroyed.

        :param str pid: The pool id
        :param int ttl: The TTL for an idle pool

        """
    with cls._lock:
        cls._ensure_pool_exists(pid)
        cls._pools[pid].set_idle_ttl(ttl)


def to_gh(g, quiet=True):
    """Turns every red node into a green node by changing regular edges into hadamard edges"""
    ty = g.types()
    for v in g.vertices():
        if ty[v] == 2:
            g.set_type(v, 1)
            for e in g.incident_edges(v):
                et = g.edge_type(e)
                if et == 2:
                    g.set_edge_type(e, 1)
                elif et == 1:
                    g.set_edge_type(e, 2)


def get_server(oneandone_conn, instance, full_object=False):
    """
    Validates that the server exists whether by ID or name.
    Returns the server if one was found.
    """
    for server in oneandone_conn.list_servers(per_page=1000):
        if instance in (server['id'], server['name']):
            if full_object:
                return server
            return server['id']


def from_list_to_set(ref, tab):
    """Convert list to a set

    Used for the retention restore

    :param ref: Not used
    :type ref:
    :param tab: list to parse
    :type tab: list
    :return: list of names
    :rtype: list
    """
    return set(tab)


def Validator(node, value):
    """
    A validator is called after preparation of the deserialized value.

    If ``value`` is not valid, raise a :class:`colander.Invalid`
    instance as an exception after.

    ``node`` is a :class:`colander.SchemaNode` instance, for use when
    raising a :class:`colander.Invalid` exception.
    """


def sqlize(string):
    """SQL-izes a string to ensure the characters are all legal

    Args:
        string (str): The string to be processed

    Returns:
        the processed SQL-friendly string
    """
    return string.upper().replace(' ', '_').replace('-', '_').replace(':', '_')


@staticmethod
def register_account(account):
    """
        Register an account on website

        This is a static method, it would be called even if the backend is
        instancied.

        :param account: describe the account to create
        :type account: :class:`Account`
        :raises: :class:`AccountRegisterError`
        """
    raise NotImplementedError()


def is_grey(rgb, threshold=20):
    """
    Return true if an rgb color is a shade of grey.
    """
    return abs(rgb[0] - rgb[1]) <= threshold and abs(rgb[1] - rgb[2]
        ) <= threshold and abs(rgb[2] - rgb[0]) <= threshold


def send_upgrade_response(connection):
    """
    This function writes the 101 Switching Protocols response.
    """
    response = b'HTTP/1.1 101 Switching Protocols\r\nUpgrade: h2c\r\n\r\n'
    connection.sendall(response)


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


@classmethod
def dims(cls, value):
    """Produce iterable of all dimensions"""
    try:
        return value.__class__.__dimensions__
    except AttributeError as err:
        dimensions = []
        for base in cls.types(value):
            length = getattr(base, '_length_', None)
            if length is not None:
                dimensions.append(length)
        dimensions = tuple(dimensions)
        value.__class__.__dimensions__ = dimensions
        return dimensions


def reveal():
    """Show hidden particles

    """
    pass


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


def permute_vector(permutation, vector):
    """
    Returns the result of applying the given permutation to the given vector.
    Input permutation and vector should be of the same length.
    Input permutation should be an index vector (e.g. a permutation of
    the integers from 0 to dimension-1 of the vector)
    """
    return vector[permutation]


@classmethod
def build_from_config(cls, config, dependencies):
    """Create a new instance using the provided infos for initialisation.

        Parameters
        ----------
        config : dict(str)
            Dictionary holding the new values to give to the members in string
            format, or dictionnary like for instance with prefs.

        dependencies : dict
            Dictionary holding the necessary classes needed when rebuilding..

        """
    raise NotImplementedError()


@classmethod
def _short_kislev(cls, year):
    """Returns True if Kislev has 29 days"""
    return cls._days_in_year(year) % 10 == 3


def listLinesWithKeyfromOnlineText(url, key):
    """List lines from text file located at url, with key.

   :param url: url
   :type url: string
   :param key: key word
   :type key: string
   :returns: list of lines
   :rtype: list

   :Example:

   >>> from westpy import *
   >>> url = "http://www.quantum-simulation.org/potentials/sg15_oncv/upf/Si_ONCV_PBE-1.1.upf"
   >>> key = "z_valence"
   >>> l = listLinesWithKeyfromOnlineText(url,key)
   >>> print(l)
   ['       z_valence="    4.00"']

   .. note:: Can be used to grep values from a UPF file.
   """
    from urllib.request import urlopen
    import re
    data = urlopen(url)
    greplist = []
    for line in data:
        if key in str(line):
            greplist.append(line)
    return greplist


def stroke_subdivide(number_cuts: int=1):
    """Subdivide between continuous selected points of the stroke adding a point half way between them

    :param number_cuts: Number of Cuts
    :type number_cuts: int
    """
    pass


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

        :param NoPasswordLinkViewCreateReportDetails val:
        :rtype: EventDetails
        """
    return cls('no_password_link_view_create_report_details', val)


def is_number(num):
    """Check if string is a number"""
    try:
        float(num)
        return True
    except:
        return False


def _(x):
    """Identity function used to trigger string extraction."""
    return x


def normalize(q):
    """Convert Quaternion to Unit Quaternion.

        Unit Quaternion is Quaternion who's length is equal to 1.

        >>> q = Quaternion((1, 3, 3, 3))
        >>> q.normalize()
        >>> print(q) # doctest: +ELLIPSIS
        (0.1889822... + 0.5669467...i + 0.5669467...j + 0.5669467...k)

        """
    norm = abs(q)
    q.w = q.w / norm,
    q.x = q.x / norm,
    q.y = q.y / norm,
    q.z = q.z / norm,


def _load_textile(sTextilePath):
    """Load lines from the textile file."""
    fTextile = open(sTextilePath, 'rb')
    aLines = []
    aCurLine = []
    for sLine in fTextile.readlines():
        if sLine.endswith('\\\n'):
            if aCurLine:
                aCurLine.append(sLine[:-2])
            else:
                aCurLine = [sLine[:-2]]
            continue
        elif aCurLine:
            aCurLine.append(sLine)
            aLines.append(''.join(aCurLine))
            aCurLine = []
        else:
            aLines.append(sLine)
    fTextile.close()
    return aLines


@staticmethod
def _build_result_metainfo(args):
    """
        Internal helper for collecting metadata from args to results
        """
    data = dict()
    if hasattr(args, 'branch') and args.branch:
        data['build_branch'] = args.branch
    if hasattr(args, 'commitId') and args.commitId:
        data['buildcommit'] = args.commitId
    if hasattr(args, 'gitUrl') and args.gitUrl:
        data['build_git_url'] = args.gitUrl
    if hasattr(args, 'buildUrl') and args.buildUrl:
        data['build_url'] = args.buildUrl
    if hasattr(args, 'campaign') and args.campaign:
        data['campaign'] = args.campaign
    if hasattr(args, 'jobId') and args.jobId:
        data['job_id'] = args.jobId
    if hasattr(args, 'toolchain') and args.toolchain:
        data['toolchain'] = args.toolchain
    if hasattr(args, 'buildDate') and args.buildDate:
        data['build_date'] = args.buildDate
    return data


@staticmethod
def _ticks(n):
    """Ticks labels between 1 and `n` pixels.

        Parameters
        ----------
        n: int
            Total number of pixels.

        Return
        ------
        list
            List of ticks.

        """
    return [1, n // 4, n // 2, n // 4 + n // 2, n]


def __iter__():
    """Return an iterator object.
        """


def _warning(text):
    """Colorize terminal output to bold yellow."""
    return '\x1b[1m\x1b[33m{text}\x1b[0m'.format(text=text)


def append_filename_to_path(path, filename):
    """Append a filename to a system file path.

    This method correctly appends a filename to a file path with the
    correct path separators used within the path string.

    Args:
        path (:obj:`str`): The system file path.
        filename (:obj:`str`): The filename to append.

    Returns:
        :obj:`str`: The filename correctly appended to the file path.
    """
    if len(path) > 0 and path[-1] in ('/', '\\'):
        return f'{path}{filename}'
    elif '\\' in path:
        return f'{path}\\{filename}'
    else:
        return f'{path}/{filename}'


def isGroupRoutine(rname):
    """Returns ``True`` if the specified routine is a file group evaluation
    routine, ``False``otherwise.
    """
    return rname.endswith('Group')


@staticmethod
def _sort_by_value(cards: list, order: str) ->list:
    """Sorts cards according to value. Uses selection sort"""
    unsorted_cards = cards.copy()
    sorted_cards = []
    sort_fx = min if order == 'asc' else max
    for _ in cards:
        smallest_card = sort_fx(unsorted_cards)
        unsorted_cards.remove(smallest_card)
        sorted_cards.append(smallest_card)
    return sorted_cards


def _register_configs(configs, to_register):
    """ param dict configs: pair param_name(str) : param_configs(dict)
        param to_register: pair param_name(str) : param_configs(dict) or attr(str) : attr_value(object)
    """
    _configs = {}
    for identifier, attr_value in to_register.items():
        assert isinstance(identifier, str), KeyError()
        if identifier in configs:
            _configs[identifier] = attr_value
        else:
            for config in configs.values():
                config[identifier] = attr_value
    for identifier, attr_value in _configs.items():
        configs[identifier].update(attr_value)


def __call__(name, typ, body):
    """ Return true if the rule matches, else false. """


@staticmethod
def project_help_block_message():
    """Assemble a block of relevant help text to be returned with an invalid request."""
    message = (
        'You must supply either a project id (like "/projectinfo/<project_id>")'
        )
    message += (
        ' or search for one using the form "/projectinfo/search/<search_term_1>+<search_term_2>"'
        )
    return message


def format_size(size):
    """Convert a size in bytes into a human readable string.

    Example
    -------
    ::

        >>>format_size(2.25*1024)
        '2.25 kB'

    Parameters
    ----------
    size : int
        Size in bytes.

    Returns
    -------
    str
    """
    for unit in ['bytes', 'kB', 'MB']:
        if size < 1024:
            return '{:.2f} {}'.format(size, unit)
        size /= 1024
    return '{:.2f} {}'.format(size, 'GB')


def tonumber(test, alttext=None):
    """
    Checks if something is a number or matches alttext

    Parameters
    ----------
    test : str
        Text to test.
    alttext : str, optional
        Alternate text to test. The default is None.

    Returns
    -------
    str or int or float
        Returns a lower case verion of alttext, or a number.

    """
    if alttext is not None and test.lower() == alttext.lower():
        return test.lower()
    if not test.replace('.', '', 1).isdigit():
        return -999
    if '.' in test:
        return float(test)
    return int(test)


def price_to_book_value(price_per_share, book_value_per_share):
    """Computes price to book value.

    @params
    -------
    price_per_share: share price
    book_value_per_share: book value per share

    returns
    -------
    Price to book value, int or float

    explanation
    -----------

    """
    return price_per_share / book_value_per_share


@staticmethod
def format_interval(t):
    """
        Formats a number of seconds as a clock time, [H:]MM:SS

        Parameters
        ----------
        t  : int
            Number of seconds.

        Returns
        -------
        out  : str
            [H:]MM:SS
        """
    mins, s = divmod(int(t), 60)
    h, m = divmod(mins, 60)
    if h:
        return '{0:d}:{1:02d}:{2:02d}'.format(h, m, s)
    else:
        return '{0:02d}:{1:02d}'.format(m, s)


@staticmethod
def is_repo(path):
    """
        should return True if it is a valid
        repo of the provided scm type.
        """
    return False


@staticmethod
def _define_module_argument_spec():
    """
        Define the argument spec for the ansible module
        :return: argument spec dictionary
        """
    return {'argument_spec': dict(group_id=dict(required=True))}


def get_callback_info():
    """Retrieves the messageId and replyToAddress from the message header.
    This is used for async calls."""
    messageId = None
    replyToAddress = None
    from soaplib.wsgi_soap import request
    headerElement = request.header
    if headerElement:
        headers = headerElement.getchildren()
        for header in headers:
            if header.tag.lower().endswith('messageid'):
                messageId = header.text
            if header.tag.lower().find('replyto') != -1:
                replyToElems = header.getchildren()
                for replyTo in replyToElems:
                    if replyTo.tag.lower().endswith('address'):
                        replyToAddress = replyTo.text
    return messageId, replyToAddress


def view_frame():
    """Reset viewable area to show range around current frame

    """
    pass


def get_slug_in_language(record, language):
    """This is an adapter from django-hvad's lazy_translation_getter."""
    if not record or not hasattr(record, 'safe_translation_getter'):
        return None
    return record.safe_translation_getter(field='slug', language_code=
        language, default=None)


def dict_replace(subject_dict, string):
    """
    Replace a dict map, key to its value in the stirng
    :param subject_dict: dict
    :param string: string
    :return: string
    """
    for i, j in subject_dict.items():
        string = string.replace(i, j)
    return string


def quarter_path(t: float, diameter: float) ->float:
    """
    Describes the y values of a a straight path a quarter above the center of a
    detector given a position x and detector diameter d0.

    """
    return diameter / 8


def list_web_acls(NextMarker=None, Limit=None):
    """
    Returns an array of  WebACLSummary objects in the response.
    See also: AWS API Documentation

    Examples
    The following example returns an array of up to 100 web ACLs.
    Expected Output:

    :example: response = client.list_web_acls(
        NextMarker='string',
        Limit=123
    )

    :type NextMarker: string
    :param NextMarker: If you specify a value for Limit and you have more WebACL objects than the number that you specify for Limit , AWS WAF returns a NextMarker value in the response that allows you to list another group of WebACL objects. For the second and subsequent ListWebACLs requests, specify the value of NextMarker from the previous response to get information about another batch of WebACL objects.

    :type Limit: integer
    :param Limit: Specifies the number of WebACL objects that you want AWS WAF to return for this request. If you have more WebACL objects than the number that you specify for Limit , the response includes a NextMarker value that you can use to get another batch of WebACL objects.

    :rtype: dict
    :return: {
        'NextMarker': 'string',
        'WebACLs': [
            {
                'WebACLId': 'string',
                'Name': 'string'
            },
        ]
    }

    """
    pass


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


@classmethod
def _from_dict(cls, _dict):
    """Initialize a AudioDetails object from a json dictionary."""
    args = {}
    if 'type' in _dict:
        args['type'] = _dict.get('type')
    if 'codec' in _dict:
        args['codec'] = _dict.get('codec')
    if 'frequency' in _dict:
        args['frequency'] = _dict.get('frequency')
    if 'compression' in _dict:
        args['compression'] = _dict.get('compression')
    return cls(**args)


@classmethod
def build_from_config(cls, config, dependencies):
    """Rebuild the task and the sequence from a config file.

        """
    builder = cls.mro()[1].build_from_config.__func__
    task = builder(cls, config, dependencies)
    if 'sequence' in config:
        pulse_dep = dependencies['exopy.pulses.item']
        builder = pulse_dep['exopy_pulses.RootSequence']
        conf = config['sequence']
        seq = builder.build_from_config(conf, dependencies)
        task.sequence = seq
    return task


def notify(message, subject):
    """ Sends the message to the subscriber
        """


def equalize_perms(l):
    """
    Extend the permutations in ``l`` to have the same lengths.

    EXAMPLES::

        sage: from surface_dynamics.misc.permutation import equalize_perms
        sage: li = [[0, 1], [2, 1, 0]]
        sage: equalize_perms(li)
        3
    """
    n = max(map(len, l))
    for p in l:
        p.extend(range(len(p), n))
    return n


def _str_or_none(string):
    """ Return a string of None if string is empty. """
    if string is None or string == '':
        return None
    return string


def apply_filter_of_class(filt, dev_raw):
    """apply class parameter filter"""
    return dev_raw['hostdev_class_name'] == filt['val']


@staticmethod
def _directive_call_func(directive_body):
    """Directive for :py:meth:`dispatch_call`"""
    func_obj, func_args, func_kwargs = directive_body
    return func_obj(*func_args, **func_kwargs)


def _noop(_game, mix):
    """A noop for checking regret"""
    return mix


def allCountries():
    """
            Method that returns all countries from the vocabulary
        """


def rect_I(w, t):
    """Return second moment of area for rectangular cross-sections.

    I_rect = (w×t^3)/12
    Source: Lueger 1904

    Args:
        w: width
        t: thickness

    Returns:
        A scalar.
    """
    return w * t ** 3 / 12


@staticmethod
def _variant_levels(level, variant):
    """
        Gets the level for the variant.

        :param int level: the current variant level
        :param int variant: the value for this level if variant

        :returns: a level for the object and one for the function
        :rtype: int * int
        """
    return (level + variant, level + variant) if variant != 0 else (variant,
        level)


def mse_persist_time_and_memory(run, session, timings):
    """
    Persist the memory results in the database.

    Args:
        run: The run we attach this timing results to.
        session: The db transaction we belong to.
        timings: The timing measurements we want to store.
    """
    from benchbuild.utils import schema as s
    for timing in timings:
        session.add(s.Metric(name='time.user_s', value=timing[0], run_id=
            run.id))
        session.add(s.Metric(name='time.system_s', value=timing[1], run_id=
            run.id))
        session.add(s.Metric(name='time.real_s', value=timing[2], run_id=
            run.id))
        session.add(s.Metric(name='time.rss', value=timing[3], run_id=run.id))


@staticmethod
def encode_stream(stream):
    """Utility method to encode a stream using utf-8.

        :param Any stream: The stream to be encoded using utf-8
        :return: A generator that yields the contents of the stream encoded as utf-8
        """
    for obj in stream:
        yield obj.encode('utf-8')


def get_api_interfaces_name_by_type(api_interfaces, type_str, key_name='name'):
    """
    Extract interface names from Interfaces API response by type
    :param api_interfaces: Interfaces API response
    :param type_str: Type string to match
    :param key_name: Optional - Key name to use (default 'name')
    :return: List of Interface names matching type_str
    """
    interface_name_list = []
    for interface in api_interfaces:
        if_name = interface.get(key_name)
        if if_name and interface.get('type') == type_str:
            interface_name_list.append(if_name)
    return interface_name_list


def ft_generic_win(fn, fw, fp, *args, **kwargs):
    """Iterates over the list of single features that make up a context
    window feature, and yields them one at a time. This function is the
    default behaviour for context window features.

    Note: If a window feature requires special behaviour, another window
    function needs to be provided and linked to it in the constructor. See
    `fnx` and `win_fnx` attributes in the constructor.

    **FEATURE VECTOR TEMPLATE BUILDING FUNCTION**

    :param fn: function name
    :param fw: context window
    :param fp: additional feature function parameters
    """
    prms = tuple() if fp is None else tuple(fp)
    for i in fw:
        yield (fn, i) + prms