def send_message(message, shortname, client, channel, nick):
    """
    Send a message to channel.
    """
    if message:
        client.msg(channel, message)


def relative_error(U, V, product=None):
    """Compute error between U and V relative to norm of U."""
    return (U - V).norm(product) / U.norm(product)


def is_response_to_head(response):
    """
    Checks whether the request of a response has been a HEAD-request.
    Handles the quirks of AppEngine.

    :param conn:
    :type conn: :class:`httplib.HTTPResponse`
    """
    method = response._method
    if isinstance(method, int):
        return method == 3
    return method.upper() == 'HEAD'


def potri(A=None, out=None, name=None, **kwargs):
    """Performs matrix inversion from a Cholesky factorization.
    Input is a tensor *A* of dimension *n >= 2*.

    If *n=2*, *A* is a triangular matrix (entries of upper or lower triangle are all zero)
    with positive diagonal. We compute:

      *out* = *A*\\ :sup:`-T` \\* *A*\\ :sup:`-1` if *lower* = *true*
      *out* = *A*\\ :sup:`-1` \\* *A*\\ :sup:`-T` if *lower* = *false*

    In other words, if *A* is the Cholesky factor of a symmetric positive definite matrix
    *B* (obtained by *potrf*), then

      *out* = *B*\\ :sup:`-1`

    If *n>2*, *potri* is performed separately on the trailing two dimensions for all inputs
    (batch mode).

    .. note:: The operator supports float32 and float64 data types only.

    .. note:: Use this operator only if you are certain you need the inverse of *B*, and
              cannot use the Cholesky factor *A* (*potrf*), together with backsubstitution
              (*trsm*). The latter is numerically much safer, and also cheaper.

    Examples::

       Single matrix inverse
       A = [[2.0, 0], [0.5, 2.0]]
       potri(A) = [[0.26563, -0.0625], [-0.0625, 0.25]]

       Batch matrix inverse
       A = [[[2.0, 0], [0.5, 2.0]], [[4.0, 0], [1.0, 4.0]]]
       potri(A) = [[[0.26563, -0.0625], [-0.0625, 0.25]],
                   [[0.06641, -0.01562], [-0.01562, 0,0625]]]

    Defined in src/operator/tensor/la_op.cc:L275

    Parameters
    ----------
    A : NDArray
        Tensor of lower triangular matrices

    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 verbs():
    """Returns a list of the supported verb types"""
    return ['VerbCreateTable', 'VerbCreateIndex', 'VerbSelect',
        'VerbCustom', 'VerbInsert', 'VerbDelete', 'VerbUpdate']


def fun_wv(xchannel, crpix1, crval1, cdelt1):
    """Compute wavelengths from channels.

    The wavelength calibration is provided through the usual parameters
    CRPIX1, CRVAL1 and CDELT1.

    Parameters
    ----------
    xchannel : numpy array
        Input channels where the wavelengths will be evaluated.
    crpix1: float
        CRPIX1 keyword.
    crval1: float
        CRVAL1 keyword.
    cdelt1: float
        CDELT1 keyword.

    Returns
    -------
    wv : numpy array
        Computed wavelengths

    """
    wv = crval1 + (xchannel - crpix1) * cdelt1
    return wv


def size_(got, mandatory_or_optional, expect):
    """
    check if expected size match result size
    """
    if mandatory_or_optional == 'mandatory':
        if not got:
            assert False, 'expect mandatory'
        elif expect is 0:
            pass
        else:
            assert got == expect, 'expect size `%s`, got `%s`' % (expect, got)
    elif not got:
        pass
    elif expect is 0:
        pass
    else:
        assert got == expect, 'expect size `%s`, got `%s`' % (expect, got)


def precision_sleep(t=0.02, min_time=0.017):
    """
    sleep for t seconds.
    """
    from time import time, sleep, perf_counter
    import platform
    min_time
    time_start = perf_counter()
    if platform.system() == 'Linux':
        sleep(t)
    elif t > min_time:
        sleep(t - min_time)
        time_left = t - (perf_counter() - time_start)
        time_while_start = perf_counter()
        while perf_counter() - time_while_start <= time_left:
            pass
    else:
        time_left = t - (perf_counter() - time_start)
        time_while_start = perf_counter()
        while perf_counter() - time_while_start <= time_left:
            pass


def fonts_event(win, plot, figure, fontlab_box, fticks_box, conf):
    """
    This function change the font of the plot.
    Parameters:
    -----------
    win         FigureCanvas, obj
    plot        subplot, obj
    figure      Figure, obj
    fontlab_box QComboBox widget
    fticks_box      ''      ''
    flegend_box     ''      ''
    """
    flabel = fontlab_box.currentText()
    fticks = fticks_box.currentText()
    conf.axis['Axis_label_font'] = flabel
    conf.ticks['Ticks_label_font'] = fticks
    labx = plot.xaxis.get_label()
    laby = plot.yaxis.get_label()
    labx.set_fontname(flabel)
    laby.set_fontname(flabel)
    if fticks not in ['Goha-Tibeb Zemen']:
        labels = plot.get_xticklabels()
        for i in labels:
            i.set_fontproperties(fticks)
        labels = plot.get_yticklabels()
        for i in labels:
            i.set_fontproperties(fticks)
    figure.tight_layout()
    win.draw()


def get_neighbor_types(neighbor_dict, sep=None):
    """
    Given a *neighbor_dict* (where a key is a "target" word and its
    value is a list of all of its neighbors), return a list of `(word1,
    word2, relationship)` triples, where `relationship` is one of
    "deletion," "addition," "substitution," or "unknown".
    """
    types = []
    targets = list(neighbor_dict.keys())
    while targets:
        current = targets.pop()
        current_key = current
        if sep:
            current = current.split(sep)
        for neighbor in neighbor_dict[current_key]:
            neighbor_key = neighbor
            if sep:
                neighbor = neighbor.split(sep)
            if len(current) == len(neighbor):
                types.append((current_key, neighbor_key, 'substitution'))
            elif len(current) > len(neighbor):
                types.append((current_key, neighbor_key, 'deletion'))
            elif len(current) < len(neighbor):
                types.append((current_key, neighbor_key, 'addition'))
            else:
                types.append((current_key, neighbor_key, 'unknown'))
    return types


def __check_if_negative(duration_in_seconds: int) ->None:
    """
    Check if duration_in_seconds is negative.

    :param duration_in_seconds: Duration in seconds.
        max: 67767976233532799.
    """
    if duration_in_seconds < 0:
        raise ValueError('duration_in_seconds needs to be positive.')


@staticmethod
def _global_parse_mode():
    """
        Detect global parse mode

        :return:
        """
    from aiogram import Bot
    bot = Bot.get_current()
    if bot is not None:
        return bot.parse_mode


@classmethod
def normalize_name(cls, name):
    """Replace some characters in command names."""
    return name.lower().replace('_', '-').replace(' ', '-')


def formatUintHex64(value):
    """
    Format an 64 bits unsigned integer.
    """
    return u'0x%016x' % value


def motion_regressors(motion_params, order=0, derivatives=1):
    """Compute motion regressors upto given order and derivative

    motion + d(motion)/dt + d2(motion)/dt2 (linear + quadratic)
    """
    import os
    import numpy as np
    from nipype.utils.filemanip import filename_to_list
    out_files = []
    for idx, filename in enumerate(filename_to_list(motion_params)):
        params = np.genfromtxt(filename)
        out_params = params
        for d in range(1, derivatives + 1):
            cparams = np.vstack((np.repeat(params[(0), :][(None), :], d,
                axis=0), params))
            out_params = np.hstack((out_params, np.diff(cparams, d, axis=0)))
        out_params2 = out_params
        for i in range(2, order + 1):
            out_params2 = np.hstack((out_params2, np.power(out_params, i)))
        filename = os.path.join(os.getcwd(), 'motion_regressor%02d.txt' % idx)
        np.savetxt(filename, out_params2, fmt=b'%.10f')
        out_files.append(filename)
    return out_files


@classmethod
def add_options(cls, parser):
    """Register options for PyFlakes on the Flake8 OptionManager."""
    parser.add_option('--builtins', parse_from_config=True,
        comma_separated_list=True, help=
        'define more built-ins, comma separated')
    parser.add_option('--doctests', default=False, action='store_true',
        parse_from_config=True, help='check syntax of the doctests')
    parser.add_option('--include-in-doctest', default='', dest=
        'include_in_doctest', parse_from_config=True, comma_separated_list=
        True, normalize_paths=True, help='Run doctests only on these files',
        type='string')
    parser.add_option('--exclude-from-doctest', default='', dest=
        'exclude_from_doctest', parse_from_config=True,
        comma_separated_list=True, normalize_paths=True, help=
        'Skip these files when running doctests', type='string')


@classmethod
def expected_string(cls, dialect=None, called_from=None):
    """Return the expected string for this segment.

        This is never going to be called on an _instance_
        but rather on the class, as part of a grammar, and therefore
        as part of the matching phase. So we use the match grammar.
        """
    return cls._match_grammar().expected_string(dialect=dialect,
        called_from=called_from)


def select_pinned():
    """Select all pinned UV vertices

    """
    pass


def volume_depolarization_cross_parallel(signal_cross, signal_parallel,
    t_cross, t_parallel, r_cross, r_parallel, v_star):
    """
    Calculate the linear volume depolarization ratio in a lidar system that is
    able to detect the cross-to-parallel depolarization ratio.
    The calibration factor from the delta-90 calibration is being used.

    Parameters
    ----------
    signal_cross: vector
       The input vertical profile from the cross channel. Normal measurement (phi=0).
    signal_parallel: vector
       The input vertical profile from the parallel channel. Normal measurement (phi=0).
    t_cross: float
       Transmittance of cross component through transmitted path.
    t_parallel: float
       Transmittance of parallel component through transmitted path.
    r_cross: float
       Transmittance of cross component through reflected path.
    r_parallel: float
       Transmittance of parallel component through reflected path.
    v_star: float
       The calibration constant.

    Returns
    -------
    delta_v: vector
       The linear volume depolarization.

    Notes
    -----
    The linear volume depolarization ratio is calculated by the formula:

    .. math::
       \\delta^V = \\frac{\\frac{\\delta^*}{V^*}T_p - R_p}{R_s - \\frac{\\delta^*}{V^*}T_s}

    References
    ----------
    Freudenthaler, V. et al. Depolarization ratio profiling at several wavelengths in pure
    Saharan dust during SAMUM 2006. Tellus, 61B, 165-179 (2008)
    """
    delta_star = signal_cross / signal_parallel
    delta_v = (delta_star * t_parallel / v_star - r_parallel) / (r_cross -
        delta_star * t_cross / v_star)
    return delta_v


def get_content_encoding():
    """Return the file content encoding.
        """


def writebytes(b, path):
    """Write binary to file.
    """
    with open(path, 'wb') as f:
        f.write(b)


@property
def help(cls):
    """
        Property which creates a dynamic help text including the
        ``server_name`` and ``server_class``.
        """
    return (
        'Start %(server_name)s (server_class=%(server_module)s.%(server_class)s'
         % {'server_name': cls.server_name, 'server_module': cls.
        server_class.__module__, 'server_class': cls.server_class.__name__})


def get_percent(full, value):
    """
    returns a value in percent. (how much percent of ..)
    rounded whole numbers
    """
    return round(value * (100 / full))


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

        :param GroupRemoveMemberType val:
        :rtype: EventType
        """
    return cls('group_remove_member', val)


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

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

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


