def perms_canonical_labels_from(x, y, j0):
    """
    Return canonical labels for ``x``, ``y`` that starts at ``j0``.

    .. WARNING:

        The group generated by ``x`` and the elements of ``y`` should be
        transitive.

    INPUT:

    - ``x`` -- list - a permutation of `[0, ..., n]` as a list

    - ``y`` -- list of permutations of `[0, ..., n]` as a list of lists

    - ``j0`` -- an index in [0, ..., n]

    OUTPUT:

    mapping: a permutation that specify the new labels

    EXAMPLES::

        sage: from surface_dynamics.misc.constellation import perms_canonical_labels_from
        sage: perms_canonical_labels_from([0,1,2],[[1,2,0]],0)
        [0, 1, 2]
        sage: perms_canonical_labels_from([1,0,2],[[2,0,1]],0)
        [0, 1, 2]
        sage: perms_canonical_labels_from([1,0,2],[[2,0,1]],1)
        [1, 0, 2]
        sage: perms_canonical_labels_from([1,0,2],[[2,0,1]],2)
        [2, 1, 0]
    """
    n = len(x)
    k = 0
    mapping = [None] * n
    waiting = [[] for i in range(len(y))]
    while k < n:
        mapping[j0] = k
        waiting[0].append(j0)
        k += 1
        j = x[j0]
        while j != j0:
            mapping[j] = k
            waiting[0].append(j)
            k += 1
            j = x[j]
        l = 0
        while l < len(waiting):
            i = 0
            while i < len(waiting[l]):
                j1 = waiting[l][i]
                if mapping[y[l][j1]] is None:
                    break
                i += 1
            if i == len(waiting[l]):
                if l < len(waiting) - 1:
                    waiting[l + 1].extend(waiting[l])
                waiting[l] = []
                l += 1
                i = 0
            else:
                j0 = y[l][j1]
                if l < len(waiting) - 1:
                    waiting[l + 1].extend(waiting[l][:i + 1])
                del waiting[l][:i + 1]
                break
    return mapping


