@classmethod
def export_orders_to_prestashop_using_cron(cls):
    """
        Export order status to prestashop using cron
        """
    channels = cls.search([('source', '=', 'prestashop')])
    for channel in channels:
        channel.export_orders_to_prestashop()


def glClearColor(red, green, blue, alpha):
    """Specify clear values for the color buffers

    :param alpha: Specify the red, green, blue, and alpha values used when the color buffers are cleared. The initial values are all 0.
    """
    pass


def ci(x, y, z):
    """
    Turn an (x, y, z) tuple into a chunk index.

    This is really a macro and not a function, but Python doesn't know the
    difference. Hopefully this is faster on PyPy than on CPython.
    """
    return (x * 16 + z) * 256 + y


def rebuild_db_indexes(database, table):
    """Rebuild database indexes"""
    raise NotImplementedError


def is_function_pointer_stack(stack):
    """Count how many non-nested paranthesis are in the stack.  Useful for determining if a stack is a function pointer"""
    paren_depth = 0
    paren_count = 0
    star_after_first_paren = False
    last_e = None
    for e in stack:
        if e == '(':
            paren_depth += 1
        elif e == ')' and paren_depth > 0:
            paren_depth -= 1
            if paren_depth == 0:
                paren_count += 1
        elif e == '*' and last_e == '(' and paren_count == 0 and paren_depth == 1:
            star_after_first_paren = True
        last_e = e
    if star_after_first_paren and paren_count == 2:
        return True
    else:
        return False


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 is_sequence(arg):
    """
    Handelt es sich im Sinne von SQL um eine Sequenz (abzugleichen mit
    ... = ANY (...) anstelle von ... = ...)?

    >>> is_sequence('test')
    False
    >>> is_sequence(['a', 'b'])
    True
    >>> is_sequence(42)
    False

    Auch Generatoren werden erkannt:
    >>> is_sequence(xrange(1, 3))
    True
    """
    if hasattr(arg, 'strip'):
        return False
    return hasattr(arg, '__getitem__') or hasattr(arg, '__iter__')


def smart_truncate(content, length=100, suffix='...'):
    """
    Truncate a text so that the last word is removed, and it doesn't cut out in the middle of a word.
    """
    if len(content) <= length:
        return content
    else:
        return ' '.join(content[:length + 1].split(' ')[0:-1]) + suffix


@staticmethod
def _is_mounted(blkdev_info_dict):
    """Method to check if partition is mounted"""
    if blkdev_info_dict['mountpoint'] is not None:
        return True
    return False


def ones(shape, dtype, ctx):
    """Create a one tensor.

    Parameters
    ----------
    shape : tuple of int
        The tensor shape.
    dtype : data type
        It should be one of the values in the data type dict.
    ctx : context
        The device of the result tensor.

    Returns
    -------
    Tensor
        The one tensor.
    """
    pass


def plugins_versions():
    """Show packages version"""
    import pkg_resources
    packages = {}
    for package in pkg_resources.working_set:
        entry_map = package.get_entry_map('rally_plugins')
        if not entry_map:
            continue
        packages[package.project_name] = package.version
    return packages


def should_build_with_cython(package, release=None):
    """Returns the previously used Cython version (or 'unknown' if not
    previously built) if Cython should be used to build extension modules from
    pyx files.  If the ``release`` parameter is not specified an attempt is
    made to determine the release flag from `astropy.version`.
    """
    from ..setup_helpers import _module_state
    try:
        version_module = __import__(package + '.cython_version', fromlist=[
            'release', 'cython_version'])
    except ImportError:
        version_module = None
    if release is None and version_module is not None:
        try:
            release = version_module.release
        except AttributeError:
            pass
    try:
        cython_version = version_module.cython_version
    except AttributeError:
        cython_version = 'unknown'
    if _module_state['have_cython'] and (not release or cython_version ==
        'unknown'):
        return cython_version
    else:
        return False


def get_counter(data, base):
    """
    See setCounters() / getCounters() methods in IJ source, ij/gui/PointRoi.java.
    """
    b0 = data[base]
    b1 = data[base + 1]
    b2 = data[base + 2]
    b3 = data[base + 3]
    counter = b3
    position = (b1 << 8) + b2
    return counter, position


def create_or_update_tags(Tags=None):
    """
    Creates or updates tags for the specified Auto Scaling group.
    When you specify a tag with a key that already exists, the operation overwrites the previous tag definition, and you do not get an error message.
    For more information, see Tagging Auto Scaling Groups and Instances in the Auto Scaling User Guide .
    See also: AWS API Documentation

    Examples
    This example adds two tags to the specified Auto Scaling group.
    Expected Output:

    :example: response = client.create_or_update_tags(
        Tags=[
            {
                'ResourceId': 'string',
                'ResourceType': 'string',
                'Key': 'string',
                'Value': 'string',
                'PropagateAtLaunch': True|False
            },
        ]
    )

    :type Tags: list
    :param Tags: [REQUIRED]
            One or more tags.
            (dict) --Describes a tag for an Auto Scaling group.
            ResourceId (string) --The name of the group.
            ResourceType (string) --The type of resource. The only supported value is auto-scaling-group .
            Key (string) -- [REQUIRED]The tag key.
            Value (string) --The tag value.
            PropagateAtLaunch (boolean) --Determines whether the tag is added to new instances as they are launched in the group.

    :return: response = client.create_or_update_tags(
        Tags=[
            {
                'Key': 'Role',
                'PropagateAtLaunch': True,
                'ResourceId': 'my-auto-scaling-group',
                'ResourceType': 'auto-scaling-group',
                'Value': 'WebServer',
            },
            {
                'Key': 'Dept',
                'PropagateAtLaunch': True,
                'ResourceId': 'my-auto-scaling-group',
                'ResourceType': 'auto-scaling-group',
                'Value': 'Research',
            },
        ],
    )

    print(response)

    """
    pass


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

        :param PaperDocChangeSubscriptionType val:
        :rtype: EventType
        """
    return cls('paper_doc_change_subscription', val)


def publish(service, nodeIdentifier, items=[]):
    """
        Publish to a node.

        Node that the C{items} parameter is optional, because so-called
        transient, notification-only nodes do not use items and publish
        actions only signify a change in some resource.

        @param service: The publish-subscribe service entity.
        @type service: L{JID<twisted.words.protocols.jabber.jid.JID>}
        @param nodeIdentifier: Identifier of the node to publish to.
        @type nodeIdentifier: C{unicode}
        @param items: List of item elements.
        @type items: C{list} of L{Item}
        @rtype: L{Deferred<twisted.internet.defer.Deferred>}
        """


def receive_leave_group(group_state: 'GroupState'):
    """
    Received IGMP Leave packet regarding group GroupState
    """
    group_state.group_state_logger.debug(
        'Querier Version1MembersPresent: receive_leave_group')
    return


def canonical_property(archive, name):
    """
    Make sure "core" is added to properties without namespace.
    """
    if name in ['count', 'tag']:
        return name
    metadata = archive._namespace_schemas
    if name == '*':
        name = '*.*'
    else:
        split_name = name.split('.')
        if split_name[0] not in metadata and (split_name[0] in metadata[
            'core'] or split_name[0] == 'validity_duration'):
            name = '%s.%s' % ('core', name)
    return name


@classmethod
def short2full(cls, code):
    """Convert an ISO 3166-2 country code to the corresponding full name"""
    return cls._country_map.get(code.upper())


def timing(stat, value, rate=1, buf=None, rate_applied=False):
    """
        Log timing information in milliseconds.

        ``stat`` is the name of the metric to record and ``value`` is
        the timing measurement in milliseconds. Note that Statsd
        maintains several data points for each timing metric, so
        timing metrics can take more disk space than counters or
        gauges.
        """


@staticmethod
def iterator(fn):
    """Tag the method as the collection remover.

        The iterator method is called with no arguments.  It is expected to
        return an iterator over all collection members::

            @collection.iterator
            def __iter__(self): ...

        """
    fn._sa_instrument_role = 'iterator'
    return fn


@staticmethod
def get_remote(repo, name):
    """Return the git.Remote object base on the name."""
    for remote in repo.remotes:
        if remote.name == name:
            return remote
    return None


def Q5(primer: str, *args, **kwargs):
    """For Q5 Ta they take the lower of the two Tms and add 1C
    (up to 72C). For Phusion they take the lower of the two
    and add 3C (up to 72C).
    """
    raise NotImplementedError


@classmethod
def convert_to_timestamps(cls, tracks_row_strings):
    """Accepts tracks durations in hh:mm:ss format; one per row"""
    lines = cls.parse_tracks_hhmmss(tracks_row_strings)
    i = 1
    timestamps = ['0:00']
    while i < len(lines):
        timestamps.append(cls.add(timestamps[i - 1], lines[i - 1][-1]))
        i += 1
    return timestamps


@staticmethod
def _format_set(value) ->list:
    """
        Formatting list of values in the event of IN operation
        :param value: str
        :return: list
        """
    value_list = value.values
    format_list = []
    for item in value_list:
        format_list.append("'{}'".format(item))
    return format_list


@classmethod
def from_number(cls, value, name, min, max, specials, *args, **kwargs):
    """
        Create a new :class:`~crython.field.CronField` instance from the given numeric value.

        :param value: A :class:`~int` value.
        :param name: Name of the column this field represents within an expression.
        :param min: Lower bound for the value, inclusive
        :param max: Upper bound for the value, inclusive
        :param specials: Set of special characters valid for this field type
        :param args: Additional positional args
        :param kwargs: Additional keyword args
        :return: A :class:`~crython.field.CronField`
        """
    if not min <= value <= max:
        raise ValueError('Value must be between {0} and {1}'.format(min, max))
    return cls(value, name, min, max, specials, *args, **kwargs)


@staticmethod
def get_elastic_mappings(es_major):
    """Get Elasticsearch mapping.

        :param es_major: major version of Elasticsearch, as string
        :returns:        dictionary with a key, 'items', with the mapping
        """
    mapping = """
        {
            "properties": {
                "Event_Description": {
                    "type": "keyword"
                },
                "Event_Description_Analyzed": {
                    "type": "text",
                    "index": true
                },
                "Event_Creations": {
                    "type": "keyword"
                },
                "Event_Creations_Analyzed": {
                    "type": "text",
                    "index": true
                },
                "Feedback_from_Attendees": {
                    "type": "keyword"
                },
                "Feedback_from_Attendees_Analyzed": {
                    "type": "text",
                    "index": true
                },
                "Your_Feedback": {
                    "type": "keyword"
                },
                "Your_Feedback_Analyzed": {
                    "type": "text",
                    "index": true
                },
                "geolocation": {
                    "type": "geo_point"
                }
           }
        } """
    return {'items': mapping}


def pipeline(*iterators):
    """Wrap all iterators around each other in the given order."""
    pipeline = None
    for it in iterators:
        if pipeline is None:
            pipeline = it
        else:
            pipeline = it(pipeline)
    return pipeline


def range_conversion(x, c, d):
    """
    Function to convert an initial range of [-1,1] to any custom range desired
    Parameters
    ----------
    x: float
        The value to convert
    c: float
        new range min value
    d: float
        new range max value
    Returns
    -------
    y: float
        the converted x value to the new range

    """
    a = -1
    b = 1
    y = (x - a) * float(d - c) / (b - a) + c
    y = round(y, 2)
    return y


def test_bit(int_type, offset):
    """
    testBit() returns True if the bit at 'offset' is one.
    From http://wiki.python.org/moin/BitManipulation
    """
    mask = 1 << offset
    return bool(int_type & mask)


def outlier_removal_null(dataframe, colname, low_cut, high_cut):
    """Replace outliers with empty values on dataframe[colname]"""
    col = dataframe[colname]
    dataframe.loc[col.apply(lambda x: isinstance(x, (int, float)) and (x <
        low_cut or x > high_cut)), colname] = None
    return dataframe


def make_opacity_dict(lam, a, k_abs, k_sca, g_sca, rho_s, zscat=None):
    """
    To mimick the behavior of the `makedustopac.py` code by Kees Dullemond:
    package the opacity information to a dictionary.
    """
    package = {'lamcm': lam, 'kabs': k_abs, 'kscat': k_sca, 'gscat': g_sca,
        'rho_s': rho_s, 'a': a, 'zscat': zscat}
    return package


@staticmethod
def _remove_none_filter(row):
    """remove any rows which have None as grouping key

        [GroupingResults(grouping_key="key1", results={})] rows get created
        when partition does not get any grouped data assigned to it
        """
    if len(row[0].results) > 0 and row[0].grouping_key is not None:
        return row


def safe_super(_class, _inst):
    """safe super call that resolves for the same method
    even with multiple inheritance"""
    try:
        return getattr(super(_class, _inst), _inst.__fname__)
    except:
        return lambda *x, **kx: ()


def valide(coord, liste_coord):
    """Évite deux points trop proches l'un de l'autre"""
    rep = True
    for c in liste_coord:
        if abs(coord[0] - c[0]) <= 0.5 and abs(coord[1] - c[1]) <= 0.5:
            rep = False
            break
    return rep


def remove_empty(entry):
    """
        Filters all empty strings and 'None' entries from a list
    """
    return len(entry) >= 1


def invalidate():
    """Causes the next access to reread the dirstate.

        This is different from localrepo.invalidatedirstate() because it always
        rereads the dirstate. Use localrepo.invalidatedirstate() if you want to
        check whether the dirstate has changed before rereading it."""


def select_less():
    """Shrink the current selection of adjacent selected strips

    """
    pass


def get_nodes(graph, metanode):
    """
    Return a list of nodes for a given metanode, in sorted order.
    """
    metanode = graph.metagraph.get_metanode(metanode)
    metanode_to_nodes = graph.get_metanode_to_nodes()
    nodes = sorted(metanode_to_nodes[metanode])
    return nodes


def p_AttributeOrOperation_stringifier(p):
    """AttributeOrOperation : stringifier StringifierAttributeOrOperation
  """
    p[0] = p[2]
    p[0].stringifier = True


def resolve_merge_commit(commit):
    """
  If commit was made by merge-queue, find the real owner and return that
  commit.
  """
    try:
        while commit.author.email.startswith(u'merge'):
            commit = commit.parents[-1]
        return commit
    except:
        return None


def make_list_fill_var(to_check, length=0, var=None):
    """Returns a list with the objects or a list filled with var."""
    if not isinstance(to_check, list):
        to_check = [to_check]
    difference = length - len(to_check)
    if difference > 0:
        to_check += [var] * difference
    return to_check


def id_maker(type_name, id_number):
    """Generate a consistent ID that is unique within a document,
    assuming `id_number` is unique within the tag type.
    """
    return '%s_%s' % (type_name.upper(), str(id_number))


def log_create_repository(repository_dict, created_by, **kwargs):
    """
    Post create repository Hook.

    :param repository: dict dump of repository object
    :param created_by: username who created repository

    available keys of repository_dict:

     'repo_type',
     'description',
     'private',
     'created_on',
     'enable_downloads',
     'repo_id',
     'owner_id',
     'enable_statistics',
     'clone_uri',
     'fork_id',
     'group_id',
     'repo_name'

    """
    from kallithea import EXTENSIONS
    callback = getattr(EXTENSIONS, 'CREATE_REPO_HOOK', None)
    if callable(callback):
        kw = {}
        kw.update(repository_dict)
        kw.update({'created_by': created_by})
        kw.update(kwargs)
        return callback(**kw)
    return 0


@classmethod
def _parse_production_url(cls, parsed_url, emulator_host):
    """Parses production URL like https://foo-bar.firebaseio.com/"""
    if parsed_url.scheme != 'https':
        raise ValueError(
            'Invalid database URL scheme: "{0}". Database URL must be an HTTPS URL.'
            .format(parsed_url.scheme))
    namespace = parsed_url.netloc.split('.')[0]
    if not namespace:
        raise ValueError(
            'Invalid database URL: "{0}". Database URL must be a valid URL to a Firebase Realtime Database instance.'
            .format(parsed_url.geturl()))
    if emulator_host:
        base_url = 'http://{0}'.format(emulator_host)
    else:
        base_url = 'https://{0}'.format(parsed_url.netloc)
    return base_url, namespace