def list_jobs(jobQueue=None, jobStatus=None, maxResults=None, nextToken=None):
    """
    Returns a list of task jobs for a specified job queue. You can filter the results by job status with the jobStatus parameter.
    See also: AWS API Documentation

    Examples
    This example lists the running jobs in the HighPriority job queue.
    Expected Output:
    This example lists jobs in the HighPriority job queue that are in the SUBMITTED job status.
    Expected Output:

    :example: response = client.list_jobs(
        jobQueue='string',
        jobStatus='SUBMITTED'|'PENDING'|'RUNNABLE'|'STARTING'|'RUNNING'|'SUCCEEDED'|'FAILED',
        maxResults=123,
        nextToken='string'
    )

    :type jobQueue: string
    :param jobQueue: [REQUIRED]
            The name or full Amazon Resource Name (ARN) of the job queue with which to list jobs.

    :type jobStatus: string
    :param jobStatus: The job status with which to filter jobs in the specified queue.

    :type maxResults: integer
    :param maxResults: The maximum number of results returned by ListJobs in paginated output. When this parameter is used, ListJobs only returns maxResults results in a single page along with a nextToken response element. The remaining results of the initial request can be seen by sending another ListJobs request with the returned nextToken value. This value can be between 1 and 100. If this parameter is not used, then ListJobs returns up to 100 results and a nextToken value if applicable.

    :type nextToken: string
    :param nextToken: The nextToken value returned from a previous paginated ListJobs request where maxResults was used and the results exceeded the value of that parameter. Pagination continues from the end of the previous results that returned the nextToken value. This value is null when there are no more results to return.
            Note
            This token should be treated as an opaque identifier that is only used to retrieve the next items in a list and not for other programmatic purposes.

    :rtype: dict
    :return: {
        'jobSummaryList': [
            {
                'jobId': 'string',
                'jobName': 'string'
            },
        ],
        'nextToken': 'string'
    }

    """
    pass


def hex_to_rgba(hex_str):
    """
    Converts hexadecimal number to RGBA tuple in following formats:
        - "RRGGBB" (2F2F2F)
        - "AARRGGBB" (882F2F2F)
        - "RGB" (CCC)
    :param hex_str: str, hexadecimal string
    :return: tuple(float, float, float, float), color tuple (R, G, B, A)
    """
    if hex_str.startswith('#'):
        hex_str = hex_str[1:]
    if len(hex_str) == 8:
        return int(hex_str[2:4], 16), int(hex_str[4:6], 16), int(hex_str[6:
            8], 16), int(hex_str[0:2], 16)
    elif len(hex_str) == 6:
        return int(hex_str[0:2], 16), int(hex_str[2:4], 16), int(hex_str[4:
            6], 16), 255
    elif len(hex_str) == 3:
        return int(hex_str[0:1] * 2, 16), int(hex_str[1:2] * 2, 16), int(
            hex_str[2:3] * 2, 16), 255
    else:
        raise Exception('Invalid hex length: {} ({})'.format(hex_str, len(
            hex_str)))


def split_command_from_args(text: (str or None)) ->(str or None, str or None):
    """
    Splits the command (including any target) from its arguments
    :param text: the full message
    :return: (command, args)
    """
    if text is None or len(text) <= 0:
        return None, None
    if ' ' in text:
        return text.split(' ', 1)
    else:
        return text, None


def turbulent_Gnielinski_smooth_1(Re, Pr):
    """Calculates internal convection Nusselt number for turbulent flows
    in pipe according to [2]_ as in [1]_. This is a simplified case assuming
    smooth pipe.

    .. math::
        Nu = 0.0214(Re^{0.8}-100)Pr^{0.4}

    Parameters
    ----------
    Re : float
        Reynolds number, [-]
    Pr : float
        Prandtl number, [-]

    Returns
    -------
    Nu : float
        Nusselt number, [-]

    Notes
    -----
    Range according to [1]_ is 0.5 < Pr ≤ 1.5  and 10^4 ≤ Re ≤ 5*10^6.

    Examples
    --------
    >>> turbulent_Gnielinski_smooth_1(Re=1E5, Pr=1.2)
    227.88800494373442

    References
    ----------
    .. [1] Rohsenow, Warren and James Hartnett and Young Cho. Handbook of Heat
       Transfer, 3E. New York: McGraw-Hill, 1998.
    .. [2] Gnielinski, V. (1976). New Equation for Heat and Mass Transfer in
       Turbulent Pipe and Channel Flow, International Chemical Engineering,
       Vol. 16, pp. 359–368.
    """
    return 0.0214 * (Re ** 0.8 - 100.0) * Pr ** 0.4


def _insert_automodapi_configs(c):
    """Add configurations related to automodapi, autodoc, and numpydoc to the
    state.
    """
    c['numpydoc_show_class_members'] = False
    c['autosummary_generate'] = True
    c['automodapi_toctreedirnm'] = 'py-api'
    c['automodsumm_inherited_members'] = True
    c['autodoc_inherit_docstrings'] = True
    c['autoclass_content'] = 'class'
    c['autodoc_default_flags'] = ['show-inheritance', 'special-members']
    return c


def conform_values(taxis1, taxis2):
    """Given two time axes, return new axes such that their values are comparable."""
    from pygeode.timeaxis import Time
    assert isinstance(taxis1, Time)
    assert isinstance(taxis2, Time)
    assert type(taxis1) is type(taxis2
        ), "can't conform time axes of different types"
    allowed_fields = type(taxis1).allowed_fields
    if set(taxis1.auxarrays.keys()) < set(taxis2.auxarrays.keys()):
        taxis1, taxis2 = taxis2, taxis1
    assert set(taxis1.auxarrays.keys()) >= set(taxis2.auxarrays.keys()
        ), 'incompatible fields'
    end_resolution = False
    for name in allowed_fields:
        if name not in taxis1.auxarrays:
            continue
        if end_resolution:
            assert name not in taxis2.auxarrays, 'incompatible fields'
        if name not in taxis2.auxarrays:
            end_resolution = True
    units = taxis2.units
    startdate = taxis2.startdate
    taxis1 = type(taxis1)(units=units, startdate=startdate, **taxis1.auxarrays)
    return taxis1, taxis2


def assert_cmd_has_no_qmark(command: str, context: str='') ->None:
    """Throws Exception if the query contains a question marks."""
    if '?' not in command:
        return
    message = ''
    if context:
        message = ' ' + context
    message = (message +
        "Set commands must not contain question-marks. Sent command: '{0}'"
        .format(command.strip('\n')))
    raise Exception(message)


@classmethod
def find_from_schema_id(cls, schema_id):
    """Find registry from a schema id."""
    for r in cls.list():
        for schema in r.entity_schemas:
            if schema['id'] == schema_id:
                return r


@staticmethod
def estimateNextState(state, move):
    """
		Estimate what the game state will be after the given move
		is applied to the given state.

		:param state:  Current game state (GameState)
		:param move:  Move to play
		:return:  New state (GameState)
		:raises  RuntimeError: if move is not possible
		:raises NotImplementedError: if child does not override this function
		"""
    raise NotImplementedError()


def abstractMethod():
    """ This should be called when an abstract method is called that should have been
    implemented by a subclass. It should not be called in situations where no implementation
    (i.e. a 'pass' behavior) is acceptable. """
    raise NotImplementedError('Method not implemented!')


def _get_weight_param_summary(wp):
    """Get a summary of _NeuralNetwork_pb2.WeightParams
    Args:
    wp : _NeuralNetwork_pb2.WeightParams - the _NeuralNetwork_pb2.WeightParams message to display
    Returns:
    a str summary for wp
    """
    summary_str = ''
    if wp.HasField('quantization'):
        nbits = wp.quantization.numberOfBits
        quant_type = 'linearly' if wp.quantization.HasField(
            'linearQuantization') else 'lookup-table'
        summary_str += '{}-bit {} quantized'.format(nbits, quant_type)
    if len(wp.floatValue) > 0:
        summary_str += '({} floatValues)'.format(len(wp.floatValue))
    if len(wp.float16Value) > 0:
        summary_str += '({} bytes float16Values)'.format(len(wp.float16Value))
    if len(wp.rawValue) > 0:
        summary_str += '({} bytes rawValues)'.format(len(wp.rawValue))
    return summary_str


def set_default_tab(tab=None, view=None):
    """Sets the default tab. The id of the tab is passed as
        argument or in the request payload as ``tab``.
        """


def assert_mode(path, mode):
    """
    Assert last 3 octal mode digits match given mode exactly

    Parameters
    ----------
    path : pathlib.Path
        Path whose mode to assert
    mode : int
        Expected mode
    """
    actual = path.stat().st_mode & 511
    assert actual == mode, '{:o} != {:o}'.format(actual, mode)


def ka_cont(T):
    """ Thermal conductivity of air, neglecting non-continuum effects.

    See :func:`ka` for details.

    Parameters
    ----------
    T :
        ambient air temperature surrounding droplet, K

    Returns
    -------
    float
        :math:`k_a(T)` in J/m/s/K

    See Also
    --------
    ka : includes correction for non-continuum effects.

    """
    return 0.001 * (4.39 + 0.071 * T)


def from_settings(settings):
    """Return an instance of the class for the given settings"""


@classmethod
def is_datasource_for(cls, data, header, **kwargs):
    """Determines if header corresponds to an COR image"""
    return str(header.get('detector', '')).startswith('HI')


@classmethod
def name_of_class(cls) ->str:
    """
        A string name for the class, with the prior suffix removed.
        """
    return cls.__name__.replace('Prior', '')


@classmethod
def create_router_interface(cls, router_id, subnet_id):
    """Wrapper utility that returns a router interface."""
    interface = cls.client.add_router_interface_with_subnet_id(router_id,
        subnet_id)
    return interface


def _show_progress_bar(downloaded, total):
    """
    progress bar for command line
    """
    htlen = 33
    percent = downloaded / total * 100
    hashtags = int(percent / 100 * htlen)
    print('|' + '#' * hashtags + ' ' * (htlen - hashtags) + '|' +
        '  {0}/{1} '.format(downloaded, total) + ' {:.1f}'.format(percent).
        ljust(5) + ' %', end='\r', flush=True)


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

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

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


