def approximate_pubo_extrema(P):
    """approximate_pubo_extrema.

    Find the approximate minimum and maximum possible values that a PUBO can
    take. This is very approximate! The estimated minimum value that this
    function returns will definitely be less than or equal to the true
    minimum (most likely, it will be much less). Similarly, the estimated
    maximum value that this function returns will definitely be greater than or
    equal to the true maximum (most likely, it will be much more).

    Parameters
    ----------
    P : dict, PUBO, or PUBOMatrix object.
        ``P`` represents a PUBO. Please see ``qubovert.PUBO`` or
        ``qubovert.utils.PUBOMatrix``.

    Return
    ------
    bounds : tuple (min, max).
        The approximate minimum and maximum of the PUBO.

    """
    min_, max_ = 0, 0
    for k, v in P.items():
        if not k:
            min_ += v
            max_ += v
        elif v < 0:
            min_ += v
        else:
            max_ += v
    return min_, max_


@staticmethod
def get_human_uptime(uptime):
    """
        Convert a timespan of seconds into hours, days, ...

        :param uptime: Uptime in seconds
        :type uptime: int
        :return:
        """
    if uptime > 60 * 60 * 24:
        uptime_days = int(uptime / (60 * 60 * 24))
        uptime_hours = int((uptime - uptime_days * (60 * 60 * 24)) / (60 * 60))
        uptime_minutes = int((uptime - (uptime_days * (60 * 60 * 24) +
            uptime_hours * 60 * 60)) / 60)
        uptime_seconds = int(uptime - (uptime_days * (60 * 60 * 24) + (
            uptime_hours * (60 * 60) + uptime_minutes * 60)))
        uptime = str(uptime_days) + 'd:' + str(uptime_hours) + 'h:' + str(int
            (uptime_minutes)) + 'm:' + str(int(uptime_seconds)) + 's'
    elif uptime > 60 * 60:
        uptime_hours = int(uptime / (60 * 60))
        uptime_minutes = int((uptime - uptime_hours * (60 * 60)) / 60)
        uptime_seconds = int(uptime - (uptime_hours * (60 * 60) +
            uptime_minutes * 60))
        uptime = str(uptime_hours) + 'h:' + str(int(uptime_minutes)
            ) + 'm:' + str(int(uptime_seconds)) + 's'
    elif uptime > 60:
        uptime_minutes = int(uptime / 60)
        uptime_seconds = uptime - uptime_minutes * 60
        uptime = str(uptime_minutes) + 'm:' + str(int(uptime_seconds)) + 's'
    else:
        uptime = str(int(uptime)) + ' seconds'
    return uptime


def convert_param(parameter_dict, vals_as_string=False):
    """
    converts dictionary format {argument_name: value, argument_name: value, ...}
    to {'workflow_argument_name': argument_name, 'value': value}
    """
    metadata_parameters = []
    for k, v in parameter_dict.items():
        if not vals_as_string:
            try:
                v = float(v)
                if v % 1 == 0:
                    v = int(v)
            except ValueError:
                v = str(v)
        else:
            v = str(v)
        metadata_parameters.append({'workflow_argument_name': k, 'value': v})
    return metadata_parameters