def quantized_concat(*data, **kwargs):
    """Joins input arrays along a given axis.

    The dimensions of the input arrays should be the same except the axis along
    which they will be concatenated.
    The dimension of the output array along the concatenated axis will be equal
    to the sum of the corresponding dimensions of the input arrays.
    All inputs with different min/max will be rescaled by using largest [min, max] pairs.
    If any input holds int8, then the output will be int8. Otherwise output will be uint8.

    Defined in src/operator/quantization/quantized_concat.cc:L108

    Parameters
    ----------
    data : NDArray[]
        List of arrays to concatenate
    dim : int, optional, default='1'
        the dimension to be concated.

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

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


def rating_widget(key='rating', maximum=10):
    """A customizable star rating widget"""
    widget = {'key': 'rating', 'type': 'template', 'template':
        '

{{model.{0}}} out of 10'
        .format(key, maximum)}
    return widget


def hide_fields_in_newer_versions(obj):
    """This method hides fields that were added in newer API versions.

    Certain node fields were introduced at certain API versions.
    These fields are only made available when the request's API version
    matches or exceeds the versions when these fields were introduced.
    """
    pass


def price_to_bookvalue(price, bookvalue_per_share):
    """Computes price to book value ratio.

    @params
    -------
    price: price per share
    bookvalue_per_share: book value per share, calculated by "total coomon stock value / tangible book value"

    returns
    -------
    Returns price to book value, int or float

    explanation
    -----------
    Market price of the company should follow the its tangible book value. Deviations from its tangible book
    makes the company overvalued and undervalued.
    """
    price_to_book = price / bookvalue_per_share
    return price_to_book


def df_corr_pearson(data, y, excluded_list=False):
    """One-by-One Correlation

    Based on the input data, returns a dictionary where each column
    is provided a correlation coefficient and number of unique values.
    Columns with non-numeric values will have None as their coefficient.

    data : dataframe
        A Pandas dataframe with the data
    y : str
        The prediction variable
    excluded_list : bool
        If True, then also a list will be returned with column labels for
        non-numeric columns.

    """
    out = {}
    category_columns = []
    for col in data.columns:
        try:
            out[col] = [data[y].corr(data[col]), len(data[col].unique())]
        except TypeError:
            out[col] = [None, len(data[col].unique())]
            category_columns.append(col)
    if excluded_list:
        return out, category_columns
    else:
        return out


def size(N):
    """size(N:long) : int
    Returns the size of the number N in bits.
    """
    bits = 0
    while N >> bits:
        bits += 1
    return bits


def advise_corrupt_share(reason=str):
    """Clients who discover hash failures in shares that they have
        downloaded from me will use this method to inform me about the
        failures. I will record their concern so that my operator can
        manually inspect the shares in question. I return None.

        This is a wrapper around RIStorageServer.advise_corrupt_share()
        that is tied to a specific share, and therefore does not need the
        extra share-identifying arguments. Please see that method for full
        documentation.
        """


def filter_proportion(iterable, proportion):
    """Generator that yields 0 < proportion <= 1 of the elements of an iterable."""
    if not 0 < proportion <= 1:
        raise ValueError('Filter proportion must be between 0 and 1')
    sourceiter, p = iter(iterable), 0
    while True:
        v = next(sourceiter)
        p += proportion
        if p >= 1:
            p -= 1
            yield v


def proper_motion(sources, settings):
    """
    Remove sources based on the proper motion range and signal-to-noise

    input
    ------
    sources - pandas dataframe, SCAMP full catalog
    settings - dictionary, settings parameter:value pairs

    return
    ------
    sources - pandas dataframe, sources data without the sources filtered in this step
    """
    pm_low = settings['PM_LOW']
    pm_up = settings['PM_UP']
    SN = settings['PM_SNR']
    sources = sources[(sources.PM >= pm_low) & (sources.PM <= pm_up)]
    sources = sources[sources.PM / sources.PMERR >= SN]
    return sources


def chars_to_ranges(s):
    """
    Return a list of character codes consisting of pairs
    [code1a, code1b, code2a, code2b,...] which cover all
    the characters in |s|.
    """
    char_list = list(s)
    char_list.sort()
    i = 0
    n = len(char_list)
    result = []
    while i < n:
        code1 = ord(char_list[i])
        code2 = code1 + 1
        i += 1
        while i < n and code2 >= ord(char_list[i]):
            code2 += 1
            i += 1
        result.append(code1)
        result.append(code2)
    return result


def getitem(x, key):
    """Like :func:`operator.getitem`, but allows setting key using partial
    ``partial(chunk.getitem, key=key)
    """
    return x[key]


def simple_fargs_out(_in, obtained):
    """
    Simple function who can be used in callback on coromask, the
    inputs are /_in/ and /obtained/ value from the coroutine executed.
    Return obtained

    :param _in: the input list
    :param obtained: the object that came from the result of coroutine execution

    :returns: obtained
    """
    return obtained


def is_string(x):
    """Tests if something is a string"""
    return isinstance(x, str)


@classmethod
def _get_dmi(cls, df):
    """ get the default setting for DMI

        including:
        +DI: 14 days SMMA of +DM,
        -DI: 14 days SMMA of -DM,
        DX: based on +DI and -DI
        ADX: 6 days SMMA of DX
        :param df: data
        :return:
        """
    df['pdi'] = cls._get_pdi(df, cls.PDI_SMMA)
    df['mdi'] = cls._get_mdi(df, cls.MDI_SMMA)
    df['dx'] = cls._get_dx(df, cls.DX_SMMA)
    df['adx'] = df['dx_{}_ema'.format(cls.ADX_EMA)]
    df['adxr'] = df['adx_{}_ema'.format(cls.ADXR_EMA)]


def deleteDefaultContent(portal):
    """ Delete default (placeholder) content created by Plone"""
    contentIds = ['news', 'front-page', 'Members', 'events']
    contentIds = [id for id in contentIds if id in portal.objectIds()]
    portal.manage_delObjects(contentIds)


def setmode(value):
    """exists for rpio compatibility"""
    pass


def datetime_to_ISO_string(aDate):
    """ Take a datetime and convert to string of the form YYYY-MM-DDTHH:MM:SS.S
    """
    return aDate.isoformat()


def vertex_group_add():
    """Add a new vertex group to the active object

    """
    pass


def perm_get_ssh_challenge_token(issuer, kwargs):
    """
    Checks if an account can request a challenge token.

    :param issuer: Account identifier which issues the command.
    :param kwargs: List of arguments for the action.
    :returns: True if account is allowed to call the API call, otherwise False
    """
    return True


def _write_edge_symbol(molecule, n_idx, n_jdx):
    """
    Determines whether a symbol should be written for the edge between `n_idx`
    and `n_jdx` in `molecule`. It should not be written if it's a bond of order
    1 or an aromatic bond between two aromatic atoms; unless it's a single bond
    between two aromatic atoms.

    Parameters
    ----------
    molecule : nx.Graph
        The molecule.
    n_idx : Hashable
        The first node key describing the edge.
    n_jdx : Hashable
        The second node key describing the edge.

    Returns
    -------
    bool
        Whether an explicit symbol is needed for this edge.
    """
    order = molecule.edges[n_idx, n_jdx].get('order', 1)
    aromatic_atoms = molecule.nodes[n_idx].get('element', '*').islower(
        ) and molecule.nodes[n_jdx].get('element', '*').islower()
    aromatic_bond = aromatic_atoms and order == 1.5
    cross_aromatic = aromatic_atoms and order == 1
    single_bond = order == 1
    return cross_aromatic or not (aromatic_bond or single_bond)


def decode_ascii(string):
    """Decodes a string as ascii."""
    return string.decode('ascii')


def can_paginate(operation_name=None):
    """
    Check if an operation can be paginated.

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

    """
    pass


@classmethod
def encode_int(cls, obj):
    """Verify the object is an int, and ASCII-encode it.

        :param int obj: An integer to be encoded.
        :raises: :class:`TypeError` if `obj` is not an integer.
        :return: A binary representation of the int `obj` suitable to pass as the `payload` to
                 send_exit().
        """
    if not isinstance(obj, int):
        raise TypeError(
            "cannot encode non-integer object in encode_int(): object was {} (type '{}')."
            .format(obj, type(obj)))
    return str(obj).encode('ascii')


def insert_qimage_format(cursor, format):
    """
    Insert a QImage given by a format at a cursor.
    :param cursor: QTextCursor where to insert.
    :param format: QImageFormat of the image.
    :return:
    """
    cursor.insertBlock()
    cursor.insertImage(format)
    cursor.insertBlock()


def atom_degree(atom):
    """Get the degree of an atom.

    Note that the result will be different depending on whether the Hs are
    explicitly modeled in the graph.

    Parameters
    ----------
    atom : rdkit.Chem.rdchem.Atom
        RDKit atom instance.

    Returns
    -------
    list
        List containing one int only.

    See Also
    --------
    atom_total_degree
    """
    return [atom.GetDegree()]


@classmethod
def parse_file_path(cls, file_path):
    """Parse a file address path without the file specifier."""
    address = None
    pattern = cls.file_regex.match(file_path)
    if pattern:
        address = pattern.group(1)
    return address


@staticmethod
def combinations(row, col):
    """ Returns iterable with tuples of all indices of a NxM matrix """
    for i in range(0, row):
        for j in range(0, col):
            yield i, j


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 compute_equal_space(available_size, all_elements_size, offset=0):
    """
        Function to return an equal space between elements
    """
    available_size -= offset
    total_content_size = sum(all_elements_size)
    dspace = (available_size - total_content_size) / float(len(
        all_elements_size) + 1)
    return dspace


def makeNodeID(Rec, ndType, extras=None):
    """Helper to make a node ID, extras is currently not used"""
    if ndType == 'raw':
        recID = Rec
    else:
        recID = Rec.get(ndType)
    if recID is None:
        pass
    elif isinstance(recID, list):
        recID = tuple(recID)
    else:
        recID = recID
    extraDict = {}
    if extras:
        for tag in extras:
            if tag == 'raw':
                extraDict['Tag'] = Rec
            else:
                extraDict['Tag'] = Rec.get(tag)
    return recID, extraDict


def AutoFields(context):
    """Return a list of fields for context autogenerated by grok.
        """


def in_memory(iterator):
    """
    Pull an entire iterator into memory and then re-expose as an iterator.
    """
    return iter(list(iterator))


@classmethod
def normalize_email(cls, email):
    """
        Normalize the address by lowercasing the domain part of the email
        address.
        """
    email = email or ''
    try:
        email_name, domain_part = email.strip().rsplit('@', 1)
    except ValueError:
        pass
    else:
        email = '@'.join([email_name, domain_part.lower()])
    return email


def __call__(event):
    """
        Process the event.
        """


def get_execute_options(defaults=None):
    """Execute-related options

    """
    if defaults is None:
        defaults = {}
    options = {'--script': {'action': 'store', 'dest': 'script', 'default':
        defaults.get('script', None), 'help': 'BigML script Id.'},
        '--script-file': {'action': 'store', 'dest': 'script_file',
        'default': defaults.get('script_file', None), 'help':
        'BigML script JSON structure file.'}, '--scripts': {'action':
        'store', 'dest': 'scripts', 'default': defaults.get('scripts', None
        ), 'help':
        'Path to a file containing script/ids. Just one script per line (e.g., script/50a20697035d0706da0004a4).'
        }, '--library': {'action': 'store', 'dest': 'library', 'default':
        defaults.get('library', None), 'help': 'BigML library Id.'},
        '--library-file': {'action': 'store', 'dest': 'library_file',
        'default': defaults.get('library_file', None), 'help':
        'BigML library JSON structure file.'}, '--libraries': {'action':
        'store', 'dest': 'libraries', 'default': defaults.get('libraries',
        None), 'help':
        'Path to a file containing libraries/ids. Just one library per line (e.g., library/50a20697035d0706da0004a4).'
        }, '--execution': {'action': 'store', 'dest': 'execution',
        'default': defaults.get('execution', None), 'help':
        'BigML execution Id.'}, '--execution-file': {'action': 'store',
        'dest': 'execution_file', 'default': defaults.get('execution_file',
        None), 'help': 'BigML execution JSON structure file.'},
        '--executions': {'action': 'store', 'dest': 'executions', 'default':
        defaults.get('executions', None), 'help':
        'Path to a file containing execution/ids. Just one execution per line (e.g., execution/50a20697035d0706da0004a4).'
        }, '--code-file': {'action': 'store', 'dest': 'code_file',
        'default': defaults.get('code_file', None), 'help':
        'Path to the file that contains Whizzml source code.'}, '--code': {
        'action': 'store', 'dest': 'code', 'default': defaults.get('code',
        None), 'help': 'String of Whizzml source code.'}, '--output': {
        'action': 'store', 'dest': 'output', 'default': defaults.get(
        'output', None), 'help':
        'Path to the file to output the execution results.'}, '--imports':
        {'action': 'store', 'dest': 'imports', 'default': defaults.get(
        'imports', None), 'help':
        'Comma-separated list of libraries IDs to be included as imports in scripts or other libraries.'
        }, '--embedded-imports': {'action': 'store', 'dest':
        'embedded_imports', 'default': defaults.get('embedded_imports',
        None), 'help':
        'File that contains the paths to the import code files, one per line.'
        }, '--inputs': {'action': 'store', 'dest': 'inputs', 'default':
        defaults.get('inputs', None), 'help':
        'Path to the JSON file with the description of the execution inputs'
        }, '--input-maps': {'action': 'store', 'dest': 'input_maps',
        'default': defaults.get('input_maps', None), 'help':
        'Path to the JSON file with the description of the execution inputs for a list of scripts'
        }, '--declare-inputs': {'action': 'store', 'dest': 'declare_inputs',
        'default': defaults.get('declare_inputs', None), 'help':
        'Path to the JSON file with the description of the input parameters'
        }, '--outputs': {'action': 'store', 'dest': 'outputs', 'default':
        defaults.get('outputs', None), 'help':
        'Path to the JSON file with the names of the output parameters'},
        '--declare-outputs': {'action': 'store', 'dest': 'declare_outputs',
        'default': defaults.get('declare_outputs', None), 'help':
        'Path to the JSON file with the description of the script outputs'},
        '--creation-defaults': {'action': 'store', 'dest':
        'creation_defaults', 'default': defaults.get('creation_defaults',
        None), 'help':
        'Path to the JSON file with the default configurations for created resources.'
        }, '--no-execute': {'action': 'store_true', 'dest': 'no_execute',
        'default': defaults.get('no_execute', False), 'help':
        "Don't execute the script. Compile only.'"}, '--execute': {'action':
        'store_false', 'dest': 'no_execute', 'default': defaults.get(
        'no_execute', False), 'help':
        'Execute the script. (Opposed to --no-execute).'}, '--to-library':
        {'action': 'store_true', 'dest': 'to_library', 'default': defaults.
        get('to_library', False), 'help': 'Compile the code as a library.'}}
    return options


def __exit__(exc_type, exc_val, exc_tb):
    """Support for the context manager protocol.

        Close the file and allow exceptions to propogate.
        """


def read(cls, path: str, **kwargs):
    """
        Read the contents of a file from it's destination
        """
    raise NotImplementedError('override in subclass')


def p_with_stmt_star_2(p):
    """with_stmt_star : with_stmt_star COMMA with_item"""
    last = p[1]
    while len(last.body) > 0:
        last = last.body[0]
    last.body.append(p[3])
    p[0] = p[1]


def read_output(filename):
    """Reads in a Tarquin txt results file and returns a dict of the information

    Parameters
    ----------
    filename : txt file
        The filename to read from

    Returns
    -------
    result : dict

    """
    with open(filename) as fin:
        data = fin.read()
        metabolite_fits = {}
        fit_quality = {}
        sections = data.split('\n\n')
        metabolite_lines = sections[0].splitlines()[2:]
        for line in metabolite_lines:
            name, concentration, pc_sd, sd = line.split()
            metabolite_fits[name] = {'concentration': concentration, 'sd':
                pc_sd}
        lines = sections[1].splitlines()[2:]
        for line in lines:
            key, value = line.split(':')
            fit_quality[key.strip()] = float(value.strip())
        return {'metabolite_fits': metabolite_fits, 'quality': fit_quality}


def get_inheritors(cls):
    """
    Get a set of all classes that inherit from the given class.
    """
    subclasses = set()
    work = [cls]
    while work:
        parent = work.pop()
        for child in parent.__subclasses__():
            if child not in subclasses:
                subclasses.add(child)
                work.append(child)
    return subclasses


@classmethod
def get_version(cls):
    """Get the current version as a tuple."""
    return cls.get(part='major').value, cls.get(part='minor').value


def retrieve(obj=None, history_id=None, selector=None, preserve=()):
    """Retrieves a former state of an object.

        Requires either an object which is the working copy, or a history_id
        for an object if no history_id is provided the history_id will be
        obtained from the working copy object.

        Returns an 'IVersionData' object.

        Set the selector to None if you like to retrieve the most actual
        version.

        Modifiers may overwrite some aspects of the retrieved version by
        the equivalent aspects of the working copy. Sometimes the
        overwritten information is from interest. Attributes (and
        subattributes) beeing from interest can be passed with the
        'preserve' argument.
        E.g. preserve=('family_name', 'nick_name', 'real_name')
        """


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

    The ".dev0" means dirty.

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


def getWorkername():
    """Return the name of the worker which handled this build."""


def get_tree_url(ref, repository_url=None):
    """ Get a link for a ref (commit, branch or tag) for the repository. """
    return '{repository_url}/tree/{ref}'.format(repository_url=
        repository_url, ref=ref) if repository_url else None


def resolve_import_alias(name, import_names):
    """Resolve a name from an aliased import to its original name.

    :param name: The potentially aliased name to resolve.
    :type name: str
    :param import_names: The pairs of original names and aliases
        from the import.
    :type import_names: iterable(tuple(str, str or None))

    :returns: The original name.
    :rtype: str
    """
    resolved_name = name
    for import_name, imported_as in import_names:
        if import_name == name:
            break
        if imported_as == name:
            resolved_name = import_name
            break
    return resolved_name


def p_expression_discard_expression_expression(p):
    """expression : DISCARD_TAG expression expression"""
    p[0] = p[3]


def getWingDebuggerVersion():
    """Return a string containing the debugger version (possibly including
           SVN information)"""


def unsigned_int_8(value: str) ->int:
    """
    Parse value as an integer and verify that it is an unsigned 8-bit value.

    :param value: The number as a string
    :return: The corresponding integer
    """
    value = int(value)
    if not 0 <= value < 2 ** 8:
        raise ValueError(
            'The specified value must be an unsigned 8-bit integer')
    return value


def join_names(names):
    """
    Returns a well formated list of names, ready for printing.

    Examples:
      - Trevor Reznik
      - Teddy and Leonard
      - Rita, Astor, Cody and Dexter
    """
    if 1 < len(names):
        return ', '.join(sorted(names[:-1])) + ' and ' + names[-1]
    elif len(names) == 0:
        return '[deleted]'
    return names[0]


@classmethod
def _get_toolkit_to_apic_classmap(cls):
    """
        Gets the APIC class to an acitoolkit class mapping dictionary
        :returns: dict of APIC class names to acitoolkit classes
        """
    return {}


def add_keys(apps, schema_editor):
    """
    We can't import the Post model directly as it may be a newer
    version than this migration expects. We use the historical version.
    """
    Setting = apps.get_model('settings', 'Setting')
    key = ''
    try:
        key = 'APPROVE_REVIEW'
        Setting.objects.get(key=key)
    except Exception:
        Setting.objects.create(title='منتشر شدن پیام ها به صورت پیش فرض',
            key=key, value='False', value_type='b', is_show=False,
            is_variable_in_home=False)
    try:
        key = 'USER_DEFAULT_LIMIT_DEVICE_LOGIN'
        Setting.objects.get(key=key)
    except Exception:
        Setting.objects.create(title='تعداد گوشی های مجاز هر کاربر', key=
            key, value='1', value_type='i', is_show=False,
            is_variable_in_home=False)
    try:
        key = 'USER_IS_LIMIT_DEVICE_LOGIN_ACTIVE'
        Setting.objects.get(key=key)
    except Exception:
        Setting.objects.create(title='فعال بودن محدودیت دستگاه', key=key,
            value='False', value_type='b', is_show=False,
            is_variable_in_home=False)
    try:
        key = 'MAX_PRODUCT_SHARING_USER_ALLOWED_PER_PRODUCT'
        Setting.objects.get(key=key)
    except Exception:
        Setting.objects.create(title=
            'تعداد دسترسی های داده شده توسط این کاربر برای یک کالای خاص',
            key=key, value='1', value_type='i', is_show=False,
            is_variable_in_home=False)
    try:
        key = 'MAX_PRODUCT_SHARING_USER_ALLOWED_FOR_ALL_PRODUCTS'
        Setting.objects.get(key=key)
    except Exception:
        Setting.objects.create(title=
            'تعداد دسترسی های داده شده توسط این کاربر برای همه کالاها', key
            =key, value='10', value_type='i', is_show=False,
            is_variable_in_home=False)


def check_notwanted(zelf, *args, **kwargs):
    """ whether an thing is not desired. """
    not_want = args[0]
    for key, value in not_want.items():
        if key == 'format':
            continue
        if key not in zelf:
            continue
        if value in zelf[key]:
            return True
    return False


def getFlatNodes():
    """Return a flat list of nodes in the tree. Children of
        expanded nodes are shown.
        """


def unindex_doc(docid):
    """Remove a document from the index.

        docid: int, identifying the document

        return: None

        This call is a no-op if the docid isn't in the index, however,
        after this call, the index should have no references to the docid.
        """


def b2h(num, suffix='B'):
    """Format file sizes as human readable.

    https://stackoverflow.com/a/1094933

    Parameters
    ----------
    num : int
        The number of bytes.
    suffix : str, optional
        (default: 'B')

    Returns
    -------
    str
        The human readable file size string.

    Examples
    --------
    >>> b2h(2048)
    '2.0kB'
    """
    try:
        for unit in ['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z']:
            if abs(num) < 1024.0:
                return '{0:3.1f}{1}{2}'.format(num, unit, suffix)
            num /= 1024.0
        return '{0:.1f}{1}{2}'.format(num, 'Y', suffix)
    except:
        return '-'


def evict(key):
    """Evict the file pointed to by key.

        :param key: The key identifying the contents you want to evict.
        :type key: str
        """


def randomfasta_parser(subparsers):
    """
    Parser for the randomfasta tool.
    """
    parser = subparsers.add_parser('randomfasta', help=
        'create a random FASTA file', description=
        'Create a FASTA file with random nucleotide sequences.')
    parser.add_argument('seq_length', type=int, help='random sequence length')
    parser.add_argument('seq_num', type=int, help='random sequence number')
    parser.add_argument('output', help='output filename')


def update_time_range(form_data):
    """Move since and until to time_range."""
    if 'since' in form_data or 'until' in form_data:
        form_data['time_range'] = '{} : {}'.format(form_data.pop('since',
            '') or '', form_data.pop('until', '') or '')


def exercise_image_upload_dir(instance, filename):
    """
    Returns the upload target for exercise images
    """
    return 'exercise-images/{0}/{1}'.format(instance.exercise.id, filename)


def describe_cluster_subnet_groups(ClusterSubnetGroupName=None, MaxRecords=
    None, Marker=None, TagKeys=None, TagValues=None):
    """
    Returns one or more cluster subnet group objects, which contain metadata about your cluster subnet groups. By default, this operation returns information about all cluster subnet groups that are defined in you AWS account.
    If you specify both tag keys and tag values in the same request, Amazon Redshift returns all subnet groups that match any combination of the specified keys and values. For example, if you have owner and environment for tag keys, and admin and test for tag values, all subnet groups that have any combination of those values are returned.
    If both tag keys and values are omitted from the request, subnet groups are returned regardless of whether they have tag keys or values associated with them.
    See also: AWS API Documentation

    :example: response = client.describe_cluster_subnet_groups(
        ClusterSubnetGroupName='string',
        MaxRecords=123,
        Marker='string',
        TagKeys=[
            'string',
        ],
        TagValues=[
            'string',
        ]
    )

    :type ClusterSubnetGroupName: string
    :param ClusterSubnetGroupName: The name of the cluster subnet group for which information is requested.

    :type MaxRecords: integer
    :param MaxRecords: The maximum number of response records to return in each call. If the number of remaining response records exceeds the specified MaxRecords value, a value is returned in a marker field of the response. You can retrieve the next set of records by retrying the command with the returned marker value.
            Default: 100
            Constraints: minimum 20, maximum 100.

    :type Marker: string
    :param Marker: An optional parameter that specifies the starting point to return a set of response records. When the results of a DescribeClusterSubnetGroups request exceed the value specified in MaxRecords , AWS returns a value in the Marker field of the response. You can retrieve the next set of response records by providing the returned marker value in the Marker parameter and retrying the request.

    :type TagKeys: list
    :param TagKeys: A tag key or keys for which you want to return all matching cluster subnet groups that are associated with the specified key or keys. For example, suppose that you have subnet groups that are tagged with keys called owner and environment . If you specify both of these tag keys in the request, Amazon Redshift returns a response with the subnet groups that have either or both of these tag keys associated with them.
            (string) --

    :type TagValues: list
    :param TagValues: A tag value or values for which you want to return all matching cluster subnet groups that are associated with the specified tag value or values. For example, suppose that you have subnet groups that are tagged with values called admin and test . If you specify both of these tag values in the request, Amazon Redshift returns a response with the subnet groups that have either or both of these tag values associated with them.
            (string) --

    :rtype: dict
    :return: {
        'Marker': 'string',
        'ClusterSubnetGroups': [
            {
                'ClusterSubnetGroupName': 'string',
                'Description': 'string',
                'VpcId': 'string',
                'SubnetGroupStatus': 'string',
                'Subnets': [
                    {
                        'SubnetIdentifier': 'string',
                        'SubnetAvailabilityZone': {
                            'Name': 'string'
                        },
                        'SubnetStatus': 'string'
                    },
                ],
                'Tags': [
                    {
                        'Key': 'string',
                        'Value': 'string'
                    },
                ]
            },
        ]
    }

    """
    pass


def _is_empty(response):
    """Check if response body contains meaningful content.

    :rtype: bool
    """
    return not bool(response.body())


def renew_cache(df):
    """Cache a Spark DF, unpersisting first if it is already cached.

    This helps avoid problems when rerunning code that caches a DF.

    Parameters
    ----------
    df : DataFrame
        A Spark DataFrame to be cached.

    Returns
    -------
    DataFrame
        The cached DataFrame.
    """
    if df.is_cached:
        df = df.unpersist()
    return df.cache()


def write(fn, s, overwrite=True):
    """General write function for surfaces

    Parameters
    ----------
    fn: str
        Surface filename. The extension determines how the file is written as
        follows. '.asc', FreeSurfer ASCII format; '.gii', GIFTI.
        Other formats are not supported.
    """
    if fn.endswith('.asc'):
        from mvpa2.support.nibabel import surf_fs_asc
        surf_fs_asc.write(fn, s, overwrite=overwrite)
    elif fn.endswith('.gii'):
        if not fn.endswith('.surf.gii'):
            raise ValueError('GIFTI output requires extension .surf.gii')
        from mvpa2.support.nibabel import surf_gifti
        surf_gifti.write(fn, s, overwrite=overwrite)
    else:
        raise ValueError('Not implemented (based on extension): %r' % fn)


def check_buffer(coords, length, buffer):
    """
    check to see how much of the buffer is being used
    """
    s = min(coords[0], buffer)
    e = min(length - coords[1], buffer)
    return [s, e]


def reduce_bottom_rows(m, qubits):
    """Using just row_add's from the first qubit rows in m, tries to find a row that can be
    completely zero'd out. Returns the rownumber of this row when successful."""
    cols = m.cols()
    leading_one = {}
    adds = []
    for r in range(qubits):
        while True:
            i = next(i for i in range(cols) if m.data[r][i])
            if i in leading_one:
                m.row_add(leading_one[i], r)
                adds.append((leading_one[i], r))
            else:
                leading_one[i] = r
                break
    for r in range(qubits, m.rows()):
        while True:
            if not any(m.data[r]):
                return r
            i = next(i for i in range(cols) if m.data[r][i])
            if i not in leading_one:
                break
            m.row_add(leading_one[i], r)
            adds.append((leading_one[i], r))
    raise ValueError('Did not find any completely reducable row')


