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 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 int_shape(x):
    """Returns the shape of tensor or variable as a tuple of int or None entries.

    # Arguments
        x: Tensor or variable.

    # Returns
        A tuple of integers (or None entries).

    # Examples
    ```python
        >>> from keras import backend as K
        >>> inputs = K.placeholder(shape=(2, 4, 5))
        >>> K.int_shape(inputs)
        (2, 4, 5)
        >>> val = np.array([[1, 2], [3, 4]])
        >>> kvar = K.variable(value=val)
        >>> K.int_shape(kvar)
        (2, 2)
    ```

    {{np_implementation}}
    """
    if hasattr(x, '_keras_shape'):
        return x._keras_shape
    try:
        if isinstance(x.shape, tuple):
            return x.shape
        return tuple(x.shape.as_list())
    except ValueError:
        return None


def centroid(P):
    """compute average point of a set of points"""
    cx = 0
    cy = 0
    for x, y in P:
        cx += x
        cy += y
    n = float(len(P))
    return cx / n, cy / n


def run_with_stack_context(context, func):
    """Run a coroutine ``func`` in the given `StackContext`.

    It is not safe to have a ``yield`` statement within a ``with StackContext``
    block, so it is difficult to use stack context with `.gen.coroutine`.
    This helper function runs the function in the correct context while
    keeping the ``yield`` and ``with`` statements syntactically separate.

    Example::

        @gen.coroutine
        def incorrect():
            with StackContext(ctx):
                # ERROR: this will raise StackContextInconsistentError
                yield other_coroutine()

        @gen.coroutine
        def correct():
            yield run_with_stack_context(StackContext(ctx), other_coroutine)

    .. versionadded:: 3.1
    """
    with context:
        return func()


@staticmethod
def create_default_context():
    """Create a default offscreen rendering context.

        @todo: This is window system dependent; create an appropriate context
        dynamically.
        @todo: When no context exists, create a raw offscreen context instead of a
        hidden GLUT window so that rendering is possible without an X connection.
        """
    try:
        from glitter.contexts.glx import GLXContext
        return GLXContext()
    except ImportError:
        from glitter.contexts.glut import GlutWindow
        return GlutWindow(shape=(1, 1), hide=True)


def _a_decode_unicode(stream, offset, count, _):
    """
    'a3sbar',3,3 --> 6,u'bar'
    """
    if len(stream) >= offset + count:
        return offset + count, stream[offset:offset + count].decode('UTF-8')
    else:
        raise ValueError('Invalid stream length', len(stream), offset + count)


def __hue_to_rgb(v1, v2, vh):
    """
    Calculation from http://www.easyrgb.com/en/math.php
    """
    if vh < 0:
        vh += 1
    if vh > 1:
        vh -= 1
    if 6 * vh < 1:
        return v1 + (v2 - v1) * 6 * vh
    elif 2 * vh < 1:
        return v2
    elif 3 * vh < 2:
        return v1 + (v2 - v1) * (2 / 3 - vh) * 6
    else:
        return v1


def hex2dec(x):
    """
    Convert hexadecimal string to decimal number.
    For instance: '1a' -> 26
    """
    return int(x, 16)


@classmethod
def from_tuple(cls, tpl: tuple):
    """
        Gets a board position from tuple.

        Args:
            tpl: The tuple

        Returns:

        """
    return cls(tpl[0], tpl[1])


def greatcircle_to_greatcircle(from_greatcircle_coord, to_greatcircle_frame):
    """Transform between two greatcircle frames."""
    intermediate_from = from_greatcircle_coord.transform_to(
        from_greatcircle_coord.pole)
    intermediate_to = intermediate_from.transform_to(to_greatcircle_frame.pole)
    return intermediate_to.transform_to(to_greatcircle_frame)


def get_sort_key(realm):
    """Returns a sort `key` function for the argument of the same name of
        `sorted` or `list.sort`. By default this can be `None` for normal
        sorting. Providers with numeric resource ids should return `int` or
        a similar function to enable numeric sorting.
        """
    pass


def test_pyblish_availability():
    """Is Pyblish available?"""
    try:
        __import__('pyblish')
        __import__('pyblish_qml')
    except Exception:
        raise Exception('Pyblish not found')


def new_fun(arg1='Default', arg2='Default'):
    """Short explanation.

    This is the very long explanation

    Parameters
    -----------
    arg1 : type, default : 'Default'
        What is arg1.

    arg2 : {'Default', 'Different', 'Another'}
        What is arg2.

    Returns
    -----------
    out : type
        What is out.
    """


@classmethod
def find_or_create_using_ps_data(cls, customer_record):
    """Look for the party in tryton corresponding to the customer_record.
        If found, return the same else create a new one and return that.

        :param customer_record: Objectified XML record sent by pystashop
        :returns: Active record of created party
        """
    party = cls.get_party_using_ps_data(customer_record)
    if not party:
        party = cls.create_using_ps_data(customer_record)
    return party


def scroll_page_down(event):
    """
    Scroll page down. (Prefer the cursor at the top of the page, after scrolling.)
    """
    w = event.app.layout.current_window
    b = event.app.current_buffer
    if w and w.render_info:
        line_index = max(w.render_info.last_visible_line(), w.
            vertical_scroll + 1)
        w.vertical_scroll = line_index
        b.cursor_position = b.document.translate_row_col_to_index(line_index, 0
            )
        b.cursor_position += b.document.get_start_of_line_position(
            after_whitespace=True)


@staticmethod
def _sort_count(t):
    """
        sort by: count (1st item), value (2nd item), list of glyph names (3rd
        item)
        """
    return -t[0], -t[1], t[2]


def __add__(other):
    """Add another handlers object.

        During the process a copy of the current handlers object should be
        created and the other one is added to the copy. The return value is
        the copy.
        """


def xml_to_standard_dict(ordered_data, reduce_orderedDicts=False,
    reduce_lists=False, manual_selection_for_list_reduction=False):
    """
    Convert a xml/orderedDict to normal dictionary

    Parameters
    ----------
    ordered_data : orderedDict
        input xml data to convert to standard dict
    reduce_orderedDicts : bool, optional
        if collections.orderedDicts shall be converted to normal dicts
    reduce_lists : bool, list, set, optional
        if lists in the dictionary shall be converted to dictionaries with transformed keys
        (list_key + unique key from dictionary from list_element)
        if list or set is provided, only these values will be reduced
    manual_selection_for_list_reduction : bool, optional
        if manually decision on list reduction shall be used
        all keys in ``reduce_lists`` will be automatically reduced

    Returns
    -------
    dict
        the normalized dictionary

    """
    from collections import OrderedDict
    from ._helper import _reduce_lists, _dictionize
    data = dict()
    if reduce_orderedDicts:
        for key in ordered_data:
            if isinstance(ordered_data[key], OrderedDict):
                data[key] = _dictionize(ordered_data[key])
            else:
                data[key] = ordered_data[key]
    if manual_selection_for_list_reduction:
        raise NotImplemented
    elif reduce_lists:
        data = _reduce_lists(data, reduce_lists,
            manual_selection_for_list_reduction)
    return data


def set_process_priority(priority, pid=None):
    """
    Set the priority of a Windows process.

    Priority is a value between 0-5 where 2 is normal priority. Default sets
    the priority of the current Python process but can take any valid process
    ID.
    """
    import win32process, win32con, win32api
    priorityclasses = [win32process.IDLE_PRIORITY_CLASS, win32process.
        BELOW_NORMAL_PRIORITY_CLASS, win32process.NORMAL_PRIORITY_CLASS,
        win32process.ABOVE_NORMAL_PRIORITY_CLASS, win32process.
        HIGH_PRIORITY_CLASS, win32process.REALTIME_PRIORITY_CLASS]
    if pid is None:
        pid = win32api.GetCurrentProcessId()
    handle = win32api.OpenProcess(win32con.PROCESS_ALL_ACCESS, True, pid)
    win32process.SetPriorityClass(handle, priorityclasses[priority])


def topological_visit(g, v, color, order):
    """Run iterative DFS from node V"""
    total = 0
    stack = [v]
    while stack:
        v = stack[-1]
        if color[v]:
            v = stack.pop()
            if color[v] == 1:
                order.append(v)
                color[v] = 2
        else:
            color[v] = 1
            total += 1
            for w in range(len(g[0])):
                if w != v and g[v][w] and not color[w]:
                    stack.append(w)
    return total


def is_response_to_head(response):
    """
    Checks whether the request of a response has been a HEAD-request.
    Handles the quirks of AppEngine.

    :param conn:
    :type conn: :class:`httplib.HTTPResponse`
    """
    method = response._method
    if isinstance(method, int):
        return method == 3
    return method.upper() == 'HEAD'


def collapse_form(form, category):
    """ Permit to return the class of the collapsible according to errors in
    the form. """
    categories_with_error = set()
    for field in form:
        if field.errors:
            categories_with_error.add(field.field.widget.attrs['category'])
    if category.name in categories_with_error:
        return 'in'
    return ''


@staticmethod
def is_valid(control_instance, *args, **kwargs):
    """ Method to check if the new control value is correct.

        Parameters
        ----------
        control_instance: QCheckBox (mandatory)
            the control widget we want to validate

        Returns
        -------
        out: bool
            always True since the control value is always valid
        """
    return True


def show_matching_files(matching_files: list, tag: str) ->None:
    """Print the list of matching files. Or a notification if there were no results."""
    if matching_files is None:
        msg = 'No matching files with "{}" tag.\n\nMisspelled? or inexistent?'
        msg = msg.format(tag)
        print(msg)
        return
    msg = '{} matching files under tag "{}":'
    print(msg.format(len(matching_files), tag))
    for f in matching_files:
        print('\t{}'.format(f))


def _disabled_method(*_):
    """Disabled method."""
    raise AttributeError


def _edge_generator_from_csr(csr_matrix):
    """Yield weighted edge triples for use by NetworkX from a CSR matrix.

    This function is a straight rewrite of
    `networkx.convert_matrix._csr_gen_triples`. Since that is a private
    function, it is safer to include our own here.

    Parameters
    ----------
    csr_matrix : scipy.sparse.csr_matrix
        The input matrix. An edge (i, j, w) will be yielded if there is a
        data value for coordinates (i, j) in the matrix, even if that value
        is 0.

    Yields
    ------
    i, j, w : (int, int, float) tuples
        Each value `w` in the matrix along with its coordinates (i, j).

    Examples
    --------

    >>> dense = np.eye(2, dtype=np.float)
    >>> csr = sparse.csr_matrix(dense)
    >>> edges = _edge_generator_from_csr(csr)
    >>> list(edges)
    [(0, 0, 1.0), (1, 1, 1.0)]
    """
    nrows = csr_matrix.shape[0]
    values = csr_matrix.data
    indptr = csr_matrix.indptr
    col_indices = csr_matrix.indices
    for i in range(nrows):
        for j in range(indptr[i], indptr[i + 1]):
            yield i, col_indices[j], values[j]