def number_of_interactions(G, u=None, v=None, t=None):
    """Return the number of edges between two nodes at time t.

        Parameters
        ----------
        u, v : nodes, optional (default=all edges)
            If u and v are specified, return the number of edges between
            u and v. Otherwise return the total number of all edges.
        t : snapshot id (default=None)
            If None will be returned the number of edges on the flattened graph.

        Returns
        -------
        nedges : int
            The number of edges in the graph.  If nodes u and v are specified
            return the number of edges between those nodes.

        Examples
        --------
            >>> G = dn.DynGraph()
            >>> G.add_path([0,1,2,3], t=0)
            >>> dn.number_of_interactions(G, t=0)
            """
    return G.number_of_interactions(u, v, t)


def sniff(body):
    """Not implemented for csv."""
    return False


def _server_prefix(environ):
    """
    Get the ``server_prefix`` out of :py:mod:`tiddlyweb.config`.
    """
    config = environ.get('tiddlyweb.config', {})
    return config.get('server_prefix', '')


def _genXML(metadata, metaopts):
    """Use the option name as a tag name to wrap the data."""
    xml = ''
    for metaopt in metaopts:
        value = metadata.get(metaopt)
        if not value:
            value = 'unavailable'
        xml += '<%s>' % metaopt
        xml += str(value)
        xml += '</%s>\n' % metaopt
    return xml


def greater(attrs, inputs, proto_obj):
    """Logical Greater operator with broadcasting."""
    return 'broadcast_greater', attrs, inputs


def _remove_command(header, command):
    """Remove the command from the mach-o header.

    command is a 3-tuple with the same format as header.commands"""
    command_index = header.commands.index(command)
    header.commands.remove(command)
    header.header.ncmds -= 1
    header.changedHeaderSizeBy(-command[0].cmdsize)
    return command_index


def get_sort_order(qdict, default, allowed_values=None):
    """Return a sort order from a querydict object

    :param QueryDict qdict: the object to analyse
    :param string default: the default sort order if no one is found
    :param list allowed_values: an optional list of allowed values
    :return: a 2uple of strings
    """
    sort_order = qdict.get('sort_order', default)
    if sort_order.startswith('-'):
        sort_dir = '-'
        sort_order = sort_order[1:]
    else:
        sort_dir = ''
    if allowed_values is not None and sort_order not in allowed_values:
        return default, ''
    return sort_order, sort_dir


def space_newline_fix(text):
    """Replace "space-newline" with "newline".

    Args:
        text (str): The string to work with

    Returns:
        The text with the appropriate fix.
    """
    space_newline = ' \n'
    fix = '\n'
    while space_newline in text:
        text = text.replace(space_newline, fix)
    return text


def mag_cols_only(cols):
    """
    Returns only the columns names of the magnitudes by excluding columns with "e_" in it.

    :param cols: A list with all column names
    :type cols: list
    :return: A list with the magnitude names only
    :rtype: list
    """
    out = []
    for c in cols:
        if 'e_' not in c:
            out.append(c)
    return out


@classmethod
def is_site_in_topic(cls) ->bool:
    """True if site id is in topic."""
    return True


def get_executable(executable):
    """Find the path to the executable

    Parameters
    ----------
    executable: str
        the name of the executable you wish to find
    """
    from distutils.spawn import find_executable
    return find_executable(executable)


def _parse_annotation_coords(ff, coords, xy):
    """ Convert a coordinate name and xy into a tikz coordinate string """
    if coords == 'data':
        x, y = xy
        return f'(axis cs:{x:{ff}},{y:{ff}})'
    elif coords == 'figure points':
        raise NotImplementedError
    elif coords == 'figure pixels':
        raise NotImplementedError
    elif coords == 'figure fraction':
        raise NotImplementedError
    elif coords == 'axes points':
        raise NotImplementedError
    elif coords == 'axes pixels':
        raise NotImplementedError
    elif coords == 'axes fraction':
        raise NotImplementedError
    elif coords == 'data':
        raise NotImplementedError
    elif coords == 'polar':
        raise NotImplementedError
    else:
        raise NotImplementedError


def reset_default_button(all: bool=True):
    """Reset this property’s value to its default value

    :param all: All, Reset to default values all elements of the array
    :type all: bool
    """
    pass


def allocate_connection_on_interconnect(bandwidth=None, connectionName=None,
    ownerAccount=None, interconnectId=None, vlan=None):
    """
    Deprecated in favor of  AllocateHostedConnection .
    Creates a hosted connection on an interconnect.
    Allocates a VLAN number and a specified amount of bandwidth for use by a hosted connection on the given interconnect.
    See also: AWS API Documentation

    :example: response = client.allocate_connection_on_interconnect(
        bandwidth='string',
        connectionName='string',
        ownerAccount='string',
        interconnectId='string',
        vlan=123
    )

    :type bandwidth: string
    :param bandwidth: [REQUIRED]
            Bandwidth of the connection.
            Example: '500Mbps '
            Default: None
            Values: 50Mbps, 100Mbps, 200Mbps, 300Mbps, 400Mbps, or 500Mbps

    :type connectionName: string
    :param connectionName: [REQUIRED]
            Name of the provisioned connection.
            Example: '500M Connection to AWS '
            Default: None

    :type ownerAccount: string
    :param ownerAccount: [REQUIRED]
            Numeric account Id of the customer for whom the connection will be provisioned.
            Example: 123443215678
            Default: None

    :type interconnectId: string
    :param interconnectId: [REQUIRED]
            ID of the interconnect on which the connection will be provisioned.
            Example: dxcon-456abc78
            Default: None

    :type vlan: integer
    :param vlan: [REQUIRED]
            The dedicated VLAN provisioned to the connection.
            Example: 101
            Default: None

    :rtype: dict
    :return: {
        'ownerAccount': 'string',
        'connectionId': 'string',
        'connectionName': 'string',
        'connectionState': 'ordering'|'requested'|'pending'|'available'|'down'|'deleting'|'deleted'|'rejected',
        'region': 'string',
        'location': 'string',
        'bandwidth': 'string',
        'vlan': 123,
        'partnerName': 'string',
        'loaIssueTime': datetime(2015, 1, 1),
        'lagId': 'string',
        'awsDevice': 'string'
    }

    :returns:
    Ordering : The initial state of a hosted connection provisioned on an interconnect. The connection stays in the ordering state until the owner of the hosted connection confirms or declines the connection order.
    Requested : The initial state of a standard connection. The connection stays in the requested state until the Letter of Authorization (LOA) is sent to the customer.
    Pending : The connection has been approved, and is being initialized.
    Available : The network link is up, and the connection is ready for use.
    Down : The network link is down.
    Deleting : The connection is in the process of being deleted.
    Deleted : The connection has been deleted.
    Rejected : A hosted connection in the 'Ordering' state will enter the 'Rejected' state if it is deleted by the end customer.

    """
    pass


def str_to_bool(s):
    """
    Converts a string to a bool value; looks at the first character,
    if it's y(es), t(rue) or 1 returns True, otherwise, False.
    """
    if len(s) > 0 and s[0] in 'yYtT1':
        return True
    return False


def str2bin(s):
    """
    String to binary.
    """
    ret = []
    for c in s:
        ret.append(bin(ord(c))[2:].zfill(8))
    return ''.join(ret)


def arrow_style(val):
    """
    Defines styling for badges (ui elements)
    Args:
        val: float (positive or negative)

    Returns: background-color, color, class for font awesome icons

    """
    if round(val, 1) < 0:
        return '#50B1A2', '#fff', 'down'
    if round(val, 1) > 0:
        return '#C3043E', '#fff', 'up'
    return '#FFC802', '#444', 'right'


def units_length_preset_add(name: str='', remove_active: bool=False):
    """Add or remove length units preset

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


def __repr__(cls):
    """
        Custom repr for Model subclasses.
        """
    return cls._format_cls_repr()


def __or__(i1, i2):
    """ Return the union of *i1* and *i2*. """
    return i1.__class__(i1._union(i1, i2))


def camel_to_snake(camel):
    """Convert camelCase to snake_case."""
    ret = []
    last_lower = False
    for char in camel:
        current_upper = char.upper() == char
        if current_upper and last_lower:
            ret.append('_')
            ret.append(char.lower())
        else:
            ret.append(char.lower())
        last_lower = not current_upper
    return ''.join(ret)


def cmd_list_users(app, dbc, args):
    """
List all known users.

usage: scrobbler list-users
    """
    dbc.execute('select * from sessions')
    for user, key in dbc.fetchall():
        print('{}\t\t| {}'.format(user, key))
    print()


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

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

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

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

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

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

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


def describe_event(event, tag):
    """ Textual description for this task's method and attributes. """
    task = event.task
    desc = task.method
    if task.is_scratch:
        desc = 'scratch %s' % desc
    if task.package:
        desc = '%s %s' % (task.package, desc)
    if task.target:
        desc += ' for %s' % task.target
    if task.arch:
        desc += ' for %s' % task.arch
    if tag:
        desc += ' for tag %s' % tag
    return desc


def transformBytes(result, encoding):
    """Called to allow the transformer to modify the result if the result
        is an encoded string.

        Return a new six.text_type string, encoded string or iterable.

        Return None to indicate that the response should not be modified.
        """


def addhomeaddress():
    """
    @api {post} /map/usualaddress/addhomeaddress 增加家地址
    @apiVersion 1.0.0
    @apiGroup Usualaddress
    @apiDescription 增加家地址

    @apiParam (Headers) {String} token 令牌
    @apiParam (Headers) {String} device_token 设备令牌
    @apiParam (Headers) {String} content_type 内容类型
    @apiParam (Headers) {String} timestamp 时间戳
    @apiParam (Headers) {String} location 经纬度

    @apiParam (Body) {String} poi_id poi_id
    @apiParam (Body) {String} address 地址

    @apiSuccessExample {json} Success-Response:
    {
        "data": "Success.",
        "req_id": "r_a2b05d090d3b456d96612e95dee825e3",
        "err_resp": {
            "code": "0",
            "msg": null
        }
    }

    @apiError (Error) 21030 poi_id or address could not be both empty

    @apiErrorExample {json} Error-Response:
    {
        "err_resp": {
            "code": "21030",
            "msg": "poi_id or address could not be both empty"
        },
        "req_id": "r_8cdd6b30180449c9ae1a04356c96c4c2"
    }
    """


