def pkginfo_unicode(pkg_info, field):
    """Hack to coax Unicode out of an email Message() - Python 3.3+"""
    text = pkg_info[field]
    field = field.lower()
    if not isinstance(text, str):
        if not hasattr(pkg_info, 'raw_items'):
            return str(text)
        for item in pkg_info.raw_items():
            if item[0].lower() == field:
                text = item[1].encode('ascii', 'surrogateescape').decode(
                    'utf-8')
                break
    return text


def get_duration_from_s(s, max_length=59 * 60 + 59):
    """
    Formats seconds as "%M:%S"
    If max_length exceed 60, give format in "%H:%M:%S"
    :param s: Seconds in int/float
    :param max_length: Max length in seconds. Default is 59 minutes, 59 seconds
    :returns: s formatted as "%M:%S"
    """
    if not isinstance(s, (int, float)):
        raise TypeError('Seconds must be int/float')
    elif s < 0:
        raise TypeError('Seconds must be positive')
    elif max_length and s > max_length:
        s = max_length
    m = s / 60
    h = ''
    if m > 60:
        h = ('%s:' % int(m / 60)).zfill(3)
        m = m % 60
    return '%s%s:%s' % (h, str(int(m)).zfill(2), str(int(s % 60)).zfill(2))


def truncate_seq_pair(tokens_a, tokens_b, max_num_tokens, rng):
    """Truncates a pair of sequences to a maximum sequence length."""
    while True:
        total_length = len(tokens_a) + len(tokens_b)
        if total_length <= max_num_tokens:
            break
        trunc_tokens = tokens_a if len(tokens_a) > len(tokens_b) else tokens_b
        assert len(trunc_tokens) >= 1
        if rng.random() < 0.5:
            del trunc_tokens[0]
        else:
            trunc_tokens.pop()


def find_duplicates(l: list) ->[]:
    """
    Finds duplicate entries in the given list
    :param l: the list to check
    :return: map of (value -> list of indexes)
    """
    if not len(l) != len(set(l)):
        return []
    tmp = {}
    for i, v in enumerate(l):
        if v in tmp.keys():
            tmp[v].append(i)
        else:
            tmp[v] = [i]
    result = {}
    for k, v in tmp.items():
        if len(v) > 1:
            result[k] = v
    return result


def listify(data):
    """
    Ensure data is a list

    Parameters
    ----------
    data : any
        The data to put into a list

    Returns
    -------
    list

    """
    if data is None:
        return data
    if isinstance(data, (set, list, tuple)):
        return list(data)
    return [data]


def skipdocs(obj):
    """
    Skip this object in the automatically generated documentation.
    """
    obj._skipdocs = True
    return obj


def facet_query(**kw):
    """ Return a dict with info about a selection of this facet. kw is the index to search for, ie Type='Document'
        """


def ONLY_CHANGE_AND_PERIODIC(s, t, v):
    """Only change events pass"""
    from taurus.core import TaurusEventType
    if t in [TaurusEventType.Change, TaurusEventType.Periodic]:
        return s, t, v
    else:
        return None


def tap(value, interceptor):
    """Invokes `interceptor` with the `value` as the first argument and then
    returns `value`. The purpose of this method is to "tap into" a method chain
    in order to perform operations on intermediate results within the chain.

    Args:
        value (mixed): Current value of chain operation.
        interceptor (function): Function called on `value`.

    Returns:
        mixed: `value` after `interceptor` call.

    Example:

        >>> data = []
        >>> def log(value): data.append(value)
        >>> chain([1, 2, 3, 4]).map(lambda x: x * 2).tap(log).value()
        [2, 4, 6, 8]
        >>> data
        [[2, 4, 6, 8]]

    .. versionadded:: 1.0.0
    """
    interceptor(value)
    return value


def _usage(args):
    """
    Gets usage help content.
    """
    usage = ['usage: lscaat <subcommand> [args] [options]', '',
        'Type lscaat help <subcommand> for help on a specific subcommand.',
        'Type caat --help for help on command options.', '',
        'Available subcommands:', '', '  changes', '  diff', '  info',
        '  list (ls)', '  remove (rm)', '  restore', '', 'Options:', '',
        '  Several command options exist that are the same as found in caat.',
        '  Consult the man pages for lscaat for details.', '',
        'lscaat is a part of the caat backup program and is used to restore,',
        'list and remove items from one or more backups.  Can also be used',
        'to display useful information about the status of your backups.']
    return '\n'.join(usage)


def check_for_debug(supernova_args, nova_args):
    """
    If the user wanted to run the executable with debugging enabled, we need
    to apply the correct arguments to the executable.

    Heat is a corner case since it uses -d instead of --debug.
    """
    if supernova_args['debug'] and supernova_args['executable'] == 'heat':
        nova_args.insert(0, '-d ')
    elif supernova_args['debug']:
        nova_args.insert(0, '--debug ')
    return nova_args


@staticmethod
def _create_parameter_dict(parameter_df, keys, value):
    """
        Function to create parameters dictionary
        :param parameter_df:
        :param keys:
        :param value:
        :return:
        """
    parameter_df = parameter_df.set_index(keys)
    return parameter_df[value].to_dict()


def stop_data_collection_by_agent_ids(agentIds=None):
    """
    Instructs the specified agents or connectors to stop collecting data.
    See also: AWS API Documentation

    :example: response = client.stop_data_collection_by_agent_ids(
        agentIds=[
            'string',
        ]
    )

    :type agentIds: list
    :param agentIds: [REQUIRED]
            The IDs of the agents or connectors from which to stop collecting data.
            (string) --

    :rtype: dict
    :return: {
        'agentsConfigurationStatus': [
            {
                'agentId': 'string',
                'operationSucceeded': True|False,
                'description': 'string'
            },
        ]
    }

    """
    pass


def sample_detail_size(location: int=(0, 0)):
    """Sample the mesh detail on clicked point

    :param location: Location, Screen Coordinates of sampling
    :type location: int
    """
    pass


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


def lookup(code, _cache={}):
    """Lookup an error code or class code and return its symbolic name.

    Raise `KeyError` if the code is not found.
    """
    if _cache:
        return _cache[code]
    tmp = {}
    for k, v in globals().items():
        if isinstance(v, str) and len(v) in (2, 5):
            tmp[v] = k
    assert tmp
    _cache.update(tmp)
    return _cache[code]


def create_build_project(client, role, bucket, buildspec, image):
    """
    Creates a new AWS CodeBuild Project to build the PyPi package(s).

    Parameters
    ----------
    client : botocore.client.S3
        A boto3 client for S3.
    role : str
        Name of the IAM Role the AWS CodeBuild project should use.
    bucket : str
        Name of the bucket the build artifact will be put in.
    buildspec : str
        A valid AWS CodeBuild Buildspec in YAML. Use s3.generate_buildspec().
    image : str
        The Docker image to use for the CodeBuild project.

    Returns
    -------
    dict
        boto3 response object. See https://boto3.amazonaws.com/v1/documentation
        /api/latest/reference/services
        /codebuild.html#CodeBuild.Client.create_project for more information.
    """
    print('Creating CodeBuild project...')
    try:
        response = client.create_project(name='alppbBuilder', source={
            'type': 'NO_SOURCE', 'buildspec': buildspec}, artifacts={'type':
            'S3', 'location': bucket}, environment={'type':
            'LINUX_CONTAINER', 'image': image, 'computeType':
            'BUILD_GENERAL1_SMALL'}, serviceRole=role)
    except client.exceptions.ResourceAlreadyExistsException:
        print('>>alppbBuilder project already exists, overwriting...')
        response = client.update_project(name='alppbBuilder', source={
            'type': 'NO_SOURCE', 'buildspec': buildspec}, artifacts={'type':
            'S3', 'location': bucket}, environment={'type':
            'LINUX_CONTAINER', 'image': image, 'computeType':
            'BUILD_GENERAL1_SMALL'}, serviceRole=role)
    return response


def add_RM_to_fits_header(header, pol, phi_sample=None):
    """
    Adds RM axis to the data in place of frequency.

    NB:Knicked and modified from Brentjens RM Synthesis code
    """
    hdr = header.copy()
    if len(phi_sample) >= 2:
        new_hdr = {'naxis3': len(phi_sample), 'crpix3': 1.0, 'cdelt3':
            phi_sample[1] - phi_sample[0], 'crval3': phi_sample[0],
            'ctype3': 'RM', 'cunit3': 'rad/m^2', 'POL': '%s' % pol}
    else:
        new_hdr = {'naxis3': 1, 'cunit3': 'rad/m^2', 'ctype3': 'RM', 'POL':
            '%s' % pol}
    hdr.update(new_hdr)
    return hdr


def any_non_int_numbers(collection):
    """Returns true if any numbers in the collection are not integers"""
    return any(map(lambda n: not isinstance(n, int), collection))


def make_json(structure, variable_name=None, indent=1, **k):
    """Converts something into a json string, optionally attributing the result
    to a variable.

    It also escapes the forward slash, making the result suitable
    to be included in an HTML <script> tag.
    """
    import json
    s = json.dumps(structure, indent=indent, **k).replace('/', '\\/')
    return '{0} = {1};\n'.format(variable_name, s) if variable_name else s


def p_stringlist_single(p):
    """stringlist : string"""
    p[0] = [p[1]]


def _format_date(dt):
    """convert a datetime into an RFC 822 formatted date

    Input date must be in GMT.
    """
    return '%s, %02d %s %04d %02d:%02d:%02d GMT' % (['Mon', 'Tue', 'Wed',
        'Thu', 'Fri', 'Sat', 'Sun'][dt.weekday()], dt.day, ['Jan', 'Feb',
        'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov',
        'Dec'][dt.month - 1], dt.year, dt.hour, dt.minute, dt.second)


def check_name_length(cell):
    """
    Verifies that the string has at least 1 non-whitespace character.

    Parameters
    ----------
    cell : QLineEdit
        a QLineEdit containing a string.
    """
    cell_value = cell.text()
    text = cell_value.strip()
    if len(text):
        cell.setStyleSheet('QLineEdit{background: white;}')
        return text, True
    else:
        cell.setStyleSheet('QLineEdit{background: red;}')
        return None, False


def post_upgrade():
    """Run post-upgrade checks (optional)."""


@staticmethod
def _convert_number_bmk(axis_value, _):
    """Converts the values on axes to Billions, Millions or Thousands"""
    if axis_value >= 1000000000.0:
        return '{:1.1f}B'.format(axis_value * 1e-09)
    if axis_value >= 1000000.0:
        return '{:1.1f}M'.format(axis_value * 1e-06)
    if axis_value >= 1000.0:
        return '{:1.1f}K'.format(axis_value * 0.001)
    if axis_value >= 1 or axis_value == 0:
        return '{:1.0f}'.format(axis_value)
    return axis_value