def multi_sum_sq(*data, **kwargs):
    """Compute the sums of squares of multiple arrays

    Defined in src/operator/contrib/multi_sum_sq.cc:L36

    Parameters
    ----------
    data : NDArray[]
        Arrays
    num_arrays : int, required
        number of input arrays.

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

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


def 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 to_MB(value):
    """Приводит биты в МБ"""
    return value / 1024.0 / 1024.0


def Jogelkar(x, p):
    """Jogelkar window function.

    Parameters
    ----------
    x : float
        State variable.
    p : int
        p constant.
    """
    return (1 - (2 * x - 1)) ** (2 * p)


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 refresh_pyconstraints():
    """Refresh all pyconstraints

    """
    pass


def check_property_present(prop, obj1, obj2):
    """Helper method checks if a property is present on both objects."""
    if prop in obj1 and prop in obj2:
        return True
    return False


@staticmethod
def is_indicator():
    """ Determines if the object is a Indicator. """
    return False


def _maximal_independent_set(G):
    """Returns a maximal independent set of nodes in ``G`` by repeatedly
    choosing an independent node of minimum degree (with respect to the
    subgraph of unchosen nodes).

    """
    result = set()
    remaining = set(G)
    while remaining:
        G = G.subgraph(remaining)
        v = min(remaining, key=G.degree)
        result.add(v)
        remaining -= set(G[v]) | {v}
    return result


def _mix_colors(c1, c2, v):
    """Mixes two colors according to v in the 0-1 range
    where 0 only r1 and 1 only r2 and e.g. 0.5 is exactly in between"""
    r1, g1, b1 = c1
    r2, g2, b2 = c2
    return int(r2 * v + r1 * (1 - v)), int(g2 * v + g1 * (1 - v)), int(b2 *
        v + b1 * (1 - v))


def _range_to_slice(seq, length=None):
    """
    Returns a slice if possible (including for sequences of 1 element) otherwise returns the input sequence itself

    Parameters
    ----------
    seq : sequence-like of int
        List, tuple or ndarray of integers representing the range.
        It should be something like [start, start+step, start+2*step, ...]
    length : int, optional
        length of sequence of positions. This is only useful when you must be able to transform decreasing sequences
        which can stop at 0.

    Returns
    -------
    slice or sequence-like
        return the input sequence if a slice cannot be defined

    Examples
    --------
    >>> _range_to_slice([3, 4, 5])
    slice(3, 6, None)
    >>> _range_to_slice([3, 4, 6])
    [3, 4, 6]
    >>> _range_to_slice([3, 5, 7])
    slice(3, 9, 2)
    >>> _range_to_slice([-3, -2])
    slice(-3, -1, None)
    >>> _range_to_slice([-1, -2])
    slice(-1, -3, -1)
    >>> _range_to_slice([2, 1])
    slice(2, 0, -1)
    >>> _range_to_slice([1, 0], 4)
    slice(-3, -5, -1)
    >>> _range_to_slice([1, 0])
    [1, 0]
    >>> _range_to_slice([1])
    slice(1, 2, None)
    >>> _range_to_slice([])
    []
    """
    if len(seq) < 1:
        return seq
    start = seq[0]
    if len(seq) == 1:
        return slice(start, start + 1)
    second = seq[1]
    step = second - start
    prev_value = second
    for value in seq[2:]:
        if value != prev_value + step:
            return seq
        prev_value = value
    stop = prev_value + step
    if prev_value == 0 and step < 0:
        if length is None:
            return seq
        else:
            stop -= length
            start -= length
    if step == 1:
        step = None
    return slice(start, stop, step)


def error_handle(ans: dict):
    """
    лучше чем ничего
    """
    if 'error' in ans:
        if 'message' in ans['error']:
            print(ans['error']['message'])


@staticmethod
def _alert_summary(alert_row):
    """Return summarized string of alert properties."""
    if 'TI Risk' in alert_row:
        return (f'{alert_row.StartTimeUtc} - {alert_row.AlertName}' +
            f' - ({alert_row.CompromisedEntity}) ' +
            f' - [id:{alert_row.SystemAlertId}]' +
            f" - TI Risk: {alert_row['TI Risk']}")
    return (f'{alert_row.StartTimeUtc} - {alert_row.AlertName}' +
        f' - ({alert_row.CompromisedEntity}) ' +
        f' - [id:{alert_row.SystemAlertId}]')


def remove_b_for_nucl_phys(citation_elements):
    """Removes b from the volume of some journals

    Removes the B from the volume for Nucl.Phys.Proc.Suppl. because in INSPIRE
    that journal is handled differently.
    """
    for el in citation_elements:
        if el['type'] == 'JOURNAL' and el['title'
            ] == 'Nucl.Phys.Proc.Suppl.' and 'volume' in el and (el[
            'volume'].startswith('b') or el['volume'].startswith('B')):
            el['volume'] = el['volume'][1:]
    return citation_elements


@classmethod
def handle_cursor(cls, cursor, query, session):
    """Handle a live cursor between the execute and fetchall calls

        The flow works without this method doing anything, but it allows
        for handling the cursor and updating progress information in the
        query object"""
    pass


def phalf_from_ps(bk, pk, ps):
    """Compute pressure of half levels of hybrid sigma-pressure coordinates."""
    return ps * bk + pk


def get(name, default=None):
    """Return the named subclass if we contain it, else default"""


@classmethod
def read_chunk(cls, opc_sync: bool, context: str) ->'IoTransferEventArgs':
    """Creates new IoTransferEventArgs of read string

		:param opc_sync: defines if the command is OPC-synchronised
		:param context: SCPI query. It is truncated to maximum of 100 characters.
		:return: IoTransferEventArgs object of a read string operation."""
    return cls(True, opc_sync, None, context)


def check_coordinate_system(coordinate_system, valid_coord_systems=(
    'cartesian', 'spherical')):
    """
    Check if the coordinate system is a valid one.

    Parameters
    ----------
    coordinate_system : str
        Coordinate system to be checked.
    valid_coord_system : tuple or list (optional)
        Tuple or list containing the valid coordinate systems.
        Default (``cartesian``, ``spherical``).
    """
    if coordinate_system not in valid_coord_systems:
        raise ValueError('Coordinate system {} not recognized.'.format(
            coordinate_system))


def parse_chaos_parameters(chaos_parameters):
    """Parse ChaosParameters from string"""
    from azure.servicefabric.models import ChaosParameters, ChaosContext, ChaosTargetFilter
    from sfctl.custom_cluster_upgrade import create_cluster_health_policy
    time_to_run = chaos_parameters.get('TimeToRunInSeconds')
    max_cluster_stabilization = chaos_parameters.get(
        'MaxClusterStabilizationTimeoutInSeconds')
    max_concurrent_faults = chaos_parameters.get('MaxConcurrentFaults')
    enable_move_replica_faults = chaos_parameters.get('EnableMoveReplicaFaults'
        )
    wait_time_between_faults = chaos_parameters.get(
        'WaitTimeBetweenFaultsInSeconds')
    wait_time_between_iterations = chaos_parameters.get(
        'WaitTimeBetweenIterationsInSeconds')
    cluster_health_policy = chaos_parameters.get('ClusterHealthPolicy')
    health_policy = None
    if cluster_health_policy is not None:
        health_policy = create_cluster_health_policy(cluster_health_policy.
            get('ConsiderWarningAsError'), cluster_health_policy.get(
            'MaxPercentUnhealthyNodes'), cluster_health_policy.get(
            'MaxPercentUnhealthyApplications'), cluster_health_policy.get(
            'ApplicationTypeHealthPolicyMap'))
    chaos_context = chaos_parameters.get('Context')
    context = None
    if chaos_context is not None:
        context = ChaosContext(map=chaos_context.get('Map'))
    chaos_target_filter = chaos_parameters.get('ChaosTargetFilter')
    target_filter = None
    if chaos_target_filter is not None:
        target_filter = ChaosTargetFilter(node_type_inclusion_list=
            chaos_target_filter.get('NodeTypeInclusionList'),
            application_inclusion_list=chaos_target_filter.get(
            'ApplicationTypeInclusionList'))
    return ChaosParameters(time_to_run_in_seconds=time_to_run,
        max_cluster_stabilization_timeout_in_seconds=
        max_cluster_stabilization, max_concurrent_faults=
        max_concurrent_faults, enable_move_replica_faults=
        enable_move_replica_faults, wait_time_between_faults_in_seconds=
        wait_time_between_faults, wait_time_between_iterations_in_seconds=
        wait_time_between_iterations, cluster_health_policy=health_policy,
        context=context, chaos_target_filter=target_filter)


def _autotuple(a):
    """Automatically convert the supplied iterable to a scalar or tuple as appropriate."""
    if not hasattr(a, '__iter__'):
        return a
    if len(a) == 1:
        return a[0]
    return tuple(a)


def normals_make_consistent(calc_length: bool=False):
    """Recalculate the direction of selected handles

    :param calc_length: Length, Recalculate handle length
    :type calc_length: bool
    """
    pass


@classmethod
def can_solve(cls, resource):
    """Tells if the solver is able to resolve the given resource.

        Arguments
        ---------
        resource : subclass of ``dataql.resources.Resource``
            The resource to check if it is solvable by the current solver class

        Returns
        -------
        boolean
            ``True`` if the current solver class can solve the given resource, ``False`` otherwise.

        Example
        -------

        >>> AttributeSolver.solvable_resources
        (<class 'dataql.resources.Field'>,)
        >>> AttributeSolver.can_solve(Field('foo'))
        True
        >>> AttributeSolver.can_solve(Object('bar'))
        False

        """
    for solvable_resource in cls.solvable_resources:
        if isinstance(resource, solvable_resource):
            return True
    return False


def bezier_subdivide(cp, t):
    """
    Subdivide a cubic bezier curve defined by the control points `cp`.

    Parameters
    ----------
    cp : List[QPointF]
        The control points for a cubic bezier curve.
    t : float
        The cut point; a value between 0 and 1.

    Returns
    -------
    cp : Tuple[List[QPointF], List[QPointF]]
        Two lists of new control points for the new left and right part
        respectively.
    """
    c00, c01, c02, c03 = cp
    c10 = c00 * (1 - t) + c01 * t
    c11 = c01 * (1 - t) + c02 * t
    c12 = c02 * (1 - t) + c03 * t
    c20 = c10 * (1 - t) + c11 * t
    c21 = c11 * (1 - t) + c12 * t
    c30 = c20 * (1 - t) + c21 * t
    first = [c00, c10, c20, c30]
    second = [c30, c21, c12, c03]
    return first, second


def device_from_request(request):
    """
    Determine's the device name from the request by first looking for an
    overridding cookie, and if not found then matching the user agent.
    Used at both the template level for choosing the template to load and
    also at the cache level as a cache key prefix.
    """
    from mezzanine.conf import settings
    try:
        for device, _ in settings.DEVICE_USER_AGENTS:
            if device == request.COOKIES['mezzanine-device']:
                return device
    except KeyError:
        try:
            user_agent = request.META['HTTP_USER_AGENT'].lower()
        except KeyError:
            pass
        else:
            try:
                user_agent = user_agent.decode('utf-8')
            except (AttributeError, UnicodeDecodeError):
                pass
            for device, ua_strings in settings.DEVICE_USER_AGENTS:
                for ua_string in ua_strings:
                    if ua_string.lower() in user_agent:
                        return device
    return ''


def format_uptime(uptime_in_seconds):
    """Format number of seconds into human-readable string.

    :param uptime_in_seconds: The server uptime in seconds.
    :returns: A human-readable string representing the uptime.

    >>> uptime = format_uptime('56892')
    >>> print(uptime)
    15 hours 48 min 12 sec
    """
    m, s = divmod(int(uptime_in_seconds), 60)
    h, m = divmod(m, 60)
    d, h = divmod(h, 24)
    uptime_values = []
    for value, unit in ((d, 'days'), (h, 'hours'), (m, 'min'), (s, 'sec')):
        if value == 0 and not uptime_values:
            continue
        elif value == 1 and unit.endswith('s'):
            unit = unit[:-1]
        uptime_values.append('{0} {1}'.format(value, unit))
    uptime = ' '.join(uptime_values)
    return uptime


def bookmark_delete(index: int=-1):
    """Delete selected bookmark

    :param index: Index
    :type index: int
    """
    pass


def price_to_sales(price_per_share, sales_per_share):
    """Computes price to sales ratio.

    @params
    -------
    price_per_share: share price
    sales_per_share: sales (or revenue) per share

    returns
    -------
    Price to sales ratio, int or float

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

    """
    return price_per_share / sales_per_share


@classmethod
def _from_dict(cls, _dict):
    """Initialize a ContentItem object from a json dictionary."""
    args = {}
    if 'content' in _dict:
        args['content'] = _dict.get('content')
    else:
        raise ValueError(
            "Required property 'content' not present in ContentItem JSON")
    if 'id' in _dict:
        args['id'] = _dict.get('id')
    if 'created' in _dict:
        args['created'] = _dict.get('created')
    if 'updated' in _dict:
        args['updated'] = _dict.get('updated')
    if 'contenttype' in _dict:
        args['contenttype'] = _dict.get('contenttype')
    if 'language' in _dict:
        args['language'] = _dict.get('language')
    if 'parentid' in _dict:
        args['parentid'] = _dict.get('parentid')
    if 'reply' in _dict:
        args['reply'] = _dict.get('reply')
    if 'forward' in _dict:
        args['forward'] = _dict.get('forward')
    return cls(**args)


def _auxLogMinPsi(z_i, d, z0, Psi, Lm):
    """
    Auxiliar function that is used in the denominator of the C_tau-like coefficients

    Taken from Dias, Micrometeorological Approaches to to estimate fluxes of greenhouse gases between the surface and the
    atmosphere, (Chapter 7, eqs. 94-97, p. 22.)

    CONSIDER TAKING THIS SOMEWHERE ELSE!
    """
    import numpy as np
    if hasattr(Psi, '__call__') == False:
        raise TypeError('Psi argument has to be a function')
    a = np.log((z_i - d) / z0)
    b = Psi((z_i - d) / Lm)
    return a - b


def find_neighbors(tri):
    """
    The find_neighbors function performes the listing of all the neighboring
    nodes for each node in the triangulation. It is based on an idea provided
    at stackoverflow about listing the neighboring points of triangulation
    nodes.

    Parameters
    ----------
    tri: scipy.spatial.qhull.Delaunay
            Delaunay triangulation generated from the point_data variable.

    Returns
    -------
    neighbors: collections.defaultdict
            Sets of neighboring nodes for each node in the triangulation.

    Reference
    ---------
    .. [1] Answers provided by astrofrog and glyg at https://stackoverflow.com/questions/12374781/how-to-find-all-neighbors-of-a-given-point-in-a-delaunay-triangulation-using-sci/17811731.

    See also
    --------
    scipy.spatial: spatial algorithms and data structures.

    scipy.spatial.Delaunay: Delaunay tesselation in N dimensions.

    Usage
    -----
    >>> neighbors = basic_info.find_neighbors(tri)

    """
    from collections import defaultdict
    neighbors = defaultdict(set)
    for simplex in tri.simplices:
        for pid in simplex:
            other = set(simplex)
            other.remove(pid)
            neighbors[pid] = neighbors[pid].union(other)
    for node in range(len(neighbors)):
        len(neighbors[node])
    return neighbors


def check_date(data, theyear=None, themonth=None, full=False):
    """
    년도와 월 인자를 검사하는 함수이다.
    Args:
        data(pandas DF): 타자 또는 투수 데이터
        year(int): 찾는 년도로 없는 경우 최근 년도로 지정
        month(str): 입력은 06과 같은 스트링 타입 찾는 월로 없는 경우 년도별 정규시즌의 모든 월로 지정
        full(boolean): False가 기본 값으로 True 입력시 전체 데이터 반환
    Returns:
       output(pandas DF): 입력받은 년도하고 월에 따라 추출된 타자 또는 투수 데이터
    """
    if full == True:
        return data
    else:
        if theyear is None and themonth is None:
            return data[data.year == max(data.year)]
        if theyear is not None and themonth is None:
            return data[data.year == theyear]
        if theyear is None and themonth is not None:
            return data[data.month == themonth]
        if theyear is not None and themonth is not None:
            return data[(data.year == theyear) & (data.month == themonth)]


def get_pending_time(user_email):
    """
        returns a time indicating a user's pending status
        """


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 version():
    """
    Returns the library version
    :return:
    """
    return '1.2.0'


def is_iterable(obj):
    """Return True if the object is a list or a tuple.

    Parameters
    ----------
    obj : list or tuple
        Object to be tested.

    Returns
    -------
    bool
        True if the object is a list or a tuple.
    """
    return isinstance(obj, list) or isinstance(obj, tuple)


def ik_clear():
    """Remove all IK Constraints from selected bones

    """
    pass


@staticmethod
def write(writer, value):
    """
        Writes Zserio bool type to the bit stream.

        :param writer: Bit stream where to write.
        :param value: Zserio bool type to write.
        """
    writer.writeBool(value)


def bootstrap_pex_env(entry_point):
    """Bootstrap the current runtime environment using a given pex."""
    from .environment import PEXEnvironment
    from .finders import register_finders
    from .pex_info import PexInfo
    register_finders()
    PEXEnvironment(entry_point, PexInfo.from_pex(entry_point)).activate()


@classmethod
def remove(cls, pid):
    """Remove a pool, closing all connections

        :param str pid: The pool ID

        """
    with cls._lock:
        cls._ensure_pool_exists(pid)
        cls._pools[pid].close()
        del cls._pools[pid]


def __new__(cls, visibilities_1d, *args, **kwargs):
    """ A hyper array with square-pixels.

        Parameters
        ----------
        array_1d: ndarray
            An array representing image (e.g. an image, noise map, etc.)
        pixel_scales: (float, float)
            The arc-second to pixel conversion factor of each pixel.
        origin : (float, float)
            The arc-second origin of the hyper array's coordinate system.
        """
    obj = visibilities_1d.view(cls)
    return obj


@staticmethod
def delete_all_workflows(wf_ctrl, force=True):
    """
        Delete all the workflows.
        If force is set to True: the call will block until the workflows are
        deleted. With force set to True, if a workflow can not be deleted
        properly it is deleted from Soma-workflow database. However, if some
        jobs are still running they will not be killed. In this case the return
        value is False.

        Parameters
        ----------
        wf_ctrl: client.WorkflowController

        force: bool

        Returns
        -------
        success: bool
        """
    deleted_properly = True
    while wf_ctrl.workflows():
        wf_id = wf_ctrl.workflows().keys()[0]
        deleted_properly = deleted_properly and wf_ctrl.delete_workflow(wf_id,
            force)
    return deleted_properly


def print_clusterprocedure():
    """Print clustering guide."""
    print(
        """
          In ``PySPLIT``
          1. Create ``TrajectoryGroup`` with desired set of trajectories
          2. ``TrajectoryGroup.make_infile()``

          In ``HYSPLIT``
          3. Trajectory --> Special Runs --> Clustering --> Standard
          4. Adjust clustering parameters and working folder
             (where output will be stored, where INFILE lives)
          5. ``Run cluster analysis``
          6. Determine and set appropriate number of clusters
          7. Assign trajectories to clusters (``Run``)
          8. ``Display Means``, ``Quit``

          In ``PySPLIT``
          9. ``spawn_clusters()``"""
        )


def command(method):
    """ This is a decorator, put `@command` on top of the methods you want to
        set as command of your bot.

        Example usage:

            >>> class MyBot(Bot):
            ...     @command
            ...     def hello(self):
            ...             return "hello!"
            ...
            >>> bot = MyBot()
            >>> bot.process("/hello") # the default command prepend is "/"
            'hello!'

    """
    method.is_command = True
    return method


def contextfunction(f):
    """This decorator can be used to mark a function or method context callable.
    A context callable is passed the active :class:`Context` as first argument when
    called from the template.  This is useful if a function wants to get access
    to the context or functions provided on the context object.  For example
    a function that returns a sorted list of template variables the current
    template exports could look like this::

        @contextfunction
        def get_exported_names(context):
            return sorted(context.exported_vars)
    """
    f.contextfunction = True
    return f


def longzip(a, b):
    """Like `izip` but yields `None` for missing items."""
    aiter = iter(a)
    biter = iter(b)
    try:
        for item1 in aiter:
            yield item1, biter.next()
    except StopIteration:
        for item1 in aiter:
            yield item1, None
    else:
        for item2 in biter:
            yield None, item2


def _format(color):
    """Formats an r, g, b tuple as a hex encoded string"""
    return '{:02x}{:02x}{:02x}'.format(*color)


def get_posts(user_email):
    """
        returns as an iterable the list of all posts for a user
        """


@staticmethod
def _clear(queue):
    """ Only uses documented methods, but is slower. """
    while not queue.empty():
        queue.get()
        queue.task_done()


def list_routes(app):
    """
    debug to list routes for app
    """
    from urllib import parse
    from flask import url_for
    output = []
    for rule in app.url_map.iter_rules():
        options = {}
        for arg in rule.arguments:
            options[arg] = '[{0}]'.format(arg)
        methods = ','.join(rule.methods)
        url = url_for(rule.endpoint, **options)
        line = parse.unquote('{:50s} {:20s} {}'.format(rule.endpoint,
            methods, url))
        output.append(line)
    for line in sorted(output):
        print(line)


def keywithmaxval(d):
    """ a) create a list of the dict's keys and values;
         b) return the key with the max value"""
    v = list(d.values())
    k = list(d.keys())
    return k[v.index(max(v))]


@staticmethod
def _parse_time(time_index):
    """
        Convert UTC datetime index into:
        - Days since Greenwhich Noon
        - Zulu hour

        Parameters
        ----------
        time_index : pandas.DatetimeIndex
            Datetime stamps of interest

        Returns
        -------
        n : ndarray
            Days since Greenwich Noon
        zulu : ndarray
            Decimal hour in UTC (Zulu Hour)
        """
    n = (time_index.to_julian_date() - 2451545).values
    zulu = (time_index.hour + time_index.minute / 60).values
    return n, zulu


def set_vif_mtu_config(conf, mtu):
    """Populate a LibvirtConfigGuestInterface instance
    with network mtu.
    """
    conf.mtu = mtu


def state(size):
    """Construct a data container for a serialization stream with a specified size."""
    return bytearray(size)


def crc16(data, crc_init=0):
    """ Calculate 16-bit CRC from input data
    :param data:
    :param crc_init: Initialization value
    :rtype: int value
    """
    crc = crc_init
    for c in data:
        crc ^= c << 8
        for _ in range(8):
            temp = crc << 1
            if crc & 32768:
                temp ^= 4129
            crc = temp
    return crc


def getParentObject():
    """Returns the parent of the current object, equivalent to
           aq_inner(aq_parent(context)), or context.aq_inner.getParentNode()
        """


def extensions(fp, comp_ext_list=['gz', 'tgz', 'zip', 'xz', 'bz2'], **kwargs):
    """
    Return The extension of a file in lower-case. If archived file ("gz", "tgz", "zip", "xz", "bz2")
    the method will output the base extension + the archive extension as a string
    """
    split_name = fp.split('/')[-1].split('.')
    if len(split_name) == 1:
        return ''
    elif len(split_name) > 2 and split_name[-1].lower() in comp_ext_list:
        return '.{}.{}'.format(split_name[-2], split_name[-1]).lower()
    else:
        return '.{}'.format(split_name[-1]).lower()


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

        :param WebSessionsChangeIdleLengthPolicyType val:
        :rtype: EventType
        """
    return cls('web_sessions_change_idle_length_policy', val)