def context_cycle_int(data_path: str='', reverse: bool=False, wrap: bool=False
    ):
    """Set a context value (useful for cycling active material, vertex keys, groups, etc.)

    :param data_path: Context Attributes, RNA context string
    :type data_path: str
    :param reverse: Reverse, Cycle backwards
    :type reverse: bool
    :param wrap: Wrap, Wrap back to the first/last values
    :type wrap: bool
    """
    pass


def excess_missing_data_flagger_and_cutter(df, useful_cols,
    nan_fraction_threshold=0.15, cutter=True):
    """
    Function calculates `null_count_density` (number of missing values for each feature as a fraction of the /
    number of samples), and, if specified, culls these from the input dataframe (inplace)

    Parameters
    ----------
    df : pandas.DataFrame
        Desired features
    useful_cols : pandas.DataFrame
        Lookup table detailing desired features
    nan_fraction_threshold : int
        Threshold for fraction of samples with missing values (for a given feature) above which the feature is deemed unacceptable
    cutter : bool
        If true [default], df is modified to remove features with an unacceptably large fraction of missing values

    Returns
    -------
    null_counts : pandas.Series
        Record of number of missing values for each feature
    null_count_density : pandas.Series
        Record of number of missing values for each feature as fraction of number of samples
    excess_null_count : list
        List of features where the null count density exceeds `nan_fraction_threshold`
    useful_cols : pandas.DataFrame
        Returned unchanged if `cutter` == False, else the clipped features are removed
    """
    null_counts = df.isna().sum()
    null_count_density = null_counts / df.shape[0]
    excess_null_count = null_count_density[null_count_density >
        nan_fraction_threshold]
    excess_null_count = list(null_count_density[null_count_density >
        nan_fraction_threshold].index)
    if cutter == True and len(excess_null_count) > 0:
        print(
            f'Following features dropped for having a null count density greater than {nan_fraction_threshold}: {excess_null_count} and have been dropped'
            )
        df.drop(excess_null_count, axis=1, inplace=True)
        useful_cols = useful_cols.loc[(~useful_cols.feature.isin(
            excess_null_count)), :]
    return null_counts, null_count_density, excess_null_count, useful_cols


def numericise(value, empty2zero=False, default_blank=''):
    """Returns a value that depends on the input string:
        - Float if input can be converted to Float
        - Integer if input can be converted to integer
        - Zero if the input string is empty and empty2zero flag is set
        - The same input string, empty or not, otherwise.

    Executable examples:

    >>> numericise("faa")
    'faa'
    >>> numericise("3")
    3
    >>> numericise("3.1")
    3.1
    >>> numericise("", empty2zero=True)
    0
    >>> numericise("", empty2zero=False)
    ''
    >>> numericise("", default_blank=None)
    >>>
    >>> numericise("", default_blank="foo")
    'foo'
    >>> numericise("")
    ''
    >>> numericise(None)
    >>>
    """
    if value is not None:
        try:
            value = int(value)
        except ValueError:
            try:
                value = float(value)
            except ValueError:
                if value == '':
                    if empty2zero:
                        value = 0
                    else:
                        value = default_blank
    return value


def vacuum_to_air(lambda_vac):
    """
    Vacuum-to-air wavelength conversion

    Args:
        lambda_vac: vacuum wavelength in Angstrom

    Returns:
        lambda_air: air wavelength in Angstrom

    Source:
        http://www.astro.uu.se/valdwiki/Air-to-vacuum%20conversion

    Original reference:
        Donald Morton (2000, ApJ. Suppl., 130, 403)

    Example:

    >>> # The following code converts wavenumber=2000 cm**-1 to wavelength in Angstrom
    >>> vacuum_to_air(1e8/2000)
    49986.36934549974
    """
    s = 10000.0 / lambda_vac
    n = 1 + 8.34254e-05 + 0.02406147 / (130 - s ** 2) + 0.00015998 / (38.9 -
        s ** 2)
    lambda_air = lambda_vac / n
    return lambda_air


def is_transition_allowed(transition, silent=False):
    """Checks whether a transition is currently allowed.
        This will automatically add warning / error messages unless
        ``silent=True`` is passed.
        """


def fit_exponential(X, y):
    """
    Fits an exponential curve to the data.
    """
    raise NotImplementedError('Exponential best fit lines are not implemented')


def _powers(base):
    """generate an infinite series of powers of the specified base"""
    power = 1
    while True:
        yield power
        power *= base


def normalize_intensity(window):
    """Normalize interrogation window by removing the mean value.

    Parameters
    ----------
    window :  2d np.ndarray
        the interrogation window array

    Returns
    -------
    window :  2d np.ndarray
        the interrogation window array, with mean value equal to zero.

    """
    return window - window.mean()


def get_version(package):
    """Return a package version as a 3-tuple of integers.
    """
    if package == 'numba':
        import numba
        v = numba.__version__.replace('rc', '.').replace('dev', '.').split('.')
        return tuple(map(int, v[:3]))
    raise NotImplementedError(f'get version of package {package}')


def getCreatorPath():
    """ Returns a string of the path to the user object in the user
        folder they were found in. """


def keyitem_restore(item_id: int=0):
    """Restore key map item

    :param item_id: Item Identifier, Identifier of the item to remove
    :type item_id: int
    """
    pass


def needs_update():
    """return if this feed needs to be updated."""


def move(x, y, z):
    """string for the move action"""
    return 'move_' + x + '_from_' + y + '_to_' + z


def get_n_rings(mol):
    """
    Computes the number of rings in a molecule
    """
    return mol.GetRingInfo().NumRings()


def lambd_NH3_NH4_CB89(T, P):
    """n-c: ammonia ammonium [CB89]."""
    lambd = 0
    valid = T == 298.15
    return lambd, valid


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

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

    Example::

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

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