def _get_full_name(code_name: str, proj=None) ->str:
    """
    Return the label of an object retrieved by name

    If a :class:`Project` has been provided, code names can be converted into
    labels for plotting. This function is different to `framework.get_label()` though,
    because it supports converting population names to labels as well (this information is
    in the project's data, not in the framework), and it also supports converting
    link syntax (e.g. `sus:vac`) into full names as well. Note also that this means that the strings
    returned by `_get_full_name` can be as specific as necessary for plotting.

    :param code_name: The code name for a variable (e.g. `'sus'`, `'pris'`, `'sus:vac'`)
    :param proj: Optionally specify a :class:`Project` instance
    :return: If a project was provided, returns the full name. Otherwise, just returns the code name
    """
    if proj is None:
        return code_name
    if code_name in proj.data.pops:
        return proj.data.pops[code_name]['label']
    if ':' in code_name:
        output_tokens = code_name.split(':')
        if len(output_tokens) == 2:
            output_tokens.append('')
        src, dest, par = output_tokens
        if dest == 'flow':
            if src in proj.framework:
                return '{0} (flow)'.format(proj.framework.get_label(src))
            else:
                return '{0} (flow)'.format(src)
        if src and src in proj.framework:
            src = proj.framework.get_label(src)
        if dest and dest in proj.framework:
            dest = proj.framework.get_label(dest)
        if par and par in proj.framework:
            par = proj.framework.get_label(par)
        full = 'Flow'
        if src:
            full += ' from {}'.format(src)
        if dest:
            full += ' to {}'.format(dest)
        if par:
            full += ' ({})'.format(par)
        return full
    elif code_name in proj.framework:
        return proj.framework.get_label(code_name)
    else:
        return code_name


@staticmethod
def convert_temperature(temperature):
    """Convert temperature to celsius"""
    if temperature is None:
        return None
    return round(float(temperature) / 100, 1)


def get_exception_message(ex):
    """Build exception message with details.
    """
    template = '{0}: {1!r}'
    return template.format(type(ex).__name__, ex.args)


def write_meta_result(in_adaffile, out_adaffile):
    """Copy meta and result from in file to out file."""
    out_adaffile.meta.hjoin(in_adaffile.meta)
    out_adaffile.res.hjoin(in_adaffile.res)


def line_last_two_words(line):
    """return last two words"""
    if len(line.split()) > 1:
        return ' '.join([line.split()[-2], line.split()[-1]])
    else:
        return False


def job_show(context, data_dict):
    """Show background job. Only sysadmins."""
    return {'success': False}


@staticmethod
def plane_points_idx(points, ctx, plane='Transversal'):
    """
        Convert a points in a 3D cube in terms of [mm, mm, mm] to the current plane in terms of [idx,idx].

        :param points: INPUT: list of points in [[x0,y0,z0],[x1,y1,z1], ...[xn,yn,zn]] (mm) format
                       OUTPUT: list of points pseudo-2D format.
        :param ctx:
        :param plane:

        TODO: code would be easier to read, if this is split up into two steps. 1) conv. to index, 2) extraction.
        """
    ct_pixsize_inv = 1.0 / ctx.pixel_size
    ct_slicedist_inv = 1.0 / ctx.slice_distance
    for point in points:
        if plane == 'Transversal':
            point[:, (0)] *= ct_pixsize_inv
            point[:, (1)] *= ct_pixsize_inv
        elif plane == 'Sagittal':
            point[:, (0)] = (-point[:, (1)] + ctx.pixel_size * ctx.dimx
                ) * ct_pixsize_inv
            point[:, (1)] = (-point[:, (2)] + ctx.slice_distance * ctx.dimz
                ) * ct_slicedist_inv
        elif plane == 'Coronal':
            point[:, (0)] = (-point[:, (0)] + ctx.pixel_size * ctx.dimy
                ) * ct_pixsize_inv
            point[:, (1)] = (-point[:, (2)] + ctx.slice_distance * ctx.dimz
                ) * ct_slicedist_inv


def window(iterable: iter, size: int, stride: int=2, unequal: str='pad',
    padval=0) ->list:
    """Pass through an iterable and return certain windowed segments.

    It's basically a moving window of a certain size and stride
    that extracts subsets of an iiterable.

    Parameters
    ----------
    iterable : iter
        The thing to move through
    size: int
        The size of the window to pan with. This is how many
        elements will be considered as part of a subset.
    stride: int
        After getting a subset, how many steps should the window
        move before selecting the next chunk?
    unequal : str
        Can be 'pad' or 'drop'. It's very possible that the
        end of a list wont contain the expected number of items,
        eg.
        [1,2,3]
        with a size of 4 would only find 3 elements. What should happen?
        If 'pad' we add a value to that subset. Specify the value with the
        padval keyword argument. If 'drop' we simply let the subset be
        3 items.

    Examples
    --------
    orig = [1,2,3,4,5,6,7,8]
    window(orig, size=2, stride=3)

      -> [(1,2),3,4,5,6,7,8]
      -> [1,2,3,(4,5),6,7,8]
      -> [1,2,3,4,5,6,(7,8)]

    would return [[1,2], [4,5], [7,8]]

    """
    finished = list()
    start = 0
    end = start + size
    final = len(iterable)
    while start <= final:
        current = iterable[start:end]
        if len(current) == 0:
            break
        if len(current) < size:
            if unequal == 'pad':
                while len(current) < size:
                    if isinstance(current, bytes):
                        current = current + b'\x00'
                    else:
                        current.append(padval)
            if unequal == 'drop':
                pass
        finished.append(current)
        if end >= final:
            break
        start += stride
        end += stride
    return finished


@classmethod
def from_client(cls, client, *args, **kwargs):
    """Construct a OAuth2 object from a `spotify.Client`."""
    return cls(client.http.client_id, *args, **kwargs)


def get_result_class(cls):
    """
    For the given model class, determine what class we should use for the
    nodes returned by its tree methods (such as get_children).

    Usually this will be trivially the same as the initial model class,
    but there are special cases when model inheritance is in use:

    * If the model extends another via multi-table inheritance, we need to
      use whichever ancestor originally implemented the tree behaviour (i.e.
      the one which defines the 'parent' field). We can't use the
      subclass, because it's not guaranteed that the other nodes reachable
      from the current one will be instances of the same subclass.

    * If the model is a proxy model, the returned nodes should also use
      the proxy class.
    """
    base_class = cls._meta.get_field('parent').model
    if cls._meta.proxy_for_model == base_class:
        return cls
    else:
        return base_class


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 '+'


@staticmethod
def sigma(state, tk):
    """Return the next state from the current one and an input token."""
    raise NotImplementedError('must implement the sigma method!')


def stacked_preferred_size(container, components=None):
    """ Returns the size (width,height) that is preferred for this component.

    Overrides Component.
    """
    if container.fixed_preferred_size is not None:
        container._cached_preferred_size = container.fixed_preferred_size
        return container.fixed_preferred_size
    if components is None:
        components = container.components
    ndx = container.stack_index
    other_ndx = 1 - ndx
    no_visible_components = True
    total_size = 0
    max_other_size = 0
    for component in components:
        if not container._should_layout(component):
            continue
        no_visible_components = False
        pref_size = component.get_preferred_size()
        total_size += pref_size[ndx] + container.spacing
        if pref_size[other_ndx] > max_other_size:
            max_other_size = pref_size[other_ndx]
    if total_size >= container.spacing:
        total_size -= container.spacing
    if (container.stack_dimension not in container.resizable and container.
        stack_dimension not in container.fit_components):
        total_size = container.bounds[ndx]
    elif no_visible_components or total_size == 0:
        total_size = container.default_size[ndx]
    if (container.other_dimension not in container.resizable and container.
        other_dimension not in container.fit_components):
        max_other_size = container.bounds[other_ndx]
    elif no_visible_components or max_other_size == 0:
        max_other_size = container.default_size[other_ndx]
    if ndx == 0:
        container._cached_preferred_size = (total_size + container.hpadding,
            max_other_size + container.vpadding)
    else:
        container._cached_preferred_size = (max_other_size + container.
            hpadding, total_size + container.vpadding)
    return container._cached_preferred_size


@classmethod
def allowedParentTypes(klass):
    """Get types of widgets this can be a child of."""
    return ()


def main(args):
    """
    Performs motif mapping.
    """
    print(args)


def format_time(dt):
    """
    Format a python datetime object into a value suitable for the API
    :param dt: datetime timestamp
    :return:
    """
    return dt.strftime('%d/%m/%Y %H:%M:%S')


@staticmethod
def all_filtered(output):
    """
        if all port are filtered, then we have nothing to extract
        :param output:
        :return:
        """
    if 'are filtered' in output:
        print(' '.join(output))
        return 0
    return 1


def instantiate(t):
    """Instantiate `t` if it's a type, otherwise do nothing"""
    return t() if isinstance(t, type) else t


def _get_hash_string(target):
    """Calculate Object hash.

    Parameters
    ----------
    target
        An object. It must implement or inherit __hash__ method.

    Returns
    -------
        The hash string.

    """
    return str(target.__hash__(target))


def get_description(cls, value):
    """
        Get description from value.
        """
    try:
        return cls._descriptions[value]
    except KeyError:
        raise ValueError('not a member of enumeration: %r' % value)


@classmethod
def convert_packets(cls, pkts, **kwargs):
    """Converts many packets to this type.

        This is implemented as a generator.

        See ``Packet.convert_packet``.
        """
    for pkt in pkts:
        yield cls.convert_packet(pkt, **kwargs)


def merge_dicts(d1, d2):
    """ Function to merge two dictionaries.

    INPUTS
    ======
    d1 : dictionary
    d2 : dictionary

    OUTPUTS
    =======
    dnew : new dictionary that is a combination of d1 and d2

    """
    dnew = d1.copy()
    for key in d2:
        if key in dnew:
            for item in d2[key]:
                if item not in dnew[key]:
                    dnew[key] = dnew[key] + [item]
        else:
            dnew[key] = d2[key]
    return dnew


def _receive_data_tf(event):
    """Standard logging handler for receiving a P-DATA-TF PDU."""
    pass


def to_urwid_color(p_color):
    """
    Given a Color object, transform it to a color that urwid understands.
    """
    if not p_color.is_valid():
        return 'black'
    elif p_color.is_neutral():
        return 'default'
    else:
        return 'h{}'.format(p_color.color)


def renderRow(row, cssClass=None):
    """Render the table body rows."""


def mae_tase(tase_array):
    """
    mean_abs_error,求两组数据的平均绝对误差
    :param tase_array:包含命中空报和漏报的多维数组，其中最后一维长度为4，分别记录了（total_count,e_sum,ae_sum,se_sum）
    （样本数，误差和、绝对误差和，误差平方和），它由tase返回
    :return: 0到无穷大，最优值为0
    """
    mean_abs_error = tase_array[..., 2] / tase_array[..., 0]
    return mean_abs_error


