def match_rules(rules, app, action):
    """
    This will match rules found in Policy.
    """
    for rule in rules.split(','):
        try:
            rule_app, rule_action = rule.split(':')
            rule_app = rule_app.replace(' ', '')
            rule_action = rule_action.replace(' ', '')
            if rule_app == '*' or rule_app == app:
                if (rule_action == '*' or rule_action == action or action ==
                    '%'):
                    return True
        except Exception as ex:
            continue
    return False


def _F_N2(lbda_mu=0.3):
    """Depolarisation factor of N2 for Rayleigh scattering cross section

    Taken from `Bates 1984 <http://www.sciencedirect.com/science/article/pii/
    0032063384901028>`_

    Parameters
    ----------
    lbda_mu : float or ndarray
        wavelength in micrometers

    Returns
    -------
    float or ndarray
        depolarisation factor of N2
    """
    return 1.034 + 0.000317 / lbda_mu ** 2


def is_nonnegative_integer(argument) ->bool:
    """
    Is true when ``argument`` equals a nonnegative integer.

    ..  container:: example

        >>> abjad.mathtools.is_nonnegative_integer(99)
        True

        >>> abjad.mathtools.is_nonnegative_integer(0)
        True

        >>> abjad.mathtools.is_nonnegative_integer(-1)
        False

    """
    if argument == int(argument):
        if 0 <= argument:
            return True
    return False


def _get_query_parameters(module_params):
    """
    Builds query parameter
    :returns: dictionary, which is applicable builds the query format
     eg : {"$filter":"Type eq 2000"}
     """
    system_query_options_param = module_params.get('system_query_options')
    query_parameter = None
    if system_query_options_param:
        filter_by_val = system_query_options_param.get('filter')
        if filter_by_val:
            query_parameter = {'$filter': filter_by_val}
    return query_parameter


@classmethod
def delete(cls, id):
    """Delete this ssh key."""
    return cls.call('hosting.ssh.delete', cls.usable_id(id))


def check_units(value, dimension: str):
    """ Check if units are of a certain dimension

    Parameters
    ----------
    value: `pint.quantity._Quantity`
        The pint :class:`pint.quantity._Quantity` to check
    dimemension: `str`
        Desired dimensionality of value

    Returns
    -------
    result: `bool`
        If the units are of the desired dimension, returns True.

    Raises
    ------
    ValueError
        Raised if the unit dimensions are incorrrect or the
        the value is not a pint unit quantity.

    Examples
    --------
    >>> check_units(100 * units.millilters, '[length]^3')
    True

    Notes
    -----
    See the pint_ documentation for more examples on dimensionality.

    .. pint_: https://pint.readthedocs.io/en/latest/wrapping.html#checking-dimensionality
    """
    try:
        if value.check(dimension):
            return True
        else:
            raise ValueError(
                f'{value} must contain pint units of dimension {dimension}.')
    except AttributeError:
        raise ValueError(
            f'{value} does contain pint units.(must be of dimension {dimension}).'
            )


def _is_mutually_exclusive(graph, canonical_internal, alternative_internal):
    """
    Return true if the is no edges between the paths.
    """
    for i in canonical_internal:
        for j in alternative_internal:
            if graph.has_edge(i, j) or graph.has_edge(j, i):
                return False
    return True


def find_bounds(items, item):
    """ Binary search bracketing indices.

    Parameters
    ----------
    items : list
        Ascending sorted items.
    item : comparable object

    Returns
    -------
    [lower, upper) half-open indices
    """
    n_1 = len(items) - 1
    if n_1 < 0:
        return None, None
    if item <= items[0]:
        return 0, 0
    if item >= items[-1]:
        return n_1, n_1
    left, right = 0, n_1
    while left <= right:
        mid = int((left + right) / 2)
        if items[mid] == item:
            break
        elif items[mid] < item:
            left = mid + 1
        else:
            right = mid - 1
    if right < left:
        left = right
    else:
        left = mid
    right = min(n_1, left + 1)
    if items[left] <= item and item <= items[right]:
        return left, right
    else:
        return None, None


@classmethod
def callback_hash_tag_name_attribute_name_value_consitency(cls, element,
    hashpipe, children=True):
    """
        calculate hash over tag, attribute_names, attribute_values

        :param element: etree.element
        :param hashpipe: hash algorithm interface
        :param children: bool - if false children of element ignored for hash calculation
        """
    _element_childes = element.getchildren()
    if children:
        for child in _element_childes:
            hashpipe.update(cls.
                callback_hash_tag_name_attribute_name_value_consitency(
                child, hashpipe))
    hashpipe.update(bytes(str(element.tag) + '#tag', 'utf-8'))
    if hasattr(element, 'attrib'):
        for _name in sorted(element.attrib.keys()):
            _value = element.attrib[_name]
            hashpipe.update(bytes(_name + _value + '#att', 'utf-8'))
    return bytes(hashpipe.hexdigest(), 'utf-8')


def action_sanitize():
    """Make action suitable for use as a Pose Library

    """
    pass


def __iter__():
    """Return iterator of factory keys.
        """


