@classmethod
def create_from_apic_json(cls, data, parent):
    """
        create from the apic json

        :param data: json dictionary
        :param parent: parent object
        :return: object created from json dictionary
        """
    attributes = data['vzEntry']['attributes']
    if 'name' in attributes:
        name = str(attributes.get('name'))
    elif 'dn' in attributes:
        name = cls._get_name_from_dn(str(attributes.get('dn')))
    else:
        raise ValueError('Name not found in attributes')
    entry = cls(name=name, parent=parent)
    entry._populate_from_attributes(attributes)
    return entry


@classmethod
def get_location_from_HDX_code(cls, code, locations=None, configuration=None):
    """Get location from HDX location code

        Args:
            code (str): code for which to get location name
            locations (Optional[List[Dict]]): Valid locations list. Defaults to list downloaded from HDX.
            configuration (Optional[Configuration]): HDX configuration. Defaults to global configuration.

        Returns:
            Optional[str]: location name
        """
    if locations is None:
        locations = cls.validlocations(configuration)
    for locdict in locations:
        if code.upper() == locdict['name'].upper():
            return locdict['title']
    return None


def chunks(data, size, padding=None):
    """Split data into chunks
    Args:
        data      : The target data to split
        size (int): The size of each chunk
        padding   : Data for padding (None if not to add padding)

    Returns:
        list: split chunks
    """
    assert size > 0
    result = []
    for i in range(0, len(data), size):
        result.append(data[i:i + size])
    if padding is not None and len(data) % size > 0:
        result[-1] += padding * (size - len(data) % size)
    return result


def get_playlist_youtube_url(playlist_code):
    """ Get the Youtube Playlist URL given its code

    Example:
        https://www.youtube.com/playlist?list=PLuMK2S9sZg71QqVzwepG-bLBxcJWEzcW9
        must return:
        PLuMK2S9sZg71QqVzwepG-bLBxcJWEzcW9
    """
    return 'https://www.youtube.com/playlist?list={:s}'.format(playlist_code)


def setCreators(creators):
    """ Set DCMI Creator elements - resource authors.

        o Permission:  Modify portal content
        """


@staticmethod
def is_hc_type(x):
    """ Is this one of our types of Handicap markets
        """
    return x in ['hc', '1x2_hc']


def set_defaults(options, **defaults):
    """Update options with default values."""
    if 'defaults' not in options:
        options = dict(options)
        options['defaults'] = defaults
    return options


def has_metadata(name):
    """Does the package's distribution contain the named metadata?"""


def select_set():
    """Set the console selection

    """
    pass


def get_attr_from_base_classes(bases, attrs, attr, default=None):
    """
    The attribute is retrieved from the base classes if they are not already
    present on the object.

    Args:
        bases (tuple, list): The base classes for a class.
        attrs (dict): The attributes of the class.
        attr (str): Specific attribute being looked for.
        default (any): Whatever default value is expected if the
            attr is not found.

    Returns:
        attribute value as found in base classes or a default when attribute
        is not found and default is provided.

    Raises:
        AttributeError: When the attribute is not present anywhere in the
            call chain hierarchy specified through bases and the attributes
            of the class itself
    """
    if attr in attrs:
        return attrs[attr]
    for base in bases:
        try:
            return getattr(base, attr)
        except AttributeError:
            continue
    if default is not None:
        return default
    raise AttributeError('None of the bases have {} attribute'.format(attr))


def createMainWidget(argv):
    """
    Function to create the main widget.

    @param argv list of commandline parameters (list of strings)
    @return reference to the main widget (QWidget)
    """
    from HexEdit.HexEditMainWindow import HexEditMainWindow
    try:
        fileName = argv[1]
    except IndexError:
        fileName = ''
    editor = HexEditMainWindow(fileName, None)
    return editor


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

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


def _skl_grid_score(X, y, scorer_, best_estimator_, refit, multimetric_):
    """Returns the score on the given data, if the estimator has been
        refit.

        This uses the score defined by ``scoring`` where provided, and the
        ``best_estimator_.score`` method otherwise.

        Parameters
        ----------
        X : array-like, shape = [n_samples, n_features]
            Input data, where n_samples is the number of samples and
            n_features is the number of features.

        y : array-like, shape = [n_samples] or [n_samples, n_output], optional
            Target relative to X for classification or regression;
            None for unsupervised learning.

        Returns
        -------
        score : float
        """
    if scorer_ is None:
        raise ValueError(
            "No score function explicitly defined, and the estimator doesn't provide one %s"
             % best_estimator_)
    score = scorer_[refit] if multimetric_ else scorer_
    return score(best_estimator_, X, y)


def onlywhite(line):
    """Return true if the line does only consist of whitespace characters."""
    for c in line:
        if c is not ' ' and c is not '  ':
            return c is ' '
    return line


def remove_cookie_by_name(cookiejar, name, domain=None, path=None):
    """Unsets a cookie by name, by default over all domains and paths.

    Wraps CookieJar.clear(), is O(n).
    """
    clearables = []
    for cookie in cookiejar:
        if cookie.name != name:
            continue
        if domain is not None and domain != cookie.domain:
            continue
        if path is not None and path != cookie.path:
            continue
        clearables.append((cookie.domain, cookie.path, cookie.name))
    for domain, path, name in clearables:
        cookiejar.clear(domain, path, name)


def data_transformer(x, y, xfactor, yfactor, **kwargs):
    """Multiplies x or y data by their corresponding factor."""
    return {'x': x * xfactor, 'y': y * yfactor}


def get_A2_hom(s):
    """
    Builds A2 for the spatial error GM estimation with homoscedasticity as in
    Anselin (2011) :cite:`Anselin2011`

    .. math::

        A_2 = \\dfrac{(W + W')}{2}

    ...

    Parameters
    ----------
    s               : csr_matrix
                      PySAL W object converted into Scipy sparse matrix
    Returns
    -------
    Implicit        : csr_matrix
                      A2 matrix in scipy sparse format
    """
    return (s + s.T) / 2.0


def prody_catdcd(*dcd, **kwargs):
    """Concatenate *dcd* files.

    :arg select: atom selection

    :arg align: atom selection for aligning frames

    :arg pdb: PDB file used in atom selections and as reference for alignment

    :arg psf: PSF file used in atom selections

    :arg output: output filename

    :arg first: index of the first output frame

    :arg last: index of the last output frame

    :arg stride: number of steps between output frames"""
    import prody
    LOGGER = prody.LOGGER
    if kwargs.get('numframes', False):
        from sys import stdout
        for fn in dcd:
            stdout.write(str(prody.DCDFile(fn).numFrames()) + '\n')
        return
    from os.path import splitext
    ag = None
    psf = kwargs.get('psf', None)
    if psf:
        ag = prody.parsePSF(psf)
    pdb = kwargs.get('pdb', None)
    if pdb:
        if ag:
            ag = prody.parsePDB(pdb, ag=ag)
        else:
            ag = prody.parsePDB(pdb)
    align = kwargs.get('align', None)
    select = kwargs.get('select', None)
    if select == 'all':
        select = None
    if ag is None and (align or select):
        raise ValueError(
            'one of PSF or PDB files must be provided for align and select options to work'
            )
    dcd = list(dcd)
    traj = prody.Trajectory(dcd.pop(0))
    while dcd:
        traj.addFile(dcd.pop(0))
    if ag:
        traj.link(ag)
        if ag.numCoordsets():
            traj.setCoords(ag.getCoords())
        if select:
            select = ag.select(select)
            if select is None:
                raise ValueError('{0} did not match any atoms'.format(repr(
                    kwargs.get('select'))))
        else:
            select = ag
        LOGGER.info('{0} atoms are selected for writing output.'.format(len
            (select)))
        if align:
            align = ag.select(align)
            traj.setAtoms(align)
            LOGGER.info('{0} atoms are selected for aligning frames.'.
                format(len(align)))
    output = kwargs.get('output', 'trajectory.dcd')
    out = prody.DCDFile(output, 'w')
    count = 0
    stride = kwargs.get('stride', 1)
    goto = stride != 1
    slc = slice(kwargs.get('first', 0), kwargs.get('last', -1), stride
        ).indices(len(traj) + 1)
    for i in range(*slc):
        if goto:
            traj.goto(i)
        frame = next(traj)
        if align:
            frame.superpose()
        if select:
            out.write(select._getCoords(), frame.getUnitcell())
        else:
            out.write(frame._getCoords(), frame.getUnitcell())
        count += 1
    traj.close()
    out.close()
    LOGGER.info('{0} frames are written into {1}.'.format(count, output))


@staticmethod
def login(email, password, reciever, title, text):
    """
        If you use gmail or similar, check if the option for blocking
        not-safe log is enable, if is enable, disable it.
        """
    import smtplib
    title = 'Subject: ' + str(title) + '\n\n'
    _message = title + text
    _email = smtplib.SMTP('smtp.gmail.com', 587)
    _email.ehlo()
    _email.starttls()
    _email.login(email, password)
    _email.sendmail(email, reciever, _message)
    _email.quit()
    return _message


@staticmethod
def concat_url(endpoint, url):
    """Concatenate endpoint and final URL.

        E.g., "http://keystone/v2.0/" and "/tokens" are concatenated to
        "http://keystone/v2.0/tokens".

        :param endpoint: the base URL
        :param url: the final URL
        """
    return '%s/%s' % (endpoint.rstrip('/'), url.strip('/'))


def composition(particles):
    """
    Return a dictionary containing the number of particles of each
    species appearing the input `particles` list.
    """
    from collections import defaultdict
    comp = defaultdict(int)
    for p in particles:
        comp[p.species] += 1
    return comp


@staticmethod
def _get_name_from_dn(dn):
    """
        Get the instance name from the dn

        :param dn: string containing the distinguished name URL
        :return: string containing the name
        """
    name = dn.split('/sys/ch/supslot-1/sup')[1].split('/')[0]
    return name


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


@staticmethod
def change_scene_register(register_id):
    """Change the scene register id.

        :param    int    register_id:    Register id 0..9
        :return:  The PCK command (without address header) as text
        :rtype:   str
        """
    if register_id < 0 or register_id > 9:
        raise ValueError('Wrong register_id.')
    return 'SZW{:03d}'.format(register_id)


@classmethod
def tree_to_dict(cls, tree):
    """
        Given an OptionTree, convert it into the equivalent dictionary format.
        """
    specs = {}
    for k in tree.keys():
        spec_key = '.'.join(k)
        specs[spec_key] = {}
        for grp in tree[k].groups:
            kwargs = tree[k].groups[grp].kwargs
            if kwargs:
                specs[spec_key][grp] = kwargs
    return specs


def sysinfo(filepath: str=''):
    """Generate system information, saved into a text file

    :param filepath: filepath
    :type filepath: str
    """
    pass


def not_none(passed, default):
    """Returns `passed` if not None, else `default` is returned"""
    return passed if passed is not None else default