def p_named_col(p):
    """col : col AS col_name"""
    col = p[1]
    col.named_as = p[3]
    p[0] = col


@classmethod
def addState(cls, state):
    """ Adds a state to the FSA
        This method should be preferred instead of the "setState" method
        """
    currentState = cls.getState()
    if state > cls.S_IDLE:
        currentState &= ~cls.S_IDLE
    cls.setState(currentState | state)


def combine_extractor_and_dimension_name(extractor, dim):
    """Joins the duckling extractor name with a dimension's name."""
    return '{} ({})'.format(extractor, dim)


def render_pep440_bare(pieces):
    """TAG[.DISTANCE[.dev0]] .

    The ".dev0" means dirty.

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


def get_push_src(repo, ref, tag):
    """
    Determine wether we can push the ref

    If the ref is further ahead than the tag
    we only want to push up to this tag.
    """
    commit = repo.rev_parse('%s^{commit}' % tag)
    if repo.rev_parse(ref) == commit:
        return ref
    else:
        return commit


def faces_select_linked_flat(sharpness: float=0.0174533):
    """Select linked faces by angle

    :param sharpness: Sharpness
    :type sharpness: float
    """
    pass


def get_duplicated_elements(elements_list):
    """
        Given an `elements_list` with duplicated elements, return a set only with the duplicated
        elements in the list. If there are not duplicated elements, an empty set is returned.

        How do I find the duplicates in a list and create another list with them?
        https://stackoverflow.com/questions/9835762/how-do-i-find-the-duplicates-in-a-list-and-create-another-list-with-them
    """
    visited_elements = set()
    visited_and_duplicated = set()
    add_item_to_visited_elements = visited_elements.add
    add_item_to_visited_and_duplicated = visited_and_duplicated.add
    for item in elements_list:
        if item in visited_elements:
            add_item_to_visited_and_duplicated(item)
        else:
            add_item_to_visited_elements(item)
    return visited_and_duplicated


def get_mime_type():
    """Get data mime-type.
        """


def process_vrml(vrml_filename, fmt2, fname2, log, data, quiet=False):
    """
    Converts VRML to Nastran
    """
    assert fmt2 in ['nastran', 'stl'], 'format2=%s' % fmt2
    from pyNastran.converters.dev.vrml.vrml import vrml_to_nastran, vrml_to_stl
    if fmt2 == 'nastran':
        vrml_to_nastran(vrml_filename, fname2, log=log)
    if fmt2 == 'stl':
        vrml_to_stl(vrml_filename, fname2, log=log)
    else:
        raise NotImplementedError(
            'fmt2=%s is not supported by process_vrml' % fmt2)


def _metric(method, aggregator, sort):
    """Return 3-element list defining a metric, an aggregator and a sort order.

    .. note::

        This is a private function called by :func:`_add_default_metrics`.

    :param method:     image comparison metric (see :ref:`exquires-compare`)
    :param aggregator: data aggregator (see :ref:`exquires-aggregate`)
    :param sort:       best-to-worst order (`0`: ascending, `1`: descending)
    :type method:      `string`
    :type aggregator:  `string`
    :type sort:        `integer`

    :return:           metric, aggregator, and sort order
    :rtype:            `list`

    """
    return [' '.join(['exquires-compare', method, '{0} {1}']), ' '.join([
        'exquires-aggregate', aggregator, '{0}']), sort]


@staticmethod
def _transform_droplist(data_drop):
    """
        Create the droplists for the table elements

        :return List of dictionaries with keys text and link
        """
    link_list = []
    if isinstance(data_drop, str):
        raise Exception('Links with only strings must not be in a list')
    if not isinstance(data_drop, list):
        data_drop = [data_drop]
    for i in range(len(data_drop)):
        link_list_element = []
        if not isinstance(data_drop[i], list):
            data_drop[i] = [data_drop[i]]
        for j in range(len(data_drop[i])):
            if 'text' not in data_drop[i][j]:
                raise Exception('Text missing in droplist link')
            elif 'link' not in data_drop[i][j]:
                raise Exception('Link missing in droplist link')
            text = data_drop[i][j]['text']
            link = data_drop[i][j]['link']
            link_list_element.append({'text': text, 'link': link})
        link_list.append(link_list_element)
    return link_list


def post_install(context):
    """Post install script"""
    if context.readDataFile('redturtlejquerybrowser_default.txt') is None:
        return


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

        :param DeviceApprovalsChangeMobilePolicyDetails val:
        :rtype: EventDetails
        """
    return cls('device_approvals_change_mobile_policy_details', val)