def write_zeros(fileobj, count, block_size=8194):
    """ Write `count` zero bytes to `fileobj`

    Parameters
    ----------
    fileobj : file-like object
        with ``write`` method
    count : int
        number of bytes to write
    block_size : int, optional
        largest continuous block to write.
    """
    nblocks = int(count // block_size)
    rem = count % block_size
    blk = b'\x00' * block_size
    for bno in range(nblocks):
        fileobj.write(blk)
    fileobj.write(b'\x00' * rem)


def unitvector(ctx, n, i):
    """
        Return the i-th n-dimensional unit vector.
        """
    assert 0 < i <= n, 'this unit vector does not exist'
    return [ctx.zero] * (i - 1) + [ctx.one] + [ctx.zero] * (n - i)


def dotted_cdr(p: str) ->str:
    """ Return the rightmost node of path p
    :param p: path
    :return: rightmost dot separated nodp

    >>> dotted_cdr("A1.b2.c3")
    'c3'

    >>> dotted_cdr("abc")
    'abc'

    >>> dotted_cdr("a1.b2.")
    ''

    >>> dotted_cdr(".a")
    'a'

    >>> dotted_cdr(".")
    ''

    >>> dotted_cdr('')
    ''

    """
    return p if '.' not in p else p.rsplit('.', 1)[1]


def bisect(rlo, rhi, acc, tol, fun, **kwargs):
    """
        Performs a bisection search.

        **Input**:
            - fun -- a function such that fun(r)==True iff x_0>r, where x_0 is the value to be found.
    """
    while rhi - rlo > acc:
        r = 0.5 * (rhi + rlo)
        if kwargs:
            isvalid = fun(r, tol, **kwargs)
        else:
            isvalid = fun(r, tol)
        if isvalid:
            rlo = r
        else:
            rhi = r
    return rlo


def ghost_curves_create():
    """Create snapshot (Ghosts) of selected F-Curves as background aid for active Graph Editor

    """
    pass


def execute(interactive: bool=False):
    """Execute the current console line as a python expression

    :param interactive: interactive
    :type interactive: bool
    """
    pass


def getMonthAbbreviations():
    """Return a list of month abbreviations."""


def xlwings_dims_call_spec():
    """A list :term:`call-spec` for :meth:`_redim_filter` :term:`filter` that imitates results of *xlwings* library."""
    return '["redim", [0, 1, 1, 1, 2]]'


def freestyle_modifier_remove():
    """Remove the modifier from the list of modifiers

    """
    pass


def output_value(output, fail_on_err=False):
    """Returns the value of the command output"""
    stdout, stderr = output.communicate()
    if output.returncode == 0:
        return stdout
    elif fail_on_err:
        raise ValueError(stderr)
    else:
        return stderr


def im_func(method):
    """ Gets the function from the method in both Python 2 and 3. """
    return getattr(method, 'im_func', method)


def invert(interval):
    """Invert an interval.

    Example:
    >>> invert(['C', 'E'])
    ['E', 'C']
    """
    interval.reverse()
    res = list(interval)
    interval.reverse()
    return res


def tag_list_to_dict(tags_list):
    """Convert Boto3-style key-value tags list into dict"""
    tags_dict = {}
    for tag in tags_list:
        if 'key' in tag:
            tags_dict[tag['key']] = tag['value']
        elif 'Key' in tag:
            tags_dict[tag['Key']] = tag['Value']
    return tags_dict


def create_detops(header, DMS=False, read_mode=None, nint=None, ngroup=None,
    detector=None, wind_mode=None, xpix=None, ypix=None, x0=None, y0=None,
    nff=None):
    """Detector class from header

    Create a detector class based on header settings.
    Can override settings with a variety of keyword arguments.

    Parameters
    ----------
    header : obj
        Header from NIRCam FITS file
    DMS : bool
        Is header format from Data Management Systems? Otherwises, ISIM-like.

    Keyword Args
    ------------
    read_mode : str
        NIRCam Ramp Readout mode such as 'RAPID', 'BRIGHT1', etc.
    nint : int
        Number of integrations (ramps).
    ngroup : int
        Number of groups in a integration.
    detector : int, str
        NIRCam detector ID (481-490) or SCA ID (A1-B5).
    wind_mode : str
        Window mode type 'FULL', 'STRIPE', 'WINDOW'.
    xpix : int
        Size of window in x-pixels for frame time calculation.
    ypix : int
        Size of window in y-pixels for frame time calculation.
    x0 : int
        Lower-left x-coord position of detector window.
    y0 : int
        Lower-left y-coord position of detector window.
    nff : int
        Number of fast row resets.

    """
    detector = header['SCA_ID'] if detector is None else detector
    xpix = header['SUBSIZE1'] if DMS else header['NAXIS1'
        ] if xpix is None else xpix
    ypix = header['SUBSIZE2'] if DMS else header['NAXIS2'
        ] if ypix is None else ypix
    if x0 is None:
        x1 = header['SUBSTRT1'] if DMS else header['COLCORNR']
        x0 = x1 - 1
    if y0 is None:
        y1 = header['SUBSTRT2'] if DMS else header['ROWCORNR']
        y0 = y1 - 1
    if wind_mode is None:
        if DMS:
            if 'FULL' in header['SUBARRAY']:
                wind_mode = 'FULL'
            elif 'GRISM' in header['SUBARRAY']:
                wind_mode = 'STRIPE'
            else:
                wind_mode = 'WINDOW'
        elif not header['SUBARRAY']:
            wind_mode = 'FULL'
        elif 'DISABLE' in header['HWINMODE']:
            wind_mode = 'STRIPE'
        else:
            wind_mode = 'WINDOW'
    if DMS:
        hnames = ['READPATT', 'NINTS', 'NGROUPS']
    else:
        hnames = ['READOUT', 'NINT', 'NGROUP']
    read_mode = header[hnames[0]] if read_mode is None else read_mode
    nint = header[hnames[1]] if nint is None else nint
    ngroup = header[hnames[2]] if ngroup is None else ngroup
    ma_args = {'read_mode': read_mode, 'nint': nint, 'ngroup': ngroup}
    from pynrc.pynrc_core import DetectorOps
    return DetectorOps(detector, wind_mode, xpix, ypix, x0, y0, nff, **ma_args)


@staticmethod
def can_access():
    """See pyams_utils.interfaces.form.IDataManager"""
    return True


def is_tool(name):
    """Check whether `name` is on PATH and marked as executable."""
    from shutil import which
    return which(name) is not None


@classmethod
def from_rv_discrete(cls, ssrv, prng=None):
    """
        Create a ScalarDistribution from a scipy.states.rv_discrete instance.

        Parameters
        ----------
        ssrv : scipy.stats.rv_discrete
            The random variable to convert to a dit.ScalarDistribution.
        prng : RandomState
            A pseudo-random number generator with a `rand` method which can
            generate random numbers. For now, this is assumed to be something
            with an API compatibile to NumPy's RandomState class. If `None`,
            then we initialize to dit.math.prng.

        Returns
        -------
        d : ScalarDistribution
            A ScalarDistribution representation of `ssrv`.
        """
    outcomes = ssrv.xk
    pmf = ssrv.pk
    prng = prng if prng is not None else ssrv.random_state
    return cls(outcomes, pmf, prng=prng)


def call_graphivz_script(script):
    """Shows a graph using dot and eog."""
    from tempfile import NamedTemporaryFile
    from subprocess import Popen, PIPE
    dotcmd = ['dot', '-Tpng']
    dotproc = Popen(dotcmd, stdin=PIPE, stdout=PIPE)
    out, err = dotproc.communicate(script)
    if out:
        with NamedTemporaryFile(suffix='.png') as tmpf:
            tmpf.write(out)
            tmpf.flush()
            Popen(['eog', tmpf.name]).wait()


def None_Omit(Input_Str):
    """
    Replace None object with "None" string.

    :param Input_Str: input string
    :type Input_Str : str
    :return: modified string as str
    """
    result = Input_Str
    result = result.replace('None', '"None"')
    return result


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

        :param TeamMergeRequestSentShownToSecondaryTeamDetails val:
        :rtype: EventDetails
        """
    return cls('team_merge_request_sent_shown_to_secondary_team_details', val)


def cache_inc(key, value=1, expires=None, cache=None):
    """Increments the specified key value by the specified value.

    * http://uwsgi.readthedocs.io/en/latest/Changelog-1.9.9.html#math-for-cache

    :param str|unicode key:

    :param int value:

    :param int expires: Expire timeout (seconds).

    :param str|unicode cache: Cache name with optional address (if @-syntax is used).

    :rtype: bool
    """
    return False


def command_ping(util, _):
    """ Handler for command ping """
    return util.ping()


def modify_val(val, modify_by=0.0, should_modify=True, upper_lim=1, lower_lim=0
    ):
    """Modify a value and check its range."""
    if should_modify:
        val = val + modify_by
    if val > upper_lim:
        return upper_lim
    elif val < lower_lim:
        return lower_lim
    else:
        return val


@classmethod
def epoch_ms_to_dttm(cls) ->str:
    """
        SQL expression that converts epoch (milliseconds) to datetime that can be used
        in a query.

        :return: SQL Expression
        """
    return cls.epoch_to_dttm().replace('{col}', '({col}/1000)')


def _assert_input_is_valid(input_value, validators, validated_func, input_name
    ):
    """
    Called by the `validating_wrapper` in the first step (a) `apply_on_each_func_args` for each function input before
    executing the function. It simply delegates to the validator. The signature of this function is hardcoded to
    correspond to `apply_on_each_func_args`'s behaviour and should therefore not be changed.

    :param input_value: the value to validate
    :param validators: the Validators that will be applied on input_value_to_validate
    :param validated_func: the function for which this validation is performed. This is not used, since the Validator
        knows it already, but we should not change the signature here.
    :param input_name: the name of the function input that is being validated
    :return: Nothing
    """
    for validator in validators:
        validator.assert_valid(input_name, input_value)


def _insert_rst_epilog(c):
    """Insert the rst_epilog variable into the configuration.

    This should be applied after other configurations so that the epilog can
    use other configuration variables.
    """
    c['rst_epilog'] = (
        """
.. |eups-tag| replace:: {eups_tag}
.. |eups-tag-mono| replace:: ``{eups_tag}``
.. |eups-tag-bold| replace:: **{eups_tag}**
    """
        .format(eups_tag=c['release_eups_tag']))
    return c


def _fullmatch_greedy(r, s):
    """Check if regex object r fully matches string s
    In Python 3 this is done by calling r.fullmatch()
    In Python 2 this is done by comparing the length of the matched substring to that of s.
    Therefore, equivalence is only guaranteed on regex without non-greedy operators.
    """
    try:
        return bool(r.fullmatch(s))
    except:
        m = r.match(s)
        return m and m.end() == len(s)


@classmethod
def get_news_from_most_recent_issue(cls):
    """Returns the news stories from the most recently published
        issue of the newsletter.
        """
    issue = cls.get_most_recently_published_issue()
    news_section = None
    if issue:
        for section in issue.sections.all():
            if section.name.lower() == 'news':
                news_section = section
                break
    if news_section:
        news_stories = news_section.posts.order_by('-pub_date')
    else:
        news_stories = None
    return news_stories


def _validate_float(s, accept_none=False):
    """
	A validation method to convert input s to float or raise error if it is not convertable
	"""
    if s is None and accept_none:
        return None
    try:
        return float(s)
    except ValueError:
        raise ValueError('Could not convert "%s" to float' % s)


def skip_redundant(iterable, skipset=None):
    """Redundant items are repeated items or items in the original skipset."""
    if skipset is None:
        skipset = set()
    for item in iterable:
        if item not in skipset:
            skipset.add(item)
            yield item


def format_git_describe(git_str, pep440=False):
    """format the result of calling 'git describe' as a python version"""
    if git_str is None:
        return None
    if '-' not in git_str:
        return git_str
    else:
        git_str = git_str.replace('-', '.post', 1)
        if pep440:
            return git_str.split('-')[0]
        else:
            return git_str.replace('-g', '+git')


def circle(target, pore_diameter='pore.diameter'):
    """
    Calculate cross-sectional area assuming the pore body is a circle

    Only suitable for true 2D simulations

    Parameters
    ----------
    target : OpenPNM Geometry Object
        The Geometry object which this model is associated with. This controls
        the length of the calculated array, and also provides access to other
        necessary geometric properties.

    pore_diameter : string
        The dictionary key of the array on the Geometry object containing the
        pore diameter values necessary to find the area.

    """
    return target[pore_diameter]


def is_nil(xs):
    """Checks if the input value is null or undefined"""
    return xs is None


def assert_trigger(library, session, protocol):
    """Asserts software or hardware trigger.

    Corresponds to viAssertTrigger function of the VISA library.

    :param library: the visa library wrapped by ctypes.
    :param session: Unique logical identifier to a session.
    :param protocol: Trigger protocol to use during assertion. (Constants.PROT*)
    :return: return value of the library call.
    :rtype: :class:`pyvisa.constants.StatusCode`
    """
    return library.viAssertTrigger(session, protocol)


@staticmethod
def header(line, width):
    """
        Gets the header string.

        :param line:
            The line of text.
        :param width:
            Width of the output.

        :return:
            The header string.
        """
    length = len(line)
    left = (width - length) // 2
    right = width - length - left
    return ' ' * left + line + ' ' * right


def scroll_page(up: bool=False):
    """Scroll page up or down

    :param up: Up, Scroll up one page
    :type up: bool
    """
    pass


def itemindex(l):
    """itemindex(l) -> dict of item : index of item

    Make an index of the items in the list.  The dictionary contains
    the items in the list as the keys, and the index of the first
    occurrence of the item as the value.
    Adapted from BioPython.
    """
    dict = {}
    for i in range(len(l)):
        if l[i] not in dict:
            dict[l[i]] = i
    return dict


def defaultToNoneOrValue(value, default=''):
    """Convert a value to NoneType if it matches a default.

    Parameters
    ----------
    value : anything
        The value to possibly convert.
    default : anything, optional
        The default to check if NoneType return is necessary.

    Returns
    -------
    anything
        The converted value.
    """
    return None if value == default else value


@staticmethod
def load(filename: str):
    """Load and return an instance from the file `filename`

Parameters
----------
filename : str
    a path for the file to be loaded
        """
    import pickle
    with open(filename, 'rb') as f:
        obj = pickle.load(f)
    obj._stopwords = lambda x: False
    return obj


def try_pop(d, key, default):
    """
    >>> d = {"a": "b", "c": "d", "e": "f"}
    >>> try_pop(d, "g", "default")
    'default'
    >>> d
    {'a': 'b', 'c': 'd', 'e': 'f'}
    >>> try_pop(d, "c", "default")
    'd'
    >>> d
    {'a': 'b', 'e': 'f'}
    """
    value = d.get(key, default)
    if key in d:
        d.pop(key)
    return value


def __iter__():
    """Return an iteration on the ids"""


@classmethod
def export_single_profile(cls, clusters, cf_fpath, irp=0, fpath_out=None,
    key=None, forecast_fpath=None):
    """Get a single representative profile timeseries dataframe.

        Parameters
        ----------
        clusters : pd.DataFrame
            Single DataFrame with (gid, gen_gid, cluster_id, rank).
        cf_fpath : str
            reV generation output file.
        irp : int
            Rank of profile to get. Zero is the most representative profile.
        fpath_out : str
            Optional filepath to export files to.
        key : str | None
            Rank column to sort by to get the best ranked profile.
            None will use implicit logic to select the rank key.
        forecast_fpath : str
            reV generation output file for forecast data. If this is input,
            profiles will be taken from forecast fpath instead of fpath gen
            based on a NN mapping.
        """
    rp = cls(clusters, cf_fpath, key=key, forecast_fpath=forecast_fpath)
    cols = clusters.cluster_id.unique()
    if rp.key == 'rank_included_trg':
        for itrg, df in rp.clusters.groupby('trg'):
            if fpath_out is not None:
                fpath_out_trg = fpath_out.replace('.csv', '_trg{}.csv'.
                    format(itrg))
            rp._get_rep_profile(df, cf_fpath, irp=irp, fpath_out=
                fpath_out_trg, key=rp.key, forecast_fpath=rp.
                _forecast_fpath, cols=cols)
    else:
        rp._get_rep_profile(rp.clusters, cf_fpath, irp=irp, fpath_out=
            fpath_out, key=rp.key, forecast_fpath=rp._forecast_fpath, cols=cols
            )


def file_extension(path):
    """Get the file extension of a path/filename."""
    return path.split('/')[-1].split('.')[-1]


def get_rms_bq(var):
    """
    Return the RMS base quality at this position
    """
    return var.INFO.get('BQ')


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 rank_gufunc(x):
    """ Returns ranked data along specified dimension """
    import bottleneck
    ranks = bottleneck.nanrankdata(x, axis=-1)
    ranks = ranks[..., 0]
    return ranks


def bit_on(num: int, bit: int) ->int:
    """Return the value of a number's bit position.

    For example, since :math:`42 = 2^1 + 2^3 + 2^5`,
    this function will return 1 in bit positions 1, 3, 5:

    >>> [bit_on(42, i) for i in range(clog2(42))]
    [0, 1, 0, 1, 0, 1]
    """
    return num >> bit & 1


@staticmethod
def build_connection_name(connection):
    """
        Build a connections full name based on the module/name of the function.

        :param connection: connection
        :return: connection path
        """
    return '.'.join([connection.__module__, connection.__name__])


def isValidTPV(tpv):
    """Is this a valid TPV code?
    """
    tpv = tpv.lstrip('QR-Code:')
    if len(tpv) != len('EETTTTPPVVOCCCCCC'):
        return False
    return tpv.isnumeric()


def my_layout(G):
    """For grafer fra make_cliques der koden ligger i de to første tallene"""
    pos = dict()
    for i in G.nodes():
        x = i.split()[0]
        pos[i] = int(x[0]), int(x[1])
    return pos


def serialize(obj, with_help=False, with_defaults=True):
    """
  Return a serializable representation of the object. If the object has an
  `as_dict` method, then it will call and return the output of that method.
  Otherwise return the object itself.
  """
    if hasattr(obj, 'as_odict'):
        fun = getattr(obj, 'as_odict')
        if callable(fun):
            return fun(with_help=with_help, with_defaults=with_defaults)
    if hasattr(obj, 'as_dict'):
        fun = getattr(obj, 'as_dict')
        if callable(fun):
            return fun(with_help=with_help, with_defaults=with_defaults)
    return obj


def reverse(dna_sequence):
    """simple string reversal"""
    return dna_sequence[::-1]


@classmethod
def connect_sqlite(cls, database=':memory:', **kwargs):
    """
        Initializes a SQLite connection to the given database.

        @param database -- the name of the database file to connect to (default database in RAM)
        """
    import sqlite3
    connection = sqlite3.connect(database=database, **kwargs)
    c = connection.cursor()
    return cls(connection, c)


def fractional_parameter(fractional_parameter, parameter2):
    """
    Defines fractional parameter link where the original parameter ranges
    between 0-1 of parameter2.

    Parameters
    ----------
    fractional_parameter : string
        new parameter that ranges between 0 and 1.
    parameter2 : string
        parameter that is larger or equal than the original parameter
    """
    return fractional_parameter * parameter2


def tags_in_context(context, get=None):
    """Fetch the unique tags within a context

    Parameters
    ----------
    context : str
        The context to obtain tags from.

    Returns
    -------
    set
        The set of sample identifers within a context.

    Raises
    ------
    ValueError
        If the requested context is not known.

    Redis Command Summary
    ---------------------
    SMEMBERS <context>:samples-represented
    """
    import redbiom
    import redbiom._requests
    import redbiom.util
    if get is None:
        config = redbiom.get_config()
        get = redbiom._requests.make_get(config)
    redbiom._requests.valid(context, get)
    obs = get(context, 'SMEMBERS', 'samples-represented')
    _, _, tags, _ = redbiom.util.partition_samples_by_tags(obs)
    return set(tags)


def alternator(*items):
    """Returns a generator that yields the supplied arguments as a repeating sequence."""
    i = 0
    while 1:
        yield items[i % len(items)]
        i += 1


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

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

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

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

    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 normalize_key(key):
    """key -> normalized key"""


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

    The ".dev0" means dirty.

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


def offset_slice(pixels1, pixels2, i, j):
    """Return two sliced arrays where the first slice is offset by i,j
    relative to the second slice.
    """
    if i < 0:
        height = min(pixels1.shape[0] + i, pixels2.shape[0])
        p1_imin = -i
        p2_imin = 0
    else:
        height = min(pixels1.shape[0], pixels2.shape[0] - i)
        p1_imin = 0
        p2_imin = i
    p1_imax = p1_imin + height
    p2_imax = p2_imin + height
    if j < 0:
        width = min(pixels1.shape[1] + j, pixels2.shape[1])
        p1_jmin = -j
        p2_jmin = 0
    else:
        width = min(pixels1.shape[1], pixels2.shape[1] - j)
        p1_jmin = 0
        p2_jmin = j
    p1_jmax = p1_jmin + width
    p2_jmax = p2_jmin + width
    p1 = pixels1[p1_imin:p1_imax, p1_jmin:p1_jmax]
    p2 = pixels2[p2_imin:p2_imax, p2_jmin:p2_jmax]
    return p1, p2


def _change_name(curr_name: str, context: str) ->str:
    """
    Function to add descriptive tags to Tensor name, after the tensor is modified.
    Currently handles Lorentz Transformation and Config Changes.

    Parameters
    ----------
    curr_name : str
            Current name of the tensor
    context : str
            Context of name change - '__lt', for lorentz_transformation
                                   - '__' + newconfig, for config_change (cc)
    Returns
    -------
    str
        Altered name of the tensor, with appropriate tags

    """
    return curr_name + context if curr_name is not None else None


def parse_module(mod):
    """
    Collect AST objects from a python module
    """
    keys = dir(mod)
    assert 'AST' in keys
    asts = getattr(mod, 'AST')
    if type(asts) != dict:
        asts = {mod.__name__: asts}
    return asts


def _normalize_row_probability(x):
    """Ensure the state transition matrix rows sum to 1
    """
    return x / x.sum(axis=1, keepdims=True)


def is_user_context(context):
    """Indicates if the request context is a normal user."""
    if not context:
        return False
    if context.is_admin:
        return False
    if not context.user_id or not context.project_id:
        return False
    return True


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 add_VAR_DESC(cdf):
    """
    add the VAR_DESC global attribute constructed from variable names found in the file

    :param object cdf: netCDF file object
    """
    varkeys = cdf.variables.keys()
    dimkeys = cdf.dimensions.keys()
    varnames = []
    for key in varkeys:
        varnames.append(key)
    dimnames = []
    for key in dimkeys:
        dimnames.append(key)
    buf = ''
    for varname in varnames:
        if varname not in dimnames:
            buf = '%s:%s' % (buf, varname)
    cdf.VAR_DESC = buf


def set_option(name, value):
    """
    Set package option

    Parameters
    ----------
    name : str
        Name of the option
    value : object
        New value of the option

    Returns
    -------
    old : object
        Old value of the option
    """
    d = globals()
    if name in {'get_option', 'set_option'} or name not in d:
        from ..exceptions import PlotnineError
        raise PlotnineError('Unknown option {}'.format(name))
    old = d[name]
    d[name] = value
    return old


def report_name(root):
    """
    Function returns scan report name.
    :param root: root element of scan file tree
    :return: scan report name
    """
    name = root.find('Report').get('name')
    return name


def __toarray(X):
    """ Converts DataFrames to numpy arrays.
    """
    if hasattr(X, 'values'):
        X = X.values
    return X


def normalize_response_value(rv):
    """ Normalize the response value into a 3-tuple (rv, status, headers)
        :type rv: tuple|*
        :returns: tuple(rv, status, headers)
        :rtype: tuple(Response|JsonResponse|*, int|None, dict|None)
    """
    status = headers = None
    if isinstance(rv, tuple):
        rv, status, headers = rv + (None,) * (3 - len(rv))
    return rv, status, headers


def save_mxnet_model(model, prefix, epoch=0):
    """Save the model as MXNet model. Creates MXNet symbol and params file.

    The saved model can be used to load in MXNet engine for inference. Can be used to perform
    inference on any language bindings supported by MXNet.

    Note: data_names and data_shapes required in MXNet represent input layer name and shape.
    When you call save_mxnet_model, these information will be printed.
    You can change the first dimension of data_shapes to match batch size for inference.

    Below sample code shows how to load a Keras-MXNet pre-trained model saved with 'prefix',
    input name as '/dense_1_input1' and inference batch size of 1 and data shape of 784.

    ```python
    >>> import mxnet as mx
    >>> sym, arg_params, aux_params = mx.model.load_checkpoint(prefix, epoch=0)
    ##  data_names and data_shapes will be print
    >>> mod = mx.mod.Module(symbol=sym, data_names=['/dense_1_input1'],                             context=mx.cpu(), label_names=None)
    >>> mod.bind(for_training=False, data_shapes=[('/dense_1_input1', (1,784))],                  label_shapes=mod._label_shapes)
    >>> mod.set_params(arg_params, aux_params, allow_missing=True)
    ##  Prepare data iterator
    >>> data_iter = mx.io.NDArrayIter(data, label=None, batch_size=1)
    ##  Predict
    >>> result = mod.predict(data_iter)
    ```

    # Arguments
        model: Keras model instance to be saved as MXNet model.
        prefix: Prefix name of the saved Model (symbol and params) files.
                Model will be saved as '<prefix>-symbol.json' and '<prefix>-<epoch>.params'.
        epoch: (Optional) Tag the params file with epoch of the model being saved. Default is 0.
               Model params file is saved as '<prefix>-<epoch>.params' or '<prefix>-0000.params' by default.

    # Returns
        data_names, data_shapes

    # Raises
        AssertionError if Model is not compiled.
    """
    assert model is not None, 'MXNet Backend: Invalid state. Model cannot be None.'
    if not model.compiled:
        raise AssertionError(
            'MXNet Backend: Model is not compiled. Cannot save the MXNet model!'
            )
    symbol = model._pred_mxnet_symbol
    module = model._module
    assert symbol is not None, 'MXNet Backend: Invalid state. MXNet Symbol cannot be None.'
    assert module is not None, 'MXNet Backend: Invalid state. MXNet Module cannot be None.'
    pred_module = module._buckets['pred']
    data_names = pred_module.data_names
    data_shapes = pred_module.data_shapes
    symbol_fname = '%s-symbol.json' % prefix
    params_fname = '%s-%04d.params' % (prefix, epoch)
    symbol.save(symbol_fname)
    module.save_params(params_fname)
    print('MXNet Backend: Successfully exported the model as MXNet model!')
    print('MXNet symbol file - ', symbol_fname)
    print('MXNet params file - ', params_fname)
    print('\n\nModel input data_names and data_shapes are: ')
    print('data_names : ', data_names)
    print('data_shapes : ', data_shapes)
    print(
        """

Note: In the above data_shapes, the first dimension represent the batch_size used for model training. """
        )
    print(
        'You can change the batch_size for binding the module based on your inference batch_size.'
        )
    return data_names, data_shapes


def get_lomb_amplitude_ratio(lomb_model, i):
    """
    Get the ratio of the amplitudes of the first harmonic for the ith and first
    frequencies from a fitted Lomb-Scargle model.
    """
    return lomb_model['freq_fits'][i - 1]['amplitude'][0] / lomb_model[
        'freq_fits'][0]['amplitude'][0]


def aCommon():
    """Return a string representing the object's value in the
        format: Mar 1, 1997 1:45 pm"""


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


def dpad_downright_heading(controller):
    """
    Callback function that is triggered, when the direction down right was pressed

    :param controller:              the controller that triggered the action
    :type controller:               steuer.Controller
    """
    print('DIRECTION:' + str(controller.number) + ':' + controller.name +
        ':DPAD Down Right heading')


@classmethod
def connect(cls, array1, array2):
    """
        Create a new LensConnect from the combination of multiple
        """
    return cls(*array1.lenses, *array2.lenses)


def header_line(length, border='-'):
    """Return header of length"""
    return border * length


@classmethod
def get_by_name(cls, context, name):
    """Find a node based on name and return a Node object.

        :param cls: the :class:`Node`
        :param context: Security context
        :param name: the logical name of a node.
        :returns: a :class:`Node` object.
        """
    db_node = cls.dbapi.get_node_by_name(name)
    node = cls._from_db_object(context, cls(), db_node)
    return node


def lambd_NH3_S_CB89(T, P):
    """n-a: ammonia sulfide [CB89]."""
    lambd = 0.174
    valid = T == 298.15
    return lambd, valid


def client(args):
    """Start a client connects to the gateway"""
    from ..clients.python import PyClient
    PyClient(args)


def set_safe_paths(list_of_paths):
    """ Set list of safe writeable paths """
    global _SAFE_PATHS
    _SAFE_PATHS = list_of_paths


@classmethod
def for_grammar(cls, g):
    """ Create a parser for the Grammar in g """
    p = cls()
    p.init_from_grammar(g)
    return p


def get_title(reg_doc):
    """ Extract the title of the regulation. """
    parent = reg_doc.xpath('self::PART/HD|.//PART/HD')[0]
    title = parent.text
    return title


@classmethod
def _from_et(cls, root, parent):
    """
        Create a :class:`Library` from a :code:`library` element.

        :param root: The element tree tree to parse.
        :param parent: :class:`EagleFilePart` that should hold the resulting :class:`EagleFilePart`
        :rtype: :class:`Library`
        """
    n = cls()
    n._init_from_et(root, parent)
    return n


def hide_render_clear():
    """Reveal the render object by setting the hide render flag

    """
    pass


def matches(event):
    """Return a list of subscriptions that match the given event.

        :param event: a `NotificationEvent`
        :return: a list of tuples (class, distributor, sid, authenticated,
                 address, format, priority, adverb), where small `priority`
                 values override larger ones and `adverb` is either
                 'always' or 'never'.
        """


def number2currency(value, decimals=2, sign='$'):
    """Format number as currency money with thousand separator, 2 decimals."""
    number, decimal = ('%%.%df' % decimals % value).split('.')
    parts = []
    while len(number) > 3:
        part, number = number[-3:], number[:-3]
        parts.append(part)
    parts.append(number)
    parts.reverse()
    if int(decimal) == 0:
        currency_money = ','.join(parts) + sign
    else:
        currency_money = ','.join(parts) + '.' + decimal + sign
    return currency_money


def estimate():
    """Estimate running time of upgrade in seconds (optional)."""
    return 1


def reorder_title(title, articles=('the',), separators=(',', ', ')):
    """
    Reorder the title
    :param title:
    :type title:
    :param articles:
    :type articles:
    :param separators:
    :type separators:
    :return:
    :rtype:
    """
    ltitle = title.lower()
    for article in articles:
        for separator in separators:
            suffix = separator + article
            if ltitle[-len(suffix):] == suffix:
                return title[-len(suffix) + len(separator):] + ' ' + title[:
                    -len(suffix)]
    return title


def kMedoids(similarityMatrix, initialCentroids=None, k=None):
    """Algorithm that clusters any dataset based on a similarity matrix
    Either the initialCentroids or k are passed"""
    pass


def underride(d, **options):
    """Add key-value pairs to d only if key is not in d.

    d: dictionary
    options: keyword args to add to d

    :return: modified d
    """
    for key, val in options.items():
        d.setdefault(key, val)
    return d


@classmethod
def get_by_id(cls, id):
    """Given an integer ID, fetch the record from fulfil.io"""
    return cls(values=cls.rpc.read([id], tuple(cls._eager_fields))[0])


def p_global_param_flag_value(p):
    """ global_param_flag_value : ON
                                | OFF
                                | TRUE
                                | FALSE
    """
    p[0] = p[1]


def set_rng(new_rng):
    """Set the package-level random number generator.

    Parameters
    ----------
    new_rng : ``numpy.random`` or a :class:`numpy.random.RandomState` instance
        The random number generator to use.
    """
    global _rng
    _rng = new_rng


def split_mantissa_exponent(v, format_spec='.8g'):
    """
    Given a number, split it into its mantissa and base 10 exponent
    parts, each as strings.  If the exponent is too small, it may be
    returned as the empty string.

    Parameters
    ----------
    v : float

    format_spec : str, optional
        Number representation formatting string

    Returns
    -------
    mantissa, exponent : tuple of strings
    """
    x = format(v, format_spec).split('e')
    if x[0] != '1.' + '0' * (len(x[0]) - 2):
        m = x[0]
    else:
        m = ''
    if len(x) == 2:
        ex = x[1].lstrip('0+')
        if len(ex) > 0 and ex[0] == '-':
            ex = '-' + ex[1:].lstrip('0')
    else:
        ex = ''
    return m, ex


def psi_Ca_HCO3_SO4_HMW84(T, P):
    """c-a-a': calcium bicarbonate sulfate [HMW84]."""
    psi = 0.0
    valid = T == 298.15
    return psi, valid


def get_classes(class_name):
    """get_classes(class_name) -> class_object_list : cast new type class only"""
    cls_list = []
    import gc
    import inspect
    for obj in gc.get_objects():
        try:
            if getattr(obj, '__class__', None):
                if inspect.isclass(obj) and obj.__name__ == class_name:
                    cls_list.append(obj)
        except ReferenceError:
            continue
    return cls_list


def __call_permissive__(context, request):
    """ Guaranteed-permissive version of __call__ """


def setmaxsize(value):
    """Set the default maximum size for arrays without using core memory."""
    global NX_MAXSIZE
    NX_MAXSIZE = value


def in_p4(t: float) ->float:
    """
    quartic ease-in function

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


@staticmethod
def p_ref_group_optional_list_optional(p):
    """ref_group_optional_list_optional : empty
                                            | ref_group_optional_list"""
    p[0] = tuple() if p[1] is None else p[1]


def split_email(s, h):
    """Given a sender email s and a HELO domain h, create a valid tuple
    (l, d) local-part and domain-part.

    Examples:
    >>> split_email('', 'wayforward.net')
    ('postmaster', 'wayforward.net')

    >>> split_email('foo.com', 'wayforward.net')
    ('postmaster', 'foo.com')

    >>> split_email('terry@wayforward.net', 'optsw.com')
    ('terry', 'wayforward.net')
    """
    if not s:
        return 'postmaster', h
    else:
        parts = s.split('@', 1)
        if parts[0] == '':
            parts[0] = 'postmaster'
        if len(parts) == 2:
            return tuple(parts)
        else:
            return 'postmaster', s


def to_enum_value(ival, enum_class, fallback, starter=-1):
    """
    convert the integer argument to the corresponding
    enumerator value on the given enumeration, if feasible,
    or the fallback value otherwise.
    """
    rmap = dict(enumerate(enum_class, starter))
    return rmap.get(ival, fallback)


def prody_contacts(**kwargs):
    """Identify contacts of a target structure with one or more ligands.
    Contacting atoms (or extended subset of atoms, such as residues) are
    outputted in PDB file format.

    :arg target: target PDB identifier or filename

    :arg ligand: ligand PDB identifier(s) or filename(s)

    :arg select: atom selection string for target structure

    :arg radius: contact radius (Å), default is ``4.0``

    :arg extend: output same ``'residue'``, ``'chain'``, or ``'segment'`` along
        with contacting atoms

    :arg prefix: prefix for output file, default is *target* filename

    :arg suffix: output filename suffix, default is *ligand* filename"""
    import prody
    LOGGER = prody.LOGGER
    target = prody.parsePDB(kwargs['target'])
    title = kwargs.get('prefix') or target.getTitle()
    selstr = kwargs.get('select')
    if selstr:
        target = target.select(selstr)
    contacts = prody.Contacts(target)
    suffix = kwargs.get('suffix', '_contacts')
    extend = kwargs.get('extend')
    radius = float(kwargs.get('radius', 4.0))
    ligands = kwargs.get('ligand')
    if len(ligands) > 1:
        outfn = lambda fn: title + suffix + '_' + fn + '.pdb'
    else:
        outfn = lambda fn: title + suffix + '.pdb'
    for pdb in ligands:
        ligand = prody.parsePDB(pdb)
        sel = contacts(radius, ligand)
        if sel:
            LOGGER.info('{0} atoms from {1} contact {2}.'.format(len(sel),
                pdb, str(target)))
            if extend:
                sel = target.select('same ' + extend + ' as sel', sel=sel)
                LOGGER.info(
                    'Selection is extended to {0} atoms of the same {1}(s).'
                    .format(len(sel), extend))
            pdbfn = outfn(ligand.getTitle())
            LOGGER.info('Writing contacts into ' + pdbfn)
            prody.writePDB(pdbfn, sel)


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

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

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

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

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

    """
    pass


@classmethod
def head_by_id(cls, session, resource_id, path_args=None):
    """Get an object representing the headers of a remote resource.

        :param session: The session to use for making this request.
        :type session: :class:`~ecl.session.Session`
        :param resource_id: This resource's identifier, if needed by
                            the request.
        :param dict path_args: A dictionary of arguments to construct
                               a compound URL.
                               See `How path_args are used`_ for details.

        :return: A :class:`Resource` representing the headers.
        :raises: :exc:`~ecl.exceptions.MethodNotSupported` if
                 :data:`Resource.allow_head` is not set to ``True``.
        """
    data = cls.head_data_by_id(session, resource_id, path_args=path_args)
    return cls.existing(**data)


def calculate_new_length(gene_split, gene_results, hit):
    """ Function for calcualting new length if the gene is split on several
   contigs
   """
    first = 1
    for split in gene_split[hit['sbjct_header']]:
        new_start = int(gene_results[split]['sbjct_start'])
        new_end = int(gene_results[split]['sbjct_end'])
        if first == 1:
            new_length = int(gene_results[split]['HSP_length'])
            old_start = new_start
            old_end = new_end
            first = 0
            continue
        if new_start < old_start:
            new_length = new_length + (old_start - new_start)
            old_start = new_start
        if new_end > old_end:
            new_length = new_length + (new_end - old_end)
            old_end = new_end
    return new_length


def run_topology(jar_path, configs):
    """Subcommand specific run logic."""
    raise NotImplementedError


def _adjust_n_months(other_day, n, reference_day):
    """Adjust the number of times a monthly offset is applied based
    on the day of a given date, and the reference day provided.
    """
    if n > 0 and other_day < reference_day:
        n = n - 1
    elif n <= 0 and other_day > reference_day:
        n = n + 1
    return n


@classmethod
def put_unique(cls, item, **kwargs):
    """Put a single item into the table for this model, with a unique attribute constraint on the hash key

        :param dict item: The item to put into the table
        :param \\*\\*kwargs: All other kwargs are passed through to the put_unique method on the table
        """
    return cls.Table.put_unique(cls.Schema.dynamorm_validate(item), **kwargs)


def expand_dicts(dicts, key, values):
    """Expand and return the dicts with all values for the key.

    For each dict in dicts and each value in values, a new dict is generated.
    This new dict contains all entries from the original one as well
    as a mapping from key to value.
    If a value is None, a copy of the original dict is added.
    Overall, len(dicts)*len(values) dicts are generated and returned.

    Parameters
    ----------
    dicts: list
        List of dictionaries to expand
    key: str
        Key of the entry to be added to each dict
    values: list
        List of values to be added to each dict
    """
    expanded = []
    for old in dicts:
        for value in values:
            if value is not None:
                expanded.append({**old, key: value})
            else:
                expanded.append({**old})
    return expanded


def STR_LEN_BYTES(expression):
    """
    Returns the number of UTF-8 encoded bytes in the specified string.
    https://docs.mongodb.com/manual/reference/operator/aggregation/strLenBytes/
    for more details
    :param expression: The string or expression of the string
    :return: Aggregation operator
    """
    return {'$strLenBytes': expression}


def nodes_iter(G):
    """Return an iterator over the graph nodes."""
    return G.nodes_iter()


def addIndex(indexDef):
    """
        Adds the index to the class.
        """


def get():
    """Return the TG of the context"""


def u(string: str) ->bytes:
    """Shortcut to encode string to bytes."""
    return string.encode('utf8')


def set_arctic_settings(clock_params, settings):
    """Set the settings for the arctic clocking routine"""
    clock_params.well_depth = settings.well_depth
    clock_params.n_iterations = settings.niter
    clock_params.express = settings.express
    clock_params.n_levels = settings.n_levels
    clock_params.charge_injection = settings.charge_injection_mode
    clock_params.readout_offset = settings.readout_offset


def to_actual(point, origin):
    """
    Get the actual coordinates of a point defined relative to another
    """
    actual_point = ()
    if len(point) != len(origin):
        raise ValueError
    for i, axis in enumerate(point):
        actual_point += axis + origin[i],
    return actual_point


def output():
    """
    'name' is required, should be lowercase alphanumeric and _
    'type' is required, see https://docs.demyst.com/apis/gateway/types/ for acceptable type values.
    """
    return [{'name': 'output_field_example', 'type': 'String',
        'description':
        'An example of how to list the outputs of the data function',
        'sample': 'blue'}]


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 ft_ln(data, i, cols, rel=0, *args, **kwargs):
    """Generates a context feature based on the length of the value the
    `form` column.

    :param data: data
    :type: np.recarray
    :param i: focus position
    :type i: int
    :param cols: column map
    :type cols: dict
    :param rel: relative position of context features
    :type rel: int
    :return: feature
    :rtype: str
    """
    ln = None
    if 0 <= i + rel < len(data):
        ln = len(data[i + rel][cols['form']])
    return 'ln[%s]=%s' % (str(rel), ln)


def zeropad(num, largest):
    """Return a zero-padded string of a number, given the largest number.

    TODO: want to support floating-point numbers as well? Or rename function
    accordingly.

    Parameters
    ----------
    num : int
        The number to be formatted with zeros padding on the left.
    largest : int
        The number that determines the number of zeros to pad with.

    Returns
    -------
    padded : str
        The original number, `num`, formatted as a string with zeros added
        on the left.

    """
    num_digits = len('{:.0f}'.format(largest))
    padded = '{0:0{width}}'.format(num, width=num_digits)
    return padded


def _get_bytearray_from_array(src: 'typing.Iterable[bytes]') ->bytearray:
    """Get bytearray from array of bytes blocks.

    :param src: source to process
    :type src: typing.List[bytes]
    :return: bytearray
    :rtype: bytearray
    """
    return bytearray(b''.join(src))


def get_projecthoneypot_ip_lookup_url(ip):
    """
    Returns the ProjectHoneyPot.org URL to lookup information relating to an IP
    """
    return 'https://www.projecthoneypot.org/ip_{0}'.format(ip)


def set_bit(f, offset):
    """
    sets the bit at an offset
    """
    mask = 1 << offset
    return f | mask


def load_handlers(name):
    """Load the (URL pattern, handler) tuples for each component."""
    mod = __import__(name, fromlist=['default_handlers'])
    return mod.default_handlers


def getMeasure(unique_name):
    """Returns a IMeasure in the cube with the given unique name."""


def get_schema():
    """Schema structure of this resource

    :return: schema dictionary
    :rtype: dict
    """
    return {'schema': {'schema_version': {'type': 'integer', 'default': 1},
        'action': {'schema_version': 1, 'title': 'Action', 'comment':
        'Use "add" to add a new acknowledge, or "delete" to delete an acknowledge'
        , 'type': 'string', 'default': 'add', 'allowed': ['add', 'delete']},
        'host': {'schema_version': 1, 'title': 'Host', 'comment':
        'The host concerned by the acknowledge.', 'type': 'objectid',
        'data_relation': {'resource': 'host', 'embeddable': True},
        'required': True}, 'service': {'schema_version': 1, 'title':
        'Service', 'comment': 'The service concerned by the acknowledge.',
        'type': 'objectid', 'data_relation': {'resource': 'service',
        'embeddable': True}, 'required': True, 'nullable': True}, 'user': {
        'schema_version': 1, 'title': 'User', 'comment':
        'The user concerned by the acknowledge.', 'type': 'objectid',
        'data_relation': {'resource': 'user', 'embeddable': True},
        'required': True}, 'comment': {'schema_version': 1, 'title':
        'Comment', 'comment':
        'The comment of the acknowledge action. Free text.', 'type':
        'string', 'default': ''}, 'processed': {'schema_version': 1,
        'title': 'Processed', 'comment':
        'The action has been set on the host/service by Alignak and it can be considered as effective if processed is True'
        , 'type': 'boolean', 'default': False}, 'notified': {
        'schema_version': 1, 'title': 'Notified', 'comment':
        'The action has been fetched by the Alignak arbiter if notified is True but it is not yet to be considered as an effective scheduled downtime'
        , 'type': 'boolean', 'default': False}, 'sticky': {'schema_version':
        1, 'title': 'Sticky', 'comment':
        'If the sticky option is set, the acknowledgement will remain until the host/service recovers. Otherwise the acknowledgement will automatically be removed when the host/service state changes.'
        , 'type': 'boolean', 'default': True}, 'notify': {'schema_version':
        1, 'title': 'Notify', 'comment':
        'If the notify option is set, a notification will be sent out to contacts indicating that the current host/service problem has been acknowledged, else there will be no notification.'
        , 'type': 'boolean', 'default': False}, 'persistent': {
        'schema_version': 1, 'title': 'Persistent', 'comment':
        'Alignak always consider an acknowledge as persistent. Thus this property is of no importance and it will be removed in a future version.'
        , 'type': 'boolean', 'default': True}, '_realm': {'schema_version':
        1, 'title': 'Realm', 'comment':
        'Realm this element belongs to. Note that this property will always be forced to the value of the concerned host realm.'
        , 'type': 'objectid', 'data_relation': {'resource': 'realm',
        'embeddable': True}}, '_sub_realm': {'schema_version': 1, 'title':
        'Sub-realms', 'comment':
        'Is this element visible in the sub-realms of its realm?', 'type':
        'boolean', 'default': True}, '_users_read': {'schema_version': 1,
        'type': 'list', 'schema': {'type': 'objectid', 'data_relation': {
        'resource': 'user', 'embeddable': True}}}}, 'schema_deleted': {}}


def render_pep440_pre(pieces):
    """TAG[.post.devDISTANCE] -- No -dirty.

    Exceptions:
    1: no tags. 0.post.devDISTANCE
    """
    if pieces['closest-tag']:
        rendered = pieces['closest-tag']
        if pieces['distance']:
            rendered += '.post.dev%d' % pieces['distance']
    else:
        rendered = '0.post.dev%d' % pieces['distance']
    return rendered


def _remove_reserved_attributes(attributes):
    """
    Removes elog reserved attributes (from the attributes dict) that can not be sent.

    :param attributes: dictionary of attributes to be cleaned.
    :return:
    """
    if attributes:
        attributes.get('$@MID@$', None)
        attributes.pop('Date', None)
        attributes.pop('Attachment', None)
        attributes.pop('Text', None)


@staticmethod
def _add_debugging_fields(gelf_dict, record):
    """Add debugging fields to the given ``gelf_dict``

        :param gelf_dict: Dictionary representing a GELF log.
        :type gelf_dict: dict

        :param record: :class:`logging.LogRecord` to extract debugging
            fields from to insert into the given ``gelf_dict``.
        :type record: logging.LogRecord
        """
    gelf_dict.update({'file': record.pathname, 'line': record.lineno,
        '_function': record.funcName, '_pid': record.process,
        '_thread_name': record.threadName})
    pn = getattr(record, 'processName', None)
    if pn is not None:
        gelf_dict['_process_name'] = pn


def u2_get_ui_obj(d, resourceId=None, resourceIdMatches=None, text=None,
    textContains=None, textMatches=None, textStartsWith=None, className=
    None, classNameMatches=None, description=None, descriptionContains=None,
    descriptionMatches=None, descriptionStartsWith=None, packageName=None,
    packageNameMatches=None, checkable: bool=False, checked: bool=False,
    clickable: bool=False, longClickable: bool=False, scrollable: bool=
    False, enabled: bool=False, focusable: bool=False, focused: bool=False,
    selected: bool=False, index: int=0, instance: int=0):
    """
    u2获取指定UI元素对象(因为用u2编码时没有参数提示)
        note: (参数默认值可从 from uiautomator2.session import Selector查看)
    :return: UiObject (from uiautomator2.session import UiObject) eg: ele: UiObject = u2_get_ui_obj(d=d, resourceId='xxxx') 来调用后续方法
    """
    kwargs = {}
    if resourceId is not None:
        kwargs.update({'resourceId': resourceId})
    if resourceIdMatches is not None:
        kwargs.update({'resourceIdMatches': resourceIdMatches})
    if text is not None:
        kwargs.update({'text': text})
    if textContains is not None:
        kwargs.update({'textContains': textContains})
    if textMatches is not None:
        kwargs.update({'textMatches': textMatches})
    if textStartsWith is not None:
        kwargs.update({'textStartsWith': textStartsWith})
    if className is not None:
        kwargs.update({'className': className})
    if classNameMatches is not None:
        kwargs.update({'classNameMatches': classNameMatches})
    if description is not None:
        kwargs.update({'description': description})
    if descriptionContains is not None:
        kwargs.update({'descriptionContains': descriptionContains})
    if descriptionMatches is not None:
        kwargs.update({'descriptionMatches': descriptionMatches})
    if descriptionStartsWith is not None:
        kwargs.update({'descriptionStartsWith': descriptionStartsWith})
    if packageName is not None:
        kwargs.update({'packageName': packageName})
    if packageNameMatches is not None:
        kwargs.update({'packageNameMatches': packageNameMatches})
    if checkable:
        kwargs.update({'checkable': checkable})
    if checked:
        kwargs.update({'checked': checked})
    if clickable:
        kwargs.update({'clickable': clickable})
    if longClickable:
        kwargs.update({'longClickable': longClickable})
    if scrollable:
        kwargs.update({'scrollable': scrollable})
    if enabled:
        kwargs.update({'enabled': enabled})
    if focusable:
        kwargs.update({'focusable': focusable})
    if focused:
        kwargs.update({'focused': focused})
    if selected:
        kwargs.update({'selected': selected})
    if index != 0:
        kwargs.update({'index': index})
    if instance != 0:
        kwargs.update({'instance': instance})
    return d(**kwargs)


def dropSpans(spans, text):
    """
    Drop from text the blocks identified in :param spans:, possibly nested.
    """
    spans.sort()
    res = ''
    offset = 0
    for s, e in spans:
        if offset <= s:
            if offset < s:
                res += text[offset:s]
            offset = e
    res += text[offset:]
    return res


def clear_session(request, *names):
    """
    Removes values for the given session variables names
    if they exist.
    """
    for name in names:
        try:
            del request.session[name]
        except KeyError:
            pass


def safe_enc(inp):
    """Limit the output to ascii to prevent
       encoding errors when output to console"""
    return inp.encode('ascii', errors='ignore').decode('ascii')


def fuzzy_row_key(rdata, col):
    """
    Lookup correct index using closest col name.
    If the col has trailing Nones, these are ignored
    return -- key
    """
    try:
        col = col[:col.index(None)]
    except ValueError:
        pass
    if len(col) == 1:
        col = col[0]
    return col


def two_sum(a, b):
    """
    Add ``a`` and ``b`` exactly, returning the result as two float64s.
    The first is the approximate sum (with some floating point error)
    and the second is the error of the float64 sum.

    Using the procedure of Shewchuk, 1997,
    Discrete & Computational Geometry 18(3):305-363
    http://www.cs.berkeley.edu/~jrs/papers/robustr.pdf

    Returns
    -------
    sum, err : float64
        Approximate sum of a + b and the exact floating point error
    """
    x = a + b
    eb = x - a
    ea = x - eb
    eb = b - eb
    ea = a - ea
    return x, ea + eb


def is_naive(dt):
    """Determines if a given datetime.datetime is naive."""
    return dt.tzinfo is None or dt.tzinfo.utcoffset(dt) is None


def _a_encode_long(value, mapping):
    """
    42 --> ('2', 'J', '42')
    """
    assert isinstance(value, int) and not isinstance(value, int
        ), 'VALUE has invalid type: %s' % type(value)
    value = str(value).encode('UTF-8')
    return str(len(value)).encode('UTF-8'), b'J', value


def points_to_weights(point_values):
    """Convert a list of point values to a list of fractional weights.
       The return value at index i is the fraction that point_values[i]
       represents of the sum of point_values."""
    s = sum(point_values)
    if not s:
        return [float('NaN') for p in point_values]
    return [(float(p) / s) for p in point_values]


def file_len(fname):
    """
    count number of lines in file
    copy-pasted from http://stackoverflow.com/questions/845058/how-to-get-line-count-cheaply-in-python
    """
    with open(fname) as f:
        for i, l in enumerate(f):
            pass
    return i + 1


def write(dictionary, serializer=None):
    """
        Write a dictionary to the appropriate destination.

        @note: This method is thread-safe.

        @param serializer: Either C{None}, or a
            L{eliot._validation._MessageSerializer} which can be used to
            validate this message.

        @param dictionary: The message to write out. The given dictionary
             will not be mutated.
        @type dictionary: C{dict}
        """


def _check_cmd(cmd_list):
    """Sanity check of the commands in 'cmd_list'"""
    for cmd in cmd_list:
        assert 'jobs' not in cmd
        assert 'cmd' in cmd
        assert 'label' in cmd


def t_CPP_COMMENT1(t):
    """(/\\*(.|\\n)*?\\*/)"""
    ncr = t.value.count('\n')
    t.lexer.lineno += ncr
    t.type = 'CPP_WS'
    t.value = '\n' * ncr if ncr else ' '
    return t


def emotionV(frequencyVec, scoreVec):
    """Given the frequency vector and the score vector, compute the happs.

    Doesn't use numpy, but equivalent to `np.dot(freq,happs)/np.sum(freq)`."""
    tmpSum = sum(frequencyVec)
    if tmpSum > 0:
        happs = 0.0
        for i in range(len(scoreVec)):
            happs += frequencyVec[i] * float(scoreVec[i])
        happs = float(happs) / float(tmpSum)
        return happs
    else:
        return -1


def refresh(root, extension):
    """Refresh the extension in root.
        """


def head(filepath, N):
    """ Retrieve the first N lines of a file.

    >>> from mlib._doctest import repo_path
    >>> filepath = repo_path()+"/doctest_working/workfile.txt"
    >>> with open(filepath,"w") as f: f.write("\\n".join(["Line %d"%i for i in range(100)]))
    789

    >>> print(head(filepath, 1))
    Line 0
    <BLANKLINE>

    >>> print(head(filepath, 10))
    Line 0
    Line 1
    Line 2
    Line 3
    Line 4
    Line 5
    Line 6
    Line 7
    Line 8
    Line 9
    <BLANKLINE>

    >>> rm(filepath)

    """
    try:
        with open(filepath) as f:
            return ''.join([next(f) for x in range(N)])
    except StopIteration:
        with open(filepath) as f:
            return f.read()


def find_src_root(metadata):
    """
    Determine source root from src_root or package_dir key.
    Replace package_dir in metadata with src_root.
    Only understands a single root.
    """
    src_root = ''
    if 'package_dir' in metadata:
        try:
            src_root = metadata['package_dir']['']
            del metadata['package_dir']
        except KeyError:
            raise ValueError(
                'Need package_dir mapping "" to a single directory')
    elif 'src_root' in metadata:
        src_root = metadata['src_root']
    metadata['src_root'] = src_root or ''
    return src_root


def pytest_addoption(parser):
    """
    Pytest hook - register command line arguments. We want to register the
    --func_cov argument to explicitly pass the location of the package to
    discover and the ignore_func_names ini setting.

    Args:
        parser:
    """
    group = parser.getgroup('func_cov')
    group.addoption('--func_cov', dest='func_cov_source', action='append',
        default=[], metavar='SOURCE', nargs='?', const=True)
    parser.addini('ignore_func_names', 'function names to ignore',
        'linelist', [])


def get(cls, name):
    """Get a registered task function for a given name."""
    try:
        task_func = cls._registry[name]
    except KeyError:
        raise ValueError('{} not found in registry for {}'.format(name, cls
            .__name__))
    else:
        return task_func


def assign_exit_code(fit_succeeded, gulp_errors, parser_errors):
    """ given the error messages, assign an exit code """
    if '**** No. of variables exceeds no. of observables ****' in gulp_errors:
        return 'ERROR_NOT_ENOUGH_OBSERVABLES'
    elif '**** No lower sum of squares could be found ****' in gulp_errors:
        return 'ERROR_FIT_UNSUCCESFUL'
    elif not fit_succeeded:
        return 'ERROR_FIT_UNSUCCESFUL'
    elif gulp_errors:
        return 'ERROR_GULP_UNKNOWN'
    elif parser_errors:
        return 'ERROR_PARSING_STDOUT'
    return None


def bin2dec(x):
    """Convert ``x``, an array of "bits" (MSB first), to it's decimal value."""
    bits = []
    bits.extend(x)
    bits.reverse()
    multi = 1
    value = 0
    for b in bits:
        value += b * multi
        multi *= 2
    return value


def set_bit(value, index, new_bit):
    """ Set the index'th bit of value to new_bit, and return the new value.
    :param value:   The integer to set the new_bit in
    :type value:    int
    :param index: 0-based index
    :param new_bit: New value the bit shall have (0 or 1)
    :return:    Changed value
    :rtype: int
    """
    mask = 1 << index
    value &= ~mask
    if new_bit:
        value |= mask
    return value


def _generate_windows_body(hooks):
    """Generate Windows specific functions.

    At the moment it implements load_impls_from_library, class destructor, and an utility function
    to convert from utf8 to wide-strings so we can use the wide family of windows
    functions that accept unicode.
    """
    result = ['public:', f'    ~HookCaller() {{',
        f'        for (auto handle : this->handles) {{',
        f'            FreeLibrary(handle);', f'        }}', f'    }}']
    result += [
        f'    void load_impls_from_library(const std::string& utf8_filename) {{'
        ,
        f'        std::wstring w_filename = utf8_to_wstring(utf8_filename);',
        f'        auto handle = LoadLibraryW(w_filename.c_str());',
        f'        if (handle == NULL) {{',
        f'            throw std::runtime_error("Error loading library " + utf8_filename + ": " + std::to_string(GetLastError()));'
        , f'        }}', f'        this->handles.push_back(handle);', '']
    for index, hook in enumerate(hooks):
        result += [
            f'        auto p{index} = GetProcAddress(handle, "{hook.function_name}");'
            , f'        if (p{index} != nullptr) {{',
            f'            this->append_{hook.name}_impl((uintptr_t)(p{index}));'
            , f'        }}', '']
    result.append('    }')
    result += ['', '', 'private:',
        f'    std::wstring utf8_to_wstring(const std::string& s) {{',
        f'        int flags = 0;',
        f'        int required_size = MultiByteToWideChar(CP_UTF8, flags, s.c_str(), -1, nullptr, 0);'
        , f'        std::wstring result;',
        f'        if (required_size == 0) {{',
        f'            return result;', f'        }}',
        f'        result.resize(required_size);',
        f'        int err = MultiByteToWideChar(CP_UTF8, flags, s.c_str(), -1, &result[0], required_size);'
        , f'        if (err == 0) {{',
        f'            // error handling: https://docs.microsoft.com/en-us/windows/desktop/api/stringapiset/nf-stringapiset-multibytetowidechar#return-value'
        , f'            switch (GetLastError()) {{',
        f'                case ERROR_INSUFFICIENT_BUFFER: throw std::runtime_error("utf8_to_wstring: ERROR_INSUFFICIENT_BUFFER");'
        ,
        f'                case ERROR_INVALID_FLAGS: throw std::runtime_error("utf8_to_wstring: ERROR_INVALID_FLAGS");'
        ,
        f'                case ERROR_INVALID_PARAMETER: throw std::runtime_error("utf8_to_wstring: ERROR_INVALID_PARAMETER");'
        ,
        f'                case ERROR_NO_UNICODE_TRANSLATION: throw std::runtime_error("utf8_to_wstring: ERROR_NO_UNICODE_TRANSLATION");'
        ,
        f'                default: throw std::runtime_error("Undefined error: " + std::to_string(GetLastError()));'
        , f'            }}', f'        }}', f'        return result;',
        f'    }}', f'', f'', f'private:', f'    std::vector<HMODULE> handles;']
    return result


def keyconfig_test():
    """Test key-config for conflicts

    """
    pass


def ExportInstance(r, instance, mode, destination, shutdown=None,
    remove_instance=None, x509_key_name=None, destination_x509_ca=None):
    """
    Exports an instance.

    @type instance: string
    @param instance: Instance name
    @type mode: string
    @param mode: Export mode
    @rtype: string
    @return: Job ID
    """
    body = {'destination': destination, 'mode': mode}
    if shutdown is not None:
        body['shutdown'] = shutdown
    if remove_instance is not None:
        body['remove_instance'] = remove_instance
    if x509_key_name is not None:
        body['x509_key_name'] = x509_key_name
    if destination_x509_ca is not None:
        body['destination_x509_ca'] = destination_x509_ca
    return r.request('put', '/2/instances/%s/export' % instance, content=body)


def _getReplyResults():
    """ Return the ZCatalog results that represent this object's replies.

        o XXX: Huh?

        o Often, the actual objects are not needed.  This is less expensive
          than fetching the objects.

        o Permission: View
        """


def _round_and_pad(value, decimals):
    """
    Round the input value to `decimals` places, and pad with 0's
    if the resulting value is less than `decimals`.

    :param value:
        The value to round
    :param decimals:
        Number of decimals places which should be displayed after the rounding.
    :return:
        str of the rounded value
    """
    if isinstance(value, int) and decimals != 0:
        value = float(value)
    elif decimals == 0:
        return repr(int(round(value, decimals)))
    rounded = repr(round(value, decimals))
    rounded += '0' * (decimals - len(rounded.split('.')[1]))
    return rounded


def _extract_spotinst_access_token(definition: dict):
    """
    extract the provided access token
    """
    return definition['Mappings']['Senza']['Info']['SpotinstAccessToken']


def parse_presentation_logfile(in_file, con_names, con_codes, con_design=
    None, con_duration=None, pulsecode=30):
    """
    Function-interface for PresentationLogfileCrawler. Can be used to create
    a Nipype node.

    Parameters
    ----------
    in_file : str or list
        Absolute path to logfile (can be a list of paths).
    con_names : list
        List with names for each condition
    con_codes : list
        List with codes for conditions. Can be a single integer or string (in
        the latter case, it may be a substring) or a list with possible values.
    con_design : list or str
        Which 'design' to assume for events (if 'multivar', all events -
        regardless of condition - are treated as a separate
        condition/regressor; if 'univar', all events from a single condition
        are treated as a single condition). Default: 'univar' for all
        conditions.
    con_duration : list
        If the duration cannot be parsed from the logfile, you can specify them
        here manually (per condition).
    pulsecode : int
        Code with which the first (or any) pulse is logged.
    """
    from skbold.exp_model import PresentationLogfileCrawler
    plc = PresentationLogfileCrawler(in_file=in_file, con_names=con_names,
        con_codes=con_codes, con_design=con_design, con_duration=
        con_duration, pulsecode=pulsecode, write_bfsl=True, verbose=False)
    subject_info_files = plc.parse()
    return subject_info_files


def subdirectories(work_directory, subdirectory_prefix):
    """ Return subdirectories of current work directory"""
    pass


@classmethod
def register(cls, name):
    """Register an item with the importer.

        :param name:
        """
    cls._community_modules.append(name)


def parse_font_awesome_icon(option):
    """
    Function that parses an argument related to the `icon` and `description`
    properties of `ipywidgets.Button`. If the provided option is an `str` that
    starts with `fa-`, then a font-awesome icon is assumed.

    Parameters
    ----------
    option : `str` or ``None``
        The selected `description` option.

    Returns
    -------
    icon : `str` or ``None``
        The selected icon option.
    description : `str` or ``None``
        The selected description option.
    """
    if option is None:
        icon = description = None
    elif len(option) > 3 and option[:3] == 'fa-':
        icon = option
        description = ''
    else:
        icon = None
        description = option
    return icon, description


def _check_is_max_context(doc_spans, cur_span_index, position):
    """Check if this is the 'max context' doc span for the token."""
    best_score = None
    best_span_index = None
    for span_index, doc_span in enumerate(doc_spans):
        end = doc_span.start + doc_span.length - 1
        if position < doc_span.start:
            continue
        if position > end:
            continue
        num_left_context = position - doc_span.start
        num_right_context = end - position
        score = min(num_left_context, num_right_context
            ) + 0.01 * doc_span.length
        if best_score is None or score > best_score:
            best_score = score
            best_span_index = span_index
    return cur_span_index == best_span_index


def if_match(node, kv_map):
    """判断某个节点是否包含所有传入参数属性
       node: 节点
       kv_map: 属性及属性值组成的map"""
    for key in kv_map:
        if node.get(key) != kv_map.get(key):
            return False
    return True


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


def get_mode(filename):
    """Returns the mode of a file, which can be used to determine if a file
       exists, if a file is a file or a directory.
    """
    import os
    try:
        return os.stat(filename)[0]
    except OSError:
        return 0


def dict_has_value(dict_, key):
    """Return True if the key is contained in the dict.

    Parameters
    ----------
    dict_: dict
        Dict to check in
    key: str
        Key to check
    """
    return key in dict_


def _create_tile_list(xs, ys, level, grid_size):
    """
    Returns an iterator tile_coords for the given tile ranges (`xs` and `ys`).
    If the one tile_coord is negative or out of the `grid_size` bound,
    the coord is None.
    """
    x_limit = grid_size[0]
    y_limit = grid_size[1]
    for y in ys:
        for x in xs:
            if x < 0 or y < 0 or x >= x_limit or y >= y_limit:
                yield None
            else:
                yield x, y, level


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

        :returns: this backend does not supports entries resuming
        """
    return False


def logLogisticCDF(x, alpha, beta, omga):
    """ x : non-negative  data series
      Cumulative distribution function of a three parameter Log-logistic distributin  (Fisk distribution)
        scale=.1
        shape=3
        loc=5
        x=7
        logLogisticCDF(x,scale, shape,loc)
        0.9998750156230471"""
    return 1 / (1 + pow(alpha / (x - omga), beta))


def Byte(value):
    """Encode a single byte"""
    return bytes((value,))


def turbulent_Sieder_Tate(Re, Pr, mu=None, mu_w=None):
    """Calculates internal convection Nusselt number for turbulent flows
    in pipe according to [1]_ and supposedly [2]_.

    .. math::
        Nu = 0.027Re^{4/5}Pr^{1/3}\\left(\\frac{\\mu}{\\mu_s}\\right)^{0.14}

    Parameters
    ----------
    Re : float
        Reynolds number, [-]
    Pr : float
        Prandtl number, [-]
    mu : float
        Viscosity of fluid, [Pa*s]
    mu_w : float
        Viscosity of fluid at wall temperature, [Pa*s]

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

    Notes
    -----
    A linear coefficient of 0.023 is often listed with this equation. The
    source of the discrepancy is not known. The equation is not present in the
    original paper, but is nevertheless the source usually cited for it.

    Examples
    --------
    >>> turbulent_Sieder_Tate(Re=1E5, Pr=1.2)
    286.9178136793052
    >>> turbulent_Sieder_Tate(Re=1E5, Pr=1.2, mu=0.01, mu_w=0.067)
    219.84016455766044

    References
    ----------
    .. [1] Rohsenow, Warren and James Hartnett and Young Cho. Handbook of Heat
       Transfer, 3E. New York: McGraw-Hill, 1998.
    .. [2] Sieder, E. N., and G. E. Tate. "Heat Transfer and Pressure Drop of
       Liquids in Tubes." Industrial & Engineering Chemistry 28, no. 12
       (December 1, 1936): 1429-35. doi:10.1021/ie50324a027.
    """
    Nu = 0.027 * Re ** 0.8 * Pr ** (1 / 3.0)
    if mu_w and mu:
        Nu *= (mu / mu_w) ** 0.14
    return Nu


@classmethod
def from_gs(cls, graphics):
    """Creates a new FillState from a ColoredState object."""
    ret = cls()
    ret.color = graphics.fill_color
    return ret


@staticmethod
def heartbeat():
    """Update member status to indicate it is still alive.

        Method to run once in a while to be sure that the member is not dead
        and is still an active member of a group.

        :return: The number of seconds to wait before sending a new heartbeat.
        """
    pass


def is_numlike(obj):
    """ Return True if `obj` looks like a number
    """
    try:
        obj + 1
    except:
        return False
    return True


def p_foreach_optional_arg(p):
    """foreach_optional_arg : empty
                            | DOUBLE_ARROW foreach_variable"""
    if len(p) == 3:
        p[0] = p[2]


def roundAndCut(number, ndigits=8, threshold=1e-08):
    """ round a number to ndigits digits and set it to zero if its absolute
        value is below threshold
    """
    if abs(number) < threshold:
        return 0.0
    else:
        return round(number, ndigits)


def det3x3(matrix):
    """return the determinant of a 3x3 matrix"""
    positive = matrix[0, 0] * matrix[1, 1] * matrix[2, 2] + matrix[0, 1
        ] * matrix[1, 2] * matrix[2, 0] + matrix[0, 2] * matrix[1, 0] * matrix[
        2, 1]
    minus = matrix[2, 0] * matrix[1, 1] * matrix[0, 2] + matrix[2, 1] * matrix[
        1, 2] * matrix[0, 0] + matrix[2, 2] * matrix[1, 0] * matrix[0, 1]
    return positive - minus


def _phase(repo, subset, *targets):
    """helper to select all rev in <targets> phases"""
    return repo._phasecache.getrevset(repo, targets, subset)


def search_in_list_of_dict_by_key_value(d_list, key, value):
    """Search a specific value of a certain key in a list of dictionary.
    Returns the index of first matching index item in the list or -1 if not found"""
    for idx, dic in enumerate(d_list):
        if dic.get(key) == value:
            return idx
    return -1


def pgettext_tip(msgid: str, msgctxt: str):
    """Try to translate the given msgid (with optional msgctxt), if tooltips’ translation is enabled.

    :param msgid: The string to translate.
    :type msgid: str
    :param msgctxt: The translation context (defaults to BLT_I18NCONTEXT_DEFAULT).
    :type msgctxt: str
    :return:  The translated string (or msgid if no translation was found).
    """
    pass


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

    The ".dev0" means dirty.

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


@classmethod
def is_compatible(cls, model, device='CPU', **kwargs):
    """
         This function will gradually grow to cover more cases.
         Need to be careful of false negatives. There are some cases that seemingly
         are not supported on CoreML, which the graph transformer optimizes and converts to
         a graph that can be converted to CoreML.

         1. Check whether the layers for which CoreML expects constant weights are in
            the list of initializers in the onnx graph
         2. unsupported ops like "And", "Or" etc

         """
    node_set = set()
    initializer_set = set()
    graph = model.graph
    for t in graph.initializer:
        initializer_set.add(t.name)
    for node in graph.node:
        if node.op_type in ['ConvTranspose', 'Conv', 'BatchNormalization',
            'InstanceNormalization', 'PRelu']:
            if len(node.input) > 1 and node.input[1] not in initializer_set:
                return False
        node_set.add(node.op_type)
    for node in graph.node:
        if node.op_type in ['Cast', 'And', 'Or', 'Xor', 'Not', 'Less',
            'Greater', 'Equal', 'Ceil', 'Floor']:
            return False
    return True


@staticmethod
def dispatch(circuit, name):
    """
        Return requested function so it can be then
        called in `classify` method and proccessed respectively.
        """
    return getattr(circuit._session, name)


@classmethod
def from_stat(cls, st):
    """
        Create from something isomorphic to FakeStat (such as a FakeStat
        or a real stat).
        """
    return cls(st_mode=st.st_mode, st_nlink=st.st_nlink, st_mtime=st.
        st_mtime, st_ctime=st.st_ctime, st_atime=st.st_atime, st_ino=st.
        st_ino, st_size=st.st_size, st_uid=st.st_uid, st_gid=st.st_gid,
        st_rdev=st.st_rdev)


def __listafy(argument):
    """make argument a list if it is not"""
    if not isinstance(argument, list):
        argument = [argument]
    return argument


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

        :param EndedEnterpriseAdminSessionDeprecatedDetails val:
        :rtype: EventDetails
        """
    return cls('ended_enterprise_admin_session_deprecated_details', val)


def batch_slice(index: int, batch_size: int) ->slice:
    """Return slice corresponding to given index for given batch_size.

    Parameters
    ---------------
    index: int,
        Index corresponding to batch to be rendered.
    batch_size: int
        Batch size for the current Sequence.

    Returns
    ---------------
    Return slice corresponding to given index for given batch_size.
    """
    return slice(index * batch_size, (index + 1) * batch_size)


def target_glucose_value(percent_effect_duration, min_value, max_value):
    """ Computes a target glucose value for a correction, at a given time
        during the insulin effect duration

    Arguments:
    percent_effect_duration -- percent of time elapsed of the insulin
                               effect duration
    min_value -- minimum (starting) target value
    max_value -- maximum (starting) target value

    Output:
    A target value somewhere between the minimum and maximum (inclusive)
    """
    use_min_value_until_percent = 0.5
    if percent_effect_duration <= use_min_value_until_percent:
        return min_value
    if percent_effect_duration >= 1:
        return max_value
    slope = (max_value - min_value) / (1 - use_min_value_until_percent)
    return min_value + slope * (percent_effect_duration -
        use_min_value_until_percent)


@classmethod
def remove_hostgroup(cls, options=None):
    """Disassociate a hostgroup"""
    cls.command_sub = 'remove-hostgroup'
    return cls.execute(cls._construct_command(options))


def context_set_enum(data_path: str='', value: str=''):
    """Set a context value

    :param data_path: Context Attributes, RNA context string
    :type data_path: str
    :param value: Value, Assignment value (as a string)
    :type value: str
    """
    pass


def _clean_input(comma_string):
    """Clean comma separated option inputs in CLI"""
    return list(map(lambda term: term.strip(' '), comma_string.split(',')))


def psi_Mg_Na_Cl_HMW84(T, P):
    """c-c'-a: magnesium sodium chloride [HMW84]."""
    psi = -0.012
    valid = T == 298.15
    return psi, valid


def find_wrapper(haystack, needle_uuid):
    """Finds the corresponding wrapper from a list given the UUID.

    :param haystack:  A list of wrappers.  Usually generated from a 'feed' that
                      has been loaded via the wrapper's wrap(response) method.
    :param needle_uuid: The UUID of the object to find in the list.
    :return: The corresponding wrapper for that UUID.  If not found, None.
    """
    for wrapper in haystack:
        if wrapper.uuid == needle_uuid:
            return wrapper
    return None


@classmethod
def for_diff(cls, diff):
    """
        Determines what type of diff this represents
        """
    if diff.new_file:
        return cls.A
    elif diff.deleted_file:
        return cls.D
    elif diff.renamed:
        return cls.R
    elif diff.a_blob and diff.b_blob and diff.a_blob != diff.b_blob:
        return cls.M
    return cls.U


def authenticate(req):
    """Return the name of the remote user, or `None` if the identity of the
        user is unknown."""


def mk_lst(values, unlst=False):
    """
    while iterating through several type of lists and items it is convenient to
    assume that we recieve a list, use this function to accomplish this. It also
    convenient to be able to return the original type after were done with it.
    """
    if type(values) != list and not unlst:
        values = [values]
    if unlst:
        if type(values) == list:
            if len(values) == 1:
                values = values[0]
    return values


def getid(obj):
    """Return id if argument is a Resource.

    Abstracts the common pattern of allowing both an object or an object's ID
    (UUID) as a parameter when dealing with relationships.
    """
    try:
        if obj.uuid:
            return obj.uuid
    except AttributeError:
        pass
    try:
        return obj.id
    except AttributeError:
        return obj


def _get_replacements(tokens, data, sec):
    """Helper function for _read_config. """
    replacements = list()
    for token in tokens:
        if ':' in token:
            tsec, tkey = token.split(':')
            tval = ''
            if tsec in data:
                if tkey in data[tsec]:
                    tval = data[tsec][tkey]
        elif token in data[sec]:
            tval = data[sec][token]
        else:
            tval = ''
        replacements.append(('${%s}' % token, tval))
    return replacements


def isplit(string, sep='\t\n\x0b\x0c\r '):
    """ Returns an iterator over string.split().
        This is efficient in combination with cooccurrence(),
        since the string may be very long (e.g., Brown corpus).
    """
    a = []
    for ch in string:
        if ch not in sep:
            a.append(ch)
            continue
        if a:
            yield ''.join(a)
            a = []
    if a:
        yield ''.join(a)


def _search_status(rdict, doc, status):
    """Includes the relevant entries from `doc` in the resulting `rdict` only
    if the status matches.

    .. warning:: `rdict` is modified by this function.
    """
    if status is None or status == 'issued':
        rdict['issued'] = doc.get('issuance_history')
    if status is None or status == 'revoked':
        rdict['revoked'] = doc.get('revocation_history')
    if status is None or status == 'active':
        rdict['active'] = doc.get('grants')


def colorToTuple(color):
    """Coverts a color object to a tuple RGB tuple representing the color."""
    return color.Red(), color.Green(), color.Blue()


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

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


def get_boolean(message, default=True):
    """ Get a yes/no input from the user, prompting them with a message.

    Returns:
        input (boolean): True or False depending on the user's input
    """
    if not isinstance(default, bool):
        raise TypeError('Default must be a boolean')
    result = input('{} ({}): '.format(message, 'no' if not default else 'yes'))
    if not result:
        return default
    result = result.strip().lower()
    return result in ('yes', 'y')


def weekly_cull(dir_to_cull: list) ->list:
    """Take a list of snapshots from a directory (already reduced to one day) and cull.

        This culling will return a list with the snapshots to remove for the given day.

        For a perfect set of snapshots, (where the user has been doing one snapshot per hour and         doing the daily culling) it should leave behind (remove from list):

        - day1-1800

        :param dir_to_cull: A list containing snapshots. Assumes another function        has already reduced this list to a list containing only one day's worth of        snapshots.
        :returns: A list containing all the subvolumes to cull.
        """
    sorted_dir_to_cull = sorted(dir_to_cull)
    if len(sorted_dir_to_cull) != 0:
        sorted_dir_to_cull.pop()
    return sorted_dir_to_cull


@classmethod
def deserialize_item(cls, item):
    """
        Deserialize a query that stored in ``item`` tuple like: (key, value)
        """
    fields = getattr(cls, 'fields', None)
    if fields and isinstance(fields, dict):
        if item[0] in fields:
            return {item[0], fields[item(0)].deserialize(item[1])}
    return {item[0]: item[1]}


def _reduce_datetimes(row):
    """Receives a row, converts datetimes to strings."""
    row = list(row)
    for i in range(len(row)):
        if hasattr(row[i], 'isoformat'):
            row[i] = row[i].isoformat()
    return tuple(row)


def _new_object(cls):
    """Helper function for pickle"""
    return cls.__new__(cls)


@classmethod
def generate(cls, variable: str) ->str:
    """Generates unique name for variable."""
    try:
        return '_py_backwards_{}_{}'.format(variable, cls._counter)
    finally:
        cls._counter += 1