def convert_to_utf8_unicode(arg):
    """TODO: currently useless"""
    pass


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

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

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


@classmethod
def from_dict(cls, file_dict):
    """
        Create a SimpleUploadedFile object from a dictionary with keys:
           - filename
           - content-type
           - content
        """
    return cls(file_dict['filename'], file_dict['content'], file_dict.get(
        'content-type', 'text/plain'))


def echo_worker(data):
    """
    Example of worker that simply echoes back the received data.

    :param data: Request data dict.
    :returns: True, data
    """
    print('echo worker running')
    return data


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

    The ".dev0" means dirty.

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


def psi_H_CO3_Cl_HMW84(T, P):
    """c-a-a': hydrogen carbonate chloride [HMW84]."""
    psi = 0.0
    valid = T == 298.15
    return psi, valid


def box_pack_2d(boxes: list):
    """Returns the normal of the 3D tri or quad.

    :param boxes: list of boxes, each box is a list where the first 4 items are [x, y, width, height, …] other items are ignored.
    :type boxes: list
    :return:  the width and height of the packed bounding box
    """
    pass


def get_preferred_sparse_format():
    """Get the preferred sparse matrix format supported by the backend.

    Different backends have their preferred backend. This info is useful when
    constructing a sparse matrix.
    """
    return 'csr'


def spooler_pid():
    """Returns first spooler process ID

    :rtype: int
    """
    return -1


def calc_crc16(data):
    """Calc byte string CRC16"""
    s = 0
    if len(data) % 2 == 1:
        data += chr(0)
    for i in range(0, len(data), 2):
        if type(data[i]) is str:
            s += ord(data[i]) + (ord(data[i + 1]) << 8)
        else:
            s += data[i] + (data[i + 1] << 8)
        s &= 4294967295
    s = (s >> 16) + (s & 65535)
    s = ~s & 65535
    return s >> 8 | s << 8 & 65280


def format_timezone(offset, unnecessary_negative_timezone=False):
    """Format a timezone for Git serialization.

    :param offset: Timezone offset as seconds difference to UTC
    :param unnecessary_negative_timezone: Whether to use a minus sign for
        UTC or positive timezones (-0000 and --700 rather than +0000 / +0700).
    """
    if offset % 60 != 0:
        raise ValueError('Unable to handle non-minute offset.')
    if offset < 0 or unnecessary_negative_timezone:
        sign = '-'
        offset = -offset
    else:
        sign = '+'
    return '%c%02d%02d' % (sign, offset / 3600, offset / 60 % 60)


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

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

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


def describe_maintenance_window_targets(WindowId=None, Filters=None,
    MaxResults=None, NextToken=None):
    """
    Lists the targets registered with the Maintenance Window.
    See also: AWS API Documentation

    :example: response = client.describe_maintenance_window_targets(
        WindowId='string',
        Filters=[
            {
                'Key': 'string',
                'Values': [
                    'string',
                ]
            },
        ],
        MaxResults=123,
        NextToken='string'
    )

    :type WindowId: string
    :param WindowId: [REQUIRED]
            The ID of the Maintenance Window whose targets should be retrieved.

    :type Filters: list
    :param Filters: Optional filters that can be used to narrow down the scope of the returned window targets. The supported filter keys are Type, WindowTargetId and OwnerInformation.
            (dict) --Filter used in the request.
            Key (string) --The name of the filter.
            Values (list) --The filter values.
            (string) --

    :type MaxResults: integer
    :param MaxResults: The maximum number of items to return for this call. The call also returns a token that you can specify in a subsequent call to get the next set of results.

    :type NextToken: string
    :param NextToken: The token for the next set of items to return. (You received this token from a previous call.)

    :rtype: dict
    :return: {
        'Targets': [
            {
                'WindowId': 'string',
                'WindowTargetId': 'string',
                'ResourceType': 'INSTANCE',
                'Targets': [
                    {
                        'Key': 'string',
                        'Values': [
                            'string',
                        ]
                    },
                ],
                'OwnerInformation': 'string'
            },
        ],
        'NextToken': 'string'
    }

    :returns:
    (string) --

    """
    pass


@staticmethod
def _wrap_function(original_func, wrapper_infodict):
    """Return a wrapped version of func.

        :param original_func: The function to be wrapped.
        :param wrapper_infodict: The infodict to use for constructing the
            wrapper.
        """
    src = ('lambda %(signature)s: _original_func_(%(signature)s)' %
        wrapper_infodict)
    wrapped_func = eval(src, dict(_original_func_=original_func))
    wrapped_func.__name__ = wrapper_infodict['name']
    wrapped_func.__doc__ = wrapper_infodict['doc']
    wrapped_func.__module__ = wrapper_infodict['module']
    wrapped_func.__dict__.update(wrapper_infodict['dict'])
    wrapped_func.__defaults__ = wrapper_infodict['defaults']
    return wrapped_func


def apply_extra_context(extra_context, context):
    """
    Adds items from extra_context dict to context.  If a value in extra_context
    is callable, then it is called and the result is added to context.
    """
    for key, value in extra_context.iteritems():
        if callable(value):
            context[key] = value()
        else:
            context[key] = value


def offset_clear():
    """Clear strip offsets from the start and end frames

    """
    pass


def smooth_radius():
    """Interpolate radii of selected points

    """
    pass


def pvwatts_losses(soiling=2, shading=3, snow=0, mismatch=2, wiring=2,
    connections=0.5, lid=1.5, nameplate_rating=1, age=0, availability=3):
    """
    Implements NREL's PVWatts system loss model.
    The PVWatts loss model [1]_ is:

    .. math::

        L_{total}(\\%) = 100 [ 1 - \\Pi_i ( 1 - \\frac{L_i}{100} ) ]

    All parameters must be in units of %. Parameters may be
    array-like, though all array sizes must match.

    Parameters
    ----------
    soiling: numeric, default 2
    shading: numeric, default 3
    snow: numeric, default 0
    mismatch: numeric, default 2
    wiring: numeric, default 2
    connections: numeric, default 0.5
    lid: numeric, default 1.5
        Light induced degradation
    nameplate_rating: numeric, default 1
    age: numeric, default 0
    availability: numeric, default 3

    Returns
    -------
    losses: numeric
        System losses in units of %.

    References
    ----------
    .. [1] A. P. Dobos, "PVWatts Version 5 Manual"
           http://pvwatts.nrel.gov/downloads/pvwattsv5.pdf
           (2014).
    """
    params = [soiling, shading, snow, mismatch, wiring, connections, lid,
        nameplate_rating, age, availability]
    perf = 1
    for param in params:
        perf *= 1 - param / 100
    losses = (1 - perf) * 100.0
    return losses


def richness(row, rarefy=0, count=False):
    """Return the richness of an iterable."""
    if count:
        return sum(row > 0)
    row_sum, R = sum(row), 0
    for val in row:
        prob_success = val / row_sum
        prob_fail = 1 - prob_success
        prob_detect = 1 - prob_fail ** rarefy
        if val and rarefy <= 0:
            R += 1
        else:
            R += prob_detect
    return int(R + 0.5)


def expand(ind, upper_bound):
    """Expand a slice or integer into an explicit array of indices"""
    import numpy as np
    if hasattr(ind, '__len__'):
        return np.array(ind, dtype='int32')
    if isinstance(ind, int):
        return np.array([ind], dtype='int32')
    assert isinstance(ind, slice), 'unknown slicing mechanism - ' + repr(ind)
    start, stop, step = ind.start, ind.stop, ind.step
    if step is None:
        step = 1
    assert step != 0
    if start is None:
        if step > 0:
            start = 0
        else:
            start = upper_bound - 1
    if start < 0:
        start += upper_bound
    if stop is None:
        if step > 0:
            stop = upper_bound
        else:
            stop = -1
    elif stop < 0:
        stop += upper_bound
    return np.arange(start, stop, step, dtype='int32')


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

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

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


@classmethod
def clearOwner(cls, f0):
    """Return a copy of f0 with no owner specified, or None if f0 is None."""
    if (f0 is None or f0.dataset is None and f0.sizeGeq is None and f0.
        mtime is None and f0.notPaths == [] and f0.regex is None):
        return None
    else:
        return cls(None, f0.dataset, f0.sizeGeq, f0.mtime, f0.notPaths, f0.
            regex)


@property
def value(G):
    """
        The value of the game in short-hand.

        Returns
        -------
        v : str
            The value of the Game as a string.
        """
    from .printing import value_str
    return value_str(G)


@staticmethod
def replace_all(text, dic):
    """"Returns a string replacing all the sequence of characters defined in the dictionary . """
    for key, value in dic.items():
        text = text.replace(key, value)
    return text


def get_i18n_block(inifile_or_dict, key, pop=False):
    """Extracts an i18n block from an ini file or dictionary for a given
    key. If "pop", delete keys from "inifile_or_dict".
    """
    rv = {}
    for k in list(inifile_or_dict):
        if k == key:
            rv['en'] = inifile_or_dict.pop(k) if pop else inifile_or_dict[k]
        elif k.startswith(key + '['):
            rv[k[len(key) + 1:-1]] = inifile_or_dict.pop(k
                ) if pop else inifile_or_dict[k]
    return rv


def _from_data_nist(raw_data):
    """Convert a NIST data format to an internal format."""
    for point in raw_data:
        point.pop('species_data')
    return raw_data


def _json_dump_kwargs(**kwargs):
    """Load kwargs to be passed to `json.dump` and `json.dumps`.
    """
    kw = dict(indent=2, separators=(',', ':'), ensure_ascii=False)
    for kk, vv in kwargs.items():
        kw[kk] = vv
    return kw


def get_scheduler_and_lock_factory(lib):
    """
    Return factories for creating a period task scheduler and locks.

    The scheduler will be a scheduler class from the APScheduler_
    framework (which see for the API), and the lock factory is an
    appropriate locking object for synchronizing independently running
    tasks. Example::

        sched_factory, lock_factory = _get_scheduler_and_lock_factory('threading')
        sched = sched_factory()
        sched.add_job(task1, 'interval', seconds=5)
        sched.add_job(task2, 'interval', seconds=30)

        shared_data_lock = lock_factory()

        def task1():
          # ...
          with shared_data_lock:
            # modify shared data

    Argument `lib` is one of: ``threading``, ``gevent``, ``tornado``,
    ``asyncio`` (Python 3.5+ "async" system), ``twisted``, ``qt``;
    each of them selects a scheduler and lock objects compatible with
    the named framework for concurrent processing.

    .. _APScheduler: https://apscheduler.readthedocs.org/en/latest/userguide.html
    """
    if lib == 'threading':
        from apscheduler.schedulers.background import BackgroundScheduler
        from threading import Lock
        return BackgroundScheduler, Lock
    elif lib == 'gevent':
        from apscheduler.schedulers.gevent import GeventScheduler
        from gevent.lock import Semaphore
        return GeventScheduler, Semaphore
    elif lib in ['asyncio', 'tornado', 'twisted', 'qt']:
        raise NotImplemented('Support for {lib} is not yet available!'.
            format(lib=lib))
    else:
        raise ValueError(
            "Library '{lib}' is unknown to `{mod}._get_scheduler_and_lock_factory()`"
            .format(lib=lib, mod=__name__))