def pullnodeIDs(in_network, name_key='dn_name'):
    """ This function will return the values contained, for each node in
    a network, given an input key. By default it will return the node names
    """
    import networkx as nx
    import numpy as np
    from nipype.interfaces.base import isdefined
    if not isdefined(in_network):
        raise ValueError
        return None
    try:
        ntwk = nx.read_graphml(in_network)
    except:
        ntwk = nx.read_gpickle(in_network)
    nodedata = ntwk.node
    ids = []
    integer_nodelist = []
    for node in list(nodedata.keys()):
        integer_nodelist.append(int(node))
    for node in np.sort(integer_nodelist):
        try:
            nodeid = nodedata[node][name_key]
        except KeyError:
            nodeid = nodedata[str(node)][name_key]
        ids.append(nodeid)
    return ids


def read_file(path):
    """Read a file should be a pathlib Path object"""
    data = ''
    with path.open('r') as f:
        data = f.read()
    return data


@classmethod
def from_address(cls, address):
    """Creates and address object from an address string"""
    return cls(address=address)


def isket(qob):
    """Checks if ``qob`` is in ket form -- an array column.
    """
    return qob.shape[0] > 1 and qob.shape[1] == 1


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 isa(*types):
    """
    Creates a function checking if its argument
    is of any of given types.
    """
    return lambda x: isinstance(x, types)


def filter_data(data, min_samples):
    """
    Remove all alleles from data that have less than min_samples
    samples.
    """
    for marker in data['alleles'].keys():
        for allele in data['alleles'][marker].keys():
            if len(data['alleles'][marker][allele]) < min_samples:
                del data['alleles'][marker][allele]
                continue
        if not data['alleles'][marker]:
            del data['alleles'][marker]


@classmethod
def bringToFront(cls):
    """Brings page to front (activates tab).
        """
    return cls.build_send_payload('bringToFront', {}), None


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


def find_clashes(all_items):
    """Find schedule items which clash (common slot and venue)"""
    clashes = {}
    seen_venue_slots = {}
    for item in all_items:
        for slot in item.slots.all():
            pos = item.venue, slot
            if pos in seen_venue_slots:
                if seen_venue_slots[pos] not in clashes:
                    clashes[pos] = [seen_venue_slots[pos]]
                clashes[pos].append(item)
            else:
                seen_venue_slots[pos] = item
    return clashes.items()


def record_param_count(parent=None, new_value=None, **kwargs):
    """Size getter/setter for the record parameters array element count."""
    if parent is None:
        raise KeyError('Cannot get/set the size of record parameter ' +
            'array without a supplied parent.')
    if new_value is None:
        return (parent.size - 3) * 2
    assert not new_value % 2, 'record byte sizes must be a multiple of 2.'
    parent.size = 3 + new_value // 2


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 parser(stream, objconf, tuples, **kwargs):
    """ Parses the pipe content

    Args:
        stream (Iter[dict]): The source. Note: this shares the `tuples`
            iterator, so consuming it will consume `tuples` as well.

        objconf (obj): the item independent configuration (an Objectify
            instance).

        tuples (Iter[(dict, obj)]): Iterable of tuples of (item, objconf)
            `item` is an element in the source stream and `objconf` is the item
            configuration (an Objectify instance). Note: this shares the
            `stream` iterator, so consuming it will consume `stream` as well.

        kwargs (dict): Keyword arguments.

    Returns:
        Iter(dict): The output stream

    Examples:
        >>> from itertools import repeat
        >>>
        >>> kwargs = {}
        >>> stream = ({'x': x} for x in range(5))
        >>> tuples = zip(stream, repeat(None))
        >>> next(parser(stream, None, tuples, **kwargs)) == {'x': 4}
        True
    """
    return reversed(list(stream))


def isVisible():
    """Return True if the VR pane is visible."""


@staticmethod
def homogenize_types(df, groupby_cols):
    """Converting all GROUPBY columns to strings

        When grouping by a numeric (say FLOAT) column, pydruid returns
        strings in the dataframe. This creates issues downstream related
        to having mixed types in the dataframe

        Here we replace None with <NULL> and make the whole series a
        str instead of an object.
        """
    for col in groupby_cols:
        df[col] = df[col].fillna('<NULL>').astype('unicode')
    return df


def disconnect_lifelines(line, send, received):
    """
    Disconnect lifeline and set appropriate kind of message item. If
    there are no lifelines connected on both ends, then remove the message
    from the data model.
    """
    if not line.subject:
        return
    if send:
        event = line.subject.receiveEvent
        if event:
            event.unlink()
    if received:
        event = line.subject.sendEvent
        if event:
            event.unlink()
    if not send or not received:
        message = line.subject
        del line.subject
        if not message.presentation:
            message.unlink()


@staticmethod
def get_credentials_module():
    """
        Returns the credentials module.

        :returns: the module
        :rtype: module
        """
    import inspect
    import importlib
    import os
    return importlib.import_module('%(module)s.configs.%(stage)s' % {
        'module': inspect.getmodule(inspect.stack()[1][0]).__name__.split(
        '.')[0], 'stage': os.environ['DJANGO_CONFIGURATION']})


def segments_overlap(a, b):
    """Returns True if GPS segment ``a`` overlaps GPS segment ``b``
    """
    return a[1] > b[0] and a[0] < b[1]


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


@staticmethod
def hex_to_int(value):
    """
        Takes a hex string (such as #00ff00) and returns its integer
        equivalent

        eg: #00000f becomes : 15

        """
    return int(value.lstrip('#'), 16)


def setpathinbrowser(context, path, file):
    """
    set path and file in the filebrowser
    """
    for a in context.window.screen.areas:
        if a.type == 'FILE_BROWSER':
            params = a.spaces[0].params
            break
    try:
        params
    except UnboundLocalError:
        return {'CANCELLED'}
    params.directory = path
    params.filename = file
    return path, params


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

        :param TfaChangePolicyDetails val:
        :rtype: EventDetails
        """
    return cls('tfa_change_policy_details', val)


def is_superuser(request, view, obj=None):
    """
    Checks if the current user is a superuser.
    """
    return request.user.is_superuser


def package_root(varmap):
    """Return correct directory for the root package.

    The "root" package is the one where modules which do not
    belong to a package are located (see the distutils docs).
    This function should not need to be called directly in
    your actual setup script, but it can be useful for testing.
    Note that it looks for a ``package_root`` setup var, which
    can be used as a shortcut if your "root" package is not in
    the standard place (which is your setup script directory),
    rather than having to declare a ``package_dir`` dictionary
    with a ``''`` key.
    """
    try:
        return varmap['package_dir']['']
    except KeyError:
        try:
            result = varmap['package_root']
        except KeyError:
            return '.'
        else:
            dirmap = varmap.setdefault('package_dir', {})
            if '' not in dirmap:
                dirmap[''] = result
            return result


@classmethod
def clean(cls):
    """A method that sets or restores the state of the class.

        Normally Dectate only sets up configuration into the ``config``
        attribute, but in some cases you may touch other aspects of the
        class during configuration time. You can override this classmethod
        to set up the state of the class in its pristine condition.
        """
    pass


def disconnect():
    """Drops current connection.

    :rtype: None
    """


@staticmethod
def _adjust_time(time):
    """
        Returns the same time in unix timestamp minus one hour.
        :param int time: the unix epoch time to be adjusted
        :return int:
        """
    return time - 3600


def delete_ml_model(MLModelId=None):
    """
    Assigns the DELETED status to an MLModel , rendering it unusable.
    After using the DeleteMLModel operation, you can use the GetMLModel operation to verify that the status of the MLModel changed to DELETED.
    Caution: The result of the DeleteMLModel operation is irreversible.
    See also: AWS API Documentation

    :example: response = client.delete_ml_model(
        MLModelId='string'
    )

    :type MLModelId: string
    :param MLModelId: [REQUIRED]
            A user-supplied ID that uniquely identifies the MLModel .

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

    """
    pass


def decode_YCbCr422_8():
    """Decode YCbCr422 buffer with given bit depth."""
    raise NotImplementedError


def truncate():
    """Truncate the trees.
        """


def distance(plane):
    """Distance the plane is from the origin along its the normal.

    Negative value indicates the plane is facing the origin.
    """
    return plane[3]


def extract_from_list(var):
    """ Extract name, min, mean and max from a list

    Args:
        var (list): List in a format like ['x', -1, 1] or (-2, 0, 3)

    Returns:
        name, value, min, max

    """
    var = list(var)
    name = val = lwb = upb = None
    assert len(var) >= 2, "Please use a format like ['x', -1, 1] or (-2, 0, 3)"
    if isinstance(var[0], str):
        name = var[0]
        var = var[1:]
    var = sorted(var)
    if len(var) == 2:
        lwb, upb = var
        val = lwb + upb
        val /= 2.0
    if len(var) == 3:
        lwb, val, upb = var
    return name, val, lwb, upb


def get_transphire_dict():
    """
    Translate transphire ctf dict into relion star file information.

    Arguments:
    None

    Return:
    Dtype dict
    """
    transphire_dict = {}
    transphire_dict = {'defocus_1': '_rlnDefocusU', 'defocus_2':
        '_rlnDefocusV', 'defocus': '_rlnDefocusU', 'defocus_diff':
        '_rlnDefocusV', 'astigmatism': '_rlnDefocusAngle', 'phase_shift':
        '_rlnPhaseShift', 'cross_corr': '_rlnCtfFigureOfMerit', 'limit':
        '_rlnCtfMaxResolution', 'file_name': '_rlnMicrographName'}
    return transphire_dict


def analyse_style(words):
    """
    Outputs an analysis of the style of the verse (viskuri law and alliteration)
    :param words: ["vesi", "vanhin", "voitehista"]
    :return: a dictionary of the style {"viskuri":True, "alliteration": True}
    """
    return_dict = {}
    first_letters = []
    lengths = []
    for w in words:
        if w[0] == u'å':
            first_letters.append(u'o')
        else:
            first_letters.append(w[0])
        lengths.append(len(w))
    if len(first_letters) != len(set(first_letters)):
        return_dict['alliteration'] = True
    else:
        return_dict['alliteration'] = False
    last_len = lengths[len(lengths) - 1]
    last_at_end = True
    for i in range(len(lengths) - 1):
        w = lengths[i]
        if w > last_len:
            last_at_end = False
            break
    return_dict['viskuri'] = last_at_end
    return return_dict


def read_homefile(filepath: str='', load_ui: bool=True, use_empty: bool=
    False, use_splash: bool=False, app_template='Template'):
    """Open the default file (doesn’t save the current file)

    :param filepath: File Path, Path to an alternative start-up file
    :type filepath: str
    :param load_ui: Load UI, Load user interface setup from the .blend file
    :type load_ui: bool
    :param use_empty: Empty
    :type use_empty: bool
    :param use_splash: Splash
    :type use_splash: bool
    """
    pass


def constant(s):
    """Constant pumping."""
    return 1.0 / s


def find_str(s, char):
    """Finds a substring in a string.

    :param s: String you are searching in.
    :param char: String you are searching for.
    :return: If the substring is found it returns the index of the first occurrence, otherwise returns -1.
    """
    index = 0
    if char in s:
        c = char[0]
        for ch in s:
            if ch == c:
                if s[index:index + len(char)] == char:
                    return index
            index += 1
    return -1


def format_leads(leads):
    """For a list of leads, removes the "custom" key from each lead and
    transforms all "custom.* fields into a new "custom_fields" list."""
    new_leads = []
    for lead in leads:
        custom_fields = []
        new_lead = {'custom_fields': custom_fields}
        for k, v in lead.items():
            if k.startswith('custom.'):
                custom_id = k.split('.')[1]
                custom_fields.append({'id': custom_id, 'value': v})
            elif k != 'custom':
                new_lead[k] = v
        new_leads.append(new_lead)
    return new_leads