def _element_list(an, no):
    """Binary mapping of homoatomic interactions.

    Parameters
    ----------
    an : list
        List of atom numbers.
    no : int
        Select atom number.
    """
    binary_inter = []
    for n in an:
        if n == no:
            binary_inter.append(1.0)
        else:
            binary_inter.append(0.0)
    return binary_inter


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

        :param LookupError val:
        :rtype: ThumbnailV2Error
        """
    return cls('path', val)


def read(filename, binary=True):
    """
    Open and read a file

    :param filename: filename to open and read
    :param binary: True if the file should be read as binary
    :return: bytes if binary is True, str otherwise
    """
    with open(filename, 'rb' if binary else 'r') as f:
        return f.read()


def _upcount(ls):
    """
    count the ratio of upmove days by given a list
    """
    count = 0
    for i in range(len(ls) - 1):
        if ls.iloc[i + 1] > ls.iloc[i]:
            count += 1
    return count / (len(ls) - 1)


def mean_and_error(a1, a2):
    """calculate mean and error from two 1D array-like

    Examples
    --------
    >>> import pytraj as pt
    >>> a0 = [2, 4, 6]
    >>> a1 = [3, 5, 7]
    >>> mean_and_error(a0, a1)
    (4.5, 0.5)
    """
    import numpy as np
    mean = np.mean
    a1 = np.asarray(a1)
    a2 = np.asarray(a2)
    assert len(a1.shape) == len(a2.shape) == 1, '1D array'
    return mean(a1 + a2) / 2, mean(np.abs(a1 - a2)) / 2


def transform_to_2d(data, max_axis):
    """
    Projects 3d data cube along one axis using maximum intensity with
    preservation of the signs. Adapted from nilearn.
    """
    import numpy as np
    new_shape = list(data.shape)
    del new_shape[max_axis]
    a1, a2 = np.indices(new_shape)
    inds = [a1, a2]
    inds.insert(max_axis, np.abs(data).argmax(axis=max_axis))
    maximum_intensity_data = data[inds]
    return np.rot90(maximum_intensity_data)


def booly(arg):
    """
    arg: str representing something boolean-like
    return: boolean representation of `arg`
    """
    comp = arg.lower()
    if comp in ('yes', 'y', 'true', 't', '1'):
        return True
    elif comp in ('no', 'n', 'false', 'f', '0'):
        return False
    else:
        raise ValueError('Could not convert {!r} to boolean'.format(arg))


def rocketLiftOff(currentForward, coords, startDrop, distance):
    """
    Controls the height of the rocket by simply increasing it by one each time.
    """
    global SelectedColour
    if (currentForward < startDrop) == 0:
        for i in range(0, len(coords)):
            coords[i][1] = coords[i][1] + 1
    return coords


def getUserNames(login_email, get_all=False):
    """returns the username for an email address as a string.
        If the get_all flag is set a list with all usernames for an email adress
        should be returned.
        """


def get_spc_dtype_list(load_all=False, endianess='<', version=0.61):
    """
    Get the data type list for an SPC spectrum.
    Further information about the file format is available `here
    <https://github.com/hyperspy/hyperspy/files/29506/SPECTRUM-V70.pdf>`__.

    Parameters
    ----------
    load_all : bool
        Switch to control if all the data is loaded, or if just the
        important pieces of the signal will be read (speeds up loading time)
    endianess : char
        byte-order used to read the data
    version : float
        version of spc file to read (only 0.61 and 0.70 have been tested)
        Default is 0.61 to be as backwards-compatible as possible, but the
        file version can be read from the file anyway, so this parameter
        should always be set programmatically

    Table of header tags:
        - fVersion: 4 byte float; *File format Version*
        - aVersion: 4 byte float; *Application Version*
        - fileName: 8 array of 1 byte char; *File name w/o '.spc' extension (OLD)*
        - collectDateYear: 2 byte short; *Year the spectrum was collected*
        - collectDateDay: 1 byte char; *Day the spectrum was collected*
        - collectDateMon: 1 byte char; *Month the spectrum was collected*
        - collectTimeMin: 1 byte char; *Minute the spectrum was collected*
        - collectTimeHour: 1 byte char; *Hour the spectrum was collected*
        - collectTimeHund: 1 byte char; *Hundredth second the spectrum was collected*
        - collectTimeSec: 1 byte char; *Second the spectrum was collected*
        - fileSize: 4 byte long; *Size of spectrum file in bytes*
        - dataStart: 4 byte long; *Start of spectrum data in bytes offset from 0 of file*
        - numPts: 2 byte short; *Number of spectrum pts*
        - intersectingDist: 2 byte short; *Intersecting distance * 100 (mm)*
        - workingDist: 2 byte short; *Working distance * 100*
        - scaleSetting: 2 byte short; *Scale setting distance * 100*

        - filler1: 24 byte;

        - spectrumLabel: 256 array of 1 byte char; *Type label for spectrum, 0-39=material type, 40-255=sample*
        - imageFilename: 8 array of 1 byte char; *Parent Image filename*
        - spotX: 2 byte short; *Spot X  in parent image file*
        - spotY: 2 byte short; *Spot Y in parent image file*
        - imageADC: 2 byte short; *Image ADC value 0-4095*
        - discrValues: 5 array of 4 byte long; *Analyzer Discriminator Values*
        - discrEnabled: 5 array of 1 byte unsigned char; *Discriminator Flags (0=Disabled,1=Enabled)*
        - pileupProcessed: 1 byte char; *Pileup Processed Flag (0=No PU,1=Static PU, 2=Dynamic PU,...)*
        - fpgaVersion: 4 byte long; *Firmware Version.*
        - pileupProcVersion: 4 byte long; *Pileup Processing Software Version*
        - NB5000CFG: 4 byte long; *Defines Hitachi NB5000 Dual Stage Cfg 0=None, 10=Eucentric Crossx,11= Eucentric Surface 12= Side Entry - Side 13 = Side Entry - Top*

        - filler2: 12 byte;

        - evPerChan: 4 byte long; *EV/channel*
        - ADCTimeConstant: 2 byte short; *ADC Time constant*
        - analysisType: 2 byte short; *Preset mode 1=clock, 2=count, 3=none, 4=live, 5=resume*
        - preset: 4 byte float; *Analysis Time Preset value*
        - maxp: 4 byte long; *Maximum counts of the spectrum*
        - maxPeakCh: 4 byte long; *Max peak channel number*
        - xRayTubeZ: 2 byte short; *XRF*
        - filterZ: 2 byte short; *XRF*
        - current: 4 byte float; *XRF*
        - sampleCond: 2 byte short; *XRF Air= 0, Vacuum= 1, Helium= 2*
        - sampleType: 2 byte short; *Bulk or thin*
        - xrayCollimator: 2 byte unsigned short; *0=None, 1=Installed*
        - xrayCapilaryType: 2 byte unsigned short; *0=Mono, 1=Poly*
        - xrayCapilarySize: 2 byte unsigned short; *Range : 20 – 5000 Microns*
        - xrayFilterThickness: 2 byte unsigned short; *Range : 0 – 10000 Microns*
        - spectrumSmoothed: 2 byte unsigned short; *1= Spectrum Smoothed, Else 0*
        - detector_Size_SiLi: 2 byte unsigned short; *Eagle Detector 0=30mm, 1=80mm*
        - spectrumReCalib: 2 byte unsigned short; *1= Peaks Recalibrated, Else 0*
        - eagleSystem: 2 byte unsigned short; *0=None, 2=Eagle2, 3=Eagle3, 4-Xscope*
        - sumPeakRemoved: 2 byte unsigned short; *1= Sum Peaks Removed, Else 0*
        - edaxSoftwareType: 2 byte unsigned short; *1= Team Spectrum, Else 0*

        - filler3: 6 byte;

        - escapePeakRemoved: 2 byte unsigned short; *1=Escape Peak Was Removed, Else 0*
        - analyzerType: 4 byte unsigned long; *Hardware type 1=EDI1, 2=EDI2, 3=DPP2, 31=DPP-FR, 32=DPP-FR2, 4=DPP3, 5= APOLLO XLT/XLS/DPP-4 (EDPP)*
        - startEnergy: 4 byte float; *Starting energy of spectrum*
        - endEnergy: 4 byte float; *Ending energy of spectrum*
        - liveTime: 4 byte float; *LiveTime*
        - tilt: 4 byte float; *Tilt angle*
        - takeoff: 4 byte float; *Take off angle*
        - beamCurFact: 4 byte float; *Beam current factor*
        - detReso: 4 byte float; *Detector resolution*
        - detectType: 4 byte unsigned long; *Detector Type: 1=Std-BE, 2=UTW, 3=Super UTW, 4=ECON 3/4 Open, 5=ECON 3/4 Closed, 6=ECON 5/6 Open, 7=ECON 5/6 Closed, 8=TEMECON; Add + 10 For Sapphire SiLi Detectors, (11-18), which started shipping in 1996. 30 = APOLLO 10 SDD, 31=APOLLO XV, 32 = APOLLO 10+, 40 = APOLLO 40 SDD ,50 = APOLLO-X, 51=APOLLO-XP, 52 = APOLLO-XL, 53 = APOLLO XL-XRF, 60 =APOLLO-XLT-LS, 61 =APOLLO-XLT-NW, 62 =APOLLO-XLT-SUTW*
        - parThick: 4 byte float; *Parlodion light shield thickness*
        - alThick: 4 byte float; *Aluminum light shield thickness*
        - beWinThick: 4 byte float; *Be window thickness*
        - auThick: 4 byte float; *Gold light shield thickness*
        - siDead: 4 byte float; *Si dead layer thickness*
        - siLive: 4 byte float; *Si live layer thickness*
        - xrayInc: 4 byte float; *X-ray incidence angle*
        - azimuth: 4 byte float; *Azimuth angle of detector*
        - elevation: 4 byte float; *Elevation angle of detector*
        - bCoeff: 4 byte float; *K-line B coefficient*
        - cCoeff: 4 byte float; *K-line C coefficient*
        - tailMax: 4 byte float; *Tail function maximum channel*
        - tailHeight: 4 byte float; *Tail height adjustment percentage*
        - kV: 4 byte float; *Acc voltage*
        - apThick: 4 byte float; *Ap window thickness*
        - xTilt: 4 byte float; *x tilt angle for mDX*
        - yTilt: 4 byte float; *y tilt angle for mDX*
        - yagStatus: 4 byte unsigned long; *0 = N/A, 1 = YAG OUT, 2 = YAG IN*

        - filler4: 24 byte;

        - rawDataType: 2 byte unsigned short; *TEM or SEM data*
        - totalBkgdCount: 4 byte float; *Accumulated background counts*
        - totalSpectralCount: 4 byte unsigned long; *Accumulated spectrum counts*
        - avginputCount: 4 byte float; *Average spectral counts*
        - stdDevInputCount: 4 byte float; *Standard deviation of spectral counts*
        - peakToBack: 2 byte unsigned short; *Peak to background setting. 0 = off, 1 = low, 2 = medium, 3 = high, 4 = user selected*
        - peakToBackValue: 4 byte float; *Peak to back value*

        - filler5: 38 byte;

        - numElem: 2 byte short; *Number of peak id elements 0-48*
        - at: 48 array of 2 byte unsigned short; *atomic numbers for peak id elems*
        - line: 48 array of 2 byte unsigned short; *line numbers for peak id elems*
        - energy: 48 array of 4 byte float; *float energy of identified peaks*
        - height: 48 array of 4 byte unsigned long; *height in counts of id' ed peaks*
        - spkht: 48 array of 2 byte short; *sorted peak height of id' ed peaks*

        - filler5_1: 30 byte;

        - numRois: 2 byte short; *Number of ROI's defined 0-48*
        - st: 48 array of 2 byte short; *Start channel # for each ROI*
        - end: 48 array of 2 byte short; *End channel # for each ROI*
        - roiEnable: 48 array of 2 byte short; *ROI enable/disable flags*
        - roiNames: (24 x 8) array of 1 byte char; *8 char name for eah ROI*

        - filler5_2: 1 byte;

        - userID: 80 array of 1 byte char; *User ID (Vision S/W) - Overlapping*

        - filler5_3: 111 byte;

        - sRoi: 48 array of 2 byte short; *sorted ROI heights*
        - scaNum: 48 array of 2 byte short; *SCA number assigned for each ROI*

        - filler6: 12 byte;

        - backgrdWidth: 2 byte short; *Background width*
        - manBkgrdPerc: 4 byte float; *Percentage to move manual background down*
        - numBkgrdPts: 2 byte short; *Number of background points (2-64)*
        - backMethod: 4 byte unsigned long; *Background method 1=auto, 2=manual*
        - backStEng: 4 byte float; *Starting energy of background*
        - backEndEng: 4 byte float; *Ending energy of background*
        - bg: 64 array of 2 byte short; *Channel # of background point*
        - bgType: 4 byte unsigned long; *Background type. 1 = curve, 2 = linear.*
        - concenKev1: 4 byte float; *First concentration background point*
        - concenKev2: 4 byte float; *Second concentration background point*
        - concenMethod: 2 byte short; *0 = Off, 1 = On*
        - jobFilename: 32 array of 1 byte char; *Vision Job Filename*

        - filler7: 16 byte;

        - numLabels: 2 byte short; *Number of displayed labels*
        - label: (10 x 32) array 1 byte char; *32 character labels on the spectrum*
        - labelx: 10 array of 2 byte short; *x position of label in terms of channel #*
        - labely: 10 array of 4 byte long; *y position of label in terms of counts*
        - zListFlag: 4 byte long; *Flag to indicate if Z List was written*
        - bgPercents: 64 array of 4 byte float; *Percentage to move background point up and down.*
        - IswGBg: 2 byte short; *= 1 if new backgrd pts exist*
        - BgPoints: 5 array of 4 byte float; *Background points*
        - IswGConc: 2 byte short; *= 1 if given concentrations exist*
        - numConcen: 2 byte short; *Number of elements (up to 24)*
        - ZList: 24 array of 2 byte short; *Element list for which given concentrations exist*
        - GivenConc: 24 array of 4 byte float; *Given concentrations for each element in Zlist*

        - filler8: 598 byte;

        - s: 4096 array of 4 byte long; *counts for each channel*
        - longFileName: 256 array of 1 byte char; *Long filename for 32 bit version*
        - longImageFileName: 256 array of 1 byte char; *Associated long image file name*
        - ADCTimeConstantNew: 4 byte float; *Time constant: 2.5… 100 OR 1.6… 102.4 us*

        # the following datatypes are only included for version 0.70:

        - filler9: 60 byte;

        - numZElements: 2 byte short; *number of Z List elements for quant*
        - zAtoms: 48 array of 2 byte short; *Z List Atomic numbers*
        - zShells: 48 array of 2 byte short; *Z List Shell numbers*

    Returns
    -------
    dtype_list : list
        List of the data tags and data types that will be used by numpy to
        read an SPC file header.
    """
    end = endianess
    if load_all:
        dtype_list = [('fVersion', end + 'f4'), ('aVersion', end + 'f4'), (
            'fileName', '8i1'), ('collectDateYear', end + 'i2'), (
            'collectDateDay', end + 'i1'), ('collectDateMon', end + 'i1'),
            ('collectTimeMin', end + 'i1'), ('collectTimeHour', end + 'i1'),
            ('collectTimeHund', end + 'i1'), ('collectTimeSec', end + 'i1'),
            ('fileSize', end + 'i4'), ('dataStart', end + 'i4'), ('numPts',
            end + 'i2'), ('intersectingDist', end + 'i2'), ('workingDist',
            end + 'i2'), ('scaleSetting', end + 'i2'), ('filler1', 'V24'),
            ('spectrumLabel', '256i1'), ('imageFilename', '8i1'), ('spotX',
            end + 'i2'), ('spotY', end + 'i2'), ('imageADC', end + 'i2'), (
            'discrValues', end + '5i4'), ('discrEnabled', end + '5i1'), (
            'pileupProcessed', end + 'i1'), ('fpgaVersion', end + 'i4'), (
            'pileupProcVersion', end + 'i4'), ('NB5000CFG', end + 'i4'), (
            'filler2', 'V12'), ('evPerChan', end + 'i4'), (
            'ADCTimeConstant', end + 'i2'), ('analysisType', end + 'i2'), (
            'preset', end + 'f4'), ('maxp', end + 'i4'), ('maxPeakCh', end +
            'i4'), ('xRayTubeZ', end + 'i2'), ('filterZ', end + 'i2'), (
            'current', end + 'f4'), ('sampleCond', end + 'i2'), (
            'sampleType', end + 'i2'), ('xrayCollimator', end + 'u2'), (
            'xrayCapilaryType', end + 'u2'), ('xrayCapilarySize', end +
            'u2'), ('xrayFilterThickness', end + 'u2'), ('spectrumSmoothed',
            end + 'u2'), ('detector_Size_SiLi', end + 'u2'), (
            'spectrumReCalib', end + 'u2'), ('eagleSystem', end + 'u2'), (
            'sumPeakRemoved', end + 'u2'), ('edaxSoftwareType', end + 'u2'),
            ('filler3', 'V6'), ('escapePeakRemoved', end + 'u2'), (
            'analyzerType', end + 'u4'), ('startEnergy', end + 'f4'), (
            'endEnergy', end + 'f4'), ('liveTime', end + 'f4'), ('tilt',
            end + 'f4'), ('takeoff', end + 'f4'), ('beamCurFact', end +
            'f4'), ('detReso', end + 'f4'), ('detectType', end + 'u4'), (
            'parThick', end + 'f4'), ('alThick', end + 'f4'), ('beWinThick',
            end + 'f4'), ('auThick', end + 'f4'), ('siDead', end + 'f4'), (
            'siLive', end + 'f4'), ('xrayInc', end + 'f4'), ('azimuth', end +
            'f4'), ('elevation', end + 'f4'), ('bCoeff', end + 'f4'), (
            'cCoeff', end + 'f4'), ('tailMax', end + 'f4'), ('tailHeight',
            end + 'f4'), ('kV', end + 'f4'), ('apThick', end + 'f4'), (
            'xTilt', end + 'f4'), ('yTilt', end + 'f4'), ('yagStatus', end +
            'u4'), ('filler4', 'V24'), ('rawDataType', end + 'u2'), (
            'totalBkgdCount', end + 'f4'), ('totalSpectralCount', end +
            'u4'), ('avginputCount', end + 'f4'), ('stdDevInputCount', end +
            'f4'), ('peakToBack', end + 'u2'), ('peakToBackValue', end +
            'f4'), ('filler5', 'V38'), ('numElem', end + 'i2'), ('at', end +
            '48u2'), ('line', end + '48u2'), ('energy', end + '48f4'), (
            'height', end + '48u4'), ('spkht', end + '48i2'), ('filler5_1',
            'V30'), ('numRois', end + 'i2'), ('st', end + '48i2'), ('end',
            end + '48i2'), ('roiEnable', end + '48i2'), ('roiNames',
            '(24,8)i1'), ('filler5_2', 'V1'), ('userID', '80i1'), (
            'filler5_3', 'V111'), ('sRoi', end + '48i2'), ('scaNum', end +
            '48i2'), ('filler6', 'V12'), ('backgrdWidth', end + 'i2'), (
            'manBkgrdPerc', end + 'f4'), ('numBkgrdPts', end + 'i2'), (
            'backMethod', end + 'u4'), ('backStEng', end + 'f4'), (
            'backEndEng', end + 'f4'), ('bg', end + '64i2'), ('bgType', end +
            'u4'), ('concenKev1', end + 'f4'), ('concenKev2', end + 'f4'),
            ('concenMethod', end + 'i2'), ('jobFilename', end + '32i1'), (
            'filler7', 'V16'), ('numLabels', end + 'i2'), ('label', end +
            '(10,32)i1'), ('labelx', end + '10i2'), ('labely', end + '10i4'
            ), ('zListFlag', end + 'i4'), ('bgPercents', end + '64f4'), (
            'IswGBg', end + 'i2'), ('BgPoints', end + '5f4'), ('IswGConc',
            end + 'i2'), ('numConcen', end + 'i2'), ('ZList', end + '24i2'),
            ('GivenConc', end + '24f4'), ('filler8', 'V598'), ('s', end +
            '4096i4'), ('longFileName', end + '256i1'), (
            'longImageFileName', end + '256i1')]
        if version >= 0.7:
            dtype_list.extend([('ADCTimeConstantNew', end + 'f4'), (
                'filler9', 'V60'), ('numZElements', end + 'i2'), ('zAtoms',
                end + '48i2'), ('zShells', end + '48i2')])
    else:
        dtype_list = [('filler1', 'V28'), ('dataStart', end + 'i4'), (
            'numPts', end + 'i2'), ('filler1_1', 'V350'), ('evPerChan', end +
            'i4'), ('filler2', 'V60'), ('startEnergy', end + 'f4'), (
            'endEnergy', end + 'f4'), ('liveTime', end + 'f4'), ('tilt',
            end + 'f4'), ('filler3', 'V8'), ('detReso', end + 'f4'), (
            'filler4', 'V32'), ('azimuth', end + 'f4'), ('elevation', end +
            'f4'), ('filler5', 'V16'), ('kV', end + 'f4'), ('filler6',
            'V102'), ('numElem', end + 'i2'), ('at', end + '48u2'), (
            'filler7', 'V20004')]
    return dtype_list


@classmethod
def has_resuming(cls):
    """Returns whether it supports to resume the fetch process.

        :returns: this backend supports items resuming
        """
    return True


def strip_base_dir(filename, base_dir):
    """Strip base directory from filename if it starts there.

    >>> strip_base_dir('/path/to/base/relpath/to/file',
    ...                '/path/to/base/')
    'relpath/to/file'

    >>> strip_base_dir('/path/to/somewhere/else/relpath/to/file',
    ...                '/path/to/base/')
    '/path/to/somewhere/else/relpath/to/file'

    """
    if filename.startswith(base_dir):
        filename = filename[len(base_dir):]
    return filename


def inclusive(data):
    """Return sample quartiles using Tukey's method.

        Q1 and Q3 are calculated as the medians of the two halves of the data,
        where the median Q2 is included in both halves. This is equivalent to
        Tukey's hinges H1, M, H2.
        """
    n = len(data)
    i = (n + 1) // 4
    m = n // 2
    if n % 4 in (0, 3):
        q1 = (data[i] + data[i - 1]) / 2
        q3 = (data[-i - 1] + data[-i]) / 2
    else:
        q1 = data[i]
        q3 = data[-i - 1]
    if n % 2 == 0:
        q2 = (data[m - 1] + data[m]) / 2
    else:
        q2 = data[m]
    return q1, q2, q3


def get_event_binding_key(organization: str, service: str):
    """
    acme.onboarding.1.event.user.created
      |       |      |        |      |-> Action (past verb)
      |       |      |        |-> domain entity
      |       |      |-> version
      |       |-> service
      |-> organization
    """
    return f'{organization}.{service}.*.event.#'


def not_implemented(f):
    """Decorator for unimplemented methods.

    The function is effectively removed (set to None).

    """
    return


def str_2_bytes(input_str):
    """
    用于将 str 类型转换为 bytes 类型
    :param input_str:
    :return:
    """
    return input_str.encode(encoding='GBK')


def encode_items(items):
    """
    Function that encode all elements in the list of items passed as a parameter.

    :param items:  A list of tuple
    :returns:      A list of tuple with all items encoded in 'utf-8'
    """
    encoded = []
    for key, values in items:
        for value in values:
            encoded.append((key.encode('utf-8'), value.encode('utf-8')))
    return encoded


def beginningPage(R):
    """As pages may not be given as numbers this is the most accurate this function can be"""
    p = R['PG']
    if p.startswith('suppl '):
        p = p[6:]
    return p.split(' ')[0].split('-')[0].replace(';', '')


def str_at_begin_of_str(str1, str2):
    """
        from xdict.utils import *
        str_at_begin_of_str('abc','abcd')
    """
    len1 = str1.__len__()
    begin = str2[:len1]
    if str1 == begin:
        return True
    else:
        return False


def background_image_remove(index: int=0):
    """Remove a background image from the 3D view

    :param index: Index, Background image index to remove
    :type index: int
    """
    pass


def grouper_list(l, n):
    """Evenly divide list into fixed-length piece, no filled value if chunk
    size smaller than fixed-length.

    Example::

        >>> list(grouper(range(10), n=3)
        [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9]]

    **中文文档**

    将一个列表按照尺寸n, 依次打包输出, 有多少输出多少, 并不强制填充包的大小到n。

    下列实现是按照性能从高到低进行排列的:

    - 方法1: 建立一个counter, 在向chunk中添加元素时, 同时将counter与n比较, 如果一致
      则yield。然后在最后将剩余的item视情况yield。
    - 方法2: 建立一个list, 每次添加一个元素, 并检查size。
    - 方法3: 调用grouper()函数, 然后对里面的None元素进行清理。
    """
    chunk = list()
    counter = 0
    for item in l:
        counter += 1
        chunk.append(item)
        if counter == n:
            yield chunk
            chunk = list()
            counter = 0
    if len(chunk) > 0:
        yield chunk


def set_or_delete(dictionary, key, value):
    """
    Set value as value of dict key key. If value is None, delete key key from dict.

    :param dictionary: Dictionary to work on.
    :param key: Key to set or delete. If deleting and key does not exist in dict, nothing is done.
    :param value: Value to set. If value is None, delete key.
    :return: Nothing, modifies dict in place.
    """
    if value:
        dictionary[key] = value
    elif dictionary.get(key):
        del dictionary[key]


def create_urwid_toplevel():
    """Create a toplevel widget.
        """


def _process_text(text, _infile_extension):
    """Process extracted text and return it as a simple string."""
    text = text.decode('utf-8')
    if _infile_extension == '.pdf' or _infile_extension == 'pdf':
        text = text.strip()
    return text


def isSiteSyndicationAllowed():
    """ Return the site-wide syndication flag
        """


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

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


def isFrozen(status):
    """
    Return a boolean indicating whether the given status name is frozen or not.

    @type status: C{unicode}
    @rtype: C{bool}
    """
    return status.startswith(u'.')


def str2int(s):
    """Convert a byte string to an integer.

    @param s: byte string representing a positive integer to convert
    @return: converted integer
    """
    s = bytearray(s)
    r = 0
    for c in s:
        r = r << 8 | c
    return r


def validate_template(template):
    """Check that the provided template only consists of DNA nucleotides"""
    for base in template:
        if base not in 'GATC':
            raise ValueError('template must consist of only GATC')


def conv_input_length(output_length, filter_size, stride, pad=0):
    """Helper function to compute the input size of a convolution operation

    This function computes the length along a single axis, which corresponds
    to a 1D convolution. It can also be used for convolutions with higher
    dimensionalities by using it individually for each axis.

    Parameters
    ----------
    output_length : int or None
        The size of the output.

    filter_size : int
        The size of the filter.

    stride : int
        The stride of the convolution operation.

    pad : int, 'full' or 'same' (default: 0)
        By default, the convolution is only computed where the input and the
        filter fully overlap (a valid convolution). When ``stride=1``, this
        yields an output that is smaller than the input by ``filter_size - 1``.
        The `pad` argument allows you to implicitly pad the input with zeros,
        extending the output size.

        A single integer results in symmetric zero-padding of the given size on
        both borders.

        ``'full'`` pads with one less than the filter size on both sides. This
        is equivalent to computing the convolution wherever the input and the
        filter overlap by at least one position.

        ``'same'`` pads with half the filter size on both sides (one less on
        the second side for an even filter size). When ``stride=1``, this
        results in an output size equal to the input size.

    Returns
    -------
    int or None
        The smallest input size corresponding to the given convolution
        parameters for the given output size, or ``None`` if `output_size` is
        ``None``. For a strided convolution, any input size of up to
        ``stride - 1`` elements larger than returned will still give the same
        output size.

    Raises
    ------
    ValueError
        When an invalid padding is specified, a `ValueError` is raised.

    Notes
    -----
    This can be used to compute the output size of a convolution backward pass,
    also called transposed convolution, fractionally-strided convolution or
    (wrongly) deconvolution in the literature.
    """
    if output_length is None:
        return None
    if pad == 'valid':
        pad = 0
    elif pad == 'full':
        pad = filter_size - 1
    elif pad == 'same':
        pad = filter_size // 2
    if not isinstance(pad, int):
        raise ValueError('Invalid pad: {0}'.format(pad))
    return (output_length - 1) * stride - 2 * pad + filter_size


def clean_kwargs(kwargs):
    """Format the kwargs to conform to API"""
    for key, value in kwargs.iteritems():
        if hasattr(value, '__iter__'):
            kwargs[key] = ','.join(map(str, value))


@staticmethod
def filenames_diff_cmd(r):
    """Get the names of the py files in diff."""
    return ['bzr', 'status', '-S', '-r', r.rev]


@classmethod
def run(cls, session_name=None, macro=None, sessions_file=None):
    """Run the application"""
    instance = cls(session_name, sessions_file=sessions_file)
    instance.start_ui(macro)
    if instance.connection:
        instance.connection.close()


def parallel_gpu_jobs(allow_growth=True, fraction=0.5):
    """Sets the max used memory as a fraction for tensorflow
    backend

    allow_growth :: True of False

    fraction :: a float value (e.g. 0.5 means 4gb out of 8gb)

    """
    import keras.backend as K
    import tensorflow as tf
    gpu_options = tf.GPUOptions(allow_growth=allow_growth,
        per_process_gpu_memory_fraction=fraction)
    config = tf.ConfigProto(gpu_options=gpu_options)
    session = tf.Session(config=config)
    K.set_session(session)


def geq(first=None, second=None):
    """ Checks if first element is greater than or equals the second """
    if first is None or second is None:
        return True
    return first >= second


def num_authors(df, period: str):
    """ Number of authors in a given time period.

    :param df: pd.DataFrame, base table
    :param period: str, 'Y', year
    :return: df aggregated by period
    :rtype: pd.DataFrame
    """
    per = df.ts.dt.to_period(period)
    cols = ['name', 'owner_name', 'project_name']
    grp = [per, 'owner_name', 'project_name']
    result = df[cols].groupby(grp).count()
    result.columns = ['num_authors']
    result = result.reset_index()
    return result


@classmethod
def pubsub_serialize(cls, instance, serializer):
    """ Serialize the given model instance before sending it to the users.

        :param instance: Model instance
        :param serializer: Drf serializer
        :return:
        """
    return serializer.to_representation(instance)


def uuid2bytes(u):
    """ Return compact bytes for UUID. """
    if u is None:
        return ''
    return ''.join(u.split('-')).decode('hex')


@staticmethod
def is_empty(s):
    """注意：该函数先去掉首尾空格再判断是否为空"""
    return 0 == len(s.strip())


def split_at(iterable, pred):
    """Yield lists of items from *iterable*, where each list is delimited by
    an item where callable *pred* returns ``True``. The lists do not include
    the delimiting items.

        >>> list(split_at('abcdcba', lambda x: x == 'b'))
        [['a'], ['c', 'd', 'c'], ['a']]

        >>> list(split_at(range(10), lambda n: n % 2 == 1))
        [[0], [2], [4], [6], [8], []]
    """
    buf = []
    for item in iterable:
        if pred(item):
            yield buf
            buf = []
        else:
            buf.append(item)
    yield buf


def p_enum_values(p):
    """
    enum_values : enum_values ',' enum_value
                | enum_value
    """
    if len(p) == 4:
        p[0] = p[1] + [p[3]]
    elif len(p) == 2:
        p[0] = [p[1]]


def median(a):
    """
    Return the median of the elements of array a.
    """
    b = list(a)
    b.sort()
    length = len(b)
    if length % 2 == 1:
        return b[length // 2]
    else:
        return float(b[length // 2 - 1] + b[length // 2]) / 2.0


def get_csrf_token(request):
    """ Return a cross-site request forgery protection token.  It
        will be an ascii-compatible unicode string.  If a token was previously
        set for this user via ``new_csrf_token``, that token will be returned.
        If no CSRF token was previously set, ``new_csrf_token`` will be
        called, which will create and set a token, and this token will be
        returned.

        """


def _parse_content_type_header(header):
    """Returns content type and parameters from given header

    :param header: string
    :return: tuple containing content type and dictionary of
         parameters
    """
    tokens = header.split(';')
    content_type, params = tokens[0].strip(), tokens[1:]
    params_dict = {}
    items_to_strip = '"\' '
    for param in params:
        param = param.strip()
        if param:
            key, value = param, True
            index_of_equals = param.find('=')
            if index_of_equals != -1:
                key = param[:index_of_equals].strip(items_to_strip)
                value = param[index_of_equals + 1:].strip(items_to_strip)
            params_dict[key.lower()] = value
    return content_type, params_dict


def concatenate_script(list_ur_commands):
    """
    Internal function that concatenates generated UR script into one large
    script file. Usually used to combine scripts generated by the
    GrasshopperPython components

    Args:
        list_ur_commands: A list of formatted UR Script strings

    Returns:
        ur_script: The concatenated script
    """
    ur_script = '\ndef clay_script():\n'
    combined_script = ''
    for ur_cmd in list_ur_commands:
        combined_script += ur_cmd
    lines = combined_script.split('\n')
    for l in lines:
        ur_script += '\t' + l + '\n'
    ur_script += 'end\n'
    ur_script += '\nclay_script()\n'
    return ur_script


def get_first_val(key_tuple, dict_obj):
    """Return the first value mapped by a key in the given tuple.

    Parameters
    ----------
    key_tuple : tuple
        The keys to use for extraction, in order.
    dict_obj : dict
        The dict to extract from.

    Returns
    -------
    value : object
        The extracted value, if exists. Otherwise, raises KeyError.

    Example
    -------
    >>> dict_obj = {'a': 1, 'c': 2}
    >>> get_first_val(('a', 'b', 'c'), dict_obj)
    1
    >>> get_first_val(('b', 'c', 'a'), dict_obj)
    2
    >>> get_first_val(('e'), dict_obj)
    Traceback (most recent call last):
     ...
    KeyError: 'None of the provided keys was found'
    """
    for key in key_tuple:
        try:
            return dict_obj[key]
        except KeyError:
            pass
    raise KeyError('None of the provided keys was found')


def complete_openbis_config(config, resolver, local_only=True):
    """Add default values for empty entries in the config."""
    config_dict = resolver.config.config_dict(local_only)
    if config.get('url') is None:
        config['url'] = config_dict['openbis_url']
    if config.get('verify_certificates') is None:
        config['verify_certificates'] = config_dict['verify_certificates']
    if config.get('token') is None:
        config['token'] = None
    if config.get(
        'allow_http_but_do_not_use_this_in_production_and_only_within_safe_networks'
        ) is None:
        config[
            'allow_http_but_do_not_use_this_in_production_and_only_within_safe_networks'
            ] = not config_dict['allow_only_https']


def iterate(delay=0):
    """
        Run the main loop's I/O polling function for a period of time.

        This is most useful in applications where the UI is being drawn "as
        fast as possible", such as games. All pending L{IDelayedCall}s will
        be called.

        The reactor must have been started (via the C{run()} method) prior to
        any invocations of this method.  It must also be stopped manually
        after the last call to this method (via the C{stop()} method).  This
        method is not re-entrant: you must not call it recursively; in
        particular, you must not call it while the reactor is running.
        """


def as_string(dt):
    """Format datetime instance `dt` according to RFC2822.

    >>> print (as_string (datetime.datetime (2001, 11, 8, 20, 8, 47)))
    08 Nov 2001 20:08:47 -0000
    """
    result = dt.strftime('%d %b %Y %H:%M:%S %z')
    if dt.utcoffset() is None:
        result += '-0000'
    return result


@classmethod
def _to_str(cls, value):
    """Represents values either as string or None values as empty string.

        Args:
            value: a value

        """
    if value is None:
        return ''
    else:
        return str(value)


@staticmethod
def tf_weight_raw(tf):
    """Returns unscaled tf"""
    return tf


def to_brix(value):
    """
    Convert gravity value to brix value
    """
    brix = ((182.4601 * value - 775.6821) * value + 1262.7794
        ) * value - 669.5622
    return brix


@staticmethod
def _float_str(number: float) ->str:
    """
        Return a string representation for the given floating point number. Avoiding scientific notation, because this
        is unsupported by ffmpeg. Internally using 9 decimal digit precision, which translates to nanosecond precision if
        used for time.
        Try hard to not confuse ffmpeg, by removing all trailing zeros and, in case the number is an integer, the trailing
        decimal point.
        """
    return f'{number:0.9f}'.rstrip('0').rstrip('.')


def model_find_module(model, module_to_find):
    """Given a module name, find the module in the provided model.

    Arguments:
        model: the model to search
        module_to_find: the module whose name we want to look up

    Returns:
        The module or None, if the module was not found.
    """
    for name, m in model.named_modules():
        if name == module_to_find:
            return m
    return None


def describe_document_versions(DocumentId=None, Marker=None, Limit=None,
    Include=None, Fields=None):
    """
    Retrieves the document versions for the specified document.
    By default, only active versions are returned.
    See also: AWS API Documentation

    :example: response = client.describe_document_versions(
        DocumentId='string',
        Marker='string',
        Limit=123,
        Include='string',
        Fields='string'
    )

    :type DocumentId: string
    :param DocumentId: [REQUIRED]
            The ID of the document.

    :type Marker: string
    :param Marker: The marker for the next set of results. (You received this marker from a previous call.)

    :type Limit: integer
    :param Limit: The maximum number of versions to return with this call.

    :type Include: string
    :param Include: A comma-separated list of values. Specify 'INITIALIZED' to include incomplete versions.

    :type Fields: string
    :param Fields: Specify 'SOURCE' to include initialized versions and a URL for the source document.

    :rtype: dict
    :return: {
        'DocumentVersions': [
            {
                'Id': 'string',
                'Name': 'string',
                'ContentType': 'string',
                'Size': 123,
                'Signature': 'string',
                'Status': 'INITIALIZED'|'ACTIVE',
                'CreatedTimestamp': datetime(2015, 1, 1),
                'ModifiedTimestamp': datetime(2015, 1, 1),
                'ContentCreatedTimestamp': datetime(2015, 1, 1),
                'ContentModifiedTimestamp': datetime(2015, 1, 1),
                'CreatorId': 'string',
                'Thumbnail': {
                    'string': 'string'
                },
                'Source': {
                    'string': 'string'
                }
            },
        ],
        'Marker': 'string'
    }

    :returns:
    (string) --
    (string) --

    """
    pass


def exists_pos(pos, rhythm):
    """checks if position is used in rhythm"""
    for i in rhythm:
        if pos == i[0]:
            return True
    return False


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

        :param FileGetCopyReferenceType val:
        :rtype: EventType
        """
    return cls('file_get_copy_reference', val)