def addPlatform(parser):
    """
    Add option to specify a platform.
    """
    if hasattr(parser, 'add_option'):
        from .options_old import addPlatform
        return addPlatform(parser)
    parser.add_argument('-c', '--platform', help=
        'runtime platform. With "best", the most appropriate is chosen [default: %(default)s]'
        , default=None)
    parser.add_argument('--force-platform', action='store_true', help=
        'ignore platform compatibility check', default=False)
    return parser


def create_gctf_v1_06_command(ctf_name, file_sum, file_input, file_output,
    settings, name):
    """Create the Gctf v1.06 command"""
    ignore_list = []
    ignore_list.append('Use movies')
    ignore_list.append('Phase plate')
    command = []
    command.append('{0}'.format(settings['Path'][ctf_name]))
    if settings[ctf_name]['Phase plate'] == 'False':
        ignore_list.append('--phase_shift_L')
        ignore_list.append('--phase_shift_H')
        ignore_list.append('--phase_shift_S')
        ignore_list.append('--phase_shift_T')
        ignore_list.append('--only_search_ps')
        ignore_list.append('--cosearch_refine_ps')
    else:
        pass
    if settings[ctf_name]['Use movies'] == 'False':
        ignore_list.append('--do_mdef_refine')
        ignore_list.append('--mdef_ave_type')
        ignore_list.append('--mdef_aveN')
        ignore_list.append('--mdef_fit')
        file_input = file_sum
    else:
        pass
    ignore_list.append('Split Gpu?')
    ignore_list.append('--gid')
    if settings[ctf_name]['Split Gpu?'] == 'True':
        try:
            gpu_id = int(name.split('_')[-1]) - 1
        except ValueError:
            gpu_id = 0
        try:
            gpu = settings[ctf_name]['--gid'].split()[gpu_id]
        except IndexError:
            raise UserWarning(
                'There are less gpus provided than threads available! Please restart with the same number of pipeline processors as GPUs provided and restart! Stopping this thread!'
                )
    else:
        gpu = settings[ctf_name]['--gid']
    command.append('--gid')
    command.append('{0}'.format(gpu))
    command.append('--ctfstar')
    command.append('{0}_gctf.star'.format(file_output))
    for key in settings[ctf_name]:
        if key in ignore_list:
            continue
        elif settings[ctf_name][key]:
            command.append(key)
            command.append('{0}'.format(settings[ctf_name][key]))
        else:
            continue
    command.append('{0}'.format(file_input))
    return ' '.join(command), gpu


@classmethod
def from_proto(cls, proto_mesh, scale):
    """
        TODO: add documentation
        """
    mesh = cls(**proto_mesh.items())
    mesh._copy_roche_values()
    mesh._scale_mesh(scale=scale)
    return mesh


def _guess_file_format(filename):
    """Guess the file format from the filename.

	Parameters
	----------
	filename : string
		The filename of the file.

	Returns
	-------
	string
		The file type. This is one of ["asdf", "fits"].
	"""
    if filename.endswith('asdf'):
        return 'asdf'
    elif filename.endswith('fits') or filename.endswith('fits.gz'):
        return 'fits'
    else:
        return None


def find(itter, target, key=None):
    """Returns the index of an element in a callable which can be use a key function"""
    assert key == None or callable(key
        ), "key shold be a function that takes the itter's item and returns that wanted matched item"
    for i, x in enumerate(itter):
        if key:
            x = key(x)
        if x == target:
            return i
    else:
        return -1


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

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


def exit_(event):
    """
    Pressing Ctrl-Q will exit the user interface.

    Setting a return value means: quit the event loop that drives the user
    interface and return this value from the `CommandLineInterface.run()` call.
    """
    event.cli.exit(result=None)


@staticmethod
def _build_instruct(rw, bytes2send, reg_addr, reg_value=0):
    """Builds an instruction.
        Take arguments to form adequat instruction.
        Return an array containing the serie of instruction bits
        (i.e. each case of array contains '0' or '1').
        Details:   Prototype of transmission on AD9912 serial bus:
             16 bits header    | (up to) 4 bytes data
        R/W | W1:W0 |  A12:A0  |     ............
        ex: read FTW0_0 register
         1  |  0:0  |  0x0000  |
         => 0x8000
        ex: read Part ID (2 bytes)
         1  |  0:1  |  0x0002  |
         => 0xA002
        :param rw: 1 = read, 0 = Write (int).
        :param bytes2Send: 0=1Byte, 1=2Bytes, 2=3Bytes, 3=4Bytes or more (int).
        :param regAddr: enter the register address to write to (int).
        :param regValue: only if register writing is requested (int).
        :returns: instruction (int)
        """
    if rw == 1:
        rw = 1 << 15
        bytes2send = bytes2send << 13
        instruct = rw + bytes2send + reg_addr
    else:
        bytes2send = bytes2send << 21
        reg_addr = reg_addr << 8
        instruct = rw + bytes2send + reg_addr + reg_value
    return instruct


def is_leap_year(year):
    """Returns True if the year is a leap year, False otherwise."""
    return year % 4 == 0 and (year % 100 > 0 or year % 400 == 0)


def vertical_vorticity2d(tensorW):
    """
    Calculate the vorticity vector from the vorticity tensor in two dimension
    """
    wz = 2 * tensorW[1][0]
    return wz


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

        :param ShowcaseUntrashedDetails val:
        :rtype: EventDetails
        """
    return cls('showcase_untrashed_details', val)


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

        :param list of [MemberAddResult] val:
        :rtype: MembersAddLaunch
        """
    return cls('complete', val)


def find_and_fire_hook(event_name, instance, user_override=None):
    """
    Look up Hooks that apply
    """
    from django.contrib.auth.models import User
    from rest_hooks.models import Hook, HOOK_EVENTS
    if not event_name in HOOK_EVENTS.keys():
        raise Exception('"{}" does not exist in `settings.HOOK_EVENTS`.'.
            format(event_name))
    filters = {'event': event_name}
    if user_override is not False:
        if user_override:
            filters['user'] = user_override
        elif hasattr(instance, 'user'):
            filters['user'] = instance.user
        elif isinstance(instance, User):
            filters['user'] = instance
        else:
            raise Exception('{} has no `user` property. REST Hooks needs this.'
                .format(repr(instance)))
    hooks = Hook.objects.filter(**filters)
    for hook in hooks:
        hook.deliver_hook(instance)


def _get_iface_blocks(data):
    """"Yield interface blocks as pairs of v4 and v6 halves."""
    lines, lines6 = [], []
    crt_lines = lines
    for line in data.splitlines():
        line = line.strip()
        if not line or line.startswith('#'):
            continue
        if 'iface' in line:
            if 'inet6' in line:
                crt_lines = lines6
            if lines:
                yield lines, lines6
            lines[:] = []
            lines6[:] = []
            crt_lines = lines
        crt_lines.append(line)
    if lines:
        yield lines, lines6


def json_response(request):
    """Determine if the request's response should be JSON."""
    if request.query.get('format') == 'json':
        return True
    else:
        return request.content_type == 'application/json'


def visual_transform_apply():
    """Apply the object’s visual transformation to its data

    """
    pass


@classmethod
def isroute(cls, other: object) ->bool:
    """
            Is other an instance of Route?

            :param other: Object to compare
        """
    return isinstance(other, cls)


@classmethod
def from_inversion_vector(cls, inversion):
    """
        Calculates the permutation from the inversion vector.

        Examples
        ========

        >>> from sympy.combinatorics.permutations import Permutation
        >>> Permutation.print_cyclic = False
        >>> Permutation.from_inversion_vector([3, 2, 1, 0, 0])
        Permutation([3, 2, 1, 0, 4, 5])

        """
    size = len(inversion)
    N = list(range(size + 1))
    perm = []
    try:
        for k in range(size):
            val = N[inversion[k]]
            perm.append(val)
            N.remove(val)
    except IndexError:
        raise ValueError('The inversion vector is not valid.')
    perm.extend(N)
    return cls._af_new(perm)


def tidy_mothur_sequences(sequence_data):
    """Renoves gap characters from sequences imported from mothur."""
    new_sequence_data = sequence_data.copy(deep=True)
    for column in sequence_data:
        new_sequence_data[column] = sequence_data[column].str.replace('-', '')
    return new_sequence_data


def toolbar():
    """Undocumented contribute <https://developer.blender.org/T51061>

    """
    pass


def get_int_attr(node, attribute):
    """Cast an element attribute to an int or return None if not present"""
    attr = node.get(attribute)
    return None if attr is None else int(attr)


def jacobi(a, b):
    """Calculates the value of the Jacobi symbol (a/b) where both a and b are
    positive integers, and b is odd

    :returns: -1, 0 or 1
    """
    assert a > 0
    assert b > 0
    if a == 0:
        return 0
    result = 1
    while a > 1:
        if a & 1:
            if (a - 1) * (b - 1) >> 2 & 1:
                result = -result
            a, b = b % a, a
        else:
            if b * b - 1 >> 3 & 1:
                result = -result
            a >>= 1
    if a == 0:
        return 0
    return result


def se2hmt(A, Bc):
    """
    Iab = se2hmt(A, Bc)

    Create a Hit-or-Miss Template (or interval) from a pair of
    structuring elements.

    `se2hmt` creates the Hit-or-Miss Template (HMT), also called
    interval `[A,Bc]` from the structuring elements `A` and `Bc` such that
    `A` is included in the complement of `Bc` . The only difference
    between this function and `se2interval` is that here the second
    structuring element is the complement of the one used in the
    other function. The advantage of this function over
    `se2interval` is that this one is more flexible in the use of
    the structuring elements as they are not required to have the
    same size.

    Parameters
    ----------
    A :  Structuring Element Left extremity.
    Bc : Structuring Element Complement of the right extremity.

    Returns
    -------
    Iab : Interval
    """
    return A, Bc


def get_request_data(request):
    """Получение данных, передаваемых с запросом"""
    if request.method == 'POST':
        return request.POST
    else:
        return request.GET


def isiter(val):
    """Return True is val is iterable."""
    try:
        iter(val)
    except TypeError:
        return False
    else:
        return True


