def get_doc():
    """Get documentation of this resource

    :return: rst string
    :rtype: str
    """
    return """
    The ``actionacknowledge`` contains the acknowledgement requested and processed.

    To acknowledge an host/service problem the client post on this endpoint to create a new
    acknowledge request that will be managed by the Alignak backend Broker module to build an
    external command notified to the Alignak framework.

    **Note** that the Alignak Web Services module allow to use more external commands.
    """


def fetch_clip(chrom, st, cigar):
    """ fetch head soft clip regions defined by cigar. st must be zero based
	return list of tuple of (chrom,st, end)
	"""
    chrom_st = st
    clip_bound = []
    for c, s in cigar:
        if c == 0:
            chrom_st += s
        elif c == 1:
            continue
        elif c == 2:
            chrom_st += s
        elif c == 3:
            chrom_st += s
        elif c == 4:
            clip_bound.append((chrom, chrom_st, chrom_st + s))
            chrom_st += s
        else:
            continue
    return clip_bound


def is_tag_mutable(context, tag):
    """Return True if the tag is mutable in this context."""
    if context.is_admin:
        return True
    if context.owner is None:
        return False
    return tag.namespace.owner == context.owner


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 query(context):
    """Return the existing annotation or None if no annotaion
        was created before.
        """


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


def _plain_bfs(G, source):
    """A fast BFS node generator"""
    seen = set()
    nextlevel = {source}
    while nextlevel:
        thislevel = nextlevel
        nextlevel = set()
        for v in thislevel:
            if v not in seen:
                yield v
                seen.add(v)
                nextlevel.update(G[v])


def _smallest_distance(node):
    """
    Takes a TreeNode object as an input and returns the leaf with with the
    smallest distance to the given node.
    """
    smallest_dist = None
    for leaf in node.iter_leaves():
        dist = leaf.distance_to(node)
        if not smallest_dist or dist < smallest_dist:
            leaf_to_keep = leaf
            smallest_dist = dist
    return leaf_to_keep


@classmethod
def get_language_filename(cls, mask, code):
    """Return full filename of a language file.

        Calculated forfor given path, filemask and language code.
        """
    return mask.replace('*', cls.get_language_code(code))


def msg_is_unicode(text):
    """ does this message needs to be sent as unicode ? """
    try:
        text.encode('ascii')
    except (UnicodeEncodeError, UnicodeDecodeError):
        return True
    else:
        return False


def _is_authenticated():
    """stub to test for authenticated user TODO: implementation"""
    return True


def fuse_scribbles(scribbles_a, scribbles_b):
    """ Fuse two scribbles in the default format.

    # Arguments
        scribbles_a: Dictionary. Default representation of scribbles A.
        scribbles_b: Dictionary. Default representation of scribbles B.

    # Returns
        dict: Returns a dictionary with scribbles A and B fused.
    """
    if scribbles_a['sequence'] != scribbles_b['sequence']:
        raise ValueError('Scribbles to fuse are not from the same sequence')
    if len(scribbles_a['scribbles']) != len(scribbles_b['scribbles']):
        raise ValueError('Scribbles does not have the same number of frames')
    scribbles = dict(scribbles_a)
    nb_frames = len(scribbles['scribbles'])
    for i in range(nb_frames):
        scribbles['scribbles'][i] += scribbles_b['scribbles'][i]
    return scribbles


@classmethod
def run_hooks(cls, hook_type, *args, **kwargs):
    """Run all hooks of specified type.

        :param cls: class that registers hooks
        :param hook_type: hook type, e.g., '__pre_parse_args__'
        :param args: args to be passed to every hook function
        :param kwargs: kwargs to be passed to every hook function
        """
    hook_funcs = cls._hooks_map.get(hook_type) or []
    for hook_func in hook_funcs:
        hook_func(*args, **kwargs)


def _maybe_singleton(it):
    """unpack single-entry collection to single value"""
    if len(it) == 1:
        return it[0]
    return it


def removePolicy(policy_id):
    """Removes a versioning policy from the tool and all types which
           support it"""


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

        :param int val:
        :rtype: UploadApiRateLimitValue
        """
    return cls('limit', val)


def size(path):
    """Return the size of the file at path.

        This method returns the modification time. It is assumed that the path
        exists. You can use the `type(path)` method to determine whether
        `path` points to a valid file.
        """


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


def bytesToString(value):
    """Coverts value in bytes to corresponding string representation.

    b'hello' -> 'hello'
    b'abc' -> 'abc'

    :type value: bytes
    :param value: the value
    :rtype: string
    :return: value in string
    """
    try:
        return ''.join(map(chr, list(value)))
    except:
        raise TypeError('value is not of type bytes')


def checksum(data):
    """Creates the ICMP checksum as in RFC 1071

    :param data: Data to calculate the checksum ofs
    :type data: bytes
    :return: Calculated checksum
    :rtype: int

    Divides the data in 16-bits chunks, then make their 1's complement sum"""
    subtotal = 0
    for i in range(0, len(data) - 1, 2):
        subtotal += (data[i] << 8) + data[i + 1]
    if len(data) % 2:
        subtotal += data[len(data) - 1] << 8
    while subtotal >> 16:
        subtotal = (subtotal & 65535) + (subtotal >> 16)
    check = ~subtotal
    return check << 8 & 65280 | check >> 8 & 255


def orderObjects(key, reverse=None):
    """ Order sub-objects by key and direction. """


def is_list_type(value):
    """
    判断value是否列表类型，兼容python2、python3

    :param value: 输入值
    :type value: any
    :returns: 判断结果
    :rtype: bool
    """
    return isinstance(value, (list, set, tuple))


def best_matches(links):
    """
    Subsequent to duke() with singlematch=True. Returns reduced list of
    matches on the base of the highest score for each duplicated entry.

    Parameters
    ----------
    links : pd.DataFrame
        Links as returned by duke
    """
    labels = links.columns.difference({'scores'})
    return links.groupby(links.iloc[:, (1)], as_index=False, sort=False).apply(
        lambda x: x.loc[x.scores.idxmax(), labels])


def get_builtins():
    """Python 2.x and 3.x have different names for accessing builtins"""
    try:
        __import__('builtins')
        return 'builtins'
    except ImportError:
        return '__builtin__'


def delDotPrefix(string):
    """Delete dot prefix to file extension if present"""
    return string[1:] if string.find('.') == 0 else string


def config(configfile):
    """
    read a configfile and return the dataframe

    >>> configs = config('egf.py')

    :param configfile: the path to the configuration file
    :returns dataset: the dictionary with the configu info
    """
    configs = {}
    with open(configfile) as f:
        exec(f.read(), configs)
    return configs


def bin2bytes(x):
    """Convert an array of bits (MSB first) into a string of characters."""
    bits = []
    bits.extend(x)
    bits.reverse()
    i = 0
    out = b''
    multi = 1
    ttl = 0
    for b in bits:
        i += 1
        ttl += b * multi
        multi *= 2
        if i == 8:
            i = 0
            out += bytes([ttl])
            multi = 1
            ttl = 0
    if multi > 1:
        out += bytes([ttl])
    out = bytearray(out)
    out.reverse()
    out = bytes(out)
    return out


def _get_module_tag(namespace, directive):
    """Get the project-relative path to some Python class, method, or function.

    Args:
        namespace (str):
            The importable Python location of some class, method, or function.
            Example: "foo.bar.ClassName.get_method_data".
        directive (str):
            The Python type that `namespace` is. Example: "py:method".

    Raises:
        EnvironmentError:
            If `directive` and `namespace` were both found properly but,
            for some reason, the top-level website / file path for the
            Sphinx project stored by intersphinx could not be found.

    Returns:
        tuple[str, str]:
            The exact path, relative to a Sphinx project's root
            directory, where this module is tagged, followed by a tag
            like "foo" which will be later used to get a permalink to
            some header in the HTML file.

    """
    tokens = namespace.split('.')
    if directive in {'py:method'}:
        base = '/'.join(tokens[:-2])
        return '_modules/{base}.html'.format(base=base), '.'.join(tokens[-2:])
    base = '/'.join(tokens[:-1])
    return '_modules/{base}.html'.format(base=base), tokens[-1]


@staticmethod
def mutate_label(label):
    """
        Most engines support mixed case aliases that can include numbers
        and special characters, like commas, parentheses etc. For engines that
        have restrictions on what types of aliases are supported, this method
        can be overridden to ensure that labels conform to the engine's
        limitations. Mutated labels should be deterministic (input label A always
        yields output label X) and unique (input labels A and B don't yield the same
        output label X).
        """
    return label


@staticmethod
def metadata_id(item):
    """Extracts the identifier from a Meetup item."""
    return str(item['id'])


def lambda_A_calc(classes, table, P, POP):
    """
    Calculate Goodman and Kruskal's lambda A.

    :param classes: confusion matrix classes
    :type classes : list
    :param table: confusion matrix table
    :type table : dict
    :param P: condition positive
    :type P : dict
    :param POP: population
    :type POP : int
    :return: Goodman and Kruskal's lambda A as float
    """
    try:
        result = 0
        maxreference = max(list(P.values()))
        length = POP
        for i in classes:
            col = []
            for col_item in table.values():
                col.append(col_item[i])
            result += max(col)
        result = (result - maxreference) / (length - maxreference)
        return result
    except Exception:
        return 'None'


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


@staticmethod
def _convert_indirect_jump_targets_to_states(job, indirect_jump_targets):
    """
        Convert each concrete indirect jump target into a SimState. If there are non-zero successors and the original
        jumpkind is a call, we also generate a fake-ret successor.

        :param job:                     The CFGJob instance.
        :param indirect_jump_targets:   A collection of concrete jump targets resolved from a indirect jump.
        :return:                        A list of SimStates.
        :rtype:                         list
        """
    first_successor = job.sim_successors.all_successors[0]
    successors = []
    for t in indirect_jump_targets:
        a = first_successor.copy()
        a.ip = t
        successors.append(a)
    if successors and first_successor.history.jumpkind == 'Ijk_Call':
        a = first_successor.copy()
        a.ip = job.cfg_node.addr + job.cfg_node.size
        a.history.jumpkind = 'Ijk_FakeRet'
        successors.append(a)
    return successors


def wf_user():
    """
    Returns the user name that started the current workflow job.

    """
    return '{{ params.user.name }}'


def bezier_detail(detail_value):
    """Change the resolution used to draw bezier curves.

    :param detail_value: New resolution to be used.
    :type detail_value: int
    """
    global bezier_resolution
    bezier_resolution = max(1, detail_value)


def one_to_many(df, unitcol, manycol):
    """
    Assert that a many-to-one relationship is preserved between two
    columns. For example, a retail store will have have distinct
    departments, each with several employees. If each employee may
    only work in a single department, then the relationship of the
    department to the employees is one to many.

    Parameters
    ==========
    df : DataFrame
    unitcol : str
        The column that encapulates the groups in ``manycol``.
    manycol : str
        The column that must remain unique in the distict pairs
        between ``manycol`` and ``unitcol``

    Returns
    =======
    df : DataFrame

    """
    subset = df[[manycol, unitcol]].drop_duplicates()
    for many in subset[manycol].unique():
        if subset[subset[manycol] == many].shape[0] > 1:
            msg = '{} in {} has multiple values for {}'.format(many,
                manycol, unitcol)
            raise AssertionError(msg)
    return df


def set_verbose(verbosity):
    """Sets the global verbosity for all modules."""
    global verbose
    verbose = verbosity


def object_add_grid_scale_apply_operator(operator, context):
    """Scale an operators distance values by the grid size.

    """
    pass