def authGSSServerUserName(context):
    """
    Get the user name of the principal trying to authenticate to the server.
    This method must only be called after L{authGSSServerStep} returns a
    complete or continue response code.

    @param context: The context object returned from L{authGSSClientInit}.

    @return: A string containing the user name.
    """


def format_to_str(value, empty_value='--', format_string='%0.2f'):
    """
    Format value with format_string when evaluated as True
    else return the empty value
    """
    if not value:
        return empty_value
    return format_string % value


def forwards(apps, schema_editor):
    """
    Change all Play objects into Work objects, and their associated
    data into WorkRole and WorkSelection models, then delete the Play.
    """
    Play = apps.get_model('spectator_events', 'Play')
    Work = apps.get_model('spectator_events', 'Work')
    WorkRole = apps.get_model('spectator_events', 'WorkRole')
    WorkSelection = apps.get_model('spectator_events', 'WorkSelection')
    for p in Play.objects.all():
        work = Work.objects.create(kind='play', title=p.title, title_sort=p
            .title_sort)
        for role in p.roles.all():
            WorkRole.objects.create(creator=role.creator, work=work,
                role_name=role.role_name, role_order=role.role_order)
        for selection in p.events.all():
            WorkSelection.objects.create(event=selection.event, work=work,
                order=selection.order)
        p.delete()


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 sort_calculation_queue(graph_unsorted):
    """
    Sort the calculation queue.

    Returns
    -------
    list
    """
    graph_sorted = []
    while graph_unsorted:
        acyclic = False
        for item in graph_unsorted:
            for edge in item[1]:
                if edge in dict(graph_unsorted):
                    break
            else:
                acyclic = True
                graph_unsorted.remove(item)
                graph_sorted.append(item[0])
        if not acyclic:
            raise RuntimeError('A cyclic dependency occurred')
    return graph_sorted[::-1]


def context_toggle_enum(data_path: str='', value_1: str='', value_2: str=''):
    """Toggle a context value

    :param data_path: Context Attributes, RNA context string
    :type data_path: str
    :param value_1: Value, Toggle enum
    :type value_1: str
    :param value_2: Value, Toggle enum
    :type value_2: str
    """
    pass


def downgrade():
    """Migrations for the downgrade."""


def F2C(F):
    """Convert Fahrenheit to Celcius"""
    return (F - 32) / 1.8


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

    The ".dev0" means dirty.

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


def set_transformer_in_out(transformer, inputCol, outputCol):
    """Set input and output column(s) of a transformer instance."""
    transformer = transformer.copy()
    try:
        transformer.setInputCol(inputCol)
    except AttributeError:
        try:
            transformer.setInputCols([inputCol])
        except AttributeError:
            message = (
                "Invalid transformer (doesn't have setInputCol or setInputCols): "
                , str(transformer.__class__))
            raise ValueError(message)
    try:
        transformer.setOutputCol(outputCol)
    except AttributeError:
        try:
            transformer.setOutputCols([outputCol])
        except AttributeError:
            pass
    return transformer


@classmethod
def set_class_default(mcs, model, attr, value, instances=False):
    """Set DEFAULT attribute for Model class

        Arguments:
        model -- name of model class
        attr -- attribute name
        value -- new attribute value

        Keyword arguments:
        instances -- update instances too (default=False)
        """
    cls = mcs.__classes__[model]
    if attr in cls.REPLACE:
        attr = cls.REPLACE[attr]
    if attr in cls.DEFAULT:
        cls.DEFAULT[attr] = value
    if instances:
        cls.set_instances_default(attr, value)


def fix(data=None, out=None, name=None, **kwargs):
    """Returns element-wise rounded value to the nearest \\
    integer towards zero of the input.

    Example::

       fix([-2.1, -1.9, 1.9, 2.1]) = [-2., -1.,  1., 2.]

    The storage type of ``fix`` output depends upon the input storage type:

       - fix(default) = default
       - fix(row_sparse) = row_sparse
       - fix(csr) = csr

    Defined in src/operator/tensor/elemwise_unary_op_basic.cc:L875

    Parameters
    ----------
    data : NDArray
        The input array.

    out : NDArray, optional
        The output NDArray to hold the result.

    Returns
    -------
    out : NDArray or list of NDArrays
        The output of this function.
    """
    return 0,


def assert_string_data(value: str) ->None:
    """Asserts value is string type."""
    assert isinstance(value, str
        ), f'Input value type must be string. Actual type: {type(value)}, value: {value}'


def _get_best_indexes(logits, n_best_size):
    """Get the n-best logits from a list."""
    index_and_score = sorted(enumerate(logits), key=lambda x: x[1], reverse
        =True)
    best_indexes = []
    for i in range(len(index_and_score)):
        if i >= n_best_size:
            break
        best_indexes.append(index_and_score[i][0])
    return best_indexes


def as_scalar(data):
    """Returns a scalar whose value is copied from this array.

    Parameters
    ----------
    data : Tensor
        The input data

    Returns
    -------
    scalar
        The scalar value in the tensor.
    """
    pass


@staticmethod
def _compile_flag_table(flag_data_set):
    """ Take the parsed data set from Scrape.parse_flag_table and creates a dictionary.
            :param flag_data_set: list(list(str, str, str, str)): list of lists len 4 of:
                                    flag name, short name, data type, description
            :return: dict(str:dict(str:str, str:str, str:str), dict with keys of flags and each flag value is a dict
                     of short name 'short', data type 'data_type' and description 'description'
        """
    flags = {}
    for flag_data in flag_data_set:
        name, short, data_type, description = flag_data
        flags[name] = {'short': short, 'data_type': data_type,
            'description': description}
    return flags


def gen_name(prefix='', suffix=''):
    """
    Generate simple "random" name

    Parameters
    ----------
    prefix : string, optional
        Prefix of the name
    suffix : string, optional
        Suffix of the name

    Returns
    -------
    string

    """
    out = ''
    numbers = '0123456789'
    letters = 'abcdefghijklmnopqrstuvwxyz'
    chars = numbers + letters
    value = id(eval('{}'))
    value, i = divmod(value, len(letters))
    out = letters[i] + out
    while value:
        value, i = divmod(value, len(chars))
        out = chars[i] + out
    return '%s%s%s' % (prefix, ''.join(reversed(out)), suffix)


def __get_pcs_steps(in_file):
    """

    Get a list indicating the type of step for each step in a PCS data file.

    Parameters
    ----------
    in_file: str
        Path to PCS file

    Returns
    -------
    steps: list
        A list of step types. for numeric data, the step type is 'data', for
        other step types 'other'

    """
    steps = []
    with open(in_file) as dat_file:
        for line in dat_file:
            if line.startswith('Step ') and ' started at ' in line:
                steps.append('data')
            if line.lower().startswith('step type\tmapper\t') or line.lower(
                ).startswith('step type\tzero_check\t') or line.lower(
                ).startswith('step type\tfilm_zero\t') or line.lower(
                ).startswith('step type\theating\t'):
                steps[-1] = 'other'
    return steps


def colordiff(rgb1, rgb2):
    """From w3c (greater than 500 is good).
       (range [0..765])
    """
    r, g, b = rgb1
    r2, g2, b2 = rgb2
    return max(r, r2) - min(r, r2) + max(g, g2) - min(g, g2) + max(b, b2
        ) - min(b, b2)


def network_split_edge(network, u, v, t=0.5):
    """Split and edge by inserting a node along its length.

    Parameters
    ----------
    u : str
        The key of the first node of the edge.
    v : str
        The key of the second node of the edge.
    t : float
        The position of the inserted node.

    Returns
    -------
    str
        The key of the inserted node.

    Raises
    ------
    ValueError
        If `t` is not `0 <= t <= 1`.
    Exception
        If `u` and `v` are not neighbors.

    Examples
    --------
    >>>
    """
    if not network.has_edge(u, v):
        return
    if t <= 0.0:
        raise ValueError('t should be greater than 0.0.')
    if t >= 1.0:
        raise ValueError('t should be smaller than 1.0.')
    x, y, z = network.edge_point(u, v, t)
    w = network.add_node(x=x, y=y, z=z)
    network.add_edge(u, w)
    network.add_edge(w, v)
    if v in network.edge[u]:
        del network.edge[u][v]
    elif u in network.edge[v]:
        del network.edge[v][u]
    else:
        raise Exception
    network.adjacency[u][w] = None
    network.adjacency[w][v] = None
    del network.adjacency[u][v]
    network.adjacency[v][w] = None
    network.adjacency[w][u] = None
    del network.adjacency[v][u]
    return w


@staticmethod
def validate_string(cls, value):
    """Override this method to do your own input validation on the input
        string. This is called before converting the incoming string to the
        native python value."""
    return cls.Attributes.nillable or value is not None


@staticmethod
def _was_exp_claim_rejected_due_to_clock_skew(network_response):
    """
        Determine whether the network response indicates that the authorization request was rejected because of
        the exp claim. This can happen if the current system time is too different from the Box server time.

        Returns True if the status code is 400, the error code is invalid_grant, and the error description indicates
        a problem with the exp claim; False, otherwise.

        :param network_response:
        :type network_response:
            :class:`Response`
        :rtype:
            `bool`
        """
    status_code = network_response.status_code
    try:
        json_response = network_response.json()
    except ValueError:
        return False
    error_code = json_response.get('error', '')
    error_description = json_response.get('error_description', '')
    return (status_code == 400 and error_code == 'invalid_grant' and 'exp' in
        error_description)


def _add_doc(func, doc):
    """Add documentation to a function."""
    func.__doc__ = doc


def _get_neuron_id(dataframe):
    """Unique identifier string for a neuron"""
    return dataframe.animal + '_' + dataframe.day.map('{:02d}'.format
        ) + '_' + dataframe.epoch.map('{:02}'.format
        ) + '_' + dataframe.tetrode_number.map('{:03}'.format
        ) + '_' + dataframe.neuron_number.map('{:03}'.format)


def _parse_vnc_port(std_out):
    """Parse the VNC port number out of the standard output from mkvterm.

    :return:  The port number parsed otherwise None if no valid port
    """
    line = std_out.splitlines()[0] if std_out else None
    return int(line) if line and line.isdigit() else None


def set_native_id(idx):
    """
    Set native (unsorted) CUDA device ID

    Parameters
    ----------

    idx : int.
        Specifies the (unsorted) native index of the device.
    """
    import ctypes as ct
    from .util import safe_call as safe_call
    from .library import backend as backend
    if backend.name() != 'cuda':
        raise RuntimeError('Invalid backend loaded')
    safe_call(backend.get().afcu_set_native_id(idx))
    return


@staticmethod
def get_name_n_params(name, deflt=None):
    """Extract name and params from string like 'name(params)'"""
    deflt = '' if deflt is None else deflt
    i = name.find('(')
    j = name.rfind(')')
    if i >= 0 and j >= i:
        n = name[:i].strip()
        p = name[i + 1:j].strip()
    else:
        n = name.strip()
        p = deflt.strip()
    return n, p