@staticmethod
def list_size(query_list):
    """
        Find size of a list object even if it is a one element non-list
        :param query_list: List to be sized

        """
    if isinstance(query_list, list):
        return len(query_list)
    else:
        return 1


def delete_node(node):
    """
        Cleans up a node.
    """
    node.getparent().remove(node)


@staticmethod
def _get_networks(args):
    """Get the IPNetwork objects to work on.

        This method is useful for subclasses to redefine, to specify a
        different way of getting the networks.

        """
    return args.networks


def process():
    """ process the contents of the queue, i.e. start indexing;
            returns the number of processed queue items """


@staticmethod
def forward(ctx, input, a, b):
    """
        In the forward pass we receive a Tensor containing the input and return
        a Tensor containing the output. ctx is a context object that can be used
        to stash information for backward computation. You can cache arbitrary
        objects for use in the backward pass using the ctx.save_for_backward method.
        """
    ctx.save_for_backward(input, a, b)
    S = a.shape[0]
    output = input.clamp(min=0)
    for s in range(S):
        t = -input + b[s]
        output += a[s] * t.clamp(min=0)
    return output


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

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


def _plot_overlap(ax, x_grid, y_min):
    """Plot the overlap region."""
    highlight_color = [0.95, 0.9, 0.4]
    line, = ax.plot(x_grid, y_min, color=highlight_color, lw=8, label='overlap'
        )
    line.zorder -= 1


def echo(*args):
    """Equivalent to print with no end and sep strings.

    Also flushes immediately.
    """
    print(*args, end='', sep='', flush=True)


def globally_can_edit(brains):
    """View edit column
        """


@staticmethod
def __determine_mask_mode(mask_string: str):
    """If the mask string starts with '0:' or '1:', or generally
        if it contains a non-0 or 1 symbol, assume it is RLE."""
    mode = 'bitmap'
    if len(mask_string) < 3:
        mode = 'bitmap'
    elif ':' in mask_string[:3]:
        mode = 'rle'
    return mode


def max_contrast(array):
    """Sets all positive values to one and all negative values to -1.

    Needed for first pass lookup on word table.

    Args:
        array (numpy.ndarray): target array
    """
    array[array > 0] = 1
    array[array < 0] = -1
    return None


def foreach(func, iterable):
    """
    Call function for each element of an iterable. Basically, it's a list
    comprehension without a return value.

    Arguments:
        func (function): Function to call.
        iterable (iterable): Sequence of items.
    """
    for item in iterable:
        func(item)


def provides(base):
    """Returns whether or not this extension can provide for the
        server."""
    version = base.basic_rfc.server_version[0]
    if version is None:
        return False
    elif version.startswith('ircd-seven'):
        return True
    return False


def compare_dicts(dict1, dict2):
    """
    Checks if dict1 equals dict2
    """
    for k, v in dict2.items():
        if v != dict1[k]:
            return False
    return True


@staticmethod
def import_container(name):
    """ Abstract method to import an external container, the specific
        implementation depends on the language used.

        :param str name: name of the external entity to be imported.

        :raises NotImplementedError: this is an abstract method.
        """
    raise NotImplementedError('Abstract method')


def provider_parser(subparser):
    """Specify arguments for Gandi Lexicon Provider."""
    subparser.add_argument('--auth-token', help='specify Gandi API key')
    subparser.add_argument('--api-protocol', help=
        '(optional) specify Gandi API protocol to use: rpc (default) or rest')


@classmethod
def indexOf(cls, data, pattern, index, count):
    """
        Finds the first occurrence of the pattern in the text.
        data : Data where to find.
        pattern : Search pattern.
        index : Byte index to start.
        count : Count of bytes to search.
        Return True if pattern is found.
        """
    failure = cls.__computeFailure(pattern)
    j = 0
    if not data or len(data) < index:
        return -1
    for i in range(index, count):
        while j > 0 and pattern[j] != data[i]:
            j = failure[j - 1]
        if pattern[j] == data[i]:
            j = j + 1
        if j == len(pattern):
            return i - len(pattern) + 1
    return -1


def merge_unique_indices(afi, afid, bfi, bfid):
    """Merge two pairs of (index ids, index dimensions) sequences into one pair without duplicates.

    The id tuples afi, bfi are assumed already sorted by id.
    Given a list of (id, dim) tuples already sorted by id,
    return a unique list with duplicates removed.
    Also checks that the dimensions of duplicates are matching.
    """
    na = len(afi)
    nb = len(bfi)
    if na == 0:
        return bfi, bfid
    elif nb == 0:
        return afi, afid
    ak = 0
    bk = 0
    fi = []
    fid = []
    while True:
        if afi[ak] < bfi[bk]:
            fi.append(afi[ak])
            fid.append(afid[ak])
            ak += 1
        elif afi[ak] > bfi[bk]:
            fi.append(bfi[bk])
            fid.append(bfid[bk])
            bk += 1
        else:
            fi.append(afi[ak])
            fid.append(afid[ak])
            ak += 1
            bk += 1
        if ak == na:
            if bk != nb:
                fi.extend(bfi[bk:])
                fid.extend(bfid[bk:])
            break
        elif bk == nb:
            fi.extend(afi[ak:])
            fid.extend(afid[ak:])
            break
    return tuple(fi), tuple(fid)


def html_encode(text):
    """
    Encode characters with a special meaning as HTML.

    :param text: The plain text (a string).
    :returns: The text converted to HTML (a string).
    """
    text = text.replace('&', '&')
    text = text.replace('<', '<')
    text = text.replace('>', '>')
    text = text.replace('"', '"')
    return text


def normalize_version(ver, length=4):
    """Takes version as a list and how long it should be.
      Appends 0's if it's not long enough."""
    if len(ver) > length:
        raise Exception('Version is longer than the longest length')
    return ver + [0] * (length - len(ver))


def reset():
    """Reset the cache object.

        Remove all objects from cache.
        """


@staticmethod
def _singleton(it):
    """Test whether iterable contains one unique element.

        :param it: iterable

        :returns: bool, iterable contains one unique element
        """
    return len(set(it)) == 1


def __call__(environ, status, headers):
    """ args -> True | False

        o 'environ' is the WSGI environment.

        o 'status' is the HTTP status as returned by the downstream
          WSGI application.

        o 'headers' are the headers returned by the downstream WSGI
          application.

        This interface is responsible for returning True if
        a challenge needs to be presented to the user, False otherwise.
        """


def add_spelling(ix, fieldnames, commit=True):
    """Adds spelling files to an existing index that was created without
    them, and modifies the schema so the given fields have the ``spelling``
    attribute. Only works on filedb indexes.
    >>> ix = index.open_dir("testindex")
    >>> add_spelling(ix, ["content", "tags"])
    :param ix: a :class:`whoosh.filedb.fileindex.FileIndex` object.
    :param fieldnames: a list of field names to create word graphs for.
    :param force: if True, overwrites existing word graph files. This is only
        useful for debugging.
    """
    from whoosh.automata import fst
    from cylleneus.engine.reading import SegmentReader
    writer = ix.writer()
    storage = writer.storage
    schema = writer.schema
    segments = writer.segments
    for segment in segments:
        ext = segment.codec().FST_EXT
        r = SegmentReader(storage, schema, segment)
        f = segment.create_file(storage, ext)
        gw = fst.GraphWriter(f)
        for fieldname in fieldnames:
            gw.start_field(fieldname)
            for word in r.lexicon(fieldname):
                gw.insert(word)
            gw.finish_field()
        gw.close()
    for fieldname in fieldnames:
        schema[fieldname].spelling = True
    if commit:
        writer.commit(merge=False)


def returnElemCallback(retelem):
    """Callback for when a sheet appears.

    Returns: element returned by observer callback
    """
    return retelem