@staticmethod
def get_number_of_points(rf):
    """
        Return the total number of points for a radar:
            - For a masked array this all all points that are not masked
            - For a normal array this is all points

        :param rf: (masked) array of reflectivity measurements
        :type rf: numpy.ndarray
        :returns: total number of measurement points of the radar
        :rtype: int
        """
    try:
        return len(rf.count(axis=0).flatten().nonzero()[0])
    except AttributeError:
        return len(rf[(0), :].flatten())


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

    Positional arguments:
    type_ -- corresponding `ieprinters` dictionary key for the instance.
    data -- bytearray data to read.
    """
    raise NotImplementedError


@classmethod
def _fromSiddhiAppRuntimeProxy(cls, siddhi_app_runtime_proxy):
    """
        Internal Constructor to wrap around JAVA Class SiddhiAppRuntime
        :param siddhi_app_runtime_proxy:
        :return:
        """
    instance = cls.__new__(cls)
    instance.siddhi_app_runtime_proxy = siddhi_app_runtime_proxy
    return instance


@classmethod
def analyse_cmd_para(cls, cmd_para_str='', is_start_in_string=False):
    """
        解析命令的参数（通过流方式调用_analyse_para_stream_dealer）

        @decorators classmethod - 定义类成员函数，无需实例化可调用类内部函数

        @param {string} cmd_para_str='' - 要解析的参数字符串
        @param {bool} is_start_in_string=False - 是否在字符串中间启动，在多行分开解析时使用

        @returns {list} - 解析结果，格式如下:
            [参数名, 参数值, 关联符('='或' ')，开始位置(int), 结束位置(int), 引号是否结束(bool), 处理是否结束(bool)]

        """
    _para_list = list()
    if is_start_in_string:
        _para_list.append(['', '', '', 0, -1, False, False])
    cls._analyse_para_stream_dealer(deal_obj=None, position=0, str_obj=
        cmd_para_str, para_list=_para_list)
    _len = len(_para_list)
    if _len > 0 and not _para_list[_len - 1][6]:
        _para_list[_len - 1][6] = True
        _para_list[_len - 1][4] = _len
        if _para_list[_len - 1][0] == '' and _para_list[_len - 1][1][0:1
            ] != '"':
            _index = _para_list[_len - 1][1].find('=')
            if _index > 0:
                _para_list[_len - 1][0] = _para_list[_len - 1][1][0:_index]
                _para_list[_len - 1][1] = _para_list[_len - 1][1][_index + 1:]
                _para_list[_len - 1][2] = '='
    return _para_list


def reshape_axis(ax, axis_size_pix):
    """reshape axis to the specified size in pixels

    this will reshape an axis so that the given axis is the specified size in pixels, which we use
    to make sure that an axis is the same size as (or an integer multiple of) the array we're
    trying to display. this is to prevent aliasing

    NOTE: this can only shrink a big axis, not make a small one bigger, and will throw an exception
    if you try to do that.

    Arguments
    ---------
    ax : `matpotlib.pyplot.axis`
        the axis to reshape
    axis_size_pix : `int`
        the target size of the axis, in pixels

    Returns
    -------
    ax : `matplotlib.pyplot.axis`
        the reshaped axis
    """
    if ax.bbox.width < axis_size_pix[1] or ax.bbox.height < axis_size_pix[0]:
        raise Exception(
            'Your axis is too small! Axis size: ({}, {}). Image size: ({}, {})'
            .format(ax.bbox.width, ax.bbox.height, axis_size_pix[1],
            axis_size_pix[0]))
    bbox = ax.figure.get_window_extent().transformed(ax.figure.
        dpi_scale_trans.inverted())
    fig_width, fig_height = (bbox.width * ax.figure.dpi, bbox.height * ax.
        figure.dpi)
    rel_axis_width = axis_size_pix[1] / fig_width
    rel_axis_height = axis_size_pix[0] / fig_height
    ax.set_position([*ax.get_position().bounds[:2], rel_axis_width,
        rel_axis_height])
    return ax


def create_arc(archive, compression, cmd, verbosity, interactive, filenames):
    """Create a ARC archive."""
    cmdlist = [cmd, 'a', archive]
    cmdlist.extend(filenames)
    return cmdlist


def zuul_filter_result(result):
    """Remove keys from shell/command output.

    Zuul streams stdout into the log above, so including stdout and stderr
    in the result dict that ansible displays in the logs is duplicate
    noise. We keep stdout in the result dict so that other callback plugins
    like ARA could also have access to it. But drop them here.

    Remove changed so that we don't show a bunch of "changed" titles
    on successful shell tasks, since that doesn't make sense from a Zuul
    POV. The super class treats missing "changed" key as False.

    Remove cmd because most of the script content where people want to
    see the script run is run with -x. It's possible we may want to revist
    this to be smarter about when we remove it - like, only remove it
    if it has an embedded newline - so that for normal 'simple' uses
    of cmd it'll echo what the command was for folks.
    """
    stdout = result.pop('stdout', '')
    stdout_lines = result.pop('stdout_lines', [])
    if not stdout_lines and stdout:
        stdout_lines = stdout.split('\n')
    for key in ('changed', 'cmd', 'zuul_log_id', 'invocation', 'stderr',
        'stderr_lines'):
        result.pop(key, None)
    return stdout_lines


@classmethod
def _get_name_from_dn(cls, dn):
    """
        Get the instance name from the dn

        :param dn: string containing the distinguished name URL
        :return: string containing the name or None if not present
        """
    delimits = cls._get_name_dn_delimiters()
    name = None
    if len(delimits) == 2:
        if delimits[0] in dn:
            name = dn.split(delimits[0])[1].split(delimits[1])[0]
    elif len(delimits) == 1:
        if delimits[0] in dn:
            name = dn.split(delimits[0])[1]
    return name


def __call__(request, subpath, kw):
    """
        Modifies a subpath and/or keyword arguments from which a static asset
        URL will be computed during URL generation.

        The ``subpath`` argument is a path of ``/``-delimited segments that
        represent the portion of the asset URL which is used to find the asset.
        The ``kw`` argument is a dict of keywords that are to be passed
        eventually to :meth:`~pyramid.request.Request.static_url` for URL
        generation.  The return value should be a two-tuple of
        ``(subpath, kw)`` where ``subpath`` is the relative URL from where the
        file is served and ``kw`` is the same input argument. The return value
        should be modified to include the cache bust token in the generated
        URL.

        The ``kw`` dictionary contains extra arguments passed to
        :meth:`~pyramid.request.Request.static_url` as well as some extra
        items that may be usful including:

          - ``pathspec`` is the path specification for the resource
            to be cache busted.

          - ``rawspec`` is the original location of the file, ignoring
            any calls to :meth:`pyramid.config.Configurator.override_asset`.

        The ``pathspec`` and ``rawspec`` values are only different in cases
        where an asset has been mounted into a virtual location using
        :meth:`pyramid.config.Configurator.override_asset`. For example, with
        a call to ``request.static_url('myapp:static/foo.png'), the
        ``pathspec`` is ``myapp:static/foo.png`` whereas the ``rawspec`` may
        be ``themepkg:bar.png``, assuming a call to
        ``config.override_asset('myapp:static/foo.png', 'themepkg:bar.png')``.
        """


def image_mode(image):
    """
    Show mode of image is 'RGB' or 'RGBA'
    image: an Image object
    return: mode
    """
    mode = image.mode
    return mode


@classmethod
def from_values(cls, vals):
    """
        Returns a Layout given a list (or tuple) of viewable
        elements or just a single viewable element.
        """
    return cls(items=cls._process_items(vals))


def line_tokenizer(inputstring):
    """Yield a list of tokens for each line in a file.

    If a quoted string is incomplete at the end of a physical line, the
    logical line continues to the next line.  Likewise, join two lines if
    the first line ends in a backslash.

    Setup a test file:
    >>> teststr = r'''First line.
    ... Beginning of second \\
    ... line and end.
    ... Beginning of "third
    ... line" and end.'''
    >>>

    Make sure that the lexical analyzer works:
    >>> it = line_tokenizer(teststr)
    >>> it.next()
    ['First', 'line.']
    >>> it.next()
    ['Beginning', 'of', 'second', 'line', 'and', 'end.']
    >>> it.next()
    ['Beginning', 'of', 'third\\nline', 'and', 'end.']
    >>>
    """
    from shlex import split
    logical_line = ''
    tokens = []
    for physical_line in inputstring.splitlines(True):
        logical_line += physical_line
        try:
            new_tokens = split(logical_line, comments=True)
        except ValueError:
            continue
        if new_tokens and new_tokens[-1] == '\n':
            tokens += new_tokens[:-1]
            logical_line = ''
            continue
        else:
            tokens += new_tokens
            yield tokens
        logical_line = ''
        tokens = []
    if logical_line:
        raise ValueError('Syntax error: unmatched quote at EOF')


def get_facet(SchemaArn=None, Name=None):
    """
    Gets details of the  Facet , such as facet name, attributes,  Rule s, or ObjectType . You can call this on all kinds of schema facets -- published, development, or applied.
    See also: AWS API Documentation

    :example: response = client.get_facet(
        SchemaArn='string',
        Name='string'
    )

    :type SchemaArn: string
    :param SchemaArn: [REQUIRED]
            The Amazon Resource Name (ARN) that is associated with the Facet . For more information, see arns .

    :type Name: string
    :param Name: [REQUIRED]
            The name of the facet to retrieve.

    :rtype: dict
    :return: {
        'Facet': {
            'Name': 'string',
            'ObjectType': 'NODE'|'LEAF_NODE'|'POLICY'|'INDEX'
        }
    }

    """
    pass


@classmethod
def from_dict(cls, connection, data):
    """Returns an alert object from a dictionary item,
        which is usually from AppOptics's API"""
    obj = cls(connection, data.get('name'), version=data.get('version'),
        description=data.get('description'), conditions=data.get(
        'conditions'), services=data.get('services'), _id=data.get('id'),
        active=data.get('active'), rearm_seconds=data.get('rearm_seconds'),
        attributes=data.get('attributes'), md=data.get('md'), created_at=
        data.get('created_at'), updated_at=data.get('updated_at'),
        rearm_per_signal=data.get('rearm_per_signal'))
    return obj


def _idnaBytes(text):
    """
    Convert some text typed by a human into some ASCII bytes. This is a
    copy of twisted.internet._idna._idnaBytes. For documentation, see the
    twisted documentation.
    """
    try:
        import idna
    except ImportError:
        return text.encode('idna')
    else:
        return idna.encode(text)


@classmethod
def get_model_name(cls):
    """
        Get the name of this Model.
        Returns (str):

        """
    return cls.Meta.verbose_name


def canvas(with_attribution=True):
    """
    Placeholder function to show example docstring (NumPy format)

    Replace this function and doc string for your own project

    Parameters
    ----------
    with_attribution : bool, Optional, default: True
        Set whether or not to display who the quote is from

    Returns
    -------
    quote : str
        Compiled string including quote and optional attribution
    """
    quote = 'The code is but a canvas to our imagination.'
    if with_attribution:
        quote += '\n\t- Adapted from Henry David Thoreau'
    return quote


def is_power2(num):
    """Test if num is a power of 2. (int -> bool)"""
    num = int(num)
    return num != 0 and num & num - 1 == 0


def dt2doy(dt):
    """Convert datetime to integer DOY (Julian)
    """
    return int(dt.timetuple().tm_yday)


def pyramid_vol(base_area, height):
    """Usage: Find the volume of a pyramid  using base area and height"""
    return base_area * height / 3