def add_brains():
    """ See adapters.FacetBuilder
        """


def is_iterable(obj):
    """Tests if an object implements the iterable protocol.
    This function is intentionally not capitalized, because
    it does not check w.r.t. (capital) Iterable class from
    typing or collections.
    """
    try:
        itr = iter(obj)
        del itr
        return True
    except:
        return False


@classmethod
def get(cls, *args, **kwargs):
    """Get the seq number."""
    result = cls.save({'id': cls.seq_uid(*args, **kwargs)}, render='raw')
    if kwargs.get('raw'):
        return result
    return result.get('_version')


def _mv_legacy_headers_for_service(mv_service_type):
    """Workaround for services that predate standardization.

    TODO(sdague): eventually convert this to using os-service-types
    and put the logic there. However, right now this is so little
    logic, inlining it for release is a better call.

    """
    headers = []
    if mv_service_type == 'compute':
        headers.append('X-OpenStack-Nova-API-Version')
    elif mv_service_type == 'baremetal':
        headers.append('X-OpenStack-Ironic-API-Version')
    return headers


def shared_lib_name(group_name: str) ->str:
    """Given a group name, return the actual name of its extension module.

    (This just adds a suffix to the final component.)
    """
    return '{}__mypyc'.format(group_name)


def validate_pre_plugin_load():
    """Checks if the configuration variables are valid.

    If the configuration is invalid then the method will return an error
    message. If all is OK then it will return None.
    """
    message = None
    return message


def escapeRegExpString(string):
    """
        Escape the given string to include it as a regular expression

        @param string: A regular expression to be escaped
        @return: Escaped string
    """
    toEscapeChars = ['\\', '(', ')', '.', '|', '^', '$', '*', '+', '?', '[',
        ']']
    escapedValue = ''
    for i in range(len(string)):
        if string[i] in toEscapeChars:
            escapedValue += '\\' + string[i]
        else:
            escapedValue += string[i]
    return escapedValue


def mask_hash(hash, show=6, char='*'):
    """
    Return the given hash, with only the first ``show`` number shown. The
    rest are masked with ``char`` for security reasons.
    """
    masked = hash[:show]
    masked += char * len(hash[show:])
    return masked


def is_packet_type(cls):
    """Check if class is one the packet types."""
    from .packet_types import EddystoneUIDFrame, EddystoneURLFrame, EddystoneEncryptedTLMFrame, EddystoneTLMFrame, EddystoneEIDFrame, IBeaconAdvertisement, EstimoteTelemetryFrameA, EstimoteTelemetryFrameB
    return cls in [EddystoneURLFrame, EddystoneUIDFrame,
        EddystoneEncryptedTLMFrame, EddystoneTLMFrame, EddystoneEIDFrame,
        IBeaconAdvertisement, EstimoteTelemetryFrameA, EstimoteTelemetryFrameB]


def _dist_wrapper(dist_func, dist_matrix, slice_, *args, **kwargs):
    """Write in-place to a slice of a distance matrix"""
    dist_matrix[:, (slice_)] = dist_func(*args, **kwargs)


def standard_warning_format(message: str, category: str, filename: str,
    lineno: int, file: str=None, line: int=None) ->str:
    """
    Sets the standard warning message format to be:
        filename: lineno: category: message

    Parameters
    ----------
        message: str
            warning message to be printed to a user
        category: str
            type of the warning message
        filename: str
            name of the associated to the warning message
        lineno : int
            line number where the warning message was raised
        file : str
        line : str

    Returns
    -------
        formatted warning message to be printed to the console
    """
    return '{filename}: {linenum}: {category}: {message}\n'.format(filename
        =filename, linenum=lineno, category=category.__name__, message=message)


@staticmethod
def service_name() ->str:
    """
        Returns a service name that this custom resource manages.

        :return: Service name.
        """
    return 'CodeStar'


def contains(array, *args):
    """
    Check rather the given array contains at least one of the given items
    :param array:
    :param args:
    :return: true if at least one item exists, false otherwise
    """
    for arg in args:
        if array.__contains__(arg):
            return True
    return False


def range_of(x):
    """All indices of collection `x` (i.e. `list(range(len(x)))`)"""
    return list(range(len(x)))


def descendants(revs):
    """Obtain descendant revision numbers for a set of revision numbers.

        If ``nullrev`` is in the set, this is equivalent to ``revs()``.
        """


def getvar(request, field_name, setsession=False):
    """Check field in POST/GET request and return field value
    if there is value you can also save a session variable
    """
    if request.method == 'GET':
        if field_name in request.GET:
            val = request.GET[field_name]
        else:
            val = ''
    if request.method == 'POST':
        if field_name in request.POST:
            val = request.POST[field_name]
        else:
            val = ''
    if setsession and val and val != '':
        request.session['session_' + field_name] = val
    return val


@classmethod
def merge_pexes(cls, path, pex_info, interpreter, pexes,
    interpeter_constraints=None):
    """Generates a merged pex at path."""
    with cls.merged_pex(path, pex_info, interpreter, pexes,
        interpeter_constraints) as builder:
        builder.freeze(bytecode_compile=False)


@classmethod
def _brightness_threshold(cls, rgb_tuple, min_brightness, light_color,
    dark_color='black'):
    """
        Determine ideal plot label color (light or dark) based on brightness of
        background color based on a given brightness threshold.

        Adapted from https://trendct.org/2016/01/22/how-to-choose-a-label-color-to-contrast-with-background/
        """
    if cls._check_brightness(rgb_tuple) > min_brightness:
        return dark_color
    return light_color


def keymap_restore(all: bool=False):
    """Restore key map(s)

    :param all: All Keymaps, Restore all keymaps to default
    :type all: bool
    """
    pass


def _validate_target(target, output_shape):
    """
    Check whether ``target``,
    an integer index into the model's output
    is valid for the given ``output_shape``.
    """
    if isinstance(target, int):
        output_nodes = output_shape[1:][0]
        if not 0 <= target < output_nodes:
            raise ValueError(
                'Prediction target index is outside the required range [0, {}). '
                , 'Got {}'.format(output_nodes, target))
    else:
        raise TypeError('Prediction target must be int. Got: {}'.format(target)
            )


@staticmethod
def _find_needle(image, lower, upper, threshold=5):
    """
        Determines and extracts the top area of the lower image that we will
        try to find in the upper one.

        This method exists to attempt to eradicate the unreliable situation
        where we are determining where to stitch based on areas of the images
        which lack text.

        :param image: The second image in the join pair.
        :param lower: The minimum height of the needle area.
        :param upper: The maximum height of the needle area.
        :param threshold: The minimum number of unique colours a viable match
                          area contains.
        :return: The decided needle image.
        """
    assert lower <= upper <= image.height
    for offset in range(lower, upper + 1):
        crop = image.crop((0, 0, image.width, offset))
        if not crop.getcolors(threshold - 1):
            return crop
    return image.crop((0, 0, image.width, upper))


def activate_avatar_action(user):
    """Activate the selected avatar in the activate_avatar state."""
    return user.activate_avatar_by_index(int(user.choice) - 1)


def _imdex2(closed, n):
    """(INTERNAL) Return first and second index.
    """
    return (n - 1, 0) if closed else (0, 1)


def build_metadata_from_setuptools_dict(metadata):
    """Build and return metadata from a setuptools dict.

    This is typically from package metadata.
    """
    project_urls = metadata['project_urls']
    output = {'name': metadata['name'], 'version': metadata['version'],
        'description': metadata['description'], 'homepage': metadata['url'],
        'license': metadata['license'], 'maintainers': metadata['author'],
        'repository': project_urls['Source'], 'issuesurl': project_urls[
        'Tracker']}
    output['contributors'] = metadata.get('contributors', None)
    return output


def _blend(img1, img2, alpha):
    """
    Weighted sum of two images

    Arguments
    ---------
    img1 : torch tensor
    img2 : torch tensor
    alpha : float between 0 and 1
        how much weight to put on img1 and 1-alpha weight
        to put on img2
    """
    return img1.mul(alpha).add(1 - alpha, img2)


def batcher(X_, y_=None, w_=None, batch_size=-1):
    """Split data to mini-batches.

    Parameters
    ----------
    X_ : {numpy.array, scipy.sparse.csr_matrix}, shape (n_samples, n_features)
        Training vector, where n_samples in the number of samples and
        n_features is the number of features.

    y_ : np.array or None, shape (n_samples,)
        Target vector relative to X.

    w_ : np.array or None, shape (n_samples,)
        Vector of sample weights.

    batch_size : int
        Size of batches.
        Use -1 for full-size batches

    Yields
    -------
    ret_x : {numpy.array, scipy.sparse.csr_matrix}, shape (batch_size, n_features)
        Same type as input

    ret_y : np.array or None, shape (batch_size,)

    ret_w : np.array or None, shape (batch_size,)
    """
    n_samples = X_.shape[0]
    if batch_size == -1:
        batch_size = n_samples
    if batch_size < 1:
        raise ValueError('Parameter batch_size={} is unsupported'.format(
            batch_size))
    for i in range(0, n_samples, batch_size):
        upper_bound = min(i + batch_size, n_samples)
        ret_x = X_[i:upper_bound]
        ret_y = None
        ret_w = None
        if y_ is not None:
            ret_y = y_[i:i + batch_size]
        if w_ is not None:
            ret_w = w_[i:i + batch_size]
        yield ret_x, ret_y, ret_w


def activate(client, name, file_=None):
    """Activate a model view.

    Args:
        client (obj):
            creopyson Client.
        name (str):
            View name.
        `file_` (str, optional):
            Model name. Defaults is current active model.

    Returns:
        None

    """
    data = {'name': name}
    if file_ is not None:
        data['file'] = file_
    else:
        active_file = client.file_get_active()
        if active_file is not None:
            data['file'] = active_file['file']
    return client._creoson_post('view', 'activate', data)


def vienna_output(seq, pairs, header_lines=None, removed=None):
    """Return sequence and structure information in vienna format

    seq -- string of sequence characters, no validation
    pairs -- Pairs object or list of tuples
    header_lines -- list of header lines at the top of the file

    Return value is a formatted string:
    > header information
    sequence
    vienna structure
    """
    result = []
    if not header_lines:
        head = '> Nested structure'
    else:
        head = '> ' + header_lines[0].strip()
    result.append(head)
    result.append(seq)
    result.append(pairs.toVienna(len(seq)))
    if removed is not None:
        result.append('>REMOVED BASE PAIRS FOR: %s' % head)
        try:
            result.append(removed.toVienna(len(seq)))
        except:
            result.append(str(removed))
    return '\n'.join(result)