def theta_Ca_MgOH_HMW84(T, P):
    """c-c': calcium magnesium-hydroxide [HMW84]."""
    theta = 0.0
    valid = T == 298.15
    return theta, valid


def parse_grandchildren_using_function(parent, child_tag, parse_function,
    tag=None, optional=False):
    """
    Find and parse grandchildren using a specified function.

    :param parent: The parent ``Element`` object.
    :param child_tag: The name of the child tag.
    :param parse_function: A function which accepts an ``Element`` and returns an object.
    :param tag: Thet ag name of tehs pecific type of grandchild to parse, or None to parse all grandchildren.
    :param optional: If False, raise an exception if no parent node is found.

    :raises: An Exception if no parent node with the tag name specified by
        ``child_class.PARENT_TAG_NAME`` is found and ``optional`` is ``False``.

    :returns: A list of objects.
    """
    node = parent.find(child_tag)
    if node == None:
        if optional:
            return []
        else:
            raise Exception(
                'Node {0} does not contain required child node {1}.'.format
                (parent.tag, tag))
    else:
        if tag == None:
            nodes = node.getchildren()
        else:
            nodes = node.findall(tag)
        children = []
        for n in nodes:
            c = parse_function(n)
            if c != None:
                children.append(c)
        return children


def _validate_required_field(exception, config_type, field_name, config,
    config_name):
    """Validate required field is present."""
    if field_name not in config:
        raise exception(
            f'Field {field_name} is required for {config_type} {config_name}')