def _grouper(iterable, n):
    """
    Collect data into fixed-length chunks or blocks.

    :param iterable:
        Iterable object.
    :param iterable: iter

    :param n:
        Length chunks or blocks.
    :type n: int
    """
    args = [iter(iterable)] * n
    return zip(*args)


def generate_queryset_ids(objects):
    """
    Returns IDs of queryset objects given
    """
    for item in objects:
        yield item.id


def byte2bit_string(data):
    """
    >>> byte2bit_string(0x1b)
    '00011011'
    """
    return f'{data:08b}'


def collapse_into_single_dates(x, y):
    """
    Function used for a time plot to convert multiple values into one value, while retaining enough information
    to perform a moving average over time
    :param x: a list of dates in ascending order
    :param y: a list of values and can use the '+' operator as a function of date
    :return: a unique list of dates, sum of y for that date, and number of original points for that date
    :rtype: dict
    """
    x_collapsed = [x[0]]
    y_collapsed = [y[0]]
    w_collapsed = [1]
    for n in range(1, len(x)):
        if x[n] == x_collapsed[-1]:
            y_collapsed[-1] = y_collapsed[-1] + y[n]
            w_collapsed[-1] += 1
        else:
            x_collapsed.append(x[n])
            y_collapsed.append(y[n])
            w_collapsed.append(1)
    return {'x': x_collapsed, 'y': y_collapsed, 'w': w_collapsed}


@classmethod
def get_exchange_name(cls):
    """
        Get exchange name
        :return: Exchange name string
        """
    return 'OkCoin'


def inc(num):
    """
    A function that increments its argument by 1.

    Complexity: O(1)
    params:
        num: the number to increment
    returns: the incremented number
    """
    return num + 1


def like_prefix(value, start='%'):
    """
    gets a copy of string with `%` or couple of `_` values attached to beginning.

    it is to be used in like operator.

    :param str value: value to be processed.

    :param str start: start place holder to be prefixed.
                      it could be `%` or couple of `_` values
                      for exact matching.
                      defaults to `%` if not provided.

    :rtype: str
    """
    if value is None:
        return None
    return '{start}{value}'.format(start=start, value=value)


def compact_from_uint256(v):
    """Convert uint256 to compact encoding
    """
    nbytes = v.bit_length() + 7 >> 3
    compact = 0
    if nbytes <= 3:
        compact = (v & 16777215) << 8 * (3 - nbytes)
    else:
        compact = v >> 8 * (nbytes - 3)
        compact = compact & 16777215
    if compact & 8388608:
        compact >>= 8
        nbytes += 1
    return compact | nbytes << 24


def reset() ->None:
    """Reset the settings to their default values (as listed in the documentation
    for the ``config`` function above).
    """


def log_error_and_raise(message, exception, logger):
    """
    Logs an 'error' message and subsequently throws an exception

    :param message: message to show
    :type message: str
    :param exception: exception to raise
    :param logger: logger to use
    """
    logger.error(message)
    raise exception(message)


def convert(input, type):
    """
    Little in-line func to do string-specified type conversions
    """
    if type == 'float':
        return float(input)
    elif type == 'int':
        return int(input)
    elif type == 'str':
        return str(input)
    else:
        return None


def scopes_to_string(scopes):
    """Converts scope value to a string suitable for sending to OAuth 2.0
    authorization servers.

    Args:
        scopes (Sequence[str]): The sequence of scopes to convert.

    Returns:
        str: The scopes formatted as a single string.
    """
    return ' '.join(scopes)


def sort(l, cmp):
    """Sort the list l (in place) according to the comparison function
    cmp.  The comparison function, cmp(x, y), should return something
    less than 0 when x < y, 0 when x == y, something greater than 0 when
    x > y.  The sort is ascending in the following sense:  For the sorted
    list: When i < j, cmp(l[i], l[j]) <= 0.

    This sort is not stable.  In fact it is a deliberate emulation of
    the O(n**2) sort implemented in the SORT subroutine of
    to.SBBXgrid.f.  This is necessary to achieve results that are as
    close as possible to the GISS code.  We should switch to using
    Python's built-in sort routine.
    """
    for n in range(len(l) - 1):
        nlmax = n
        for nn in range(n + 1, len(l)):
            if cmp(l[nn], l[nlmax]) < 0:
                nlmax = nn
        t = l[nlmax]
        l[nlmax] = l[n]
        l[n] = t
    return