def environ_to_message(environ):
    """
    WSGI environ -> ASGI message
    """
    message = {'method': environ['REQUEST_METHOD'].upper(), 'root_path':
        environ.get('SCRIPT_NAME', ''), 'path': environ.get('PATH_INFO', ''
        ), 'query_string': environ.get('QUERY_STRING', ''), 'http_version':
        environ.get('SERVER_PROTOCOL', 'http/1.0').split('/', 1)[-1],
        'scheme': environ.get('wsgi.url_scheme', 'http')}
    if 'REMOTE_ADDR' in environ and 'REMOTE_PORT' in environ:
        message['client'] = [environ['REMOTE_ADDR'], int(environ[
            'REMOTE_PORT'])]
    if 'SERVER_NAME' in environ and 'SERVER_PORT' in environ:
        message['server'] = [environ['SERVER_NAME'], int(environ[
            'SERVER_PORT'])]
    headers = []
    if environ.get('CONTENT_TYPE'):
        headers.append([b'content-type', environ['CONTENT_TYPE'].encode(
            'latin-1')])
    if environ.get('CONTENT_LENGTH'):
        headers.append([b'content-length', environ['CONTENT_LENGTH'].encode
            ('latin-1')])
    for key, val in environ.items():
        if key.startswith('HTTP_'):
            key_bytes = key[5:].replace('_', '-').upper().encode('latin-1')
            val_bytes = val.encode()
            headers.append([key_bytes, val_bytes])
    return message


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

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

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

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


def create_tags(ResourceName=None, Tags=None):
    """
    Adds one or more tags to a specified resource.
    A resource can have up to 10 tags. If you try to create more than 10 tags for a resource, you will receive an error and the attempt will fail.
    If you specify a key that already exists for the resource, the value for that key will be updated with the new value.
    See also: AWS API Documentation

    :example: response = client.create_tags(
        ResourceName='string',
        Tags=[
            {
                'Key': 'string',
                'Value': 'string'
            },
        ]
    )

    :type ResourceName: string
    :param ResourceName: [REQUIRED]
            The Amazon Resource Name (ARN) to which you want to add the tag or tags. For example, arn:aws:redshift:us-east-1:123456789:cluster:t1 .

    :type Tags: list
    :param Tags: [REQUIRED]
            One or more name/value pairs to add as tags to the specified resource. Each tag name is passed in with the parameter Key and the corresponding value is passed in with the parameter Value . The Key and Value parameters are separated by a comma (,). Separate multiple tags with a space. For example, --tags 'Key'='owner','Value'='admin' 'Key'='environment','Value'='test' 'Key'='version','Value'='1.0' .
            (dict) --A tag consisting of a name/value pair for a resource.
            Key (string) --The key, or name, for the resource tag.
            Value (string) --The value for the resource tag.

    """
    pass


def unlink_data():
    """Undocumented contribute <https://developer.blender.org/T51061>

    """
    pass


def _find_inclusions(state, labels, remove_initial=True):
    """Find the number of inclusions found at each step."""
    inclusions = []
    n_initial_inc = 0
    cur_inclusions = 0
    n_initial = 0
    n_queries = state.n_queries()
    for query_i in range(n_queries):
        try:
            label_methods = state.get('label_methods', query_i)
            label_idx = state.get('label_idx', query_i)
        except KeyError:
            continue
        for i in range(len(label_idx)):
            if label_methods[i] == 'initial' and remove_initial:
                n_initial_inc += labels[label_idx[i]]
                n_initial += 1
            else:
                cur_inclusions += labels[label_idx[i]]
                inclusions.append(cur_inclusions)
    inclusions_after_init = sum(labels)
    if remove_initial:
        inclusions_after_init -= n_initial_inc
    return inclusions, inclusions_after_init, n_initial


def scan_spectrum_file(filename):
    """
    go over mgf file and return list with all spectrum titles
    """
    titles = []
    f = open(filename)
    while 1:
        rows = f.readlines(10000)
        if not rows:
            break
        for row in rows:
            if row[0] == 'T':
                if row[:5] == 'TITLE':
                    titles.append(row.rstrip()[6:])
    f.close()
    return titles


def _seek_to_n_lines_from_end(f, numlines=10):
    """
    Seek to `numlines` lines from the end of the file `f`.
    """
    buf = ''
    buf_pos = 0
    f.seek(0, 2)
    line_count = 0
    while line_count < numlines:
        newline_pos = buf.rfind('\n', 0, buf_pos)
        file_pos = f.tell()
        if newline_pos == -1:
            if file_pos == 0:
                break
            else:
                toread = min(1024, file_pos)
                f.seek(-toread, 1)
                buf = f.read(toread) + buf[:buf_pos]
                f.seek(-toread, 1)
                buf_pos = len(buf) - 1
        else:
            buf_pos = newline_pos
            line_count += 1
    if line_count == numlines:
        f.seek(buf_pos + 1, 1)


def fetch_package_version(dist_name):
    """
    >>> fetch_package_version('sentry')
    """
    try:
        import pkg_resources
    except ImportError:
        raise NotImplementedError(
            'pkg_resources is not available on this Python install')
    dist = pkg_resources.get_distribution(dist_name)
    return dist.version


def file_status(status, response):
    """Response for when file is on the hpss system."""
    response_headers = [('X-Pacifica-Messsage', 'File was found' if status else
        'File Not found'), ('X-Pacifica-File', str(getattr(status,
        'filepath', 'File Not Found'))), ('X-Content-Length', str(getattr(
        status, 'filesize', 'File Not Found'))), ('Last-Modified', str(
        getattr(status, 'mtime', 'File Not Found'))), ('X-Pacifica-Ctime',
        str(getattr(status, 'ctime', 'File Not Found'))), (
        'X-Pacifica-Bytes-Per-Level', str(getattr(status, 'bytes_per_level',
        'File Not Found'))), ('X-Pacifica-File-Storage-Media', str(getattr(
        status, 'file_storage_media', 'File Not Found'))), ('Content-Type',
        'application/json')]
    response.status = '204 No Content' if status else '404 Not Found'
    for key, value in response_headers:
        response.headers[key] = value


def smooth_actor(actor, factor=15):
    """
    Smooth an actor's mesh

    :param actor:
    :param factor:  (Default value = 15)

    """
    actor.smoothLaplacian(niter=factor)


def rotate_points(points):
    """Rotate the points around the center of the field.

  Args:
    points:  Numpy array holding one or several points.

  Returns:
    The rotated points.
  """
    return -points


def p_arglist(p):
    """ arglist : arglist COMMA arg
    """
    p[1].addNewArg(p[3])
    p[0] = p[1]


@classmethod
def CreateTranslation(cls, x=0, y=0, z=0):
    """
        Creates a translation matrix for the given offset.

        :param x: x-coordinate of translation (default 0)
        :type x:  ``int`` or ``float``

        :param y: y-coordinate of translation (default 0)
        :type y:  ``int`` or ``float``

        :param z: z-coordinate of translation (default 0)
        :type z:  ``int`` or ``float``
        """
    result = cls()
    result.translate(x, y, z)
    return result


def hasPrincipal(id):
    """Returns a boolean representing the presence of the
        principal with the given id in the folder.
        """


def delete_cluster_security_group(ClusterSecurityGroupName=None):
    """
    Deletes an Amazon Redshift security group.
    For information about managing security groups, go to Amazon Redshift Cluster Security Groups in the Amazon Redshift Cluster Management Guide .
    See also: AWS API Documentation

    :example: response = client.delete_cluster_security_group(
        ClusterSecurityGroupName='string'
    )

    :type ClusterSecurityGroupName: string
    :param ClusterSecurityGroupName: [REQUIRED]
            The name of the cluster security group to be deleted.

    """
    pass


def _write_export(export, file_obj=None):
    """
    Write a string to a file.
    If file_obj isn't specified, return the string

    Parameters
    ---------
    export: a string of the export data
    file_obj: a file-like object or a filename
    """
    if file_obj is None:
        return export
    if hasattr(file_obj, 'write'):
        out_file = file_obj
    else:
        out_file = open(file_obj, 'wb')
    try:
        out_file.write(export)
    except TypeError:
        out_file.write(export.encode('utf-8'))
    out_file.close()
    return export


def flatten(seq, seqtypes=(list, tuple)):
    """
    Flatten a sequence of sequences.

    Returns:
        A flattened list.
    """
    result = []
    tasks = [iter(seq)]
    while tasks:
        try:
            elem = next(tasks[-1])
            if isinstance(elem, seqtypes):
                tasks.append(iter(elem))
            else:
                result.append(elem)
        except StopIteration:
            tasks.pop()
    return result


@staticmethod
def get_subtype(object_dictionary):
    """
        Given the hash representation of a subtype of this class,
        use the info in the hash to return the class of the subtype.
        """
    type = object_dictionary['protocol']
    if type == 'SAML2':
        return 'Saml2IdentityProvider'
    else:
        return 'IdentityProvider'


def create_none_dataset(py_obj, h_group, call_id=0, **kwargs):
    """ Dump None type to file

    Args:
        py_obj: python object to dump; must be None object
        h_group (h5.File.group): group to dump data into.
        call_id (int): index to identify object's relative location in the iterable.
    """
    d = h_group.create_dataset('data_%i' % call_id, data=[0], **kwargs)
    d.attrs['type'] = ['none']


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

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

    """
    pass


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

        :param GoogleSsoChangePolicyDetails val:
        :rtype: EventDetails
        """
    return cls('google_sso_change_policy_details', val)


@classmethod
def from_value_iterable(cls, value_iterable, value_renderer_class=None,
    frame_renderer_class=None, value_and_frame_renderer_kwargs=None, **
    listkwargs):
    """
        A shortcut for creating an object of this class with the given ``**listkwargs``
        as __init__ arguments, and then calling :meth:`.extend_with_values` with
        ``value_iterable``, ``value_renderer_class`` and ``frame_renderer_class`` as
        arguments.

        See :meth:`.extend_with_values` for documentation for the arguments.

        Returns:
            An object of this class.
        """
    listobject = cls(**listkwargs)
    listobject.extend_with_values(value_iterable=value_iterable,
        value_renderer_class=value_renderer_class, frame_renderer_class=
        frame_renderer_class, value_and_frame_renderer_kwargs=
        value_and_frame_renderer_kwargs)
    return listobject


def _get_best_indexes(logits, n_best_size):
    """Get the n-best logits from a list."""
    index_and_score = sorted(enumerate(logits), key=lambda x: x[1], reverse
        =True)
    best_indexes = []
    for i in range(len(index_and_score)):
        if i >= n_best_size:
            break
        best_indexes.append(index_and_score[i][0])
    return best_indexes


