def map_mean_of_link_nodes_to_link(grid, var_name, out=None):
    """Map the mean of a link's nodes to the link.

    map_mean_of_link_nodes_to_link iterates across the grid and
    identifies the node values at both the "head" and "tail" of a given link.
    This function takes the sum of the two values of 'var_name' at both the
    "to" and "from" node. The average value of the two node values of
    'var_name' is then mapped to the link.

    Parameters
    ----------
    grid : ModelGrid
        A landlab ModelGrid.
    var_name : array or field name
        Values defined at nodes.
    out : ndarray, optional
        Buffer to place mapped values into or `None` to create a new array.

    Returns
    -------
    ndarray
        Mapped values at links.

    Examples
    --------
    >>> import numpy as np
    >>> from landlab.grid.mappers import map_mean_of_link_nodes_to_link
    >>> from landlab import RasterModelGrid

    >>> rmg = RasterModelGrid((3, 4))
    >>> rmg.at_node['z'] = np.array([ 0,  1,  2,  3,
    ...                               4,  5,  6,  7,
    ...                               8,  9, 10, 11])
    >>> map_mean_of_link_nodes_to_link(rmg, 'z')
    array([  0.5,   1.5,   2.5,   2. ,   3. ,   4. ,   5. ,   4.5,   5.5,
             6.5,   6. ,   7. ,   8. ,   9. ,   8.5,   9.5,  10.5])

    >>> values_at_links = rmg.empty(at='link')
    >>> rtn = map_mean_of_link_nodes_to_link(rmg, 'z', out=values_at_links)
    >>> values_at_links
    array([  0.5,   1.5,   2.5,   2. ,   3. ,   4. ,   5. ,   4.5,   5.5,
             6.5,   6. ,   7. ,   8. ,   9. ,   8.5,   9.5,  10.5])
    >>> rtn is values_at_links
    True

    LLCATS: NINF LINF MAP
    """
    if out is None:
        out = grid.empty(at='link')
    if type(var_name) is str:
        var_name = grid.at_node[var_name]
    out[:] = 0.5 * (var_name[grid.node_at_link_head] + var_name[grid.
        node_at_link_tail])
    return out


def validateInvariants(obj, errors=None):
    """Validate invariants

        Validate object to defined invariants.  If errors is None,
        raises first Invalid error; if errors is a list, appends all errors
        to list, then raises Invalid with the errors as the first element
        of the "args" tuple."""


@staticmethod
def user_parse(data):
    """Parse information from the provider."""
    yield 'id', data.get('id')
    yield 'username', data.get('username')
    yield 'discriminator', data.get('discriminator')
    yield 'picture', 'https://cdn.discordapp.com/avatars/{}/{}.png'.format(data
        .get('id'), data.get('avatar'))


def changes_from_tree(names, lookup_entry, object_store, tree,
    want_unchanged=False):
    """Find the differences between the contents of a tree and
    a working copy.

    :param names: Iterable of names in the working copy
    :param lookup_entry: Function to lookup an entry in the working copy
    :param object_store: Object store to use for retrieving tree contents
    :param tree: SHA1 of the root tree, or None for an empty tree
    :param want_unchanged: Whether unchanged files should be reported
    :return: Iterator over tuples with (oldpath, newpath), (oldmode, newmode),
        (oldsha, newsha)
    """
    other_names = set(names)
    if tree is not None:
        for name, mode, sha in object_store.iter_tree_contents(tree):
            try:
                other_sha, other_mode = lookup_entry(name)
            except KeyError:
                yield (name, None), (mode, None), (sha, None)
            else:
                other_names.remove(name)
                if want_unchanged or other_sha != sha or other_mode != mode:
                    yield (name, name), (mode, other_mode), (sha, other_sha)
    for name in other_names:
        other_sha, other_mode = lookup_entry(name)
        yield (None, name), (None, other_mode), (None, other_sha)


def __call__(context, request):
    """Returns a bound skin template instance."""


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

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

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


def case_3D():
    """
    solar = data("solar")
    model_y1 = lm("y1 ~ A*B*C*D", data=solar)
    summary(model_y1)
    pareto_plot(model_y1)

    model_y2 = lm("y2 ~ A*B*C*D", data=solar)
    summary(model_y2)
    pareto_plot(model_y2)
    pareto_plot(model_y2, main="Pareto plot for Energy Delivery Efficiency")

    # 4H
    A = B = C = c(-1, +1)
    A, B, C = expand.grid(A=A, B=B, C=C)

    # These 4 factors are generated, using the trade-off table relationships
    D = A*B
    E = A*C
    F = B*C
    G = A*B*C

    # These are the 8 experimental outcomes, corresponding to the 8 entries
    # in each of the vectors above
    y = c(320, 276, 306, 290, 272, 274, 290, 255)

    expt = gather(A=A, B=B, C=C, D=D, E=E, F=F, G=G, y=y)

    # And finally, the linear model
    mod_ff = lm("y ~ A*B*C*D*E*F*G", expt)
    pareto_plot(mod_ff)

    # Now rebuild the linear model with only the 4 important terms
    mod_res4 = lm("y ~ A*C*E*G", expt)
    pareto_plot(mod_res4)
    """
    pass


def command(cmd, label, env={}):
    """Create a Benchpress command, which define a single benchmark execution

    This is a help function to create a Benchpress command, which is a Python `dict` of the parameters given.

    Parameters
    ----------
    cmd : str
        The bash string that makes up the command
    label : str
        The human readable label of the command
    env : dict
        The Python dictionary of environment variables to define before execution'

    Returns
    -------
    command : dict
        The created Benchpress command
    """
    return {'cmd': cmd, 'label': label, 'env': env}


@property
def yaml():
    """A YAML representation of the :class:`Dataset` object. If headers have been
        set, a YAML list of objects will be returned. If no headers have
        been set, a YAML list of lists (rows) will be returned instead.

        A dataset object can also be imported by setting the :class:`Dataset.yaml` attribute: ::

            data = tablib.Dataset()
            data.yaml = '- {age: 90, first_name: John, last_name: Adams}'

        Import assumes (for now) that headers exist.
        """
    pass


def dfa_intersection(dfa_1: dict, dfa_2: dict) ->dict:
    """ Returns a DFA accepting the intersection of the DFAs in
    input.

    Let :math:`A_1 = (Σ, S_1 , s_{01} , ρ_1 , F_1 )` and
    :math:`A_2 = (Σ, S_2 , s_{02} , ρ_2 , F_2 )` be two DFAs.
    Then there is a DFA :math:`A_∧` that runs simultaneously both
    :math:`A_1` and :math:`A_2` on the input word and
    accepts when both accept.
    It is defined as:

    :math:`A_∧ = (Σ, S_1 × S_2 , (s_{01} , s_{02} ), ρ, F_1 × F_2 )`

    where

    :math:`ρ((s_1 , s_2 ), a) = (s_{X1} , s_{X2} )` iff
    :math:`s_{X1} = ρ_1 (s_1 , a)` and :math:`s_{X2}= ρ_2 (s_2 , a)`

    Implementation proposed guarantees the resulting DFA has only
    **reachable** states.

    :param dict dfa_1: first input DFA;
    :param dict dfa_2: second input DFA.
    :return: *(dict)* representing the intersected DFA.
    """
    intersection = {'alphabet': dfa_1['alphabet'].intersection(dfa_2[
        'alphabet']), 'states': {(dfa_1['initial_state'], dfa_2[
        'initial_state'])}, 'initial_state': (dfa_1['initial_state'], dfa_2
        ['initial_state']), 'accepting_states': set(), 'transitions': dict()}
    boundary = set()
    boundary.add(intersection['initial_state'])
    while boundary:
        state_dfa_1, state_dfa_2 = boundary.pop()
        if state_dfa_1 in dfa_1['accepting_states'] and state_dfa_2 in dfa_2[
            'accepting_states']:
            intersection['accepting_states'].add((state_dfa_1, state_dfa_2))
        for a in intersection['alphabet']:
            if (state_dfa_1, a) in dfa_1['transitions'] and (state_dfa_2, a
                ) in dfa_2['transitions']:
                next_state_1 = dfa_1['transitions'][state_dfa_1, a]
                next_state_2 = dfa_2['transitions'][state_dfa_2, a]
                if (next_state_1, next_state_2) not in intersection['states']:
                    intersection['states'].add((next_state_1, next_state_2))
                    boundary.add((next_state_1, next_state_2))
                intersection['transitions'][(state_dfa_1, state_dfa_2), a
                    ] = next_state_1, next_state_2
    return intersection


def getMeanWave(Parms):
    """returns mean wavelength from Instrument parameters dictionary

    :param dict Parms: Instrument parameters;
        must contain:
        Lam: single wavelength
        or
        Lam1,Lam2: Ka1,Ka2 radiation wavelength
        I(L2)/I(L1): Ka2/Ka1 ratio

    :returns: float wave: mean wavelength

    """
    try:
        return Parms['Lam'][1]
    except KeyError:
        meanLam = (Parms['Lam1'][1] + Parms['I(L2)/I(L1)'][1] * Parms[
            'Lam2'][1]) / (1.0 + Parms['I(L2)/I(L1)'][1])
        return meanLam


def _applySpecialOrthoOptsCentre(centre, displayCtx, xax, yax, canvas):
    """Shared by the ``xcentre``, ``ycentre``, and ``zcentre`` functions.
    """
    xlo = displayCtx.bounds.getLo(xax)
    ylo = displayCtx.bounds.getLo(yax)
    xlen = displayCtx.bounds.getLen(xax)
    ylen = displayCtx.bounds.getLen(yax)
    xmid = xlo + 0.5 * xlen
    ymid = ylo + 0.5 * ylen
    x = xmid + 0.5 * xlen * centre[0]
    y = ymid + 0.5 * ylen * centre[1]
    canvas.centreDisplayAt(x, y)


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

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

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

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

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

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


def _mockable_print(arg):
    """A print function that can be mocked in tests.

    Args:
        arg: the thing to print
    """
    print(arg)