def ensure_tuple(var):
    """Ensures that variable is a tuple, even if its a scalar"""
    if getattr(var, '__iter__', False):
        return tuple(var)
    return var,


def GetTimestamp(header):
    """

    gets the timestamp of when the header was created

    """
    pass


def compression_apply(signal, gain):
    """Applies a predetermined gain function to the input signal. `gain`
        should have been generated previously using the `compress` function.

        Parameters
        ----------
        signal : array
            The input signal to be compressed (mono)
        gain : array
            The gain function, generated by `compress`

        Returns
        -------
        sigout : array
            The input signal with the gain function applied

        Notes
        -----
        There is no in-built facility using this function to delay the audio
        signal relative to the gain control signal (to reduceovershoot
        effects), which is an option in the compress function.

        Adapted from Matlab code provided by Ian Wiggins, Institute of Hearing
        Research, Nottingham
    """
    lin_gain = 10.0 ** (gain / 20.0)
    sigout = signal * lin_gain
    return sigout


def _fill_publisher(r, entry):
    """
    Make a "named entry" dict with a publisher field
    :param r: BibJSON record dict that will be filled
    :param entry: bibtexparser entry that will be used to fill the BibJSON record
    :return None
    """
    if 'publisher' not in entry:
        return
    r['publisher'] = {'name': entry['publisher']}
    if 'address' in entry:
        r['publisher']['address'] = entry['address']


@staticmethod
def rotl(v, n):
    """
        circularly rotate v left n places
        """
    assert n <= len(v)
    return v[n:] + v[:n]


def _create_ansi_color_dict(color_cls):
    """ Create a table that maps the 16 named ansi colors to their Windows code. """
    return {'ansidefault': color_cls.BLACK, 'ansiblack': color_cls.BLACK,
        'ansigray': color_cls.GRAY, 'ansibrightblack': color_cls.BLACK |
        color_cls.INTENSITY, 'ansiwhite': color_cls.GRAY | color_cls.
        INTENSITY, 'ansired': color_cls.RED, 'ansigreen': color_cls.GREEN,
        'ansiyellow': color_cls.YELLOW, 'ansiblue': color_cls.BLUE,
        'ansimagenta': color_cls.MAGENTA, 'ansicyan': color_cls.CYAN,
        'ansibrightred': color_cls.RED | color_cls.INTENSITY,
        'ansibrightgreen': color_cls.GREEN | color_cls.INTENSITY,
        'ansibrightyellow': color_cls.YELLOW | color_cls.INTENSITY,
        'ansibrightblue': color_cls.BLUE | color_cls.INTENSITY,
        'ansibrightmagenta': color_cls.MAGENTA | color_cls.INTENSITY,
        'ansibrightcyan': color_cls.CYAN | color_cls.INTENSITY}


def lorentzian(height, center_x, center_y, width_x, width_y):
    """Returns a gaussian function with the given parameters"""
    width_x = float(width_x) ** 2
    width_y = float(width_y) ** 2
    return lambda x, y: height / (1.0 + 4 * (x - center_x) ** 2 / width_x +
        4 * (y - center_y) ** 2 / width_y)


@staticmethod
def is_segment_name(string) ->bool:
    """
        Is true when ``string`` is canonical segment name.

        ..  container:: example

            >>> abjad.Path.is_segment_name('_')
            True

            >>> abjad.Path.is_segment_name('_1')
            True

            >>> abjad.Path.is_segment_name('_2')
            True

            >>> abjad.Path.is_segment_name('_99')
            True

            >>> abjad.Path.is_segment_name('A')
            True

            >>> abjad.Path.is_segment_name('A1')
            True

            >>> abjad.Path.is_segment_name('A2')
            True

            >>> abjad.Path.is_segment_name('A99')
            True

            >>> abjad.Path.is_segment_name('B')
            True

            >>> abjad.Path.is_segment_name('B1')
            True

            >>> abjad.Path.is_segment_name('B2')
            True

            >>> abjad.Path.is_segment_name('B99')
            True

            >>> abjad.Path.is_segment_name('AA')
            True

            >>> abjad.Path.is_segment_name('AA1')
            True

            >>> abjad.Path.is_segment_name('AA2')
            True

            >>> abjad.Path.is_segment_name('AA99')
            True

            >>> abjad.Path.is_segment_name('AB')
            True

            >>> abjad.Path.is_segment_name('AB1')
            True

            >>> abjad.Path.is_segment_name('AB2')
            True

            >>> abjad.Path.is_segment_name('AB99')
            True

            >>> abjad.Path.is_segment_name('__')
            False

            >>> abjad.Path.is_segment_name('1')
            False

            >>> abjad.Path.is_segment_name('a')
            False

            >>> abjad.Path.is_segment_name('b')
            False

            >>> abjad.Path.is_segment_name('aa')
            False

            >>> abjad.Path.is_segment_name('ab')
            False

            >>> abjad.Path.is_segment_name('AAA')
            False

        """
    if not isinstance(string, str):
        return False
    if not bool(string):
        return False
    if not (string[0].isupper() or string[0] == '_'):
        return False
    if len(string) == 1:
        return True
    if not (string[1].isupper() or string[1].isdigit()):
        return False
    if len(string) == 2:
        return True
    return string[2:].isnumeric()


def _chunkify(arr, size):
    """ Split up a bytestream into chunks """
    arrs = []
    for i in range(0, len(arr), size):
        chunk = bytearray(arr[i:i + size])
        arrs.append(chunk)
    return arrs


def lfn_bases():
    """Return LFN Base list"""
    storeResultLFNBase = ['/store/backfill/1', '/store/backfill/2',
        '/store/data', '/store/mc', '/store/generator', '/store/relval',
        '/store/hidata', '/store/himc', '/store/results/analysisops',
        '/store/results/b_physics', '/store/results/b_tagging',
        '/store/results/b2g', '/store/results/e_gamma_ecal',
        '/store/results/ewk', '/store/results/exotica',
        '/store/results/forward', '/store/results/heavy_ions',
        '/store/results/higgs', '/store/results/jets_met_hcal',
        '/store/results/muon', '/store/results/qcd', '/store/results/susy',
        '/store/results/tau_pflow', '/store/results/top',
        '/store/results/tracker_dpg', '/store/results/tracker_pog',
        '/store/results/trigger']
    return storeResultLFNBase


def storecollapsemsg(repo, collapsemsg):
    """Store the collapse message to allow recovery"""
    collapsemsg = collapsemsg or b''
    f = repo.vfs(b'last-message.txt', b'w')
    f.write(b'%s\n' % collapsemsg)
    f.close()


def extract_annotation(data):
    """Extract names and values of rows and columns.

    Parameter:
        data : DataFrame | Panel

    Returns:
        col_name, col_values, row_name, row_values
    """
    xlabel = None
    xvalues = None
    ylabel = None
    yvalues = None
    if hasattr(data, 'minor_axis'):
        xvalues = data.minor_axis
        if hasattr(data.minor_axis, 'name'):
            xlabel = data.minor_axis.name
    if hasattr(data, 'columns'):
        xvalues = data.columns
        if hasattr(data.columns, 'name'):
            xlabel = data.columns.name
    if hasattr(data, 'major_axis'):
        yvalues = data.major_axis
        if hasattr(data.major_axis, 'name'):
            ylabel = data.major_axis.name
    if hasattr(data, 'index'):
        yvalues = data.index
        if hasattr(data.index, 'name'):
            ylabel = data.index.name
    return xlabel, xvalues, ylabel, yvalues


@classmethod
def CheckElement(cls, elem):
    """
		Return True if element is a Table element whose Name
		attribute matches the .tableName attribute of this class ;
		return False otherwise.  See also .CheckProperties().
		"""
    return cls.CheckProperties(elem.tagName, elem.attributes)


def get_spaced_line(line, depth=0):
    """
    Prepend a line with certain space
    :param line: the line to edit
    :param depth: the number of spaces to insert
    :return: the prepended line
    """
    if type(line) == str:
        return ' ' * depth + str(line)
    return line


def t_php_DOC_COMMENT(t):
    """/\\*\\*(.|\\n)*?\\*/"""
    t.lexer.lineno += t.value.count('\n')
    return t


def polyfill_integers(generator, low, high=None, size=None, dtype='int32',
    endpoint=False):
    """Sample integers from a generator in different numpy versions.

    Parameters
    ----------
    generator : numpy.random.Generator or numpy.random.RandomState
        The generator to sample from. If it is a ``RandomState``,
        :func:`numpy.random.RandomState.randint` will be called,
        otherwise :func:`numpy.random.Generator.integers`.

    low : int or array-like of ints
        See :func:`numpy.random.Generator.integers`.

    high : int or array-like of ints, optional
        See :func:`numpy.random.Generator.integers`.

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

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

    endpoint : bool, optional
        See :func:`numpy.random.Generator.integers`.

    Returns
    -------
    int or ndarray of ints
        See :func:`numpy.random.Generator.integers`.

    """
    if hasattr(generator, 'randint'):
        if endpoint:
            if high is None:
                high = low + 1
                low = 0
            else:
                high = high + 1
        return generator.randint(low=low, high=high, size=size, dtype=dtype)
    return generator.integers(low=low, high=high, size=size, dtype=dtype,
        endpoint=endpoint)


def _pipe_segment_with_colons(align, colwidth):
    """Return a segment of a horizontal line with optional colons which
    indicate column's alignment (as in `pipe` output format)."""
    w = colwidth
    if align in ['right', 'decimal']:
        return '-' * (w - 1) + ':'
    elif align == 'center':
        return ':' + '-' * (w - 2) + ':'
    elif align == 'left':
        return ':' + '-' * (w - 1)
    else:
        return '-' * w


def first_true(iterable, default=False, pred=None):
    """Returns the first true value in the iterable.

    If no true value is found, returns *default*

    If *pred* is not None, returns the first item
    for which pred(item) is true.

    """
    return next(filter(pred, iterable), default)