def deleteReceived(event):
    """
        Called when a deletion notification has been received for a node.

        @param event: The items event.
        @type event: L{ItemsEvent<wokkel.pubsub.DeleteEvent>}
        """


def serialise_number(i, context=None):
    """Serialise a Number value.

    i -- integer

    """
    return ('%d' % i).encode('ascii')


def save_page(page, filename):
    """Save page content to disk

    Parameters
    ----------
    page : requests get result

    filename : str
        The path to the file that will store the page contents

    """
    with open(filename, 'w') as f:
        f.write(page.text)
        f.close()


@classmethod
def unguard(cls):
    """
        Disable the mass assigment restrictions.
        """
    cls.__unguarded__ = True


def _generate_fingerprint(operation, atoms, atoms_parameters, connectivity,
    **kwargs):
    """Return the parameters of a convolutions of atomic properties
    based on connectivity in a periodic unit cell.

    Parameters
    ----------
    operations : list of functions
        A list of operation functions to produce the fingerprints from.
    atoms : object
        Atomic structure to generate fingerprint for.
    atoms_parameters : ndarray (N, M)
        General chemical properties specific to this atoms object
        and list of seed parameters.
    connectivity : ndarray (N, N)
        Estimated connectivity matrix where n is the number
        of atoms in the atoms-object.

    Returns
    -------
    fingerprint : ndarray (M,)
        Fingerprint produced from a given operation and seed parameters.
    """
    fingerprint = operation(atoms=atoms, atoms_parameters=atoms_parameters,
        connectivity=connectivity, **kwargs)
    return fingerprint


def get_displayed_page_number(i, num_pages, site):
    """Get page number to be displayed for entry `i`."""
    if not i:
        i = 0
    if site.config['INDEXES_STATIC']:
        return i if i > 0 else num_pages
    else:
        return i + 1 if site.config['INDEXES_PAGES_MAIN'] else i


def delete_track():
    """Delete selected tracks

    """
    pass


def class_register(cls):
    """Class decorator that maps Kite HTTP method names to class methods."""
    cls.handler_registry = {}
    cls.sender_registry = {}
    for method_name in dir(cls):
        method = getattr(cls, method_name)
        if hasattr(method, '_handle'):
            cls.handler_registry.update({method._handle: method_name})
        if hasattr(method, '_sends'):
            cls.sender_registry.update({method._sends: method_name})
    return cls


def _reduce(groupby, fn):
    """Reduce a groupby by applying a function to every column."""
    return groupby.apply(lambda df: df.apply(fn))


def unescapeString(string):
    """
        Unescape the given string

        @param string: An escaped string
        @return: Unescaped string
    """
    toUnescapeChars = ['\\', '(', ')']
    unescapedValue = ''
    i = 0
    while i < len(string):
        if string[i] == '\\' and i != len(string) - 1:
            if string[i + 1] in toUnescapeChars:
                if string[i + 1] == '\\':
                    unescapedValue += '\\'
                    i += 1
                else:
                    pass
            elif string[i + 1] == 'r':
                i += 1
                unescapedValue += '\r'
            elif string[i + 1] == 'n':
                i += 1
                unescapedValue += '\n'
            elif string[i + 1] == 't':
                i += 1
                unescapedValue += '\t'
            elif string[i + 1] == 'b':
                i += 1
                unescapedValue += '\x08'
            elif string[i + 1] == 'f':
                i += 1
                unescapedValue += '\x0c'
            else:
                unescapedValue += string[i]
        else:
            unescapedValue += string[i]
        i += 1
    return unescapedValue


def _unsafe_dict_update(default_dict, override_dict):
    """
    Using defaults and an overriding dictionary, create a new dictionary.
    This new dictionary has the same values as the default dictionary and
    the same types. Thus, if there are values that are in the overriding
    dictionary, but not in the original, they will be ignored.

    Arguments
    ---------
    default_dict: dict
        Starting dictionary with defaults.
    override_dict: dict
        Dictionary with custom values (such as model parameters).

    Returns
    -------
    dict
        Merged dictionary.
    """
    new_dict = default_dict
    for key in override_dict:
        if key not in default_dict:
            print(f'Warning: key {key} is being ignored.')
    for key in new_dict:
        if key in override_dict:
            str_val = override_dict[key]
            if type(new_dict[key]) == bool:
                new_dict[key] = str_val in ['True', 'true', 'T', 't', True]
            else:
                try:
                    new_dict[key] = type(new_dict[key])(str_val)
                except TypeError:
                    raise TypeError(f'Error at {key}')
    return new_dict


def completeness_run_check(columns, df):
    """
    Check for consistency between parameters and the dataframe, an assertion
    error will incur if the check is not passed.

    :param columns: Columns on which to run the metric
    :type columns: list
    :param df: Dataframe on which to run the metric
    :type df: DataFrame
    """
    if columns is not None:
        for col in columns:
            assert col in df.columns, "Column '%s' is not a column part of the dataframe" % col


def get_literal_name(v):
    """ Get a human-friendly name for the given literal.

    :param v: Value
    :type v: *
    :rtype: unicode
    """
    return str(v)


def update_quota():
    """Update used space, and verify quota for this content.
        """


def get():
    """
    @api {post} /map/poihistory/get  获取历史
    @apiVersion 1.0.0
    @apiGroup History
    @apiDescription  获取历史

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

    @apiParam (Body) {String} page 页数

    @apiSuccess (Success) {String}  keywords 关键字
    @apiSuccess (Success) {String}  sqtype 类型
    @apiSuccess (Success) {String}  time 时间

    @apiSuccessExample {json} Success-Response:
    {
        "data": [
            {
                "keywords": "加油站",
                "sqtype": "KEYWORD",
                "time": "2018-07-17 14:09:22"
            }
        ],
        "req_id": "r_bb99baa658c4414faeed31b9d82ca3a4",
        "err_resp": {
            "code": "0",
            "msg": null
        }
    }

    """


def white_strip(q, f, x, add_v):
    """
    Subroutine of ``all_intervals_covered()``.

    Check if column and diagonal strip of x are all white.
    If so, x cannot be covered. Vertex function is not extreme.
    """
    for xx in [x, (f - x - 1) % q]:
        for y in range(1, q):
            for u in [xx, (xx - y) % q]:
                if add_v[u, y] and add_v[u + 1, y]:
                    return False
        for y in (list(range(xx)) + list(range(xx + 1, q))):
            if add_v[xx, y + 1] and add_v[xx + 1, y] and (xx + y + 1) % q != f:
                return False
    return True


def get_doc():
    """Get documentation of this resource

    :return: rst string
    :rtype: str
    """
    return """
    The ``host`` model is used to represent a monitored host.

    An host may be a router, a server, a workstation, ... that you want to be monitored by your
    Alignak framework.
    """


def version_match(required, candidate):
    """Test that an available version satisfies the required version.

    To be suitable a version must be of the same major version as required
    and be at least a match in minor/patch level.

    eg. 3.3 is a match for a required 3.1 but 4.1 is not.

    :param tuple required: the version that must be met.
    :param tuple candidate: the version to test against required.

    :returns: True if candidate is suitable False otherwise.
    :rtype: bool
    """
    if candidate[0] != required[0]:
        return False
    if candidate < required:
        return False
    return True


def attach_suffix(item_list, suffix):
    """ add a int suffix to a parameter vector
        int representation of parameters
    """
    vals = []
    for item in item_list:
        vals.append([int(item), int(suffix)])
    return vals


def read_userpref():
    """Load last saved preferences

    """
    pass


@classmethod
def is_datasource_for(cls, data, header, **kwargs):
    """Determines if header corresponds to an SWAP image"""
    return header.get('instrume') == 'SWAP'


def get_source_location_by_offset(source: str, offset: int) ->int:
    """Retrieve the Solidity source code location based on the source map
    offset.

    :param source: The Solidity source to analyze
    :param offset: The source map's offset
    :return: The offset's source line number equivalent
    """
    return source.encode('utf-8')[0:offset].count('\n'.encode('utf-8')) + 1


def list_perceel_adapter(obj, request):
    """
    Adapter for rendering a list of
    :class: `crabpy.gateway.capakey.Perceel` to json.
    """
    return {'id': obj.id, 'sectie': obj.sectie, 'capakey': obj.capakey,
        'percid': obj.percid}


def bake():
    """Bake selected F-Curves to a set of sampled points defining a similar curve

    """
    pass


def multiply_vector(vector, factor):
    """Multiplies a vector of two coordinates by a given factor."""
    return factor * vector[0], factor * vector[1]


@classmethod
def from_path(cls, path):
    """
        Create a new, parsed `SSHConfig` from the file found at ``path``.

        .. versionadded:: 2.7
        """
    with open(path) as flo:
        return cls.from_file(flo)


def default_configuration():
    """
    Generate the default configuration for the training parameters.
    :return: Dictionary, the default configuration parameters.
    """
    tmp = {'batch_norm_decay_decay_activate': True,
        'batch_norm_decay_decay_period': 24000,
        'batch_norm_decay_starting_decay': 0.7,
        'batch_norm_decay_ending_decay': 0.9,
        'learning_rate_decay_activate': True, 'learning_rate_decay_period':
        16000, 'learning_rate_decay_rate': 0.99, 'learning_rate_decay_type':
        'polynomial', 'batch_norm_activate': True, 'batch_size': 8,
        'convolution_per_layer': [3, 3, 3, 3], 'da-3-elastic-activate':
        True, 'da-elastic-alpha_max': 9, 'da-elastic-order': 3,
        'da-4-flipping-activate': True, 'da-flipping-order': 4,
        'da-gaussian_blur-activate': True, 'da-gaussian_blur-order': 6,
        'da-gaussian_blur-sigma_max': 1.5, 'da-5-noise_addition-activate':
        False, 'da-noise_addition-order': 5,
        'da-2-random_rotation-activate': False,
        'da-random_rotation-high_bound': 89, 'da-random_rotation-low_bound':
        5, 'da-random_rotation-order': 2, 'da-1-rescaling-activate': False,
        'da-rescaling-factor_max': 1.2, 'da-rescaling-order': 1,
        'da-0-shifting-activate': True, 'da-shifting-order': 0,
        'da-shifting-percentage_max': 0.1, 'da-type': 'all', 'depth': 4,
        'downsampling': 'convolution', 'dropout': 0.75,
        'features_per_convolution': [[[1, 16], [16, 16], [16, 16]], [[16,
        32], [32, 32], [32, 32]], [[32, 64], [64, 64], [64, 64]], [[64, 128
        ], [128, 128], [128, 128]]], 'learning_rate': 0.001, 'n_classes': 3,
        'size_of_convolutions_per_layer': [[5, 5, 5], [3, 3, 3], [3, 3, 3],
        [3, 3, 3]], 'weighted_cost-activate': True,
        'weighted_cost-balanced_activate': True,
        'weighted_cost-balanced_weights': [1.1, 1, 1.3],
        'weighted_cost-boundaries_activate': False,
        'weighted_cost-boundaries_sigma': 2, 'thresholds': [0, 0.2, 0.8],
        'trainingset': 'SEM_3c_512', 'trainingset_patchsize': 512,
        'balanced_weights': [1.1, 1, 1.3], 'dataset_mean': 120.95,
        'dataset_variance': 60.23}
    return tmp