def array_xy_offsets(test_geo, test_xy):
    """Return upper left array coordinates of test_xy in test_geo

    Parameters
    ----------
    test_geo (): GDAL Geotransform used to calcululate the offset
    test_xy (): x/y coordinates in the same projection as test_geo
        passed as a list or tuple

    Returns
    -------
    x_offset: x coordinate of the upper left of the array
    y_offset: y coordinate of the uppler left of the array

    """
    x_offset = int((test_xy[0] - test_geo[0]) / test_geo[1])
    y_offset = int((test_xy[1] - test_geo[3]) / test_geo[5])
    return x_offset, y_offset


def valid_config(config):
    """ validation config"""
    del config
    return True


@staticmethod
def _extract_macros_from_template(template, env):
    """Take a template string and extract any macros from it.

        Lovingly inspired by http://codyaray.com/2015/05/auto-load-jinja2-macros
        """
    from jinja2.runtime import Macro
    context = {}
    macro_template = env.from_string(template)
    for k in macro_template.module.__dict__:
        attr = getattr(macro_template.module, k)
        if isinstance(attr, Macro):
            context[k] = attr
    return context


def calculate_after_treatment_temperature_threshold(
    engine_normalization_temperature, initial_engine_temperature):
    """
    Calculates the engine coolant temperature when the after treatment system
    is warm [°C].

    :param engine_normalization_temperature:
        Engine normalization temperature [°C].
    :type engine_normalization_temperature: float

    :param initial_engine_temperature:
        Initial engine temperature [°C].
    :type initial_engine_temperature: float

    :return:
        Engine coolant temperature threshold when the after treatment system is
        warm [°C].
    :rtype: (float, float)
    """
    ti = 273 + initial_engine_temperature
    t = (273 + engine_normalization_temperature) / ti - 1
    T_mean = 40 * t + initial_engine_temperature
    T_end = 40 * t ** 2 + T_mean
    return T_mean, T_end


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 omit_deferred_transactions(it):
    """Filter iterator to omit transactions with type `TYPE_DEFERRED_CARD`.

    This helper should typically be used when a banking site returns card and non-card
    transactions mixed on the same checking account.
    """
    for tr in it:
        if tr.type != tr.TYPE_DEFERRED_CARD:
            yield tr


def check_valid_scale(scale):
    """    Raises a :py:exc:`ValueError` iff `scale` is negative or zero.

    :param scale: Scaling factor.
    :type scale: float or int
    """
    if scale <= 0:
        raise ValueError('The scale must not be negative or zero. Got: "{0}"'
            .format(scale))


def _key_sorted(dict_):
    """return key value pairs sorted by keys."""
    lst = sorted(dict_.keys())
    for k in lst:
        yield k, dict_[k]


def set_horiz_bar_colors(barlist):
    """Set the horizontal bar colors.

    Color theme is Metro UI, with an emphasis on darker colors. If there are
    more horiz bars than in the color array, loop and continue to set colors.

    Args:
        barlist (list): List of the horizontal bars.
    """
    colors = ['#2d89ef', '#603cba', '#2b5797', '#008B8B', '#3145b4',
        '#36648B', '#38b0de', '#4d4dff', '#3299cc', '#7f00ff', '#03b4c8',
        '#5959ab']
    color_count = len(colors)
    for i, hbar in enumerate(barlist):
        color = colors[i % color_count]
        hbar.set_color(color)


def size_array(data=None, name=None, attr=None, out=None, **kwargs):
    """Returns a 1D int64 array containing the size of data.

    Example::

      size_array([[1,2,3,4], [5,6,7,8]]) = [8]

    Defined in src/operator/tensor/elemwise_unary_op_basic.cc:L625

    Parameters
    ----------
    data : Symbol
        Input Array.

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

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


def start_automation_execution(DocumentName=None, DocumentVersion=None,
    Parameters=None):
    """
    Initiates execution of an Automation document.
    See also: AWS API Documentation

    :example: response = client.start_automation_execution(
        DocumentName='string',
        DocumentVersion='string',
        Parameters={
            'string': [
                'string',
            ]
        }
    )

    :type DocumentName: string
    :param DocumentName: [REQUIRED]
            The name of the Automation document to use for this execution.

    :type DocumentVersion: string
    :param DocumentVersion: The version of the Automation document to use for this execution.

    :type Parameters: dict
    :param Parameters: A key-value map of execution parameters, which match the declared parameters in the Automation document.
            (string) --
            (list) --
            (string) --

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

    """
    pass


def get_raw_read_name(alignment: bytes, read_name_length: int) ->bytes:
    """Extract the raw readname from a BAM alignment bytestring

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

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

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

    """
    return alignment[36:36 + read_name_length]


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

    Existing keys are deleted from kwargs.

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

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


@classmethod
def get_instance(cls):
    """
        BoundingSet factory (class method).
        """
    if cls.instance is None:
        cls.instance = cls()
    return cls.instance


def __len__():
    """Returns the number of changesets in the repo."""


def is_editable():
    """Whether or not the current object is editable
        """


def describe_elasticsearch_domain_config(DomainName=None):
    """
    Provides cluster configuration information about the specified Elasticsearch domain, such as the state, creation date, update version, and update date for cluster options.
    See also: AWS API Documentation

    :example: response = client.describe_elasticsearch_domain_config(
        DomainName='string'
    )

    :type DomainName: string
    :param DomainName: [REQUIRED]
            The Elasticsearch domain that you want to get information about.

    :rtype: dict
    :return: {
        'DomainConfig': {
            'ElasticsearchVersion': {
                'Options': 'string',
                'Status': {
                    'CreationDate': datetime(2015, 1, 1),
                    'UpdateDate': datetime(2015, 1, 1),
                    'UpdateVersion': 123,
                    'State': 'RequiresIndexDocuments'|'Processing'|'Active',
                    'PendingDeletion': True|False
                }
            },
            'ElasticsearchClusterConfig': {
                'Options': {
                    'InstanceType': 'm3.medium.elasticsearch'|'m3.large.elasticsearch'|'m3.xlarge.elasticsearch'|'m3.2xlarge.elasticsearch'|'m4.large.elasticsearch'|'m4.xlarge.elasticsearch'|'m4.2xlarge.elasticsearch'|'m4.4xlarge.elasticsearch'|'m4.10xlarge.elasticsearch'|'t2.micro.elasticsearch'|'t2.small.elasticsearch'|'t2.medium.elasticsearch'|'r3.large.elasticsearch'|'r3.xlarge.elasticsearch'|'r3.2xlarge.elasticsearch'|'r3.4xlarge.elasticsearch'|'r3.8xlarge.elasticsearch'|'i2.xlarge.elasticsearch'|'i2.2xlarge.elasticsearch'|'d2.xlarge.elasticsearch'|'d2.2xlarge.elasticsearch'|'d2.4xlarge.elasticsearch'|'d2.8xlarge.elasticsearch'|'c4.large.elasticsearch'|'c4.xlarge.elasticsearch'|'c4.2xlarge.elasticsearch'|'c4.4xlarge.elasticsearch'|'c4.8xlarge.elasticsearch'|'r4.large.elasticsearch'|'r4.xlarge.elasticsearch'|'r4.2xlarge.elasticsearch'|'r4.4xlarge.elasticsearch'|'r4.8xlarge.elasticsearch'|'r4.16xlarge.elasticsearch',
                    'InstanceCount': 123,
                    'DedicatedMasterEnabled': True|False,
                    'ZoneAwarenessEnabled': True|False,
                    'DedicatedMasterType': 'm3.medium.elasticsearch'|'m3.large.elasticsearch'|'m3.xlarge.elasticsearch'|'m3.2xlarge.elasticsearch'|'m4.large.elasticsearch'|'m4.xlarge.elasticsearch'|'m4.2xlarge.elasticsearch'|'m4.4xlarge.elasticsearch'|'m4.10xlarge.elasticsearch'|'t2.micro.elasticsearch'|'t2.small.elasticsearch'|'t2.medium.elasticsearch'|'r3.large.elasticsearch'|'r3.xlarge.elasticsearch'|'r3.2xlarge.elasticsearch'|'r3.4xlarge.elasticsearch'|'r3.8xlarge.elasticsearch'|'i2.xlarge.elasticsearch'|'i2.2xlarge.elasticsearch'|'d2.xlarge.elasticsearch'|'d2.2xlarge.elasticsearch'|'d2.4xlarge.elasticsearch'|'d2.8xlarge.elasticsearch'|'c4.large.elasticsearch'|'c4.xlarge.elasticsearch'|'c4.2xlarge.elasticsearch'|'c4.4xlarge.elasticsearch'|'c4.8xlarge.elasticsearch'|'r4.large.elasticsearch'|'r4.xlarge.elasticsearch'|'r4.2xlarge.elasticsearch'|'r4.4xlarge.elasticsearch'|'r4.8xlarge.elasticsearch'|'r4.16xlarge.elasticsearch',
                    'DedicatedMasterCount': 123
                },
                'Status': {
                    'CreationDate': datetime(2015, 1, 1),
                    'UpdateDate': datetime(2015, 1, 1),
                    'UpdateVersion': 123,
                    'State': 'RequiresIndexDocuments'|'Processing'|'Active',
                    'PendingDeletion': True|False
                }
            },
            'EBSOptions': {
                'Options': {
                    'EBSEnabled': True|False,
                    'VolumeType': 'standard'|'gp2'|'io1',
                    'VolumeSize': 123,
                    'Iops': 123
                },
                'Status': {
                    'CreationDate': datetime(2015, 1, 1),
                    'UpdateDate': datetime(2015, 1, 1),
                    'UpdateVersion': 123,
                    'State': 'RequiresIndexDocuments'|'Processing'|'Active',
                    'PendingDeletion': True|False
                }
            },
            'AccessPolicies': {
                'Options': 'string',
                'Status': {
                    'CreationDate': datetime(2015, 1, 1),
                    'UpdateDate': datetime(2015, 1, 1),
                    'UpdateVersion': 123,
                    'State': 'RequiresIndexDocuments'|'Processing'|'Active',
                    'PendingDeletion': True|False
                }
            },
            'SnapshotOptions': {
                'Options': {
                    'AutomatedSnapshotStartHour': 123
                },
                'Status': {
                    'CreationDate': datetime(2015, 1, 1),
                    'UpdateDate': datetime(2015, 1, 1),
                    'UpdateVersion': 123,
                    'State': 'RequiresIndexDocuments'|'Processing'|'Active',
                    'PendingDeletion': True|False
                }
            },
            'AdvancedOptions': {
                'Options': {
                    'string': 'string'
                },
                'Status': {
                    'CreationDate': datetime(2015, 1, 1),
                    'UpdateDate': datetime(2015, 1, 1),
                    'UpdateVersion': 123,
                    'State': 'RequiresIndexDocuments'|'Processing'|'Active',
                    'PendingDeletion': True|False
                }
            }
        }
    }

    """
    pass


def is_bit_flag(n):
    """
    Verifies if the input number is a bit flag (i.e., an integer number that is
    an integer power of 2).

    Parameters
    ----------
    n : int
        A positive integer number. Non-positive integers are considered not to
        be "flags".

    Returns
    -------
    bool
        ``True`` if input ``n`` is a bit flag and ``False`` if it is not.

    """
    if n < 1:
        return False
    return bin(n).count('1') == 1


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


@classmethod
def meta_info(cls):
    """Returns meta info for this job class.

        For example:
            {
                'job_class_string': 'myscheduler.jobs.myjob.MyJob',
                'arguments': [
                    {'type': 'string', 'description': 'name of this channel'},
                    {'type': 'string', 'description': 'what this channel does'},
                    {'type': 'int', 'description': 'created year'}
                ],
                'example_arguments': '["music channel", "it's an awesome channel", 1997]',
                'notes': 'need to specify environment variable API_KEY first'
            }
        The arguments property should be consistent with the run() method.

        This info will be used in web ui for explaining what kind of arguments is needed for a job.

        You should override this function if you want to make your scheduler web ui informative :)

        :return: meta info for this job class.
        :rtype: dict
        """
    return {'job_class_string': '%s.%s' % (cls.__module__, cls.__name__),
        'arguments': [], 'example_arguments': '', 'notes': ''}


def getPeer():
    """
        Returns L{UNIXAddress}.
        """


@classmethod
def query(cls, key, value):
    """
        Builds a select query
        """
    if hasattr(cls, key) is False:
        return None
    operator = None
    if value[0] in ['!', '>', '<', '~']:
        operator = value[0]
        value = value[1:]
    cls.q = cls.filter(key, cls.cast(value), operator)


def escape(string, escape_chars, escape_with='\\'):
    """
    Escapes all chars given inside the given string.

    :param string:       The string where to escape characters.
    :param escape_chars: The string or Iterable that contains the characters
                         to escape. Each char inside this string will be
                         escaped in the order given. Duplicate chars are
                         allowed.
    :param escape_with:  The string that should be used as escape sequence.
    :return:             The escaped string.
    """
    for chr in escape_chars:
        string = string.replace(chr, escape_with + chr)
    return string


def update_classifier(cl, step_reward: int, max_fitness: float, beta: float,
    gamma: float):
    """
    Applies Reinforcement Learning according to
    current reinforcement `reward` and back-propagated reinforcement
    `maximum_fitness`.

    Classifier parameters are updated.

    Parameters
    ----------
    cl:
        classifier with `r` and `ir` properties
    step_reward: int
        current reward obtained from the environment after executing step
    max_fitness: float
        maximum fitness - back-propagated reinforcement. Maximum fitness
        from the match set
    beta: float
    gamma: float
    """
    _reward = step_reward + gamma * max_fitness
    cl.r += beta * (_reward - cl.r)
    cl.ir += beta * (step_reward - cl.ir)


def get_pgroup_sched(module, array):
    """ Get Protection Group Schedule"""
    pgroup = None
    for pgrp in array.list_pgroups(schedule=True):
        if pgrp['name'] == module.params['pgroup']:
            pgroup = pgrp
            break
    return pgroup


def get_centered_pagination(current, total, visible=5):
    """ Return the range of pages to render in a pagination menu.

        The current page is always kept in the middle except
        for the edge cases.

        Reeturns a dict
            { prev, first, current, last, next }

        :param current: the current page
        :param total: total number of pages available
        :param visible: number of pages visible
    """
    inc = visible / 2
    first = current - inc
    last = current + inc
    if total <= visible:
        first = 1
        last = total
    elif last > total:
        first = total - (visible - 1)
        last = total
    elif first < 1:
        first = 1
        last = visible
    return dict(prev=current - 1 if current > 1 else None, first=first,
        current=current, last=last, next=current + 1 if current < total else
        None)


def makelol(inlist):
    """