def ifelse(test, if_true, if_false):
    """
    Return `if_true` is argument `test` evaluates to `True`,
    return `if_false` otherwise.

    This is just a workaround for Python 2.4 lack of the
    conditional assignment operator::

      >>> a = 1
      >>> b = ifelse(a, "yes", "no"); print(b)
      yes
      >>> b = ifelse(not a, 'yay', 'nope'); print(b)
      nope

    """
    if test:
        return if_true
    else:
        return if_false


def plot_ts(ts_df, plot_title, eventDates, eventLabels=None, save_file_name
    =None, xLabel=None, yLabel=None, show=False):
    """Function to plot the time series data. """
    ax = ts_df.plot(title=plot_title, marker='*', markerfacecolor='red',
        markersize=10, linestyle='solid')
    colors = ['r', 'g', 'c', 'm', 'y', 'b', 'k']
    if not eventLabels:
        for eventDate in eventDates:
            ax.axvline(eventDate, color='r', linestyle='--', lw=2)
    else:
        for idx in range(len(eventDates)):
            ax.axvline(eventDates[idx], color=colors[idx], linestyle='--',
                lw=2, label=eventLabels[idx])
            ax.legend()
    if xLabel:
        ax.set_xlabel(xLabel, fontweight='bold')
    if yLabel:
        ax.set_ylabel(yLabel, fontweight='bold')
    fig = ax.get_figure()
    if save_file_name:
        fig.savefig(save_file_name, bbox_inches='tight')
    if show:
        fig.show()


def _is_iterable(obj):
    """A Python 2 and 3 compatible util to check whether `obj` is iterable."""
    try:
        iter(obj)
        return True
    except TypeError:
        return False


def zerocopy_from_dlpack(dlpack_tensor):
    """Create a tensor that shares the dlpack_tensor.

    Parameters
    ----------
    dlpack_tensor : dlpack capsule
        The dlpack tensor.

    Returns
    -------
    Tensor
        A framework-specific tensor.
    """
    pass


def wavelength_to_rgb(wavelength, gamma=0.8):
    """This converts a given wavelength of light to an
    approximate RGB color value. The wavelength must be given
    in nanometers in the range from 380 nm through 750 nm
    (789 THz through 400 THz).

    Based on code by Dan Bruton
    http://www.physics.sfasu.edu/astro/color/spectra.html
    """
    wavelength = float(wavelength)
    if wavelength >= 380 and wavelength <= 440:
        attenuation = 0.3 + 0.7 * (wavelength - 380) / (440 - 380)
        R = (-(wavelength - 440) / (440 - 380) * attenuation) ** gamma
        G = 0.0
        B = (1.0 * attenuation) ** gamma
    elif wavelength >= 440 and wavelength <= 490:
        R = 0.0
        G = ((wavelength - 440) / (490 - 440)) ** gamma
        B = 1.0
    elif wavelength >= 490 and wavelength <= 510:
        R = 0.0
        G = 1.0
        B = (-(wavelength - 510) / (510 - 490)) ** gamma
    elif wavelength >= 510 and wavelength <= 580:
        R = ((wavelength - 510) / (580 - 510)) ** gamma
        G = 1.0
        B = 0.0
    elif wavelength >= 580 and wavelength <= 645:
        R = 1.0
        G = (-(wavelength - 645) / (645 - 580)) ** gamma
        B = 0.0
    elif wavelength >= 645 and wavelength <= 750:
        attenuation = 0.3 + 0.7 * (750 - wavelength) / (750 - 645)
        R = (1.0 * attenuation) ** gamma
        G = 0.0
        B = 0.0
    else:
        R = 0.0
        G = 0.0
        B = 0.0
    R = R * 255
    G = G * 255
    B = B * 255
    return int(R), int(G), int(B)


def _gen_path_responses(http_method, resource_name):
    """
    This function receives a HTTP method and a resource name and generates the standard responses of the method

    :param str http_method:
        http method used

    :param str resource_name:
        name of the resource being served

    :rtype dict:
    :return: dict containing the standard responses of the method
    """
    if http_method == 'GET_Collection':
        return {'200': {'description': 'successful operation', 'schema': {
            'type': 'array', 'items': {'$ref': '#/definitions/%s' %
            resource_name}}}}
    elif http_method == 'PUT':
        return {'204': {'description': 'successfully updated'}, '400': {
            'description': 'invalid %s supplied' % resource_name}, '404': {
            'description': '%s not found' % resource_name}}
    elif http_method == 'GET':
        return {'200': {'description': 'successful operation', 'schema': {
            '$ref': '#/definitions/%s' % resource_name}}, '400': {
            'description': 'invalid ID supplied'}, '404': {'description':
            '%s not found' % resource_name}}
    elif http_method == 'POST':
        return {'201': {'description': 'the %s was created successfully' %
            resource_name}, '405': {'description': 'invalid input'}}
    elif http_method == 'DELETE':
        return {'204': {'description': 'successfully deleted'}, '400': {
            'description': 'invalid ID supplied'}, '404': {'description':
            '%s not found' % resource_name}}
    return None


def last_segment(account_name):
    """Get the last segment of an account."""
    return account_name.split(':')[-1]


def v202_fixes(defaults, runtime, harmonization, dry_run):
    """
    Migrating collector parameter `feed` to `name`. RIPE expert set: `query_ripe_stat_ip` with `query_ripe_stat_asn` as default
    """
    changed = None
    for bot_id, bot in runtime.items():
        if bot['group'] == 'Collector' and bot['parameters'].get('feed'):
            try:
                bot['parameters']['name'] = bot['parameters']['feed']
                del bot['parameters']['feed']
            except KeyError:
                pass
            else:
                changed = True
        if bot['module'] == 'intelmq.bots.experts.ripe.expert':
            if 'query_ripe_stat_asn' in bot['parameters']:
                if 'query_ripe_stat_ip' not in bot['parameters']:
                    bot['parameters']['query_ripe_stat_ip'] = bot['parameters'
                        ]['query_ripe_stat_asn']
                    changed = True
        if bot['module'] in ('intelmq.bots.experts.cymru_whois.expert',
            'intelmq.bots.experts.reverse_dns.expert',
            'intelmq.bots.experts.modify.expert'):
            if 'overwrite' not in bot['parameters']:
                bot['parameters']['overwrite'] = True
                changed = True
    return changed, defaults, runtime, harmonization


@staticmethod
def address_zone(address):
    """
        Get the zone a address belongs to.
        """
    parts = reversed(address.split('.')[:-1])
    return '%s.in-addr.arpa.' % '.'.join(parts)


def version():
    """Versions of main packages."""
    import pkg_resources
    ver = pkg_resources.get_distribution('pyspedas_examples').version
    print('pyspedas_examples version: ' + ver)
    verp = pkg_resources.get_distribution('pyspedas').version
    print('pyspedas version: ' + verp)


def get_query(request, model, **kw):
    """called to retrieve a filtered and sorted sqla query."""


def biquadratic_distance(p, q):
    """ The *biquadratic distance*, :math:`d_{bq}(p, q) := 2 (p - q)^2 + (4/9) * (p - q)^4`."""
    d = 2 * (p - q) ** 2
    return d + d ** 2 / 9.0


def _split_line(line):
    """Split line into leading whitespace, list of words, and trailing whitespace."""
    return line[:-len(line.lstrip())], line.split(), line[len(line.rstrip()):]


def extract_temperature_value_from_pimc_file_path(file_path):
    """ does what it says, returns a float"""
    return float(file_path.split('_T')[1].split('_J')[0])


def tupleit1(anarray):
    """Convert a non-hashable 1D numpy array to a hashable tuple."""
    return tuple(list(anarray))


def notify(transitions, logger):
    """
    A generator taking a sequence of alarm transitions, logs them, and then re-yields them:

        transitions = notify( a.compute(), logging.info )
        for trans in transitions:
            ...
    """
    for trans in transitions:
        logger(trans.message())
        yield trans


@staticmethod
def _make_record_id(record):
    """Make record id based on CHROM POS REF ALT"""
    alt = record.ALT[0]
    ref = record.REF
    if len(alt) > 10:
        alt = alt[0:7] + '...'
    if len(ref) > 10:
        ref = ref[0:7] + '...'
    record_id = '{}_{}_{}_{}'.format(record.CHROM, record.POS, ref, alt)
    return record_id


@classmethod
def register_native_mapping(cls, type_id, callback):
    """
        Register a function to convert a core foundation data type into its
        equivalent in python

        :param type_id:
            The CFTypeId for the type

        :param callback:
            A callback to pass the CFType object to
        """
    cls._native_map[int(type_id)] = callback


def cols_to_float(df, columns):
    """Convert selected column values to float and return dataframe.

    Args:
        df: Pandas dataframe.
        columns: List of columns to convert.

    Returns:
        Original dataframe with converted column data.
    """
    for col in columns:
        df[col] = df[col].astype(float)
    return df


@staticmethod
def reduce(mapped, reducer):
    """
        Takes a list of events and a reducer function and returns
        a new Event with the result, for each column. The reducer is
        of the form

        ::

            function sum(valueList) {
                return calcValue;
            }

        Parameters
        ----------
        mapped : dict
            Dict as produced by map()
        reducer : function
            The reducer function.

        Returns
        -------
        dict
            A dict of reduced values.
        """
    result = dict()
    for k, v in list(mapped.items()):
        result[k] = reducer(v)
    return result


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 interpolate(x0, y0, x1, y1, x):
    """
    Linear interpolation between two values.

    """
    y = (y0 * (x1 - x) + y1 * (x - x0)) / (x1 - x0)
    return y


def exportZip(out):
    """Exports the contents of this directory as a zip file, which will
        be written to the open file handle ``out``.
        """


def _convert_tick_direction(tick_direction):
    """Convert the given tick direction to one that can be used by Matplotlib.

    References:
        - https://matplotlib.org/api/_as_gen/matplotlib.axes.Axes.tick_params.html
    """
    if tick_direction is None:
        returned_tick_direction = None
    else:
        possible_values = ['in', 'out']
        if tick_direction not in possible_values:
            raise ValueError('Invalid tick direction: "{}"Possible values: {}'
                .format(tick_direction, possible_values))
        if tick_direction == 'in':
            returned_tick_direction = 'in'
        elif tick_direction == 'out':
            returned_tick_direction = 'out'
    return returned_tick_direction


def parameters_ui(layout, params):
    """ Create the ui for the rig parameters."""
    r = layout.row()
    r.prop(params, 'neck_pos')
    r = layout.row()
    r.prop(params, 'pivot_pos')
    r = layout.row()
    r.prop(params, 'tail_pos')
    r = layout.row()
    r.prop(params, 'tweak_extra_layers')
    r.active = params.tweak_extra_layers
    col = r.column(align=True)
    row = col.row(align=True)
    for i in range(8):
        row.prop(params, 'tweak_layers', index=i, toggle=True, text='')
    row = col.row(align=True)
    for i in range(16, 24):
        row.prop(params, 'tweak_layers', index=i, toggle=True, text='')
    col = r.column(align=True)
    row = col.row(align=True)
    for i in range(8, 16):
        row.prop(params, 'tweak_layers', index=i, toggle=True, text='')
    row = col.row(align=True)
    for i in range(24, 32):
        row.prop(params, 'tweak_layers', index=i, toggle=True, text='')