def constant(target, value):
    """
    Places the given constant value into the target object

    Parameters
    ----------
    target : OpenPNM Object
        The object which this model is associated with. This controls the
        length of the calculated array, and also provides access to other
        necessary properties.

    value : scalar
        The numerical value to apply

    Returns
    -------
    value : NumPy ndarray
        Array containing constant values equal to ``value``.

    Notes
    -----
    This model is mostly useless and for testing purposes, but might be used
    to 'reset' an array back to a default value.

    """
    return value


def inject_input_stream(application_scope):
    """Return the input stream."""
    return application_scope.infile


def _test():
    """perform internal tests."""
    import doctest
    doctest.testmod()


@classmethod
def has_access(cls, instance, user):
    """ Does the given user has access to the model instance. This can be used to only send model data to specific users.

        (Note: The user may be anonymous)

        :param instance: Model instance
        :param user:     User connected via pubsub
        :rtype: bool
        """
    return True


def assert_query_has_qmark(query: str, context: str='') ->None:
    """Throws Exception if the query does not contain any question marks."""
    if '?' in query:
        return
    message = ''
    if context:
        message = ' ' + context
    message = (message +
        "Query commands must contain question-marks. Sent query: '{0}'".
        format(query.strip('\n')))
    raise Exception(message)


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

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

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


def plaintext(file, **kwds):
    """Retrieve content as-is but with mimetype text/plain."""
    file.mimetype = 'text/plain'


@classmethod
def parse(cls, line):
    """Return a new :py:class:`~PyIRC.auxparse.CTCPMessage` from
        the :py:class:`~PyIRC.line.Line` instance specified.
        """
    message = line.params[1]
    if not message.startswith('\x01') or not message.endswith('\x01'):
        return None
    message = message[1:-1]
    command, _, param = message.partition(' ')
    param = param.strip()
    if not param:
        param = None
    if not line.hostmask or not line.hostmask.nick:
        target = line.params[0]
    else:
        target = line.hostmask.nick
    return cls(line.command.upper(), command.upper(), target, param)


def list_rar(archive, compression, cmd, verbosity, interactive):
    """List a RAR archive."""
    cmdlist = [cmd]
    if verbosity > 1:
        cmdlist.append('v')
    else:
        cmdlist.append('l')
    if not interactive:
        cmdlist.extend(['-p-', '-y'])
    cmdlist.extend(['--', archive])
    return cmdlist


def getNucleotideCodon(sequence, x1):
    """Returns the entire codon of the nucleotide at pos x1 in sequence,
	and the position of that nocleotide in the codon in a tuple"""
    if x1 < 0 or x1 >= len(sequence):
        return None
    p = x1 % 3
    if p == 0:
        return sequence[x1:x1 + 3], 0
    elif p == 1:
        return sequence[x1 - 1:x1 + 2], 1
    elif p == 2:
        return sequence[x1 - 2:x1 + 1], 2


@classmethod
def create(cls, meta_template, ctx=None, **kwargs):
    """Initialize a counter."""
    assert 'meta_template' not in kwargs
    return cls(template_instance=meta_template.format(**ctx or {}), **kwargs)


def is_array(obj):
    """Test if input object is a numerical vector.

    > *Input arguments*

    * `obj`: Input variable.

    > *Returns*

    `True`, if `obj` is a vector.
    """
    import collections
    return isinstance(obj, collections.Iterable) and not isinstance(obj, str)


def KK_RC20(w, Rs, R_values, t_values):
    """
    Kramers-Kronig Function: -RC-

    Kristian B. Knudsen (kknu@berkeley.edu / kristianbknudsen@gmail.com)
    """
    return Rs + R_values[0] / (1 + w * 1.0j * t_values[0]) + R_values[1] / (
        1 + w * 1.0j * t_values[1]) + R_values[2] / (1 + w * 1.0j * t_values[2]
        ) + R_values[3] / (1 + w * 1.0j * t_values[3]) + R_values[4] / (1 +
        w * 1.0j * t_values[4]) + R_values[5] / (1 + w * 1.0j * t_values[5]
        ) + R_values[6] / (1 + w * 1.0j * t_values[6]) + R_values[7] / (1 +
        w * 1.0j * t_values[7]) + R_values[8] / (1 + w * 1.0j * t_values[8]
        ) + R_values[9] / (1 + w * 1.0j * t_values[9]) + R_values[10] / (1 +
        w * 1.0j * t_values[10]) + R_values[11] / (1 + w * 1.0j * t_values[11]
        ) + R_values[12] / (1 + w * 1.0j * t_values[12]) + R_values[13] / (
        1 + w * 1.0j * t_values[13]) + R_values[14] / (1 + w * 1.0j *
        t_values[14]) + R_values[15] / (1 + w * 1.0j * t_values[15]
        ) + R_values[16] / (1 + w * 1.0j * t_values[16]) + R_values[17] / (
        1 + w * 1.0j * t_values[17]) + R_values[18] / (1 + w * 1.0j *
        t_values[18]) + R_values[19] / (1 + w * 1.0j * t_values[19])


def parse_fixed_width(types, lines):
    """Parse a fixed width line."""
    values = []
    line = []
    for width, parser in types:
        if not line:
            line = lines.pop(0).replace('\n', '')
        values.append(parser(line[:width]))
        line = line[width:]
    return values


def _format(command, body, headers):
    """
    Return a formatted STOMP frame as a bytestring.
    """
    bits = [command, '\n']
    if body:
        bits.extend(('content-length:', str(len(body)), '\n'))
    for key, value in headers.iteritems():
        bits.extend((key.replace('_', '-'), ':', str(value), '\n'))
    bits.extend(('\n', body or '', '\x00\n\n\n\n'))
    return ''.join(bits)


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

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

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


@staticmethod
def __template_name(class_name, parameters, parameter_map):
    """
        Return a C++ style template name, for example 'C<a=3,b>'.
        """
    parameter_strings = []
    for p in parameters:
        if p in parameter_map:
            parameter_strings.append('{0}={1}'.format(p, str(parameter_map[p]))
                )
        else:
            parameter_strings.append(p)
    return '{0}<{1}>'.format(class_name, ', '.join(parameter_strings))


@classmethod
def getDefault(class_, field):
    """Default layouts for this File p_field"""
    return class_.bg if field.inGrid() else class_.b


def no_match(obj, h5f, *args, **kwargs):
    """ If no match is made, raise an exception """
    try:
        import dill as cPickle
    except ImportError:
        import cPickle
    pickled_obj = cPickle.dumps(obj)
    h5f.create_dataset('type', data=['pickle'])
    h5f.create_dataset('data', data=[pickled_obj])
    print('Warning: %s type not understood, data have been serialized' %
        type(obj))


def _get_messages(data):
    """
    Get messages (ErrorCode) from Response.

    :param data: dict of datas
    :return list: Empty list or list of errors
    """
    error_messages = []
    for ret in data.get('responses', [data]):
        if 'errorCode' in ret:
            error_messages.append('{0}: {1}'.format(ret['errorCode'], ret.
                get('message')))
    return error_messages


def params_to_list(args):
    """Convert a list of arguments (some of which may be lists) to a flat list"""
    result = []
    for arg in args:
        if isinstance(arg, list):
            result += arg
        else:
            result.append(arg)
    return result


def task_done(task, status_line, consumer_name, consumer_length):
    """Acknowledge the task done; Called by task queue server"""


def store_cookies():
    """Return True if a Poll should set a cookie on the client
        side to prevent people to vote multiple times.
        """


def forwards_func(apps, schema_editor):
    """
    Convert pages to GDPR user consent documents
    """
    user_consent_document_model = apps.get_model('shuup_gdpr',
        'GDPRUserConsentDocument')
    gdpr_user_consent_model = apps.get_model('shuup_gdpr', 'GDPRUserConsent')
    reversion_version_model = apps.get_model('reversion', 'Version')
    for consent in gdpr_user_consent_model.objects.all():
        consents = set()
        for page_id in consent.documents.values_list('id', flat=True):
            version = reversion_version_model.objects.filter(object_id=page_id
                ).first()
            if version:
                doc = user_consent_document_model.objects.create(page_id=
                    page_id, version=version)
                consents.add(doc.id)
        consent.consents = consents


def validate_jhove(filename, jhove='jhove', ignore=('More than 50 IFDs',)):
    """Validate TIFF file using jhove -m TIFF-hul.

    Raise ValueError if jhove outputs an error message unless the message
    contains one of the strings in 'ignore'.

    JHOVE does not support bigtiff or more than 50 IFDs.

    See `JHOVE TIFF-hul Module <http://jhove.sourceforge.net/tiff-hul.html>`_

    """
    import subprocess
    out = subprocess.check_output([jhove, filename, '-m', 'TIFF-hul'])
    if b'ErrorMessage: ' in out:
        for line in out.splitlines():
            line = line.strip()
            if line.startswith(b'ErrorMessage: '):
                error = line[14:].decode('utf8')
                for i in ignore:
                    if i in error:
                        break
                else:
                    raise ValueError(error)
                break


def build_properties(cls, new_attrs):
    """
    Given a class and a new set of attributes (as passed in by
    __classinit__), create or modify properties based on functions
    with special names ending in __get, __set, and __del.
    """
    for name, value in new_attrs.items():
        if name.endswith('__get') or name.endswith('__set') or name.endswith(
            '__del'):
            base = name[:-5]
            if hasattr(cls, base):
                old_prop = getattr(cls, base)
                if not isinstance(old_prop, property):
                    raise ValueError(
                        'Attribute %s is a %s, not a property; function %s is named like a property'
                         % (base, type(old_prop), name))
                attrs = {'fget': old_prop.fget, 'fset': old_prop.fset,
                    'fdel': old_prop.fdel, 'doc': old_prop.__doc__}
            else:
                attrs = {}
            attrs['f' + name[-3:]] = value
            if name.endswith('__get') and value.__doc__:
                attrs['doc'] = value.__doc__
            new_prop = property(**attrs)
            setattr(cls, base, new_prop)