def analyse_text(text):
    """
        Has to return a float between ``0`` and ``1`` that indicates
        if a lexer wants to highlight this text. Used by ``guess_lexer``.
        If this method returns ``0`` it won't highlight it in any case, if
        it returns ``1`` highlighting with this lexer is guaranteed.

        The `LexerMeta` metaclass automatically wraps this function so
        that it works like a static method (no ``self`` or ``cls``
        parameter) and the return value is automatically converted to
        `float`. If the return value is an object that is boolean `False`
        it's the same as if the return values was ``0.0``.
        """


def is_exist(sitepath):
    """Is there a valid layout under `sitepath`. Returns a boolean."""


def module_name_split(name):
    """
    Split the module name into package name and module name.
    """
    if '.' in name:
        package_name, module = name.rsplit('.', 1)
    else:
        package_name, module = '', name
    return package_name, module


def find_nearest(origin, distance=1.84467e+19):
    """Find the nearest elements to a point in the distance range.

		Parameters:
		co (Vector) – Find nearest elements to this point.
		distance (float) – Maximum distance threshold.

		Returns: Returns a list of tuples (Vector location, Vector normal, int index, float distance),

		Return type: list"""
    from . import Vector
    return [(Vector, Vector, 1, 1.0), (Vector, Vector, 1, 1.0), (Vector,
        Vector, 1, 1.0), (Vector, Vector, 1, 1.0)]


def _get_parameter_info(parameters_metadata, parameter_id):
    """General information for given parameter id.

    :param parameters_metadata: Metadata for all parameters
    :type parameters_metadata: List of dictionaries
    :param parameter_id: Parameter id
    :type parameter_id: Integer

    :returns: Database name, time step, realm, instrument, start_date, end_date and unit for given parameter
    :rtype: (string, string, string, string, string, string, string)
    """
    for dic in parameters_metadata:
        if int(dic['parameter_id']) == parameter_id:
            database = dic['database']
            time_step = dic['timestep']
            realm = dic['realm']
            instrument = dic['instrument']
            start_date = dic['start_date']
            end_date = dic['end_date']
            unit = dic['units']
    return database, time_step, realm, instrument, start_date, end_date, unit


def chunking_query_by_n_users(table_name='%(table_name)s', max_chunksize=50000
    ):
    """
    Create a chunk_id which is based on the unique users (caller_id) and
    the maximum size of users per chunk defined in attributes.

    Inputs
    ------
    table_name : Name of the table the query is supposed to run on,
                 defaulting to '%(table_name)s', i.e. no substitution.
    max_chunksize : Maximum number of users per chunk.

    Output
    ------
    Crosswalk between caller_id and chunk_id.
    """
    query = """
        SELECT
          caller_id,
          -- as soon as chunk limit is reached the id increases by 1
          SMALLINT((counter-1) / %(max_chunksize)s)+1 as chunk_id
        FROM
        (
          SELECT
            caller_id,
            ROW_NUMBER() OVER (ORDER BY caller_id) as counter -- no ties
          FROM %(table_name)s
          GROUP BY caller_id
        )
    """
    return query % {'table_name': table_name, 'max_chunksize': max_chunksize}


def p_or_test(p):
    """ or_test : and_test
                 | or_test OR and_test
                 | or_test BADOR and_test"""
    if len(p) == 2:
        p[0] = p[1]
    else:
        p[0] = ['MATHOP', 'or', p[1], p[3]]


def get_wind_shear(wxdata: [str]) ->([str], str):
    """
    Returns the report list and the remove wind shear
    """
    shear = None
    for i, item in reversed(list(enumerate(wxdata))):
        if len(item) > 6 and item.startswith('WS') and item[5] == '/':
            shear = wxdata.pop(i).replace('KT', '')
    return wxdata, shear


@staticmethod
def _make_filter_string(reqd, prefd, ontos):
    """
        TODO: expand to deal with list input

        >>> z = ZoomaClient()
        >>> z._make_filter_string("atlas,gwas","gwas","efo")
        'required:[atlas,gwas],preferred:[gwas],ontologies:[efo]'
        >>> z._make_filter_string(None,None,"none")
        'ontologies:[none]'
        """
    filters = []
    if reqd:
        filters.append('required:[{}]'.format(reqd))
    if prefd:
        filters.append('preferred:[{}]'.format(prefd))
    if ontos:
        filters.append('ontologies:[{}]'.format(ontos))
    return ','.join(filters)


def _offset_to_tzname(offset):
    """
    Converts an offset in minutes to an RFC 3339 "time-offset" string.

    >>> _offset_to_tzname(0)
    '+00:00'
    >>> _offset_to_tzname(-1)
    '-00:01'
    >>> _offset_to_tzname(-60)
    '-01:00'
    >>> _offset_to_tzname(-779)
    '-12:59'
    >>> _offset_to_tzname(1)
    '+00:01'
    >>> _offset_to_tzname(60)
    '+01:00'
    >>> _offset_to_tzname(779)
    '+12:59'
    """
    offset = int(offset)
    if offset < 0:
        tzsign = '-'
    else:
        tzsign = '+'
    offset = abs(offset)
    tzhour = offset / 60
    tzmin = offset % 60
    return '%s%02d:%02d' % (tzsign, tzhour, tzmin)


def clip_path(surface, node):
    """Store a clip path definition."""
    if 'id' in node:
        surface.paths[node['id']] = node


def triangles(creation_sequence):
    """
    Compute number of triangles in the threshold graph with the
    given creation sequence.
    """
    cs = creation_sequence
    dr = cs.count('d')
    ntri = dr * (dr - 1) * (dr - 2) / 6
    for i, typ in enumerate(cs):
        if typ == 'i':
            ntri += dr * (dr - 1) / 2
        else:
            dr -= 1
    return ntri


def LeNet_Model(s, model_name='LeNet'):
    """
    LeNet model definition (batch normalization version)

    Parameters
    ----------
    s : CAS
        Specifies the CAS connection object
    model_name : string, optional
        Specifies the name of CAS table to store the model

    Returns
    -------
    None
        A CAS table defining the model is created

    """
    s.deepLearn.buildModel(model=dict(name=model_name, replace=True), type=
        'CNN')
    s.deepLearn.addLayer(model=model_name, name='mnist', layer=dict(type=
        'input', nchannels=1, width=28, height=28, scale=0.00392156862745098))
    s.deepLearn.addLayer(model=model_name, name='conv1', layer=dict(type=
        'convolution', nFilters=20, width=5, height=5, stride=1, act=
        'identity', noBias=True, init='xavier'), srcLayers=['mnist'])
    s.deepLearn.addLayer(model=model_name, name='conv1_bn', layer=dict(type
        ='batchnorm', act='relu'), srcLayers=['conv1'])
    s.deepLearn.addLayer(model=model_name, name='pool1', layer=dict(type=
        'pooling', width=2, height=2, stride=2, pool='max'), srcLayers=[
        'conv1_bn'])
    s.deepLearn.addLayer(model=model_name, name='conv2', layer=dict(type=
        'convolution', nFilters=50, width=5, height=5, stride=1, act=
        'identity', noBias=True, init='xavier'), srcLayers=['pool1'])
    s.deepLearn.addLayer(model=model_name, name='conv2_bn', layer=dict(type
        ='batchnorm', act='relu'), srcLayers=['conv2'])
    s.deepLearn.addLayer(model=model_name, name='pool2', layer=dict(type=
        'pooling', width=2, height=2, stride=2, pool='max'), srcLayers=[
        'conv2_bn'])
    s.deepLearn.addLayer(model=model_name, name='ip1', layer=dict(type=
        'fullconnect', n=500, init='xavier', act='relu'), srcLayers=['pool2'])
    s.deepLearn.addLayer(model=model_name, name='ip2', layer=dict(type=
        'output', n=10, init='xavier', act='softmax'), srcLayers=['ip1'])


@staticmethod
def _for_each_option_group(callback, options):
    """
        Given set of options, call a callback for each option group.

        :param options: List of option groups, or a dict listing options directly.
        :param callable callback: Must accept at least 2 parameters: ``options`` (``dict``), listing options
            in the group, and keyword parameter ``group_name`` (``str``), which is set to group name when
            the ``options`` defines an option group.
        """
    if isinstance(options, dict):
        callback(options)
    elif isinstance(options, (list, tuple)):
        for group in options:
            if isinstance(group, dict):
                callback(group)
            else:
                group_name, group_options = group
                callback(group_options, group_name=group_name)


def vertex_group_remove(all: bool=False, all_unlocked: bool=False):
    """Delete the active or all vertex groups from the active object

    :param all: All, Remove all vertex groups
    :type all: bool
    :param all_unlocked: All Unlocked, Remove all unlocked vertex groups
    :type all_unlocked: bool
    """
    pass


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 update_sub_lists(out, inp):
    """Extends dictionary `out` lists with those in `inp`

    Assumes dictionaries where all values are lists
    """
    for k, v in inp.items():
        try:
            out[k].extend(v)
        except KeyError:
            out[k] = list(v)


def make_default_short_help(help, max_length=45):
    """Return a condensed version of help string."""
    words = help.split()
    total_length = 0
    result = []
    done = False
    for word in words:
        if word[-1:] == '.':
            done = True
        new_length = result and 1 + len(word) or len(word)
        if total_length + new_length > max_length:
            result.append('...')
            done = True
        else:
            if result:
                result.append(' ')
            result.append(word)
        if done:
            break
        total_length += new_length
    return ''.join(result)


def DoNothing():
    """A routine that does nothing. This is called in place of IPyBreak and pdbBreak
    except when the debug option is set True in config.py
    """
    pass


def raise_(ex):
    """I like to use exceptions as flow control, and I like to define functions
    using lambda So this is a helper function to let me raise exceptions in
    lambda"""
    raise ex


def read_viewlayers():
    """Read all render layers of all used scenes

    """
    pass


def shufflelr(x, width, hflip_indices):
    """flip and rearrange coords"""
    x[:, (0)] = width - x[:, (0)]
    x = x[hflip_indices]
    return x


@staticmethod
def __b(value):
    """
        Because Hg Lib is setup to only work with binary encoded strings(8 bit ASCII) and is TERRIBLE at sanitizing
        its inputs, this function is necessary to do that for it.  This also makes unicode out of the question for
        HG repos.
        :param value: A value to be binarized.
        :return:
        """
    if isinstance(value, bytes):
        return value
    return str(value).encode('latin-1')


def star_finder(att, sky, scanner):
    """
    Finds times at which source transit CCD line of scanner and estimates their position in the BCRS frame.
    :param sky: object
    :param att:object
    :param scanner: object
    :return: scanner.star_positions, scanner.obs_times.
    """
    for star in sky.elements:
        scanner.reset_memory()
        scanner.intercept(att, star)
        if len(scanner.times_deep_scan) != 0:
            scanner.deep_scan(att, star)


def _parse_out_sequence_file(sample):
    """
    Removes keys in argument sample that are not in sample_keys and
        stores them in sequence_file_dict

    arguments:
            sample -- Sample object
            the dictionary inside the Sample object is changed

    returns a dictionary containing keys not in sample_keys to be used to
        create a SequenceFile object
    """
    sample_keys = ['sequencer_sample_name', 'description', 'sampleName',
        'sample_project']
    sequence_file_dict = {}
    sample_dict = sample.get_uploadable_dict()
    for key in list(sample_dict.keys()):
        if key not in sample_keys:
            sequence_file_dict[key] = sample_dict[key]
    return sequence_file_dict


def selection_opacity_toggle():
    """Hide/Unhide selected points for Grease Pencil strokes setting alpha factor

    """
    pass


def load_scipy_sparse_linalg_dsolve_linsolve(finder, module):
    """the scipy.linalg.dsolve.linsolve optionally loads scikits.umfpack"""
    module.IgnoreName('scikits.umfpack')