def compile_VICASCII_Livneh2015_locations(maptable):
    """
    Compile the list of file URLs for Livneh et al., 2015 VIC.ASCII outputs

    maptable: (dataframe) a dataframe that contains the FID, LAT, LONG_, and ELEV for each interpolated data file
    """
    domain = '192.12.137.7'
    subdomain = '/pub/dcp/archive/OBS/livneh2014.1_16deg/VIC.ASCII'
    locations = []
    for ind, row in maptable.iterrows():
        loci = '_'.join(['Fluxes_Livneh_NAmerExt_15Oct2014', str(row['LAT']
            ), str(row['LONG_'])])
        url = '/'.join(['ftp://' + domain + subdomain, 'latitude.' + str(
            row['LAT']), loci + '.bz2'])
        locations.append(url)
    return locations


@staticmethod
def _checkDepth(z, dep_lays_choose):
    """
        TODO: Add docstring

        """
    if z > dep_lays_choose[-1]:
        return -1
    else:
        k = ((z - dep_lays_choose) ** 2).argmin()
        return k


@staticmethod
def get_count(df, col_id):
    """
        Count the unique ids in col_id of df
        ------------
        :param df: encoded pandas Dataframe
        :param col_id: name of the column in df
        :return count: number of different values in col_id of df
        """
    list_unique_id = df[[col_id]].groupby(col_id, as_index=False)
    count = list_unique_id.size()
    return count


def _plots_first(fname):
    """Decorate filename so that examples with plots are displayed first."""
    if not (fname.startswith('plot') and fname.endswith('.py')):
        return 'zz' + fname
    return fname


@classmethod
def set_failed(cls, task_id, exception):
    """Mark task as failed after run - called by simulator.

        :param task_id: an ID of task that should be marked as failed
        :param exception: exception raised in task
        """
    cls.task_failures[task_id] = exception


@staticmethod
def _bar_size(length: int, current: int, total: int) ->int:
    """Return the number of bars to draw"""
    return int(current * length / float(total))


@staticmethod
def run(pathfmt):
    """Execute the postprocessor for a file"""


def system_from_snapshot(system, snapshot):
    """Create a system from a given snapshot."""
    system_copy = system.copy()
    system_copy.particles.ekin = snapshot.get('ekin', None)
    system_copy.particles.vpot = snapshot.get('vpot', None)
    system_copy.order = snapshot.get('order', None)
    system_copy.particles.set_pos(snapshot.get('pos', None))
    system_copy.particles.set_vel(snapshot.get('vel', None))
    return system_copy


def load_numpy_distutils_system_info(finder, module):
    """the numpy.distutils.system_info module optionally imports the Numeric
       module; ignore the error if the module cannot be found."""
    module.IgnoreName('Numeric')


def call_with_or_without_args(def_to_call, dv_args):
    """
	Helper for def return_when_def_is_true.
	This def checks dv_args and if its value is None,
	it calls param def_to_call without any arguments,
	otherside calls with dv_args as param list,
	key=paramater name, value=paramater value.
	"""
    if dv_args is None:
        return def_to_call()
    else:
        return def_to_call(**dv_args)


def device_list():
    """
    device_list() returns available devices for acceleration as a tuple.
    If no device is available, it returns an empty tuple.
    """
    from reikna import cluda
    import reikna.transformations
    from reikna.cluda import functions, dtypes
    devices_list = ()
    try:
        api = cluda.cuda_api()
        available_cuda_device = cluda.find_devices(api)
        cuda_flag = 1
        for api_n in available_cuda_device.keys():
            cuda_gpus = available_cuda_device[api_n]
            for dev_num in cuda_gpus:
                id = available_cuda_device[api_n][dev_num]
                platform = api.get_platforms()[api_n]
                device = platform.get_devices()[id]
                thr = api.Thread(device)
                wavefront = api.DeviceParameters(device).warp_size
                devices_list += ('cuda', api_n, dev_num, platform, device,
                    thr, wavefront),
    except:
        pass
    try:
        api = cluda.ocl_api()
        available_ocl_device = cluda.find_devices(api)
        ocl_flag = 1
        for api_n in available_ocl_device.keys():
            ocl_gpus = available_ocl_device[api_n]
            for dev_num in ocl_gpus:
                id = available_ocl_device[api_n][dev_num]
                platform = api.get_platforms()[api_n]
                device = platform.get_devices()[id]
                thr = api.Thread(device)
                wavefront = api.DeviceParameters(device).warp_size
                devices_list += ('ocl', api_n, dev_num, platform, device,
                    thr, wavefront),
    except:
        pass
    return devices_list


def lexicon_names(lexicons):
    """Yield the names of the lexicons with the language removed if
    that is the same as the previous lexicon's language.

    """
    curlang = None
    for l in lexicons:
        fullname = repr(l)
        lang, name = fullname.split('.')
        if lang == curlang:
            yield name
        else:
            yield fullname
            curlang = lang


def get_key_by_value(dict_, value):
    """Return key by value."""
    for key, val in dict_.items():
        if value == val:
            return key
    return None


def nameInternalNodes(tree):
    """Given a bio python tree without named internal nodes, name
them. This obliterates anything names that might have been inside
already (e.g. if confidence values have been put in the name field)."""
    for j, n in enumerate(tree.get_nonterminals()):
        n.name = 'i' + str(j)
    return tree


def is_compatible(wheel, tags=None):
    """ Hacked function to monkey patch into distlib """
    return True


def allFuncs(funcs, *args):
    """Returns True if all functions in 'funcs' return True."""
    for f in funcs:
        if callable(f) and not f(*args):
            return False
    return True


def Access(NewType, Accessed):
    """
	Return code for VHDL Access declaration of type pointer.
	"""
    return '\ntype {0} is access {1};'.format(NewType, Accessed)


def ensure_tuple(val):
    """If val is not a tuple, make it a 1-tuple containing val.

    This is useful for uniform processing of Lua output which can be either a
    single value or a tuple of values.

    """
    if not isinstance(val, tuple):
        return val,
    return val


def finish():
    """When the CiphertextDownloader is done, this finish() function will be
        called. Whatever it returns will be returned to the invoker of
        Downloader.download.
        """


def is_interactive():
    """ determine if script is being run within a jupyter notebook or as a script """
    import __main__ as main
    return not hasattr(main, '__file__')


@staticmethod
def esc_(string):
    """ fix strings for use as names in classes """
    if string == 'id':
        return 'id_'
    elif string == 'def':
        return 'def_'
    return string.replace('-', '_').replace(':', '')


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


def fromBasicServiceEndpoint(endpoint):
    """Trivial transform from a basic endpoint to itself. This
        method exists to allow BasicServiceEndpoint to be used as a
        filter.

        If you are subclassing this object, re-implement this function.

        @param endpoint: An instance of BasicServiceEndpoint
        @return: The object that was passed in, with no processing.
        """
    return endpoint


def implemented_by(interface, cls):
    """
        Check if class claims to provide the interface.

        Note that classes that implement the :py:class:`.DynamicInterface`
        interface cannot dynamically claim to `implement` an interface,
        although individual instances can claim to `provide` an interface.

        :return bool: :py:obj:`True` if interface is implemented by the class,
            else :py:obj:`False`.
        """
    return issubclass(cls, interface._verified) or issubclass(cls,
        interface._unverified)


def make_rr_subparser(subparsers, rec_type, args_and_types):
    """
    Make a subparser for a given type of DNS record
    """
    sp = subparsers.add_parser(rec_type)
    sp.add_argument('name', type=str)
    sp.add_argument('ttl', type=int, nargs='?')
    sp.add_argument(rec_type, type=str)
    for my_spec in args_and_types:
        argname, argtype = my_spec[:2]
        if len(my_spec) > 2:
            nargs = my_spec[2]
            sp.add_argument(argname, type=argtype, nargs=nargs)
        else:
            sp.add_argument(argname, type=argtype)
    return sp


def max_column_width(column):
    """
    Max width of a column, looping over all column elements
    """
    return column.apply(lambda x: len(str(x))).max()


@classmethod
def all_features(cls):
    """
        All new features for this game. Usually just the Map Name, and
        you don't need to touch this. If your map implements new features for
        side_info, then define a classmethod with the new features only.
        """
    return ['GAME', 'INFO', cls.__name__, '']


def replace_null(df, value, columns='*'):
    """
    Replace nulls with specified value.

    Parameters
    ----------
    columns   : optional list of column names to consider. Columns specified in subset that do not have
                matching data type are ignored. For example, if value is a string, and subset contains a non-string column,
                then the non-string column is simply ignored.
    value     : Value to replace null values with. If the value is a dict, then subset is ignored and value
                must be a mapping from column name (string) to replacement value. The replacement
                value must be an int, long, float, or string.

    return df : dataframe with replaced null values.
    """
    if columns == '*':
        columns = None
    if isinstance(columns, str):
        columns = [columns]
    if columns is not None:
        assert isinstance(columns, list
            ), 'Error: columns argument must be a list'
    assert isinstance(value, (int, float, str, dict)
        ), 'Error: value argument must be an int, long, float, string, or dict'
    return df.fillna(value, subset=columns)


def _offset(value):
    """Parse timezone to offset in seconds.

    Args:
        value: A timezone in the '+0000' format. An integer would also work.

    Returns:
        The timezone offset from GMT in seconds as an integer.
    """
    o = int(value)
    if o == 0:
        return 0
    a = abs(o)
    s = a * 36 + a % 100 * 24
    return o // a * s


def _set_description(ctx):
    """Sets document description.

    """
    if len(ctx.doc.reports) and ctx.doc.reports[0].measure is not None:
        ctx.ext.description = ctx.doc.reports[0].measure.name


@classmethod
def from_string(cls, s):
    """Convert string representation of range to instance of `cls`."""
    args = cls.args_from_string(s)
    if args:
        return cls(*args)


def _stop_times_definitions(df):
    """
    Append GTFS definitions for stop time columns to stop time dataframe

    Parameters
    ----------
    df : pandas:DataFrame
        stop time dataframe

    Returns
    -------
    df : pandas.DataFrame
    """
    if 'pickup_type' in df.columns:
        stop_times_pickup_type = {(0): 'Regularly Scheduled', (1):
            'Not available', (2): 'Phone arrangement only', (3):
            'Driver arrangement only'}
        df['pickup_type_desc'] = df['pickup_type'].map(stop_times_pickup_type
            .get)
    if 'drop_off_type' in df.columns:
        stop_times_drop_off_type = {(0): 'Regularly Scheduled', (1):
            'Not available', (2): 'Phone arrangement only', (3):
            'Driver arrangement only'}
        df['drop_off_type_desc'] = df['drop_off_type'].map(
            stop_times_drop_off_type.get)
    if 'timepoint' in df.columns:
        stop_times_timepoint = {'': 'Exact times', (0): 'Approximate times',
            (1): 'Exact times'}
        df['timepoint_desc'] = df['timepoint'].map(stop_times_timepoint.get)
    return df