@staticmethod
def pytest_addoption(parser):
    """
        Adds custom options to the ``pytest`` command.
        https://docs.pytest.org/en/latest/writing_plugins.html#_pytest.hookspec.pytest_addoption
        """
    group = parser.getgroup('crate', 'integration tests')
    group.addoption('--crate-version', dest='crate_version', default=
        'latest-stable', help='CrateDB version')


@classmethod
def root_factory(cls, request):
    """Called by Pyramid routing framework to create a new root for a request."""
    return cls(request)


def _format_float(arg):
    """Formats a float value to be as short as possible.

    Trims extraneous trailing zeros and period to give API
    args the best possible chance of fitting within 2000 char
    URL length restrictions.

    For example:

    format_float(40) -> "40"
    format_float(40.0) -> "40"
    format_float(40.1) -> "40.1"
    format_float(40.001) -> "40.001"
    format_float(40.0010) -> "40.001"

    :param arg: The lat or lng float.
    :type arg: float

    :rtype: string
    """
    return '{}'.format(round(float(arg), 6)).rstrip('0').rstrip('.')


def is_valid_xvg_param(ext):
    """ Checks xvg parameter """
    formats = ['xmgrace', 'xmgr', 'none']
    return ext in formats


def bech32_polymod(values):
    """Internal function that computes the Bech32 checksum."""
    generator = [996825010, 642813549, 513874426, 1027748829, 705979059]
    chk = 1
    for value in values:
        top = chk >> 25
        chk = (chk & 33554431) << 5 ^ value
        for i in range(5):
            chk ^= generator[i] if top >> i & 1 else 0
    return chk


def _is_nth_child_of_kind(stack, allowed_nums, kind):
    """
    Checks if the stack contains a cursor which is of the given kind and the
    stack also has a child of this element which number is in the allowed_nums
    list.

    :param stack:        The stack holding a tuple holding the parent cursors
                         and the child number.
    :param allowed_nums: List/iterator of child numbers allowed.
    :param kind:         The kind of the parent element.
    :return:             Number of matches.
    """
    is_kind_child = False
    count = 0
    for elem, child_num in stack:
        if is_kind_child and child_num in allowed_nums:
            count += 1
        if elem.kind == kind:
            is_kind_child = True
        else:
            is_kind_child = False
    return count


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


def _parse_nodata(data):
    """Parse :const:`NODATA` data type. Does nothing."""


def i_am_the_spooler():
    """Returns flag indicating whether you are the Spooler.

    :rtype: bool
    """
    return False


def firn_permittivity(rhof, rhoi=917.0, epsi_real=3.12, epsi_imag=-9.5):
    """
    Calculate the dielectric permittivity of firn with the DECOMP mixing model
    Wilhelms (2005), GRL

    Parameters
    ---------
    rhof:           firn density       (kg/m3)
    rhoi:           ice density       (kg/m3)
    epsi_real:      real permittivity of ice (relative)
    epsi_imag:      imaginary permittivity of ice (relative)

    Output
    ---------
    eps_f:          firn permittivity   (relative)
    """
    lhs = 1.0 + rhof / rhoi * ((epsi_real - 1.0j * epsi_imag) ** (1 / 3.0) - 1)
    eps_f = lhs ** 3.0
    return eps_f


def create_id_box(label, num_digits, box_width=None):
    """Creates the ID box given a label to show and number of digits.

    """
    parts = ['\\begin{center}', '\\Large']
    if box_width is not None:
        parts.append('\\resizebox{%fcm}{!}{' % box_width)
    parts.append('\\begin{tabular}{l|' + num_digits * 'p{3mm}|' + '}')
    parts.append('\\cline{2-%d}' % (1 + num_digits))
    parts.append('\\textbf{%s}: ' % label + num_digits * '& ' + '\\\\')
    parts.append('\\cline{2-%d}' % (1 + num_digits))
    parts.append('\\end{tabular}')
    if box_width is not None:
        parts.append('}')
    parts.append('\\end{center}')
    return '\n'.join(parts)


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

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

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


@classmethod
def factory(cls, paramstyle, case_insensitive=False):
    """
        return a Binder subclass instance appropriate
        to the underlying db library paramstyle bind variable

        :param paramstyle: parameter style string as per PEP-249
        :case_insensitive: %(custid)s will match {"custid":1} or {"CUSTID":2}, with priority
        going to the initial case.  mixed-case keys (custId) will only match {"custId":3}

        """
    try:
        inst = cls._di_paramstyle[paramstyle]()
        if case_insensitive:
            inst._key_expand = inst._case_insensitive
        return inst
    except KeyError:
        msg = (
            """got:%s,
                  but expecting one of %s.
                  See
                  https://www.python.org/dev/peps/pep-0249/#paramstyle
                  for details"""
             % (paramstyle, '/'.join(list(cls._di_paramstyle.keys()))))
        raise ValueError(msg)
    except NotImplementedError:
        msg = '%s is not implemented yet' % paramstyle
        raise NotImplementedError(msg)


@classmethod
def configured_class(cls):
    """Returns the currently configured class."""
    base = cls.configurable_base()
    if base.__dict__.get('_Configurable__impl_class') is None:
        base.__impl_class = cls.configurable_default()
    if base.__impl_class is not None:
        return base.__impl_class
    else:
        raise ValueError('configured class not found')


def msg(cmds, message, level=3):
    """
    Prints a message based on the level of verbosity given in cmds

    Parameters
    ----------
    cmds : UserCommands
        just for the SIM_VERBOSE and SIM_MESSAGE_LEVEL keywords
    message : str
        message to be printed
    level : int, optional
        all messages with level <= SIM_MESSAGE_LEVEL are printed. I.e. level=5
        messages are not important, level=1 are very important
    """
    if cmds['SIM_VERBOSE'] == 'yes' and level <= cmds['SIM_MESSAGE_LEVEL']:
        print(message)


def gradientboosting_feature_importance(X_train, y_train, classification):
    """
    Fits a Gradient Boosted LGBM Tree to the data and prints an analysis of feature importance
    Returns a pandas DataFrame of feature importance
    """
    import numpy as np
    import lightgbm as lgb
    import pandas as pd
    feature_importances = np.zeros(X_train.shape[1])
    model = None
    if classification:
        model = lgb.LGBMClassifier(boosting_type='goss', n_estimators=10000,
            class_weight='balanced')
    else:
        model = lgb.LGBMRegressor(boosting_type='goss', n_estimators=10000,
            class_weight='balanced')
    from sklearn.model_selection import train_test_split
    for i in range(2):
        train_features, valid_features, train_y, valid_y = train_test_split(
            X_train, y_train, test_size=0.25, random_state=i)
        model.fit(train_features, train_y, early_stopping_rounds=100,
            eval_set=[(valid_features, valid_y)], eval_metric='auc',
            verbose=200)
        feature_importances += model.feature_importances_
    feature_importances = feature_importances / 2
    feature_importances = pd.DataFrame({'feature': list(X_train.columns),
        'importance': feature_importances}).sort_values('importance',
        ascending=False)
    print(feature_importances.head())
    zero_features = list(feature_importances[feature_importances[
        'importance'] == 0.0]['feature'])
    print('There are %d features with 0.0 importance' % len(zero_features))
    print(feature_importances.tail())
    return feature_importances


def utr(dp, mu, rhog, rhos):
    """
    Determine the transport velocity of particles in a circulating fluidized
    bed riser. Based on Equation 2 in article by Zhang et al. [1]_.

    Parameters
    ----------
    dp : float
        Diameter of particle [m]
    mu : float
        Viscosity of gas [kg/(m s)]
    rhog : float
        Density of gas [kg/m^3]
    rhos : float
        Density of solid particle [kg/m^3]

    Returns
    -------
    utr : float
        Transport velocity [m/s]

    Example
    -------
    >>> utr(0.0005, 3.6e-5, 0.44, 1630)
    26.0617

    References
    ----------
    .. [1] H.L. Zhang, J. Degreve, R. Dewil, and J. Baeyens. Operation diagram
        of Circulating Fluidized Beds (CFBs). Procedia Engineering, 102,
        pp. 1092-1103, 2015.
    """
    g = 9.81
    ar = dp ** 3 * rhog * (rhos - rhog) * g / mu ** 2
    utr = mu / (dp * rhog) * (3.23 + 0.23 * ar)
    return utr


def report_versions():
    """Creates a string that reports the version of polyphemus and all its
    dependencies.
    """
    vstr = 'Polyphemus: {polyphemus_version}\n'
    return vstr.format(**globals())


def El2EstVol(Elements):
    """Estimate volume from molecular formula; assumes atom volume = 10A^3

    :param dict Elements: elements in molecular formula;
        each must contain
        Num: number of atoms in formula

    :returns: float volume: estimate of molecular volume in A^3

    """
    vol = 0
    for El in Elements:
        vol += 10.0 * Elements[El]['Num']
    return vol


def parse_to_var(data, var, stoptag=''):
    """ Parses a variable 'var' from 'data'.

    :returns: (out,i) tuple
    out - the rest of the line with 'var' and a " " removed. If nothing is followed, then True is returned.
    i - number of lines parsed.
    """
    out = {}
    i = 0
    if type(data) is str:
        data = data.split()
    for line in data:
        if line.find(stoptag) > -1:
            break
        items = line.split()
        if items[0] in var:
            if len(items) > 1:
                out[var[items[0]]] = line.replace(items[0] + ' ', '')
            else:
                out[var[items[0]]] = True
        i += 1
    return out, i


def modify_html(html):
    """ Perform style substitutions where docutils doesn't do what we want.
    """
    substitutions = {'<tt class="docutils literal">': '<code>', '</tt>':
        '</code>'}
    for old, new in substitutions.items():
        html = html.replace(old, new)
    return html


def req_map(hub):
    """
    Gather the requisite restrtrictions and populate the requisite behavior map
    """
    rmap = {}
    for mod in hub.idem.req:
        if mod.__sub_name__ == 'init':
            continue
        if hasattr(mod, 'define'):
            rmap[mod.__sub_name__] = mod.define()
    hub.idem.RMAP = rmap


def extract_aaf(var):
    """
    Extract the AAF directly from the INFO field.
    """
    return var.INFO.get('AF')


def generate_hostmap(baremetal_client, compute_client):
    """Create a map between Compute nodes and Baremetal nodes"""
    hostmap = {}
    for node in compute_client.servers.list():
        bm_node = baremetal_client.node.get_by_instance_uuid(node.id)
        for port in baremetal_client.port.list(node=bm_node.uuid):
            hostmap[port.address] = {'compute_name': node.name,
                'baremetal_name': bm_node.name}
    if hostmap == {}:
        return None
    else:
        return hostmap


def tree_path_parent():
    """Go to parent node tree

    """
    pass