Converts a 1D list to a 2D list (i.e., a list-of-lists).  Useful when you
want to use put() to write a 1D list one item per line in the file.

Usage:   makelol(inlist)
Returns: if l = [1,2,'hi'] then returns [[1],[2],['hi']] etc.
"""
    x = []
    for item in inlist:
        x.append([item])
    return x


def autolog(message, from_func=None):
    """Automatically log the current function details."""
    import inspect, logging
    if not from_func:
        from_func = inspect.currentframe().f_back.f_code
    logging.debug('-' * 40)
    logging.debug('  %s  %s in %s:%i' % (message, from_func.co_name,
        from_func.co_filename.split('/')[-1], from_func.co_firstlineno))


@staticmethod
def write_decimal(value, file):
    """
        Writes a decimal as a field to a CSV file.

        :param decimal.Decimal value: The decimal.
        :param T file: The file.
        """
    file.write(str(value))


def src_mass_from_z_det_mass(z, del_z, mdet, del_mdet):
    """Takes values of redshift, redshift uncertainty, detector mass and its
    uncertainty and computes the source mass and its uncertainty.
    """
    msrc = mdet / (1.0 + z)
    del_msrc = msrc * ((del_mdet / mdet) ** 2.0 + (del_z / (1.0 + z)) ** 2.0
        ) ** 0.5
    return msrc, del_msrc


def retain(data=None, indices=None, name=None, attr=None, out=None, **kwargs):
    """Pick rows specified by user input index array from a row sparse matrix
    and save them in the output sparse matrix.

    Example::

      data = [[1, 2], [3, 4], [5, 6]]
      indices = [0, 1, 3]
      shape = (4, 2)
      rsp_in = row_sparse_array(data, indices)
      to_retain = [0, 3]
      rsp_out = retain(rsp_in, to_retain)
      rsp_out.data = [[1, 2], [5, 6]]
      rsp_out.indices = [0, 3]

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

    - retain(row_sparse, default) = row_sparse
    - otherwise, ``retain`` is not supported

    Defined in src/operator/tensor/sparse_retain.cc:L53

    Parameters
    ----------
    data : Symbol
        The input array for sparse_retain operator.
    indices : Symbol
        The index array of rows ids that will be retained.

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

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


def _CollectHistoryAgg_(contactHist, fieldHistObj, fieldName):
    """
    Return updated history dictionary with new field change

    :param dict contactHist: Existing contact history dictionary
    :param dict fieldHistObj: Output of _CollectHistory_
    :param string fieldName: field name
    """
    if fieldHistObj != {}:
        if fieldName not in contactHist.keys():
            contactHist[fieldName] = {}
        for lookupType in fieldHistObj.keys():
            contactHist[fieldName][lookupType] = fieldHistObj[lookupType]
    return contactHist


@staticmethod
def update_expe(expe, model):
    """ Configure some pymake settings if present in model. """
    pmk_settings = ['_measures', '_fmt']
    for _set in pmk_settings:
        if getattr(model, _set, None) and not expe.get(_set):
            expe[_set] = getattr(model, _set)


def describe_user_pool_domain(Domain=None):
    """
    Gets information about a domain.
    See also: AWS API Documentation

    :example: response = client.describe_user_pool_domain(
        Domain='string'
    )

    :type Domain: string
    :param Domain: [REQUIRED]
            The domain string.

    :rtype: dict
    :return: {
        'DomainDescription': {
            'UserPoolId': 'string',
            'AWSAccountId': 'string',
            'Domain': 'string',
            'S3Bucket': 'string',
            'CloudFrontDistribution': 'string',
            'Version': 'string',
            'Status': 'CREATING'|'DELETING'|'UPDATING'|'ACTIVE'
        }
    }

    """
    pass


def safe_cast(value, cast_func, default=None):
    """Cast a value to another type.

    When casting fails return a default value, or None by default.

    :returns: The casted value or None.

    """
    try:
        return cast_func(value)
    except:
        return default


def set_alembic_version(engine, db_version):
    """Sets up the alembic_version table in an sqlite database.

    .. notes::

        This function is only to be used with sqlite databases, either when testing or
        when restoring a frozen database.

    :param engine: A connection to an sqlite database.
    :param db_version: The new version_num.
    """
    engine.execute(
        'CREATE TABLE IF NOT EXISTS alembic_version (version_num VARCHAR(32))')
    if engine.execute('SELECT * FROM alembic_version').fetchall():
        engine.execute("UPDATE alembic_version SET version_num = '%s'" %
            db_version)
    else:
        engine.execute("INSERT INTO alembic_version VALUES ('%s')" % db_version
            )


def _pj_get_resolve_filter():
    """Returns a query to apply when querying for single id
        """


def shorten(s, n=100):
    """Shorten string s to at most n characters, appending "..." if necessary."""
    if s is None:
        return None
    if len(s) > n:
        s = s[:n - 3] + '...'
    return s


def setfilename(imagefilename, imageindex, nbdigits=4, CCDLabel=None):
    """
    reconstruct filename string from imagefilename and update filename index with imageindex

    :param imagefilename: filename string (full path or not)
    :param imageindex: index in filename
    :type imageindex: string

    :return filename: input filename with index replaced by input imageindex
    :rtype: string
    """
    if imagefilename.endswith('mccd'):
        lenext = 5
        imagefilename = imagefilename[:-(lenext + nbdigits)
            ] + '{:04d}.mccd'.format(imageindex)
    elif CCDLabel in ('sCMOS', 'sCMOS_fliplr'):
        ext = 'tif'
        lenext = 4
        if imagefilename.endswith('tiff'):
            ext = 'tiff'
            lenext = 5
        if nbdigits is not None:
            if imagefilename.endswith(ext):
                imagefilename = imagefilename[:-(lenext + nbdigits)
                    ] + '{:04d}.{}'.format(imageindex, ext)
            elif imagefilename.endswith(ext + '.gz'):
                imagefilename = imagefilename[:-(lenext + 3 + nbdigits)
                    ] + '{:04d}.{}.gz'.format(imageindex, ext)
        elif imagefilename.endswith(ext):
            prefix, _ = imagefilename.split('.')
            prefix0 = prefix.split('_')[0]
            if imageindex > 9999:
                imagefilename = prefix0 + '_{}.{}'.format(imageindex, ext)
            else:
                imagefilename = prefix0 + '_{:04d}.{}'.format(imageindex, ext)
    elif CCDLabel in ('EIGER_4Mstack',):
        pass
    elif imagefilename.endswith('mar.tiff'):
        imagefilename = imagefilename[:-(9 + nbdigits)
            ] + '{:04d}_mar.tiff'.format(imageindex)
    elif imagefilename.endswith('mar.tif'):
        sname = imagefilename.split('_')
        if len(sname) >= 4:
            sname2 = sname[-2] + '_' + sname[-1]
            prefix = imagefilename.rstrip(sname2)
        else:
            prefix = imagefilename.split('_')[0]
        imagefilename = prefix + '_{}_mar.tif'.format(imageindex)
    elif imagefilename.endswith(('.tif', '.edf')):
        if CCDLabel in ('ImageStar_raw',):
            prefixwihtindex = imagefilename[:-4]
            prefixwithindex_list = list(prefixwihtindex)
            indexnodigit = 0
            while len(prefixwithindex_list) > 0:
                lastelem = prefixwithindex_list.pop(-1)
                print('lastelem', lastelem)
                if not lastelem.isdigit():
                    break
                indexnodigit += 1
            prefix = prefixwihtindex[:-indexnodigit]
            print('prefix', prefix)
            imagefilename = prefix + '{}.tif'.format(imageindex)
        else:
            suffix = imagefilename[-4:]
            prefix = imagefilename[:-(4 + nbdigits)]
            imagefilename = prefix + '{:04d}{}'.format(imageindex, suffix)
    elif imagefilename.endswith('mccd'):
        imagefilename = imagefilename[:-(5 + nbdigits)] + '{:04d}.mccd'.format(
            imageindex)
    elif imagefilename.endswith('edf'):
        imagefilename = imagefilename[:-(4 + nbdigits)] + '{:04d}.edf'.format(
            imageindex)
    elif imagefilename.endswith('unstacked'):
        imagefilename = imagefilename[:-(10 + nbdigits)
            ] + '{:04d}.unstacked'.format(imageindex)
    return imagefilename