def getCRS(filePath):
    """
    extracts coordinatesystem from gml File

    input "filepath": type string, file path to gml file

    returns epsg code of used coordinate reference system: type list

    coordinatesystem= []
    ogr2ogr.main(["","-f", "GeoJSON", "outputCRS.json", filePath])
    myGeojson = pygeoj.load(filepath="outputCRS.json")
    properties= (myGeojson.get_feature(0).properties)
    for key, value in properties.items():
        if key=="srsID":
            coordinatesystem.append(value)
        else:
            pass
    os.remove("outputCRS.json")
    if hf.searchForParameters(["crs","srsID"],coordinatesystem) is None:
        raise Exception('The gml file from ' + filePath + ' has no CRS')
    if hf.searchForParameters(["crs","srsID"],coordinatesystem,) == "4326" or "WGS84":
        return "4326"
    else:
        raise Exception('The gml file from ' + filePath + ' has no WGS84 CRS')
    return "4326"
    """
    return '4326'


def coloredText(text='', color='red', htmlClass='', pull=False, size=False,
    addBackgroundColor=False):
    """
    *Colour text a given colour*

    **Key Arguments:**
        - ``text`` -- the text to color
        - ``color`` -- the color
        - ``htmlClass`` -- the class for the text
        - ``size`` -- the relative size of the text
        - ``addBackgroundColor`` -- add a complimentary background color to the text

    **Return:**
        - ``text`` -- the coloured text span
    """
    if pull is not False:
        pull = 'pull-%(pull)s' % locals()
    else:
        pull = ''
    if size is not False:
        size = 'size-%(size)s' % locals()
    else:
        size = ''
    if addBackgroundColor is not False:
        addBackgroundColor = 'addBackground'
    else:
        addBackgroundColor = ''
    text = (
        '%(text)s'
         % locals())
    return text


def get_vm_host(vbo, vm_name):
    """
    Get the VM host that a VM is on
    """
    try:
        return filter(lambda vbox: vm_name in vbox.get_vm_names(), vbo.
            servers.values())[0]
    except IndexError:
        return None


@staticmethod
def set_root_namespace(context, node):
    """ Sets root namespace into context from node text"""
    context.root_namespace = node.text


@staticmethod
def match(event, kwargs):
    """Compare an event object with the given keywork arguments.

        Called when using :func:`__call__`. See above for an example."""
    for i in kwargs:
        if not hasattr(event, i):
            break
        if getattr(event, i) != kwargs[i]:
            break
    else:
        return True
    return False


@staticmethod
def matches_indexing_condition(item):
    """
        Returns True by default to index all documents.
        """
    return True


def normalize(mat):
    """ Normalize columns so that each of them sum up to 1 """
    norms = mat.sum(0)
    norms[norms == 0] = 1
    mat /= norms
    return mat


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

        :param LoginFailDetails val:
        :rtype: EventDetails
        """
    return cls('login_fail_details', val)


def count():
    """Return the number of spiders in the queue.

        This method can return a deferred. """


def getPath():
    """Return the Python path of the class."""


def create_name_behavior_id(name: str, team_id: int) ->str:
    """
   Reconstructs fully qualified behavior name from name and team_id
   :param name: brain name
   :param team_id: team ID
   :return: name_behavior_id
   """
    return name + '?team=' + str(team_id)


def bool2int(bool):
    """Convert a bool to an int."""
    if bool:
        return 1
    else:
        return 0


def simulate_until_attractor_or_max_t_storing_all_states(max_attractor_l,
    _simulate_until_attractor_or_target_substate_or_max_t, initial_state,
    perturbed_nodes_by_t, predecessor_node_lists, truth_tables):
    """
    Simulates until attractor is found (or one of optionally given constrains is exceeded).

    State is not considered as part of the attractor until all the perturbations are carried out. Initial state
    can be considered as part of the attractor only if no perturbations are present.

    :param max_attractor_l: maximum length of attractor to search for
    :param _simulate_until_attractor_or_target_substate_or_max_t: [function]
    to perform simulation accounting for the time cap (if any)
    :param initial_state: initial state of the network
    :param perturbed_nodes_by_t: dict (by time step) of dicts (by node) of
        node states
    :param predecessor_node_lists: list of predecessor node lists
    :param truth_tables: list of dicts (key: tuple of predecessor node states,
        value: resulting node state)
    :return attractor or None if not found
    """
    attractor = None
    (states, state_codes_since_last_perturbation, _, attractor_is_found, *_
        ) = (_simulate_until_attractor_or_target_substate_or_max_t(
        initial_state, perturbed_nodes_by_t, predecessor_node_lists,
        truth_tables))
    if attractor_is_found:
        attractor_first_state_code = state_codes_since_last_perturbation[-1]
        attractor_trajectory_l = state_codes_since_last_perturbation.index(
            attractor_first_state_code)
        attractor_l = len(state_codes_since_last_perturbation) - (
            attractor_trajectory_l + 1)
        if attractor_l <= max_attractor_l:
            attractor_state_codes = state_codes_since_last_perturbation[-
                attractor_l:]
            attractor_min_state_code = min(attractor_state_codes)
            attractor_states = states[-attractor_l:]
            attractor_trajectory_l = len(states) - (attractor_l + 1)
            attractor = (attractor_min_state_code, attractor_state_codes,
                attractor_states, attractor_trajectory_l)
    return attractor


@classmethod
def adapt_emulated_to_native(cls, impl, **kw):
    """Produce a MySQL native :class:`.mysql.ENUM` from plain
        :class:`.Enum`.

        """
    kw.setdefault('validate_strings', impl.validate_strings)
    kw.setdefault('values_callable', impl.values_callable)
    return cls(**kw)


def getHierarchies(unique_name=None):
    """Returns a list of IHierarchy in the catalog optionally
        matching the given name."""


@classmethod
def from_disk(cls, data_file_path):
    """
        Creates an instance of the class from disk.

        Ideally we would support loading of any file type. For now
        we'll punt on building in any logic until we have more types to deal
        with.
        """
    return cls._from_schafer_file(data_file_path)


@staticmethod
def is_hello(x) ->bool:
    """Return if packet is a hello packet."""
    if 'length' in x:
        val = x['length']
    else:
        val = x.header.value['length']
    return bool(val == 32)


def get_supported_conversions():
    """Return an iterable of tuples in the form (key, name, extension,
        in_mimetype, out_mimetype, quality) representing the MIME conversions
        supported and
        the quality ratio of the conversion in the range 0 to 9, where 0 means
        no support and 9 means "perfect" support. eg. ('latex', 'LaTeX', 'tex',
        'text/x-trac-wiki', 'text/plain', 8)"""


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

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


@staticmethod
def is_ignored(match):
    """
        Ignore matches when scanning for title (hole).

        Full word language and countries won't be ignored if they are uppercase.
        """
    return not (len(match) > 3 and match.raw.isupper()) and match.name in (
        'language', 'country', 'episode_details')


def isConnected():
    """Return True if the worker is currently online, False if not."""


def number_callback(_option, opt, _value, parser):
    """I manage options -R, -1 and -2"""
    val = int(opt[1:])
    parser.values.requests = val


def sanitize(s) ->str:
    """
    Returns string decoded from utf-8 with leading/trailing whitespace
    character removed
    """
    return s.decode('utf-8').strip()


def antenna_interactions_agg_query(table_name='%(table_name)s'):
    """
    Aggregated dataframe of antenna interactions over all chunks.

    Inputs
    ------
    table_name : name of the table the query is supposed to run on,
                 defaulting to '%(table_name)s', i.e. no substitution

    Output
    ------
    Aggregated dataframe of antenna interactions over all chunks.
    """
    query = """
        SELECT
          antenna_id1,
          antenna_id2,
          SUM(sms_count) as sms_count,
          SUM(call_count) as call_count,
          SUM(vol_sum) as vol_sum
        FROM %(table_name)s
        GROUP BY antenna_id1, antenna_id2
    """
    return query % {'table_name': table_name}


@staticmethod
def doc_merger(prnt_attr_doc, child_doc):
    """ Merges the parent and child docstrings into a single docstring.

        Parameters
        ----------
        prnt_attr_doc: Union[None, str]
        child_doc: Union[None, str]

        Raises
        ------
        NotImplementedError"""
    raise NotImplementedError


def convert_ms(ms):
    """
    Converts milliseconds into h:m:s

    :param ms: int
    :return: str
    """
    seconds = ms / 1000 % 60
    seconds = int(seconds)
    if seconds < 10:
        seconds = '0' + str(seconds)
    else:
        seconds = str(seconds)
    minutes = ms / (1000 * 60) % 60
    minutes = int(minutes)
    if minutes < 10:
        minutes = '0' + str(minutes)
    else:
        minutes = str(minutes)
    hours = ms / (1000 * 60 * 60) % 24
    hours = int(hours)
    if hours < 10:
        hours = '0' + str(hours)
    else:
        hours = str(hours)
    return hours + ':' + minutes + ':' + seconds


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_selector(labels):
    """
  Transfer Labels to selector.
  """
    parts = []
    for key in labels.keys():
        parts.append('{0}={1}'.format(key, labels[key]))
    return ','.join(parts)


def _html_escape(string):
    """HTML escape all of these " & < >"""
    html_codes = {'"': '"', '<': '<', '>': '>'}
    string = string.replace('&', '&')
    for char in html_codes:
        string = string.replace(char, html_codes[char])
    return string


@staticmethod
def __percentage_storage_saved(task):
    """
        Calculate the percentage of storage space saved by the compression.
        :param task: information about the task
        :return: percentage of storage space saved
        """
    task_information = task.get_task_information()
    return int((1 - task_information.output_filesize / task_information.
        filesize) * 100)


def parse_photo_link(photo_url):
    """
    Extracts the base URL (URL without query parameters) and the photo name from a Onedrive photo URL
    :param photo_url: photo URL
    :return: base URL and photo name
    """
    base_url = photo_url.split('?')[0]
    name = base_url.split('/')[-1]
    return base_url, name


@staticmethod
def supports_dry_runs():
    """ The CSV plugin supports dry runs.

        Returns:
            bool: True
        """
    return True