def categories_to_list(doc_id, analyzed, single_document=False):
    """Converts categories response to flat list with doc_id included.

    :param doc_id: Will be inserted to each row as first element
    :param analyzed: Response json from anacode api for categories call
    :type analyzed: list
    :param single_document: Is analysis describing just one document
    :type single_document: bool
    :return: dict -- Dictionary with one key 'categories' pointing to flat list
     of categories
    """
    cat_list = []
    for order, text_analyzed in enumerate(analyzed):
        for result_dict in text_analyzed:
            row = [doc_id, 0, result_dict.get('label'), result_dict.get(
                'probability')]
            if single_document:
                row[1] += order
            else:
                row[0] += order
            cat_list.append(row)
    return {'categories': cat_list}


@staticmethod
def pointInPolygon(p, polygon):
    """
        Finds out if a point is inside a polygon or not
        @type p: tuple of (float, float)
        @type polygon: Polyline or list of tuple of (float, float)
        @rtype: bool
        """
    x = p[0]
    y = p[1]
    n = len(polygon)
    inside = False
    p1x, p1y = polygon[0][0:2]
    for index in range(n + 1):
        p2x, p2y = polygon[index % n][0:2]
        if min(p1y, p2y) < y <= max(p1y, p2y):
            if x <= max(p1x, p2x):
                if p1y != p2y:
                    xints = (y - p1y) * (p2x - p1x) / (p2y - p1y) + p1x
                if p1x == p2x or x <= xints:
                    inside = not inside
        p1x, p1y = p2x, p2y
    return inside


@classmethod
def IsSystemLevelTypeIndicator(cls, type_indicator):
    """Determines if the type indicator is at system-level.

    Args:
      type_indicator (str): type indicator.

    Returns:
      bool: True if the type indicator is at system-level.
    """
    return type_indicator in cls._system_level_type_indicators


def _get_win_folder_from_registry(csidl_name):
    """
  This is a fallback technique at best. I'm not sure if using the
  registry for this guarantees us the correct answer for all CSIDL_*
  names.
  """
    import _winreg
    shell_folder_name = {'CSIDL_APPDATA': 'AppData', 'CSIDL_COMMON_APPDATA':
        'Common AppData', 'CSIDL_LOCAL_APPDATA': 'Local AppData'}[csidl_name]
    key = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER,
        'Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders'
        )
    directory, _ = _winreg.QueryValueEx(key, shell_folder_name)
    return directory


def hide(unselected: bool=False):
    """Hide selected curves from Graph Editor view

    :param unselected: Unselected, Hide unselected rather than selected curves
    :type unselected: bool
    """
    pass


@staticmethod
def deserialize(o):
    """this is a placeholder function to support SQLiteGraphDB api compatibility. NO SERIALIZING IN RAM!!!"""
    return o


def get_count_fields_model(instance):
    """
    This method get count fields from model instance.

    Args:
        instance (obj): instance class model.

    Returns:
        int: Total fields of model.
    """
    return len(instance._meta.fields)


def _portfolio_difference(df, portvar, long, short, byvars=None, retvars=None):
    """
    Calculates long portfolio minus short portfolio
    """
    if byvars:
        out = df[df[portvar] == long].set_index(byvars) - df[df[portvar] ==
            short].set_index(byvars)
    else:
        out = df[df[portvar] == long] - df[df[portvar] == short]
    if retvars:
        return out[retvars]
    else:
        return out


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 knife_tool(use_occlude_geometry: bool=True, only_selected: bool=False,
    wait_for_input: bool=True):
    """Cut new topology

    :param use_occlude_geometry: Occlude Geometry, Only cut the front most geometry
    :type use_occlude_geometry: bool
    :param only_selected: Only Selected, Only cut selected geometry
    :type only_selected: bool
    :param wait_for_input: Wait for Input
    :type wait_for_input: bool
    """
    pass


def find_torrent(info_hash, torrent_list):
    """Find torrent file in given list of Torrent classes

    @param info_hash: info hash of torrent
    @type info_hash: str

    @param torrent_list: list of L{Torrent} instances (see L{RTorrent.get_torrents})
    @type torrent_list: list

    @return: L{Torrent} instance, or -1 if not found
    """
    for t in torrent_list:
        if t.info_hash == info_hash:
            return t
    return -1


def dewPointTemp(theta, e):
    """
    Calculates the dew point temperature.
    theta has to be in Kelvin and e in kPa
    """
    import numpy as np
    ln = np.log(e / 0.611)
    coef = ln / (17.502 - ln)
    return 240.97 * coef + 273.16


def map_id_to_word(integer, tokenizer):
    """
    This methods retuns the english word, which
    corresponse to to given integer. If no
    word exists in the tokenizer the method returns None.

    :param int integer: numerical representation of a word
    :param Tokenizer tokenizer: Tokenizer

    :return str word: word OR None, if no matching word was found
    """
    for word, index in tokenizer.word_index.items():
        if index == integer:
            return word
    return None


def clear(zelf):
    """ Clear the ready flag. """
    zelf._ready.clear()


@staticmethod
def mm_to_px(measure):
    """Convert millimeters to pixel."""
    return measure * 3.779527559


def parse_frog(lines):
    """
    Interpret the output of the frog parser.
    Input should be a sequence of lines (i.e. the output of call_frog)
    Result is a sequence of dicts representing the tokens
    """
    sid = 0
    for i, l in enumerate(lines):
        if not l:
            sid += 1
        else:
            print(l.strip())
            parts = l.split('\t')
            tid, token, lemma, morph, pos, conf, ne, _, parent, rel = parts
            if rel:
                rel = rel, int(parent) - 1
            r = dict(id=i, sentence=sid, word=token, lemma=lemma, pos=pos,
                pos_confidence=float(conf), rel=rel)
            if ne != 'O':
                r['ne'] = ne.split('_', 1)[0][2:]
            yield r


def _delta_te(in_values, te1=None, te2=None):
    """Read :math:`\\Delta_	ext{TE}` from BIDS metadata dict"""
    if isinstance(in_values, float):
        te2 = in_values
        te1 = 0.0
    if isinstance(in_values, dict):
        te1 = in_values.get('EchoTime1')
        te2 = in_values.get('EchoTime2')
        if not all((te1, te2)):
            te2 = in_values.get('EchoTimeDifference')
            te1 = 0
    if isinstance(in_values, list):
        te2, te1 = in_values
        if isinstance(te1, list):
            te1 = te1[1]
        if isinstance(te2, list):
            te2 = te2[1]
    if te1 is None and te2 is None:
        raise RuntimeError(
            'EchoTime1 and EchoTime2 metadata fields not found. Please consult the BIDS specification.'
            )
    if te1 is None:
        raise RuntimeError(
            'EchoTime1 metadata field not found. Please consult the BIDS specification.'
            )
    if te2 is None:
        raise RuntimeError(
            'EchoTime2 metadata field not found. Please consult the BIDS specification.'
            )
    return abs(float(te2) - float(te1))


def is_cython_function(fn):
    """Checks if a function is compiled w/Cython."""
    if hasattr(fn, '__func__'):
        fn = fn.__func__
    name = type(fn).__name__
    return (name == 'method_descriptor' or name ==
        'cython_function_or_method' or name == 'builtin_function_or_method')


def __updatedict__(dm, ds):
    """Update content from ds in dm, if no exists then create it."""
    for key in ds.keys():
        if isinstance(ds[key], dict):
            if key in dm:
                ds[key].update(dm[key])
        elif isinstance(ds[key], list):
            if key in dm:
                ds[key] = set(ds[key] + dm[key])
        elif isinstance(ds[key], (int, float, str, bytes)):
            if key in dm:
                ds[key] = dm[key]
    dm.update(ds)
    return dm


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

        :param FileCommentsChangePolicyDetails val:
        :rtype: EventDetails
        """
    return cls('file_comments_change_policy_details', val)


def _nuc_pad_missing(nuc_alns, gen_lens):
    """
    >>> _nuc_pad_missing(['AAAAAAA'], gen_lens=[3, 5, 4])
    ['***', 'AAAAAAA', '****']
    """
    assert len(gen_lens) == len(nuc_alns) * 2 + 1
    alns = []
    for i, aln in enumerate(nuc_alns):
        alns.append('*' * gen_lens[i * 2])
        alns.append(aln)
    alns.append('*' * gen_lens[-1])
    return alns


def find_routes(routes, uri, decomposed_uri=None):
    """ Returns routes matching the given URL.
    """
    sub_num = 0
    uri_no_sub = None
    if decomposed_uri is not None:
        uri_no_sub, sub_num = decomposed_uri
    res = []
    for route in routes:
        route_params = route.matchUri(uri)
        if route_params is not None:
            res.append((route, route_params, 1))
    if sub_num > 1:
        for route in routes:
            route_params = route.matchUri(uri_no_sub)
            if route_params is not None:
                res.append((route, route_params, sub_num))
    return res


def asint(text):
    """
    Safely converts a string to an integer, returning ``None`` if the string is ``None``.

    :type text: str
    :rtype: int

    """
    if text is not None:
        return int(text)


def inside(point):
    """Return True if point on screen."""
    return -200 < point.x < 200 and -200 < point.y < 200


@classmethod
def from_dict(cls, data):
    """Create SkyModel from dict"""
    from gammapy.modeling.models import SPATIAL_MODELS, SPECTRAL_MODELS, TEMPORAL_MODELS
    model_class = SPECTRAL_MODELS.get_cls(data['spectral']['type'])
    spectral_model = model_class.from_dict(data['spectral'])
    spatial_data = data.get('spatial')
    if spatial_data is not None:
        model_class = SPATIAL_MODELS.get_cls(spatial_data['type'])
        spatial_model = model_class.from_dict(spatial_data)
    else:
        spatial_model = None
    temporal_data = data.get('temporal')
    if temporal_data is not None:
        model_class = TEMPORAL_MODELS.get_cls(temporal_data['type'])
        temporal_model = model_class.from_dict(temporal_data)
    else:
        temporal_model = None
    return cls(name=data['name'], spatial_model=spatial_model,
        spectral_model=spectral_model, temporal_model=temporal_model,
        apply_irf=data.get('apply_irf', cls._apply_irf_default),
        datasets_names=data.get('datasets_names'))


def get_func_description_from_docstring(docstring):
    """
    Get the string of the function's description in docstring.

    Parameters
    ----------
    docstring : str
        Target docstring.

    Returns
    ----------
    func_description : str
        Description of the function in docstring.
    """
    if docstring == '':
        return ''
    last_line_num = 0
    line_splitted_list = docstring.split('\n')
    for line_str in line_splitted_list:
        is_hyphen_line = '----' in line_str
        if is_hyphen_line:
            last_line_num -= 1
            break
        last_line_num += 1
    if last_line_num <= 0:
        return ''
    func_description = '\n'.join(line_splitted_list[:last_line_num])
    func_description = func_description.strip()
    if func_description.replace(' ', '') == '':
        return ''
    if not func_description.startswith('    '):
        func_description = '    %s' % func_description
    return func_description


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

        :param PaperPublishedLinkChangePermissionType val:
        :rtype: EventType
        """
    return cls('paper_published_link_change_permission', val)


def remove_duplicates(list_of_tuples):
    """
    Takes a list of tuples and removes duplicate entries.
    Reverses the pairs (0, 1, 2, 3) to (2, 3, 0, 1) for comparison.
    :param list_of_tuples: [(0, 1, 2, 3), (2, 3, 0, 1)]
    :return: List of unique tuples.
    """
    reduced = set()
    for i in list_of_tuples:
        if not (i[2], i[3], i[0], i[1]) in reduced:
            reduced.add(i)
    return list(reduced)