def abort():
    """Aborts the new message.

        The message file is closed and removed from the ``tmp`` subdirectory
        of the `maildir`.

        Calling ``abort()`` more than once is allowed.
        """


def sum2digits(d):
    """ Sum digits of a number that is less or equal 18.

        >>> sum2digits(2)
        2
        >>> sum2digits(17)
        8
    """
    return d // 10 + d % 10


def _process_logging(cluster):
    """
    Parse cluster.logging.clusterLogging to verify if
    at least one entry has audit logging set to Enabled.
    """
    logging = False
    cluster_logging = cluster.get('logging', {}).get('clusterLogging')
    if cluster_logging:
        logging = any(filter(lambda x: 'audit' in x['types'] and x[
            'enabled'], cluster_logging))
    return logging


def is_list(annotation):
    """Returns True if annotation is a typing.List"""
    annotation_origin = getattr(annotation, '__origin__', None)
    return annotation_origin == list


@staticmethod
def directory_filter(directory, unwanted_dirs):
    """
        This method weeds out unwanted hidden directories from the model archive .mar file
        :param directory:
        :param unwanted_dirs:
        :return:
        """
    if directory in unwanted_dirs:
        return False
    if directory.startswith('.'):
        return False
    return True


def normalize_datapath_id(datapath_id):
    """Normalize datapath_id value."""
    if isinstance(datapath_id, int):
        return datapath_id
    if isinstance(datapath_id, str) and datapath_id:
        return int(datapath_id.replace(':', ''), 16)
    raise ValueError('Invalid datapath_id: %r' % datapath_id)


def t_ALWAYS_REPLY_RFC1048(t):
    """always-reply-rfc1048"""
    return t


def __call__(value):
    """
        Return a tuple with a new index name and a new value.
        if the index name returned is different from the native one, caller
        must replace treated index with the new ones.
        """


@staticmethod
def _probe_wrapper(func, tgen, p):
    """
        Wrapper function that point to constraint function.

        :param func: constraint function.
        :param args: positional arguments to pass on to constraint function
        :param kwargs: key arguments to pass on to constraint function
        :param p: annealer state used to calculate the probe parameters
        :return: A new probe solution based on tgen and a random function
        """
    return func(p, tgen)


def router(prefix, viewset, base_name):
    """
    Define an API route

    :param prefix:
    :param viewset:
    :param base_name:
    :return:
    """
    return {'prefix': prefix, 'viewset': viewset, 'base_name': base_name}


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

    The ".dev0" means dirty.

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


@classmethod
def header_type(cls, header_chunk):
    """Return the header type, given the first header chunk"""
    header_bits = cls.header_type_mask & header_chunk[0]
    for key, val in cls.header_type_by_desc.items():
        if val == header_bits:
            return key
    raise ValueError('Undefined header type:', header_bits)


@staticmethod
def positional_to_model(value):
    """Converts a positional argument to a model value"""
    return value


def join_tokens(tokens):
    """ Join a list of tokens together, simple when using the custom tokenize method """
    return ''.join(tokens)


def memstr_to_bytes(text):
    """ Convert a memory text to its value in bytes.
    """
    kilo = 1024
    units = dict(K=kilo, M=kilo ** 2, G=kilo ** 3)
    try:
        size = int(units[text[-1]] * float(text[:-1]))
    except (KeyError, ValueError):
        raise ValueError(
            "Invalid literal for size give: %s (type %s) should be alike '10G', '500M', '50K'."
             % (text, type(text)))
    return size


def jday(year, mon, day, hr, minute, sec):
    """Return two floats that, when added, produce the specified Julian date.

     The first float returned gives the date, while the second float
     provides an additional offset for the particular hour, minute, and
     second of that date.  Because the second float is much smaller in
     magnitude it can, unlike the first float, be accurate down to very
     small fractions of a second.

     >>> jd, fr = jday(2020, 2, 11, 13, 57, 0)
     >>> jd
     2458890.5
     >>> fr
     0.58125

     Note that the first float, which gives the moment of midnight that
     commences the given calendar date, always carries the fraction
     ``.5`` because Julian dates begin and end at noon.  This made
     Julian dates more convenient for astronomers in Europe, by making
     the whole night belong to a single Julian date.

     This function is a simple translation to Python of the C++ routine
     ``jday()`` in Vallado's ``SGP4.cpp``.

     """
    jd = 367.0 * year - 7 * (year + (mon + 9) // 12.0
        ) * 0.25 // 1.0 + 275 * mon / 9.0 // 1.0 + day + 1721013.5
    fr = (sec + minute * 60.0 + hr * 3600.0) / 86400.0
    return jd, fr


def escapeNTB(st, bar=True):
    """
		scapes Newline, Tab, Baskslash, and vertical Bar (if bar=True)
	"""
    st = st.replace('\\\\', '\\\\\\\\')
    st = st.replace('\t', '\\t')
    st = st.replace('\n', '\\n')
    if bar:
        st = st.replace('|', '\\|')
    return st


def glTranslate(x, y, z):
    """Multiply the current matrix by a translation matrix

    :param z: Specify the x, y, and z coordinates of a translation vector.
    """
    pass


def lif_exponential_voltage_update(v_cur, v_rest, v_in, alpha_v, tau_v, dt,
    refrac_counts):
    """Calculate change in cell's voltage based on current and incoming voltage.

    Voltage updates are performed according to the following formula:

    .. math::

        voltage_{t+1} = voltage_{t} + \\frac{(-(voltage_{t} - rest_{t}) + alpha * incoming_{t}) * dt}{tau}

    :param v_cur: Current voltages
    :param v_rest: Resting voltages
    :param v_in: Incoming voltages
    :param alpha_v: Incoming voltage scaling factor
    :param tau_v: Voltage decay time constant
    :param dt: Duration of single timestep
    :param refrac_counts: Number of timesteps left in refractory state for each :class:`Neuron`

    :return: New voltages
    """
    v_delta = dt / tau_v * (-(v_cur - v_rest) + alpha_v * v_in)
    non_refrac = refrac_counts == 0
    v_cur += v_delta * non_refrac.to(v_delta.dtype)
    return v_cur


@classmethod
def close_rf_cache(cls):
    """Run anything remaining on CachedRF object"""
    cls.rf_cache.close()


@staticmethod
def p_expression_binop(p):
    """expression : expression '+' expression
                      | expression '-' expression
                      | expression '*' expression
                      | expression '/' expression
                      | expression '|' expression
                      | expression LSHIFT expression
                      | expression RSHIFT expression"""
    if p[2] == '+':
        p[0] = p[1] + p[3]
    elif p[2] == '-':
        p[0] = p[1] - p[3]
    elif p[2] == '*':
        p[0] = p[1] * p[3]
    elif p[2] == '/':
        p[0] = p[1] / p[3]
    elif p[2] == '<<':
        p[0] = p[1] << p[3]
    elif p[2] == '>>':
        p[0] = p[1] >> p[3]
    elif p[2] == '|':
        p[0] = p[1] | p[3]


def vertex(a, x, h, k):
    """
    definition: func(a, x, h, k) {...}
    objective : returns the 'y' of the vertex formula
                y = a (x-h)^2 + k
    """
    result = a * ((x - h) * (x - h)) + k
    return result


def get_member_id_as_string(member):
    """Get string representation of ``member`` ID."""


def _octant_gt(octant, y, coord):
    """Return whether y is further along the circle than coord."""
    if octant % 2 == 1:
        return y < coord
    else:
        return y > coord


def _test_args():
    """Extra arguments to use when zipline's automated tests run this example.
    """
    import pandas as pd
    return {'start': pd.Timestamp('2008', tz='utc'), 'end': pd.Timestamp(
        '2013', tz='utc')}


def _fileobj_to_fd(fileobj):
    """ Return a file descriptor from a file object. If
    given an integer will simply return that integer back. """
    if isinstance(fileobj, int):
        fd = fileobj
    else:
        try:
            fd = int(fileobj.fileno())
        except (AttributeError, TypeError, ValueError):
            raise ValueError('Invalid file object: {0!r}'.format(fileobj))
    if fd < 0:
        raise ValueError('Invalid file descriptor: {0}'.format(fd))
    return fd


def gap_proportion(sequences, gap_chars='-'):
    """
    Generates a list with the proportion of gaps by index in a set of
    sequences.
    """
    aln_len = None
    gaps = []
    for i, sequence in enumerate(sequences):
        if aln_len is None:
            aln_len = len(sequence)
            gaps = [0] * aln_len
        elif not len(sequence) == aln_len:
            raise ValueError(
                'Unexpected sequence length {0}. Is this an alignment?'.
                format(len(sequence)))
        for j, char in enumerate(sequence.seq):
            if char in gap_chars:
                gaps[j] += 1
    sequence_count = float(i + 1)
    gap_props = [(i / sequence_count) for i in gaps]
    return gap_props


def main():
    """
    main() function, not directly callable.
    :return:
    """
    print('Not directly executable')


@classmethod
def dark_magenta(cls):
    """A factory method that returns a :class:`Colour` with a value of ``0xad1457``."""
    return cls(11342935)


def describe_cache_engine_versions(Engine=None, EngineVersion=None,
    CacheParameterGroupFamily=None, MaxRecords=None, Marker=None,
    DefaultOnly=None):
    """
    Returns a list of the available cache engines and their versions.
    See also: AWS API Documentation

    :example: response = client.describe_cache_engine_versions(
        Engine='string',
        EngineVersion='string',
        CacheParameterGroupFamily='string',
        MaxRecords=123,
        Marker='string',
        DefaultOnly=True|False
    )

    :type Engine: string
    :param Engine: The cache engine to return. Valid values: memcached | redis

    :type EngineVersion: string
    :param EngineVersion: The cache engine version to return.
            Example: 1.4.14

    :type CacheParameterGroupFamily: string
    :param CacheParameterGroupFamily: The name of a specific cache parameter group family to return details for.
            Valid values are: memcached1.4 | redis2.6 | redis2.8 | redis3.2
            Constraints:
            Must be 1 to 255 alphanumeric characters
            First character must be a letter
            Cannot end with a hyphen or contain two consecutive hyphens

    :type MaxRecords: integer
    :param MaxRecords: The maximum number of records to include in the response. If more records exist than the specified MaxRecords value, a marker is included in the response so that the remaining results can be retrieved.
            Default: 100
            Constraints: minimum 20; maximum 100.

    :type Marker: string
    :param Marker: An optional marker returned from a prior request. Use this marker for pagination of results from this operation. If this parameter is specified, the response includes only records beyond the marker, up to the value specified by MaxRecords .

    :type DefaultOnly: boolean
    :param DefaultOnly: If true , specifies that only the default version of the specified engine or engine and major version combination is to be returned.

    :rtype: dict
    :return: {
        'Marker': 'string',
        'CacheEngineVersions': [
            {
                'Engine': 'string',
                'EngineVersion': 'string',
                'CacheParameterGroupFamily': 'string',
                'CacheEngineDescription': 'string',
                'CacheEngineVersionDescription': 'string'
            },
        ]
    }

    """
    pass