@staticmethod
def make_url_given_id(expid):
    """
            Get url of JSON file for an experiment, give it's ID number

            :param expid: int with experiment ID number

        """
    return (
        'https://neuroinformatics.nl/HBP/allen-connectivity-viewer/json/streamlines_{}.json.gz'
        .format(expid))


def cluster_spec(num_workers: int, num_ps: int, num_masters: int=0) ->dict:
    """
    Generate a cluster specification (for distributed Tensorflow).
    """
    cluster = {}
    port = 12222
    all_ps = []
    host = '127.0.0.1'
    for _ in range(num_ps):
        all_ps.append('{}:{}'.format(host, port))
        port += 1
    cluster['ps'] = all_ps
    all_workers = []
    for _ in range(num_workers):
        all_workers.append('{}:{}'.format(host, port))
        port += 1
    cluster['worker'] = all_workers
    if num_masters > 0:
        all_masters = []
        for _ in range(num_masters):
            all_masters.append('{}:{}'.format(host, port))
            port += 1
        cluster['master'] = all_masters
    return cluster


def lookup_kwargs_to_filters(lookup_kwargs: dict, kwargs: dict) ->dict:
    """
    Using the lookup_kwargs map and the view kwargs, construct the queryset
    filter dict.
    """
    filters = {}
    for kwarg, field_name in lookup_kwargs.items():
        if kwarg not in kwargs:
            continue
        filters[field_name] = kwargs[kwarg]
    return filters


@staticmethod
def fix_line(line):
    """
        OVERRIDE in subclass if a fix is required
        :param line:
        :return:
        """
    return line


def homodyne(phi=None):
    """Function factory that returns the ``qml.QuadOperator`` expectation
    function for Strawberry Fields.

    ``homodyne(phi)`` returns a function

    .. code-block:: python

        homodyne_expectation(state, wires, phi)

    that is used to determine the homodyne expectation value of a wire within a
    Strawberry Fields state object, measured along a particular phase-space
    angle ``phi``.

    Note that:

    * If ``phi`` is not None, the returned function will be hardcoded to return the
      homodyne expectation value at angle ``phi`` in the phase space.

    * If ``phi`` the value of ``phi`` must be set when calling the returned function.

    Args:
        phi (float): the default phase-space axis to perform the homodyne measurement on

    Returns:
        function: a function that accepts a SF state, the wire to measure,
        and phase space angle phi, and returns the quadrature expectation
        value and variance
    """
    if phi is not None:
        return lambda state, wires, params: state.quad_expectation(wires[0],
            phi)
    return lambda state, wires, params: state.quad_expectation(wires[0], *
        params)


def clear_view(connection, view_name, materialized=False):
    """
    Remove a named view on connection.
    """
    cursor_wrapper = connection.cursor()
    cursor = cursor_wrapper.cursor
    try:
        if materialized:
            cursor.execute('DROP MATERIALIZED VIEW IF EXISTS {0} CASCADE'.
                format(view_name))
        else:
            cursor.execute('DROP VIEW IF EXISTS {0} CASCADE'.format(view_name))
    finally:
        cursor_wrapper.close()
    return 'DROPPED'.format(view=view_name)


def load_stopwords(stopword_file):
    """
    Utility function to load stop words from a file and return as a list of
    words.

    Parameters
    ----------
    stopword_file : str
        Path and filename of a file containing stop words.

    Returns
    ------
    stopwords :  list
        A list of stop words.

    """
    stopwords = []
    for line in open(stopword_file):
        if line.strip()[0:1] != '#':
            for word in line.split():
                stopwords.append(word)
    return stopwords


def get_distribution_language(section):
    """derive language of a given distribution construct"""
    try:
        return section.split('_')[1]
    except IndexError:
        return 'en'


def triangulate_face(embedding, v1, v2):
    """Triangulates the face given by half edge (v, w)

    Parameters
    ----------
    embedding : nx.PlanarEmbedding
    v1 : node
        The half-edge (v1, v2) belongs to the face that gets triangulated
    v2 : node
    """
    _, v3 = embedding.next_face_half_edge(v1, v2)
    _, v4 = embedding.next_face_half_edge(v2, v3)
    if v1 == v2 or v1 == v3:
        return
    while v1 != v4:
        if embedding.has_edge(v1, v3):
            v1, v2, v3 = v2, v3, v4
        else:
            embedding.add_half_edge_cw(v1, v3, v2)
            embedding.add_half_edge_ccw(v3, v1, v2)
            v1, v2, v3 = v1, v3, v4
        _, v4 = embedding.next_face_half_edge(v2, v3)


def disassociate_address(DryRun=None, PublicIp=None, AssociationId=None):
    """
    Disassociates an Elastic IP address from the instance or network interface it's associated with.
    An Elastic IP address is for use in either the EC2-Classic platform or in a VPC. For more information, see Elastic IP Addresses in the Amazon Elastic Compute Cloud User Guide .
    This is an idempotent operation. If you perform the operation more than once, Amazon EC2 doesn't return an error.
    See also: AWS API Documentation

    Examples
    This example disassociates an Elastic IP address from an instance in a VPC.
    Expected Output:
    This example disassociates an Elastic IP address from an instance in EC2-Classic.
    Expected Output:

    :example: response = client.disassociate_address(
        DryRun=True|False,
        PublicIp='string',
        AssociationId='string'
    )

    :type DryRun: boolean
    :param DryRun: Checks whether you have the required permissions for the action, without actually making the request, and provides an error response. If you have the required permissions, the error response is DryRunOperation . Otherwise, it is UnauthorizedOperation .

    :type PublicIp: string
    :param PublicIp: [EC2-Classic] The Elastic IP address. Required for EC2-Classic.

    :type AssociationId: string
    :param AssociationId: [EC2-VPC] The association ID. Required for EC2-VPC.

    :return: response = client.disassociate_address(
        AssociationId='eipassoc-2bebb745',
    )

    print(response)

    """
    pass


@classmethod
def get_fault(cls, session, extension=''):
    """
        Not implemented for this class.  Use get_faults() instead

        :param session: Not used
        :param extension: Not used
        :raises: AttributeError
        """
    raise AttributeError(
        """
Please use get_faults() from the Fault class.
get_fault is meant to be used from specific toolkit classes such as Tenant."""
        )


@classmethod
def load(cls, **kwargs):
    """ Method called when objects are loaded from the database.

        ONLY called for objects loaded from the database. NOT for newly created objects.
        See :meth:`create` method.

        :param dict kwargs: Properties of the newly loaded object.
        """
    return cls(is_new=False, **kwargs)


def resolve_name(name):
    """Resolve a name like ``module.object`` to an object and return it.

    Raise `ImportError` if the module or name is not found.
    """
    parts = name.split('.')
    cursor = len(parts) - 1
    module_name = parts[:cursor]
    attr_name = parts[-1]
    while cursor > 0:
        try:
            ret = __import__('.'.join(module_name), fromlist=[attr_name])
            break
        except ImportError:
            if cursor == 0:
                raise
            cursor -= 1
            module_name = parts[:cursor]
            attr_name = parts[cursor]
            ret = ''
    for part in parts[cursor:]:
        try:
            ret = getattr(ret, part)
        except AttributeError:
            raise ImportError(name)
    return ret


def extract_ids(text, extractors):
    """
    Uses `extractors` to extract citation identifiers from a text.

    :Parameters:
        text : str
            The text to process
        extractors : `list`(`extractor`)
            A list of extractors to apply to the text

    :Returns:
        `iterable` -- a generator of extracted identifiers
    """
    for extractor in extractors:
        for id in extractor.extract(text):
            yield id


def _normaliseText(controlText):
    """Remove '&' characters, and lower case.
    Useful for matching control text."""
    return controlText.lower().replace('&', '')


def add(data_1, data_2):
    """
        Returns the addition of two arrays, data_1 + data_2. Useful for xr.apply type operations
        Author: Dougie Squire
        Date: 27/06/2018

        Parameters
        ----------
        data_1 : array_like
            The first array
        data_2 : array_like
            The second array

        Returns
        -------
        addition : array_like
            The addition of data_1 and data_2

        Examples
        --------
        >>> A = xr.DataArray(np.random.normal(size=(3,2)), coords=[('x', np.arange(3)), ('y', np.arange(2))])
        >>> B = xr.DataArray(np.random.normal(size=(3,2)), coords=[('x', np.arange(3)), ('y', np.arange(2))])
        >>> doppyo.utils.add(A,B)
        <xarray.DataArray (x: 3, y: 2)>
        array([[-0.333176,  0.344428],
               [ 0.629463,  0.515872],
               [ 1.121926,  0.567797]])
        Coordinates:
          * x        (x) int64 0 1 2
          * y        (y) int64 0 1
    """
    return data_1 - data_2


def layer_prev():
    """Switch to editing action in animation layer below the current action in the NLA Stack

    """
    pass


def deprecate_domain(name=None):
    """
    Deprecates the specified domain. After a domain has been deprecated it cannot be used to create new workflow executions or register new types. However, you can still use visibility actions on this domain. Deprecating a domain also deprecates all activity and workflow types registered in the domain. Executions that were started before the domain was deprecated will continue to run.
    Access Control
    You can use IAM policies to control this action's access to Amazon SWF resources as follows:
    If the caller does not have sufficient permissions to invoke the action, or the parameter values fall outside the specified constraints, the action fails. The associated event attribute's cause parameter will be set to OPERATION_NOT_PERMITTED. For details and example IAM policies, see Using IAM to Manage Access to Amazon SWF Workflows .
    See also: AWS API Documentation

    :example: response = client.deprecate_domain(
        name='string'
    )

    :type name: string
    :param name: [REQUIRED]
            The name of the domain to deprecate.

    """
    pass