def parse_gcc_style_error_message(message, filename, has_column=True):
    """Parse GCC-style error message.

    Return (line_number, message). Raise ValueError if message cannot be
    parsed.

    """
    colons = 2 if has_column else 1
    prefix = filename + ':'
    if not message.startswith(prefix):
        raise ValueError()
    message = message[len(prefix):]
    split_message = message.split(':', colons)
    line_number = int(split_message[0])
    return line_number, split_message[colons].strip()


def value():
    """Return the value of the object.

        :return: value

        """

    def fget(self):
        return self._value

    def fset(self, value):
        self._value = value
    return locals()


def _get_builtin_permissions(report):
    """
    Return (codename, name) for all autogenerated permissions.
    By default, this is ('add', 'change', 'delete', 'view')
    """
    default_permissions = ['print', 'view']
    perms = []
    for action in default_permissions:
        permission_name = '%s_%s' % (action, report.get_report_slug())
        perms.append((permission_name, 'Can %s %s' % (action, report.
            report_title)))
    return perms


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


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 group_add():
    """Add an object to a new group

    """
    pass


def strf2(val):
    """Formate une valeur float avec mantisse de taille raisonnable"""
    if val == 0.0:
        return '0.0'
    elif abs(val) > 1.0:
        strg = '{0:.2f}'.format(val)
    elif abs(val) > 0.01:
        strg = '{0:.4f}'.format(val)
        if strg[-2:] == '00':
            return strg[:-2]
        elif strg[-1:] == '0':
            return strg[:-1]
        else:
            return strg
    else:
        return '{0:.7e}'.format(val)
    if strg[-3:] == '000':
        return strg[:-3]
    elif strg[-2:] == '00':
        return strg[:-2]
    else:
        return strg


def unique_check(df):
    """
    Returns the count of duplicate rows and the Dataframe
    :param df: df['Column']
    :return:len(duplicate),dfDuplicates
    """
    report_df = df[df.duplicated(keep=False)]
    report_length = len(report_df)
    return report_length, report_df


@classmethod
def from_data(cls, reddit, data):
    """Return an instance of Redditor, or None from ``data``."""
    if data == '[deleted]':
        return None
    return cls(reddit, data)


def theta_Br_Cl_PK74(T, P):
    """a-a': bromide chloride [PK74]."""
    theta = 0.0
    valid = T == 298.15
    return theta, valid


def do_filesizeformat(value, binary=False):
    """Format the value like a 'human-readable' file size (i.e. 13 kB,
    4.1 MB, 102 Bytes, etc).  Per default decimal prefixes are used (Mega,
    Giga, etc.), if the second parameter is set to `True` the binary
    prefixes are used (Mebi, Gibi).
    """
    bytes = float(value)
    base = binary and 1024 or 1000
    prefixes = [binary and 'KiB' or 'kB', binary and 'MiB' or 'MB', binary and
        'GiB' or 'GB', binary and 'TiB' or 'TB', binary and 'PiB' or 'PB',
        binary and 'EiB' or 'EB', binary and 'ZiB' or 'ZB', binary and
        'YiB' or 'YB']
    if bytes == 1:
        return '1 Byte'
    elif bytes < base:
        return '%d Bytes' % bytes
    else:
        for i, prefix in enumerate(prefixes):
            unit = base ** (i + 2)
            if bytes < unit:
                return '%.1f %s' % (base * bytes / unit, prefix)
        return '%.1f %s' % (base * bytes / unit, prefix)


def to_bool(val):
    """Convert val to True or False.

    Converts 'true' (case-insensitive) and 1, '1', or True to True.
    Converts 'false', 'null' or 'none' (case-insensitive), the empty string '',
    and 0, '0', or False to False.
    Raises a ValueError for any other input.

    >>> to_bool('true')
    True
    >>> to_bool('False')
    False
    >>> to_bool(0)
    False
    >>> to_bool('0')
    False
    >>> to_bool(None)
    False
    >>> to_bool('yes')
    ValueError("Invalid boolean value 'yes'")
    """
    strval = str(val).lower()
    if strval in ('true', '1'):
        return True
    elif strval in ('false', '0', 'null', 'none', ''):
        return False
    else:
        raise ValueError(f'Invalid boolean value {val!r}')


@staticmethod
def check_code(code):
    """ Check is code is authorized """
    if 'input' in code:
        return '', 'input command is not allowed'
    elif 'reset' in code:
        return 'reset -f', 'Resetting namespace...'
    else:
        return code, None


@classmethod
def copy(cls, graph):
    """Copy the input graph object."""
    new_graph = cls()
    new_graph.add_nodes_from(graph.nodes(data=True))
    new_graph.add_edges_from(graph.edges(data=True))
    return new_graph


def parse_kwargs(kwargs, *keys, **keyvalues):
    """Return dict with keys from keys|keyvals and values from kwargs|keyvals.

    Existing keys are deleted from kwargs.

    >>> kwargs = {'one': 1, 'two': 2, 'four': 4}
    >>> kwargs2 = parse_kwargs(kwargs, 'two', 'three', four=None, five=5)
    >>> kwargs == {'one': 1}
    True
    >>> kwargs2 == {'two': 2, 'four': 4, 'five': 5}
    True

    """
    result = {}
    for key in keys:
        if key in kwargs:
            result[key] = kwargs[key]
            del kwargs[key]
    for key, value in keyvalues.items():
        if key in kwargs:
            result[key] = kwargs[key]
            del kwargs[key]
        else:
            result[key] = value
    return result


def reste(a, b):
    """Renvoie le reste de la division de ``a`` par ``b``.

    Arguments:
        a (int): Un nombre entier.
        b (int): Un nombre entier non nul.
    """
    r = a % b
    if r < 0:
        r = r + abs(b)
    return r


def read_charge(element):
    """Returns an integer corresponding to the charge of the element, up to 9.
    Example: read_charge('Xe^2+')
    """
    if element.endswith('+'):
        try:
            return int(element.split('+')[0][-1:])
        except ValueError:
            return 1
    elif element.endswith('-'):
        try:
            return -int(element.split('-')[0][-1:])
        except ValueError:
            return -1
    else:
        return 0


def get_paginator(operation_name=None):
    """
    Create a paginator for an operation.

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

    :rtype: L{botocore.paginate.Paginator}
    """
    pass


def filetypes():
    """Get supported text filetypes for network import."""
    return {'ini': 'Nemoa Network Description', 'txt':
        'Nemoa Network Description'}


def _set_map_float(src_dict, dst_proto, attr_name):
    """ Setter for a dictionary of floats """
    if src_dict[attr_name] is None:
        return
    for key, value in src_dict[attr_name].items():
        if value is None:
            continue
        getattr(dst_proto, attr_name)[key] = float(value)


def encode_int(value):
    """Integer is an acceptable type, so we just return it"""
    return value


@staticmethod
def _check_contains_key(file, dictionary, key):
    """
        :param str file: The reference file, which to give in the error message
        :param dict dictionary: the dict to check the key's existance
        :param str key: the key to check for
        :raises ValueError

        Checks if a dict originating from a certain file contains a certain key and raises an exception otherwise
        """
    if key not in dictionary:
        raise ValueError(
            'Could not find %s in %s, record folder seems not to be valid!' %
            (key, file))


def calc_pdo(shoot_pctg: float, save_pctg: float) ->float:
    """
    Calculates an advanced hockey statistic known as PDO or SPSV%.  Note: this is not a true PDO calculation
    because it is not calculated for teams at 'even strength'.

    :param shoot_pctg: A team's shooting percentage.
    :param save_pctg: A team's save percentage.
    :return: PDO (SPSV%) stat = (shoot_pctg + save_pctg * 100) * 10
    """
    return (shoot_pctg + save_pctg * 100) * 10


def raise_(exception=None):
    """Raises an exception. This works very similarly to the raise
    statement except it is a function and thus an expression. For
    maximum compatibility between Python 2 and 3, raise_() takes at
    most one argument and does not support the "raise from" syntax or
    the 3-argument raise statement form. See the following example use
    case, which is a frequent idiom in Ruby and Perl but is not
    possible by default in Python, due to its statement rules.

    result = do_some_work() or raise_(Exception("Error: work failed"))

    do_some_work() would be a function which returns None if it fails
    or the result if it succeeds. So the exception is raised if the
    function fails.

    """
    if exception is None:
        raise
    else:
        raise exception


def get_doc():
    """Get documentation of this resource

    :return: rst string
    :rtype: str
    """
    return """
    The ``alignak`` model is used to store the global configuration of an Alignak instance.

    """