def get_message_by_id(message_id: str, lang: str='de') ->str:
    """Return validation message string by id."""
    if lang == 'de':
        if message_id == '0001':
            message_str = (
                'Element {} enthält keine Subelemente, obwohl eines oder mehrere Subelemente erwartet.'
                )
        elif message_id == '0002':
            message_str = (
                'Element {} enthält keinen Elementinhalt, obwohl das Element nicht leer sein darf.'
                )
        elif message_id == '0003':
            message_str = (
                'Element {} enthält ein nicht erwartetes Attribut: {}.')
        elif message_id == '0004':
            message_str = 'Element {} enthält nicht das Pflicht-Attribut {}.'
        elif message_id == '0005':
            message_str = (
                'Element {} enthält ein nicht erwartetes Subelement: {}.')
        elif message_id == '0006':
            message_str = 'Element {} enthält nicht das Pflicht-Subelement {}.'
        elif message_id == '0007':
            message_str = (
                'Element {} ist {} mal vorhanden, erwartet wird jedoch nur {} Vorkommen.'
                )
        elif message_id == '0008':
            message_str = (
                'Element {} darf keinen Text (Character Content) im Elementinhalt enthalten.'
                )
        elif message_id == '0009':
            message_str = (
                'Element {} darf keinen Text (Character Content) vor dem Folgeelement (Tail) enthalten.'
                )
        elif message_id == '0010':
            message_str = (
                "Element {}: Tatsächlicher Elementwert entspricht nicht den zulässigen Werten: '{}' != '{}'."
                )
        elif message_id == '0011':
            message_str = (
                "Element {}: Tatsächlicher Elementwert entspricht nicht den zulässigen Patterns: '{}' != '{}'."
                )
        elif message_id == '0012':
            message_str = (
                "Element {}, Attribut {}: Tatsächlicher Attributwert entspricht nicht den zulässigen Werten: '{}' != '{}'."
                )
        elif message_id == '0013':
            message_str = (
                "Element {}, Attribut {}: Tatsächlicher Attributwert entspricht nicht den zulässigen Patterns: '{}' != '{}'."
                )
        elif message_id == 'e0001':
            message_str = (
                'Die Datei {} ist kein wohlgeformtes XML-Dokument. Fehlermeldung: {}'
                )
        elif message_id == 'e0002':
            message_str = (
                "Der als Parameter 'input_elementtree' übergebene Wert ist kein gültiges ElementTree-Objekt. Fehlermeldung: {}"
                )
        elif message_id == 's0001':
            message_str = (
                'Das Wurzelelement {} entspricht nicht dem erwarteten Element {}.'
                )
        elif message_id == 's0002':
            message_str = (
                'Das Wurzelelement {} befindet sich nicht im erwarteten Namespace. Erwarteter Namespace: {}.'
                )
        else:
            message_str = ''
    elif message_id == '0001':
        message_str = (
            'Element {} does not contain any subelements, although one or more subelements are expected.'
            )
    elif message_id == '0002':
        message_str = (
            'Element {} does not contain any text, although it is not expected to be empty.'
            )
    elif message_id == '0003':
        message_str = 'Element {} contains an unexpected attribute: {}.'
    elif message_id == '0004':
        message_str = 'Element {} misses the mandatory attribute {}.'
    elif message_id == '0005':
        message_str = 'Element {} contains an unexpected subelement: {}.'
    elif message_id == '0006':
        message_str = 'Element {} misses the mandatory subelement {}.'
    elif message_id == '0007':
        message_str = (
            'Element {} occurs {} times, though it is expected to occur only {} times.'
            )
    elif message_id == '0008':
        message_str = 'Element {} should not contain text character content.'
    elif message_id == '0009':
        message_str = 'Element {} should not contain tail character content.'
    elif message_id == '0010':
        message_str = (
            "Element {}: Element value not eqal to allowed values: '{}' != '{}'"
            )
    elif message_id == '0011':
        message_str = (
            "Element {}: Element value not valid according to allowed patterns: '{}' != '{}'"
            )
    elif message_id == '0012':
        message_str = (
            "Element {}, attribute {}: attribute value not eqal to required value: '{}' != '{}'"
            )
    elif message_id == '0013':
        message_str = (
            "Element {}, attribute {}: attribute value not valid according to allowed patterns: '{}' != '{}'"
            )
    elif message_id == 'e0001':
        message_str = 'Input file {} is not well-formed. Error message: {}'
    elif message_id == 'e0002':
        message_str = (
            "Value passed as parameter 'input_elementtree' is not a valid ElementTree object. Error message: {}"
            )
    elif message_id == 's0001':
        message_str = 'Root element {} is not equal to expected element {}.'
    elif message_id == 's0002':
        message_str = (
            'Root element {} is not in the expected namespace. Expected namespace: {}.'
            )
    else:
        message_str = ''
    return message_str


def run_vio(build_dir, dataset_dir, dataset_name, results_dir,
    pipeline_output_dir, pipeline_type, extra_flagfile_path=''):
    """ Runs pipeline depending on the pipeline_type"""
    import subprocess
    return subprocess.call(
        '{}/stereoVIOEuroc                            --logtostderr=1 --colorlogtostderr=1 --log_prefix=0                            --dataset_path={}/{} --output_path={}                           --vio_params_path={}/params/{}/{}                            --tracker_params_path={}/params/{}/{}                            --flagfile={}/params/{}/{} --flagfile={}/params/{}/{}                            --flagfile={}/params/{}/{} --flagfile={}/params/{}/{}                            --flagfile={}/params/{}/{} --flagfile={}/params/{}/{}                            --log_output=True'
        .format(build_dir, dataset_dir, dataset_name, pipeline_output_dir,
        results_dir, pipeline_type, 'regularVioParameters.yaml',
        results_dir, pipeline_type, 'trackerParameters.yaml', results_dir,
        pipeline_type, 'flags/stereoVIOEuroc.flags', results_dir,
        pipeline_type, 'flags/Mesher.flags', results_dir, pipeline_type,
        'flags/VioBackEnd.flags', results_dir, pipeline_type,
        'flags/RegularVioBackEnd.flags', results_dir, pipeline_type,
        'flags/Visualizer3D.flags', results_dir, pipeline_type,
        extra_flagfile_path), shell=True)


def missing_ltihooks(finder, caller):
    """this module is not necessairly present so ignore it when it cannot be
       found"""
    caller.IgnoreName('ltihooks')


def _machine_fqdn(machine):
    """Returns the FQDN of the given learning machine.
    """
    from acorn.logging.decoration import _fqdn
    if hasattr(machine, '__class__'):
        return _fqdn(machine.__class__, False)
    else:
        return _fqdn(machine)


def is_iscsi_uid(uid):
    """Validate the iSCSI initiator format.

    :param uid: format like iqn.yyyy-mm.naming-authority:unique
    """
    return uid.startswith('iqn')


def clean_string(src):
    """Removes control characters"""
    return src.translate(dict.fromkeys(range(32)))


def setEdit_type_key(edit_type_value):
    """Copy edit_type_key to a variable that is global for this file.

        Parameters
        ----------
        edit_type_key : string
            a string for the keyword name to write
    """
    global edit_type
    edit_type = edit_type_value


def _enable_plugin(env, module):
    """Enable the given plugin module if it wasn't disabled explicitly."""
    if env.is_component_enabled(module) is None:
        env.enable_component(module)


def DG2017_predict(dictio, a=0.096, b=0.663):
    """Calculate the K coefficient for the DG2017 method.

    Parameters
    ----------
    dictio: dict
        a dictionary with ndarrays named "feo" and "rws"
    a and b: float
        factors in the equation: K = a * [FeO wt%] + b; default values from Di Genova et al. (2017)

    Returns
    -------
    H2O (wt %): ndarray
        The water content of the glasses calculated as Rws * (a * [FeO wt%] + b)

    """
    return dictio['rws'] * (dictio['feo'] * a + b)


def url(path):
    """Generate a Markdown link for a file/folder"""
    urlable = path.as_posix().replace('/', '').replace('.', '').lower()
    if path.is_dir():
        return f'`{path.name}`'
    return f'[`{path.name}`](#{urlable})'


def isint(value):
    """Check if input can be converted to an integer

    :param value: value to check
    :type value: a ``string`` or ``int``
    :return: ``True`` if value can be converted to an integer
    :rtype: ``bool``
    :raise: :class:`ValueError` when value can't be converted to an integer
    """
    try:
        int(value)
        return True
    except ValueError:
        return False


def edowham(alpha_p, e_eff):
    """

    Calculate the elasticity parameter of the contact problem according to
    Dowson-Hamrock.

    Parameters
    ----------
    alpha_p: ndarray, scalar
        The pressure-viscosity coefficient of the lubricant.
    e_eff: ndarray, scalar
        The effective modulus of the contact problem.

    Returns
    -------
    param_elasticity: ndarray, scalar
        The elasticity parameter of the contact problem.

    """
    param_elasticity = alpha_p * e_eff
    return param_elasticity


def split_by_pipes(cmd):
    """
    Split the command by shell pipes, but preserve contents in
    parentheses and braces. Also handles nested parens and braces.

    :param str cmd: Command to investigate.
    :return list: List of sub commands to be linked
    """
    stack_brace = []
    stack_paren = []
    cmdlist = []
    newcmd = str()
    for char in cmd:
        if char is '{':
            stack_brace.append('{')
        elif char is '}':
            stack_brace.pop()
        elif char is '(':
            stack_paren.append('(')
        elif char is ')':
            stack_paren.pop()
        if len(stack_brace) > 0 or len(stack_paren) > 0:
            newcmd += char
        elif char is '|':
            cmdlist.append(newcmd)
            newcmd = str()
            next
        else:
            newcmd += char
    cmdlist.append(newcmd)
    return cmdlist


def get_current_all_celery_handled_results_list(one_res, logger=None) ->list:
    """
    得到当前所有celery处理后子元素的子元素, 并以新集合形式返回!
    :param one_res:
    :return:
    """
    res = []
    for i in one_res:
        try:
            for j in i:
                res.append(j)
        except TypeError as e:
            continue
    return res


def from_int(arg: str, length: int=-1) ->bytes:
    """
    Transform a integer string into a bytearray of a given length.

    :return: a bytearray
    """
    narg = int(arg)
    barg = narg.to_bytes(length, 'big')
    return barg


@staticmethod
def __version_sort_helper(value: str) ->int:
    """Private Method: A sort helper. converts value: str to int and removes "."

            :param value: str: A version str (example: "3.8.1")
        """
    return int(value.replace('.', ''))


def get_sample(snd, i):
    """Return Sound snd's Sample object at index i."""
    return snd.get_sample(i)


def position_is_escaped(string, position=None):
    """
    Checks whether a char at a specific position of the string is preceded by
    an odd number of backslashes.

    :param string:   Arbitrary string
    :param position: Position of character in string that should be checked
    :return:         True if the character is escaped, False otherwise
    """
    escapes_uneven = False
    for i in range(len(string[:position]) - 1, -1, -1):
        if string[i] == '\\':
            escapes_uneven = not escapes_uneven
        else:
            break
    return escapes_uneven


def round_pos(pos):
    """Round a tuple position so it can be used for drawing."""
    x, y = pos
    return round(x), round(y)


def unique_list(X):
    """unique a list with index and count
    Example
    -------
    >>> unique_list([1,2,4,5,3,2,4])
    >>> ([1, 2, 3, 4, 5], [0, 1, 4, 2, 3], [1, 2, 1, 2, 1])
    """
    idx = sorted(range(len(X)), key=X.__getitem__)
    X_uniq = []
    X_count = []
    idx_uniq = []
    for i in idx:
        if len(X_uniq) == 0 or X[i] != X_uniq[-1]:
            X_uniq.append(X[i])
            X_count.append(1)
            idx_uniq.append(i)
        else:
            X_count[-1] += 1
    return X_uniq, idx_uniq, X_count


def _get_attr(obj, key, default=''):
    """Get an object attribute or an dict key"""
    ret = getattr(obj, key, None)
    if not ret and hasattr(obj, 'get'):
        ret = obj.get(key, None)
    if not ret:
        ret = default
    return ret


def fix_corners(surface, corner_size, bg_color, colorkey):
    """Remove pixels outside rounded corners."""
    pixels = []
    w, h = corner_size
    if colorkey:
        colorkey = *colorkey, 0
    for y in range(h):
        for x in range(w):
            if surface.get_at((x, y)) == bg_color:
                pixels.append((x, y))
                continue
            break
    for y in range(surface.get_height() - h, surface.get_height()):
        for x in range(w):
            if surface.get_at((x, y)) == bg_color:
                pixels.append((x, y))
                continue
            break
    for y in range(h):
        for x in reversed(range(surface.get_width() - w, surface.get_width())):
            if surface.get_at((x, y)) == bg_color:
                pixels.append((x, y))
                continue
            break
    for y in range(surface.get_height() - h, surface.get_height()):
        for x in reversed(range(surface.get_width() - w, surface.get_width())):
            if surface.get_at((x, y)) == bg_color:
                pixels.append((x, y))
                continue
            break
    for pixel in pixels:
        surface.set_at(pixel, colorkey)
    surface.set_colorkey(colorkey)