def add_notation(tags_segment, label, left_context, right_context,
    tagging_notation='BILOU'):
    """Receive segment of tagged tokens and return list of labeled tokens"""
    labels = []
    if tagging_notation == 'BIO':
        for offset in range(0, len(tags_segment)):
            if offset < left_context:
                token_label = 'O'
            elif offset == left_context:
                token_label = 'B-' + label
            elif offset < len(tags_segment) - right_context:
                token_label = 'I-' + label if label else label
            else:
                token_label = 'O'
            labels.append(token_label)
    if tagging_notation == 'BILOU':
        for offset in range(0, len(tags_segment)):
            if offset < left_context:
                token_label = 'O'
            elif offset == left_context and len(tags_segment
                ) - left_context - right_context == 1:
                token_label = 'U-' + label if label else label
            elif offset == left_context:
                token_label = 'B-' + label
            elif offset < len(tags_segment) - right_context - 1:
                token_label = 'I-' + label if label else label
            elif offset < len(tags_segment) - right_context:
                token_label = 'L-' + label if label else label
            else:
                token_label = 'O'
            labels.append(token_label)
    return labels


def confusion_matrix(classify=lambda document: False, documents=[(None, False)]
    ):
    """ Returns the performance of a binary classification task (i.e., predicts True or False)
        as a tuple of (TP, TN, FP, FN):
        - TP: true positives  = correct hits,
        - TN: true negatives  = correct rejections,
        - FP: false positives = false alarm (= type I error),
        - FN: false negatives = misses (= type II error).
        The given classify() function returns True or False for a document.
        The list of documents contains (document, bool)-tuples for testing,
        where True means a document that should be identified as True by classify().
    """
    TN = TP = FN = FP = 0
    for document, b1 in documents:
        b2 = classify(document)
        if b1 and b2:
            TP += 1
        elif not b1 and not b2:
            TN += 1
        elif not b1 and b2:
            FP += 1
        elif b1 and not b2:
            FN += 1
    return TP, TN, FP, FN


def delete_run(arn=None):
    """
    Deletes the run, given the run ARN.
    See also: AWS API Documentation

    Examples
    The following example deletes a specific test run.
    Expected Output:

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

    :type arn: string
    :param arn: [REQUIRED]
            The Amazon Resource Name (ARN) for the run you wish to delete.

    :rtype: dict
    :return: {}

    """
    pass


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


def put_dict_value(data, address, value):
    """Accepts a dictionary and an "address" (a list representing a nested dict value's key)
    and sets the value at that "address".
        >>> d = {'mailserver_users': [{...}, {...}], ...}
        >>> a = ['mailserver_users', 1, 'newkey']
        >>> put_dict_value(d, a, 'newval')
        {..., 'mailserver_users': [{...}, {'newkey': 'newval', ...}]}
    """
    for key in address[:-1]:
        data = data[key]
    data[address[-1]] = value
    return data


def get_isam_user(isamAppliance, check_mode=False, force=False):
    """
    Retrieve configuration of SCIM ISAM user settings
    """
    ret_obj = isamAppliance.invoke_get(
        'Retrieve configuration of SCIM ISAM user settings',
        '/mga/scim/configuration/urn:ietf:params:scim:schemas:extension:isam:1.0:User'
        )
    return ret_obj['data'][
        'urn:ietf:params:scim:schemas:extension:isam:1.0:User']


def get_sorted_paths_list(paths):
    """
    Gets sorted paths list

    Parameters
    ----------
    paths
        Dictionary of paths associated with their count

    Returns
    ----------
    listpaths
        Sorted paths list
    """
    listpaths = []
    for p in paths:
        listpaths.append([p, paths[p]])
    listpaths = sorted(listpaths, key=lambda x: x[1], reverse=True)
    return listpaths


@classmethod
def from_event(cls, ion_event):
    """Constructs the given native extension from the properties of an event.

        Args:
            ion_event (IonEvent): The event to construct the native value from.
        """
    if ion_event.value is not None:
        args, kwargs = cls._to_constructor_args(ion_event.value)
    else:
        args, kwargs = (), {}
    value = cls(*args, **kwargs)
    value.ion_type = ion_event.ion_type
    value.ion_annotations = ion_event.annotations
    return value


def precision_metric(y_true, y_pred):
    """Calculate the Precision from a keras batch"""
    from keras import backend as K
    true_positives = K.sum(K.round(K.clip(y_true * y_pred, 0, 1)))
    predicted_positives = K.sum(K.round(K.clip(y_pred, 0, 1)))
    precision = true_positives / (predicted_positives + K.epsilon())
    return precision


def get_static_ips(pageToken=None):
    """
    Returns information about all static IPs in the user's account.
    See also: AWS API Documentation

    :example: response = client.get_static_ips(
        pageToken='string'
    )

    :type pageToken: string
    :param pageToken: A token used for advancing to the next page of results from your get static IPs request.

    :rtype: dict
    :return: {
        'staticIps': [
            {
                'name': 'string',
                'arn': 'string',
                'supportCode': 'string',
                'createdAt': datetime(2015, 1, 1),
                'location': {
                    'availabilityZone': 'string',
                    'regionName': 'us-east-1'|'us-west-1'|'us-west-2'|'eu-west-1'|'eu-central-1'|'ap-south-1'|'ap-southeast-1'|'ap-southeast-2'|'ap-northeast-1'|'ap-northeast-2'
                },
                'resourceType': 'Instance'|'StaticIp'|'KeyPair'|'InstanceSnapshot'|'Domain'|'PeeredVpc',
                'ipAddress': 'string',
                'attachedTo': 'string',
                'isAttached': True|False
            },
        ],
        'nextPageToken': 'string'
    }

    """
    pass


def bitmaplist_contain(bm1, bm2):
    """
        bitmaplist_contain([1,0,1,0],[0,0,0,0])
        bitmaplist_contain([1,0,1,0],[0,0,1,0])
        bitmaplist_contain([1,0,1,0],[1,0,0,0])
        bitmaplist_contain([1,0,1,0],[1,0,1,0])
        bitmaplist_contain([1,0,1,0],[0,0,0,1])
    """
    bm3 = list(map(lambda x, y: x | y, bm1, bm2))
    if bm3 == bm1:
        return True
    else:
        return False


def network_bytes_to_kind_and_offset(network_bytes):
    """Strip of a record kind from the front of network_bytes.

    :param network_bytes: The bytes of a record.
    :return: A tuple (storage_kind, offset_of_remaining_bytes)
    """
    line_end = network_bytes.find(b'\n')
    storage_kind = network_bytes[:line_end].decode('ascii')
    return storage_kind, line_end + 1


@staticmethod
def _sentence_tokenizer_merge_matches(match):
    """ Best way we found to deal with repeating groups"""
    start, end = match.span()
    return match.string[start:end] + '<SPLIT>'


def _int2r(val):
    """Convert the integer value to the light sensor resistance.

    This method should only be used internally.

    Note
    ----
    A smaller returned value indicates a higher brightness. Resistance
    value ranges from 5.0 (brightest) to 35.0 (darkest).

    Parameters
    ----------
    val : int
        The raw data read from grove ADC.

    Returns
    -------
    float
        The light sensor resistance indicating the light intensity.

    """
    if 0 < val <= 4095:
        r_sensor = (4095.0 - val) * 10 / val
    else:
        raise RuntimeError('Value out of range or device not connected.')
    return float('{0:.2f}'.format(r_sensor))


def GetSGSpin(SGData, MSgSym):
    """get spin generators from magnetic space group symbol"""
    SpGrp = SGData['SpGrp']
    mSgSym = MSgSym + ' '
    Flds = SpGrp.split()
    iB = 0
    Spn = [1]
    if len(Flds) == 2:
        fld = Flds[1]
        iF = mSgSym[iB:].index(fld[0]) + iB
        jF = mSgSym[iF:].index(fld[-1]) + iF
        if '/' in mSgSym[iF:jF]:
            if "'" in mSgSym[iF:jF]:
                Spn.append(-1)
            else:
                Spn.append(1)
        if "'" == mSgSym[jF + 1]:
            Spn.append(-1)
        else:
            Spn.append(1)
    elif len(Flds) == 3:
        if SGData['SGPtGrp'] == '-3m':
            if not mSgSym.count("'"):
                Spn += [1, 1]
            elif mSgSym.count("'") == 2:
                Spn += [-1, 1]
            elif "3'" in mSgSym:
                Spn += [1, -1]
            else:
                Spn += [-1, -1]
        elif "'" in mSgSym:
            Spn.append(-1)
        else:
            Spn.append(1)
    else:
        for fld in Flds[1:]:
            iF = mSgSym[iB:].index(fld[0]) + iB
            jF = mSgSym[iF:].index(fld[-1]) + iF
            if "'" == mSgSym[jF + 1]:
                Spn.append(-1)
                iB = jF + 2
            else:
                Spn.append(1)
                iB = jF + 1
    Spn.append(1)
    return Spn


def make_comment(content: str) ->str:
    """Return a consistently formatted comment from the given `content` string.

    All comments (except for "##", "#!", "#:") should have a single space between
    the hash sign and the content.

    If `content` didn't start with a hash sign, one is provided.
    """
    content = content.rstrip()
    if not content:
        return '#'
    if content[0] == '#':
        content = content[1:]
    if content and content[0] not in ' !:#':
        content = ' ' + content
    return '#' + content


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

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

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


def create_pull_request(repo, branch_name, base=None, title=None):
    """Creates a pull request for the given branch"""
    base = base or 'master'
    title = title or 'Auto-Generated Pull Request'
    pull_request = repo.create_pull(title, base, branch_name)
    return pull_request


def guard_no_cluster(clusters):
    """Throws if no clusters have been specified, either via configuration or via the command line"""
    if not clusters:
        raise Exception('You must specify at least one cluster.')


def prepare_lookup_value(key, value):
    """
    Returns a lookup value prepared to be used in queryset filtering.
    """
    if key.endswith('__in'):
        value = value.split(',')
    if key.endswith('__isnull') and type(value) == str:
        if value.lower() in ('', 'false'):
            value = False
        else:
            value = True
    return value


def redirectRequest(url):
    """ Redirects request to specified url. """


def spin_double(basis, lamdict):
    """
    Double the size of a basis to introduce spin to the problem.
    Go through the basis and create an identical copy with opposite spin and
    incremented index such that the orbital basis order puts spin down in the first
    N/2 orbitals, and spin up in the second N/2.

    *args*:

        - **basis**: list of orbital objects

        - **lamdict**: dictionary of int:float pairs providing the
        spin-orbit coupling strength for the different inequivalent atoms in
        basis.

    *return*:

        - doubled basis carrying all required spin information

    ***
    """
    LB = len(basis)
    basis_double = []
    for ind in range(LB):
        basis[ind].spin = -1
        basis[ind].lam = lamdict[basis[ind].atom]
        spin_up = basis[ind].copy()
        spin_up.spin = 1
        spin_up.index = basis[ind].index + LB
        basis_double.append(spin_up)
    return basis + basis_double


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