def get_fake_paramset():
    """get a fake profile"""
    t_low = 17
    t_med = 20.5
    t_hig = 21
    profile = {}
    profile['TEMPERATURE_MONDAY_1'] = t_low
    profile['TEMPERATURE_MONDAY_2'] = t_hig
    profile['TEMPERATURE_MONDAY_3'] = t_low
    profile['TEMPERATURE_MONDAY_4'] = t_med
    profile['TEMPERATURE_MONDAY_5'] = t_low
    profile['TEMPERATURE_MONDAY_6'] = t_low
    profile['TEMPERATURE_MONDAY_7'] = t_low
    profile['TEMPERATURE_MONDAY_8'] = t_low
    profile['TEMPERATURE_MONDAY_9'] = t_low
    profile['TEMPERATURE_MONDAY_10'] = t_low
    profile['TEMPERATURE_MONDAY_11'] = t_low
    profile['TEMPERATURE_MONDAY_12'] = t_low
    profile['TEMPERATURE_MONDAY_13'] = t_low
    profile['TEMPERATURE_TUESDAY_1'] = t_low
    profile['TEMPERATURE_TUESDAY_2'] = t_hig
    profile['TEMPERATURE_TUESDAY_3'] = t_low
    profile['TEMPERATURE_TUESDAY_4'] = t_med
    profile['TEMPERATURE_TUESDAY_5'] = t_low
    profile['TEMPERATURE_TUESDAY_6'] = t_low
    profile['TEMPERATURE_TUESDAY_7'] = t_low
    profile['TEMPERATURE_TUESDAY_8'] = t_low
    profile['TEMPERATURE_TUESDAY_9'] = t_low
    profile['TEMPERATURE_TUESDAY_10'] = t_low
    profile['TEMPERATURE_TUESDAY_11'] = t_low
    profile['TEMPERATURE_TUESDAY_12'] = t_low
    profile['TEMPERATURE_TUESDAY_13'] = t_low
    profile['TEMPERATURE_WEDNESDAY_1'] = t_low
    profile['TEMPERATURE_WEDNESDAY_2'] = t_hig
    profile['TEMPERATURE_WEDNESDAY_3'] = t_low
    profile['TEMPERATURE_WEDNESDAY_4'] = t_med
    profile['TEMPERATURE_WEDNESDAY_5'] = t_low
    profile['TEMPERATURE_WEDNESDAY_6'] = t_low
    profile['TEMPERATURE_WEDNESDAY_7'] = t_low
    profile['TEMPERATURE_WEDNESDAY_8'] = t_low
    profile['TEMPERATURE_WEDNESDAY_9'] = t_low
    profile['TEMPERATURE_WEDNESDAY_10'] = t_low
    profile['TEMPERATURE_WEDNESDAY_11'] = t_low
    profile['TEMPERATURE_WEDNESDAY_12'] = t_low
    profile['TEMPERATURE_WEDNESDAY_13'] = t_low
    profile['TEMPERATURE_THURSDAY_1'] = t_low
    profile['TEMPERATURE_THURSDAY_2'] = t_hig
    profile['TEMPERATURE_THURSDAY_3'] = t_low
    profile['TEMPERATURE_THURSDAY_4'] = t_med
    profile['TEMPERATURE_THURSDAY_5'] = t_low
    profile['TEMPERATURE_THURSDAY_6'] = t_low
    profile['TEMPERATURE_THURSDAY_7'] = t_low
    profile['TEMPERATURE_THURSDAY_8'] = t_low
    profile['TEMPERATURE_THURSDAY_9'] = t_low
    profile['TEMPERATURE_THURSDAY_10'] = t_low
    profile['TEMPERATURE_THURSDAY_11'] = t_low
    profile['TEMPERATURE_THURSDAY_12'] = t_low
    profile['TEMPERATURE_THURSDAY_13'] = t_low
    profile['TEMPERATURE_FRIDAY_1'] = t_low
    profile['TEMPERATURE_FRIDAY_2'] = t_hig
    profile['TEMPERATURE_FRIDAY_3'] = t_low
    profile['TEMPERATURE_FRIDAY_4'] = t_med
    profile['TEMPERATURE_FRIDAY_5'] = t_low
    profile['TEMPERATURE_FRIDAY_6'] = t_low
    profile['TEMPERATURE_FRIDAY_7'] = t_low
    profile['TEMPERATURE_FRIDAY_8'] = t_low
    profile['TEMPERATURE_FRIDAY_9'] = t_low
    profile['TEMPERATURE_FRIDAY_10'] = t_low
    profile['TEMPERATURE_FRIDAY_11'] = t_low
    profile['TEMPERATURE_FRIDAY_12'] = t_low
    profile['TEMPERATURE_FRIDAY_13'] = t_low
    profile['TEMPERATURE_SATURDAY_1'] = t_low
    profile['TEMPERATURE_SATURDAY_2'] = t_hig
    profile['TEMPERATURE_SATURDAY_3'] = t_low
    profile['TEMPERATURE_SATURDAY_4'] = t_med
    profile['TEMPERATURE_SATURDAY_5'] = t_low
    profile['TEMPERATURE_SATURDAY_6'] = t_low
    profile['TEMPERATURE_SATURDAY_7'] = t_low
    profile['TEMPERATURE_SATURDAY_8'] = t_low
    profile['TEMPERATURE_SATURDAY_9'] = t_low
    profile['TEMPERATURE_SATURDAY_10'] = t_low
    profile['TEMPERATURE_SATURDAY_11'] = t_low
    profile['TEMPERATURE_SATURDAY_12'] = t_low
    profile['TEMPERATURE_SATURDAY_13'] = t_low
    profile['TEMPERATURE_SUNDAY_1'] = t_low
    profile['TEMPERATURE_SUNDAY_2'] = t_hig
    profile['TEMPERATURE_SUNDAY_3'] = t_low
    profile['TEMPERATURE_SUNDAY_4'] = t_med
    profile['TEMPERATURE_SUNDAY_5'] = t_low
    profile['TEMPERATURE_SUNDAY_6'] = t_low
    profile['TEMPERATURE_SUNDAY_7'] = t_low
    profile['TEMPERATURE_SUNDAY_8'] = t_low
    profile['TEMPERATURE_SUNDAY_9'] = t_low
    profile['TEMPERATURE_SUNDAY_10'] = t_low
    profile['TEMPERATURE_SUNDAY_11'] = t_low
    profile['TEMPERATURE_SUNDAY_12'] = t_low
    profile['TEMPERATURE_SUNDAY_13'] = t_low
    profile['ENDTIME_MONDAY_1'] = 60 * 5 + 30
    profile['ENDTIME_MONDAY_2'] = 60 * 7 + 0
    profile['ENDTIME_MONDAY_3'] = 60 * 16 + 0
    profile['ENDTIME_MONDAY_4'] = 60 * 21 + 0
    profile['ENDTIME_MONDAY_5'] = 60 * 23 + 0
    profile['ENDTIME_MONDAY_6'] = 60 * 24 + 0
    profile['ENDTIME_MONDAY_7'] = 60 * 24 + 0
    profile['ENDTIME_MONDAY_8'] = 60 * 24 + 0
    profile['ENDTIME_MONDAY_9'] = 60 * 24 + 0
    profile['ENDTIME_MONDAY_10'] = 60 * 24 + 0
    profile['ENDTIME_MONDAY_11'] = 60 * 24 + 0
    profile['ENDTIME_MONDAY_12'] = 60 * 24 + 0
    profile['ENDTIME_MONDAY_13'] = 60 * 24 + 0
    profile['ENDTIME_TUESDAY_1'] = 60 * 5 + 30
    profile['ENDTIME_TUESDAY_2'] = 60 * 7 + 0
    profile['ENDTIME_TUESDAY_3'] = 60 * 16 + 0
    profile['ENDTIME_TUESDAY_4'] = 60 * 21 + 0
    profile['ENDTIME_TUESDAY_5'] = 60 * 23 + 0
    profile['ENDTIME_TUESDAY_6'] = 60 * 24 + 0
    profile['ENDTIME_TUESDAY_7'] = 60 * 24 + 0
    profile['ENDTIME_TUESDAY_8'] = 60 * 24 + 0
    profile['ENDTIME_TUESDAY_9'] = 60 * 24 + 0
    profile['ENDTIME_TUESDAY_10'] = 60 * 24 + 0
    profile['ENDTIME_TUESDAY_11'] = 60 * 24 + 0
    profile['ENDTIME_TUESDAY_12'] = 60 * 24 + 0
    profile['ENDTIME_TUESDAY_13'] = 60 * 24 + 0
    profile['ENDTIME_WEDNESDAY_1'] = 60 * 5 + 30
    profile['ENDTIME_WEDNESDAY_2'] = 60 * 7 + 0
    profile['ENDTIME_WEDNESDAY_3'] = 60 * 16 + 0
    profile['ENDTIME_WEDNESDAY_4'] = 60 * 21 + 0
    profile['ENDTIME_WEDNESDAY_5'] = 60 * 23 + 0
    profile['ENDTIME_WEDNESDAY_6'] = 60 * 24 + 0
    profile['ENDTIME_WEDNESDAY_7'] = 60 * 24 + 0
    profile['ENDTIME_WEDNESDAY_8'] = 60 * 24 + 0
    profile['ENDTIME_WEDNESDAY_9'] = 60 * 24 + 0
    profile['ENDTIME_WEDNESDAY_10'] = 60 * 24 + 0
    profile['ENDTIME_WEDNESDAY_11'] = 60 * 24 + 0
    profile['ENDTIME_WEDNESDAY_12'] = 60 * 24 + 0
    profile['ENDTIME_WEDNESDAY_13'] = 60 * 24 + 0
    profile['ENDTIME_THURSDAY_1'] = 60 * 5 + 30
    profile['ENDTIME_THURSDAY_2'] = 60 * 7 + 0
    profile['ENDTIME_THURSDAY_3'] = 60 * 16 + 0
    profile['ENDTIME_THURSDAY_4'] = 60 * 21 + 0
    profile['ENDTIME_THURSDAY_5'] = 60 * 23 + 0
    profile['ENDTIME_THURSDAY_6'] = 60 * 24 + 0
    profile['ENDTIME_THURSDAY_7'] = 60 * 24 + 0
    profile['ENDTIME_THURSDAY_8'] = 60 * 24 + 0
    profile['ENDTIME_THURSDAY_9'] = 60 * 24 + 0
    profile['ENDTIME_THURSDAY_10'] = 60 * 24 + 0
    profile['ENDTIME_THURSDAY_11'] = 60 * 24 + 0
    profile['ENDTIME_THURSDAY_12'] = 60 * 24 + 0
    profile['ENDTIME_THURSDAY_13'] = 60 * 24 + 0
    profile['ENDTIME_FRIDAY_1'] = 60 * 5 + 30
    profile['ENDTIME_FRIDAY_2'] = 60 * 7 + 0
    profile['ENDTIME_FRIDAY_3'] = 60 * 16 + 0
    profile['ENDTIME_FRIDAY_4'] = 60 * 21 + 0
    profile['ENDTIME_FRIDAY_5'] = 60 * 23 + 0
    profile['ENDTIME_FRIDAY_6'] = 60 * 24 + 0
    profile['ENDTIME_FRIDAY_7'] = 60 * 24 + 0
    profile['ENDTIME_FRIDAY_8'] = 60 * 24 + 0
    profile['ENDTIME_FRIDAY_9'] = 60 * 24 + 0
    profile['ENDTIME_FRIDAY_10'] = 60 * 24 + 0
    profile['ENDTIME_FRIDAY_11'] = 60 * 24 + 0
    profile['ENDTIME_FRIDAY_12'] = 60 * 24 + 0
    profile['ENDTIME_FRIDAY_13'] = 60 * 24 + 0
    profile['ENDTIME_SATURDAY_1'] = 60 * 5 + 30
    profile['ENDTIME_SATURDAY_2'] = 60 * 7 + 0
    profile['ENDTIME_SATURDAY_3'] = 60 * 16 + 0
    profile['ENDTIME_SATURDAY_4'] = 60 * 21 + 0
    profile['ENDTIME_SATURDAY_5'] = 60 * 23 + 0
    profile['ENDTIME_SATURDAY_6'] = 60 * 24 + 0
    profile['ENDTIME_SATURDAY_7'] = 60 * 24 + 0
    profile['ENDTIME_SATURDAY_8'] = 60 * 24 + 0
    profile['ENDTIME_SATURDAY_9'] = 60 * 24 + 0
    profile['ENDTIME_SATURDAY_10'] = 60 * 24 + 0
    profile['ENDTIME_SATURDAY_11'] = 60 * 24 + 0
    profile['ENDTIME_SATURDAY_12'] = 60 * 24 + 0
    profile['ENDTIME_SATURDAY_13'] = 60 * 24 + 0
    profile['ENDTIME_SUNDAY_1'] = 60 * 5 + 30
    profile['ENDTIME_SUNDAY_2'] = 60 * 7 + 0
    profile['ENDTIME_SUNDAY_3'] = 60 * 16 + 0
    profile['ENDTIME_SUNDAY_4'] = 60 * 21 + 0
    profile['ENDTIME_SUNDAY_5'] = 60 * 23 + 0
    profile['ENDTIME_SUNDAY_6'] = 60 * 24 + 0
    profile['ENDTIME_SUNDAY_7'] = 60 * 24 + 0
    profile['ENDTIME_SUNDAY_8'] = 60 * 24 + 0
    profile['ENDTIME_SUNDAY_9'] = 60 * 24 + 0
    profile['ENDTIME_SUNDAY_10'] = 60 * 24 + 0
    profile['ENDTIME_SUNDAY_11'] = 60 * 24 + 0
    profile['ENDTIME_SUNDAY_12'] = 60 * 24 + 0
    profile['ENDTIME_SUNDAY_13'] = 60 * 24 + 0
    return profile


def none_if_equals_filter(value, equal):
    """
    Returns 'None' if the input equals the other value, otherwise it returns the input.
    """
    if value == equal:
        return None
    else:
        return value


@classmethod
def load(cls, filename):
    """
        Load a staj file, returning an MlayerModel object
        """
    fin = open(filename, 'r')
    lines = fin.readlines()
    fin.close()
    self = cls()
    try:
        self._parse(lines)
    except:
        raise ValueError('Improper staj file')
    return self


def return_index(tup):
    """
    test if second element of tup is not empty
    """
    toreturn = False
    if len(tup[1]) > 0:
        toreturn = True
    return toreturn