def normal(vectors: list) ->'mathutils.Vector':
    """Returns the normal of a 3D polygon.

    :param vectors: Vectors to calculate normals with
    :type vectors: list
    """
    pass


@classmethod
def _load_pkcs1_pem(cls, keyfile):
    """Loads a key in PKCS#1 PEM format, implement in a subclass.

        :param keyfile: contents of a PEM-encoded file that contains
            the public key.
        :type keyfile: bytes

        :return: the loaded key
        :rtype: AbstractKey
        """


def new_content_types_text(db):
    """
    Returns [Content_Types].xml text

    :param pylightxl.Database db: database contains sheetnames, and their data
    :return str: [Content_Types].xml text
    """
    xml_base = (
        '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\r\n<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">\r\n<Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/>\r\n<Default Extension="xml" ContentType="application/xml"/>\r\n<Override PartName="/xl/workbook.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"/>\r\n{many_tag_sheets}\r\n{tag_sharedStrings}\r\n<Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml"/>\r\n<Override PartName="/docProps/app.xml" ContentType="application/vnd.openxmlformats-officedocument.extended-properties+xml"/>\r\n</Types>'
        )
    xml_tag_sheet = (
        '<Override PartName="/xl/worksheets/sheet{sheet_id}.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml"/>\r\n'
        )
    xml_tag_sharedStrings = (
        '<Override PartName="/xl/sharedStrings.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml"/>\r\n'
        )
    many_tag_sheets = ''
    for sheet_id, _ in enumerate(db.ws_names, 1):
        many_tag_sheets += xml_tag_sheet.format(sheet_id=sheet_id)
    if db._sharedStrings:
        tag_sharedStrings = xml_tag_sharedStrings
    else:
        tag_sharedStrings = ''
    rv = xml_base.format(many_tag_sheets=many_tag_sheets, tag_sharedStrings
        =tag_sharedStrings)
    return rv


def extruder_heater_control(percent):
    """ Extruder heater control.
    :param percent: heater power in percent 0..100. 0 turns heater off.
    """
    pass


def foldl(fn, elems, initializer=None, name=None):
    """Reduce elems using fn to combine them from left to right.

    # Arguments
        fn: Callable that will be called upon each element in elems and an
            accumulator, for instance `lambda acc, x: acc + x`
        elems: tensor
        initializer: The first value used (`elems[0]` in case of None)
        name: A string name for the foldl node in the graph

    # Returns
        Tensor with same type and shape as `initializer`.
    """
    raise NotImplementedError(
        'MXNet Backend: foldl operator is not supported yet.')


def _q_test(date, kwargs):
    """
    Computes quarterly indicators.

    No expectation of using kwargs in this. It is for consistency.
    """
    return date.month % 3 == 0


@classmethod
def _largest_nonfractional_unit(cls, amount):
    """
        Return largest unit such that `amount` is larger than 1 when
        expressed in that unit.
        """
    units = sorted(cls._UNITS.values())
    prev = units[0].base
    for unit in units:
        if prev.amount(unit.base) <= amount < unit.amount(unit.base):
            return prev
        prev = unit
    return unit


def properties_root_device_name(properties):
    """Get root device name from image meta data.
    If it isn't specified, return None.
    """
    root_device_name = None
    for bdm in properties.get('mappings', []):
        if bdm['virtual'] == 'root':
            root_device_name = bdm['device']
    if 'root_device_name' in properties:
        root_device_name = properties['root_device_name']
    return root_device_name


def getPrincipalsForPermission(permission_id):
    """Get the principas that have a permission.

        Return the list of (principal_id, setting) tuples that describe
        security assertions for this permission.

        If no principals have been set for this permission, then the empty
        list is returned.
        """


@staticmethod
def zip_packages(packagesfile, content=None):
    """
        根据Packages生成Packages.gz,Packages.bz2
        """
    if not content:
        with open(packagesfile, 'rb') as f:
            content = f.read()
    import gzip
    zfile = gzip.open(packagesfile + '.gz', mode='wb')
    zfile.write(content)
    zfile.close()
    import bz2
    bzfile = bz2.BZ2File(packagesfile + '.bz2', 'wb')
    bzfile.write(content)
    bzfile.close()
    return


def add_custom_constraint(constr, constraint, ll):
    """Adds a custom range constraint

		constraint shall be on the format (name, minimum, maximum)"""
    name, minimum, maximum = constraint
    m = [minimum, maximum]
    for i in range(2):
        if type(m[i]) == str:
            if not ll is None:
                m[i] = eval(m[i], globals(), ll.__dict__)
            else:
                return
    [minimum, maximum] = m
    constr.add_named(name, None, 'user constraint', [minimum, maximum])


def c_array(ctype, values):
    """Create ctypes array from a python array

    Parameters
    ----------
    ctype : ctypes data type
        data type of the array we want to convert to

    values : tuple or list
        data content

    Returns
    -------
    out : ctypes array
        Created ctypes array
    """
    return (ctype * len(values))(*values)


def mouse_aabb(mpos, size, pos):
    """
    AABB Collision checker that can be used for most axis-aligned collisions.

    Intended for use in widgets to check if the mouse is within the bounds of a particular widget.
    """
    return pos[0] <= mpos[0] <= pos[0] + size[0] and pos[1] <= mpos[1] <= pos[1
        ] + size[1]


def is_string_integer(the_string: str) ->bool:
    """Tests whether a string can be represented as integer number"""
    try:
        int(the_string)
        return True
    except ValueError:
        return False


def payables_turnover(purchases, average_trade_payables):
    """Computes payables turnover.

    @params
    -------
    purchases: purchases
    average_trade_payables: average_trade_payables

    returns
    -------
    Purchases turnover, int or float

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

    """
    return purchases / average_trade_payables

    def number_of_days_of_payables(number_of_days, payables_turnover):
        """Computes number of days of payables.

        @params
        -------
        number_of_days: number of days in period
        payables_turnover: payables turnover

        returns
        -------
        Number of days of payables, int or float

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

        """
        return number_of_days / payables_turnover

    def working_capital_turnover(revenue, average_working_capital):
        """Computes working capital turnover.

        @params
        -------
        revenue: revenue
        average_working_capital: average working capital in period

        returns
        -------
        Working capital turnover, int or float

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

        """
        return revenue / average_working_capital


def count_and_log(message, i, total, log_every_n):
    """Print a message to reflect the progress of processing once a while.

    Parameters
    ----------
    message : str
        Message to print.
    i : int
        Current index.
    total : int
        Total count.
    log_every_n : None or int
        Molecule related computation can take a long time for a large dataset and we want
        to learn the progress of processing. This can be done by printing a message whenever
        a batch of ``log_every_n`` molecules have been processed. If None, no messages will
        be printed.
    """
    if log_every_n is not None and (i + 1) % log_every_n == 0:
        print('{} {:d}/{:d}'.format(message, i + 1, total))


def flush():
    """ Flush and reindex metadata attributes """


def multi_mp_sgd_mom_update(*data, **kwargs):
    """Momentum update function for multi-precision Stochastic Gradient Descent (SGD) optimizer.

    Momentum update has better convergence rates on neural networks. Mathematically it looks
    like below:

    .. math::

      v_1 = \\alpha * \\nabla J(W_0)\\\\
      v_t = \\gamma v_{t-1} - \\alpha * \\nabla J(W_{t-1})\\\\
      W_t = W_{t-1} + v_t

    It updates the weights using::

      v = momentum * v - learning_rate * gradient
      weight += v

    Where the parameter ``momentum`` is the decay rate of momentum estimates at each epoch.

    Defined in src/operator/optimizer_op.cc:L472

    Parameters
    ----------
    data : Symbol[]
        Weights
    lrs : tuple of <float>, required
        Learning rates.
    wds : tuple of <float>, required
        Weight decay augments the objective function with a regularization term that penalizes large weights. The penalty scales with the square of the magnitude of each weight.
    momentum : float, optional, default=0
        The decay rate of momentum estimates at each epoch.
    rescale_grad : float, optional, default=1
        Rescale gradient to grad = rescale_grad*grad.
    clip_gradient : float, optional, default=-1
        Clip gradient to the range of [-clip_gradient, clip_gradient] If clip_gradient <= 0, gradient clipping is turned off. grad = max(min(grad, clip_gradient), -clip_gradient).
    num_weights : int, optional, default='1'
        Number of updated weights.

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

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


def get_year(s):
    """Get year from the signature.

    Parameters
    ----------
    :param s: dict
        Signature

    Returns
    -------
    :returns: int
        Year of publication if present on the signature, -1 otherwise
    """
    v = s['publication']['year']
    v = int(v) if v else -1
    return v


def calculateKey(cls, target):
    """Calculate the reference key for this reference

        Currently this is a two-tuple of the id()'s of the
        target object and the target function respectively.
        """
    return id(target.__self__), id(target.__func__)


def face_map_remove_from():
    """Remove faces from a face map

    """
    pass


def ids():
    """
        return the docids in this Index
        """


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

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

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


def format_hex_width(value, width):
    """! @brief Formats the value as hex of the specified bit width.

    @param value Integer value to be formatted.
    @param width Bit width, must be one of 8, 16, 32, 64.
    @return String with (width / 8) hex digits. Does not have a "0x" prefix.
    """
    if width == 8:
        return '%02x' % value
    elif width == 16:
        return '%04x' % value
    elif width == 32:
        return '%08x' % value
    elif width == 64:
        return '%016x' % value
    else:
        raise ValueError('unrecognized register width (%d)' % width)


def unquote(s):
    """Turn a string in the form =AB to the ASCII character with value 0xab"""
    return chr(int(s[1:3], 16))


def results2df(results, sort=True):
    """Convert a list of IndexingResult objects to pandas DataFrame."""
    import pandas as pd
    df = pd.DataFrame(results).T
    df.columns = list(results.values())[0]._fields
    if sort:
        df = df.sort_values('score', ascending=False)
    return df


def is_bool(s):
    """
    Returns True if the given object has None type or False otherwise
    :param s: object
    :return: bool
    """
    return isinstance(s, bool) or str(s).lower() in ['true', 'false']


def glFlush():
    """Force Execution of GL commands in finite time

    """
    pass


def get_ref_pos_alt_aa(aa_change):
    """
    Determine the reference AA(s), the position in the protein, and the alternate AA(s) for a given
    mutation in the form A123B

    :param aa_change: A String describing a mutation in protein space
    :return: reference AA(s), position, Alternamte AA(s)
    :rtype: tuple(str, int, str)
    """
    expected_isdigit = False
    parts = ['']
    for char in aa_change:
        if char.isdigit() is expected_isdigit:
            parts[-1] += char
        else:
            parts.append(char)
            expected_isdigit = not expected_isdigit
    parts[1] = int(parts[1])
    if len(parts) == 2:
        parts.append('')
    return parts