def server_ad_admin_update(instance, login=None, sid=None, tenant_id=None):
    """
    Updates a server' AD admin.
    """
    instance.login = login or instance.login
    instance.sid = sid or instance.sid
    instance.tenant_id = tenant_id or instance.tenant_id
    return instance


def _reset_counter_to_gs_counts(walker):
    """
    Reset GS instance counts
    """
    walker.counter.reset_to_node('/ISA_LOOP/GS_LOOP')
    walker.counter.increment('/ISA_LOOP/GS_LOOP')
    walker.counter.increment('/ISA_LOOP/GS_LOOP/GS')


def decorate(f):
    """decorate(f)(item) => (f(item), item)

    >>> decorate(str)(2)
    ('2', 2)
    >>> negate = lambda x: 0 - x
    >>> list(map(decorate(negate), [1,2,3,4]))
    [(-1, 1), (-2, 2), (-3, 3), (-4, 4)]

    Useful in decorate-OPERATION-undecorate types of operations.

    Use 'snd' to undecorate the item.
    Here's a contrived example using 'sort'.

    >>> list(map(snd, sorted(map(decorate(negate), [1,2,4,3]))))
    [4, 3, 2, 1]

    Note you shouldn't actually do the above.  sorted() already takes
    a key kwarg.  Do this instead:

    >>> sorted([1,2,4,3], key=negate)
    [4, 3, 2, 1]

    However it's useful if the function you're using doesn't have a 'key'
    argument.  If your function is higher-order, and doesn't handle
    tuples, lift_fst might help.
    """
    return lambda item: (f(item), item)


def _convert_bool(boolean):
    """Convert to stringified boolean"""
    return str(boolean).lower()


def conv3x3(in_planes, out_planes, fn, stride=1):
    """3x3 convolution with padding"""
    return fn(in_planes, out_planes, kernel_size=3, stride=stride, padding=
        1, bias=False)


def safefloat(num):
    """converts to float, regardless
  """
    try:
        v = float(num)
    except:
        v = 0.0
    return v


def infinitve(conjugate, infinitive_map):
    """Get infinitive form of a conjugated verb.

    Given a mapping of conjugate to infinitive, this function computes
    the infinitive form of a conjugate verb. We provide models available
    for downloading, so you do not have to worry about the ``infinitive_map``.
    Regretfully we only provide models for Spanish texts.

    :param conjugate: Verb to be processed
    :type conjugate: string
    :param infinitve_map: Lexicon containing maps from conjugate to infinitive.
    :type infinitive_map: dict
    :return: Infinitive form of the verb, None if not found
    :rtype: string
    """
    conjugate = conjugate.lower()
    for word_list in infinitive_map:
        if conjugate in word_list:
            infinitive = infinitive_map[word_list]
            return infinitive if infinitive else None
    return None


@classmethod
def add_common_opts(cls, parser):
    """Add options that are common for several plugins."""
    for opt in cls.common_opt_names:
        cls._parser_add_opt(parser, opt)


def create(connection):
    """Create the latest version of the schema. This function should be
    idempotent."""
    import stucco_evolution
    stucco_evolution.Base.metadata.create_all(connection)


def strip_zeros(file_name):
    """Sometimes the covers don't have the same leading characters as
	the .nfo and .sfv file. In this case the .nfo file is most likely
	renamed too. e.g. Gentleman-Runaway-EP-2003-TLT"""
    if file_name.startswith(('00-', '00_', '01-', '01_')):
        return file_name[3:]
    elif file_name.startswith(('000-', '000_', '001-', '001_')):
        return file_name[4:]
    elif file_name.startswith(('0000-', '0000_', '0001-', '0001_')):
        return file_name[5:]
    else:
        return file_name


def validate_format(*_arg):
    """
    This method can be overridden with format validation logic.
    """
    return True


def _colon_split(value):
    """ If `value` contains colons, return a list split at colons,
  return value otherwise. """
    value_list = value.split(':')
    if len(value_list) > 1:
        return value_list
    return value


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

        :param ShowcaseUnresolveCommentType val:
        :rtype: EventType
        """
    return cls('showcase_unresolve_comment', val)


def convertToTree(tree):
    """Override this function to convert a set of values to a tree."""
    return None


def is_image(filename):
    """
    Check if filename has valid extension

    :param filename:
    :return: boolean indicating whether filename is a valid image filename
    """
    filename = filename.lower()
    return filename.endswith('.jpg') or filename.endswith('.png'
        ) or filename.endswith('.jpeg') or filename.endswith('.gif'
        ) or filename.endswith('.bmp')


def for_interface(interface, check=True, omit=(), prefix=None):
    """Get an IRecordsProxy for the given interface. If `check` is True,
        an error will be raised if one or more fields in the interface does
        not have an equivalent setting.
        """


@staticmethod
def deserialize(byts, protocol_version):
    """
        Given a bytestring, deserialize into a value according to the protocol
        for this type. Note that this does not create a new instance of this
        class; it merely gives back a value that would be appropriate to go
        inside an instance of this class.
        """
    return byts


@staticmethod
def get_message_id_from_thread(message):
    """Get Iris message id from Gmail message thread

        :param message: Gmail message
        :return: Iris message id
        :rtype: int
        """
    raise NotImplementedError


@classmethod
def static_method(cls, f):
    """Decorator which dynamically binds static methods to the model for later use."""
    setattr(cls, f.__name__, staticmethod(f))
    return f


def isint(str):
    """ Is the given string an integer

    >>> isint(str('1234'))
    1
    >>> isint(str('11a'))
    0
    """
    ok = 1
    if not str:
        return 0
    try:
        int(str)
    except ValueError:
        ok = 0
    except TypeError:
        ok = 0
    return ok


def triangle(start, end):
    """Draw triangle from start to end."""
    pass


def cumprod(x, axis=0):
    """Cumulative product of the values in a tensor, alongside the specified axis.

    # Arguments
        x: A tensor or variable.
        axis: An integer, the axis to compute the product.

    # Returns
        A tensor of the cumulative product of values of `x` along `axis`.
    """
    raise NotImplementedError(
        'MXNet Backend: cumprod operator is not supported yet.')


@classmethod
def _new(cls, name, *args, **kwargs):
    """
        User custom instance constructor.

        implement constructor this way::

            def _new(cls, name, *args, **kwargs):
                self = cls.__new__(cls)
                # put __init__(...) logic here
                self.name = name
                return self
        """
    raise NotImplementedError


def city_custom_handler(city):
    """
    Manages special cases on a city object.
    """
    pass


def rstrip(text, chars=None):
    """
    Creates a copy of ``text`` with trailing characters removed.

    The ``chars`` argument is a string specifying the set of characters to be removed. If
    omitted or None, the ``chars`` argument defaults to removing whitespace. The ``chars``
    argument is not a suffix; rather, all combinations of its values are stripped::

        >>>
        >>> rstrip('   spacious   ')
        '   spacious'
        >>> rstrip('mississippi','ipz')
        'mississ'

    :param text: The string to copy
    :type text:  ``str``

    :param chars: The trailing characters to remove
    :type chars:  ``str``

    :return: A copy of ``text`` with the trailing characters removed.
    :rtype:  ``str``
    """
    assert isinstance(text, str), '%s is not a string' % text
    return text.rstrip(chars)


def shape_key_remove(all: bool=False):
    """Remove shape key from the object

    :param all: All, Remove all shape keys
    :type all: bool
    """
    pass


@staticmethod
def prepareKeyValue(outputData, key, value):
    """ This function will append key and value in
            outputData
            if variable key exist, it will rename by
                    key1, key2, ...
        """
    for i in range(1, 100):
        var = '$(' + key + str(i) + ')'
        if not outputData.get(var, None):
            outputData[var] = value
            return var
        else:
            continue


@classmethod
def header(cls):
    """Header for HTML file."""
    return cls.html_header


def fortran_include(fname):
    """functions similar to a fortran include"""
    vars = []
    f_inc = open(fname)
    for line in f_inc:
        if 'c' in line[0]:
            pass
        elif 'parameter' in line:
            vars.extend(eval(line))
        else:
            pass
    f_inc.close()
    return vars


def select_mirror(extend: bool=False):
    """Select the Mirror objects of the selected object eg. L.sword -> R.sword

    :param extend: Extend, Extend selection instead of deselecting everything first
    :type extend: bool
    """
    pass


def false_if_empty_filter(value):
    """
    Returns 'false' if the provided value is empty.

    Args:
      value (object): the value
    Result:
      boolean: the result
    """
    if not isinstance(value, bool) and not value:
        return False
    else:
        return True


def file_cmp(fp1, fp2, bufsize=8 * 1024):
    """ Like filecmp.cmp except arguments are file-like objects instead of file names """
    while True:
        b1 = fp1.read(bufsize)
        b2 = fp2.read(bufsize)
        if b1 != b2:
            return False
        if not b1:
            return True


@classmethod
def parse(cls, reader, track_offset):
    """returns this cuesheet index from a BitstreamReader"""
    offset, number = reader.parse('64U8u24p')
    return cls(track_offset=track_offset, offset=offset, number=number)


def kama(df, price, kama, n, fast_ema=2, slow_ema=30):
    """
    Kaufman's Adaptive Moving Average (KAMA) is a moving average designed to
    account for market noise or volatility. KAMA will closely follow prices when
    the price swings are relatively small and the noise is low. KAMA will adjust
    when the price swings widen and follow prices from a greater distance.

    Parameters:
        df (pd.DataFrame): DataFrame which contain the asset information.
        price (string): the column name for the series type of the asset.
        kama (string): the column name for the kama results.
        n (int): the total number of periods.
        fast_ema (int): the time period of the fast exponential moving average.
        slow_ema (int): the time period of the slow exponential moving average.

    Returns:
        df (pd.DataFrame): Dataframe with kama of the asset calculated.

    """
    er = df[price].diff(n).abs() / df[price].diff().abs().rolling(window=n
        ).sum()
    fast_sc = 2 / (fast_ema + 1)
    slow_sc = 2 / (slow_ema + 1)
    df[kama + '_sc'] = (er * (fast_sc - slow_sc) + slow_sc) ** 2
    prev_kama = list(df[:n][price].rolling(window=n).mean())[-1]
    df.loc[n - 1, kama] = prev_kama
    df.loc[n:, (kama)] = 0.0
    kamas = [(0.0) for i in range(n)]
    for row in df.loc[n:, ([price, kama + '_sc'])].itertuples(index=False):
        kamas.append(prev_kama + row[1] * (row[0] - prev_kama))
        prev_kama = kamas[-1]
    df[kama] += kamas
    df = df.dropna().reset_index(drop=True)
    df.drop([kama + '_sc'], axis=1, inplace=True)
    return df