def get_match_extension(using=None):
    """
    Gets the extension that the template loader will match for
    django-jinja. This returns Jinja2.match_extension.

    The "using" parameter selects with Jinja2 backend to use if
    you have multiple ones configured in settings.TEMPLATES.
    If it is None and only one Jinja2 backend is defined then it
    will use that, otherwise an ImproperlyConfigured exception
    is thrown.
    """
    from .backend import Jinja2
    from django.template import engines
    if using is None:
        engine = Jinja2.get_default()
    else:
        engine = engines[using]
    return engine.match_extension


def snap_cursor_to_active():
    """Snap 3D cursor to the active item

    """
    pass


def smart_convert(data_string):
    """
    Attempts to convert a raw string into the following data types, returns the first successful:
        int, float, boolean, str
    """
    value = data_string.strip()
    type_list = [int, float]
    for var_type in type_list:
        try:
            converted_var = var_type(value)
            return converted_var
        except ValueError:
            pass
    if value == 'True':
        return True
    if value == 'False':
        return False
    return str(value)


@classmethod
def class_unique_id(cls):
    """
        具体ump类关键字唯一名称，类方法：return 'deg_edge'
        主要针对外部user设置自定义ump使用, 需要user自己保证class_unique_id的唯一性，内部不做检测
        具体使用见ABuUmpManager中extend_ump_block方法
        """
    return 'deg_edge'


@staticmethod
def has_battery():
    """Return whether the device has a battery."""
    return False


def validate_bool_kwarg(value, arg_name):
    """ Ensures that argument passed in arg_name is of type bool. """
    if not (isinstance(value, bool) or value is None):
        raise ValueError(
            'For argument "{}" expected type bool, received type {}.'.
            format(arg_name, type(value).__name__))
    return value


def get_col(rho):
    """
    Get the index (in the color palette) of the current  capacity usage.

    Parameters
    ----------
    rho: ``float``
        The capacity usage of a given powerline.

    Returns
    -------
    res: ``int``
        The integer (between 0 and 6) of this line capacity usage in terms of color.

    """
    if rho < 0.3:
        return 0
    if rho < 0.5:
        return 1
    if rho < 0.75:
        return 2
    if rho < 0.9:
        return 3
    if rho < 0.95:
        return 5
    return 6


@classmethod
def _emit_failed(cls):
    """Print FAILED on error."""
    cls._emit_message('FAILED\n')


def tidy_input_string(s):
    """Return string made lowercase and with all whitespace removed."""
    s = ''.join(s.split()).lower()
    return s


def censor(content_fragment, context):
    """
        Censors the content fragment appropriately and returns the censored value.

        :param content_fragment: The fragment being censored.
        :param context: The object that this content fragment should be censored
            with regard to. For example, the fragment's container or composite
            object that will hold the fragment.
        :return: The censored content fragment, if any censoring was done to it.
            May also raise a :class:`ValueError` if censoring is not
            allowed and the content should be thrown away.
        """


def variational_distance_pmf(p, q):
    """
    Compute the variational distance.

    Parameters
    ----------
    p : np.ndarray
        The first pmf.
    q : np.ndarray
        The second pmf.

    Returns
    -------
    vd : float
        The variational distance.

    Notes
    -----
    `p` and `q` are assumed to be 1-to-1 with regards to events.
    """
    return abs(p - q).sum() / 2


def __iter__():
    """Iter throught storage keys.
        """


def archive_observer(population, num_generations, num_evaluations, args):
    """Print the current archive to the screen.

    This function displays the current archive of the evolutionary
    computation to the screen.

    .. Arguments:
       population -- the population of Individuals
       num_generations -- the number of elapsed generations
       num_evaluations -- the number of candidate solution evaluations
       args -- a dictionary of keyword arguments

    """
    archive = args['_ec'].archive
    print(
        '----------------------------------------------------------------------------'
        )
    print('                         Archive ({0:5} individuals)'.format(len
        (archive)))
    print(
        '----------------------------------------------------------------------------'
        )
    for a in archive:
        print(a)
    print(
        '----------------------------------------------------------------------------'
        )


def foldcase(text):
    """
    Fold the case of a text to lower case.
    """
    return text.lower()


def findValueTokenSet(reltoken, name):
    """Given a relationship token and a value name, return a set (based on
        the btree family for the value) of value tokens for that relationship.
        """


@classmethod
def _validate_key(cls, key):
    """Emit a warning or raise an exception if key is invalid. Returns key."""
    if isinstance(key, str):
        if '.' in key:
            from ..errors import InvalidKeyError
            raise InvalidKeyError("keys may not contain dots ('.'): {}".
                format(key))
        else:
            return key
    elif isinstance(key, cls.VALID_KEY_TYPES):
        return cls._validate_key(str(key))
    else:
        from ..errors import KeyTypeError
        raise KeyTypeError('keys must be str, int, bool or None, not {}'.
            format(type(key).__name__))


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 extract_view_name(view):
    """
    Extract view name
    :param view:
    :return:
    """
    if hasattr(view, '__name__'):
        return view.__name__
    else:
        return view.__class__.__name__


def getAllRowElements(rowname, elements):
    """
    Function purpose: help-function to get all row elements for a specific string

    Input: rowname, elements

    Output: array values
    """
    for idx, val in enumerate(elements[0]):
        if rowname in val.lower():
            indexOf = idx
            values = []
            for x in elements:
                if x[indexOf].lower() != rowname:
                    values.append(x[indexOf])
            return values


def bytes_to_num(bs: (bytes or bytearray)):
    """4位字节数组转为数字(256进制转10进制)"""
    return bs[0] * 16777216 + bs[1] * 65536 + bs[2] * 256 + bs[3]


def SetChannel(*args, **kwargs):
    """ Stub Anduin function."""
    print('SetChannel', args, kwargs)


def parameters_ui(layout, params):
    """ Create the ui for the rig parameters.

    """
    r = layout.row()
    r.label(text='Primary rotation axis:')
    r.prop(params, 'palm_rotation_axis', text='')


@classmethod
def is_writable(cls):
    """
        Check if this instrument is able to set any properties
        """
    return callable(getattr(cls, 'set_value', None)) or callable(getattr(
        cls, 'get_field', None)) or len(cls.get_writable_properties()) > 0


@staticmethod
def order_labels_for_hopping_ops(double_exc, gde):
    """
        Orders the hopping operators according to the grouped excitations for the full singlet
        UCCSD.

        Args:
            double_exc (list): list of double excitations
            gde (list of lists): list of grouped excitations for full singlet UCCSD

        Returns:
            list: ordered_labels to order hopping ops
        """
    labeled_de = []
    for i, _ in enumerate(double_exc):
        labeled_de.append((double_exc[i], i))
    ordered_labels = []
    for group in gde:
        for exc in group:
            for l_e in labeled_de:
                if exc == l_e[0]:
                    ordered_labels.append(l_e[1])
    return ordered_labels


def get_int(byte_array, signed=True):
    """
    Gets the specified integer from its byte array.
    This should be used by this module alone, as it works with big endian.

    :param byte_array: the byte array representing th integer.
    :param signed: whether the number is signed or not.
    :return: the integer representing the given byte array.
    """
    return int.from_bytes(byte_array, byteorder='big', signed=signed)


def aggregate_digit_span(data, sub_num):
    """
    Aggregate data from the digit span task.

    Calculates various summary statistics for the digit span task for a
    given subject.

    Parameters
    ----------
    data : dataframe
        Pandas dataframe containing a single subjects trial data for the task.
    sub_num : str
        Subject number to which the data file belongs.

    Returns
    -------
    stats : list
        List containing the calculated data for the subject.
    """
    digit_correct_count = data['correct'].sum()
    digit_correct_num_items = data.shape[0]
    digit_correct_prop = digit_correct_count / digit_correct_num_items
    return [sub_num, digit_correct_count, digit_correct_prop,
        digit_correct_num_items]


def remove_comments(css):
    """Remove all CSS comment blocks."""
    iemac, preserve = False, False
    comment_start = css.find('/*')
    while comment_start >= 0:
        preserve = css[comment_start + 2:comment_start + 3] == '!'
        comment_end = css.find('*/', comment_start + 2)
        if comment_end < 0:
            if not preserve:
                css = css[:comment_start]
                break
        elif comment_end >= comment_start + 2:
            if css[comment_end - 1] == '\\':
                comment_start = comment_end + 2
                iemac = True
            elif iemac:
                comment_start = comment_end + 2
                iemac = False
            elif not preserve:
                css = css[:comment_start] + css[comment_end + 2:]
            else:
                comment_start = comment_end + 2
        comment_start = css.find('/*', comment_start)
    return css


@staticmethod
def slice_query(table, slice_length):
    """
        Slice query for entire table,
        It will just return the same result as query.all() but safely for memory cache.
        回傳值等同 query.all(), 但能確保在低記憶體主機上安全執行.
        """
    count = 0
    results = list()
    while True:
        start = slice_length * count
        end = slice_length * (count + 1)
        slice_cache = table.query.slice(start, end).all()
        if slice_cache:
            results.extend(slice_cache)
        if len(slice_cache) < slice_length:
            break
        count += 1
    return results


def from_settings(settings):
    """
        setup the endpoint from settings
        """


@classmethod
def _get_raw_data_files(cls, f, folder):
    """
            Processes DataContainer.xml and returns a list of xml raw data
            filepaths and the sample name
        """
    contf = f.open('%s/DataContainer.xml' % folder, cls.__file_mode__)
    data = contf.read()
    contf.close()
    _, root = cls.get_xml_for_string(data)
    sample_name = root.find('./MeasurementInfo').get('SampleName')
    raw_data_files = []
    for child in root.find('./RawDataReferenceList'):
        raw_data_files.append(child.text)
    return raw_data_files, sample_name


def _get_type(typ):
    """
    Return the HPCC data type equivalent of a pandas/ numpy dtype.

    Parameters
    ----------
    typ: dtype
        Numpy or pandas dtype.

    Returns
    -------
    type: string
        ECL data type.
    """
    typ = str(typ)
    if 'float' in typ:
        pass
    elif 'int' in typ:
        pass
    elif 'bool' in typ:
        pass
    else:
        pass
    return 'STRING'


@classmethod
def can_send(cls, device, notice_type):
    """
        Check if the given device has the given `notice_type` enabled
        """
    try:
        notification_setting = cls.objects.get(device=device, name=notice_type)
    except cls.DoesNotExist:
        notification_setting = cls.objects.create(device=device, name=
            notice_type)
    return notification_setting.send


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


def chunked(iterable, size):
    """Yields chunks of the requested size from the iterable.  The final chunk
    may be smaller than size"""
    if not size:
        for item in iterable:
            yield item
        return
    chunk = []
    for i, item in enumerate(iterable):
        chunk.append(item)
        if len(chunk) == size:
            yield chunk
            chunk = []
    if chunk:
        yield chunk


def _need_loop(v):
    """
    if a variable should loop to concat string
    :param v: any variable
    :return: Boolean
    """
    return isinstance(v, list) or isinstance(v, dict) or isinstance(v, tuple)


def __repr__(A):
    """For `print` and `pprint`"""
    return A.to_str()


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


def normalize_notorch(dataset):
    """Normalize data when torch is unavailable."""
    raise NotImplementedError(
        '"normalize_notorch( data )" not yet implemented.')


def write_ser(bufferdata, filename='ser'):
    """
    Write a ser file from FTICRData
    """
    with open(filename, 'wb') as f:
        for i in range(len(bufferdata)):
            for j in range(len(bufferdata[0])):
                f.write(bufferdata[i][j].astype('int32').tostring())


def autocomplete():
    """Evaluate the namespace up until the cursor and give a list of options or complete the name if there is only one

    """
    pass


def _parse_headers(header_strings):
    """Convert a list of 'key: value' strings into dict
	"""
    headers = {}
    for hs in header_strings:
        key, value = hs.split(':', 1)
        headers[key.strip()] = value.strip()
    return headers