def _extract_prop_set(line):
    """
    Extract the (key, value)-tuple from a string like:
    >>> 'set foo = "bar"'
    :param line:
    :return: tuple (key, value)
    """
    token = ' = "'
    line = line[4:]
    pos = line.find(token)
    return line[:pos], line[pos + 4:-1]


def units_system():
    """Get text for the current Rhino doc units system. (eg. 'Meters', 'Feet')"""
    try:
        import scriptcontext
        return str(scriptcontext.doc.ModelUnitSystem).split('.')[-1]
    except ImportError:
        return 'Meters'


@staticmethod
def __split_remote(default_remote, branch):
    """
        The branch may be a remote/branch combination.  Split them or use the default_remote if none is specified.
        :param default_remote: The default remote to use if none is provided in branch.
        :param branch: The branch that may also contain a remote.
        :return: A list with a remote and branch.
        """
    remote = default_remote
    split = []
    if '/' in branch:
        split = list(map(lambda x: x.trim(), branch.split('/')))
    if '\\' in branch:
        split = list(map(lambda x: x.trim(), branch.split('\\')))
    if len(split) == 2:
        remote = split[0]
        branch = split[1]
    return [remote, branch]


@classmethod
def empty(kls):
    """Return a Meta with empty configuration and empty path"""
    return kls({}, [])