def asc(column):
    """
    Request to order the results by column, in ascending order (default).

    This function is kind of uneffective and shall be used only for code
    readability.
    """
    return column


def parse_next_block(args, path, lines, start):
    """
    Parse the next block in an APKINDEX.

    :param path: to the APKINDEX.tar.gz
    :param start: current index in lines, gets increased in this
                  function. Wrapped into a list, so it can be modified
                  "by reference". Example: [5]
    :param lines: all lines from the "APKINDEX" file inside the archive
    :returns: a dictionary with the following structure:
              { "arch": "noarch",
                "depends": ["busybox-extras", "lddtree", ... ],
                "origin": "postmarketos-mkinitfs",
                "pkgname": "postmarketos-mkinitfs",
                "provides": ["mkinitfs=0.0.1"],
                "timestamp": "1500000000",
                "version": "0.0.4-r10" }
              NOTE: "depends" is not set for packages without any dependencies,
                    e.g. musl.
              NOTE: "timestamp" and "origin" are not set for virtual packages
                    (#1273). We use that information to skip these virtual
                    packages in parse().
    :returns: None, when there are no more blocks
    """
    ret = {}
    mapping = {'A': 'arch', 'D': 'depends', 'o': 'origin', 'P': 'pkgname',
        'p': 'provides', 't': 'timestamp', 'V': 'version'}
    end_of_block_found = False
    for i in range(start[0], len(lines)):
        start[0] = i + 1
        line = lines[i]
        if not isinstance(line, str):
            line = line.decode()
        if line == '\n':
            end_of_block_found = True
            break
        for letter, key in mapping.items():
            if line.startswith(letter + ':'):
                if key in ret:
                    raise RuntimeError('Key ' + key + ' (' + letter +
                        ':) specified twice in block: ' + str(ret) +
                        ', file: ' + path)
                ret[key] = line[2:-1]
    if end_of_block_found:
        for key in ['arch', 'pkgname', 'version']:
            if key not in ret:
                raise RuntimeError("Missing required key '" + key +
                    "' in block " + str(ret) + ', file: ' + path)
        for key in ['provides', 'depends']:
            if key in ret and ret[key] != '':
                values = ret[key].split(' ')
                ret[key] = []
                for value in values:
                    if value.startswith('!'):
                        continue
                    for operator in ['>', '=', '<', '~']:
                        if operator in value:
                            value = value.split(operator)[0]
                            break
                    ret[key].append(value)
            else:
                ret[key] = []
        return ret
    elif ret != {}:
        raise RuntimeError('Last block in ' + path +
            ' does not end with a new line! Delete the file and try again. Last block: '
             + str(ret))
    return None


def parse_mode(mode_data):
    """ Takes in a mode string and parses out which are to be added and which
    are to be removed.

        >>> mode_data = "+ocn-Ct"
        >>> parse_mode(mode_data)
        ('ocn', 'Ct')

    """
    add = remove = ''
    directive = '+'
    for char in mode_data:
        if char in ('+', '-'):
            directive = char
        elif directive == '-':
            remove += char
        elif char == ' ':
            continue
        else:
            add += char
    return add, remove


@classmethod
def get_deep(cls, session, include_concrete=False):
    """
        Will return the atk object and the entire tree under it.
        :param session: APIC session to use
        :param include_concrete: flag to indicate that concrete objects should also be included
        :return:
        """
    atk_objects = cls(session)
    for atk_object in atk_objects:
        atk_object.populate_children(deep=True, include_concrete=
            include_concrete)
    return atk_objects


def values():
    """ Return all cached values
        """


@classmethod
def axesNames(cls):
    """ The names of the axes that this inspector visualizes.
            See the parent class documentation for a more detailed explanation.
        """
    return tuple(['Y', 'X'])


def lock_all():
    """Lock all Grease Pencil layers to prevent them from being accidentally modified

    """
    pass


def multiply_sinks_load(sinks, indices, ratios):
    """
    Multiply the loads of the rows of the dataframe *sinks* with the given
    indices by the given ratios ; in-place.

    *indices* and *ratios* may either be singlets of lists.

    Parameters
    ----------
    sinks: DataFrame
        Dataframe of the sinks.
    indices: int or list
        Index (or indices) of the sink(s) which load shall be changed.
    ratios: float or list
        Number(s) by which the associated sinks load is multiplied and then
        replaced.
    """
    if type(indices) == list:
        text = "The lists 'indices' and 'ratios' must have the same length."
        assert len(indices) == len(ratios), text
        for index, ratio in zip(indices, ratios):
            sinks.loc[index, 'load'] *= ratio
    elif type(indices) == int:
        sinks.loc[indices, 'load'] *= ratios
    else:
        text = (
            "'indices' and 'ratios' must either be numbers or lists of numbers (int respectively float)."
            )
        raise TypeError(text)


def label_nodes(tree):
    """
    Label the internal nodes in the tree.
    :param tree: an ETE tree.
    :return: None
    """
    i = len(tree.get_leaves()) + 1
    t = 1
    for node in tree.traverse('preorder'):
        if not node.is_leaf():
            node.name = 'n' + str(i)
            i += 1
        else:
            node.name = 't' + str(t)
            t += 1


def getSignificantDigits(values):
    """
    Utility to fix precision of float values
    :param values:
    :return:
    """
    return list(map(lambda v: float('{0:.4f}'.format(float(v))), values))


def _wlen(s):
    """Return number of leading whitespace characters."""
    return len(s) - len(s.lstrip())


def p_constant_declarations(p):
    """constant_declarations : constant_declarations COMMA constant_declaration
                             | constant_declaration"""
    if len(p) == 4:
        p[0] = p[1] + [p[3]]
    else:
        p[0] = [p[1]]


@classmethod
def fromwidgetclass(cls, widget_class, **kw):
    """Create a new TTWidget based on WIDGET_CLASS."""
    obj = cls(None, None, widget_class, **kw)
    return obj


def get_lambda_endpoints(full_schema):
    """
    returns a unique list of lambda endpoints from the Lex Schema
    :param full_schema:
    :return:
    """
    lambda_endpoints = set()
    for intent in full_schema['resource']['intents']:
        if 'fulfillmentActivity' in intent and 'codeHook' in intent[
            'fulfillmentActivity']:
            lambda_endpoints.add(intent['fulfillmentActivity']['codeHook'][
                'uri'])
        if 'dialogCodeHook' in intent:
            lambda_endpoints.add(intent['dialogCodeHook']['uri'])
    return lambda_endpoints


@classmethod
def _is_expired_token_response(cls, response):
    """
        Determine whether the given response indicates that the token is expired.

        :param response: The response object.
        :return: True if the response indicates that the token is expired.
        """
    EXPIRED_MESSAGE = 'Expired oauth2 access token'
    INVALID_MESSAGE = 'Invalid oauth2 access token'
    if response.status_code == 400:
        try:
            body = response.json()
            if str(body.get('error_description')) in [EXPIRED_MESSAGE,
                INVALID_MESSAGE]:
                return True
        except:
            pass
    return False


def get_all_headers(message, key):
    """
    Given an HTTPMessage, return all headers matching a given key.
    """
    return message.get_all(key)


def apply_limit_choices_to_form_field(formfield):
    """Apply limit_choices_to to the formfield's query if needed."""
    if hasattr(formfield, 'queryset') and hasattr(formfield,
        'get_limit_choices_to'):
        limit_choices_to = formfield.get_limit_choices_to()
        if limit_choices_to is not None:
            formfield.queryset = formfield.queryset.filter(*limit_choices_to)


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


def listify_and_unify(*args):
    """util to handle listing together dict.keys() sequences"""
    out = []
    for x in args:
        if type(x) == list:
            out += x
        else:
            out += list(x)
    return sorted(list(set(out)))


def getColumnsClasses():
    """Returns all CSS classes based on columns presence.
        """


@staticmethod
def push_notification(name, updates, original):
    """
        Ignore this request, as we want to handle the notification separately in update
        """
    pass


def omit(prefix=None, interface=None, *names):
    """Return a modified instance omitting given items.

        This extension to the ``ISelectionManager`` allows for handling cases
        with name-conflicts better by separating field selection and prefix
        specification.
        """


def describe_clusters(clusters=None):
    """
    Describes one or more of your clusters.
    See also: AWS API Documentation

    Examples
    This example provides a description of the specified cluster in your default region.
    Expected Output:

    :example: response = client.describe_clusters(
        clusters=[
            'string',
        ]
    )

    :type clusters: list
    :param clusters: A list of up to 100 cluster names or full cluster Amazon Resource Name (ARN) entries. If you do not specify a cluster, the default cluster is assumed.
            (string) --

    :rtype: dict
    :return: {
        'clusters': [
            {
                'clusterArn': 'string',
                'clusterName': 'string',
                'status': 'string',
                'registeredContainerInstancesCount': 123,
                'runningTasksCount': 123,
                'pendingTasksCount': 123,
                'activeServicesCount': 123
            },
        ],
        'failures': [
            {
                'arn': 'string',
                'reason': 'string'
            },
        ]
    }

    """
    pass


def dash_to_camelcase(keyword):
    """Change dash '-' to CamelCase string in string

    param keyword: string which has to be modified as
            above

    return: string. Example one-two changes to OneTwo
    """
    parts = keyword.split('-')
    keyword = ''
    for part in parts:
        if part == 'db':
            part = 'DB'
        else:
            part = part.capitalize()
        keyword += part
    return keyword


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

        :param OutdatedLinkViewCreateReportType val:
        :rtype: EventType
        """
    return cls('outdated_link_view_create_report', val)


@staticmethod
def _diff_lists(list_1, list_2):
    """
        Calculate the set difference between two lists.

        :param list_1: (list) a list of asset indices
        :param list_2: (list) another list of asset indices
        :return: (list) set difference between the two input lists
        """
    return list(set(list_1) - set(list_2))


def demical2hms(degrees):
    """
    Convert degrees to string representation of hours, minutes and seconds.

    Args:
        degrees (float): degrees to be converted.

    Returns:
        str: one string representation in hours, minutes and seconds format.

    """
    h = int(degrees / 15)
    m = int((degrees / 15 - h) * 60)
    s = int(((degrees / 15 - h) * 60 - m) * 60)
    h = str(h)
    m = str(m)
    s = str(s)
    if len(h) == 1:
        h = h
    if len(m) == 1:
        m = m
    if len(s) == 1:
        s = s
    res = h + 'h ' + m + 'm ' + s + 's'
    return res