def load_mapping(mapping_txt):
    """Load mapping file

    Parameter
    ---------
    mapping_txt : `str`
        Path to mapping file

    Returns
    -------
    mapping : `dict`
        {1st field: 2nd field} dictionary
    """
    with open(mapping_txt, mode='r') as fp:
        lines = fp.readlines()
    mapping = dict()
    for line in lines:
        key, value, *left = line.strip().split()
        mapping[key] = value
    return mapping


def getuser():
    """
    Function to get the username from the environment or password database.

    First try various environment variables, then the password
    database.  This works on Windows as long as USERNAME is set.

    @return username
    @rtype str
    """
    import os
    for name in ('LOGNAME', 'USER', 'LNAME', 'USERNAME'):
        user = os.environ.get(name)
        if user:
            return user
    import pwd
    return pwd.getpwuid(os.getuid())[0]


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 GetInfo(r):
    """
    Gets info about the cluster.

    @rtype: dict
    @return: information about the cluster
    """
    return r.request('get', '/2/info')


def origin_dumper(**kwargs):
    """Dump data to a format suitable for use in OriginLab."""
    pass


@classmethod
def remove(cls, ids_to_delete):
    """Remove an Association instance"""
    raise NotImplementedError('Implement in subclass')


def p_with_stmt_1(p):
    """with_stmt : WITH with_item COLON suite"""
    p[2].body = p[4]
    p[0] = p[2]


def find():
    """Find specified text

    """
    pass


def _encode_asn1_str(backend, data):
    """
    Create an ASN1_OCTET_STRING from a Python byte string.
    """
    s = backend._lib.ASN1_OCTET_STRING_new()
    res = backend._lib.ASN1_OCTET_STRING_set(s, data, len(data))
    backend.openssl_assert(res == 1)
    return s


@staticmethod
def _get_shipment():
    """Return list of Model names for shipment Reference"""
    return ['stock.shipment.in', 'stock.shipment.out',
        'stock.shipment.out.return', 'stock.shipment.in.return',
        'stock.shipment.internal']


def datatypes_for_parameters():
    """
        Returns a sequence of datatypes.

        XXX: This only works for ordered params; make this work
        for named parameters. Probably want to treat the two the same,
        with ordered parameters using indexes as their name.
        """


def decode(message):
    """Decode message without key."""
    pass


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

        :param PaperDocAddCommentType val:
        :rtype: EventType
        """
    return cls('paper_doc_add_comment', val)


def instance(cls):
    """Decorator for creating one of instances.

    Parameters
    ----------
    cls : type
        A class.

    Returns
    -------
    instance : cls
        A new instance of ``cls``.
    """
    return cls()


def google_text_emphasis(style):
    """return a list of all emphasis modifiers of the element"""
    emphasis = []
    if 'text-decoration' in style:
        emphasis.append(style['text-decoration'])
    if 'font-style' in style:
        emphasis.append(style['font-style'])
    if 'font-weight' in style:
        emphasis.append(style['font-weight'])
    return emphasis


def outlier_removal_nearest_cut(dataframe, colname, low_cut, high_cut):
    """Clip outliers on dataframe[colname]"""
    col = dataframe[colname]
    dataframe.loc[col.apply(lambda x: isinstance(x, (int, float)) and x <
        low_cut), colname] = low_cut
    dataframe.loc[col.apply(lambda x: isinstance(x, (int, float)) and x >
        high_cut), colname] = high_cut
    return dataframe


def shift_line(segs, amount):
    """
    Return a shifted line from a layout structure to the left or right.
    segs -- line of a layout structure
    amount -- screen columns to shift right (+ve) or left (-ve)
    """
    assert type(amount) == int, repr(amount)
    if segs and len(segs[0]) == 2 and segs[0][1] == None:
        amount += segs[0][0]
        if amount:
            return [(amount, None)] + segs[1:]
        return segs[1:]
    if amount:
        return [(amount, None)] + segs
    return segs


@staticmethod
def __encryptionresolver__(pk, rk, property_name):
    """ define properties to encrypt
            overwrite if inherit this class
        """
    pass


def search_criteria(**kwargs):
    """Build a searching criteria

    Dummy function, just a place holder for now.
    """
    assert kwargs['sensor'] in ['aqua', 'terra']
    assert kwargs['dtype'] == 'L3m'
    return ['*DAY_CHL_chlor_a_4km*']


@classmethod
def activate(cls, flow_task, prev_activation, token):
    """Instantiate and persist new flow task."""
    raise NotImplementedError


def vector_divide(vector, value):
    """
    Divides given vector by a value
    :param vector: list(float, float, float)
    :param value: float ,value to multiple vector by
    :return: list(float, float, float)
    """
    result = [vector[0] / value, vector[1] / value, vector[2] / value]
    return result


def gpu_info():
    """Return an empty list."""
    return []


@classmethod
def lookup_cache_key(cls, cache_key):
    """Syntactic sugar for update_cache_key(cache_key)"""
    return cls.update_cache_key(cache_key)


def strings_differ(string1, string2):
    """Check whether two strings differ while avoiding timing attacks.

    This function returns True if the given strings differ and False
    if they are equal.  It's careful not to leak information about *where*
    they differ as a result of its running time, which can be very important
    to avoid certain timing-related crypto attacks:

        http://seb.dbzteam.org/crypto/python-oauth-timing-hmac.pdf

    """
    if len(string1) != len(string2):
        return True
    invalid_bits = 0
    for a, b in zip(string1, string2):
        invalid_bits += a != b
    return invalid_bits != 0


def isoweekday():
    """Return the day of the week as an integer.

        Monday is 1 and Sunday is 7. For example,
        date(2002, 12, 4).isoweekday() == 3, a Wednesday.

        See also weekday(), isocalendar().
        """


def __new__(cls, name='Default', defaults=None):
    """
        Class constructor.
        :param name: instance name id.
        :param defaults: dafault values dict or None.
        :return: an instance of the config object.
        """
    if name not in cls.__registry__:
        cls.__registry__[name] = dict.__new__(cls)
    return cls.__registry__[name]


def fit_one_cadence(arg):
    """Helper function to enable parallelism.

    This function is used by PRFPhotometry.run().
    """
    model = arg[0]
    data = arg[1]
    if len(arg) == 4:
        pos_corr1, pos_corr2 = arg[2], arg[3]
    else:
        pos_corr1, pos_corr2 = None, None
    return model.fit(data, pos_corr1=pos_corr1, pos_corr2=pos_corr2)


def fibo(max_value=None):
    """Generator for fibonaccial decay.

    Args:
        max_value: The maximum value to yield. Once the value in the
             true fibonacci sequence exceeds this, the value
             of max_value will forever after be yielded.
    """
    a = 1
    b = 1
    while True:
        if max_value is None or a < max_value:
            yield a
            a, b = b, a + b
        else:
            yield max_value


def clip_pad(tensor, pad_shape):
    """
    Clip boxes of the pad area.
    :param tensor: [n, c, H, W]
    :param pad_shape: [h, w]
    :return: [n, c, h, w]
    """
    H, W = tensor.shape[2:]
    h, w = pad_shape
    if h < H or w < W:
        tensor = tensor[:, :, :h, :w].copy()
    return tensor


def _is_prefixed(cmd_line):
    """Whether the supplied command line has already been prefixed
    with an OS specific operation.
    """
    if cmd_line is None:
        raise ValueError('CommandLine is required field for task.')
    return cmd_line.startswith('cmd.exe /c') or cmd_line.startswith('cmd /c'
        ) or cmd_line.startswith('/bin/bash -c') or cmd_line.startswith(
        '/bin/sh -c')


def create_db_cluster_parameter_group(DBClusterParameterGroupName=None,
    DBParameterGroupFamily=None, Description=None, Tags=None):
    """
    Creates a new DB cluster parameter group.
    Parameters in a DB cluster parameter group apply to all of the instances in a DB cluster.
    A DB cluster parameter group is initially created with the default parameters for the database engine used by instances in the DB cluster. To provide custom values for any of the parameters, you must modify the group after creating it using  ModifyDBClusterParameterGroup . Once you've created a DB cluster parameter group, you need to associate it with your DB cluster using  ModifyDBCluster . When you associate a new DB cluster parameter group with a running DB cluster, you need to reboot the DB instances in the DB cluster without failover for the new DB cluster parameter group and associated settings to take effect.
    For more information on Amazon Aurora, see Aurora on Amazon RDS in the Amazon RDS User Guide.
    See also: AWS API Documentation

    Examples
    This example creates a DB cluster parameter group.
    Expected Output:

    :example: response = client.create_db_cluster_parameter_group(
        DBClusterParameterGroupName='string',
        DBParameterGroupFamily='string',
        Description='string',
        Tags=[
            {
                'Key': 'string',
                'Value': 'string'
            },
        ]
    )

    :type DBClusterParameterGroupName: string
    :param DBClusterParameterGroupName: [REQUIRED]
            The name of the DB cluster parameter group.
            Constraints:
            Must be 1 to 255 alphanumeric characters
            First character must be a letter
            Cannot end with a hyphen or contain two consecutive hyphens
            Note
            This value is stored as a lowercase string.

    :type DBParameterGroupFamily: string
    :param DBParameterGroupFamily: [REQUIRED]
            The DB cluster parameter group family name. A DB cluster parameter group can be associated with one and only one DB cluster parameter group family, and can be applied only to a DB cluster running a database engine and engine version compatible with that DB cluster parameter group family.

    :type Description: string
    :param Description: [REQUIRED]
            The description for the DB cluster parameter group.

    :type Tags: list
    :param Tags: A list of tags.
            (dict) --Metadata assigned to an Amazon RDS resource consisting of a key-value pair.
            Key (string) --A key is the required name of the tag. The string value can be from 1 to 128 Unicode characters in length and cannot be prefixed with 'aws:' or 'rds:'. The string can only contain only the set of Unicode letters, digits, white-space, '_', '.', '/', '=', '+', '-' (Java regex: '^([\\p{L}\\p{Z}\\p{N}_.:/=+\\-]*)$').
            Value (string) --A value is the optional value of the tag. The string value can be from 1 to 256 Unicode characters in length and cannot be prefixed with 'aws:' or 'rds:'. The string can only contain only the set of Unicode letters, digits, white-space, '_', '.', '/', '=', '+', '-' (Java regex: '^([\\p{L}\\p{Z}\\p{N}_.:/=+\\-]*)$').

    :rtype: dict
    :return: {
        'DBClusterParameterGroup': {
            'DBClusterParameterGroupName': 'string',
            'DBParameterGroupFamily': 'string',
            'Description': 'string',
            'DBClusterParameterGroupArn': 'string'
        }
    }

    """
    pass


@staticmethod
def convert_argparse_destination(argument_name):
    """ Converts underscores to dashes, for a deterministic mechanism
         to name (and recall) argparse destinations"""
    return argument_name.lstrip('-').replace('-', '_')


def _a_in_b(first, second):
    """
    Check if interval a is inside interval b.

    Parameters
    ----------
    a : pybedtools.Interval
        First interval.
    b : pybedtools.Interval
        Second interval.

    Returns
    -------
    bool
        True if a is inside b, false otherwise.

    """
    return first.start >= second.start and first.stop <= second.stop


def p_character_with_anchor(p):
    """character : character anchor
                 | anchor character
                 | anchor anchor
                 | character flag
                 | character lookaround
                 | lookaround character
                 | character character
    """
    p[0] = []
    p[0] += p[1]
    p[0] += p[2]


def azion_cdn_cache():
    """
        Create default CDN Cache settings.
    """
    return [{'name': 'cache-1-hour-ignore-qs-cookies',
        'browser_cache_settings': False, 'cdn_cache_settings': 'override',
        'cdn_cache_settings_maximum_ttl': 3600, 'cache_by_query_string':
        'ignore', 'enable_query_string_sort': False, 'cache_by_cookies':
        'ignore'}, {'name': 'cache-5-minutes-ignore-qs-cookies',
        'browser_cache_settings': False, 'cdn_cache_settings': 'override',
        'cdn_cache_settings_maximum_ttl': 300, 'cache_by_query_string':
        'ignore', 'enable_query_string_sort': False, 'cache_by_cookies':
        'ignore'}, {'name': 'cache-bypass', 'browser_cache_settings': False,
        'cdn_cache_settings': 'bypass', 'cache_by_query_string': 'ignore',
        'cache_by_cookies': 'ignore'}]


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

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

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


def _gerrit_user_to_author(props, username='unknown'):
    """
    Convert Gerrit account properties to Buildbot format

    Take into account missing values
    """
    username = props.get('username', username)
    username = props.get('name', username)
    if 'email' in props:
        username += ' <%(email)s>' % props
    return username


def logical_not(attrs, inputs, proto_obj):
    """Logical not of two input arrays."""
    return 'logical_not', attrs, inputs


def calcgbar(Ip, Vclamp, A):
    """Function to calculate a lower bound on the cell's maximum conductance from its peak current
    Ip      :=  Peak current [nA]
    Vclamp  :=  Clamp Voltage [mV]
    A       :=  Cell surface area [um^2]
    return gbar [pS/um^2]"""
    Gmax = Ip / Vclamp
    gbar = Gmax / A
    return gbar * 1000000.0


def get(context, name):
    """
        Return the vocabulary named *name* for the content object
        *context*.

        When the vocabulary cannot be found, `LookupError` is raised.
        """


def cache_badge(request, context, _template=
    'html5_appcache/templatetags/icon.html'):
    """
    Renders the cache badge template
    """
    from django.template import RequestContext
    from django.template.loader import render_to_string
    template_context = RequestContext(request, context)
    return render_to_string(_template, context_instance=template_context)


def get(cls, reactor, source='graphite', **options):
    """Get Alert Class by source."""
    acls = cls.alerts[source]
    return acls(reactor, **options)


def is_valid_bbox(rect):
    """Left/top must be >= 0, W/H must be > 0"""
    return rect[0] >= 0 and rect[1] >= 0 and rect[2] > 0 and rect[3] > 0


def maxKey(key=None):
    """Return the maximum key.

        If a key argument if provided and not None, return the largest key
        that is less than or equal to the argument.  Raise an exception if
        no such key exists.
        """


@staticmethod
def get_data(response):
    """Value is response.status."""
    return response.code


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

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

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


def 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 normalise_between_2_values(arraylike, min_value, max_value, invert=False):
    """Normalises an array of data between two desired values.

    Any values below min_value will be converted to 0.
    Any values above max_value will be converted to 1.
    Optionally, the normalised array can be inverted, so that the original highest
    values are 0, and the original lowest values are now 1.

    Parameters
    ----------
    arraylike : np.ndarray
        Arraylike original data (numpy array or pandas Series)
    min_value : float
        Desired minimum value for normalisation
    max_value : float
        Desired max value for normalisation
    invert : bool
        If True, normalised data will be inverted (former highest value = 0)

    Returns
    -------
    normalised : np.ndarray
        Normalised array of data

    Usage
    -----
    from eccpy.tools import normalise_between_2_values
    # for array
    orig_array = np.array(range(0, 15))
    norm_array = normalise_between_2_values(orig_array, 3, 10)
    # for pandas Dataframe
    df["norm_data"] = normalise_between_2_values(df["orig_data"], 3, 10)
    """
    normalised = (arraylike - min_value) / (max_value - min_value)
    normalised[normalised > 1] = 1
    normalised[normalised < 0] = 0
    if invert:
        normalised = abs(normalised - 1)
    return normalised


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

    Like 'git describe --tags --dirty --always'.

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


def iterate(f, x):
    """
    Returns a generator of ``x``, ``f(x)``, ``f(f(x))``, etc.
    """
    while True:
        yield x
        x = f(x)


def get_recipes_from_dict(input_dict: dict) ->dict:
    """Get recipes from dict

    Attributes:
        input_dict (dict): ISO_639_1 language code

    Returns:
        recipes (dict): collection of recipes for input language
    """
    if not isinstance(input_dict, dict):
        raise TypeError('Input is not type dict')
    recipes = input_dict
    return recipes


def citation():
    """
    Print the OSMnx package's citation information.

    Boeing, G. 2017. OSMnx: New Methods for Acquiring, Constructing, Analyzing,
    and Visualizing Complex Street Networks. Computers, Environment and Urban
    Systems, 65(126-139). https://doi.org/10.1016/j.compenvurbsys.2017.05.004
    """
    cite = """To cite OSMnx, use:

Boeing, G. 2017. OSMnx: New Methods for Acquiring, Constructing, Analyzing, and Visualizing Complex Street Networks. Computers, Environment and Urban Systems, 65(126-139). https://doi.org/10.1016/j.compenvurbsys.2017.05.004

BibTeX entry for LaTeX users:

@article{boeing_osmnx_2017,
    title = {{OSMnx}: {New} {Methods} for {Acquiring}, {Constructing}, {Analyzing}, and {Visualizing} {Complex} {Street} {Networks}},
    volume = {65},
    doi = {10.1016/j.compenvurbsys.2017.05.004},
    number = {126-139},
    journal = {Computers, Environment and Urban Systems},
    author = {Boeing, Geoff},
    year = {2017}
}"""
    print(cite)


@classmethod
def hexblock_dword(cls, data, address=None, bits=None, separator=' ', width=4):
    """
        Dump a block of hexadecimal DWORDs from binary data.

        @type  data: str
        @param data: Binary data.

        @type  address: str
        @param address: Memory address where the data was read from.

        @type  bits: int
        @param bits:
            (Optional) Number of bits of the target architecture.
            The default is platform dependent. See: L{HexDump.address_size}

        @type  separator: str
        @param separator:
            Separator between the hexadecimal representation of each DWORD.

        @type  width: int
        @param width:
            (Optional) Maximum number of DWORDs to convert per text line.

        @rtype:  str
        @return: Multiline output text.
        """
    return cls.hexblock_cb(cls.hexa_dword, data, address, bits, width * 4,
        cb_kwargs={'separator': separator})


def clear_persistent_graph_cache(request):
    """
    Clears the caches for the graph cache
    """
    request.facebook = None
    request.session.delete('graph')
    if request.user.is_authenticated():
        profile = request.user.get_profile()
        profile.clear_access_token()


def check_factor(min_val, max_val, factor):
    """
    Checks if factor is min_val < factor < max_val
    :param min_val:
    :param max_val:
    :param factor:
    :return:
    """
    if factor > max_val:
        return max_val
    if factor < min_val:
        return min_val
    return factor


@staticmethod
def gcn_server(_server, _port):
    """get host and port so that pygcn could use for monitoring triggers.

        Parameters
        ----------
        _server:
            local, eApps, Atlantic_2, Atlantic_3, Linode
        _port:
            public, LVC, AMON
        """
    assert _server in ['local', 'eApps', 'Atlantic_2', 'Atlantic_3', 'Linode']
    assert _port in ['public', 'LVC', 'AMON']
    if _server == 'local':
        return '127.0.0.1', 8099
    if _server == 'eApps':
        if _port == 'public':
            return '68.169.57.253', 8099
        if _port == 'LVC':
            return '68.169.57.253', 8092
        if _port == 'AMON':
            return '68.169.57.253', 8096
    if _server == 'Atlantic_2':
        if _port == 'public':
            return '209.208.78.170', 8099
        if _port == 'LVC':
            return '209.208.78.170', 8092
        if _port == 'AMON':
            return '209.208.78.170', 8096
    if _server == 'Atlantic_3':
        _server, _port = '45.58.43.186', 8099
    if _server == 'Linode':
        if _port == 'public':
            return '50.116.49.68', 8099
        if _port != 'public':
            return '50.116.49.68', 8096
    return _server, _port


def parse_custom_arguments(click_args: list) ->dict:
    """
    Parse all the unknown arguments from click for downstream tasks. Used in
    user plugins for custom command line arguments.

    Parameters
    ----------
    click_args : list
        Unknown arguments from click

    Returns
    -------
    parsed : dict
        Parsed arguments stored as key value pair

    Note
    -----
    Unknown arguments must be long arguments i.e should start with --
    """
    parsed = {}
    for i in range(0, len(click_args), 2):
        key = click_args[i]
        val = click_args[i + 1]
        if not key.startswith('--'):
            raise RuntimeError(
                f'Could not parse argument {key}. It should be prefixed with `--`'
                )
        parsed[key[2:]] = val
    return parsed


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


def manage_edit(title, connection_id, arguments, template):
    """

        Change database method properties.

        The 'connection_id' argument is the id of a database
        connection that resides in the current folder or in a folder
        above the current folder.  The database should understand SQL.

        The 'arguments' argument is a string containing an arguments
        specification, as would be given in the SQL method creation
        form.

        The 'template' argument is a string containing the source for
        the SQL Template.

        """


def get_fit_list():
    """3 fct or just no fit"""
    return ['Gaussian', 'Moffat', 'Bessel1', 'None']


def create_user_pool(PoolName=None, Policies=None, LambdaConfig=None,
    AutoVerifiedAttributes=None, AliasAttributes=None,
    SmsVerificationMessage=None, EmailVerificationMessage=None,
    EmailVerificationSubject=None, SmsAuthenticationMessage=None,
    MfaConfiguration=None, DeviceConfiguration=None, EmailConfiguration=
    None, SmsConfiguration=None, UserPoolTags=None, AdminCreateUserConfig=
    None, Schema=None):
    """
    Creates a new Amazon Cognito user pool and sets the password policy for the pool.
    See also: AWS API Documentation

    :example: response = client.create_user_pool(
        PoolName='string',
        Policies={
            'PasswordPolicy': {
                'MinimumLength': 123,
                'RequireUppercase': True|False,
                'RequireLowercase': True|False,
                'RequireNumbers': True|False,
                'RequireSymbols': True|False
            }
        },
        LambdaConfig={
            'PreSignUp': 'string',
            'CustomMessage': 'string',
            'PostConfirmation': 'string',
            'PreAuthentication': 'string',
            'PostAuthentication': 'string',
            'DefineAuthChallenge': 'string',
            'CreateAuthChallenge': 'string',
            'VerifyAuthChallengeResponse': 'string'
        },
        AutoVerifiedAttributes=[
            'phone_number'|'email',
        ],
        AliasAttributes=[
            'phone_number'|'email'|'preferred_username',
        ],
        SmsVerificationMessage='string',
        EmailVerificationMessage='string',
        EmailVerificationSubject='string',
        SmsAuthenticationMessage='string',
        MfaConfiguration='OFF'|'ON'|'OPTIONAL',
        DeviceConfiguration={
            'ChallengeRequiredOnNewDevice': True|False,
            'DeviceOnlyRememberedOnUserPrompt': True|False
        },
        EmailConfiguration={
            'SourceArn': 'string',
            'ReplyToEmailAddress': 'string'
        },
        SmsConfiguration={
            'SnsCallerArn': 'string',
            'ExternalId': 'string'
        },
        UserPoolTags={
            'string': 'string'
        },
        AdminCreateUserConfig={
            'AllowAdminCreateUserOnly': True|False,
            'UnusedAccountValidityDays': 123,
            'InviteMessageTemplate': {
                'SMSMessage': 'string',
                'EmailMessage': 'string',
                'EmailSubject': 'string'
            }
        },
        Schema=[
            {
                'Name': 'string',
                'AttributeDataType': 'String'|'Number'|'DateTime'|'Boolean',
                'DeveloperOnlyAttribute': True|False,
                'Mutable': True|False,
                'Required': True|False,
                'NumberAttributeConstraints': {
                    'MinValue': 'string',
                    'MaxValue': 'string'
                },
                'StringAttributeConstraints': {
                    'MinLength': 'string',
                    'MaxLength': 'string'
                }
            },
        ]
    )

    :type PoolName: string
    :param PoolName: [REQUIRED]
            A string used to name the user pool.

    :type Policies: dict
    :param Policies: The policies associated with the new user pool.
            PasswordPolicy (dict) --A container for information about the user pool password policy.
            MinimumLength (integer) --The minimum length of the password policy that you have set. Cannot be less than 6.
            RequireUppercase (boolean) --In the password policy that you have set, refers to whether you have required users to use at least one uppercase letter in their password.
            RequireLowercase (boolean) --In the password policy that you have set, refers to whether you have required users to use at least one lowercase letter in their password.
            RequireNumbers (boolean) --In the password policy that you have set, refers to whether you have required users to use at least one number in their password.
            RequireSymbols (boolean) --In the password policy that you have set, refers to whether you have required users to use at least one symbol in their password.

    :type LambdaConfig: dict
    :param LambdaConfig: The Lambda trigger configuration information for the new user pool.
            PreSignUp (string) --A pre-registration AWS Lambda trigger.
            CustomMessage (string) --A custom Message AWS Lambda trigger.
            PostConfirmation (string) --A post-confirmation AWS Lambda trigger.
            PreAuthentication (string) --A pre-authentication AWS Lambda trigger.
            PostAuthentication (string) --A post-authentication AWS Lambda trigger.
            DefineAuthChallenge (string) --Defines the authentication challenge.
            CreateAuthChallenge (string) --Creates an authentication challenge.
            VerifyAuthChallengeResponse (string) --Verifies the authentication challenge response.

    :type AutoVerifiedAttributes: list
    :param AutoVerifiedAttributes: The attributes to be auto-verified. Possible values: email , phone_number .
            (string) --

    :type AliasAttributes: list
    :param AliasAttributes: Attributes supported as an alias for this user pool. Possible values: phone_number , email , or preferred_username .
            (string) --

    :type SmsVerificationMessage: string
    :param SmsVerificationMessage: A string representing the SMS verification message.

    :type EmailVerificationMessage: string
    :param EmailVerificationMessage: A string representing the email verification message.

    :type EmailVerificationSubject: string
    :param EmailVerificationSubject: A string representing the email verification subject.

    :type SmsAuthenticationMessage: string
    :param SmsAuthenticationMessage: A string representing the SMS authentication message.

    :type MfaConfiguration: string
    :param MfaConfiguration: Specifies MFA configuration details.

    :type DeviceConfiguration: dict
    :param DeviceConfiguration: The device configuration.
            ChallengeRequiredOnNewDevice (boolean) --Indicates whether a challenge is required on a new device. Only applicable to a new device.
            DeviceOnlyRememberedOnUserPrompt (boolean) --If true, a device is only remembered on user prompt.

    :type EmailConfiguration: dict
    :param EmailConfiguration: The email configuration.
            SourceArn (string) --The Amazon Resource Name (ARN) of the email source.
            ReplyToEmailAddress (string) --The REPLY-TO email address.

    :type SmsConfiguration: dict
    :param SmsConfiguration: The SMS configuration.
            SnsCallerArn (string) -- [REQUIRED]The Amazon Resource Name (ARN) of the Amazon Simple Notification Service (SNS) caller.
            ExternalId (string) --The external ID.

    :type UserPoolTags: dict
    :param UserPoolTags: The cost allocation tags for the user pool. For more information, see Adding Cost Allocation Tags to Your User Pool
            (string) --
            (string) --

    :type AdminCreateUserConfig: dict
    :param AdminCreateUserConfig: The configuration for AdminCreateUser requests.
            AllowAdminCreateUserOnly (boolean) --Set to True if only the administrator is allowed to create user profiles. Set to False if users can sign themselves up via an app.
            UnusedAccountValidityDays (integer) --The user account expiration limit, in days, after which the account is no longer usable. To reset the account after that time limit, you must call AdminCreateUser again, specifying 'RESEND' for the MessageAction parameter. The default value for this parameter is 7.
            InviteMessageTemplate (dict) --The message template to be used for the welcome message to new users.
            SMSMessage (string) --The message template for SMS messages.
            EmailMessage (string) --The message template for email messages.
            EmailSubject (string) --The subject line for email messages.

    :type Schema: list
    :param Schema: An array of schema attributes for the new user pool. These attributes can be standard or custom attributes.
            (dict) --Contains information about the schema attribute.
            Name (string) --A schema attribute of the name type.
            AttributeDataType (string) --The attribute data type.
            DeveloperOnlyAttribute (boolean) --Specifies whether the attribute type is developer only.
            Mutable (boolean) --Specifies whether the attribute can be changed once it has been created.
            Required (boolean) --Specifies whether a user pool attribute is required. If the attribute is required and the user does not provide a value, registration or sign-in will fail.
            NumberAttributeConstraints (dict) --Specifies the constraints for an attribute of the number type.
            MinValue (string) --The minimum value of an attribute that is of the number data type.
            MaxValue (string) --The maximum value of an attribute that is of the number data type.
            StringAttributeConstraints (dict) --Specifies the constraints for an attribute of the string type.
            MinLength (string) --The minimum length of an attribute value of the string type.
            MaxLength (string) --The maximum length of an attribute value of the string type.

    :rtype: dict
    :return: {
        'UserPool': {
            'Id': 'string',
            'Name': 'string',
            'Policies': {
                'PasswordPolicy': {
                    'MinimumLength': 123,
                    'RequireUppercase': True|False,
                    'RequireLowercase': True|False,
                    'RequireNumbers': True|False,
                    'RequireSymbols': True|False
                }
            },
            'LambdaConfig': {
                'PreSignUp': 'string',
                'CustomMessage': 'string',
                'PostConfirmation': 'string',
                'PreAuthentication': 'string',
                'PostAuthentication': 'string',
                'DefineAuthChallenge': 'string',
                'CreateAuthChallenge': 'string',
                'VerifyAuthChallengeResponse': 'string'
            },
            'Status': 'Enabled'|'Disabled',
            'LastModifiedDate': datetime(2015, 1, 1),
            'CreationDate': datetime(2015, 1, 1),
            'SchemaAttributes': [
                {
                    'Name': 'string',
                    'AttributeDataType': 'String'|'Number'|'DateTime'|'Boolean',
                    'DeveloperOnlyAttribute': True|False,
                    'Mutable': True|False,
                    'Required': True|False,
                    'NumberAttributeConstraints': {
                        'MinValue': 'string',
                        'MaxValue': 'string'
                    },
                    'StringAttributeConstraints': {
                        'MinLength': 'string',
                        'MaxLength': 'string'
                    }
                },
            ],
            'AutoVerifiedAttributes': [
                'phone_number'|'email',
            ],
            'AliasAttributes': [
                'phone_number'|'email'|'preferred_username',
            ],
            'SmsVerificationMessage': 'string',
            'EmailVerificationMessage': 'string',
            'EmailVerificationSubject': 'string',
            'SmsAuthenticationMessage': 'string',
            'MfaConfiguration': 'OFF'|'ON'|'OPTIONAL',
            'DeviceConfiguration': {
                'ChallengeRequiredOnNewDevice': True|False,
                'DeviceOnlyRememberedOnUserPrompt': True|False
            },
            'EstimatedNumberOfUsers': 123,
            'EmailConfiguration': {
                'SourceArn': 'string',
                'ReplyToEmailAddress': 'string'
            },
            'SmsConfiguration': {
                'SnsCallerArn': 'string',
                'ExternalId': 'string'
            },
            'UserPoolTags': {
                'string': 'string'
            },
            'SmsConfigurationFailure': 'string',
            'EmailConfigurationFailure': 'string',
            'AdminCreateUserConfig': {
                'AllowAdminCreateUserOnly': True|False,
                'UnusedAccountValidityDays': 123,
                'InviteMessageTemplate': {
                    'SMSMessage': 'string',
                    'EmailMessage': 'string',
                    'EmailSubject': 'string'
                }
            }
        }
    }

    :returns:
    (string) --

    """
    pass


def group_insert():
    """Insert selected nodes into a node group

    """
    pass


def is_in_file(file_path, text):
    """ Looks for text appearing in a file.

    :param str file_path: Path to the source file
    :param str text: Text to find in the file
    :raises OSError: If the file does not exist
    :returns bool: True is text is in file, False otherwise
    """
    with open(file_path, 'r') as f:
        content = f.read()
    return text in content


def checkSecHeads(headers):
    """Checks if security headers present, or not"""
    headersPresent = {}
    headersNotPresent = []
    security_headers = ['Referrer-Policy', 'X-XSS-Protection',
        'Content-Security-Policy', 'X-Frame-Options',
        'Strict-Transport-Security', 'X-Content-Type-Options',
        'X-Permitted-Cross-Domain-Policies', 'Public-Key-Pins', 'Expect-CT',
        'Feature-Policy', 'Report-To', 'NEL']
    for security_header in security_headers:
        if security_header in headers:
            headersPresent[security_header] = headers[security_header]
        else:
            headersNotPresent.append(security_header)
    return headersPresent, headersNotPresent


@classmethod
def register_instance(cls, target_class, serializer_func):
    """ Stores an association between a class, and a function that should
        be able to represent said class in terms of native json data types
        """
    cls.serializers[target_class] = serializer_func


def p_case_statement(t):
    """case_statement : CASE value COLON"""
    t[0] = [t[2]]


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


def get_class(name, default_class, map_class=None):
    """Return class based on default
        map_class
             if key == str -> value = class
             else: key = class -> list of strings
    """
    if map_class is None:
        map_class = {}
    klass = default_class
    if name is not None:
        try:
            klass = map_class[name]
        except:
            for k, v in map_class.items():
                if type(k) in (type,) and name in v:
                    klass = k
                    break
    return klass


def get_tracks_based_on_distance(distance: int) ->dict:
    """
    根据给与的距离生成不规律的移动轨迹tracks
    :param distance:
    :return: {'forward_tracks': [...], 'back_tracks': [...]}
    """
    print('移动距离为:{}'.format(distance))
    distance += 20
    v = 0
    t = 0.2
    forward_tracks = []
    current = 0
    mid = distance * 3 / 5
    while current < distance:
        if current < mid:
            a = 2
        else:
            a = -3
        s = v * t + 0.5 * a * t ** 2
        v = v + a * t
        current += s
        forward_tracks.append(round(s))
    back_tracks = [-3, -3, -2, -2, -2, -2, -2, -1, -1, -1]
    return {'forward_tracks': forward_tracks, 'back_tracks': back_tracks}


def rse_supported_protocol_domains():
    """ Returns a list with all supoorted RSE protocol domains."""
    return ['lan', 'wan']


def _get_scores(bm25, document):
    """Helper function for retrieving bm25 scores of given `document` in parallel
    in relation to every item in corpus.

    Parameters
    ----------
    bm25 : BM25 object
        BM25 object fitted on the corpus where documents are retrieved.
    document : list of str
        Document to be scored.

    Returns
    -------
    list of float
        BM25 scores.

    """
    return bm25.get_scores(document)


@classmethod
def header(cls):
    """No header for KDBX file."""
    return ''


@staticmethod
def get_data(index, role, column=None):
    """Get data of the given index
        If the column is is not None and different from
        the index column, will get the data from a sibling
        index with the same row.
        :param index: The index to query for data
        :type index: :class:`PySide.QtCore.QModelIndex`
        :param role: the data role
        :type role: :data:`PySide.QtCore.Qt.ItemDataRole`
        :param column: the column of the row to query for data.
        :type column: :class:`int` | None
        :returns: The data retrieved
        :raises: None
        """
    if column and index.column() != column:
        index = index.sibling(index.row(), column)
    if index.isValid():
        return index.data(role)


def get_valid_availability_zones(instance):
    """
    Fetch valid availability zones for instance or volume from shared settings.
    """
    tenant = instance.service_settings.scope
    if tenant:
        return tenant.service_settings.options.get('valid_availability_zones'
            ) or {}
    return {}


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

    Like 'git describe --tags --dirty --always'.

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


@classmethod
def update(cls, entity: 'Meta.Model', **kwargs: dict) ->'Meta.Model':
    """
        update attributes of model
        return: Model
        """
    for key, value in kwargs.items():
        setattr(entity, key, value)
    entity.save()
    return entity


def plot_calibration_purchases_vs_holdout_purchases(model,
    calibration_holdout_matrix, kind='frequency_cal', n=7, **kwargs):
    """
    Plot calibration purchases vs holdout.

    This currently relies too much on the lifetimes.util calibration_and_holdout_data function.

    Parameters
    ----------
    model: lifetimes model
        A fitted lifetimes model.
    calibration_holdout_matrix: pandas DataFrame
        DataFrame from calibration_and_holdout_data function.
    kind: str, optional
        x-axis :"frequency_cal". Purchases in calibration period,
                 "recency_cal". Age of customer at last purchase,
                 "T_cal". Age of customer at the end of calibration period,
                 "time_since_last_purchase". Time since user made last purchase
    n: int, optional
        Number of ticks on the x axis
    Returns
    -------
    axes: matplotlib.AxesSubplot

    """
    from matplotlib import pyplot as plt
    x_labels = {'frequency_cal': 'Purchases in calibration period',
        'recency_cal': 'Age of customer at last purchase', 'T_cal':
        'Age of customer at the end of calibration period',
        'time_since_last_purchase': 'Time since user made last purchase'}
    summary = calibration_holdout_matrix.copy()
    duration_holdout = summary.iloc[0]['duration_holdout']
    summary['model_predictions'] = summary.apply(lambda r: model.
        conditional_expected_number_of_purchases_up_to_time(
        duration_holdout, r['frequency_cal'], r['recency_cal'], r['T_cal']),
        axis=1)
    if kind == 'time_since_last_purchase':
        summary['time_since_last_purchase'] = summary['T_cal'] - summary[
            'recency_cal']
        ax = summary.groupby(['time_since_last_purchase'])[[
            'frequency_holdout', 'model_predictions']].mean().iloc[:n].plot(**
            kwargs)
    else:
        ax = summary.groupby(kind)[['frequency_holdout', 'model_predictions']
            ].mean().iloc[:n].plot(**kwargs)
    plt.title('Actual Purchases in Holdout Period vs Predicted Purchases')
    plt.xlabel(x_labels[kind])
    plt.ylabel('Average of Purchases in Holdout Period')
    plt.legend()
    return ax


def handles_request_body(request_func):
    """
    This function decorator may be used to mark a method as usable for
    intercepting request body content.

    handles_request_body will intercept the HTTP content in chunks as it
    arrives. This method, like others in the filter class may return a
    FilterAction.
    """
    request_func._handles_request_body = True
    return request_func


def ravel_from_mask(data, mask):
    """
    Selects out the data from a ND array whose points are marked true in `mask`. See also `unravel_from_mask`
    below which allows you to write back into data after you have transformed the 1D output in some way.

    These two functions are especially useful for hierarchical curve fitting where you want to rerun a fit over a subset
    of the data with a different model, such as when you know some of the data is best described by two bands rather than
    one.
    :param data:
    :param mask:
    :return:
    """
    return data.stack(stacked=mask.dims).where(mask.stack(stacked=mask.dims
        ), drop=True)


def __check_function_type(func):
    """Check if it is a function-like object."""
    if not callable(func):
        raise TypeError(
            'First item of the tuple (func, args, cols) must be a function-like object not a {} object'
            .format(type(func)))
    else:
        return func


def get_all_requirements(params):
    """Get all the requirements from a list of params.

    Args:
        params (list): The list of params.
    """
    requirements = []
    for param in params:
        requirements += list(param.requirements)
    return requirements


def resetCaches():
    """Causes all connection caches to be reset as connections are reopened.

    Zope's refresh feature uses this.  When you reload Python modules,
    instances of classes continue to use the old class definitions.
    To use the new code immediately, the refresh feature asks ZODB to
    clear caches by calling resetCaches().  When the instances are
    loaded by subsequent connections, they will use the new class
    definitions.
    """
    global global_reset_counter
    global_reset_counter += 1


def dot3(v1, v2):
    """
    Quick convenient function to compute dot product betwee two 3-element vectors
    dot3: 231 ns | np.dot: 745 ns
    """
    a1, a2, a3 = v1
    b1, b2, b3 = v2
    return a1 * b1 + a2 * b2 + a3 * b3


@classmethod
def buildModelName(cls, parent_model, relative_name):
    """build an 'absolute' model name from the parent model and the
        'relative' name.
        - If parent_model is a TaurusDevice, the return is a composition of
        the database model name and its device name
        - If parent_model is a TaurusAttribute, the relative name is ignored and
        the parent name is returned

        Note: This is a basic implementation. You may need to reimplement this
              for a specific scheme if it supports "useParentModel".
        """
    if parent_model is None:
        return relative_name
    parent_name = parent_model.getFullName()
    if not parent_name:
        return relative_name
    if isinstance(parent_model, cls):
        return parent_name
    return '%s%s' % (parent_name, relative_name)


def crop_to(image_to_crop, reference_image):
    """
    Crops image to the size of a reference image. This function assumes that the relevant image is located in the center
    and you want to crop away equal sizes on both the left and right as well on both the top and bottom.
    :param image_to_crop
    :param reference_image
    :return: image cropped to the size of the reference image
    """
    reference_size = reference_image.size
    current_size = image_to_crop.size
    dx = current_size[0] - reference_size[0]
    dy = current_size[1] - reference_size[1]
    left = dx / 2
    upper = dy / 2
    right = dx / 2 + reference_size[0]
    lower = dy / 2 + reference_size[1]
    return image_to_crop.crop(box=(int(left), int(upper), int(right), int(
        lower)))


def _is_qualified_charm_url(url):
    """Test an URL to see if it is revisioned."""
    parts = url.rsplit('-', 1)
    return len(parts) > 1 and parts[-1].isdigit()


@classmethod
def can_preview_object(cls, object):
    """ Override whether the node can be previewed. """
    return True


def length_score(x1, y1, x2, y2, d1, d2):
    """Scores the length of the cutting line (x1, y1)->(x2, y2) made at a
    concavity depth of d1 and d2.

    Returns
    -------
    Score : float
        Angle score according to equation (5) from the reference.

    See Also
    --------
    SplitConcavities

    References
    ----------
    .. [#] S. Weinert et al "Detection and Segmentation of Cell Nuclei in
    Virtual Microscopy Images: A Minimum-Model Approach" in Nature Scientific
    Reports,vol.2,no.503, doi:10.1038/srep00503, 2012.

    """
    r = ((x1 - x2) ** 2 + (y1 - y2) ** 2) ** 0.5
    LengthScore = r / (r + d1 + d2)
    return LengthScore


def repeater(iter, n):
    """Return an iterator that repeats each element of `iter` exactly
    `n` times before moving on to the next element.

    Examples
    --------

    >>> from climin.schedule import repeater
    >>> s = repeater([1, 2, 3], 2)
    >>> [next(s) for i in range(6)]
    [1, 1, 2, 2, 3, 3]
    """
    for i in iter:
        for j in range(n):
            yield i


def lambd_SO2_Cl_MHJZ89(T, P):
    """n-a: sulfur-dioxide chloride [MHJZ89]."""
    lambd = 0
    valid = T == 298.15
    return lambd, valid


def get_programme_ids(il_inputs_df, level):
    """
    Returns a Serise of Agg ids by level for the FM programme file generation

    :param il_inputs_df: IL input items dataframe
    :type il_inputs_df: pandas.DataFrame

    :param level: fm_programme level number
    :type  level: int
    """
    return il_inputs_df[il_inputs_df['level_id'] == level][['agg_id',
        'coverage_id']].drop_duplicates(subset=['agg_id', 'coverage_id'],
        keep='first').agg_id.reset_index(drop=True)


def IfThenElse(condition, val_if_true, val_if_false):
    """Ternary conditional function: return either *val_if_true* or
    *val_if_false* depending on *condition*.

    Example
    -------
    Here in a parameter definition (assuming that ``summer_period`` is
    defined e.g. in the *calendars* section of the model)::

      average_temperature:
        desc: 'average temperature for the season'
        value: 'IfThenElse(summer_period, 25, 8)'

    Parameters
    ----------
    condition: bool
        a boolean expression
    val_if_true: number
        value to return if the expression is True
    val_if_false: number
        value to return if the expression is False

    Returns
    -------
    number:
        One of the two values, depending on *condition*.

    """
    return val_if_true if condition else val_if_false


@staticmethod
def is_binary_string(content):
    """
        Return true if string is binary data.
        """
    textchars = bytearray([7, 8, 9, 10, 12, 13, 27]) + bytearray(range(32, 256)
        )
    return bool(content.translate(None, textchars))


def proba():
    """Retourne Bonjour nom """
    return 'Bonjour !'


@classmethod
def get(cls, client, name):
    """Get a container by name."""
    response = client.api.containers[name].get()
    container = cls(client, **response.json()['metadata'])
    return container


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

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

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


def transfer_block_fn(offset, source, target, block_size):
    """Adapter for :mod:`multiprocessing` used by :func:`Client.transfer_changes()`."""
    target.write_block(offset, source.read_block(offset, block_size))


def askopenfilename(**kwargs):
    """Return file name(s) from Tkinter's file open dialog."""
    from tkinter import Tk, filedialog
    root = Tk()
    root.withdraw()
    root.update()
    filenames = filedialog.askopenfilename(**kwargs)
    root.destroy()
    return filenames


def resolve(name, timeout=10):
    """
        Return a L{twisted.internet.defer.Deferred} that will resolve a hostname.
        """


def preset_add(name: str='', remove_active: bool=False):
    """Add or remove a Safe Areas Preset

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


def set_default_scope(value):
    """Set the default namespace scope

    :type value: str or callable
    """
    global LOCK_DEFAULT_SCOPE
    LOCK_DEFAULT_SCOPE = value


def handle_fail(erlport, method, *args, **kwargs):
    """If a request is received with invalid method, raise exception."""
    raise Exception('Invalid method %r' % method)


def convert_post_to_VERB(request, verb):
    """
    Force Django to process the VERB.
    """
    if request.method == verb:
        if not hasattr(request, '_read_started'):
            request._read_started = False
        if hasattr(request, '_post'):
            del request._post
            del request._files
        try:
            request.method = 'POST'
            request._load_post_and_files()
            request.method = verb
        except AttributeError:
            request.META['REQUEST_METHOD'] = 'POST'
            request._load_post_and_files()
            request.META['REQUEST_METHOD'] = verb
        setattr(request, verb, request.POST)
    return request


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 ether_to_wei(ether):
    """
    Convert ether to wei
    """
    return ether * 10 ** 18


@classmethod
def get_elasticsearch_schema(clz, _es_version):
    """
        Returns the elasticsearch schema for the _invenio_explicit_acls property.

        The property looks like::

            _invenio_explicit_acls [{
               "timestamp": "...when the ACL has been applied to the resource",
               "acl": <id of the acl>,
               "operation": name of the operation
               "role": [1,2]
            }]

        """
    return {'type': 'integer'}


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

    Like 'git describe --tags --dirty --always'.

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


def data(settings) ->str:
    """
    Impute name of field containing base64 encoded data.

    Parameters
    ----------
    settings : typing.Dict
        YAML parsed to dict

    Returns
    -------
    str:
        "name_of_data_field"
    """
    return '"' + settings['input']['name'] + '"'


def short_name(uri):
    """
    Return the last part of the URI (fragment or path element).
    """
    hashpos = uri.rfind('#', 0, -1)
    slashpos = uri.rfind('/', 0, -1)
    return uri[max(hashpos, slashpos + 1):]


def goToBack():
    """Redirect to back step."""


def unbundle(bundle, heads, url):
    """Transfer repository data to the peer.

        This is how the bulk of data during a push is transferred.

        Returns the integer number of heads added to the peer.
        """


def get_win_folder_with_jna(csidl):
    """ Use the Python Java wrappers to invoke – circuitously,
        I might add – a win32 filesystem API call
    """
    import array
    from com.sun import jna
    from com.sun.jna.platform import win32
    buf_size = win32.WinDef.MAX_PATH * 2
    buf = array.zeros('c', buf_size)
    shell = win32.Shell32.INSTANCE
    shell.SHGetFolderPath(None, getattr(win32.ShlObj, csidl.fullname), None,
        win32.ShlObj.SHGFP_TYPE_CURRENT, buf)
    directory = jna.Native.toString(buf.tostring()).rstrip('\x00')
    has_high_char = False
    for char in directory:
        if ord(char) > 255:
            has_high_char = True
            break
    if has_high_char:
        buf = array.zeros('c', buf_size)
        kernel = win32.Kernel32.INSTANCE
        if kernel.GetShortPathName(directory, buf, buf_size):
            directory = jna.Native.toString(buf.tostring()).rstrip('\x00')
    return directory


def truncate_ordered_dict(d, max_length=10):
    """
    Truncate an ordered dict starting from the oldest entries
    until it has the given maximum length

    :param d: OrderedDict instance
    :param int max_count: Maximum length of the dict
    """
    while len(d) > max_length:
        d.popitem(last=False)


def range():
    """ Returns the range (start date, end date tuple) currently displayed by the view
        """


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

        :param DeviceDeleteOnUnlinkFailDetails val:
        :rtype: EventDetails
        """
    return cls('device_delete_on_unlink_fail_details', val)


def permutation_arbitrary_swap(args, num_qubits):
    """
    Not yet implemented.
    """
    raise NotImplementedError('Arbitrary topological QPU not yet implemented')


def _classname(x):
    """Get class name from an object.

    Use class names to avoid clunky <class 'int'> output

    Arguments:
        x: Any object.

    Returns:
        str: The class name of the objects type.
    """
    return str(type(x)).split("'")[1]


def pop(k, default=None):
    """ Pop the key k from the dictionary and return its value.  If k
        doesn't exist, and default is provided, return the default.  If k
        doesn't exist and default is not provided, raise a KeyError."""


def goToStep(stepName):
    """Redirect to step by name."""


def max_duration(df, max_seconds=5.0):
    """Maximum duration

    Helper predicate for sample validation

    Parameters
    ----------
    df : pandas.DataFrame
        DataFrame containing the measurements for this window
    max_seconds : float
        The maximal time difference for the measurements

    Returns
    -------
    bool
        True if the duration of `df` is less than `max_seconds`
    """
    duration = df.index.max().to_pydatetime() - df.index.min().to_pydatetime()
    return duration.total_seconds() < max_seconds


def verify():
    """
        Verify if the request contains a valid authenticator.
        """


@classmethod
def from_file_system(cls, *paths, **config):
    """Create a :class:`TestSuite` object based on the given ``paths``.

        ``paths`` are file or directory paths where to read the data from.

        Internally utilizes the :class:`~.builders.TestSuiteBuilder` class
        and ``config`` can be used to configure how it is initialized.

        New in Robot Framework 3.2.
        """
    from .builder import TestSuiteBuilder
    return TestSuiteBuilder(**config).build(*paths)


def _spot_worker(device: dict):
    """
    Worker to grab spotter data

    :param device: Dictionary containing the spotter id and name

    :return: Spotter object updated from the Sofar api with its latest data values
    """
    from pysofar.spotter import Spotter
    _id = device['spotterId']
    _name = device['name']
    sptr = Spotter(_id, _name)
    sptr.update()
    return sptr


def check(value, condition, string=''):
    """
    Verify that the condition is true and return the value.

    Useful for conditional assignments, eg:
        xs = [x]*n_elements if not isinstance(x, (list, tuple)) else check(x, len(x)==n_elements)

    :param value:
    :param condition:
    :param string:
    :return:
    """
    assert condition, string
    return value


def get(section, key):
    """
        Return a configuration value based on [section][key].  The return
        value type is unknown.

        :param section: The [section] of the configuration to pull key value
            from.
        :param key: The configuration key to get the value from.
        :returns: The value of the `key` in `section`.
        :rtype: ``Unknown``

        """


def user_can_edit_setting_type(user, content_type):
    """ true if user has any permission related to this content type """
    if user.is_active and user.is_superuser:
        return True
    permission_codenames = content_type.permission_set.values_list('codename',
        flat=True)
    for codename in permission_codenames:
        permission_name = '%s.%s' % (content_type.app_label, codename)
        if user.has_perm(permission_name):
            return True
    return False


def skin_armature_create(modifier: str=''):
    """Create an armature that parallels the skin layout

    :param modifier: Modifier, Name of the modifier to edit
    :type modifier: str
    """
    pass


@classmethod
def identify(cls, delay=2000):
    """Shows identifiers in all Viewports::

            Viewport.identify()

        :param delay: Length of time in ms to leave up identifier
        """
    cls.highlight()


@staticmethod
def set_level(level):
    """Set a logging level"""
    pass


@classmethod
def __ensureCursorBeforeAnchor(cls, cursor):
    """
        Given a cursor, modify it such that the cursor.position() is before or
        at cursor.anchor() and not the other way around.

        Returns: anchorBeforeCursor, i.e. whether originally the anchor was
        before the cursor
        """
    start = cursor.selectionStart()
    end = cursor.selectionEnd()
    anchorBeforeCursor = cursor.anchor() < cursor.position()
    cls.__setCursorPositionAndAnchor(cursor, start, end)
    return anchorBeforeCursor


@classmethod
def _form_media_range(cls, type_subtype, media_type_params):
    """
        Combine `type_subtype` and `media_type_params` to form a media range.

        `type_subtype` is a ``str``, and `media_type_params` is an iterable of
        (parameter name, parameter value) tuples.
        """
    media_type_params_segment = ''
    for param_name, param_value in media_type_params:
        param_value = cls._escape_and_quote_parameter_value(param_value=
            param_value)
        media_type_params_segment += ';' + param_name + '=' + param_value
    return type_subtype + media_type_params_segment


def multiWfs(scrns, wfsObj, dmShape, read, queue):
    """
    Function to run the WFS in multiprocessing mode.

    Function is called by each of the new WFS processes spawned to run each WFS. Does the same job as the sim runWfs_noMP method of running LGS, then getting slopes from each WFS.

    Args:
        scrns (list): list of the phase screens over the WFS
        wfsObj (WFS object): the WFS object being run
        dmShape (ndArray):  shape of system DMs for WFS phase correction
        queue (Queue object): a multiprocessing Queue object used to pass data back to host process.
    """
    slopes = wfsObj.frame(scrns, dmShape, read=read)
    if wfsObj.LGS:
        lgsPsf = wfsObj.LGS.psf1
    else:
        lgsPsf = None
    res = [slopes, wfsObj.wfsDetectorPlane, wfsObj.uncorrectedPhase, lgsPsf]
    queue.put(res)


def scroll_right(deltax: int=0, deltay: int=0):
    """Scroll the view right

    :param deltax: Delta X
    :type deltax: int
    :param deltay: Delta Y
    :type deltay: int
    """
    pass


@classmethod
def get_all_consumers_info(cls, curs):
    """Get info about all consumers on all queues."""
    curs.execute('SELECT * FROM pgq.get_consumer_info();')
    return curs.fetchall()


@classmethod
def check_if_validation_class_exist(cls):
    """
            Check if validation class not empty for prevent runtime error
        """
    class_dict = cls.__dict__
    if not class_dict.get(cls.default_validation_class_attrib, None):
        raise AttributeError(
            f'Validation class not defined, please set validation_class attribute'
            )
    return True


@classmethod
def __set_message(cls, message: str, additional: str=''):
    """Sets the message for the response and format for additional message."""
    if additional:
        message += ' <|> Additional info: ' + additional
    cls.__response.fields['message'] = message


def abundance(isotope):
    """
    Natural abundance.

    :Parameters:
        *isotope* : Isotope

    :Returns:
        *abundance* : float | %

    Reference:
        *Coursey. J. S., Schwab. D. J, and Dragoset. R. A., NIST Atomic
        Weights and Isotopic Composition Database.*
    """
    return isotope._abundance


def get_app_name(app_module):
    """
    app is the object (python module) returned by get_apps method
    """
    return app_module.__name__.split('.')[0]


def merge(lists, optimize_for_speed=True):
    """ merge lists into one, while removing duplicates but keeping element order.
		`optimize_for_speed` is True has better runtime complexity
		`optimize_for_speed` is False uses less memory
	"""
    merged = []
    if optimize_for_speed:
        uniques = set()
        for list in lists:
            for element in list:
                if element not in uniques:
                    merged.append(element)
                    uniques.add(element)
    else:
        for list in lists:
            for element in list:
                if element not in merged:
                    merged.append(element)
    return merged


def delete_upload(arn=None):
    """
    Deletes an upload given the upload ARN.
    See also: AWS API Documentation

    Examples
    The following example deletes a specific upload.
    Expected Output:

    :example: response = client.delete_upload(
        arn='string'
    )

    :type arn: string
    :param arn: [REQUIRED]
            Represents the Amazon Resource Name (ARN) of the Device Farm upload you wish to delete.

    :rtype: dict
    :return: {}

    """
    pass


def shutdown():
    """Shutdown this application. Reverse of :meth:`startapp`."""


def __call__(interval_start, interval_end):
    """Iterable of recurrences of base datetime in the interval.

        interval_start, interval_end ... `datetime.date` objects

        """


def printLists(listToPrint: list, maxLineLength: int=100, sep: str='||'):
    """
    small function for printing list in a way that is a bit easier to read

    Paramaters:
    -----------
    listToPrint:list
        a list that we want to print
    maxLineLength:int (default 100)
    sep:str (default '||')

    Example:
    --------
    >>> tmpList = ['ab', 'cd', 'ef']
    ... || ab || cd || ef ||
    """
    startSep = sep + ' '
    varSep = ' ' + sep + ' '
    lineToPrint = startSep
    for var in listToPrint:
        if len(var) + len(lineToPrint) + len(varSep) <= maxLineLength:
            lineToPrint = lineToPrint + var + varSep
        else:
            print(lineToPrint)
            lineToPrint = startSep + var + varSep
    print(lineToPrint)


def P_from_head(head, rho, g=g):
    """Calculates head for a fluid of specified density at specified
    pressure.

    .. math::
        P = \\rho g \\cdot \\text{head}

    Parameters
    ----------
    head : float
        Head, [m]
    rho : float
        Density of fluid, [kg/m^3]
    g : float, optional
        Acceleration due to gravity, [m/s^2]

    Returns
    -------
    P : float
        Pressure fluid in pipe, [Pa]

    Notes
    -----

    Examples
    --------
    >>> P_from_head(head=5., rho=800.)
    39226.6
    """
    return head * rho * g


@classmethod
def get_ambient(cls):
    """Retrieve current ambient value"""
    temp = cls.get_store().get('ambient')
    return int(temp.decode()) if temp else 0


def clear():
    """
    @api {post} /music/playhistory/clear 清空历史记录
    @apiVersion 1.0.0
    @apiGroup Playhistory
    @apiDescription 清空历史记录

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

    @apiSuccessExample {json} Success-Response:
    {
        "data": "Success."
    }

    """


def provides_facts():
    """
    Returns a dictionary keyed on the facts provided by this module. The value
    of each key is the doc string describing the fact.
    """
    return {'ifd_style':
        "The type of physical interface (ifd) supported by the device. Choices are 'CLASSIC' or 'SWITCH'."
        }


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 p_DictionaryMembers(p):
    """DictionaryMembers : ExtendedAttributeList DictionaryMember DictionaryMembers"""
    p[2].extended_attributes = p[1]
    p[0] = [p[2]] + p[3]


def cmp(node, fulltext):
    """Compare fulltext to another revision.

        Returns True if the fulltext is different from what is stored.

        This takes copy metadata into account.

        TODO better document the copy metadata and censoring logic.
        """


def tagger_line_tokens(tokens):
    """Return the tagger name, email, time and timezone for a tagger line"""
    for index, token in enumerate(tokens[1:]):
        if '<' in token and '>' in token:
            e_ix = index + 1
            break
    return (' '.join(tokens[1:e_ix]),) + tuple(tokens[e_ix:])


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


@staticmethod
def filter_with_english_letters(buf):
    """
        Returns a copy of ``buf`` that retains only the sequences of English
        alphabet and high byte characters that are not between <> characters.
        Also retains English alphabet and high byte characters immediately
        before occurrences of >.

        This filter can be applied to all scripts which contain both English
        characters and extended ASCII characters, but is currently only used by
        ``Latin1Prober``.
        """
    filtered = bytearray()
    in_tag = False
    prev = 0
    for curr in range(len(buf)):
        buf_char = buf[curr:curr + 1]
        if buf_char == b'>':
            in_tag = False
        elif buf_char == b'<':
            in_tag = True
        if buf_char < b'\x80' and not buf_char.isalpha():
            if curr > prev and not in_tag:
                filtered.extend(buf[prev:curr])
                filtered.extend(b' ')
            prev = curr + 1
    if not in_tag:
        filtered.extend(buf[prev:])
    return filtered