@classmethod
def synchronize(cls, options, return_raw_response=None, timeout=3600):
    """Synchronizes a repository."""
    cls.command_sub = 'synchronize'
    return cls.execute(cls._construct_command(options), output_format='csv',
        ignore_stderr=True, return_raw_response=return_raw_response,
        timeout=timeout)


def theta_Ca_H_RGO81(T, P):
    """c-c': calcium hydrogen [RGO81]."""
    theta = 0.0612
    valid = T == 298.15
    return theta, valid


def encode_kw11(to_encode):
    """
    The function to encode kwargs.
    :param: to_encode: kwargs to encode.
    :return: encoded kwargs: dict
    """
    encoded_kw = {}
    if not isinstance(to_encode, dict):
        return encoded_kw
    for k, v in to_encode.items():
        try:
            int(k)
        except ValueError:
            encoded_kw.update({k: v})
    return encoded_kw


def cast(value):
    """Attempt to convert a given value to integer or float. If both attempts
    fail the value is returned as is.

    Parameters
    ----------
    value: string

    Returns
    -------
    int, float, or string
    """
    if value is None:
        return None
    try:
        return int(value)
    except ValueError:
        try:
            return float(value)
        except ValueError:
            return value


def update(me, m):
    """update the bounds of a variable.
as of glpk v4.60, it is known that when a
binary variable is set to a fixed value,
its kind will become integer."""
    if me.id:
        m.set_col_bnds(me.id, *me.vbounds())


def get_dataset(socrata_client, dataset_id, page_size=5000):
    """Iterate over a datasets pages using the Socrata API"""
    page_num = 0
    more_pages = True
    while more_pages:
        api_data = socrata_client.get(dataset_id, limit=page_size, offset=
            page_size * page_num)
        if len(api_data) < page_size:
            more_pages = False
        page_num += 1
        yield api_data


def match(pattern, sentence, *args, **kwargs):
    """ Returns the first match found in the given sentence, or None.
    """
    return compile(pattern, *args, **kwargs).match(sentence)


def decode_response(client_message, to_object=None):
    """ Decode response from client message"""
    parameters = dict(response=None)
    parameters['response'] = client_message.read_bool()
    return parameters


@classmethod
def limit(cls, refs, hints):
    """Limit a list of entities.

        The underlying driver layer may have already truncated the collection
        for us, but in case it was unable to handle truncation we check here.

        :param refs: the list of members of the collection
        :param hints: hints, containing, among other things, the limit
                      requested

        :returns: boolean indicating whether the list was truncated, as well
                  as the list of (truncated if necessary) entities.

        """
    NOT_LIMITED = False
    LIMITED = True
    if hints is None or hints.limit is None:
        return NOT_LIMITED, refs
    if hints.limit.get('truncated', False):
        return LIMITED, refs
    if len(refs) > hints.limit['limit']:
        return LIMITED, refs[:hints.limit['limit']]
    return NOT_LIMITED, refs


def p_track_flag_four_channels(t):
    """track_flag : FOUR_CHANNEL_AUDIO"""
    from audiotools.toc import TOCFlag_CHANNELS
    t[0] = TOCFlag_CHANNELS(4)


def zoladz(hrMax, adjuster):
    """
    Zoladz Method for target heart rate (THR) - derives exercise zones by subtracting values from HRmax. Results are +/- 5 bpm
    - Zone 1 Adjuster (easy exercise) = 50 bpm
    - Zone 2 Adjuster = 40 bpm
    - Zone 3 Adjuster = 30 bpm
    - Zone 4 Adjuster = 20 bpm
    - Zone 5 Adjuster (extremely tough exercise) = 10 bpm
    """
    return hrMax - adjuster


def maybe_int(data):
    """Try to turn data into an int; if it fails, return data."""
    try:
        return int(data)
    except ValueError:
        return data


@staticmethod
def get_addresses_model():
    """
        This is needed so the BaseState can validate the
        provided addresses and throw an error if any are missing.
        As well as automatically generate documentation.
        NOTE: types must always be "str"
        return = {
            'required_addresses': {
                'req_address_name_1': str,
                'req_address_name_2': str,
            },
            'optional_addresses': {
                'opt_address_name_1': str,
                'opt_address_name_2': str,
            },
        }
        """
    return {'required_addresses': {'subscriber': str}, 'optional_addresses': {}
        }


@classmethod
def from_string(cls, string):
    """Read the struct from string."""
    raise NotImplementedError


def p_Qualifiers_specials(p):
    """Qualifiers : Specials"""
    p[0] = p[1]


def parse_bdist_wininst(name):
    """Return (base,pyversion) or (None,None) for possible .exe name"""
    lower = name.lower()
    base, py_ver, plat = None, None, None
    if lower.endswith('.exe'):
        if lower.endswith('.win32.exe'):
            base = name[:-10]
            plat = 'win32'
        elif lower.startswith('.win32-py', -16):
            py_ver = name[-7:-4]
            base = name[:-16]
            plat = 'win32'
        elif lower.endswith('.win-amd64.exe'):
            base = name[:-14]
            plat = 'win-amd64'
        elif lower.startswith('.win-amd64-py', -20):
            py_ver = name[-7:-4]
            base = name[:-20]
            plat = 'win-amd64'
    return base, py_ver, plat


def time_to_float(datetimeobject, totalturn=24, minimum=0.0, maximum=1.0):
    """
    Function that returns a float between minimum
    and maximum for a moment within totalturn hours (default: 24)
    00:00 (Midnight) returns a value of 0, 12:00 (Midday) a value of 0.5
    """
    micro = datetimeobject.microsecond / 1000000.0
    sec = datetimeobject.second
    minutes = datetimeobject.minute * 60
    hours = datetimeobject.hour % totalturn * 60 * 60
    currentsecond = hours + minutes + sec + micro
    return minimum + currentsecond / 86400.0 * float(maximum)


def _get_sub_charset(raw_headers: list) ->list:
    """Hardcode for some invalid mail-encoding."""
    for k, _ in raw_headers:
        if b'X-QQ' in k:
            return ['gbk']
    return []


@staticmethod
def secrets_store(client, name=None, payload=None, algorithm=None,
    bit_length=None, secret_type=None, mode=None, expiration=None):
    """Create and Store a secret in Barbican.

        :param client: the Barbican client
        :type client: barbicanclient.client

        :param name: A friendly name for the Secret
        :type name: string

        :param payload: The unencrypted secret data
        :type payload: string

        :param algorithm: The algorithm associated with this secret key
        :type algorithm: string

        :param bit_length: The bit length of this secret key
        :type bit_length: int

        :param secret_type: The secret type for this secret key
        :type secret_type: string

         :param mode: The algorithm mode used with this secret keybit_length:
        :type mode: string

        :param expiration: The expiration time of the secret in ISO 8601 format
        :type expiration: string

        :returns: A new Secret object
        :rtype: class:`barbicanclient.secrets.Secret'
        """
    entity = client.secrets.create(name, payload, algorithm, bit_length,
        secret_type, mode, expiration)
    entity.store()
    return entity._get_formatted_entity()


@classmethod
def to_mask(celf, flags):
    """converts a set of EXCEPT.xxx values to a bitmask."""
    result = 0
    for e in celf.__members__.values():
        if e in flags:
            result |= e.mask
    return result


def reciprocalhdg(heading_deg):
    """The reciprocal of a heading in degrees"""
    if heading_deg + 180 > 360:
        return heading_deg - 180
    return heading_deg + 180


def ensure_bytes(s, encoding):
    """
    Ensure *s* is a bytes string.  Encode using *encoding* if it isn't.
    """
    if isinstance(s, bytes):
        return s
    return s.encode(encoding)


def rescale(a, v1):
    """Return `v1` multiplied by a scalar `a`, as a new vector."""
    x1, y1, z1 = v1
    return a * x1, a * y1, a * z1


def __lt__(other):
    """
        These objects are ordered like their values.
        """


def extract_spotify_id(raw_string):
    """
    Returns a Spotify ID of a playlist, album, etc. after extracting
    it from a given HTTP URL or Spotify URI.
    """
    if '/' in raw_string:
        if raw_string.endswith('/'):
            raw_string = raw_string[:-1]
        to_trim = raw_string.find('?')
        if not to_trim == -1:
            raw_string = raw_string[:to_trim]
        splits = raw_string.split('/')
    else:
        splits = raw_string.split(':')
    spotify_id = splits[-1]
    return spotify_id


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

        :param TeamMergeRequestExpiredShownToSecondaryTeamType val:
        :rtype: EventType
        """
    return cls('team_merge_request_expired_shown_to_secondary_team', val)


def pretty_class_dump(cls, indent=4, line_sep='\n', delim=':', name_delim='= '
    ):
    """Formats the output of _class_dump() as a string
    """
    ret = []
    sindent = ' ' * indent
    for sname, slist in cls._class_dump().items():
        if ret:
            ret += line_sep
        ret += [sindent, sname, name_delim]
        for m, c in slist:
            ret += [m, '.', c, delim]
        ret.pop()
    return ''.join(ret)


@classmethod
def get_kinetic_energy_cutoff_EEX(cls, calc, **kwargs):
    """Return kinetic energy cutoff for exact exchange (EEX) operator in eV.

        .. note :: by default returns ecutrho, as indicated in
            http://www.quantum-espresso.org/wp-content/uploads/Doc/INPUT_PW.html
        """
    from qe_tools.constants import ry_to_ev
    parameters = calc.inputs.parameters
    try:
        return parameters.get_dict()['SYSTEM']['ecutfock'] * ry_to_ev
    except KeyError:
        pass
    return cls.get_kinetic_energy_cutoff_charge_density(calc)


def properties():
    """Toggle the properties region visibility

    """
    pass


@classmethod
def arg_color_axis(cls, parser):
    """Add an `~argparse.ArgumentGroup` for colour-axis options.
        """
    group = parser.add_argument_group('Colour axis options')
    group.add_argument('--imin', type=float, help='minimum value for colorbar')
    group.add_argument('--imax', type=float, help='maximum value for colorbar')
    group.add_argument('--cmap', help=
        'Colormap. See https://matplotlib.org/examples/color/colormaps_reference.html for options'
        )
    group.add_argument('--color-scale', choices=('log', 'linear'), help=
        'scale for colorbar')
    group.add_argument('--norm', nargs='?', const='median', choices=(
        'median', 'mean'), metavar='NORM', help=
        'normalise each pixel against average in that frequency bin')
    group.add_argument('--nocolorbar', action='store_true', help=
        'hide the colour bar')


def getHome():
    """Return the place where the agent currently lives."""


def append_url_params(base_url, param_dict):
    """Append parameters to a base url.

  Args:
    base_url: the basic url, end with ?
    param_dict: dictionary of parameters.
  Returns:
    a complete url.
  """
    url = base_url
    started = False
    for key, val in param_dict.iteritems():
        if val is not None:
            url = url + '&' if started else url
            url += '{}={}'.format(key, val)
            started = True
    return url


def lineincustcols(inlist, colsizes):
    """