def tree(n, start=1):
    """
    builds a tree to depth n starting at the desired value

    Examples
    --------

    >>>tree(4)
    [[1, 2], [2, 4], [4, 8], [8, 16]]

    >>>tree(5)
    [[1, 2], [2, 4], [16, 5], [4, 8], [8, 16], [16, 32]]

    >>>tree(6)
    [[1, 2], [2, 4], [16, 5], [4, 8], [5, 10], [8, 16], [16, 32], [32, 64]]

    """
    l = []
    new_last = [start]
    for i in range(n):
        last, new_last = [new_last, []]
        for old_val in last:
            l.append([old_val, old_val * 2])
            new_last.append(old_val * 2)
            new_val = (old_val - 1) / 3
            if new_val > 1 and new_val % 1 == 0:
                l.append([old_val, int(new_val)])
                new_last.append(int(new_val))
    return sorted(l, key=lambda x: x[1])


def evaluate_compliance(event, configuration_item, valid_rule_parameters):
    """Form the evaluation(s) to be return to Config Rules

    Return either:
    None -- when no result needs to be displayed
    a string -- either COMPLIANT, NON_COMPLIANT or NOT_APPLICABLE
    a dictionary -- the evaluation dictionary, usually built by build_evaluation_from_config_item()
    a list of dictionary -- a list of evaluation dictionary , usually built by build_evaluation()

    Keyword arguments:
    event -- the event variable given in the lambda handler
    configuration_item -- the configurationItem dictionary in the invokingEvent
    valid_rule_parameters -- the output of the evaluate_parameters() representing validated parameters of the Config Rule

    Advanced Notes:
    1 -- if a resource is deleted and generate a configuration change with ResourceDeleted status, the Boilerplate code will put a NOT_APPLICABLE on this resource automatically.
    2 -- if a None or a list of dictionary is returned, the old evaluation(s) which are not returned in the new evaluation list are returned as NOT_APPLICABLE by the Boilerplate code
    3 -- if None or an empty string, list or dict is returned, the Boilerplate code will put a "shadow" evaluation to feedback that the evaluation took place properly
    """
    return 'NOT_APPLICABLE'


def p_create_definition_list_one(p):
    """create_definition_list : create_definition"""
    p[0] = {p[1][0]: p[1][1]}


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


def _bbox_area(box):
    """Calculate the area of a box.

    Args:
        box: tensor of box coordinates (x1, y1, x2, y2)

    Returns:
        The area of the box
    """
    return (box[2] - box[0]) * (box[3] - box[1])