def check_word(word):
    """
    Returns True if word is not valid.
    Returns False if word passes all inspections (is valid).
    """
    if len(word) > 16:
        return True
    else:
        return False


def iscoord(coord):
    """Checks if a value can be associated with a coordinate.

    Parameters
    ----------
    coord : array_like
        Value associated with a coordinate.

    Returns
    -------
    bool
        Indicates whether or not the value is a coordinate.

    """
    return hasattr(coord, '__len__') and len(coord) > 0 and not hasattr(coord
        [0], '__len__')


@classmethod
def pk_filter(cls, value=None):
    """Creates a primary key filter for the given model.

        :param value: primary key value
        :return: primary key filter
        :rtype: dict
        """
    return {cls.PK_NAME: value}


def release_workers_early(mpi_comm):
    """
    Signal to workers to abort before simulations.

    :param mpi_comm: MPI communicator object
    :return: None
    """
    mpi_comm.bcast(None, root=0)


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

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

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


def helpmessage():
    """Return help message."""
    message = '246 : In the cell of row 2 column 4, put number 6\n'
    message += 'b   : take Back one move\n'
    message += 'c   : show Current position\n'
    message += 'i   : show hInt for current position\n'
    message += 'q   : Quit kaidoku\n\n'
    message += '[Select problem]\n'
    message += 'j num  : Jump to problem num\n'
    message += 'n      : Next problem\n'
    message += 'p      : Previous problem\n'
    message += 'l level: change Level\n'
    message += 'book   : show index of the book\n\n'
    message += '[Help]\n'
    message += 'h  : show this Help\n'
    message += 'ha : show Help for Advanced commands'
    return message


def get_package_info(pkgs):
    """ get package versions for the passed required & optional packages.

    Using local imports to avoid import overhead on interpreter startup.
    """
    import importlib
    pversions = []
    for modname, ver_f in pkgs:
        try:
            mod = importlib.import_module(modname)
            ver = ver_f(mod)
            pversions.append((modname, ver))
        except Exception:
            pversions.append((modname, None))
    return pversions


def powOfTwo(x):
    """Return 2 raised to the power of x."""
    return 2 ** x


def dm2dd(degrees, minutes, cardinal):
    """convert coordinate format with degrees and minutes to degrees"""
    dd = degrees + minutes / 60.0
    if cardinal in ('S', 'W'):
        dd *= -1
    return dd


@classmethod
def stepOver(cls):
    """Steps over the statement.
        """
    return cls.build_send_payload('stepOver', {}), None


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

    The ".dev0" means dirty.

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


def dt_dt(sdat, tstart=None, tend=None):
    """Derivative of temperature.

    Compute dT/dt as a function of time using an explicit Euler scheme.

    Args:
        sdat (:class:`~stagpy.stagyydata.StagyyData`): a StagyyData instance.
        tstart (float): time at which the computation should start. Use the
            beginning of the time series data if set to None.
        tend (float): time at which the computation should end. Use the
            end of the time series data if set to None.
    Returns:
        tuple of :class:`numpy.array`: derivative of temperature and time
        arrays.
    """
    tseries = sdat.tseries_between(tstart, tend)
    time = tseries['t'].values
    temp = tseries['Tmean'].values
    dtdt = (temp[1:] - temp[:-1]) / (time[1:] - time[:-1])
    return dtdt, time[:-1]


def project_opened(project):
    """This function is called after opening the project"""


def transform_aabb(transform, aabb):
    """
    Apply a transformation to an axis aligned bounding box.

    The result is a new AABB in the same coordinate system as the original AABB.
    The new AABB contains all corner points of the original AABB after applying the given transformation.

    Args
        transform: The transformation to apply.
        x1:        The minimum x value of the AABB.
        y1:        The minimum y value of the AABB.
        x2:        The maximum x value of the AABB.
        y2:        The maximum y value of the AABB.
    Returns
        The new AABB as tuple (x1, y1, x2, y2)
    """
    x1, y1, x2, y2 = aabb
    points = transform.dot([[x1, x2, x1, x2], [y1, y2, y2, y1], [1, 1, 1, 1]])
    min_corner = points.min(axis=1)
    max_corner = points.max(axis=1)
    return [min_corner[0], min_corner[1], max_corner[0], max_corner[1]]


def fix_percentages_in_axis_description_for_latex(frame):
    """
    When attempting to display the output of pandas describe() as a latex
    table, the % sign will cause errors. This replaces it with 'th'
    """
    return frame.rename_axis({'25%': '25th', '50%': '50th', '75%': '75th'})


@classmethod
def from_pem_data(cls, data=None, filename=None):
    """Alternative constructor for loading from PEM format data."""
    msg = 'PEM data loading is not implemented for pure-python crypto.'
    msg += '  Please install M2Crypto to access this functionality.'
    raise NotImplementedError(msg)


def getlineno(frame):
    """Get the line number from a frame object, allowing for optimization."""
    return frame.f_lineno


def default_handler(e):
    """Exception handler for IPOPT ctypes callbacks, prints the traceback."""
    import traceback
    traceback.print_exc()


def calcuInbreedCoeff(gt):
    """
    Calculating the inbreeding coefficient by GT fields of VCF.

    Args:
        `gt`: A list. Genotype fields of all the samples.
    """
    ref_count, het_count, hom_count, n = 0, 0, 0, 0
    for g in gt:
        gs = g.split('/') if '/' in g else g.split('|')
        if '.' not in g:
            n += 1
        if '.' in g:
            pass
        elif g == '0/0' or g == '0|0':
            ref_count += 1
        elif gs[0] == gs[1]:
            hom_count += 1
        else:
            het_count += 1
    if n == 0:
        n = 1
    p = (2.0 * ref_count + het_count) / (2.0 * n)
    q = 1.0 - p
    expected_het_count = 2.0 * p * q * n if p * q > 0 else 1
    inbf = 1.0 - het_count / expected_het_count
    return inbf


def scan_setup_py():
    """Validate the contents of setup.py against Versioneer's expectations."""
    found = set()
    setters = False
    errors = 0
    with open('setup.py', 'r') as f:
        for line in f.readlines():
            if 'import versioneer' in line:
                found.add('import')
            if 'versioneer.get_cmdclass()' in line:
                found.add('cmdclass')
            if 'versioneer.get_version()' in line:
                found.add('get_version')
            if 'versioneer.VCS' in line:
                setters = True
            if 'versioneer.versionfile_source' in line:
                setters = True
    if len(found) != 3:
        print('')
        print('Your setup.py appears to be missing some important items')
        print('(but I might be wrong). Please make sure it has something')
        print('roughly like the following:')
        print('')
        print(' import versioneer')
        print(' setup( version=versioneer.get_version(),')
        print('        cmdclass=versioneer.get_cmdclass(),  ...)')
        print('')
        errors += 1
    if setters:
        print("You should remove lines like 'versioneer.VCS = ' and")
        print("'versioneer.versionfile_source = ' . This configuration")
        print('now lives in setup.cfg, and should be removed from setup.py')
        print('')
        errors += 1
    return errors


def clearobscaches(repo):
    """Remove all obsolescence related cache from a repo

    This remove all cache in obsstore is the obsstore already exist on the
    repo.

    (We could be smarter here given the exact event that trigger the cache
    clearing)"""
    if b'obsstore' in repo._filecache:
        repo.obsstore.caches.clear()


@classmethod
def load(cls, partname, content_type, blob, package):
    """
        Called by ``docx.opc.package.PartFactory`` to load an image part from
        a package being opened by ``Document(...)`` call.
        """
    return cls(partname, content_type, blob)


def convertToRowAndColumn(x, y, shape, xScale=None, yScale=None, safe=True):
    """Return (row, column) of a pixel defined by (x, y) in an image.

    :param float x: Abscissa of point
    :param float x: Ordinate of point
    :param shape: Shape of image (nRows, nColumns)
    :param xScale: Tuple of linear scaling parameters (a, b),
        x = a + b * column
    :param yScale: Tuple of linear scaling parameters (a, b),
        y = a + b * row
    :param bool safe: If True, always return coordinates within the image's
        bounds.
    :return: 2-tuple (r, c)
    """
    if xScale is None:
        c = x
    else:
        c = (x - xScale[0]) / xScale[1]
    if yScale is None:
        r = y
    else:
        r = (y - yScale[0]) / yScale[1]
    if safe:
        c = min(int(c), shape[1] - 1)
        c = max(c, 0)
        r = min(int(r), shape[0] - 1)
        r = max(r, 0)
    else:
        c = int(c)
        r = int(r)
    return r, c


def add_intercept_to_dataframe(specification, dataframe):
    """
    Checks whether `intercept` is in `specification` but not in `dataframe` and
    adds the required column to dataframe. Note this function is not
    idempotent--it alters the original argument, `dataframe`.

    Parameters
    ----------
    specification : an iterable that has a `__contains__` method.
    dataframe : pandas DataFrame.
        Dataframe containing the data for the choice model to be estimated.

    Returns
    -------
    None.
    """
    if 'intercept' in specification and 'intercept' not in dataframe.columns:
        dataframe['intercept'] = 1.0
    return None


def changeSegment(filename, detector, segment):
    """Replace '_a' with '_b' or vice versa, if appropriate.

    This was written for auto/GO wavecal file names for FUV data.  Wavecals
    are processed from the x1d file, and the name of the raw file is for
    the first segment in the input list (which will be FUVA if both segments
    are present).  When calibrating segment B data, the name or names of
    the wavecal files need to be changed to end in "_b.fits" instead of
    "_a.fits".

    Parameters
    ----------
    filename: str
        One or more file names, separated by spaces

    detector: str
        FUV or NUV

    segment: str
        FUVA or FUVB, if detector is FUV

    Returns
    -------
    str
        A copy of the input filename, but with '_a' replaced with '_b'
        or vice versa, or no change if the input name does not end in
        '_a.fits' or '_b.fits'
    """
    if detector != 'FUV':
        return filename
    if segment == 'FUVB':
        names = filename.split()
        new_names = []
        for name in names:
            if name.endswith('_a.fits'):
                n = len(name) - 7
                name = name[:n] + '_b.fits'
            new_names.append(name)
        filename = ' '.join(new_names)
    elif segment == 'FUVA':
        names = filename.split()
        new_names = []
        for name in names:
            if name.endswith('_b.fits'):
                n = len(name) - 7
                name = name[:n] + '_a.fits'
            new_names.append(name)
        filename = ' '.join(new_names)
    return filename


@staticmethod
def relaxed_constraints():
    """Hook for subtypes to add relaxed constraints for retry
           logic"""
    return []