Returns a string composed of elements in inlist, with each element
right-aligned in a column of width specified by a sequence colsizes.  The
length of colsizes must be greater than or equal to the number of columns
in inlist.

Usage:   lineincustcols (inlist,colsizes)
Returns: formatted string created from inlist
"""
    outstr = ''
    for i in range(len(inlist)):
        if not isinstance(inlist[i], str):
            item = str(inlist[i])
        else:
            item = inlist[i]
        size = len(item)
        if size <= colsizes[i]:
            for j in range(colsizes[i] - size):
                outstr = outstr + ' '
            outstr = outstr + item
        else:
            outstr = outstr + item[0:colsizes[i] + 1]
    return outstr


def delete(mastodon, collection, status):
    """
    Delete toot, unfavour favourite, or dismiss notification and mark
    it as deleted. The "record not found" error is handled elsewhere.
    """
    if collection == 'statuses':
        if status['reblog']:
            mastodon.status_unreblog(status['id'])
        else:
            mastodon.status_delete(status['id'])
    elif collection == 'favourites':
        mastodon.status_unfavourite(status['id'])
    elif collection == 'mentions':
        mastodon.notifications_dismiss(status['id'])
    status['deleted'] = True


def _csr_gen_triples(A):
    """Converts a SciPy sparse matrix in **Compressed Sparse Row** format to
    an iterable of weighted edge triples.

    """
    nrows = A.shape[0]
    data, indices, indptr = A.data, A.indices, A.indptr
    for i in range(nrows):
        for j in range(indptr[i], indptr[i + 1]):
            yield i, indices[j], data[j]


def compute_knot_vector2(degree, num_dpts, num_cpts, params):
    """ Computes a knot vector ensuring that every knot span has at least one :math:`\\overline{u}_{k}`.

    Please refer to the Equations 9.68 and 9.69 on The NURBS Book (2nd Edition), p.412 for details.

    :param degree: degree
    :type degree: int
    :param num_dpts: number of data points
    :type num_dpts: int
    :param num_cpts: number of control points
    :type num_cpts: int
    :param params: list of parameters, :math:`\\overline{u}_{k}`
    :type params: list, tuple
    :return: knot vector
    :rtype: list
    """
    kv = [(0.0) for _ in range(degree + 1)]
    d = float(num_dpts) / float(num_cpts - degree)
    for j in range(1, num_cpts - degree):
        i = int(j * d)
        alpha = j * d - i
        temp_kv = (1.0 - alpha) * params[i - 1] + alpha * params[i]
        kv.append(temp_kv)
    kv += [(1.0) for _ in range(degree + 1)]
    return kv


def update_offload(module, array):
    """Update offload target"""
    changed = False
    module.exit_json(changed=changed)


@staticmethod
def _derive_data_type(column):
    """
        Returns the proper SQL declaration of a data type of a column.

        :param dict column: The column of which the field is based.

        :rtype: str
        """
    data_type = column['data_type']
    if data_type == 'bigint':
        return data_type
    if data_type == 'int':
        return data_type
    if data_type == 'smallint':
        return data_type
    if data_type == 'tinyint':
        return data_type
    if data_type == 'bit':
        return data_type
    if data_type == 'money':
        return data_type
    if data_type == 'smallmoney':
        return data_type
    if data_type == 'decimal':
        return 'decimal({0:d},{1:d})'.format(column['precision'], column[
            'scale'])
    if data_type == 'numeric':
        return 'decimal({0:d},{1:d})'.format(column['precision'], column[
            'scale'])
    if data_type == 'float':
        return data_type
    if data_type == 'real':
        return data_type
    if data_type == 'date':
        return data_type
    if data_type == 'datetime':
        return data_type
    if data_type == 'datetime2':
        return data_type
    if data_type == 'datetimeoffset':
        return data_type
    if data_type == 'smalldatetime':
        return data_type
    if data_type == 'time':
        return data_type
    if data_type == 'char':
        return 'char({0:d})'.format(column['max_length'])
    if data_type == 'varchar':
        if column['max_length'] == -1:
            return 'varchar(max)'
        return 'varchar({0:d})'.format(column['max_length'])
    if data_type == 'text':
        return data_type
    if data_type == 'nchar':
        return 'nchar({0:d})'.format(int(column['max_length'] / 2))
    if data_type == 'nvarchar':
        if column['max_length'] == -1:
            return 'nvarchar(max)'
        return 'nvarchar({0:d})'.format(int(column['max_length'] / 2))
    if data_type == 'ntext':
        return data_type
    if data_type == 'binary':
        return data_type
    if data_type == 'varbinary':
        return 'varbinary({0:d})'.format(column['max_length'])
    if data_type == 'image':
        return data_type
    if data_type == 'xml':
        return data_type
    if data_type == 'geography':
        return data_type
    if data_type == 'geometry':
        return data_type
    raise Exception("Unexpected data type '{0}'".format(data_type))


def add_arg(func, *args, **kwargs):
    """Bind CLI arguments to a shell.py `do_foo` function."""
    if not hasattr(func, 'arguments'):
        func.arguments = []
    if (args, kwargs) not in func.arguments:
        func.arguments.insert(0, (args, kwargs))


@classmethod
def init_cli(cls):
    """Initialize swipl if it was not initialized yet"""
    from ..persistence.models import Trial
    if not cls.prolog_cli:
        from pyswip import Prolog
        cls.prolog_cli = Prolog()
        cls.prolog_cli.assertz(Trial.prolog_description.empty()[:-1])
        cls.prolog_cli.assertz('load_rules(0)')


def paginate_items(items, size=100):
    """paginate_items will return a list of lists, each of a particular max
    size
    """
    groups = []
    for idx in range(0, len(items), size):
        group = items[idx:idx + size]
        groups.append(group)
    return groups


def context_scale_int(data_path: str='', value: float=1.0, always_step:
    bool=True):
    """Scale an int context value

    :param data_path: Context Attributes, RNA context string
    :type data_path: str
    :param value: Value, Assign value
    :type value: float
    :param always_step: Always Step, Always adjust the value by a minimum of 1 when ‘value’ is not 1.0
    :type always_step: bool
    """
    pass


def polyfill_random(generator, size, dtype='float32', out=None):
    """Sample random floats from a generator in different numpy versions.

    Parameters
    ----------
    generator : numpy.random.Generator or numpy.random.RandomState
        The generator to sample from. Both ``RandomState`` and ``Generator``
        support ``random()``, but with different interfaces.

    size : int or tuple of ints, optional
        See :func:`numpy.random.Generator.random`.

    dtype : {str, dtype}, optional
        See :func:`numpy.random.Generator.random`.

    out : ndarray, optional
        See :func:`numpy.random.Generator.random`.

    Returns
    -------
    float or ndarray of floats
        See :func:`numpy.random.Generator.random`.

    """
    if hasattr(generator, 'random_sample'):
        result = generator.random_sample(size=size).astype(dtype)
        if out is not None:
            assert out.dtype.name == result.dtype.name, "Expected out array to have the same dtype as random_sample()'s result array. Got %s (out) and %s (result) instead." % (
                out.dtype.name, result.dtype.name)
            out[...] = result
        return result
    return generator.random(size=size, dtype=dtype, out=out)


def target_remove():
    """Remove the selected particle target

    """
    pass


def trace_toggle(realm):
    """Turn tracing on or off, depending on its current state."""
    if not realm.tracing:
        realm.trace_on()
    else:
        realm.trace_off()


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

    """
    pass


def _parse_field_value(line):
    """ Parse the field and value from a line. """
    if line.startswith(':'):
        return None, None
    if ':' not in line:
        return line, ''
    field, value = line.split(':', 1)
    value = value[1:] if value.startswith(' ') else value
    return field, value


@classmethod
def add_parser(cls, subparser):
    """Create parser for command line."""
    parser = super().add_parser(subparser)
    parser.add_argument('-c', '--convert', help=
        'Convert file format on server (defaults to none)')
    parser.add_argument('-o', '--output', help=
        'File where to store output (defaults to stdout)')
    return parser


@classmethod
def add_to_postmortem_exclusion_list(cls, pathname, bits=None):
    """
        Adds the given filename to the exclusion list for postmortem debugging.

        @warning: This method requires administrative rights.

        @see: L{get_postmortem_exclusion_list}

        @type  pathname: str
        @param pathname:
            Application pathname to exclude from postmortem debugging.

        @type  bits: int
        @param bits: Set to C{32} for the 32 bits debugger, or C{64} for the
            64 bits debugger. Set to {None} for the default (L{System.bits}).

        @raise WindowsError:
            Raises an exception on error.
        """
    if bits is None:
        bits = cls.bits
    elif bits not in (32, 64):
        raise NotImplementedError('Unknown architecture (%r bits)' % bits)
    if bits == 32 and cls.bits == 64:
        keyname = (
            'HKLM\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug\\AutoExclusionList'
            )
    else:
        keyname = (
            'HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug\\AutoExclusionList'
            )
    try:
        key = cls.registry[keyname]
    except KeyError:
        key = cls.registry.create(keyname)
    key[pathname] = 1


def page_name_original_metadata(index):
    """Get the key name for the page name metadata data for the indexed tiff page

    These are TIFF IFD #'s 285+

    index - zero-based index of the page
    """
    return 'PageName #%d' % index


def _to_db_dict(namespace_id, resource_type_id, model_dict):
    """transform a model dict to a metadef_namespace_resource_type dict"""
    db_dict = {'namespace_id': namespace_id, 'resource_type_id':
        resource_type_id, 'properties_target': model_dict[
        'properties_target'], 'prefix': model_dict['prefix']}
    return db_dict


@staticmethod
def p_segment_optional_parameter(p):
    """segment_optional_parameter : page
                                      | checksum"""
    p[0] = p.slice[1].type, p[1]


@classmethod
def addValidator(klass, func):
    """
        Add a function to the given classes validation list.

        @param klass: The Class to add the validator to.
        @param func: A function that accepts a single parameter that is the object
        to test for validity.  If the object is invalid, then this function should
        add errors to it's C{errors} property.

        @see: L{Errors}
        """
    klass.VALIDATIONS = klass.VALIDATIONS + [func]