def __getitem__(key):
    """Get the value associated with the given key.

        Raise :class:`KeyError` if :meth:`~BTrees.Interfaces.IKeyed.has_key` is false
        with the given key.
        """


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

        :param SharedLinkRemoveExpiryType val:
        :rtype: EventType
        """
    return cls('shared_link_remove_expiry', val)


def normalize_spectra(wave_flux_tuple_list, norm_range, dwave, p=(1e-06,
    1e-06), q=50, n_jobs=1, verbose=False):
    """ normalize multiple spectra using the same configuration

    Parameters
    ----------
    wave_flux_tuple_list: list[n_obs]
        a list of (wave, flux) tuple
    norm_range: tuple
        a tuple consisting (wave_start, wave_stop)
    dwave: float
        binning width
    p: tuple of 2 ps
        smoothing parameter between 0 and 1:
        0 -> LS-straight line
        1 -> cubic spline interpolant
    q: float in range of [0, 100]
        percentile, between 0 and 1
    n_jobs: int
        number of processes launched by joblib
    verbose: int / bool
        verbose level

    Returns
    -------
    flux_norm: ndarray
        normalized flux

    """
    pass


def cook(source_file, text, engine, content_type):
    """Parse text and return prepared template program and macros.

        Note that while *source_file* is provided to name the source
        of the input *text*, it should not be relied on to be an
        actual filename (it may be an application-specific, virtual
        path).

        The return type is a tuple ``(program, macros)``.
        """


def control_address_action(amount, asset, address):
    """
    Get control address action.

    :param amount: bytom amount.
    :type amount: int
    :param asset: bytom asset.
    :type asset: str
    :param address: bytom address.
    :type address: str
    :returns: dict -- bytom control address action.

    >>> from shuttle.providers.bytom.utils import control_address_action
    >>> control_address_action(bytom_amount, bytom_asset, bytom_address)
    {...}
    """
    return dict(amount=amount, asset=asset, address=address, type=str(
        'control_address'))


def list_policies(Filter=None, NextToken=None, MaxResults=None):
    """
    Retrieves the list of all policies in an organization of a specified type.
    This operation can be called only from the organization's master account.
    See also: AWS API Documentation

    :example: response = client.list_policies(
        Filter='SERVICE_CONTROL_POLICY',
        NextToken='string',
        MaxResults=123
    )

    :type Filter: string
    :param Filter: [REQUIRED]
            Specifies the type of policy that you want to include in the response.

    :type NextToken: string
    :param NextToken: Use this parameter if you receive a NextToken response in a previous request that indicates that there is more output available. Set it to the value of the previous call's NextToken response to indicate where the output should continue from.

    :type MaxResults: integer
    :param MaxResults: (Optional) Use this to limit the number of results you want included in the response. If you do not include this parameter, it defaults to a value that is specific to the operation. If additional items exist beyond the maximum you specify, the NextToken response element is present and has a value (is not null). Include that value as the NextToken request parameter in the next call to the operation to get the next part of the results. Note that Organizations might return fewer results than the maximum even when there are more results available. You should check NextToken after every operation to ensure that you receive all of the results.

    :rtype: dict
    :return: {
        'Policies': [
            {
                'Id': 'string',
                'Arn': 'string',
                'Name': 'string',
                'Description': 'string',
                'Type': 'SERVICE_CONTROL_POLICY',
                'AwsManaged': True|False
            },
        ],
        'NextToken': 'string'
    }

    """
    pass


def get_type(layer):
    """Get type of Keras layer.

    Parameters
    ----------

    layer: Keras.layers.Layer
        Keras layer.

    Returns
    -------

    : str
        Layer type.

    """
    return layer.__class__.__name__


@staticmethod
def _year_start(year_find, start_index, step, df):
    """
        TODO: Add docstring

        """
    year_found = 0
    this_ind = start_index
    while year_found == 0:
        this_year = df.loc[this_ind]['Year']
        if this_year >= year_find:
            year_found = 1
            return_step = this_ind - step
        this_ind = this_ind + step
    return int(return_step)


def surface_normal(points, normalize=True):
    """
    Compute the surface normal of a triangle.

    Can provide three points or an array of points.
    """
    import numpy as np
    from blmath.numerics import vx
    p1 = points[(...), (0), :]
    p2 = points[(...), (1), :]
    p3 = points[(...), (2), :]
    normal = np.cross(p2 - p1, p3 - p1)
    return vx.normalize(normal) if normalize else normal


def reset():
    """Test-only method"""
    global all_metrics, initialized
    initialized = False
    all_metrics = {}


def __init__(context, request):
    """Adapts context and request"""


@classmethod
def valid_child_of(cls, parent, obj=None):
    """
        Given a `Content` instance, does our class consent to be adopted by them?
        """
    return True


@classmethod
def from_guess_with_pipe(cls, npc_matvec, v0_guess, labels_split=None,
    dtype=None):
    """Create a `FlatLinearOperator`` from a `matvec` function acting on multiple legs.

        This function creates a wrapper `matvec` function to allow acting on a "vector" with
        multiple legs. The wrapper combines the legs into a :class:`~tenpy.linalg.charges.LegPipe`
        before calling the actual `matvec` function, and splits them again in the end.

        Parameters
        ----------
        npc_matvec : function
            Function to calculate the action of the linear operator on an npc vector
            with the given split labels `labels_split`.
            Has to return an npc vector with the same legs.
        v0_guess : :class:`~tenpy.linalg.np_conserved.Array`
            Initial guess/starting vector which can be applied to `npc_matvec`.
        labels_split : None | list of str
            Labels of v0_guess in the order in which they are to be combined into a
            :class:`~tenpy.linalg.charges.LegPipe`. ``None`` defaults to
            ``v0_guess.get_leg_labels()``.
        dtype : np.dtype | None
            The data type of the arrays. ``None`` defaults to dtype of `v0_guess` (!).

        Returns
        -------
        lin_op : cls
            Instance of the class to be used as linear operator
        guess_flat : np.ndarray
            Numpy vector representing the guess `v0_guess`.
        """
    if dtype is None:
        dtype = v0_guess.dtype
    if labels_split is None:
        labels_split = v0_guess.get_leg_labels()
    v0_combined = v0_guess.combine_legs(labels_split, qconj=+1)
    if v0_combined.rank != 1:
        raise ValueError(
            '`labels_split` must contain all the legs of `v0_guess`')
    pipe = v0_combined.legs[0]
    pipe_label = v0_combined.get_leg_labels()[0]
    res = cls(npc_matvec, pipe, dtype, v0_combined.qtotal, pipe_label)
    res._labels_split = labels_split
    res._npc_matvec_multileg = npc_matvec
    res.npc_matvec = res._npc_matvec_wrapper
    guess_flat = res.npc_to_flat(v0_combined)
    return res, guess_flat


def URITail(URI):
    """
    Returns the last bit of a URI.
    Useful for pulling out datatype from long namespaces , e.g. http://purl.org/nidash/fsl#fsl_000032
    :param URI: string
    :return: string
    """
    tail = URI.split('/')[-1]
    tail = tail.split('#')[-1]
    return tail


@classmethod
def _unichr_to_int(cls, char):
    """
        Convert to int the given character.
        """
    try:
        return ord(char)
    except:
        pass
    return -1


def escape(string, quote=True):
    """Returns a string where HTML metacharacters are properly escaped.

    Compatibility layer to avoid incompatibilities between Python versions,
    Qt versions and Qt bindings.

    >>> import silx.utils.html
    >>> silx.utils.html.escape("<html>")
    >>> "<html>"

    .. note:: Since Python 3.3 you can use the `html` module. For previous
        version, it is provided by `sgi` module.
    .. note:: Qt4 provides it with `Qt.escape` while Qt5 provide it with
        `QString.toHtmlEscaped`. But `QString` is not exposed by `PyQt` or
        `PySide`.

    :param str string: Human readable string.
    :param bool quote: Escape quote and double quotes (default behaviour).
    :returns: Valid HTML syntax to display the input string.
    :rtype: str
    """
    string = string.replace('&', '&')
    string = string.replace('<', '<')
    string = string.replace('>', '>')
    if quote:
        string = string.replace("'", ''')
        string = string.replace('"', '"')
    return string


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

        :param RelinquishFolderMembershipError val:
        :rtype: JobError
        """
    return cls('relinquish_folder_membership_error', val)


def md_link(node):
    """Extract a metadata link tuple from an xml node"""
    mimetype = node.find('type')
    mdtype = node.find('metadataType')
    content = node.find('content')
    if None in [mimetype, mdtype, content]:
        return None
    else:
        return mimetype.text, mdtype.text, content.text


def index_report(df, label='', time_fmt='%Y-%m-%d %T', return_index_dict=False
    ):
    """Sorts dataframe index, prints index's start and end points and its datetime frequency.
    if return_index_dict=True then it returns these values in a dictionary as well as printing them."""
    import pandas as pd
    df.sort_index(inplace=True)
    index_info = {'index_start': df.index[0].strftime(time_fmt),
        'index_end': df.index[-1].strftime(time_fmt), 'index_freq': df.
        index.freq}
    if df.index.freq is None:
        try:
            index_info['inferred_index_freq'] = pd.infer_freq(df.index)
        except:
            index_info['inferred_index_freq'] = 'error'
    dashes = '---' * 20
    print(dashes)
    print(f'\tINDEX REPORT:\t{label}')
    print(dashes)
    print(
        f"""* Index Endpoints:
	{df.index[0].strftime(time_fmt)} -- to -- {df.index[-1].strftime(time_fmt)}"""
        )
    print(f'* Index Freq:\n\t{df.index.freq}')
    if return_index_dict == True:
        return index_info
    else:
        return


def decorator_wrapper(f, *args, **kwargs):
    """Wrapper needed by decorator.decorate to pass through args, kwargs"""
    return f(*args, **kwargs)


def hold_request(request_type, key, data=None):
    """Hold some data for moderator approval.

        :param request_type: A `RequestType` enum value.
        :param key: The key piece of request data being held.
        :param data: Additional optional data in the form of a dictionary that
            is associated with the held request.
        :return: A unique id for this held request.
        """


@classmethod
def from_builtin_corpus(cls, corpus_label):
    """
        Construct Corpus object by loading one of the built-in datasets specified by `corpus_label`. To get a list
        of available built-in datasets, use :meth:`~tmtoolkit.corpus.Corpus.builtin_corpora`.

        :param corpus_label: the corpus to load (one of the labels listed in
                             :meth:`~tmtoolkit.corpus.Corpus.builtin_corpora`
        :return: Corpus instance
        """
    available = cls.builtin_corpora(with_paths=True)
    if corpus_label in available:
        return cls.from_zip(available[corpus_label], **cls.
            _BUILTIN_CORPORA_LOAD_KWARGS.get(corpus_label, {}))
    else:
        raise ValueError('built-in corpus does not exist:', corpus_label)


def get_data_source_by_name_and_url_query(query, name, url_query):
    """Returns a data source from given name and url of query

    Args:
        query:
        name:
        url_query:

    Returns:

    """
    return query.get_data_source_by_name_and_url_query(name, url_query)


def build_option_parser(parser):
    """Hook to add global options"""
    return parser


def load_record_and_dt(db_fp, local_path_ext, test_name, sensor_code, dbset,
    quiet=False, first=True):
    """
    Finds the file and returns the time series of values and the time step

    :param db_fp: str, Database root directory
    :param local_path_ext: str, local path to sensor file from database root directory
    :param test_name: str, name of test used as prefix of file name
    :param sensor_code: str, a sensor code (e.g. ACCX-UB1-L2C-M)
    :param dbset: module, A database set module from sfsidb.sets
    :param quiet: bool, if True then return None
    :return:
    """
    folder_path = db_fp + local_path_ext
    return dbset.wild_load_record_and_dt(folder_path, test_name,
        sensor_code, quiet, first)


def _safe_assigns(dest, source, attrs):
    """
    Shallow-copies all requested attributes from `source` to `dest` if they
    are present. If not present, nothing is done
    """
    for attr in attrs:
        if not hasattr(source, attr):
            continue
        myattr = getattr(source, attr)
        setattr(dest, attr, myattr)


def imagecodecs_reader(path):
    """Return napari LayerData from first page in TIFF file."""
    from imagecodecs import imread
    return [(imread(path), {}, 'image')]


def _bisect_left(seq, tgt, key_func, lower_search_bound=0,
    upper_search_bound=None):
    """Return the index of the last item in seq such that all e in seq[:index]
    have key_func(e) < tgt, and all e in seq[index:] have key_func(e) >= tgt.

    Thus, seq.insert(index, value) will insert value before the leftmost item
    such that meets the above condition.

    lower_search_bound and upper_search_bound bound the slice to be searched.

    Assumes that seq is already sorted.
    """
    if lower_search_bound < 0:
        raise ValueError('lower_search_bound must be non-negative')
    if upper_search_bound is None:
        upper_search_bound = len(seq)
    while lower_search_bound < upper_search_bound:
        midpoint_index = (lower_search_bound + upper_search_bound) // 2
        if key_func(seq[midpoint_index]) < tgt:
            lower_search_bound = midpoint_index + 1
        else:
            upper_search_bound = midpoint_index
    return lower_search_bound


def arg_stringname(func_arg):
    """Gets the string name of a kwarg or vararg
    In Python3.4 a function's args are
    of _ast.arg type not _ast.name
    """
    if hasattr(func_arg, 'arg'):
        return func_arg.arg
    else:
        return str(func_arg)


def _replace(_self, **kwds):
    """Return a new Quad object replacing specified fields with new values"""
    result = _self._make(map(kwds.pop, ('subject', 'predicate', 'object',
        'graph'), _self))
    if kwds:
        raise ValueError('Got unexpected field names: %r' % kwds.keys())
    return result


def Khan_Richardson(Re):
    """Calculates drag coefficient of a smooth sphere using the method in
    [1]_ as described in [2]_.

    .. math::
        C_D = (2.49Re^{-0.328} + 0.34Re^{0.067})^{3.18}

    Parameters
    ----------
    Re : float
        Particle Reynolds number of the sphere using the surrounding fluid
        density and viscosity, [-]

    Returns
    -------
    Cd : float
        Drag coefficient [-]

    Notes
    -----
    Range is Re <= 2E5

    Examples
    --------
    >>> Khan_Richardson(200.)
    0.7747572379211097

    References
    ----------
    .. [1] Khan, A. R., and J. F. Richardson. "The Resistance to Motion of a
       Solid Sphere in a Fluid." Chemical Engineering Communications 62,
       no. 1-6 (December 1, 1987): 135-50. doi:10.1080/00986448708912056.
    .. [2] Barati, Reza, Seyed Ali Akbar Salehi Neyshabouri, and Goodarz
       Ahmadi. "Development of Empirical Models with High Accuracy for
       Estimation of Drag Coefficient of Flow around a Smooth Sphere: An
       Evolutionary Approach." Powder Technology 257 (May 2014): 11-19.
       doi:10.1016/j.powtec.2014.02.045.
    """
    return (2.49 * Re ** -0.328 + 0.34 * Re ** 0.067) ** 3.18


@classmethod
def get_request_queryset(cls, ar, **filter):
    """Return the base queryset for tables on this object.

        The optional `filter` keyword arguments, if present, are
        applied as additional filter. This is used only in UNION
        tables on abstract model mixins where filtering cannot be done
        after the join.

        """
    qs = cls.get_user_queryset(ar.get_user(), **filter)
    if ar.actor.only_fields is not None:
        qs = qs.only(ar.actor.only_fields)
    return qs


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


def _int_to_roman(i):
    """From http://code.activestate.com/recipes/81611-roman-numerals/
    """
    numeral_map = tuple(zip((1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5,
        4, 1), ('M', 'CM', 'D', 'CD', 'C', 'XC', 'L', 'XL', 'X', 'IX', 'V',
        'IV', 'I')))
    result = []
    for integer, numeral in numeral_map:
        count = i // integer
        result.append(numeral * count)
        i -= integer * count
    return ''.join(result)


def is_identity(term):
    """
    Check if Pauli Term is a scalar multiple of identity

    :param PauliTerm term: A PauliTerm object
    :returns: True if the PauliTerm is a scalar multiple of identity, false otherwise
    :rtype: bool
    """
    return len(term) == 0


def _fmt_word(word, max_chars=60, crop_front=True):
    """str-convert a word.  If it exceeds max_chars, crop it to max_chars - 3
       and prefix it with "..."  eg:
          areallylongword --->  ....lylongword

    """
    word = str(word)
    if len(word) > max_chars:
        if crop_front:
            word = '...' + word[-(max_chars - 3):]
        else:
            word = word[:max_chars - 3] + '...'
    return word


def update_deployment(directory):
    """ TODO: update of deployment
    """
    pass


def reduce_base(amount, base):
    """
    Compute the reduced base of the given parameters
    :param int amount: the amount value
    :param int base: current base value
    :return: tuple containing computed (amount, base)
    :rtype: tuple
    """
    if amount == 0:
        return 0, 0
    next_amount = amount
    next_base = base
    while int(next_amount) == next_amount:
        amount = next_amount
        base = next_base
        next_amount /= 10
        next_base += 1
    return int(amount), int(base)


def calculate_sensitivity(n_rows, child, parents, col_to_binary):
    """Sensitivity function for Bayesian network construction.
    Lemma 4.1 Page 12

    Parameters
    ----------
    n_rows : int
        Number of tuples in sensitive dataset.

    child : str
        one column name

    parents : tuple
        parents of child, there may be multiple parents

    col_to_binary : dict
        mapping from column name to is_binary

    Return
    --------
    int
        Sensitivity value.
    """
    from math import log
    if col_to_binary[child] or len(parents) == 1 and col_to_binary[parents[0]]:
        a = log(n_rows) / n_rows
        b = (1 / n_rows - 1) * log(1 - 1 / n_rows)
        return a + b
    else:
        a = 2 / n_rows * log((n_rows + 1) / 2)
        b = (1 - 1 / n_rows) * log(1 + 2 / (n_rows - 1))
        return a + b


def Beta(m):
    """
    Double factorial of odd numbers: a(m) = (2*m-1)!! = 1*3*5*...*(2*m-1)
    :param m: integer
    :return: Integer
    """
    if m <= 0:
        ans = 1
    else:
        ans = 1
        for i in range(1, m):
            ans *= 2 * i + 1
    return ans


def convert_SelfReferenceProperty(model, prop, kwargs):
    """Returns a form field for a ``db.SelfReferenceProperty``."""
    return None


def is_empty(value):
    """ a boolean test except 0 and False are considered True """
    if not value and value != 0 and value is not False:
        return True
    return False


def sortArray(data, pos, reverse=False):
    """data is a list of items
    sort by pos in list; reverse if True
    """
    T = []
    for i, M in enumerate(data):
        try:
            T.append((M[pos], i))
        except IndexError:
            return data
    D = dict(zip(T, data))
    T.sort()
    if reverse:
        T.reverse()
    X = []
    for key in T:
        X.append(D[key])
    return X


def time_complexities():
    """
    Return information on functions
    time complexity
    :return: string
    """
    return 'Best Case: O(n ^ 2), Average Case: O(n ^ 2), Worst Case: O(n ^ 2)'


def mbar2lbfft2(press_mbar):
    """Convert pressure value from mbar to lb/ft^2"""
    return press_mbar * 2.08854


@staticmethod
def convert(elem, into):
    """Return factor f so that f * Term([(into, 1)]) == Term([(elem, 1)]).

        Raises TypeError if conversion is not possible."""
    raise NotImplementedError


@classmethod
def supports_to_pcm(cls):
    """returns True if all necessary components are available
        to support the .to_pcm() method"""
    try:
        from audiotools.decoders import ALACDecoder
        return True
    except ImportError:
        return False


def reset(secondsFromNow):
    """
        Reset the scheduled call's timer.

        @param secondsFromNow: how many seconds from now it should fire,
            equivalent to C{.cancel()} and then doing another
            C{reactor.callLater(secondsLater, ...)}

        @raises twisted.internet.error.AlreadyCalled: if the call has already
            happened.
        @raises twisted.internet.error.AlreadyCancelled: if the call has already
            been cancelled.
        """


def move_dates(apps, schema_editor):
    """Move dates to models."""
    RelayDomain = apps.get_model('relaydomains', 'RelayDomain')
    for model in [RelayDomain]:
        for instance in model.objects.all():
            instance.creation = instance.dates.creation
            instance.last_modification = instance.dates.last_modification
            instance.save()


def _settings_closed(events, params):
    """Handle close event from settings dialog."""
    params['fig_options'] = None


@classmethod
def get_property(cls, prop_name, default_value=None):
    """
        Return a property of the model
        """
    return getattr(cls._specifier, prop_name, default_value)


def custom_timeouts(class_obj: type) ->type:
    """
    Decorator to annotate the CustomTimeouts class. Registers the decorated class
    as the CustomTimeouts known type.
    """
    assert isinstance(class_obj, type), 'class_obj is not a Class'
    global _custom_timeouts_type
    _custom_timeouts_type = class_obj
    return class_obj


@classmethod
def get_from_schema(cls, schema):
    """Return the corresponding SIPMetadataType."""
    return cls.query.filter_by(schema=schema).one()


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


def p_statement(p):
    """statement_list : statement"""
    p[0] = p[1]


def shift_mesh(mesh, vector):
    """
    Shift a given mesh with a given vector.

    Parameters
    ----------
    mesh : single dict
        dictionary containing
        at least the following keyword
            nodes : ndarray
                Array with all node postions.
    vector : ndarray
        array containing the shifting vector
    """
    for i in range(3):
        mesh['nodes'][:, (i)] += vector[i]
    return mesh


def extract_user_id(user_id):
    """
    Get the user id exracted from a bad format (e.g, 123 from <@123>)

    :param user_id: user id in a bad format

    :return: return user id in good format
    """
    return user_id[2:-1]


def _different_coordinates(row_i, row_j):
    """
    Return True if the coordinates values are different.

    Genomic coordinates values are only compared when end and start phases
    are not -1. Phase -1 can be present because of UTR regions, which could
    have different genomic coordinates, but still have the same protein
    sequence.
    """
    if row_i['StartPhase'] != -1 and row_j['StartPhase'] != -1:
        if row_i['GenomicCodingStart'] != row_j['GenomicCodingStart']:
            return True
    if row_i['EndPhase'] != -1 and row_j['EndPhase'] != -1:
        if row_i['GenomicCodingEnd'] != row_j['GenomicCodingEnd']:
            return True
    return False


def count_tabs(sbtab_string):
    """
    Counts how many SBtabs are in in a given string.

    Parameters
    ----------
    sbtab_string: str
        SBtab table or tables in string representation.

    Returns: int
        Amount of SBtab tables in given string.
    """
    counter = 0
    for row in sbtab_string.split('\n'):
        if row.startswith('!!SBtab'):
            counter += 1
    return counter


def line_break():
    """Insert line break at cursor position

    """
    pass


def traverse(path, request, resource):
    """
    Traverse a root resource, retrieving the appropriate child for the request.

    """
    path = path.lstrip(b'/')
    for component in (path and path.split(b'/')):
        if getattr(resource, 'is_leaf', False):
            break
        resource = resource.get_child(name=component, request=request)
    return resource


def safestr(text):
    """
    Safely convert unicode to a string
    """
    if text is None:
        return
    try:
        return str(text)
    except UnicodeEncodeError:
        return str(text.encode('utf-8'))


@classmethod
def default_contact_binary(cls, *args, **kwargs):
    """
        For convenience, this function is available at the top-level as
        <phoebe.default_contact_binary> as well as
        <phoebe.frontend.bundle.Bundle.default_contact_binary>.

        This is a shortcut to <phoebe.frontend.bundle.Bundle.default_binary>
        but with `contact_binary` set to True.
        """
    return cls.default_binary(*args, contact_binary=True, **kwargs)


def _inject_mutations_1D_X(phi, dt, xx, theta0, beta, alpha):
    """
    Inject novel mutations for a timestep.
    """
    factor = 2.0 / (1.0 + 2.0 * beta) * (1.0 / (alpha + 1.0) + beta)
    phi[1] += dt / xx[1] * theta0 / 2.0 * factor * 2.0 / (xx[2] - xx[0])
    return phi


def sanitize_bandwidths(value):
    """Cleans bandwidth data from dictionary form.

    Parameters
    ----------
    value : dict
        Observation values produced by reading out from Praat.

    Returns
    -------
    float
        The first bandwidth.
    float
        The second bandwidth.
    float
        The third bandwidth.
    """
    try:
        b1 = value['B1'][0]
    except TypeError:
        b1 = value['B1']
    if b1 is None:
        b1 = 0
    try:
        b2 = value['B2'][0]
    except TypeError:
        b2 = value['B2']
    if b2 is None:
        b2 = 0
    try:
        b3 = value['B3'][0]
    except TypeError:
        b3 = value['B3']
    if b3 is None:
        b3 = 0
    return b1, b2, b3


def filtered_meta_types(user=None):
    """Return a list of the types for which the user has adequate
        permission to add that type of object.
        """


def _qt_implementation(module):
    """Helper function to get name (PyQt4, PyQt5, PySide) and the QtCore module
    """
    global _qtcore
    name = module.name.split('.')[0]
    try:
        _qtcore = __import__(name, fromlist=['QtCore']).QtCore
    except RuntimeError:
        print(
            'WARNING: Tried to load multiple incompatible Qt wrappers. Some incorrect files may be copied.'
            )
    return name, _qtcore


@classmethod
def dequeue(cls, exclude_ids=[]):
    """
        Claims the first available task and returns it. If there are no
        tasks available, returns None.

        For at-most-once delivery, commit the transaction before
        processing the task. For at-least-once delivery, dequeue and
        finish processing the task in the same transaction.

        To put a job back in the queue, you can just call
        .save(force_insert=True) on the returned object.
        """
    tasks = list(cls.objects.raw(
        """
            DELETE FROM dpq_job
            WHERE id = (
                SELECT id
                FROM dpq_job
                WHERE execute_at <= now()
                  AND NOT id = ANY(%s)
                ORDER BY priority DESC, created_at
                FOR UPDATE SKIP LOCKED
                LIMIT 1
            )
            RETURNING *;
            """
        , [list(exclude_ids)]))
    assert len(tasks) <= 1
    if tasks:
        return tasks[0]
    else:
        return None


def _build_tree_structure(cls):
    """
    Build an in-memory representation of the item tree, trying to keep
    database accesses down to a minimum. The returned dictionary looks like
    this (as json dump):

        {"6": [7, 8, 10]
         "7": [12],
         "8": [],
         ...
         }
    """
    all_nodes = {}
    if hasattr(cls, '_mptt_meta'):
        mptt_opts = cls._mptt_meta
    else:
        mptt_opts = cls._meta
    for p_id, parent_id in cls.objects.order_by(mptt_opts.tree_id_attr,
        mptt_opts.left_attr).values_list('pk', '%s_id' % mptt_opts.parent_attr
        ):
        all_nodes[str(p_id)] = []
        if parent_id:
            if str(parent_id) not in all_nodes:
                all_nodes[str(parent_id)] = []
            all_nodes[str(parent_id)] += [str(p_id)]
    return all_nodes


@staticmethod
def system_user_exists(user):
    """Check if the user exists on the system"""
    import pwd
    try:
        pwd.getpwnam(user.name)
    except KeyError:
        return False
    else:
        return True


def cross(u, v):
    """
    Return the cross product of two 2 or 3 dimensional vectors.
    """
    uDim = len(u)
    vDim = len(v)
    uxv = []
    if uDim == vDim == 2:
        uxv = [u[0] * v[1] - u[1] * v[0]]
    elif uDim == vDim == 3:
        for i in range(uDim):
            uxv = [u[1] * v[2] - u[2] * v[1], -(u[0] * v[2] - u[2] * v[0]),
                u[0] * v[1] - u[1] * v[0]]
    else:
        raise IndexError('Vector has invalid dimensions')
    return uxv


def __new__(cls, name, description=None):
    """Keep a dict of PermissionSetting instances, indexed by
        name. If the name already exists in the dict, return that
        instance rather than creating a new one.
        """
    instances = cls.__dict__.get('_z_instances')
    if instances is None:
        cls._z_instances = instances = {}
    it = instances.get(name)
    if it is None:
        instances[name] = it = object.__new__(cls)
        it._init(name, description)
    return it


@classmethod
def hot_water_operation_mode(cls, mode: str):
    """
        Payload to set operation mode for *hotwater*
        """
    return {'operation_mode': mode}


def load_map(file_name: str, map_name: str, num_levels: int=4, sigma: float=1.0
    ):
    """Loads an image map for further reading.

    :param file_name: The name of the image file.
    :type file_name: str
    :param map_name: The name that will be used to access this image.
    :type map_name: str
    :param num_levels: The number of levels in the map pyramid (default = 4). If num_levels == 0, the complete pyramid is built.
    :type num_levels: int
    :param sigma: The sigma value of the gaussian function.
    :type sigma: float
    """
    pass


def peek_assoc(store, container, _stack=None):
    """
    Deserialize association lists.
    """
    assoc = []
    if store.getRecordAttr('key', container) == 'escaped':
        for i in store.iterObjectNames(container):
            assoc.append(store.peek(i, container, _stack=_stack))
    else:
        for i in store.iterObjectNames(container):
            assoc.append((store.strRecord(i, container), store.peek(i,
                container, _stack=_stack)))
    return assoc


def get_responses(link):
    """Returns documented responses based on the @responds decorator.

    In case no documentation exists, the empty object is returned,
    instead of a default, which better represents that behavior not to
    be formally documented.

    """
    if hasattr(link, '_responses'):
        return link._responses
    return {}


def neighbor_check(node, **kargs):
    """
    Check that if a finer neighbor refined we also refine.
    This enforces that the maximum discrepency in neighbor levels
    is one.
    """
    if not node.rflag:
        return
    _, _, _, neighbors = node.find_neighbors(**kargs)
    for n in neighbors:
        if n is not None:
            if n.leaf:
                n.rflag = True


def select_less():
    """Deselect those bones at the boundary of each selection region

    """
    pass


@classmethod
def from_string(cls, s, namespace=None):
    """
        Initializes the config from a string. The string is expected to contain the config as a variable named ``CONFIG``.
        """
    if namespace is None:
        namespace = {}
    else:
        namespace = dict(namespace)
    exec(s, namespace)
    return cls(namespace['CONFIG'])


@classmethod
def rect(cls, dcode, width, height, hole_diameter=None, hole_width=None,
    hole_height=None):
    """Create a rectangular aperture definition statement"""
    if hole_diameter is not None and hole_diameter > 0:
        return cls('AD', dcode, 'R', ([width, height, hole_diameter],))
    elif hole_width is not None and hole_width > 0 and hole_height is not None and hole_height > 0:
        return cls('AD', dcode, 'R', ([width, height, hole_width,
            hole_height],))
    return cls('AD', dcode, 'R', ([width, height],))


def valid_packet(packet, constraint):
    """
        Check if a hex encoded packet received from
        rflib.Rfcat.RFrecv has the constraint value in it.

        Idea From:
            https://github.com/mossmann/stealthlock/blob/master/sl.py#L17

        :param packet:
        :param constraint:
        :return:
    """
    if constraint not in packet:
        return False
    return True


def get_tenant(session, cloud_name, cloud_user, return_type=None, **kwargs):
    """
    Get all Cloud Tennants

    :type session: zadarapy.session.Session
    :param session: A valid zadarapy.session.Session object.  Required.

    :type cloud_name: str
    :param cloud_name: Cloud Name: i.e: zadaraqa9

    :type cloud_user: str
    :param cloud_user: Cloud User

    :type return_type: str
    :param return_type: If this is set to the string 'json', this function
        will return a JSON string.  Otherwise, it will return a Python
        dictionary.  Optional (will return a Python dictionary by default).

    :rtype: dict, str
    :returns: A dictionary or JSON data set as a string depending on
        return_type parameter.
    """
    path = '/api/clouds/{0}/cloud_users/{1}.json'.format(cloud_name, cloud_user
        )
    return session.get_api(path=path, return_type=return_type, **kwargs)


def filter_pre_string(_string: str, lines_to_cut: int) ->str:
    """
    Filter the xml out of html

    :param str _string:
    :param int lines_to_cut:
    """
    filtered_array = _string.splitlines()[lines_to_cut:]
    filtered_string = ''.join(filtered_array)
    filtered_string = filtered_string.strip()
    return filtered_string


def render_cell(cell, context, jinja_env):
    """Render the Jinja-templated source of a single notebook cell.

    Parameters
    ----------
    cell : `nbformat.NotebookNode`
        An individual cell from a notebook, as a `~nbformat.NotebookNode`.
        This object can also be created programatically, see
        `nbformat.v4.new_code_cell`, `nbformat.v4.new_markdown_cell`, and
        `nbformat.v4.new_raw_cell`.
    context : `dict`-like
        The template context. Usually this is constructed via
        `cookiecutter.generate.generate_context`.
    jinja_env : `cookiecutter.environment.StrictEnvironment`
        The Jinja environment.

    Returns
    -------
    cell : `nbformat.NotebookNode`
        The input cell with the ``source`` member replaced with rendered
        content.

    Notes
    -----
    This function operates on the ``source`` member of the provided ``cell``.
    Other members of the cell are left unmodified.

    For more information about the format of a cell, see `The Notebook
    file format <https://ls.st/g01>`_ in the nbformat docs.
    """
    template = jinja_env.from_string(cell.source)
    cell.source = template.render(**context)
    return cell


def get_all_results():
    """Return a dictionary mapping pathname (a tuple of strings, ready to
        be slash-joined) to an ICheckResults instance, one for each object
        that was checked."""


def glIsShader(shader: int):
    """Determines if a name corresponds to a shader object.

    :param shader: Specifies a potential shader object.
    :type shader: int
    """
    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 tamper(payload, **kwargs):
    """
    Appends a HTTP header 'X-originating-IP' to bypass Varnish Firewall

    Reference:
        * https://web.archive.org/web/20160815052159/http://community.hpe.com/t5/Protect-Your-Assets/Bypassing-web-application-firewalls-using-HTTP-headers/ba-p/6418366

    Notes:
        Examples:
        >> X-forwarded-for: TARGET_CACHESERVER_IP (184.189.250.X)
        >> X-remote-IP: TARGET_PROXY_IP (184.189.250.X)
        >> X-originating-IP: TARGET_LOCAL_IP (127.0.0.1)
        >> x-remote-addr: TARGET_INTERNALUSER_IP (192.168.1.X)
        >> X-remote-IP: * or %00 or %0A
    """
    headers = kwargs.get('headers', {})
    headers['X-originating-IP'] = '127.0.0.1'
    return payload


def init():
    """Initialize the ATLAS specific API. !!! DEPRECATED !!!

	Returns:
	    nothing.
	"""
    pass


def floatable(value):
    """Check if a value can be converted to a float"""
    try:
        float(value)
        return True
    except ValueError:
        return False


def process_subscription_data(post_data):
    """Process the subscription data according to out model"""
    subscription_data = post_data.pop('subscription', {})
    keys = subscription_data.pop('keys', {})
    subscription_data.update(keys)
    subscription_data['browser'] = post_data.pop('browser')
    return subscription_data


def set_warning_message(message):
    """Sets a warning. This will be reported by pingers.

    :param str|unicode message:

    :rtype: bool
    """
    return False


def resume_plugin_session(engine, pid, session_id, plugin_signature):
    """Resume plugin session."""
    logger = engine.logger
    plugins = engine.store.plugins
    plugin_sessions = engine.store.plugin_sessions
    plugin_signatures = engine.store.plugin_signatures
    if pid in plugins:
        if session_id in plugin_sessions:
            plugin_sessions[session_id].append(plugins[pid])
        else:
            plugin_sessions[session_id] = [plugins[pid]]
    if plugin_signature in plugin_signatures:
        plugin_info = plugin_signatures[plugin_signature]
        logger.info('Resuming plugin %s', pid)
        return plugin_info
    return None


def select(extend: bool=False, deselect: bool=False, toggle: bool=False,
    deselect_all: bool=False, center: bool=False, enumerate: bool=False,
    object: bool=False, location: int=(0, 0)):
    """Select and activate item(s)

    :param extend: Extend, Extend selection instead of deselecting everything first
    :type extend: bool
    :param deselect: Deselect, Remove from selection
    :type deselect: bool
    :param toggle: Toggle Selection, Toggle the selection
    :type toggle: bool
    :param deselect_all: Deselect On Nothing, Deselect all when nothing under the cursor
    :type deselect_all: bool
    :param center: Center, Use the object center when selecting, in editmode used to extend object selection
    :type center: bool
    :param enumerate: Enumerate, List objects under the mouse (object mode only)
    :type enumerate: bool
    :param object: Object, Use object selection (editmode only)
    :type object: bool
    :param location: Location, Mouse location
    :type location: int
    """
    pass


def ClearStoppedFlag():
    """
    This set ``_StoppedFlag`` to False.
    """
    global _StoppedFlag
    _StoppedFlag = False


def event_station(event, stations, debug=True):
    """ Find the station corresponding to event['station'] """
    if event['station'] in stations:
        return stations[event['station']]
    return None


def latex_num(c):
    """Returns latex string of numbers, potentially using exponential notation."""
    cstr = '%.4g' % c
    if 'e' in cstr:
        idx = cstr.index('e')
        cstr = '%s \\times 10^{%i}' % (cstr[:idx], int(cstr[idx + 1:]))
    return cstr


def split_first(s, delims):
    """
    Given a string and an iterable of delimiters, split on the first found
    delimiter. Return two split parts and the matched delimiter.

    If not found, then the first part is the full input string.

    Example::

        >>> split_first('foo/bar?baz', '?/=')
        ('foo', 'bar?baz', '/')
        >>> split_first('foo/bar?baz', '123')
        ('foo/bar?baz', '', None)

    Scales linearly with number of delims. Not ideal for large number of delims.
    """
    min_idx = None
    min_delim = None
    for d in delims:
        idx = s.find(d)
        if idx < 0:
            continue
        if min_idx is None or idx < min_idx:
            min_idx = idx
            min_delim = d
    if min_idx is None or min_idx < 0:
        return s, '', None
    return s[:min_idx], s[min_idx + 1:], min_delim


def list_projects():
    """Return the list of available projects"""


@staticmethod
def get_subtype(object_dictionary):
    """
        Given the hash representation of a subtype of this class,
        use the info in the hash to return the class of the subtype.
        """
    type = object_dictionary['validatorType']
    if type == 'DEFAULT':
        return 'DefaultTagDefinitionValidator'
    if type == 'ENUM':
        return 'EnumTagDefinitionValidator'
    else:
        return 'BaseTagDefinitionValidator'


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 romanInversionName(inChord, inv=None):
    """
    Extremely similar to Chord's inversionName() method, but returns string
    values and allows incomplete triads
    """
    if inv is None:
        inv = inChord.inversion()
    if inChord.isSeventh() or inChord.seventh is not None:
        if inv == 0:
            return '7'
        elif inv == 1:
            return '65'
        elif inv == 2:
            return '43'
        elif inv == 3:
            return '42'
        else:
            return ''
    elif inChord.isTriad() or inChord.isIncompleteMajorTriad(
        ) or inChord.isIncompleteMinorTriad():
        if inv == 0:
            return ''
        elif inv == 1:
            return '6'
        elif inv == 2:
            return '64'
        else:
            return ''
    else:
        return ''


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

        :param DeleteTeamInviteLinkType val:
        :rtype: EventType
        """
    return cls('delete_team_invite_link', val)


@classmethod
def updated(cls, timestamp=None):
    """
        Returns all shows updated since a timestamp.
        The server time is in PST.
        To establish a baseline timestamp, you can use the Server.time() method.

        :param timestamp: Start with this timestamp and find anything updated since then.
        """
    return cls._get('shows/updated', timestamp)


def resolveAlias(line, aliasDict):
    """Look for alias in alias and replace it with rela command
    @param line : string to analyse
    @param aliasDict: aliases dictionnary
    @return: modified line"""
    tokens = line.split()
    if len(tokens) > 0 and tokens[0] in aliasDict:
        line = '%s %s' % (aliasDict[tokens[0]], ' '.join(tokens[1:]))
    return line


def forgiver_reclassifier(original_classifier, p):
    """Function to reclassify the strategy"""
    if p not in (0, 1):
        original_classifier['stochastic'] = True
    return original_classifier