@classmethod
def has_archiving(cls):
    """Returns whether it supports archiving items on the fetch process.

        :returns: this backend does not support items archive
        """
    return False


def get_service_type(f):
    """Retrieves service type from function."""
    return getattr(f, 'service_type', None)


def get_pmin(survey):
    """
   A function to get the pmin value for the aplpy chart, as a function of the instrument.

   Args:
      fc_params: the parameters of the finding charts (a dictionary)
   Returns:
      pmin (float): the pmin value
   """
    if survey in ['2MASS-J', '2MASS-H', '2MASS-K']:
        return 30.0
    else:
        return 10.0


def select_border(gesture_mode: int=0, xmin: int=0, xmax: int=0, ymin: int=
    0, ymax: int=0, extend: bool=True, axis_range: bool=False,
    include_handles: bool=False):
    """Select all keyframes within the specified region

    :param gesture_mode: Gesture Mode
    :type gesture_mode: int
    :param xmin: X Min
    :type xmin: int
    :param xmax: X Max
    :type xmax: int
    :param ymin: Y Min
    :type ymin: int
    :param ymax: Y Max
    :type ymax: int
    :param extend: Extend, Extend selection instead of deselecting everything first
    :type extend: bool
    :param axis_range: Axis Range
    :type axis_range: bool
    :param include_handles: Include Handles, Are handles tested individually against the selection criteria
    :type include_handles: bool
    """
    pass


def pass_func(*args):
    """A function that does nothing.

    Parameters
    ----------
    args
        Variable length argument list, it does not matter what or how many
        parameters you use. Does not accept keyword arguments.

    """
    pass


def close():
    """Close the file. See Python documentation for :class:`io.IOBase` for
        details.
        """


def pull_notebook_parameter(args, library_db, current_scene_db):
    """pulls parameters from a notebook into your scene"""
    from src.praxxis.sqlite import sqlite_parameter
    from src.praxxis.parameter import list_param
    params = list_param.list_notebook_param(args, library_db, current_scene_db)
    sqlite_parameter.set_many_params(current_scene_db, params)


def le(h):
    """
    Little-endian, takes a 16b number and returns an array arrange in little
    endian or [low_byte, high_byte].
    """
    h &= 65535
    return [h & 255, h >> 8]


@classmethod
def lowest(cls):
    """Returns a specific ``lowest`` version which always evaluates as older.

        You shall use this value in your :py:class:`VersionPick` dictionaries to match the oldest
        possible version of the product.
        """
    try:
        return cls._lowest
    except AttributeError:
        cls._lowest = cls('lowest')
        return cls._lowest


@classmethod
def from_pycbc(cls, pycbcseries, copy=True):
    """Convert a `pycbc.types.timeseries.TimeSeries` into a `TimeSeries`

        Parameters
        ----------
        pycbcseries : `pycbc.types.timeseries.TimeSeries`
            the input PyCBC `~pycbc.types.timeseries.TimeSeries` array

        copy : `bool`, optional, default: `True`
            if `True`, copy these data to a new array

        Returns
        -------
        timeseries : `TimeSeries`
            a GWpy version of the input timeseries
        """
    return cls(pycbcseries.data, t0=pycbcseries.start_time, dt=pycbcseries.
        delta_t, copy=copy)


@staticmethod
def _bin_to_int(v: str, num_value_bits: int) ->int:
    """Converts a binary string of n bits using two's complement to an integer."""
    if v.startswith('1'):
        int_v = int(v, 2) - 2 ** num_value_bits
    else:
        int_v = int(v, 2)
    return int_v


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

        :param UserSelectorArg val:
        :rtype: UserResendResult
        """
    return cls('invalid_user', val)


def col_names_to_lower(df):
    """Convert column names to lowercase and return dataframe.

    Args:
        df: Pandas dataframe.

    Returns:
        Original dataframe with converted column data.
    """
    return df.columns.str.lower()


def get_identifier_string(model, pk):
    """This must match haystack.utils.get_identifier exactly!"""
    return u'%s.%s.%s' % (model._meta.app_label, model._meta.module_name,
        str(pk).replace(' ', ''))


def atse_schemataMoveLeft(schema_id, schema_template, name, RESPONSE=None):
    """ move a schemata to the left"""


def pytest_sessionfinish(session, exitstatus):
    """ called after whole test run finished, right before returning the exit status to the system.

    :param _pytest.main.Session session: the pytest session object
    :param int exitstatus: the status which pytest will return to the system
    """


def _get_broadcast_shape(shape1, shape2):
    """Given two shapes that are not identical, find the shape
    that both input shapes can broadcast to."""
    if shape1 == shape2:
        return shape1
    length1 = len(shape1)
    length2 = len(shape2)
    if length1 > length2:
        shape = list(shape1)
    else:
        shape = list(shape2)
    i = max(length1, length2) - 1
    for a, b in zip(shape1[::-1], shape2[::-1]):
        if a != 1 and b != 1 and a != b:
            raise ValueError('shape1=%s is not broadcastable to shape2=%s' %
                (shape1, shape2))
        shape[i] = b if a == 1 else a
        i -= 1
    return tuple(shape)


def filter_tracks(track_threshold: float=5.0):
    """Filter tracks which has weirdly looking spikes in motion curves

    :param track_threshold: Track Threshold, Filter Threshold to select problematic tracks
    :type track_threshold: float
    """
    pass


def std_array(comment, valueType, ndim, **kwargs):
    """Description for standard array column with variable shape (used for smaller arrays)."""
    return dict(comment=comment, valueType=valueType, ndim=ndim,
        dataManagerType='StandardStMan', dataManagerGroup='StandardStMan',
        _c_order=True, option=0, maxlen=0, **kwargs)


def _check_not_tuple_of_2_elements(obj, obj_name='obj'):
    """Check object is not tuple or does not have 2 elements."""
    if not isinstance(obj, tuple) or len(obj) != 2:
        raise TypeError('%s must be a tuple of 2 elements.' % obj_name)


def filename_to_domain(filename):
    """[:-4] for the .txt at end
    """
    return filename.replace('-', '/')[:-4]


def _get_op_submodule_name(op_name, op_name_prefix, submodule_name_list):
    """Get the submodule name of a specific op"""
    assert op_name.startswith(op_name_prefix)
    for submodule_name in submodule_name_list:
        if op_name[len(op_name_prefix):].startswith(submodule_name):
            return submodule_name
    return ''


def __init__(object, depth, id_attr, children_attr, expanded_nodes=[]):
    """
        'object' is the object that is being wrapped

        'depth' is the positional depth of the node in the tree

        'id_attr' should point to an attribute/method name of 'object'
        (and all other wrapped objects), giving each object a unique
        id in the tree.

        'children_attr' should point to an attribute/method name of
        'object' containing/resulting object's children.

        'expanded_nodes' is a list containing ids of nodes that are
        expanded from the beginning.
        """


def sum(x):
    """
	Calculates sum of array
	"""
    total = 0
    for i in range(0, len(x)):
        total += x[i]
    return total


@classmethod
def get_values(cls):
    """Used by GUI tools and FilterParser to get/check acceptable values"""
    raise NotImplementedError


def _item_from(container, index):
    """Attempts to fetch a index/key from a given container."""
    if index is None:
        return container
    return container[index]


def whitespace_tokenize(text):
    """Runs basic whitespace cleaning and splitting on a piece of text."""
    text = text.strip()
    if not text:
        return []
    tokens = text.split()
    return tokens


def is_podcast_series_id(item_id):
    """Validate if ID is in the format of a Google Music series ID."""
    return len(item_id) == 27 and item_id.startswith('I')


def dict_to_sequence(d):
    """Returns an internal sequence dictionary update."""
    if hasattr(d, 'items'):
        d = d.items()
    return d


def isarray(var):
    """
    isarray - Returns True if the variable is a list
    """
    return isinstance(var, (list, tuple))


def describe_pattern(pattern):
    """
    Format the URL pattern for display in warning messages.
    """
    description = "'{}'".format(pattern.regex.pattern)
    if getattr(pattern, 'name', False):
        description += " [name='{}']".format(pattern.name)
    return description


@staticmethod
def dbm_to_watts(power_dbm):
    """Converts [dBm] to [W].

        Args:
            power_dbm (int, float): Power in [dBm].

        Returns:
            float: Power in [W].
        """
    power_W = 10.0 ** (power_dbm / 10.0) / 1000.0
    return power_W


def eyedropper_id():
    """Sample a data-block from the 3D View to store in a property

    """
    pass


@classmethod
def keys_info(cls, fqdn, key):
    """Retrieve key information."""
    return cls.json_get('%s/domains/%s/keys/%s' % (cls.api_url, fqdn, key))


def is_header_file(filename):
    """Returns true if the given file is identified as a C/C++ header file."""
    return filename.endswith(('.h', '.hpp', '.H', '.hh', '.hxx'))


def p_Argument(p):
    """Argument : ExtendedAttributeList OptionalOrRequiredArgument"""
    p[0] = p[2]
    p[0].extended_attributes = p[1]


@classmethod
def copy(cls, other):
    """Create a copy of another shape."""
    result = cls(**other._attributes)
    return result


def byte_to_gigabyte(byte):
    """
    Convert byte value to gigabyte
    """
    return byte / 1024.0 ** 3


def create_empty_data(child_list, evolved_kwargs):
    """
    Creates an empty transformer list.

    :param child_list: Child list, must be empty.
    :param evolved_kwargs: Keyword arguments, not used.
    :return:
    """
    if len(child_list) > 0:
        raise ValueError('This can be assigned only to terminals.')
    return []


@classmethod
def on_event_mapped(cls, controller, action2configure):
    """
    Callback function that is triggered, when an event was mapped

    :param action2configure:        the action that was mapped
    :type action2configure:         steuer.Action
    :param controller:              the controller the event was requested from
    :type controller:               steuer.Controller
    """
    print('EVENT:' + 'Controller {0}:{1} - action:{2} mapped'.format(
        controller.number, controller.name, action2configure.action))


def get_writer(file_format, writers, writer_base_class):
    """Returns a writer class for the given file format. This function mainly
    exists to catch ImportErrors, if a writer requires a missing library, and
    trying to find a writer, for which all dependencies are available.

    :param file_format: the file format flag from the enumeration, that lists
                        all available formats for the given data set class.
    :param writers: a dictionary, that maps file format flags to already existing
                    writer instances. If this function instantiates a new writer,
                    it will be added to that dictionary.
    :param writer_base_class: the base class for all writers. This function may
                              iterate over all sub-classes of this class, when
                              trying to create a suitable writer.
    :returns: a writer object, that can be called with the data set and the
              file path, in which the data set shall be saved.
    """
    if file_format in writers:
        return writers[file_format]
    else:
        for cls in writer_base_class.__subclasses__():
            if file_format in cls.formats:
                try:
                    writer = cls(file_format)
                except ImportError:
                    continue
                else:
                    writers[file_format] = writer
                    return writer
        raise ValueError(f'file format cannot be written: {file_format}')


@staticmethod
def read(path):
    """
        This can help you to read your file faster.
        Example:
            read('C:\\users\\Jack\\test.txt')
            ==> "Content of 'test.txt' will be shown."
        """
    op = open(path, mode='r')
    FileR = op.read()
    op.close()
    return FileR


def get_bootstrap_mds_key(cluster):
    """
    Read the bootstrap-mds key for `cluster`.
    """
    path = '{cluster}.bootstrap-mds.keyring'.format(cluster=cluster)
    try:
        with open(path, 'rb') as f:
            return f.read()
    except IOError:
        raise RuntimeError("bootstrap-mds keyring not found; run 'gatherkeys'")