def add_cache_headers(request):
    """
    The Oauth2 draft spec requires that all token endpoint traffic be marked
    as uncacheable.
    """
    resp = request.response
    resp.headerlist.append(('Cache-Control', 'no-store'))
    resp.headerlist.append(('Pragma', 'no-cache'))
    return request


def _get_base_qual(pread):
    """
    Returns: (seq, (quals))

    Used flags:
        indel
            indel length for the position following the current pileup site.
            This quantity peeks ahead to the next cigar operation in this
            alignment. If the next operation is an insertion, indel will
            be positive. If the next operation is a deletion, it will be
            negation. 0 if the next operation is not an indel.
        is_del
            1 iff the base on the padded read is a deletion
    """
    if pread.is_del:
        return '-', ()
    qpos = pread.query_position
    aln = pread.alignment
    if pread.indel > 0:
        sl = slice(qpos, qpos + pread.indel + 1)
        return aln.query_sequence[sl], tuple(aln.query_qualities[sl])
    return aln.query_sequence[qpos], (aln.query_qualities[qpos],)


@staticmethod
def default_errorhandler(connection, cursor, errorclass, errorvalue):
    u"""
        Default error handler that raises an error
        """
    raise errorclass(msg=errorvalue.get(u'msg'), errno=errorvalue.get(
        u'errno'), sqlstate=errorvalue.get(u'sqlstate'), sfqid=errorvalue.
        get(u'sfqid'), done_format_msg=errorvalue.get(u'done_format_msg'))


def is_xds_file(filename):
    """Check to see if a file looks like XDS_ASCII format."""
    first_token = open(filename, 'r').readline().split()[0]
    if first_token == '!FORMAT=XDS_ASCII':
        return True
    return False


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 _mpv_coax_proptype(value, proptype=str):
    """Intelligently coax the given python value into something that can be understood as a proptype property."""
    if type(value) is bytes:
        return value
    elif type(value) is bool:
        return b'yes' if value else b'no'
    elif proptype in (str, int, float):
        return str(proptype(value)).encode('utf-8')
    else:
        raise TypeError('Cannot coax value of type {} into property type {}'
            .format(type(value), proptype))


def comparator(predicate):
    """Makes a comparator function out of a function that reports whether the first
element is less than the second"""
    return lambda a, b: predicate(a, b) * -1 + predicate(b, a) * 1


def event_dict_to_message(logger, name, event_dict):
    """Pass the event_dict to stdlib handler for special formatting."""
    return (event_dict,), {'extra': {'_logger': logger, '_name': name}}


def _get_internal_s_exon(row, previous_end, seq):
    """
    Calculate the genomic coordinates of internal s-exons

    Also returns the genomic nucleotide sequences of the s-exon and the rest of
    the sub-exon.

    >>> row = {'S_exon_Sequence': 'MS'}
    >>> row['Strand'] = -1
    >>> _get_internal_s_exon(row, 2379649, 'ATGAGCAG')
    (2379648, 2379643, 'ATGAGC', 'AG')
    >>> row['Strand'] = 1
    >>> _get_internal_s_exon(row, 2379649, 'ATGAGCAG')
    (2379650, 2379655, 'ATGAGC', 'AG')
    """
    total_len = len(row['S_exon_Sequence']) * 3
    if row['Strand'] == 1:
        start_coordinates = previous_end + 1
        end_coordinates = previous_end + total_len
    else:
        start_coordinates = previous_end - 1
        end_coordinates = previous_end - total_len
    return start_coordinates, end_coordinates, seq[:total_len], seq[total_len:]


@classmethod
def _outputs(cls):
    """ Initializes outputs"""
    raise NotImplementedError


def parse_string(progression):
    """Return a tuple (roman numeral, accidentals, chord suffix).

    Examples:
    >>> parse_string('I')
    ('I', 0, '')
    >>> parse_string('bIM7')
    ('I', -1, 'M7')
    """
    acc = 0
    roman_numeral = ''
    suffix = ''
    i = 0
    for c in progression:
        if c == '#':
            acc += 1
        elif c == 'b':
            acc -= 1
        elif c.upper() == 'I' or c.upper() == 'V':
            roman_numeral += c.upper()
        else:
            break
        i += 1
    suffix = progression[i:]
    return roman_numeral, acc, suffix


@staticmethod
def split_note_text(note_lines):
    """Splits note text into header and notes string"""
    header = note_lines[:3]
    note_text = note_lines[3:]
    return header, note_text


@staticmethod
def _get_all_parent_nodes_nested(path, delimiter='/'):
    """Get path to all parent nodes for current leaf, starting from root down to leaf's direct parent, and return only the relative key (not the fullkey)"""
    pos = path.find(delimiter)
    lastpos = 0
    while pos != -1:
        yield path[lastpos:pos]
        lastpos = pos + 1
        pos = path.find(delimiter, pos + 1)


@staticmethod
def _split_entry_and_tags(entry):
    """
        Split the entry title (proper) from the trailing tags.

        Tags are separated from the title by a `` -- `` marker:
        anything *before* the marker is the entry title,
        anything *following* it is the (space-separated) set of tags.

        Returns a tuple consisting of entry title and set of tags.
        """
    if ' -- ' in entry:
        entry, tags_bundle = entry.split(' -- ', 1)
        entry = entry.rstrip()
        tags = set(tags_bundle.split())
        if '***' in tags:
            entry += ' ***'
            tags.remove('***')
        elif '**' in tags:
            entry += ' **'
            tags.remove('**')
    else:
        tags = set()
    return entry, tags


def wrap_string(s, startstring="(u'", endstring="')", wrap=67):
    """Line-wrap a unicode string literal definition."""
    c = len(startstring)
    contstring = "'\n" + ' ' * (len(startstring) - 2) + "u'"
    l = [startstring]
    for ch in s.replace("'", "\\'"):
        c += 1
        if ch == '\\' and c > wrap:
            c = len(startstring)
            ch = contstring + ch
        l.append(ch)
    l.append(endstring)
    return ''.join(l)


def iterate_attributes(cls):
    """iterate all the keys and attributes associated
       with a class, without using getattr().

       Does not use getattr() so that class-sensitive
       descriptors (i.e. property.__get__()) are not called.

    """
    keys = dir(cls)
    for key in keys:
        for c in cls.__mro__:
            if key in c.__dict__:
                yield key, c.__dict__[key]
                break


@classmethod
def get_station(cls, store, branch, name):
    """Fetches a station from a branch

        :param store: a store
        :param branch: the branch
        :param name: name of the station
        """
    if branch is None:
        raise TypeError(u'BranchStation.get_station() requires a Branch')
    return store.find(cls, name=name, branch=branch).one()


def base10_to_n(num, base):
    """Turn base-10 integer `num` into base-`base` form.

    Returns a list of numbers representing digits in `base`.

    For instance in base-2 we have only the digits ``0`` and
    ``1``. Turning the base-10 integer ``5`` into a base-2 number
    results in ``101`` or, as a list, in::

        >>> base10_to_n(5, base=2)
        [1, 0, 1]

    The result list represents the single "digits" of a differently
    based number. This holds also for 'digits' >= 10::

        >>> base10_to_n(127, base=16)
        [7, 15]

    which in hexadecimal notation would normally read ``0x7F``.
    """
    result = []
    curr = num
    while curr >= base:
        curr, digit = divmod(curr, base)
        result.append(digit)
    result.append(curr)
    result.reverse()
    return result


def gray():
    """The world is gray."""
    return [False, True, False, True]


@classmethod
def get_required_fields(cls):
    """
        get set of required fields

        Returns:
            ``set`` of fields
        """
    fields = super().get_required_fields()
    return fields.union({'late_fee', 'interest', 'discount'})


@classmethod
def eval(cls, *args):
    """
        Returns a canonical form of cls applied to arguments args.

        The eval() method is called when the class cls is about to be
        instantiated and it should return either some simplified instance
        (possible of some other class), or if the class cls should be
        unmodified, return None.

        Examples of eval() for the function "sign"
        ---------------------------------------------

        .. code-block:: python

            @classmethod
            def eval(cls, arg):
                if arg is S.NaN:
                    return S.NaN
                if arg.is_zero: return S.Zero
                if arg.is_positive: return S.One
                if arg.is_negative: return S.NegativeOne
                if isinstance(arg, Mul):
                    coeff, terms = arg.as_coeff_Mul(rational=True)
                    if coeff is not S.One:
                        return cls(coeff) * cls(terms)

        """
    return


@classmethod
def new(cls, key, mode, IV=None, **kwargs):
    """
        Returns a ciphering object, using the secret key contained in
        the string **key**, and using the feedback mode **mode**, which
        must be one of MODE_* defined in this module.

        If **mode** is MODE_CBC or MODE_CFB, **IV** must be provided and
        must be a string of the same length as the block size. Not
        providing a value of **IV** will result in a ValueError exception
        being raised.
        """
    return cls(key, mode, IV)


def can_paginate(operation_name=None):
    """
    Check if an operation can be paginated.

    :type operation_name: string
    :param operation_name: The operation name. This is the same name
            as the method name on the client. For example, if the
            method name is create_foo, and you'd normally invoke the
            operation as client.create_foo(**kwargs), if the
            create_foo operation can be paginated, you can use the
            call client.get_paginator('create_foo').

    """
    pass


def validate_key(k):
    """Validate a key as received on a stream.
    """
    typ = type(k)
    if typ is not str and typ is not bytes:
        raise TypeError('Unexpected key type %s (value: %r)' % (typ, k))


def get_dblogger_extra(node):
    """Return the additional information necessary to attach any log records to the given node instance.

    :param node: a Node instance
    """
    from aiida.orm import Node
    if not isinstance(node, Node) or not node.is_stored:
        return dict()
    return {'dbnode_id': node.id, 'backend': node.backend}


def ndim(x):
    """Returns the number of axes in a tensor, as an integer.

    # Arguments
        x: Tensor or variable.

    # Returns
        Integer (scalar), number of axes.

    # Examples
    ```python
        >>> from keras import backend as K
        >>> inputs = K.placeholder(shape=(2, 4, 5))
        >>> val = np.array([[1, 2], [3, 4]])
        >>> kvar = K.variable(value=val)
        >>> K.ndim(inputs)
        3
        >>> K.ndim(kvar)
        2
    ```

    {{np_implementation}}
    """
    return x.shape.rank


def time_delta_ms(start, end):
    """ Returns the delta time between to datetime objects """
    time_delta = end - start
    return int(time_delta.total_seconds()) * 1000 + int(time_delta.
        microseconds / 1000)


def LONGER(fragment):
    """Sorts longer passages first."""
    return 0 - len(fragment)


@classmethod
def _has_element(cls, container, index):
    """Check to see if an index is in the container.

        Args:
            container (obj): Object that should be checked for index.
            index (obj): Index that should be checked for.

        Returns:
            bool: True if the index is in the container.

        """
    raise NotImplementedError('This must be overwritten by the subclass.')