def subcommand_dispatcher(subcommand, args):
    """ Calls the corresponding subcommand dispatcher

    """
    return globals()['%s_dispatcher' % subcommand.replace('-', '_')](args)


def flatten_binary_scores(scores, labels, ignore=None):
    """
    Flattens predictions in the batch (binary case)
    Remove labels equal to 'ignore'
    """
    scores = scores.view(-1)
    labels = labels.view(-1)
    if ignore is None:
        return scores, labels
    valid = labels != ignore
    vscores = scores[valid]
    vlabels = labels[valid]
    return vscores, vlabels


def _get_wf_name(dwi_fname):
    """Derive the workflow name based on the output file prefix."""
    spl = dwi_fname.split('_')
    nosub = '_'.join(spl[1:])
    return ('dwi_preproc_' + nosub + '_wf').replace('__', '_').replace('-', '_'
        )


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

        :param MemberSpaceLimitsRemoveExceptionDetails val:
        :rtype: EventDetails
        """
    return cls('member_space_limits_remove_exception_details', val)


@staticmethod
def _get_name_from_dn(dn):
    """
        Get the instance name from the dn

        :param dn: string containing the distinguished name URL
        :return: string containing the name
        """
    name = dn.split('/psu-')[1].split('/')[0]
    return name


@classmethod
def remove_dirs(cls, loader_name):
    """Remove search directories for a loader."""
    cls.dirs.pop(loader_name)


def recovery_routine():
    """Revert configuration to most recent finalized checkpoint.

        Remove all changes (temporary and permanent) that have not been
        finalized. This is useful to protect against crashes and other
        execution interruptions.

        :raises .errors.PluginError: If unable to recover the configuration

        """


def get_bigram_scores(text_words, min_bgfreq=2.0):
    """
    compute scores for identifying bigrams in a collection of texts
    compute unigram and bigram frequencies (of words) and give a score for every bigram.
    depending on this score (e.g. if higher than a threshold), bigram phrases can be identified
    in the raw texts before splitting them into words
    --> once the lists of words in the text_words are replaced by appropriate bigrams, the whole thing could be repeated
        to find trigrams, etc.
    Input:
        - text_words: a list (or generator) of lists of (preprocessed) words
        - min_bgfreq: how often a bigram has to have to occur in the corpus to be recognized (if both words occur just once
                      and that in combination, it still doesn't mean it's a true phrase because we have too little observations of the words
    Returns:
        - bigram_scores: a dict with bigrams ("word1 word2") and their score
    """
    unigram_freq = {}
    bigram_freq = {}
    for wordlist in text_words:
        for i, word in enumerate(wordlist):
            try:
                unigram_freq[word] += 1.0
            except KeyError:
                unigram_freq[word] = 1.0
            if i:
                try:
                    bigram_freq['%s %s' % (wordlist[i - 1], word)] += 1.0
                except KeyError:
                    bigram_freq['%s %s' % (wordlist[i - 1], word)] = 1.0
    bigram_scores = {}
    for bigram in bigram_freq:
        if max(0.0, bigram_freq[bigram] - min_bgfreq):
            bigram_scores[bigram] = bigram_freq[bigram] / max(unigram_freq[
                bigram.split()[0]], unigram_freq[bigram.split()[1]])
    return bigram_scores


def get_dict_for_attrs(obj, attrs):
    """
    Returns dictionary for each attribute from given ``obj``.
    """
    data = {}
    for attr in attrs:
        data[attr] = getattr(obj, attr)
    return data


def get(key, default=None):
    """
        Get given key.  If not found, return default.
        """


def get_pseudos_of_calc(calc):
    """Return a dictionary of pseudos used by a given (pw.x, cp.x) calculation.

    This returns a dictionary ``pseudos`` that can be set in a builder as ``builder.pseudo = pseudos``.

    :param calc: a pw.x or cp.x calculation.
    :return: a dictionary where the key is the kind name and the value is the UpfData object.
    """
    from aiida.common.links import LinkType
    pseudos = {}
    inputs = calc.get_incoming(link_type=LinkType.INPUT_CALC)
    for linkname in inputs.keys():
        if linkname.startswith(calc._get_linkname_pseudo_prefix()):
            multiplekindstring = linkname[len(calc.
                _get_linkname_pseudo_prefix()):]
            pseudos[multiplekindstring] = inputs[linkname]
    return pseudos


def _cmpPair2(a, b):
    """Auxiliary comparision for sorting lists of pairs. Sorting on the second member of the pair."""
    (x, y), (z, w) = a, b
    if y < w:
        return -1
    elif y > w:
        return 1
    elif x < z:
        return -1
    elif x > z:
        return 1
    else:
        return 0


def old_str_format_to_new(string):
    """
    convert old format style to new style. Works for digits only
    %05d is converted to {:05d}
    :param string:
    :return:
    """
    import re
    return re.sub('%(\\d*d)', '{:\\1}', string)


def get_all(isamAppliance, check_mode=False, force=False):
    """
    Get all logdb objects
    """
    return isamAppliance.invoke_get('Get all logdb objects',
        '/core/rsp_logdb_objs')


def get_fn_list_fn(target):
    """ Returns the filename of the storage pickle for all the filenames used by the code

      :param target: name of the target/object to be processed
      :type target: string

      :return: the pickled dictionary filename
      :rtype: string
   """
    return 'bifus_fn-list_%s.pkl' % target


@classmethod
def from_seednode_metadata(cls, seednode_metadata, *args, **kwargs):
    """
        Essentially another deserialization method, but this one doesn't reconstruct a complete
        node from bytes; instead it's just enough to connect to and verify a node.

        NOTE: This is a federated only method.
        """
    seed_uri = (
        f'{seednode_metadata.checksum_address}@{seednode_metadata.rest_host}:{seednode_metadata.rest_port}'
        )
    return cls.from_seed_and_stake_info(*args, seed_uri=seed_uri, **kwargs)


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 alias(alias):
    """Select a single alias."""
    return {'alias': alias}


@classmethod
def _from_iterable(cls, it):
    """Construct an instance of the class from any iterable input.

        Must override this method if the class constructor signature
        does not accept an iterable for an input.
        """
    return cls(it)


def from_fahrenheit(fahrenheit):
    """Convert Fahrenheits to Centigrade."""
    return (fahrenheit - 32) * 5 / 9


def get_distance(pos1, pos2):
    """
    Given two X, Y, Z centers in format from output of get_center() function
    using standard three dimensional distance formula:

    square root (X^2 + Y^2 + Z^2)

    :param pos1: string of format 'X, Y, Z' Where X, Y, Z are numbers
    :param pos2: string of format 'X, Y, Z' Where X, Y, Z are numbers
    :return: distance as a float
    """
    _dist_0 = float(pos1.split(',')[0]) - float(pos2.split(',')[0])
    _dist_1 = float(pos1.split(',')[1]) - float(pos2.split(',')[1])
    _dist_2 = float(pos1.split(',')[2]) - float(pos2.split(',')[2])
    return (_dist_0 ** 2 + _dist_1 ** 2 + _dist_2 ** 2) ** 0.5


def claim_delete(transport, request, queue_name, claim_id):
    """Deletes a Claim `claim_id`

    :param transport: Transport instance to use
    :type transport: `transport.base.Transport`
    :param request: Request instance ready to be sent.
    :type request: `transport.request.Request`
    """
    request.operation = 'claim_delete'
    request.params['queue_name'] = queue_name
    request.params['claim_id'] = claim_id
    transport.send(request)


@classmethod
def from_dict(cls, d):
    """Load a Name from a dictionary."""
    nameparts = d['nameparts']
    name = cls(nameparts, d['authority'])
    if 'hybrid' in d:
        name.hybrid = d['hybrid']
    return name


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


def job_file_directory(instance, filename):
    """ Submitted job input files """
    return 'jobs/{0}/{1}'.format(str(instance.job.slug), filename)


def conditional_write(strm, fmt, value, *args, **kwargs):
    """Write to stream using fmt and value if value is not None"""
    if value is not None:
        strm.write(fmt.format(value, *args, **kwargs))


def draw():
    """Continuously execute code defined inside.

    The `draw()` function is called directly after `setup()` and all
    code inside is continuously executed until the program is stopped
    (using `exit()`) or `no_loop()` is called.

    """
    pass


@staticmethod
def to_dict(source):
    """
        Converts to a dictionary data.
        """
    try:
        return int(source)
    except ValueError:
        return None


def only_numbers(char):
    """  Validation entry widgets: only digits """
    return char.isdigit()


def get_user_id(user):
    """Return id attribute of the object if it is relation, otherwise return given value."""
    return user.id if type(user).__name__ == 'User' else user


@staticmethod
def _compute_float_overlapping(tile_size, image_size, n):
    """Method to float overlapping
        """
    return (tile_size * n - image_size) * 1.0 / (n - 1.0) if n > 1 else 0


def create_ami_from_instance(ec2client, instance, name, description,
    fingerprint):
    """Create an AMI from a running instance.

    Returns the ``ec2resource.Image`` representing the created AMI.
    """
    instance.stop()
    ec2client.get_waiter('instance_stopped').wait(InstanceIds=[instance.id],
        WaiterConfig={'Delay': 5})
    print('%s is stopped' % instance.id)
    image = instance.create_image(Name=name, Description=description)
    image.create_tags(Tags=[{'Key': 'HGIMAGEFINGERPRINT', 'Value':
        fingerprint}])
    print('waiting for image %s' % image.id)
    ec2client.get_waiter('image_available').wait(ImageIds=[image.id])
    print('image %s available as %s' % (image.id, image.name))
    return image


def args_display(p):
    """options to format the display"""
    g = p.add_argument_group('Display')
    g.add_argument('-D', dest='showdb', action='store_false', help=
        'show just the object name without database prefix')
    x = g.add_mutually_exclusive_group()
    x.add_argument('-i', '--impact', dest='sizecol', action='store_const',
        const='ImpactSize', default='TableSize', help='use impact size')
    x.add_argument('-w', '--waste', dest='sizecol', action='store_const',
        const='WastedSize', help='use wasted size')
    g.add_argument('-c', dest='create', action='store_true', help=
        'use create instead of modified time for display/sort')
    from .util import args_size
    args_size(g)


def _security_filters(requirements):
    """Produce set of filters associated with the security requirements."""
    result = set()
    for requirement in (requirements or []):
        scheme = getattr(requirement, 'scheme', None)
        if scheme:
            filter = getattr(scheme, 'filter', None)
            if filter:
                result.add(filter)
    return result


def lambd_H3PO4_K_PS76(T, P):
    """n-c: phosphoric-acid potassium [PS76]."""
    lambd = -0.07
    valid = T == 298.15
    return lambd, valid


@classmethod
def filter(cls, key, value, operator):
    """
        Adds a filter to the current query
        """
    column = getattr(cls, key)
    if isinstance(value, list):
        return cls.q.where(column.in_(value))
    if operator == '!':
        return cls.q.where(column != value)
    elif operator == '>':
        return cls.q.where(column > value)
    elif operator == '<':
        return cls.q.where(column < value)
    elif operator == '~':
        return cls.q.where(column.startswith(value))
    return cls.q.where(column == value)


def is_tomodir(subdirectories):
    """provided with the subdirectories of a given directory, check if this is
    a tomodir
    """
    required = 'exe', 'config', 'rho', 'mod', 'inv'
    is_tomodir = True
    for subdir in required:
        if subdir not in subdirectories:
            is_tomodir = False
    return is_tomodir


def parse_help(help_str):
    """
    Auto parses the help dialogs provided by developers in the doc strings.
    This is denoted by helpme - text and then a blank line.

    e.g.

    Function doc string
    helpme - more end user friendly message about what this will do

    my arguments...

    """
    result = None
    if help_str != None:
        if 'helpme' in help_str:
            z = help_str.split('helpme')
            result = z[-1].split('-')[-1].strip()
    return result


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

    """
    pass


@classmethod
def detect(cls, old_config, new_config):
    """Return experiment name conflict no matter what

        Branching event cannot be triggered experiment name is not the same.
        """
    yield cls(old_config, new_config)


def TemperatureConverter(temperature, direction=1):
    """
	direction 1: from fahrenheit to celsius
	direction 2: from celsius to fahrenheit
	"""
    temp = float(temperature)
    if direction == 1:
        print('Convert Fahrenheit to Celsius')
        result = (temp - 32) * 5 / 9
    elif direction == 2:
        print('COnvert Celsius to Fahrenheit')
        result = 9 * temp / 5 + 32
    else:
        raise ValueError('Direction is type of integer in 1 or 2')
    return round(result, 1)


def flavor_get(transport, request, flavor_name, callback=None):
    """Gets flavor data

    :param transport: Transport instance to use
    :type transport: `transport.base.Transport`
    :param request: Request instance ready to be sent.
    :type request: `transport.request.Request`
    :param flavor_name: Flavor reference name.
    :type flavor_name: `six.text_type`

    """
    request.operation = 'flavor_get'
    request.params['flavor_name'] = flavor_name
    resp = transport.send(request)
    return resp.deserialized_content


def get_odd_integer(x):
    """
    Return the ceiling odd integer given a float

    Parameters
    ----------
    x : float
        The number to be converted to the closest odd integer

    Returns
    -------
    y : int
        Odd integer of x
    """
    return int(round(round(x) / 2) * 2) + 1


def load_options_files(fname):
    """
    Load options for a Fabber run from an .fab options file

    :param fname: File name of options file
    """
    options = {}
    with open(fname, 'r') as fabfile:
        for line in fabfile.readlines():
            line = line.strip()
            if line and line[0] != '#':
                keyval = line.split('=', 1)
                key = keyval[0].strip()
                if len(keyval) > 1:
                    value = keyval[1].strip()
                else:
                    value = True
                options[key] = value
    return options


def t_ALWAYS_BROADCAST(t):
    """always-broadcast"""
    return t


def p_stringliteral(p):
    """stringliteral : STRPREFIX SHORTSTRING
                     | STRPREFIX LONGSTRING
                     | SHORTSTRING
                     | LONGSTRING"""
    if len(p) == 3:
        p[0] = p[1] + p[2]
    else:
        p[0] = p[1]


def check_setattr(ob, name):
    """
        Check whether attribute assignment is allowed.

        If a checker implements ``__setitem__``, then ``__setitem__``
        will be called rather than ``check`` to ascertain whether an
        operation is allowed. This is a hack that allows significantly
        greater performance due to the fact that low-level operator
        access is much faster than method access.

        :raises: :class:`Unauthorized`
        :raises: :class:`Forbidden`
        :return: Nothing
        """


def isunauthenticated(func):
    """Checks if the function does not require authentication.

    Mark such functions with the `@unauthenticated` decorator.

    :returns: bool
    """
    return getattr(func, 'unauthenticated', False)


@classmethod
def run(cls, excl_fpath, tm_dset, sc_point_method, excl_dict=None,
    area_filter_kernel='queen', min_area=None, check_excl_layers=False,
    resolution=64, gids=None, args=None, kwargs=None, max_workers=None,
    chunk_point_len=1000):
    """Get the supply curve points aggregation summary.

        Parameters
        ----------
        excl_fpath : str
            Filepath to exclusions h5 with techmap dataset.
        tm_dset : str
            Dataset name in the techmap file containing the
            exclusions-to-resource mapping data.
        sc_point_method : method
            Supply Curve Point Method to operate on a single SC point.
        excl_dict : dict | None
            Dictionary of exclusion LayerMask arugments {layer: {kwarg: value}}
        area_filter_kernel : str
            Contiguous area filter method to use on final exclusions mask
        min_area : float | None
            Minimum required contiguous area filter in sq-km
        check_excl_layers : bool
            Run a pre-flight check on each exclusion layer to ensure they
            contain un-excluded values
        resolution : int | None
            SC resolution, must be input in combination with gid. Prefered
            option is to use the row/col slices to define the SC point instead.
        gids : list | None
            List of gids to get summary for (can use to subset if running in
            parallel), or None for all gids in the SC extent.
        sc_point_method : method
            Supply Curve Point Method to operate on a single SC point.
        args : list | None
            List of positional args for sc_point_method
        kwargs : dict | None
            Dict of kwargs for sc_point_method
        max_workers : int | None
            Number of cores to run summary on. None is all
            available cpus.
        chunk_point_len : int
            Number of SC points to process on a single parallel worker.

        Returns
        -------
        summary : DataFrame
            Summary of the SC points.
        """
    agg = cls(excl_fpath, tm_dset, excl_dict=excl_dict, area_filter_kernel=
        area_filter_kernel, min_area=min_area, check_excl_layers=
        check_excl_layers, resolution=resolution, gids=gids)
    aggregation = agg.aggregate(sc_point_method, args=args, kwargs=kwargs,
        max_workers=max_workers, chunk_point_len=chunk_point_len)
    return aggregation


def set_predict(kwargs):
    """Set attr argument and proba"""
    out = dict()
    proba = kwargs.pop('proba', False)
    if proba:
        out['proba'] = proba
        out['attr'] = 'predict_proba' if proba else 'predict'
    return out


def chunks(l, n):
    """Yield successive n-sized chunks from l."""
    for i in range(0, len(l), n):
        yield l[i:i + n]


@staticmethod
def order_messages_by_date(messages: list, descending: bool=True) ->list:
    """Order a collection of messages by datetime received."""
    return sorted(messages, reverse=descending, key=lambda val: val.received)


def pairwise(values):
    """
    WITH values = [a, b, c, d, ...]
    RETURN [(a, b), (b, c), (c, d), ...]
    """
    i = iter(values)
    a = next(i)
    for b in i:
        yield a, b
        a = b


def docs_drop_param(docstring):
    """Drop the first parameter description for a string representation of a docstring.

    Parameters
    ----------
    docstring : str
        Docstring to drop first parameter from.

    Returns
    -------
    str
        New docstring, with first parameter dropped.

    Notes
    -----
    This function assumes numpy docs standards.
    It also assumes the parameter description to be dropped is only 2 lines long.
    """
    sep = '----------\n'
    ind = docstring.find(sep) + len(sep)
    front, back = docstring[:ind], docstring[ind:]
    for loop in range(2):
        back = back[back.find('\n') + 1:]
    return front + back


def convert_variants_trace_idx_to_trace_obj(log, variants_trace_idx):
    """
    Converts variants expressed as trace indexes to trace objects

    Parameters
    -----------
    log
        Trace log object
    variants_trace_idx
        Variants associated to a list of belonging indexes

    Returns
    -----------
    variants
        Variants associated to a list of belonging traces
    """
    variants = {}
    for key in variants_trace_idx:
        variants[key] = []
        for value in variants_trace_idx[key]:
            variants[key].append(log[value])
    return variants


def read_tables(worksheet) ->tuple:
    """
    Read tables from sheet

    :param worksheet: An openpyxl worksheet
    :return: A tuple containing - A list of tables (which is a list of rows, terminated by an empty row in the original spreadsheet),
             and a list of start row indices for each table read in
    """
    buffer = []
    tables = []
    start_rows = []
    start = None
    for i, row in enumerate(worksheet.rows):
        if len(row) > 0 and row[0].data_type == 's' and row[0
            ].value.startswith('#ignore'):
            continue
        for cell in row:
            if cell.value:
                if not buffer:
                    start = i + 1
                buffer.append(row)
                break
        else:
            if buffer:
                tables.append(buffer)
                start_rows.append(start)
            buffer = []
    if buffer:
        tables.append(buffer)
        start_rows.append(start)
    return tables, start_rows


@classmethod
def is_super_group(cls, obj) ->bool:
    """
        Check chat is super-group

        :param obj:
        :return:
        """
    return cls._check(obj, [cls.SUPER_GROUP])


def grading_file(submission):
    """ Determines if the submission has a grading file,
        leads to nice little icon in the submission overview.
    """
    if submission.grading_file.name:
        return True
    else:
        return False


@classmethod
def log(cls, store, event_type, description):
    """
        Create a new event message.

        :param store: a store
        :param event_type: the event type of this message
        :param description: the message description
        """
    cls(event_type=event_type, description=description, store=store)


def log1p(data=None, out=None, name=None, **kwargs):
    """Returns element-wise ``log(1 + x)`` value of the input.

    This function is more accurate than ``log(1 + x)``  for small ``x`` so that
    :math:`1+x\\approx 1`

    The storage type of ``log1p`` output depends upon the input storage type:

       - log1p(default) = default
       - log1p(row_sparse) = row_sparse
       - log1p(csr) = csr

    Defined in src/operator/tensor/elemwise_unary_op_logexp.cc:L206

    Parameters
    ----------
    data : NDArray
        The input array.

    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 get(isamAppliance, name, check_mode=False, force=False):
    """
    Retrieving the list of groups for an authorization roles
    """
    return isamAppliance.invoke_get(
        'Retrieving the list of groups for an authorization roles',
        '/authorization/roles/{0}/groups/v1'.format(name))


def find_subranges(lst: list) ->(int, int):
    """Takes a range of sequential numbers (possibly with gaps) and splits them
    in sequential sub-ranges defined by the minimum and maximum value."""
    from operator import itemgetter
    from itertools import groupby
    for key, group in groupby(enumerate(lst), lambda i: i[0] - i[1]):
        group = list(map(itemgetter(1), group))
        yield min(group), max(group)


def get_atomic_numbers(mol, indices):
    """Get the atomic numbers for the specified atoms.

    Parameters
    ----------
    mol : rdkit.Chem.rdchem.Mol
        RDKit molecule instance.
    indices : list of int
        Specifying atoms.

    Returns
    -------
    list of int
        Atomic numbers computed.
    """
    atomic_numbers = []
    for i in indices:
        atom = mol.GetAtomWithIdx(i)
        atomic_numbers.append(atom.GetAtomicNum())
    return atomic_numbers


def _test_args():
    """Extra arguments to use when zipline's automated tests run this example.
    """
    import pandas as pd
    return {'start': pd.Timestamp('2014-01-01', tz='utc'), 'end': pd.
        Timestamp('2014-11-01', tz='utc')}


def _listify(ids):
    """convert string to list of unit length"""
    if isinstance(ids, str):
        ids = [ids]
    return ids


def bvneg(bv):
    """
    Unary minus: - bv
    """
    return '(bvneg {})'.format(bv)


def rolling_window(arr, window_size, stride=1, return_idx=False):
    """
    There is an example of an iterator for pure-Python objects in:
    http://stackoverflow.com/questions/6822725/rolling-or-sliding-window-iterator-in-python
    This is a rolling-window iterator Numpy arrays, with window size and
    stride control. See examples below for demos.

    Parameters
    ----------
    arr : array_like
        Input numpy array.
    window_size : int
        Width of the window.
    stride : int (optional)
        Number of indices to advance the window each iteration step.
    return_idx : bool (optional)
        Whether to return the slice indices alone with the array segment.

    Examples
    --------
    >>> a = np.array([1,2,3,4,5,6])
    >>> for x in rolling_window(a, 3):
    ...     print(x)
    [1 2 3]
    [2 3 4]
    [3 4 5]
    [4 5 6]
    >>> for x in rolling_window(a, 2, stride=2):
    ...     print(x)
    [1 2]
    [3 4]
    [5 6]
    >>> for (i1,i2),x in rolling_window(a, 2, stride=2, return_idx=True): # doctest: +SKIP
    ...     print(i1, i2, x)
    (0, 2, array([1, 2]))
    (2, 4, array([3, 4]))
    (4, 6, array([5, 6]))

    """
    window_size = int(window_size)
    stride = int(stride)
    if window_size < 0 or stride < 1:
        raise ValueError
    arr_len = len(arr)
    if arr_len < window_size:
        if return_idx:
            yield (0, arr_len), arr
        else:
            yield arr
    ix1 = 0
    while ix1 < arr_len:
        ix2 = ix1 + window_size
        result = arr[ix1:ix2]
        if return_idx:
            yield (ix1, ix2), result
        else:
            yield result
        if len(result) < window_size or ix2 >= arr_len:
            break
        ix1 += stride


@classmethod
def get_backward_delivery_cargo_types(cls):
    """
        Method for fetching info about backward delivery cargo types.

        :example:
            ``Common.get_backward_delivery_cargo_types()``
        :return:
            Dictionary with info about backward delivery cargo types.
        :rtype:
            dict
        """
    req = cls.send(method='getBackwardDeliveryCargoTypes')
    return req


def clear_db_env(*args, **kwargs):
    """
    Setup global environment configuration variables.

    We have no connection-oriented environment variables, so this is a NOOP.
    """
    pass


def _get_default_title(testcase):
    """Return the default value for title field."""
    return testcase.name


def pad_dim(dim, padlen):
    """Make dim divisible by padlen."""
    return (dim + padlen - 1) // padlen * padlen


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


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


def t_ID(t):
    """[a-zA-Z][a-zA-Z0-9]*"""
    return t


def list_mailboxes(cfg, debug, conn):
    """Print a list of the mailboxes.

    :param cfg: full configuration
    :type cfg: dict
    :param debug: flag to control debug output
    :type debug: bool
    :param conn: IMAP server onnection
    :type conn: imapautofiler.client.Client

    Used by the ``--list-mailboxes`` switch.

    """
    for f in conn.list_mailboxes():
        print(f)


def parse_int(value, default=0):
    """Convert 'value' to int"""
    if not value:
        return default
    try:
        return int(value)
    except (ValueError, TypeError):
        return default


def disassociate_configuration_items_from_application(
    applicationConfigurationId=None, configurationIds=None):
    """
    Disassociates one or more configuration items from an application.
    See also: AWS API Documentation

    :example: response = client.disassociate_configuration_items_from_application(
        applicationConfigurationId='string',
        configurationIds=[
            'string',
        ]
    )

    :type applicationConfigurationId: string
    :param applicationConfigurationId: [REQUIRED]
            Configuration ID of an application from which each item is disassociated.

    :type configurationIds: list
    :param configurationIds: [REQUIRED]
            Configuration ID of each item to be disassociated from an application.
            (string) --

    :rtype: dict
    :return: {}

    :returns:
    (dict) --

    """
    pass


def object_load_bmesh(bm: 'bmesh.types.BMesh', scene: 'bpy.types.Scene',
    object: 'bpy.types.Object'):
    """Loads a bmesh into an object/mesh. This is a “private” bmop.

    :param bm: The bmesh to operate on.
    :type bm: 'bmesh.types.BMesh'
    :param scene: Undocumented.
    :type scene: 'bpy.types.Scene'
    :param object: Undocumented.
    :type object: 'bpy.types.Object'
    """
    pass


def is_vcs_link(ireq):
    """
    Returns whether an InstallRequirement is a version control link.
    """
    return ireq.link is not None and not ireq.link.is_artifact


def hamming_distance(i, j):
    """
    Return the hamming distance between the two given pythonic integers, or the
    number of places where the bits differ.

    **Note:** *We say "pythonic" integer here because this function has no cap
    on the number of bits used to represent said integer. This function will
    execute correctly regardless whether i/j is 32 bits or 512 bits, etc."

    :param i: First integer.
    :type i: int | long
    :param j: Second integer.
    :type j: int | long

    :return: Integer hamming distance between the two values.
    :rtype: int | long

    """
    return bin(i ^ j).count('1')


@classmethod
def getQtDesignerPluginInfo(cls):
    """TaurusGui is not to be in designer """
    return None


def hello() ->str:
    """
    Simple Hello World.

    >>> hello()
    'Hello World'
    """
    return 'Hello World'


def test_module():
    """
       >>> forkort_navn(25, 'Bjorn Steinar', 'Fjeld Pettersen')
       u'Bjorn S Fjeld Pettersen'
       >>> forkort_navn(22, 'Bjorn Steinar', 'Fjeld Pettersen')
       u'Bjorn S F Pettersen'
       >>> forkort_navn(18, 'Bjorn Steinar', 'Fjeld Pettersen')
       Traceback (most recent call last):
       ...
       ValueError: Bjorn S F Pettersen kan ikke forkortes til 18 bokstaver

       >>> v = forkort_navn(25, u'Bjørn Øystein', u'Fjeld Pettersen')
       >>> u'Bjørn Ø Fjeld Pettersen'
       >>> v == u'Bjørn Ø Fjeld Pettersen'
       True
       >>> v = forkort_navn(21, u'Bjørn Øystein', u'Ødal Pettersen')
       >>> v == u'Bjørn Ø Ø Pettersen'
       True

       >>> v = forkort_navn_u8(21, u'Bjørn Øystein'.encode('u8'), u'Ødal Pettersen'.encode('u8'))
       >>> v == u'Bjørn Ø Ø Pettersen'.encode('u8')
       True

       Normalisering av navn til utf-8 med stor forbokstav som eneste
       store bokstav.

       >>> normalize2u8(u'Bjørn') == u'Bjørn'.encode('u8')
       True
       >>> normalize2u8(u'BJørn') == u'Bjørn'.encode('u8')
       True
       >>> normalize2u8(u'BJØrn'.encode('u8')) == u'Bjørn'.encode('u8')
       True
       >>> normalize2u8(u'geir-arne') == 'Geir-Arne'
       True
    """
    import doctest
    doctest.testmod()


def plot_text_center(ax, text, fontsize=18):
    """
    Display text at the center of an ax from a matplotlib figure.

    Parameters
    ----------
    ax: plt.axes.Axes
        ax where to set centered text
    text: str
        text to display
    fontsize: int (default 18)
        font size of the text
    """
    left, width = 0.25, 0.5
    bottom, height = 0.25, 0.5
    right = left + width
    top = bottom + height
    ax.text(0.5 * (left + right), 0.5 * (bottom + top), text,
        horizontalalignment='center', verticalalignment='center', fontsize=
        fontsize, transform=ax.transAxes)
    ax.axis('off')


def _check_pyopengl_3D():
    """Helper to ensure users have OpenGL for 3D texture support (for now)"""
    global USE_TEX_3D
    USE_TEX_3D = True
    try:
        import OpenGL.GL as _gl
    except ImportError:
        raise ImportError('PyOpenGL is required for 3D texture support')
    return _gl


def psi_H_Mg_Br_MP98(T, P):
    """c-c'-a: hydrogen magnesium bromide [MP98]."""
    psi = -0.005
    valid = T == 298.15
    return psi, valid


def bits_to_bytes(bit_array, bpb=8):
    """Convert an array or string of bits to bytes."""
    if len(bit_array) % bpb != 0:
        raise ValueError('Number of bits must be a multiple of ' + str(bpb))
    result = b''
    for i in range(0, len(bit_array), bpb):
        bits = [str(bits) for bits in bit_array[i:i + bpb]]
        bitstring = ''.join(bits)
        result += bytes([int(bitstring, 2)])
    return result


@classmethod
def from_settings(cls):
    """Create configuration from Django settings or environment."""
    from cloud_browser.app_settings import settings
    from django.core.exceptions import ImproperlyConfigured
    conn_cls = conn_fn = None
    datastore = settings.CLOUD_BROWSER_DATASTORE
    if datastore == 'ApacheLibcloud':
        from cloud_browser.cloud.apache_libcloud import ApacheLibcloudConnection
        provider = settings.CLOUD_BROWSER_APACHE_LIBCLOUD_PROVIDER
        account = settings.CLOUD_BROWSER_APACHE_LIBCLOUD_ACCOUNT
        secret_key = settings.CLOUD_BROWSER_APACHE_LIBCLOUD_SECRET_KEY
        host = settings.CLOUD_BROWSER_APACHE_LIBCLOUD_HOST
        port = settings.CLOUD_BROWSER_APACHE_LIBCLOUD_PORT
        secure = settings.CLOUD_BROWSER_APACHE_LIBCLOUD_SECURE != 'False'
        if provider and account and secret_key:
            conn_cls = ApacheLibcloudConnection
            conn_fn = lambda : ApacheLibcloudConnection(provider, account,
                secret_key, host=host, port=port, secure=secure)
    if datastore == 'AWS':
        from cloud_browser.cloud.aws import AwsConnection
        account = settings.CLOUD_BROWSER_AWS_ACCOUNT
        secret_key = settings.CLOUD_BROWSER_AWS_SECRET_KEY
        if account and secret_key:
            conn_cls = AwsConnection
            conn_fn = lambda : AwsConnection(account, secret_key)
    if datastore == 'Google':
        from cloud_browser.cloud.google import GsConnection
        account = settings.CLOUD_BROWSER_GS_ACCOUNT
        secret_key = settings.CLOUD_BROWSER_GS_SECRET_KEY
        if account and secret_key:
            conn_cls = GsConnection
            conn_fn = lambda : GsConnection(account, secret_key)
    elif datastore == 'Rackspace':
        account = settings.CLOUD_BROWSER_RACKSPACE_ACCOUNT
        secret_key = settings.CLOUD_BROWSER_RACKSPACE_SECRET_KEY
        servicenet = settings.CLOUD_BROWSER_RACKSPACE_SERVICENET
        authurl = settings.CLOUD_BROWSER_RACKSPACE_AUTHURL
        if account and secret_key:
            from cloud_browser.cloud.rackspace import RackspaceConnection
            conn_cls = RackspaceConnection
            conn_fn = lambda : RackspaceConnection(account, secret_key,
                servicenet=servicenet, authurl=authurl)
    elif datastore == 'Filesystem':
        root = settings.CLOUD_BROWSER_FILESYSTEM_ROOT
        if root is not None:
            from cloud_browser.cloud.fs import FilesystemConnection
            conn_cls = FilesystemConnection
            conn_fn = lambda : FilesystemConnection(root)
    if conn_cls is None:
        raise ImproperlyConfigured(
            'No suitable credentials found for datastore: %s.' % datastore)
    conn_fn = staticmethod(conn_fn)
    cls.__connection_cls = conn_cls
    cls.__connection_fn = conn_fn
    return conn_cls, conn_fn


def delete_deployment(restApiId=None, deploymentId=None):
    """
    Deletes a  Deployment resource. Deleting a deployment will only succeed if there are no  Stage resources associated with it.
    See also: AWS API Documentation

    :example: response = client.delete_deployment(
        restApiId='string',
        deploymentId='string'
    )

    :type restApiId: string
    :param restApiId: [REQUIRED]
            The identifier of the RestApi resource for the Deployment resource to delete.

    :type deploymentId: string
    :param deploymentId: [REQUIRED]
            The identifier of the Deployment resource to delete.

    """
    pass


def _compute_temp_terminus(temp, temp_grad, ref_hgt, terminus_hgt,
    temp_anomaly=0):
    """Computes the (monthly) mean temperature at the glacier terminus,
    following section 2.1.2 of Marzeion et. al., 2012. The input temperature
    is scaled by the given temperature gradient and the elevation difference
    between reference altitude and the glacier terminus elevation.

    Parameters
    ----------
    temp : netCDF4 variable
        monthly mean climatological temperature (degC)
    temp_grad : netCDF4 variable or float
        temperature lapse rate [degC per m of elevation change]
    ref_hgt : float
        reference elevation for climatological temperature [m asl.]
    terminus_hgt : float
        elevation of the glacier terminus (m asl.)
    temp_anomaly : netCDF4 variable or float, optional
        monthly mean temperature anomaly, default 0

    Returns
    -------
    netCDF4 variable
        monthly mean temperature at the glacier terminus [degC]

    """
    temp_terminus = temp + temp_grad * (terminus_hgt - ref_hgt) + temp_anomaly
    return temp_terminus


def format_inheritance_flags(parent):
    """Return a human readable string of inheritance flags"""
    flags = ''
    for code, expr in (('M', parent['maxdepth'] is not None), ('F', parent[
        'pkg_filter']), ('I', parent['intransitive']), ('N', parent[
        'noconfig'])):
        if expr:
            flags += code
        else:
            flags += '.'
    return flags


def gen_select_view(sig_dic):
    """
    HTML view, for selection.
    """
    option_str = ''
    dic_tmp = sig_dic['dic']
    for key, val in dic_tmp.items():
        tmp_str = (
            """
         {{% if '{sig_en}' in postinfo.extinfo %}}
          {{% set tmp_var = postinfo.extinfo["{sig_en}"] %}}
          {{% if tmp_var == "{sig_key}" %}}
          {sig_dic}
          {{% end %}}
          {{% end %}}
         """
            .format(sig_en=sig_dic['en'], sig_key=key, sig_dic=val))
        option_str += tmp_str
    return (
        """

{sig_zh}

    {option_str}

    """
        .format(sig_zh=sig_dic['zh'], option_str=option_str))


def combine(container1, container2):
    """Combine function for Apache Spark's ``aggregate`` method.

    Typical use: ``filledHistogram = datasetRDD.aggregate(initialHistogram)(increment, combine)`` where ``datasetRDD`` is a collection of ``initialHistogram``'s input type.
   """
    return container1 + container2


def hr(width=70):
    """ Return simple ascii horizontal rule """
    if width < 2:
        return ''
    return '# ' + (width - 2) * '~'


def summarize_ndarray(data):
    """assume data is ndarray
    return its type, dtype and shape"""
    return type(data), data.dtype, data.shape


def cmd_add(args):
    """The add command adds the current proxy settings to the database"""
    print('Adding to database is not yet implemented')


def meshdeform_bind(modifier: str=''):
    """Bind mesh to cage in mesh deform modifier

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


def describe_instance_attribute(DryRun=None, InstanceId=None, Attribute=None):
    """
    Describes the specified attribute of the specified instance. You can specify only one attribute at a time. Valid attribute values are: instanceType | kernel | ramdisk | userData | disableApiTermination | instanceInitiatedShutdownBehavior | rootDeviceName | blockDeviceMapping | productCodes | sourceDestCheck | groupSet | ebsOptimized | sriovNetSupport
    See also: AWS API Documentation

    Examples
    This example describes the instance type of the specified instance.
    Expected Output:
    This example describes the disableApiTermination attribute of the specified instance.
    Expected Output:
    This example describes the blockDeviceMapping attribute of the specified instance.
    Expected Output:

    :example: response = client.describe_instance_attribute(
        DryRun=True|False,
        InstanceId='string',
        Attribute='instanceType'|'kernel'|'ramdisk'|'userData'|'disableApiTermination'|'instanceInitiatedShutdownBehavior'|'rootDeviceName'|'blockDeviceMapping'|'productCodes'|'sourceDestCheck'|'groupSet'|'ebsOptimized'|'sriovNetSupport'|'enaSupport'
    )

    :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 InstanceId: string
    :param InstanceId: [REQUIRED]
            The ID of the instance.

    :type Attribute: string
    :param Attribute: [REQUIRED]
            The instance attribute.
            Note: The enaSupport attribute is not supported at this time.

    :rtype: dict
    :return: {
        'InstanceId': 'string',
        'InstanceType': {
            'Value': 'string'
        },
        'KernelId': {
            'Value': 'string'
        },
        'RamdiskId': {
            'Value': 'string'
        },
        'UserData': {
            'Value': 'string'
        },
        'DisableApiTermination': {
            'Value': True|False
        },
        'InstanceInitiatedShutdownBehavior': {
            'Value': 'string'
        },
        'RootDeviceName': {
            'Value': 'string'
        },
        'BlockDeviceMappings': [
            {
                'DeviceName': 'string',
                'Ebs': {
                    'VolumeId': 'string',
                    'Status': 'attaching'|'attached'|'detaching'|'detached',
                    'AttachTime': datetime(2015, 1, 1),
                    'DeleteOnTermination': True|False
                }
            },
        ],
        'ProductCodes': [
            {
                'ProductCodeId': 'string',
                'ProductCodeType': 'devpay'|'marketplace'
            },
        ],
        'EbsOptimized': {
            'Value': True|False
        },
        'SriovNetSupport': {
            'Value': 'string'
        },
        'EnaSupport': {
            'Value': True|False
        },
        'SourceDestCheck': {
            'Value': True|False
        },
        'Groups': [
            {
                'GroupName': 'string',
                'GroupId': 'string'
            },
        ]
    }

    """
    pass


def nfa_nonemptiness_check(nfa: dict) ->bool:
    """ Checks if the input NFA reads any language other than the
    empty one, returning True/False.

    The language L(A) recognized by the automaton A is nonempty iff
    there are states :math:`s ∈ S_0` and :math:`t ∈ F` such that
    t is connected to s.
    Thus, automata nonemptiness is equivalent to graph reachability.

    A breadth-first-search algorithm can construct in linear time
    the set of all states connected to a state in :math:`S_0`. A
    is nonempty iff this set intersects F nontrivially.

    :param dict nfa: input NFA.
    :return: *(bool)*, True if the input nfa is nonempty, False
             otherwise.
    """
    queue = list()
    visited = set()
    for state in nfa['initial_states']:
        visited.add(state)
        queue.append(state)
    while queue:
        state = queue.pop(0)
        visited.add(state)
        for a in nfa['alphabet']:
            if (state, a) in nfa['transitions']:
                for next_state in nfa['transitions'][state, a]:
                    if next_state in nfa['accepting_states']:
                        return True
                    if next_state not in visited:
                        queue.append(next_state)
    return False


@classmethod
def _get_serializable_model(cls):
    """
        Returns a model with a valid _meta.local_fields (serializable).

        Basically, this means the original model, not a proxied model.

        (this is a workaround for a bug in django)
        """
    current_class = cls
    while current_class._meta.proxy:
        current_class = current_class._meta.proxy_for_model
    return current_class


def strlist(s):
    """Convert comma seperated file name string to list
  """
    return s.split(',')


@classmethod
def from_api_data(cls, data):
    """Creates a new Address object from API data from ticketswitch.

        Args:
            data (dict): the part of the response from a ticketswitch API call
                that concerns an address.

        Returns:
            :class:`Address <pyticketswitch.address.Address>`: a new
            :class:`Address <pyticketswitch.address.Address>` object
            populated with the data from the api.

        """
    kwargs = {'country_code': data.get('country_code'), 'county': data.get(
        'county'), 'email': data.get('email_address'), 'home_phone': data.
        get('home_phone'), 'post_code': data.get('postcode'), 'town': data.
        get('town'), 'work_phone': data.get('work_phone'), 'lines': [data.
        get('address_line_one'), data.get('address_line_two')]}
    return cls(**kwargs)


def p_dynamic_class_name_variable_properties(p):
    """dynamic_class_name_variable_properties : dynamic_class_name_variable_properties dynamic_class_name_variable_property
                                              | empty"""
    if len(p) == 3:
        p[0] = p[1] + [p[2]]
    else:
        p[0] = []


def conv_ext_to_proj(P):
    """
    Extended coordinates to projective
    :param P:
    :return:
    """
    return P[0], P[1], P[2]


def example():
    """Just an example which prints 'example called'.

    Example:

    +---------+
    | example |
    +---------+

    See also 'Other Example'.

    """
    print('example called')


def get_subnet_flow_logs_list(current_config, subnet):
    """
    Return the flow logs that cover a given subnet

    :param current_config:
    :param subnet: the subnet that the flow logs should cover
    :return:
    """
    flow_logs_list = []
    for flow_log in current_config.flow_logs:
        if current_config.flow_logs[flow_log]['ResourceId'] == subnet[
            'SubnetId'] or current_config.flow_logs[flow_log]['ResourceId'
            ] == subnet['VpcId']:
            flow_logs_list.append(flow_log)
    return flow_logs_list


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


def sort_dicoms(dicoms):
    """
    Sort the dicoms based om the image possition patient

    :param dicoms: list of dicoms
    """
    dicom_input_sorted_x = sorted(dicoms, key=lambda x: x.
        ImagePositionPatient[0])
    dicom_input_sorted_y = sorted(dicoms, key=lambda x: x.
        ImagePositionPatient[1])
    dicom_input_sorted_z = sorted(dicoms, key=lambda x: x.
        ImagePositionPatient[2])
    diff_x = abs(dicom_input_sorted_x[-1].ImagePositionPatient[0] -
        dicom_input_sorted_x[0].ImagePositionPatient[0])
    diff_y = abs(dicom_input_sorted_y[-1].ImagePositionPatient[1] -
        dicom_input_sorted_y[0].ImagePositionPatient[1])
    diff_z = abs(dicom_input_sorted_z[-1].ImagePositionPatient[2] -
        dicom_input_sorted_z[0].ImagePositionPatient[2])
    if diff_x >= diff_y and diff_x >= diff_z:
        return dicom_input_sorted_x
    if diff_y >= diff_x and diff_y >= diff_z:
        return dicom_input_sorted_y
    if diff_z >= diff_x and diff_z >= diff_y:
        return dicom_input_sorted_z


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

        :param SmartSyncChangePolicyType val:
        :rtype: EventType
        """
    return cls('smart_sync_change_policy', val)


@staticmethod
def _none_to_str(mp):
    """Use str to store Nones. Used for HDF5"""
    for k in mp.keys():
        if mp[k] is None:
            mp[k] = 'None'
    return mp


@classmethod
def table_name(cls):
    """
        Returns the model's database table name.
        """
    return cls._table_name or cls.__name__.lower()


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


def payoff_put_fprime(underlying, strike, gearing=1.0):
    """payoff_put_fprime
    derivative of payoff of call option with respect to underlying.

    :param underlying:
    :param strike:
    :param gearing:
    :return: value of derivative with respect to underlying.
    :rtype: float
    """
    if underlying < strike:
        return -gearing
    else:
        return 0.0


def _common_parser():
    """Returns a parser with common command-line options for all the scripts
    in the fortpy suite.
    """
    import argparse
    parser = argparse.ArgumentParser(add_help=False)
    parser.add_argument('-examples', action='store_true', help=
        'See detailed help and examples for this script.')
    parser.add_argument('-verbose', action='store_true', help=
        'See verbose output as the script runs.')
    parser.add_argument('-action', nargs=1, choices=['save', 'print'],
        default='print', help=
        'Specify what to do with the output (print or save)')
    parser.add_argument('-debug', action='store_true', help=
        'Print verbose calculation information for debugging.')
    return parser


def stopProducing():
    """
        Stop producing data.

        This tells a producer that its consumer has died, so it must stop
        producing data for good.
        """


def get_binary_annotations(request, response):
    """Helper method for getting all binary annotations from the request.

    :param request: the Pyramid request object
    :param response: the Pyramid response object
    :returns: binary annotation dict of {str: str}
    """
    route = request.matched_route.pattern if request.matched_route else ''
    annotations = {'http.uri': request.path, 'http.uri.qs': request.path_qs,
        'http.route': route, 'response_status_code': str(response.status_code)}
    settings = request.registry.settings
    if 'zipkin.set_extra_binary_annotations' in settings:
        annotations.update(settings['zipkin.set_extra_binary_annotations'](
            request, response))
    return annotations


def check_noexif(noexif):
    """checks if noexif parameter is boolean"""
    if not isinstance(noexif, bool):
        raise TypeError('noexif must be boolean')


@staticmethod
def getJavaPackage():
    """ Returns package name String. """
    return 'com.microsoft.ml.spark.io.http.JSONOutputParser'


def _plot_ci_bars(ax, x, central_data, ci, color, err_kws, **kwargs):
    """Plot error bars at each data point."""
    for x_i, y_i, (low, high) in zip(x, central_data, ci.T):
        ax.plot([x_i, x_i], [low, high], color=color, solid_capstyle=
            'round', **err_kws)


def numToDigits(num, places):
    """Helper, for converting numbers to textual digits."""
    s = str(num)
    if len(s) < places:
        return '0' * (places - len(s)) + s
    elif len(s) > places:
        return s[len(s) - places:]
    else:
        return s


@staticmethod
def _state_deleted(want, have):
    """ The command generator when state is deleted
        :rtype: A list
        :returns: the commands necessary to remove the current configuration
                  of the provided objects
        """
    commands = []
    if want != have:
        commands = ['no telemetry']
    return commands


def FormatClassToPython(i):
    """
    Transform a typed class name into a form which can be used as a python
    attribute

    example::

        >>> FormatClassToPython('Lfoo/bar/foo/Barfoo$InnerClass;')
        'Lfoo_bar_foo_Barfoo_InnerClass'

    :param i: classname to transform
    :rtype: str
    """
    i = i[:-1]
    i = i.replace('/', '_')
    i = i.replace('$', '_')
    return i


def generate_subsamples(table, n, axis='sample', by_id=False):
    """Indefinitely generate random subsamples

    Parameters
    ----------
    table : Table
        The table to subsample from
    n : int
        The size of the subsample
    axis : {'sample', 'observation'}, optional
        The axis to operate on, defaults to 'sample'.
    by_id : bool, optional
        If `True`, operate on IDs, if `False`, operate on values. Defaults to
        `False`.

    Returns
    -------
    GeneratorType
        Each subsequent call to .next() will yield a new randomly subsampled
        table

    Examples
    --------

    Randomly subsample the samples in the example_table 10 times:

    >>> from biom import example_table
    >>> gen = generate_subsamples(example_table, 2, by_id=True)
    >>> observed_ids = []
    >>> for _, table in zip(range(100), gen):
    ...     observed_ids.append(tuple(table.ids()))
    >>> print(sorted(set(observed_ids)))
    [('S1', 'S2'), ('S1', 'S3'), ('S2', 'S3')]

    """
    while True:
        yield table.subsample(n, axis, by_id)


@classmethod
def addEndTimes(cls, chapters, duration):
    """Add end times to chapters based on subsequent chapter start times
        Mediainfo only gives start times for each chapter

        Args:
            chapters (list): The parsed chapter info
            duration (int): Full video duration

        """
    start_prev = duration
    for i in reversed(range(0, len(chapters))):
        chapters[i]['end'] = start_prev
        start_prev = chapters[i]['start']


def create_gzip(archive, compression, cmd, verbosity, interactive, filenames):
    """Create a GZIP archive."""
    cmdlist = [cmd, 'a']
    if not interactive:
        cmdlist.append('-y')
    cmdlist.extend(['-tgzip', '-mx=9', '--', archive])
    cmdlist.extend(filenames)
    return cmdlist


@classmethod
def parse(cls, json):
    """Parse a json dict and return the correct subclass."""
    raise NotImplementedError


def create_initial_category(apps, schema_editor):
    """ Create a default category for existing discounts """
    DiscountCategory = apps.get_model('discounts', 'DiscountCategory')
    db_alias = schema_editor.connection.alias
    DiscountCategory.objects.using(db_alias).create(id=1, name=
        'General Discounts', order=1, cannotCombine=False)


def require_variable(df, variable, unit=None, year=None, exclude_on_fail=
    False, **kwargs):
    """Check whether all scenarios have a required variable

    Parameters
    ----------
    df : IamDataFrame
    args : passed to :meth:`require_variable`
    kwargs : used for downselecting IamDataFrame
        passed to :meth:`filter() <IamDataFrame.filter>`
    """
    fdf = df.filter(**kwargs)
    if len(fdf.data) > 0:
        vdf = fdf.require_variable(variable=variable, unit=unit, year=year,
            exclude_on_fail=exclude_on_fail)
        df.meta['exclude'] |= fdf.meta['exclude']
        return vdf


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


def _polymorph(cls, dct):
    """Just create a proper instance for this dct."""
    if '_id' not in dct or '/' not in dct['_id']:
        raise TypeError('Cannot infer document type!', dct)
    collection, _ = dct['_id'].split('/')
    if collection not in cls.__documents__:
        raise TypeError('Unknown document type!', collection)
    return cls.__documents__[collection](dct)


def GCD(a, b):
    """https://reference.wolfram.com/language/ref/GCD.html"""
    while b:
        a, b = b, a % b
    return a


@staticmethod
def _inheritors(klass):
    """Return all defined classes that inherit from 'klass'.
        """
    subclasses = set()
    work = [klass]
    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 from_json_type(cls, data):
    """Convert a dictionary of JSON safe data to a task"""
    assigned_to = data.pop('assigned_to')
    id = data.pop('id')
    timestamp = data.pop('timestamp')
    task = cls(**data)
    task._assigned_to = assigned_to
    task._id = id
    task._timestamp = timestamp
    return task


def context(input):
    """Return the context/device of the input tensor.

    Parameters
    ----------
    input : Tensor
        The input tensor.

    Returns
    -------
    Context object
        A framework-specific context object.
    """
    pass


def char2code(unicode):
    """Returns the ASCII code for a unicode character.

    Args:
        unicode (str):

    Raises:
        TypeError: string is length two.
    """
    try:
        code = 'U+{0:04x}'.format(ord(unicode))
    except TypeError:
        code = unicode
    return code


def check_pool_destroy(conn, poolname, logger):
    """
     Check to verify that the pool is actually gone
    """
    pool_names = conn.listStoragePools()
    if poolname not in pool_names:
        logger.info('destroy pool %s SUCCESS , ' % poolname)
        logger.info("%s doesn't seem to be an active poolname anymore, " %
            poolname)
        return True
    else:
        logger.error('destroy pool %s UNSUCCESSFUL' % poolname)
        logger.error('%s is still in the list after destroy' % poolname)
        return True


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 re_arrange(data_array, order_array):
    """
    Re-arrange the items in data_array to be
    in the order specified by order_array.
    """
    if not hasattr(data_array, '__iter__'):
        raise TypeError('Non-iterable type passed as data_array argument.')
    if not hasattr(order_array, '__iter__'):
        raise TypeError('Non-iterable type passed as order_array argument.')
    if len(order_array) != len(data_array):
        raise ValueError('data_array and order_array length do not match.')
    length = len(data_array)
    new_array = [None] * length
    for norm, index in enumerate(order_array):
        new_array[norm] = data_array[index]
    return new_array