def get_pairs(word):
    """Return set of symbol pairs in a word.
    Word is represented as tuple of symbols (symbols being variable-length strings).
    """
    pairs = set()
    prev_char = word[0]
    for char in word[1:]:
        pairs.add((prev_char, char))
        prev_char = char
    return pairs


@staticmethod
def _filter_by_regexp(job_list, regexp, attribute):
    """
        Return list of items in `job_list` whose attribute
        named `attribute` matches the supplied (non-anchored) regexp.

        Jobs that do not possess an attribute with the specified name do *not*
        match.
        """
    matching_jobs = []
    for job in job_list:
        try:
            attrvalue = getattr(job, attribute)
        except AttributeError:
            continue
        if regexp.search(attrvalue):
            matching_jobs.append(job)
    return matching_jobs


def _parser_add_duration_and_reservation(subparser, duration_required):
    """Add a 'duration' and a 'reservation' argument to subparser.

    :param subparser: subparser instance
    :param duration_required: select if duration is required or optional
    """
    subparser.add_argument('-d', '--duration', required=duration_required,
        type=int, help='experiment duration in minutes')
    subparser.add_argument('-r', '--reservation', type=int, help=
        'experiment schedule starting : seconds since 1970-01-01 00:00:00 UTC')


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

        :param str val:
        :rtype: MemberAddResult
        """
    return cls('user_on_another_team', val)


def describe_events(SourceIdentifier=None, SourceType=None, StartTime=None,
    EndTime=None, Duration=None, EventCategories=None, Filters=None,
    MaxRecords=None, Marker=None):
    """
    Lists events for a given source identifier and source type. You can also specify a start and end time. For more information on AWS DMS events, see Working with Events and Notifications .
    See also: AWS API Documentation

    :example: response = client.describe_events(
        SourceIdentifier='string',
        SourceType='replication-instance',
        StartTime=datetime(2015, 1, 1),
        EndTime=datetime(2015, 1, 1),
        Duration=123,
        EventCategories=[
            'string',
        ],
        Filters=[
            {
                'Name': 'string',
                'Values': [
                    'string',
                ]
            },
        ],
        MaxRecords=123,
        Marker='string'
    )

    :type SourceIdentifier: string
    :param SourceIdentifier: The identifier of the event source. An identifier must begin with a letter and must contain only ASCII letters, digits, and hyphens. It cannot end with a hyphen or contain two consecutive hyphens.

    :type SourceType: string
    :param SourceType: The type of AWS DMS resource that generates events.
            Valid values: replication-instance | migration-task

    :type StartTime: datetime
    :param StartTime: The start time for the events to be listed.

    :type EndTime: datetime
    :param EndTime: The end time for the events to be listed.

    :type Duration: integer
    :param Duration: The duration of the events to be listed.

    :type EventCategories: list
    :param EventCategories: A list of event categories for a source type that you want to subscribe to.
            (string) --

    :type Filters: list
    :param Filters: Filters applied to the action.
            (dict) --
            Name (string) -- [REQUIRED]The name of the filter.
            Values (list) -- [REQUIRED]The filter value.
            (string) --

    :type MaxRecords: integer
    :param MaxRecords: The maximum number of records to include in the response. If more records exist than the specified MaxRecords value, a pagination token called a marker is included in the response so that the remaining results can be retrieved.
            Default: 100
            Constraints: Minimum 20, maximum 100.

    :type Marker: string
    :param Marker: An optional pagination token provided by a previous request. If this parameter is specified, the response includes only records beyond the marker, up to the value specified by MaxRecords .

    :rtype: dict
    :return: {
        'Marker': 'string',
        'Events': [
            {
                'SourceIdentifier': 'string',
                'SourceType': 'replication-instance',
                'Message': 'string',
                'EventCategories': [
                    'string',
                ],
                'Date': datetime(2015, 1, 1)
            },
        ]
    }

    :returns:
    (string) --

    """
    pass


def channels_find(query: str='Query'):
    """Filter the set of channels shown to only include those with matching names

    :param query: Text to search for in channel names
    :type query: str
    """
    pass


def get_job(arn=None):
    """
    Gets information about a job.
    See also: AWS API Documentation

    Examples
    The following example returns information about a specific job.
    Expected Output:

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

    :type arn: string
    :param arn: [REQUIRED]
            The job's ARN.

    :rtype: dict
    :return: {
        'job': {
            'arn': 'string',
            'name': 'string',
            'type': 'BUILTIN_FUZZ'|'BUILTIN_EXPLORER'|'APPIUM_JAVA_JUNIT'|'APPIUM_JAVA_TESTNG'|'APPIUM_PYTHON'|'APPIUM_WEB_JAVA_JUNIT'|'APPIUM_WEB_JAVA_TESTNG'|'APPIUM_WEB_PYTHON'|'CALABASH'|'INSTRUMENTATION'|'UIAUTOMATION'|'UIAUTOMATOR'|'XCTEST'|'XCTEST_UI',
            'created': datetime(2015, 1, 1),
            'status': 'PENDING'|'PENDING_CONCURRENCY'|'PENDING_DEVICE'|'PROCESSING'|'SCHEDULING'|'PREPARING'|'RUNNING'|'COMPLETED'|'STOPPING',
            'result': 'PENDING'|'PASSED'|'WARNED'|'FAILED'|'SKIPPED'|'ERRORED'|'STOPPED',
            'started': datetime(2015, 1, 1),
            'stopped': datetime(2015, 1, 1),
            'counters': {
                'total': 123,
                'passed': 123,
                'failed': 123,
                'warned': 123,
                'errored': 123,
                'stopped': 123,
                'skipped': 123
            },
            'message': 'string',
            'device': {
                'arn': 'string',
                'name': 'string',
                'manufacturer': 'string',
                'model': 'string',
                'formFactor': 'PHONE'|'TABLET',
                'platform': 'ANDROID'|'IOS',
                'os': 'string',
                'cpu': {
                    'frequency': 'string',
                    'architecture': 'string',
                    'clock': 123.0
                },
                'resolution': {
                    'width': 123,
                    'height': 123
                },
                'heapSize': 123,
                'memory': 123,
                'image': 'string',
                'carrier': 'string',
                'radio': 'string',
                'remoteAccessEnabled': True|False,
                'fleetType': 'string',
                'fleetName': 'string'
            },
            'deviceMinutes': {
                'total': 123.0,
                'metered': 123.0,
                'unmetered': 123.0
            }
        }
    }

    :returns:
    PENDING: A pending status.
    PENDING_CONCURRENCY: A pending concurrency status.
    PENDING_DEVICE: A pending device status.
    PROCESSING: A processing status.
    SCHEDULING: A scheduling status.
    PREPARING: A preparing status.
    RUNNING: A running status.
    COMPLETED: A completed status.
    STOPPING: A stopping status.

    """
    pass


def update_ds(module, array):
    """Update Directory Service"""
    changed = False
    module.exit_json(changed=changed)


def edit_bass_voice(score, durated_reservoir):
    """
    Edits bass voice.
    """
    voice = score['Bass Voice']
    voice[-3:] = (
        '<e, e>\\maxima <d, d>\\longa <c, c>\\maxima <b,>\\longa <a,>\\maxima r4 r2.'
        )


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


@classmethod
def is_done_filename(cls, fname):
    """
        Returns if the filename is a done filename (ends in .DONE.lock).
        """
    return fname.endswith('DONE.lock')


def values():
    """ Return an iterable sequence of the values present in the folder.

        Respect ``order``, if set.
        """


def pkdirs(pname, wdir='.'):
    """This function creates a python package folder structure in a specified directory.

  Args:
      pname: A string, the name of the package to create.
      wdir: A string, the path to where to create the python package folder structure. Defaults to '.'.

  Returns:
    NULL: There are no returns, a selection of folders is created.
  """
    from startpypack import mkdir
    mkdir(wdir + '/' + pname)
    mkdir(wdir + '/' + pname + '/' + pname)
    mkdir(wdir + '/' + pname + '/' + pname + '/' + pname)
    mkdir(wdir + '/' + pname + '/' + pname + '/' + pname + '/files')
    mkdir(wdir + '/' + pname + '/' + pname + '/' + pname + '/files/data')
    mkdir(wdir + '/' + pname + '/' + pname + '/' + pname + '/files/docs')


def enable():
    """Enables v2 behaviors."""
    global _force_enable
    _force_enable = True


def io_socket_free(iosock):
    """ close the socket """
    if iosock:
        iosock.close()
    return None


def _transpose_list_array(x):
    """Transposes a list matrix
    """
    n_dims = len(x)
    assert n_dims > 0
    n_samples = len(x[0])
    rows = [None] * n_samples
    for i in range(n_samples):
        r = [None] * n_dims
        for j in range(n_dims):
            r[j] = x[j][i]
        rows[i] = r
    return rows


def sendFileDescriptor(descriptor):
    """
        Send a duplicate of this (file, socket, pipe, etc) descriptor to the
        other end of this connection.

        The send is non-blocking and will be queued if it cannot be performed
        immediately.  The send will be processed in order with respect to other
        C{sendFileDescriptor} calls on this transport, but not necessarily with
        respect to C{write} calls on this transport.  The send can only be
        processed if there are also bytes in the normal connection-oriented send
        buffer (ie, you must call C{write} at least as many times as you call
        C{sendFileDescriptor}).

        @param descriptor: An C{int} giving a valid file descriptor in this
            process.  Note that a I{file descriptor} may actually refer to a
            socket, a pipe, or anything else POSIX tries to treat in the same
            way as a file.

        @return: C{None}
        """


def absMagToPower(am, absMagSun=4.75, absLumSun=3.846e+33):
    """
    Convert absolute magnitude to power scale

    The default values for the absolute magnitude and luminosity
    of the Sun are adopted from Harmanec and Prsa 2011
    (2011PASP..123..976H).

    Parameters
    ----------
    am : float
        Absolute magnitude.
    absMagSun : float, optional
        Absolute magnitude of the Sun.
    absLumSun : float, optional
        Absolute luminosity of the Sun.
        The default is given in units of erg/s.

    Returns
    -------
    Power : float
        Total emitted power. Same units as `absLumSun`;
        the default corresponds to erg/s.
    """
    power = 10.0 ** ((am - absMagSun) / -2.5) * absLumSun
    return power


def from_package_str(item):
    """
    Display name space info when it is different, then diagram's or
    parent's namespace.
    """
    subject = item.subject
    canvas = item.canvas
    if not subject or not canvas:
        return False
    namespace = subject.namespace
    parent = canvas.get_parent(item)
    if parent and parent.subject and parent.subject.namespace is not namespace:
        return False
    return (f'(from {namespace.name})' if namespace is not canvas.diagram.
        namespace else '')


def _check_component_interfaces(cls):
    """
        Check that the backend has the right interfaces.

        Certain interfaces are required to support components,
        and we want to make sure that the Backend implements
        them. This is a run-time type check.
        """
    for component in cls.board.supported_components():
        if not issubclass(cls, component.interface_class()):
            raise TypeError(
                "The backend class doesn't have a required interface.")


def is_empty(iterable):
    """
    Return whether the iterable is empty or not. Consumes at most one item
    from the iterator to test.

    >>> is_empty(iter(range(0)))
    True
    >>> is_empty(iter(range(1)))
    False
    """
    try:
        next(iter(iterable))
    except StopIteration:
        return True
    return False


def all_equal(it):
    """
    Return True if all elements of the given iterator are equal.
    """
    it = iter(it)
    try:
        first = next(it)
    except StopIteration:
        return True
    for x in it:
        if x != first:
            return False
    return True


def merge_dict(data, *override):
    """
    Merges any number of dictionaries together, and returns a single dictionary.

    Usage::

        >>> md = merge_dict({"foo": "bar"}, {1: 2}, {"foo1": "bar2"})
        >>> md == {1: 2, 'foo': 'bar', 'foo1': 'bar2'}
        True
        >>> merge_dict({'foo': 'bar'}, None)
        {'foo': 'bar'}
        >>> merge_dict(None, {'foo': 'bar'})
        {'foo': 'bar'}
        >>> merge_dict(None, None)
        {}
    """
    result = {}
    for current_dict in ((data,) + override):
        if current_dict is None:
            continue
        result.update(current_dict)
    return result


def simpleJustifyAlign(line, currentLength, maxLength):
    """simple justification with only strings"""
    strings = []
    for x in line[:-1]:
        if isinstance(x, str):
            strings.append(x)
    nspaces = len(strings) - 1
    slack = maxLength - currentLength
    text = ' '.join(strings)
    if nspaces > 0 and slack > 0:
        wordspacing = slack / float(nspaces)
        result = [('wordSpacing', wordspacing), text, maxLength, (
            'wordSpacing', 0)]
    else:
        result = [text, currentLength, ('nextLine', 0)]
    nextlinemark = 'nextLine', 0
    if line and line[-1] == nextlinemark:
        result.append(nextlinemark)
    return result


def _format_remainder(float_time_number):
    """Format a floating point remainder of a time unit."""
    string = ',' + ('%f' % float_time_number)[2:].rstrip('0')
    if string == ',':
        return ''
    return string


def feval(func, *args, **kw_args):
    """Evaluates the function C{func} using positional arguments C{args}
    and keyword arguments C{kw_args}.
    """
    return eval(func)(*args, **kw_args)


def simulate_compartment(compartment, settings={}):
    """
    run a compartment simulation
        Requires:
        - a compartment

    Returns:
        - a timeseries of variables from all ports.
        - if 'return_raw_data' is True, it returns the raw data instead
    """
    timestep = settings.get('timestep', 1)
    total_time = settings.get('total_time', 10)
    return_raw_data = settings.get('return_raw_data', False)
    time = 0
    while time < total_time:
        time += timestep
        compartment.update(timestep)
    if return_raw_data:
        return compartment.emitter.get_data()
    else:
        return compartment.emitter.get_timeseries()


def _validator_args_logic(args):
    """
    Implements logic for how validator arguments work in combination.

    As per: https://github.com/XLSForm/pyxform/pull/167#issuecomment-353382008

    **backwards-compatible**
    `xls2xform.py myform --skip_validate`: no validators
    `xls2xform.py myform`: ODK only

    **new**
    `xls2xform.py myform --enketo_validate`: Enketo only
    `xls2xform.py myform --odk_validate`: ODK only
    `xls2xform.py myform --enketo_validate --odk_validate`: both
    `xls2xform.py myform --enketo_validate --odk_validate --skip_validate`: no validators
    """
    if not args.skip_validate:
        args.odk_validate = False
        args.enketo_validate = False
    elif args.skip_validate and not (args.odk_validate or args.enketo_validate
        ):
        args.odk_validate = True
        args.enketo_validate = False
    return args


def parseRegionBed(regionfile, regionDictIn):
    """
    Read through the supplied bed file and add the rows to the input region dictionary before returning it. Appends to the input dict, rather than overwriting it.
    """
    regionDict = regionDictIn
    for line in open(str(regionfile), 'r'):
        col = line.strip().split('\t')
        chrom = col[0]
        start = col[1]
        end = col[2]
        if len(col) > 3:
            name = col[3]
        else:
            name = str(chrom) + ':' + str(start) + '-' + str(end)
        regionDict[chrom].add((start, end, name))
    return regionDict


def lip2en(BM, perc_lipid):
    """Percent lipid composition to percent energy stores

    Args
    ----
    BM: float or ndarray
        Body mass of animal
    perc_lipid: float or ndarray
        Percent lipids of animal's body composition

    Returns
    -------
    en: float or ndarray
        Total energy stores

    """
    PTBW = 71.4966 - 0.6802721 * perc_lipid
    return 40.8 * BM - 48.5 * (0.01 * PTBW * BM) - 0.4


def path_reference_copy(copy_set, report=print):
    """
    Execute copying files of path_reference

    :arg copy_set: set of (from, to) pairs to copy.
    :type copy_set: set
    :arg report: function used for reporting warnings, takes a string argument.
    :type report: function
    """
    if not copy_set:
        return
    import os
    import shutil
    for file_src, file_dst in copy_set:
        if not os.path.exists(file_src):
            report('missing %r, not copying' % file_src)
        elif os.path.exists(file_dst) and os.path.samefile(file_src, file_dst):
            pass
        else:
            dir_to = os.path.dirname(file_dst)
            try:
                os.makedirs(dir_to, exist_ok=True)
            except:
                import traceback
                traceback.print_exc()
            try:
                shutil.copy(file_src, file_dst)
            except:
                import traceback
                traceback.print_exc()


def get_consxml_rt(cons_el):
    """Returns consensusXML in seconds"""
    return cons_el.find('centroid').attrib['rt']


def _unbin(tile_data, factor):
    """
    tile_data should have shape (num_frames, y, x)
    """
    s = tile_data.shape
    tile_data = tile_data.reshape((s[0], s[1], 1, s[2]))
    unbinned = tile_data.repeat(factor, axis=2)
    return unbinned.reshape((s[0], factor * s[1], s[2]))


def optional(type_):
    """
    Helper for use with `expect_types` when an input can be `type_` or `None`.

    Returns an object such that both `None` and instances of `type_` pass
    checks of the form `isinstance(obj, optional(type_))`.

    Parameters
    ----------
    type_ : type
       Type for which to produce an option.

    Examples
    --------
    >>> isinstance({}, optional(dict))
    True
    >>> isinstance(None, optional(dict))
    True
    >>> isinstance(1, optional(dict))
    False
    """
    return type_, type(None)


def remove_doubles(threshold: float=0.02, use_unselected: bool=False):
    """Selected UV vertices that are within a radius of each other are welded together

    :param threshold: Merge Distance, Maximum distance between welded vertices
    :type threshold: float
    :param use_unselected: Unselected, Merge selected to other unselected vertices
    :type use_unselected: bool
    """
    pass


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


def greedy(list_):
    """
    Divide elements into two approximately equal subsets
    with a "greedy" algorithm. Order the elements then assign elements
    to the smallest subset.

    .. warning::
        A "greedy" algorithm may not return the optimal solution.

    :param list_: A list of positive numbers
    :type list_: list

    :returns: Minimum difference between sums of subsets
    :rtype: float

    :Example:

    >>> greedy(example_list)
    8.46
    """
    list_ = sorted(list_, reverse=True)
    diff = 0.0
    for item in list_:
        if diff <= 0.0:
            diff += item
        else:
            diff -= item
    return abs(diff)


def find_variables_from_constraints(constraints):
    """
    Return a list of all "proper" Variable objects appearing in some ``c in constraints``.
    """
    variable_ids = set()
    variables = []
    for c in constraints:
        for v in c.variables():
            if v.is_proper():
                vid = id(v)
                if vid not in variable_ids:
                    variable_ids.add(vid)
                    variables.append(v)
            else:
                msg = 'Constraint \n \t' + str(c) + '\n'
                msg += 'returned an improper Variable \n \t' + str(v) + '\n'
                raise RuntimeError(msg)
    return variables


def _pad_binary(bin_str, req_len=8):
    """
    Given a binary string (returned by bin()), pad it to a full byte length.
    """
    bin_str = bin_str[2:]
    return max(0, req_len - len(bin_str)) * '0' + bin_str


def _shapeClustering(mol1, rdkit_mols):
    """
        Returns the tanimoto row based on shape method

        Parameters
        ----------
        mol1: rdkit.Chem.rdchem.Mol
            The reference molecule
        rdkit_mols: list
            The list of rdkit.Chem.rdchem.Mol objects

        Returns
        -------
        tanimotorow: np.array
            The numpy array containing the tanimoto row
        """
    from rdkit.Chem import rdMolAlign, rdShapeHelpers
    tanimoto_shape_row = []
    for mol2 in rdkit_mols:
        oa3 = rdMolAlign.GetO3A(mol1, mol2)
        oa3.Align()
        tani_shape = rdShapeHelpers.ShapeTanimotoDist(mol1, mol2)
        tanimoto_shape_row.append(tani_shape)
    return tanimoto_shape_row


@classmethod
def get_geo_distance_params(cls, value, field):
    """Get params for `geo_distance` ordering.

        Example:

            /api/articles/?ordering=-location__45.3214__-34.3421__km__planes

        :param value:
        :param field:
        :type value: str
        :type field:
        :return: Params to be used in `geo_distance` query.
        :rtype: dict
        """
    __values = cls.split_lookup_complex_value(value, maxsplit=3)
    __len_values = len(__values)
    if __len_values < 2:
        return {}
    params = {'_geo_distance': {field: {'lat': __values[0], 'lon': __values
        [1]}}}
    if __len_values > 2:
        params['_geo_distance']['unit'] = __values[2]
    else:
        params['_geo_distance']['unit'] = 'm'
    if __len_values > 3:
        params['_geo_distance']['distance_type'] = __values[3]
    else:
        params['_geo_distance']['distance_type'] = 'arc'
    return params


@staticmethod
def getJavaPackage():
    """ Returns package name String. """
    return 'com.microsoft.ml.spark.recommendation.RankingEvaluator'


def unbool(element, true=object(), false=object()):
    """
    A hack to make True and 1 and False and 0 unique for ``uniq``.
    """
    if element is True:
        return true
    elif element is False:
        return false
    return element


def num2strg(num):
    """
    Attempt to emulate Excel's default conversion from number to string.
    """
    s = str(num)
    if s.endswith('.0'):
        s = s[:-2]
    return s


@staticmethod
def map_temperature_max_hass(temperature):
    """Map Temperature from MAX! to Home Assistant."""
    if temperature is None:
        return 0.0
    return temperature


def find_concat_dim(da, possible_concat_dims):
    """ look for available dimensions in dataaray and pick the one
    from a list of candidates

    PARAMETERS
    ----------
    da : xarray.DataArray
        xmitgcm llc data array
    possible_concat_dims : list
        list of potential dims

    RETURNS
    -------
    out : str
        dimension on which to concatenate

    """
    out = None
    for d in possible_concat_dims:
        if d in da.dims:
            out = d
    return out


def createStyleState(kmlDoc, scale, idtag):
    """
    Used to create a doucment wide style state with the LabelStyle internal field scale.
    Sets the Labelstyle scale field to value "scale" and names the field "idtag"
    """
    styleState = kmlDoc.createElement('Style')
    styleState.setAttribute('id', idtag)
    labels = kmlDoc.createElement('LabelStyle')
    lscale = kmlDoc.createElement('scale')
    lscale.appendChild(kmlDoc.createTextNode(str(scale)))
    labels.appendChild(lscale)
    styleState.appendChild(labels)
    return styleState


@classmethod
def find_registry(cls, id: str=None, name: str=None) ->'Registry':
    """Finds a registry based on either id or name.

        If neither is provided and there is only 1 registry, return the
        only registry.
        """
    if id:
        return cls.get(id)
    elif name:
        return cls.find_by_name(name)
    else:
        registries = cls.list()
        if len(registries) == 1:
            return registries[0]


@classmethod
def is_valid_packagename(cls, name):
    """
        Is this a valid package name?

        >>> PkgPolicy.is_valid_packagename('doesnotmatter')
        Traceback (most recent call last):
        ...
        NotImplementedError: Class needs to provide packagename_re
        """
    if cls.packagename_re is None:
        raise NotImplementedError('Class needs to provide packagename_re')
    return True if cls.packagename_re.match(name) else False


def page_element_conf0(element):
    """Get confidence (as float value) of the first text result."""
    if element.get_TextEquiv():
        return float(element.get_TextEquiv()[0].conf or '1.0')
    return 1.0


def resumeProducing():
    """
        Produce data for the consumer a single time.

        This tells a producer to produce data for the consumer once
        (not repeatedly, once only). Typically this will be done
        by calling the consumer's C{write} method a single time with
        produced data. The producer should produce data before returning
        from C{resumeProducing()}, that is, it should not schedule a deferred
        write.
        """


def _gcd(a, b):
    """Calculate the Greatest Common Divisor of a and b.

    Unless b==0, the result will have the same sign as b (so that when
    b is divided by it, the result comes out positive).
    """
    while b:
        a, b = b, a % b
    return a


def getHandle():
    """
        Return a system- and reactor-specific handle.

        This might be a socket.socket() object, or some other type of
        object, depending on which reactor is being used. Use and
        manipulate at your own risk.

        This might be used in cases where you want to set specific
        options not exposed by the Twisted APIs.
        """


def stringToBinary(seq):
    """
    Converts a string sequence to binary representation (length, number)
    """
    length = len(seq)
    number = 0
    digit = 1
    for i in reversed(range(length)):
        number += int(seq[i]) * digit
        digit *= 2
    return length, number


@staticmethod
def removable_cells(obj):
    """
        List object removable cells

        TESTS ::

            sage: from sage.combinat.skew_partition import SkewPartition
            sage: from sage_widget_adapters.combinat.skew_partition_grid_view_adapter import SkewPartitionGridViewAdapter
            sage: SkewPartitionGridViewAdapter.removable_cells(SkewPartition([[4, 2, 1],[2, 1]]))
            [(0, 2), (1, 1), (2, 0), (0, 3)]
            sage: SkewPartitionGridViewAdapter.removable_cells(SkewPartition([[7, 4, 2, 1],[2, 1, 1]]))
            [(0, 2), (1, 1), (3, 0), (0, 6), (1, 3), (2, 1)]
        """
    ret = obj.inner().outside_corners()
    for c in obj.outer().corners():
        if not c in ret:
            ret.append(c)
    return ret


@staticmethod
def getSelectTooltip():
    """Provides the tooltip"""
    return 'Rectangle'


def get_progress_bar(total_length, percentage, item='#', start='[', end=']'):
    """Builds a progress bar representation, drawn item as base symbol. The bar is delimited by start
    and end.

    The length of the progress bar is proportional to the percentage with respect to
    the total_length.

    :param total_length: (int) total length, representing 100%.
    :param percentage: (float) progress completion percentage, between 0.0 and 1.0.
    :param item: (string) character used to draw the bar.
    :param start: (string) start character for the bar.
    :param end: (string) end character for the bar.
    :return: (string) representing the progress bar.

    Examples:

    >>> get_progress_bar(10, 0.0)
    '[]'
    >>> get_progress_bar(10, 1.0)
    '[########]'
    >>> get_progress_bar(10, 1.0, item='$')
    '[$$$$$$$$]'
    >>> get_progress_bar(10, 0.5, start='E', end='X')
    'E###X'
    """
    bar_length = int(percentage * total_length) - 2
    return start + item * bar_length + end


def _pipe_segment_with_colons(align, colwidth):
    """Return a segment of a horizontal line with optional colons which
    indicate column's alignment (as in `pipe` output format)."""
    w = colwidth
    if align in ['right', 'decimal']:
        return '-' * (w - 1) + ':'
    elif align == 'center':
        return ':' + '-' * (w - 2) + ':'
    elif align == 'left':
        return ':' + '-' * (w - 1)
    else:
        return '-' * w


def flatten(iterable):
    """
    Non-recursive flatten.
    :param iterable:
    :return:
    """
    try:
        iterator, sentinel, stack = iter(iterable), object(), []
    except TypeError:
        yield iterable
        return
    while True:
        value = next(iterator, sentinel)
        if value is sentinel:
            if not stack:
                break
            iterator = stack.pop()
        elif isinstance(value, str):
            yield value
        else:
            try:
                new_iterator = iter(value)
            except TypeError:
                yield value
            else:
                stack.append(iterator)
                iterator = new_iterator