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


def filter_framework_frames(stack):
    """
    Returns a stack clean of framework frames
    """
    result = list()
    for frame in stack:
        if 'flow/core' not in frame[0]:
            result.append(frame)
    return result


def stuff_in_dict(this_dict, key):
    """
    if the `this_dict` dictionary is not empty then return a new dictionary that
    has one (key, value) pair, where the key is set to `key` and the value is set to `this_dict`

    :param this_dict: dictionary
    :param key: string
    :return: dictionary
    """
    return {key: this_dict} if len(this_dict) > 0 else {}


def validate_str_or_list(value):
    """
    Method to raise error if a value is not a list.
    :param value: value to check to make sure it is a string, list, or None
    :returns: None or TypeError
    """
    if isinstance(value, (str, list)) or value is None:
        return True
    else:
        raise TypeError('Must be a str or list')


def recursive_getattr(root, path):
    """ returns root.path (i.e. root.attr1.attr2) """
    attribute = root
    for name in path.split('.'):
        if name != '':
            attribute = getattr(attribute, name)
    return attribute


def passes_filter_ucsc(segment):
    """Decide whether segment passes filters for UCSC data."""
    if not segment.attrs['transcript_id'].startswith('NM'):
        return False
    if segment.attrs['gene_id'].startswith('LOC'):
        return False
    return True


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

        :param ShowcaseResolveCommentType val:
        :rtype: EventType
        """
    return cls('showcase_resolve_comment', val)


def add_ros_arguments(parser):
    """
    Arguments relevant for a ros system.

    :param argparse.ArgumentParser parser:
    """
    group = parser.add_argument_group(title='ros arguments')
    group.add_argument('--rosdistro', action='store', default=None, help=
        'manually specify the ros release to install/update')


def common_filters(marker=None, limit=None, sort_key=None, sort_dir=None):
    """Generate common filters for any list request.

    :param marker: entity ID from which to start returning entities.
    :param limit: maximum number of entities to return.
    :param sort_key: field to use for sorting.
    :param sort_dir: direction of sorting: 'asc' or 'desc'.
    :returns: list of string filters.
    """
    filters = []
    if isinstance(limit, int):
        filters.append('filters.field=limit')
        filters.append('filters.value=%d' % limit)
    if marker is not None:
        filters.append('filters.field=marker')
        filters.append('filters.value=%s' % marker)
    if sort_key is not None:
        filters.append('filters.field=sort_key')
        filters.append('filters.value=%s' % sort_key)
    if sort_dir is not None:
        filters.append('filters.field=sort_dir')
        filters.append('filters.value=%s' % sort_dir)
    return filters


def hide_view_clear(select: bool=True):
    """Reveal the layer by setting the hide flag

    :param select: Select
    :type select: bool
    """
    pass


@classmethod
def broadcast_tx(cls, tx_hex):
    """Broadcasts a transaction to the blockchain.

        :param tx_hex: A signed transaction in hex form.
        :type tx_hex: ``str``
        :raises ConnectionError: If all API services fail.
        """
    success = None
    for api_call in cls.BROADCAST_TX_MAIN:
        try:
            success = api_call(tx_hex)
            if not success:
                continue
            return
        except cls.IGNORED_ERRORS:
            pass
    if success is False:
        raise ConnectionError(
            'Transaction broadcast failed, or Unspents were already used.')
    raise ConnectionError('All APIs are unreachable.')


def split_code(code, split_on=' = '):
    """Split the code in half on the string specified by `split_on`.

    Args:
        code (str): A string containg code
        split_on (str): The string on which to split the code

    Returns:
        (tuple) Code before and after the string `split_on`
    """
    splitted_code = code.split(split_on)
    if len(splitted_code) > 2:
        raise ValueError('Code has been splitted into more than two fragements'
            )
    return splitted_code if len(splitted_code) == 2 else ('', splitted_code[0])


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


def _get_real_user(user, anon_user=None):
    """
    Given a "user" that could be:

    * a real user object
    * a function that returns a real user object
    * a LocalProxy to a real user object (like Flask-Login's ``current_user``)

    This function returns the real user object, regardless of which we have.
    """
    if hasattr(user, '_get_current_object'):
        user = user._get_current_object()
    if callable(user):
        user = user()
    if anon_user and isinstance(user, anon_user):
        return None
    return user


@classmethod
def get_class_field(cls, field_name):
    """
        Return the field object with the given name (for the class, the fields
        are in the "_redis_attr_%s" form)
        """
    if not cls.has_field(field_name):
        raise AttributeError('"%s" is not a field for the model "%s"' % (
            field_name, cls.__name__))
    return getattr(cls, '_redis_attr_%s' % field_name)


def mod9710(iban):
    """
    Calculates the MOD 97 10 of the passed IBAN as specified in ISO7064.

    @method mod9710
    @param {String} iban
    @returns {Number}
    """
    remainder = iban
    block = None
    while len(remainder) > 2:
        block = remainder[:9]
        remainder = str(int(block) % 97) + remainder[len(block):]
    return int(remainder) % 97


def merge_tokens(tokenlist):
    """put all provided tokens into one token."""
    supertoken = {}
    for entry in tokenlist:
        try:
            for key in entry.keys():
                supertoken[key] = entry[key]
        except AttributeError:
            pass
    if supertoken == {}:
        return None
    return supertoken


def getSignalName(frameOrName, signalNum, db):
    """Retrieve string name of signal.

    frameOrName is the ID str or int for the message. signalNum is the int representing that this signal
    is the nth signal in the message. If the signal is not in the DBC, it will return a name
    "not in the DBC", and print out a warning.

    e.g. getSignalName(37,1, db2) or getSignalName('STEER_ANGLE_SENSOR',2, db2)
    """
    if type(frameOrName) is int:
        try:
            name = db.get_message_by_frame_id(frameOrName).signals[signalNum
                ].name
        except:
            print('warning: str addr not in DBC')
            name = 'not in DBC'
    elif type(frameOrName) is str:
        try:
            name = db.get_message_by_name(frameOrName).signals[signalNum].name
        except:
            print('warning: str addr not in DBC')
            name = 'not in DBC'
    return name


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

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


def hotKey(s):
    """
    Return the hotkey from a '~T~ilde' formatted string

    :param s: String
    :return: The escaped character or None
    """
    head, _, tail = s.partition('~')
    if tail:
        return tail[0].upper()
    return None


def subpixel(x, out_channels=1):
    """Unfold channel/depth dimensions to enlarge the feature map
    Notice: Output size is deducted.
    The size of the unfold square is automatically determined
    e.g. :
        images: 100x9x16x16.  9=3x3 square
        subpixel-out: 100x1x48x48
    Arguement:
        x: NCHW image, channel first.
        out_channels, channel number of output feature map"""
    b, c, h, w = shapes = list(x.shape)
    out_c = int(out_channels)
    if c % out_c != 0:
        print('input has', c, 'channels, cannot be split into', out_c, 'parts')
        raise Exception('subpixel inappropriate size')
    unfold_dim = int(c // out_c)
    l = int(unfold_dim ** 0.5)
    if l ** 2 != unfold_dim:
        print('remaining', unfold_dim,
            'digits for each channel, unable to sqrt.')
        raise Exception('subpixel inappropriate size %f**2 != %d' % (l, int
            (unfold_dim)))
    x = x.transpose(1, 3)
    y = x.reshape(b, h, w, unfold_dim, out_c)
    y = y.transpose(2, 3)
    y = y.reshape(b, h, l, l, w, out_c)
    y = y.reshape(b, l * h, l, w, out_c)
    y = y.transpose(2, 3)
    y = y.reshape(b, l * h, l * w, out_c)
    y = y.transpose(1, 3)
    return y


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


def div_inplace(X, varX, Y, varY):
    """In-place division with error propagation"""
    X /= Y
    T = X ** 2
    T *= varY
    varX += T
    del T
    T = Y ** 2
    varX /= T
    return X, varX


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


def singleton(ensemble):
    """Retourne l'unique élément contenu dans `ensemble`.
    """
    for element in ensemble:
        return element


def get_frame_from_json(frame):
    """Get/sanitize raw frame from JSON of frame from `tshark -x -T json ...`

    Args:
        frame (dict): A dict of a single packet from tshark.
    Returns:
        (str): The ASCII hexdump value of a packet
    """
    if not isinstance(frame, dict):
        print('frame is type', type(frame))
        raise TypeError('Frame must be dict!\n' + str(frame)[:120] + '...')
    frame_raw = frame['_source']['layers']['frame_raw']
    if isinstance(frame_raw, list):
        frame_raw = frame_raw[0]
    return frame_raw


def is_truthy(candidate_value):
    """
    Converts many representations of "True" into a boolean True
    @param: candidate_value - the value to be evaluated. Any of the following will be considered True
    "true", "TRUE", "True", "1", any number except zero, True
    """
    if isinstance(candidate_value, str):
        return candidate_value.lower() in ['true', '1']
    elif isinstance(candidate_value, int):
        return bool(candidate_value)
    elif isinstance(candidate_value, bool):
        return candidate_value
    else:
        raise TypeError('Expected a str, int or bool and got {}'.format(
            type(candidate_value)))


def __contains__(relation):
    """returns whether the relation is in the index"""


def upgrade():
    """A no-op migration for marking the Kilo release."""
    pass


def reset_session(c):
    """remove the session_id cookie and init a new session."""
    c.clear_cookie('session_id')
    c.init_session(new=True)


def stringLengthCompare(a, b):
    """
    _stringLengthCompare_

    Sort comparison function to sort strings by length from longest to shortest.
    """
    if len(a) > len(b):
        return -1
    if len(a) == len(b):
        return 0
    else:
        return 1


def when(index, *args, **kwargs):
    """Helper function so we don't have to specify json for everything."""
    kwargs.setdefault('content_type', 'application/json')
    kwargs.setdefault('template', 'json')
    return index.when(*args, **kwargs)


def sel_val_from_dim(data, dim, x):
    """ Select values from a dim.
    """
    try:
        return data.sel({dim: x})
    except:
        return data.sel({dim: x}, method='nearest')


def _endswith(value):
    """
    Maps to `string.endswith`.
    """
    return lambda v: v.endswith(value)


@classmethod
def remove(cls, name):
    """Remove provider from the registry, if it exists."""
    if name in cls._REGISTRY:
        del cls._REGISTRY[name]


def cd2d(cd, e):
    """Transform from *cd* index value to *d* count value, using the
    *e.css('ch')* (column depth) as column measure."""
    if cd is None:
        d = 0
    else:
        d = cd * (e.css('cd', 0) + e.gd) - e.gd
    return d


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


@classmethod
def from_parent_resource(cls, parent_resource):
    """Create a GroupInspector from a parent resource.

        This is a convenience method to instantiate a GroupInspector from a
        Heat StackResource object.
        """
    return cls(parent_resource.context, parent_resource.rpc_client(),
        parent_resource.nested_identifier())


def _median(data):
    """Return the median (middle value) of numeric data.

	When the number of data points is odd, return the middle data point.
	When the number of data points is even, the median is interpolated by
	taking the average of the two middle values:

	>>> median([1, 3, 5])
	3
	>>> median([1, 3, 5, 7])
	4.0

	"""
    data = sorted(data)
    n = len(data)
    if n == 0:
        raise ValueError('no median for empty data')
    if n % 2 == 1:
        return data[n // 2]
    else:
        i = n // 2
        return (data[i - 1] + data[i]) / 2


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

    """
    pass


def get_current_progress(db, progress_table):
    """How many lines in index.csv have we processed?

    progcoll -> name of the postgres table that maintains processing info.

    This table contains exactly one row, with one integer value,
    that represents the number of input lines processed.

    If starting afresh, the value will be 0.
    """
    sql = ("""
    SELECT progress
      FROM %(progress_table)s
    """ %
        locals())
    return db.execute(sql).fetchone()[0]


def decimate(it, nd=10):
    """
    Return first then each 'nd' elements from iterable 'it'.

    Parameters
    -----------

    it : iterable
        Input data.

    nd : int
        Decimation factor

    Returns
    -------

    l : list
        One in 'nd' values from 'it'.

    """
    assert isinstance(nd, int), "'nd' is not an integer: {0!r}".format(nd)
    assert nd > 0, "'nd' is not a positive integer: {0!r}".format(nd)
    l = list()
    n = 0
    for el in it:
        if not n % nd:
            l.append(el)
        n += 1
    return l


def dtype(x):
    """Returns the dtype of a Keras tensor or variable, as a string.

    # Arguments
        x: Tensor or variable.

    # Returns
        String, dtype of `x`.

    # Examples
    ```python
        >>> from keras import backend as K
        >>> K.dtype(K.placeholder(shape=(2,4,5)))
        'float32'
        >>> K.dtype(K.placeholder(shape=(2,4,5), dtype='float32'))
        'float32'
        >>> K.dtype(K.placeholder(shape=(2,4,5), dtype='float64'))
        'float64'
        # Keras variable
        >>> kvar = K.variable(np.array([[1, 2], [3, 4]]))
        >>> K.dtype(kvar)
        'float32'
        >>> kvar = K.variable(np.array([[1, 2], [3, 4]]), dtype='float32')
        >>> K.dtype(kvar)
        'float32'
    ```
    """
    return x.dtype


@classmethod
def encode(cls, packets):
    """
        Placeholder for packet encoding

        :returns: ``packets``
        """
    return packets


def get_inventory(Filters=None, ResultAttributes=None, NextToken=None,
    MaxResults=None):
    """
    Query inventory information.
    See also: AWS API Documentation

    :example: response = client.get_inventory(
        Filters=[
            {
                'Key': 'string',
                'Values': [
                    'string',
                ],
                'Type': 'Equal'|'NotEqual'|'BeginWith'|'LessThan'|'GreaterThan'
            },
        ],
        ResultAttributes=[
            {
                'TypeName': 'string'
            },
        ],
        NextToken='string',
        MaxResults=123
    )

    :type Filters: list
    :param Filters: One or more filters. Use a filter to return a more specific list of results.
            (dict) --One or more filters. Use a filter to return a more specific list of results.
            Key (string) -- [REQUIRED]The name of the filter key.
            Values (list) -- [REQUIRED]Inventory filter values. Example: inventory filter where instance IDs are specified as values Key=AWS:InstanceInformation.InstanceId,Values= i-a12b3c4d5e6g, i-1a2b3c4d5e6,Type=Equal
            (string) --
            Type (string) --The type of filter. Valid values include the following: 'Equal'|'NotEqual'|'BeginWith'|'LessThan'|'GreaterThan'

    :type ResultAttributes: list
    :param ResultAttributes: The list of inventory item types to return.
            (dict) --The inventory item result attribute.
            TypeName (string) -- [REQUIRED]Name of the inventory item type. Valid value: AWS:InstanceInformation. Default Value: AWS:InstanceInformation.

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

    :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.

    :rtype: dict
    :return: {
        'Entities': [
            {
                'Id': 'string',
                'Data': {
                    'string': {
                        'TypeName': 'string',
                        'SchemaVersion': 'string',
                        'CaptureTime': 'string',
                        'ContentHash': 'string',
                        'Content': [
                            {
                                'string': 'string'
                            },
                        ]
                    }
                }
            },
        ],
        'NextToken': 'string'
    }

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

    """
    pass


@classmethod
def get_desc(cls, name):
    """Retrieves character set information as string using an ID

        Retrieves character set and collation information based on the
        given MySQL ID.

        Returns a tuple.
        """
    try:
        return '%s/%s' % cls.get_info(name)
    except:
        raise


def common_filters(limit=None, sort_key=None, sort_dir=None, marker=None):
    """Generate common filters for any list request.

    :param limit: maximum number of entities to return.
    :param sort_key: field to use for sorting.
    :param sort_dir: direction of sorting: 'asc' or 'desc'.
    :param marker: The last actionplan UUID of the previous page.
    :returns: list of string filters.
    """
    filters = []
    if isinstance(limit, int) and limit > 0:
        filters.append('limit=%s' % limit)
    if sort_key is not None:
        filters.append('sort_key=%s' % sort_key)
    if sort_dir is not None:
        filters.append('sort_dir=%s' % sort_dir)
    if marker is not None:
        filters.append('marker=%s' % marker)
    return filters


def head(your_list, default=None):
    """Simple head function implementation."""
    return next(iter(your_list or []), default)


def split_iniline_with_one_spacekw(line):
    """
        split_iniline_with_one_spacekw()
        ________________________________________________________________________

        Split a line read from a .ini file containing just ONE 'SPACE' keyword.
        ________________________________________________________________________

        PARAMETER:
        ▪ line : str

        RETURNED STRING: the expected list of str.
    """
    res = line.split()
    space_index = res.index('SPACE')
    if space_index != -1:
        res[space_index] = ' '
    return res


def update_dictionary(dictionary, key, value):
    """
    Add the key-value pair to the dictionary and return the dictionary.

    :dictionary: dict object
    :key: String (e.g. module name)
    :value: Integer (e.g. line number)
    :returns: dict object
    """
    if key not in dictionary:
        dictionary[key] = [value]
    elif value not in dictionary[key]:
        dictionary[key].append(value)
    return dictionary


def split_dict(dict_, set_):
    """
    Partitions a dictionary into two disjoint sub-dictionaries.

    :param dict_: The original dictionary.

    :param set_: A set of keys used to form the disjoint dictionary.
    """
    new_dict = {}
    old_dict = {}
    for key, value in dict_.items():
        if key in set_:
            new_dict[key] = value
        else:
            old_dict[key] = value
    return old_dict, new_dict


def build_cmd(remote):
    """
    Build the command we pass the script to

    >>> build_cmd({'scheme': ''})
    ['sh']
    >>> build_cmd({'scheme': 'ssh', 'host': 'host', 'port': 80})
    ['ssh', '-p', 80, 'host', 'sh']
    """
    cmd = []
    if remote['scheme']:
        cmd.append('ssh')
        if remote['port']:
            cmd.extend(['-p', remote['port']])
        cmd.append(remote['host'])
    cmd.append('sh')
    return cmd


def cellDijFill(pfx, phfx, SGData, parmDict):
    """Returns the filled-out reciprocal cell (A) terms
    from the parameter dictionaries corrected for Dij.

    :param str pfx: parameter prefix ("n::", where n is a phase number)
    :param dict SGdata: a symmetry object
    :param dict parmDict: a dictionary of parameters

    :returns: A,sigA where each is a list of six terms with the A terms
    """
    if SGData['SGLaue'] in ['-1']:
        A = [parmDict[pfx + 'A0'] + parmDict[phfx + 'D11'], parmDict[pfx +
            'A1'] + parmDict[phfx + 'D22'], parmDict[pfx + 'A2'] + parmDict
            [phfx + 'D33'], parmDict[pfx + 'A3'] + parmDict[phfx + 'D12'],
            parmDict[pfx + 'A4'] + parmDict[phfx + 'D13'], parmDict[pfx +
            'A5'] + parmDict[phfx + 'D23']]
    elif SGData['SGLaue'] in ['2/m']:
        if SGData['SGUniq'] == 'a':
            A = [parmDict[pfx + 'A0'] + parmDict[phfx + 'D11'], parmDict[
                pfx + 'A1'] + parmDict[phfx + 'D22'], parmDict[pfx + 'A2'] +
                parmDict[phfx + 'D33'], 0, 0, parmDict[pfx + 'A5'] +
                parmDict[phfx + 'D23']]
        elif SGData['SGUniq'] == 'b':
            A = [parmDict[pfx + 'A0'] + parmDict[phfx + 'D11'], parmDict[
                pfx + 'A1'] + parmDict[phfx + 'D22'], parmDict[pfx + 'A2'] +
                parmDict[phfx + 'D33'], 0, parmDict[pfx + 'A4'] + parmDict[
                phfx + 'D13'], 0]
        else:
            A = [parmDict[pfx + 'A0'] + parmDict[phfx + 'D11'], parmDict[
                pfx + 'A1'] + parmDict[phfx + 'D22'], parmDict[pfx + 'A2'] +
                parmDict[phfx + 'D33'], parmDict[pfx + 'A3'] + parmDict[
                phfx + 'D12'], 0, 0]
    elif SGData['SGLaue'] in ['mmm']:
        A = [parmDict[pfx + 'A0'] + parmDict[phfx + 'D11'], parmDict[pfx +
            'A1'] + parmDict[phfx + 'D22'], parmDict[pfx + 'A2'] + parmDict
            [phfx + 'D33'], 0, 0, 0]
    elif SGData['SGLaue'] in ['4/m', '4/mmm']:
        A = [parmDict[pfx + 'A0'] + parmDict[phfx + 'D11'], parmDict[pfx +
            'A0'] + parmDict[phfx + 'D11'], parmDict[pfx + 'A2'] + parmDict
            [phfx + 'D33'], 0, 0, 0]
    elif SGData['SGLaue'] in ['6/m', '6/mmm', '3m1', '31m', '3']:
        A = [parmDict[pfx + 'A0'] + parmDict[phfx + 'D11'], parmDict[pfx +
            'A0'] + parmDict[phfx + 'D11'], parmDict[pfx + 'A2'] + parmDict
            [phfx + 'D33'], parmDict[pfx + 'A0'] + parmDict[phfx + 'D11'], 0, 0
            ]
    elif SGData['SGLaue'] in ['3R', '3mR']:
        A = [parmDict[pfx + 'A0'] + parmDict[phfx + 'D11'], parmDict[pfx +
            'A0'] + parmDict[phfx + 'D11'], parmDict[pfx + 'A0'] + parmDict
            [phfx + 'D11'], parmDict[pfx + 'A3'] + parmDict[phfx + 'D23'],
            parmDict[pfx + 'A3'] + parmDict[phfx + 'D23'], parmDict[pfx +
            'A3'] + parmDict[phfx + 'D23']]
    elif SGData['SGLaue'] in ['m3m', 'm3']:
        A = [parmDict[pfx + 'A0'] + parmDict[phfx + 'D11'], parmDict[pfx +
            'A0'] + parmDict[phfx + 'D11'], parmDict[pfx + 'A0'] + parmDict
            [phfx + 'D11'], 0, 0, 0]
    return A


def getitem(obj, key=0, default=None):
    """Get first element of list or return default"""
    try:
        return obj[key]
    except:
        return default


def loadRadianceObj(savefile=None):
    """
    Load the pickled radiance object for further use
    Usage (once you're in the correct local directory)::

        demo = bifacial_radiance.loadRadianceObj(savefile)

    Parameters
    ----------
    savefile : str
        Optional savefile name. Otherwise default to `save.pickle`

    """
    import pickle
    if savefile is None:
        savefile = 'save.pickle'
    with open(savefile, 'rb') as f:
        loadObj = pickle.load(f)
    print('Loaded file {}'.format(savefile))
    return loadObj


def get_upload_to(instance, filename):
    """
    Obtain a valid upload path for an image file.

    This needs to be a module-level function so that it can be referenced within migrations,
    but simply delegates to the `get_upload_to` method of the instance, so that AbstractImage
    subclasses can override it.
    """
    return instance.get_upload_to(filename)


def with_leading_lower(example):
    """
    Changes the leading letter of the text of example `example` to uppercase.
    """
    text = example.text
    for i, c in enumerate(text):
        if not c.isspace():
            text = text[:i] + text[i].lower() + text[i + 1:]
            break
    example.text = text
    return example


def unlink():
    """Unlink active text data-block

    """
    pass


def attach_celery_info(report, context):
    """Attach celery info from the context to the oops report.

    TaskOopsReporter puts info about the celery failure in the
    oops context. This hook moves that information to the
    report, which is what is usually desired. If you want to do
    something different then use a different hook.
    """
    for key, value in context.items():
        if key.startswith('celery.'):
            report[key] = value


@classmethod
def get_or_create(cls, obj):
    """Deprecated in favor for the canonical `objects.get_or_create` method"""
    raise DeprecationWarning(
        'Please use `%s.objects.get_or_create()` instead' % cls)


def join_paths(*path_pieces):
    """Join parts of a url path"""
    cleaned_parts = map(str, filter(None, path_pieces))
    return '/'.join(cleaned_parts + [''])


def update_termination_protection(session, termination_protection,
    stack_name, ppt):
    """Update termination protection on a stack"""
    if termination_protection is None:
        return
    client = session.client('cloudformation')
    if termination_protection:
        ppt.secho('Enabling TerminationProtection')
    else:
        ppt.secho('Disabling TerminationProtection', fg='red')
    client.update_termination_protection(StackName=stack_name,
        EnableTerminationProtection=termination_protection)


def norm(x):
    """
    功能：将舵机参数归一化到[-1,1]
    输入:待归一化舞蹈动作矩阵。数据类型为numpy.array
    返回：归一化后的舞蹈动作矩阵
    """
    x = x / 180
    out = (x - 0.5) * 2
    return out.clip(-1, 1)


def sigmaLabel(ax, xlabel, ylabel, sigma=None):
    """Label the axes on a figure with some uncertainty."""
    confStr = '$\\pm{} \\sigma$'.format(sigma) if sigma is not None else ''
    ax.set_xlabel(xlabel + confStr)
    ax.set_ylabel(ylabel + confStr)
    return ax


def populate_text_field(driver, element_locator, text):
    """Populates text field with provided text

    Args:
        element_locator ((selenium.webdriver.common.by.By., str)): element locator described using `By`. Take a look at `Locate elements By <http://selenium-python.readthedocs.io/api.html#locate-elements-by>`_ for more info.
        text (str): text to populate text field with.

    Example:
        ::

            from selenium import webdriver
            from selenium.webdriver.common.by import By
            from selenium_extensions.core import populate_text_field

            driver = webdriver.Chrome()
            ...
            populate_text_field(driver, (By.CLASS_NAME, 'textbox'), 'some text')
    """
    input_element = driver.find_element(*element_locator)
    input_element.send_keys(text)


def add_axis_to_dic(dic, adic, n):
    """
    Add an axis dictionary (adic) to a NMRPipe dictionary (dic) as axis n.
    """
    fn = ['FDF2', 'FDF1', 'FDF3', 'FDF4'][n]
    dic[fn + 'SW'] = float(adic['sw'])
    dic[fn + 'OBS'] = float(adic['obs'])
    dic[fn + 'CAR'] = float(adic['car'] / adic['obs'])
    dic[fn + 'LABEL'] = adic['label']
    if adic['complex']:
        dic[fn + 'QUADFLAG'] = 0.0
    else:
        dic[fn + 'QUADFLAG'] = 1.0
    if adic['complex'] and n != 0:
        psize = adic['size'] / 2.0
    else:
        psize = adic['size'] / 1.0
    osize = psize
    if adic['time']:
        dic[fn + 'TDSIZE'] = psize
        dic[fn + 'FTFLAG'] = 0.0
    else:
        dic[fn + 'FTSIZE'] = psize
        dic[fn + 'FTFLAG'] = 1.0
    dic[fn + 'APOD'] = dic[fn + 'TDSIZE']
    if n == 0 or dic['FD2DPHASE'] != 1:
        dic[fn + 'CENTER'] = int(psize / 2.0) + 1.0
    else:
        dic[fn + 'CENTER'] = int(psize / 4.0) + 1
        osize = psize / 2.0
    dic[fn + 'ORIG'] = dic[fn + 'CAR'] * dic[fn + 'OBS'] - dic[fn + 'SW'] * (
        osize - dic[fn + 'CENTER']) / osize
    if n == 0:
        dic['FDSIZE'] = psize
        dic['FDREALSIZE'] = psize
    if n == 1:
        dic['FDSPECNUM'] = float(adic['size'])
        if adic['encoding'] == 'complex':
            dic['FDF1AQSIGN'] = 0
        if adic['encoding'] == 'states':
            dic['FDF1AQSIGN'] = 0
        elif adic['encoding'] == 'states-tppi':
            dic['FDF1AQSIGN'] = 16
    if n == 2:
        if adic['complex']:
            dic['FDF3SIZE'] = psize * 2
        else:
            dic['FDF3SIZE'] = psize
    if n == 3:
        if adic['complex']:
            dic['FDF4SIZE'] = psize * 2
        else:
            dic['FDF3SIZE'] = psize
    return dic


def stddev(x, d):
    """Return moving time-series standard deviation over the past d days."""
    return x.rolling(d).std()


def _get_win_folder_from_registry(csidl_name):
    """This is a fallback technique at best. I'm not sure if using the
    registry for this guarantees us the correct answer for all CSIDL_*
    names.
    """
    import winreg as _winreg
    shell_folder_name = {'CSIDL_APPDATA': 'AppData', 'CSIDL_COMMON_APPDATA':
        'Common AppData', 'CSIDL_LOCAL_APPDATA': 'Local AppData'}[csidl_name]
    key = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER,
        'Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders'
        )
    dir, type = _winreg.QueryValueEx(key, shell_folder_name)
    return dir


def add_mappers_to_cube_appobject_path():
    """Add "mappers" to `cube_appobject_path` class attribute of CubicWeb
    configuration classes.
    """
    import importlib
    import logging
    LOGGER = logging.getLogger('cubicweb-jsonschema')
    LOGGER.info('adding "mappers" to cube appobjects path')
    for confmod, configclsname in [('etwist.twconfig',
        'AllInOneConfiguration'), ('server.serverconfig',
        'ServerConfiguration'), ('pyramid.config',
        'CubicWebPyramidConfiguration'), ('devtools', 'ApptestConfiguration')]:
        modname = 'cubicweb.' + confmod
        try:
            mod = importlib.import_module(modname)
        except ImportError:
            LOGGER.warning(
                'failed to import %s, "mappers" appobjects will not loaded for this configuration'
                , modname)
            continue
        configcls = getattr(mod, configclsname)
        configcls.cube_appobject_path.add('mappers')


def PSD_fitting_eqn(A, OmegaTrap, Gamma, omega):
    """
    The value of the fitting equation:
    A / ((OmegaTrap**2 - omega**2)**2 + (omega * Gamma)**2)
    to be fit to the PSD

    Parameters
    ----------
    A : float
        Fitting constant A
        A = γ**2*Γ_0*(2*K_b*T_0)/(m)
        where:
            γ = conversionFactor
            Γ_0 = Damping factor due to environment
            π = pi
    OmegaTrap : float
        The trapping frequency in the axis of interest
        (in angular frequency)
    Gamma : float
        The damping factor Gamma = Γ = Γ_0 + δΓ
        where:
            Γ_0 = Damping factor due to environment
            δΓ = extra damping due to feedback or other effects
    omega : float
        The angular frequency to calculate the value of the
        fitting equation at

    Returns
    -------
    Value : float
        The value of the fitting equation
    """
    return A / ((OmegaTrap ** 2 - omega ** 2) ** 2 + omega ** 2 * Gamma ** 2)


def convertToMapPic(byteString, mapWidth):
    """convert a bytestring into a 2D row x column array, representing an existing map of fog-of-war, creep, etc."""
    data = []
    line = ''
    for idx, char in enumerate(byteString):
        line += str(ord(char))
        if (idx + 1) % mapWidth == 0:
            data.append(line)
            line = ''
    return data


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

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


def isoformat(dt):
    """Return iso-formatted timestamp

    Like .isoformat(), but uses Z for UTC instead of +00:00
    """
    return dt.isoformat().replace('+00:00', 'Z')


def load_json(path):
    """
    Load pipeline definition file in JSON format.

    :param Path path: Path to the JSON file.

    :return: A dictionary data structure with the pipeline definition.
    :rtype: dict
    """
    from ujson import loads
    return loads(path.read_text(encoding='utf-8'))


def npairs2n(npairs):
    """return number of conditions for npairs. see also scipy.special.binom."""
    return ((8.0 * npairs + 1) ** 0.5 - 1) / 2 + 1


@staticmethod
def _extract_data_columns_from_diff_row(_field_indexes, _diff_row):
    """Extracts columns specified in _field_indexes from _diff_list"""
    _result = []
    for _curr_field in _field_indexes:
        _result.append(_diff_row[_curr_field])
    return _result


def list_get(input_list, index):
    """Method to get an item from a list that handles out-of bounds errors.

    This method is intended to be used when we are picking items from
    a list and possibly we want a number of items which is larger than
    the number of items in the list. Here, we then just return the last
    element.

    Parameters
    ----------
    input_list : list
        The list to pick from
    index : integer
        The index to pick
    """
    try:
        return input_list[index]
    except IndexError:
        return input_list[-1]


@classmethod
def get_by_user_id(cls, user_id, token=None):
    """
        Creates Channel object by Slack user id (1:1 messages with bot)
        :param user_id: str
        :param token: str
        :return:
        """
    channel_id = cls.using(token)._fetch(method='im.open', return_resource=
        'channel', user=user_id)['id']
    return cls(channel_id)


def positive_real(var, var_name):
    """
    Check if parameter *var* is a positive number.

    :raises TypeError: Parameter *var* must be a real number.
    :raises ValueError: Parameter *var* must be a positive number.
    """
    if not isinstance(var, (int, float)):
        raise TypeError('\n\nParameter {} must be a real number.\n'.format(
            var_name))
    if var <= 0:
        raise ValueError('\n\nParameter {} must be a positive number.\n'.
            format(var_name))


def set_allowed_edit(group_ids):
    """
        Set the list of groups that are allowed to add content to the tile
        """


def inStr(inst, *args, **kwds):
    """DEPRECATED, use function L{instr}.
    """
    from pygeodesy.streprs import instr
    return instr(inst, *args, **kwds)


def unquote(s):
    """
    Undo the effects of quote(). Based heavily on urllib.unquote().
    """
    mychr = chr
    myatoi = int
    list = s.split('_')
    res = [list[0]]
    myappend = res.append
    del list[0]
    for item in list:
        if item[1:2]:
            try:
                myappend(mychr(myatoi(item[:2], 16)) + item[2:])
            except ValueError:
                myappend('_' + item)
        else:
            myappend('_' + item)
    return ''.join(res)


def o2d(obj):
    """
    把对象(支持单个对象、list、set)转换成字典
    :param obj: obj, list, set
    :return:
    """
    is_list = isinstance(obj, list)
    is_set = isinstance(obj, set)
    if is_list or is_set:
        obj_arr = []
        for o in obj:
            if o:
                dict1 = {}
                dict1.update(o.__dict__)
                obj_arr.append(dict1)
        return obj_arr
    else:
        dict1 = {}
        dict1.update(obj.__dict__)
        return dict1


def get_sig(tstart, tend, tlen, evalue):
    """Check if hmm match is significant, based on dbCAN described parameters"""
    perc_cov = (tend - tstart) / tlen
    if perc_cov >= 0.35 and evalue <= 1e-15:
        return True
    else:
        return False


def tree_path_parent():
    """Go to parent node tree

    """
    pass


def preprocess_git_version_tag(tag: str):
    """Remove a prefix from a version tag."""
    if tag.startswith('ver'):
        return tag[3:]
    if tag.startswith('v'):
        return tag[1:]
    if tag and tag[0] in ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9'):
        return tag
    raise ValueError(f'given tag "{tag}" does not appear to be a version tag')


def html_escape(string):
    """ Escape HTML special characters ``&<>`` and quotes ``'"``. """
    return string.replace('&', '&').replace('<', '<').replace('>',
        '>').replace('"', '"').replace("'", ''')


def psi_Ca_Na_Cl_PK74(T, P):
    """c-c'-a: calcium sodium chloride [PK74]."""
    psi = 0.0
    valid = T == 298.15
    return psi, valid


def _check_discrete_args(at, method):
    """
    Checks the arguments for margeff if the exogenous variables are discrete.
    """
    if method in ['dyex', 'eyex']:
        raise ValueError('%s not allowed for discrete variables' % method)
    if at in ['median', 'zero']:
        raise ValueError('%s not allowed for discrete variables' % at)


@staticmethod
def connect(port, peers):
    """Establish connection on worker side."""
    manager = peers.Connect(port)
    return manager


def bounds1D(full_width, step_size):
    """
    Return the bbox coordinates for a single dimension given
    the size of the chunked dimension and the size of each box
    """
    assert step_size > 0, 'invalid step_size: {}'.format(step_size)
    assert full_width > 0, 'invalid volume_width: {}'.format(full_width)
    start = 0
    end = step_size
    bounds = []
    while end < full_width:
        bounds.append(slice(start, end))
        start += step_size
        end += step_size
    bounds.append(slice(start, end))
    return bounds


@classmethod
def _stripe_object_to_default_tax_rates(cls, target_cls, data):
    """
        Retrieves TaxRates for a Subscription or Invoice
        :param target_cls:
        :param data:
        :param instance:
        :type instance: Union[djstripe.models.Invoice, djstripe.models.Subscription]
        :return:
        """
    tax_rates = []
    for tax_rate_data in data.get('default_tax_rates', []):
        tax_rate, _ = target_cls._get_or_create_from_stripe_object(
            tax_rate_data, refetch=False)
        tax_rates.append(tax_rate)
    return tax_rates


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

        :param PaperFolderTeamInviteType val:
        :rtype: EventType
        """
    return cls('paper_folder_team_invite', val)


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


@staticmethod
def get_friendly_name():
    """Gets the user friendly display name for this condition

        This typically reflects the text found in the Jenkins UI for the
        condition

        :rtype: :class:`str`
        """
    return 'always'


def string_to_float(string):
    """
    Convert a string with a comma (i.e. '3.14') to a float.

    :param str string: string representing a float
    :return numpy.float:
    """
    string_modif = string.replace(u',', u'.').replace(u'\xa0', u'')
    try:
        return float(string_modif)
    except ValueError:
        return float('nan')


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

        :param ShowcaseChangeEnabledPolicyType val:
        :rtype: EventType
        """
    return cls('showcase_change_enabled_policy', val)


@staticmethod
def label_gen(limit: int=None) ->str:
    """generates a sequential headers. if limit is set will return at that limit"""
    headers = list('ABCDEFGHIJKLMNOPQRSTUVWXYZ')
    counter = 0
    for n in range(0, 100):
        for i in range(len(headers)):
            rtn_str = f'{headers[i]}' if n == 0 else f'{headers[i]}{n}'
            if isinstance(limit, int) and counter >= limit:
                return rtn_str
            counter += 1
            yield rtn_str


def cmpDecoratorDisplayName(lhs, rhs):
    """Returns True if the decorators display names are the same"""
    if lhs.name != rhs.name:
        return False
    if lhs.arguments != rhs.arguments:
        return False
    return True


def hunkinrange(hunk, linerange):
    """Return True if `hunk` defined as (start, length) is in `linerange`
    defined as (lowerbound, upperbound).

    >>> hunkinrange((5, 10), (2, 7))
    True
    >>> hunkinrange((5, 10), (6, 12))
    True
    >>> hunkinrange((5, 10), (13, 17))
    True
    >>> hunkinrange((5, 10), (3, 17))
    True
    >>> hunkinrange((5, 10), (1, 3))
    False
    >>> hunkinrange((5, 10), (18, 20))
    False
    >>> hunkinrange((5, 10), (1, 5))
    False
    >>> hunkinrange((5, 10), (15, 27))
    False
    """
    start, length = hunk
    lowerbound, upperbound = linerange
    return lowerbound < start + length and start < upperbound


def s2b(input_check):
    """
    Return Boolean interpretation of string input.

    :param input_check: String to check if it means True or False.
    :type input_check: str
    """
    return str(input_check).lower() in ('yes', 'true', 't', '1', 'y')


def reconstructor(fn):
    """Decorate a method as the 'reconstructor' hook.

    Designates a method as the "reconstructor", an ``__init__``-like
    method that will be called by the ORM after the instance has been
    loaded from the database or otherwise reconstituted.

    The reconstructor will be invoked with no arguments.  Scalar
    (non-collection) database-mapped attributes of the instance will
    be available for use within the function.  Eagerly-loaded
    collections are generally not yet available and will usually only
    contain the first element.  ORM state changes made to objects at
    this stage will not be recorded for the next flush() operation, so
    the activity within a reconstructor should be conservative.

    .. seealso::

        :ref:`mapping_constructors`

        :meth:`.InstanceEvents.load`

    """
    fn.__sa_reconstructor__ = True
    return fn


@staticmethod
def prepare_arguments(previous_args=None, time_factor=1.0):
    """Build argument tuple, to be passed to low level function."""
    if previous_args is None:
        return 10000000,
    else:
        try:
            return int(previous_args[0] * time_factor),
        except OverflowError:
            return previous_args[0] * 10,


def icosahedron_nodes_calculator(order):
    """Calculate the number of nodes
    corresponding to the order of an icosahedron graph

    Args:
        order (int): order of an icosahedron graph

    Returns:
        int: number of nodes in icosahedron sampling for that order
    """
    nodes = 10 * 4 ** order + 2
    return nodes


@classmethod
def set_config(mcs, config_path):
    """Set config which should be used in within Config singleton.

        :param config_path: a path to configuration that should be used
        :type config_path: str
        """
    assert mcs._instance is None
    mcs._config = config_path


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

        :param WriteError val:
        :rtype: RelocationError
        """
    return cls('from_write', val)


@classmethod
def has_init(cls):
    """
        Return True if sound subsystem has been initialized.
        """
    return cls._has_init


def _(dump):
    """
    As part of the pickle protocol, a callable that will instantiate
    the class is needed.
    It's called _ just to make it short and hidden :-)
    """
    from intbitset import intbitset
    return intbitset(dump)


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 get_blueprint_docs(blueprints, blueprint):
    """Returns doc string for blueprint."""
    doc_string = blueprints[blueprint].__doc__
    return doc_string


def merge(ranges):
    """Merge a list of overlapping ranges.

    e.g. given [[0,20], [5,25], [30,50]]
    return [[0,25], [30,50]].
    """
    merged = []
    for higher in ranges:
        if not merged:
            merged.append(higher)
        else:
            lower = merged[-1]
            if higher[0] <= lower[1]:
                upper_bound = max(lower[1], higher[1])
                merged[-1] = lower[0], upper_bound
            else:
                merged.append(higher)
    return merged


def get_sec_groups_name_and_id(groups=None):
    """
    @type groups: list
    """
    ret = []
    for group in groups:
        ret.append('GroupName:{0}\nGroupId:{1}'.format(group.get(
            'GroupName', '-'), group.get('GroupId', '-')))
    return '\n'.join(ret).rstrip()


def area_join(min_x: int=-100, min_y: int=-100, max_x: int=-100, max_y: int
    =-100):
    """Join selected areas into new window

    :param min_x: X 1
    :type min_x: int
    :param min_y: Y 1
    :type min_y: int
    :param max_x: X 2
    :type max_x: int
    :param max_y: Y 2
    :type max_y: int
    """
    pass


def count_pending_decision_tasks(domain=None, taskList=None):
    """
    Returns the estimated number of decision tasks in the specified task list. The count returned is an approximation and is not guaranteed to be exact. If you specify a task list that no decision task was ever scheduled in then 0 will be returned.
    Access Control
    You can use IAM policies to control this action's access to Amazon SWF resources as follows:
    If the caller does not have sufficient permissions to invoke the action, or the parameter values fall outside the specified constraints, the action fails. The associated event attribute's cause parameter will be set to OPERATION_NOT_PERMITTED. For details and example IAM policies, see Using IAM to Manage Access to Amazon SWF Workflows .
    See also: AWS API Documentation

    :example: response = client.count_pending_decision_tasks(
        domain='string',
        taskList={
            'name': 'string'
        }
    )

    :type domain: string
    :param domain: [REQUIRED]
            The name of the domain that contains the task list.

    :type taskList: dict
    :param taskList: [REQUIRED]
            The name of the task list.
            name (string) -- [REQUIRED]The name of the task list.

    :rtype: dict
    :return: {
        'count': 123,
        'truncated': True|False
    }

    :returns:
    domain (string) -- [REQUIRED]
    The name of the domain that contains the task list.

    taskList (dict) -- [REQUIRED]
    The name of the task list.

    name (string) -- [REQUIRED]The name of the task list.

    """
    pass


def generate_look_up_table():
    """ Generate look up table.

    :return: List
    """
    poly = 40961
    table = []
    for index in range(256):
        data = index << 1
        crc = 0
        for _ in range(8, 0, -1):
            data >>= 1
            if (data ^ crc) & 1:
                crc = crc >> 1 ^ poly
            else:
                crc >>= 1
        table.append(crc)
    return table


def dedupe_cols(frame):
    """
    Need to dedupe columns that have the same name.
    """
    cols = list(frame.columns)
    for i, item in enumerate(frame.columns):
        if item in frame.columns[:i]:
            cols[i] = 'toDROP'
    frame.columns = cols
    return frame.drop('toDROP', 1, errors='ignore')


@classmethod
def size_bits(kls, values):
    """Return the number of bits this packet requires. """
    total = 0
    for name, typ in kls.Meta.field_types:
        if callable(typ.size_bits):
            total += typ.size_bits(values)
        else:
            total += typ.size_bits
    return total


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


def is_not_whitespace(bag):
    """filter: cells which do contain printable characters"""
    return bag.filter(lambda cell: str(cell.value).strip())


@classmethod
def from_dict(cls, client, soap_dict):
    """
        Alternative initialiser, builds entity object from a dictionary representation of
        a SOAP response created by the SOAP client.
        """
    return cls(client=client, company_name=soap_dict.get('CompanyName',
        None), street=soap_dict.get('Street', None), locality=soap_dict.get
        ('Locality', None), town_city=soap_dict.get('TownCity', None),
        county=soap_dict.get('County', None), postal_code=soap_dict.get(
        'PostalCode', None), country_code=soap_dict.get('CountryCode', None))


def qscore(y_true, y_pred):
    """Keras metric function for calculating scaled error.

    :param y_true: tensor of true class labels.
    :param y_pred: class output scores from network.

    :returns: class error expressed as a phred score.
    """
    from tensorflow.keras import backend as K
    error = K.cast(K.not_equal(K.max(y_true, axis=-1), K.cast(K.argmax(
        y_pred, axis=-1), K.floatx())), K.floatx())
    error = K.sum(error) / K.sum(K.ones_like(error))
    return -10.0 * 0.434294481 * K.log(error)


def history_cycle(reverse: bool=False):
    """Cycle through history

    :param reverse: Reverse, Reverse cycle history
    :type reverse: bool
    """
    pass


def get_calendar_dates_exceptions(vehicle_journey_element):
    """Parses calendar dates exception info from TransXChange VehicleJourney element"""
    j = vehicle_journey_element
    try:
        non_operative_days = (j.OperatingProfile.BankHolidayOperation.
            DaysOfNonOperation.get_elements())
        weekdays = []
        for elem in non_operative_days:
            weekdays.append(elem._name)
        if len(weekdays) == 1:
            return weekdays[0]
        else:
            return '|'.join(weekdays)
    except:
        return None


def silence_chips(controller, interactive):
    """Silence all chips in controller"""
    for chip_key in controller.chips:
        chip = controller.get_chip(chip_key)
        if interactive:
            print('Silencing chip %d' % chip.chip_id)
        chip.config.load('chip/quiet.json')
        controller.write_configuration(chip_key)
        if interactive:
            input('Just silenced chip %d. <enter> when ready.\n' % chip.chip_id
                )
    return


@classmethod
def reset_label(cls):
    """
        reset intenal counter
        """
    cls.last_label = 0


def convert_to_lower(dic):
    """
    把字典中地健值全部转换为小写字母
    :param dic:
    :return:
    """
    lower_dic = {}
    for k, v in dic.items():
        if isinstance(v, list):
            temp_v = []
            for i in v:
                temp_d = {}
                for k2, v2 in i.items():
                    temp_d[k2.lower()] = v2
                temp_v.append(temp_d)
            f_v = temp_v
        elif isinstance(v, dict):
            temp_v = {}
            for k2, v2 in v.items():
                temp_v[k2.lower()] = v2
            f_v = temp_v
        else:
            f_v = v
        lower_dic[k.lower()] = f_v
    return lower_dic


@classmethod
def generate_deviceid(cls, seed=None):
    """
        Generate an android device ID

        :param seed: Seed value to generate a consistent device ID
        :return:
        """
    return 'android-{0!s}'.format(cls.generate_uuid(True, seed)[:16])


def tuple_2elem(var, var_name):
    """
    Check if parameter *var* is a tuple with 2 elements.

    :raises TypeError: Parameter *var* must be a tuple.
    :raises ValueError: Parameter *var* must contain 2 elements.
    """
    if var is None:
        return
    if not isinstance(var, tuple):
        raise TypeError('\n\nParameter {} must be a tuple\n'.format(var_name))
    if len(var) != 2:
        raise ValueError(
            '\n\nParameter {} must be a list/tuple of length two.\n'.format
            (var_name))


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


@staticmethod
def _mean_axes(*args, **kwargs):
    """ Inhereted from Spectrum """
    raise NotImplementedError('Only applicable to Spectrum class.')


def writeAbundance(temp, model):
    """Molecular abundances."""
    temp.append('void abundance(double x, double y, double z,')
    temp.append(' double *abundance) {\n\n')
    if type(model.abund) is float:
        temp.append('\tabundance[0] = %.3e;\n' * model.abund)
    else:
        temp.append('\tabundance[0] = ')
        temp.append('findvalue(x, y, z, abund);\n' % model.abund)
    if model.depletion:
        temp.append('\tabundance[0] *= %.3e;\n' % model.depletion)
    temp.append('\tif (abundance[0] < 0.){\n\t\tabundance[0] = 0.;\n\t}\n')
    temp.append('\n}\n\n\n')
    return


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


@classmethod
def add_form(cls, label, form_options={}):
    """ Add an app_data form to the multi form after it's creation. """
    cls.app_form_opts[label] = form_options.copy()


@classmethod
def from_geopandas(cls, ga):
    """
        Build a spatialpandas RingArray from a geopandas GeometryArray or
        GeoSeries.

        Args:
            ga: A geopandas GeometryArray or GeoSeries of LinearRing shapes.

        Returns:
            RingArray
        """
    return super().from_geopandas(ga)


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

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


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

        :param TeamMemberInfo val:
        :rtype: MemberAddResult
        """
    return cls('success', val)


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


@staticmethod
def _fix_alert_config_dict(alert_config):
    """
        Fix the alert config .args() dict for the correct key name
        """
    data = alert_config.args()
    data['params_set'] = data.get('args')
    del data['args']
    return data


@staticmethod
def get_batch_axis(layout):
    """Get the dimension that corresponds to the batch size.

        When data parallelism is used, the data will be automatically split and
        concatenated along the batch-size dimension. Axis can be -1, which means
        the whole array will be copied for each data-parallelism device.

        Parameters
        ----------
        layout : str
            layout string. For example, "NCHW".

        Returns
        -------
        int
            An axis indicating the batch_size dimension.
        """
    if layout is None:
        return 0
    return layout.find('N')


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 smart_int(string, fallback=0):
    """Convert a string to int, with fallback for invalid strings or types."""
    try:
        return int(float(string))
    except (ValueError, TypeError):
        return fallback


@classmethod
def from_euclidean(cls, location_id, xpos, ypos, zpos=0, coor='EUC_2D'):
    """Creates a Location Object from a Euclidean position"""
    location = cls(location_id)
    location.set_coords(xpos, ypos, zpos, coor)
    return location


def get_shape(shape):
    """Return rows, columns for the shape."""
    try:
        return (shape[0], shape[1]) + shape[2:]
    except IndexError:
        return (shape[0], 0) + shape[2:]
    except TypeError:
        return int(shape), 0


def get_global_dependency_results(global_result_dict, bear_instance):
    """
    This method gets all the results originating from the dependencies of a
    bear_instance. Each bear_instance may or may not have dependencies.

    :param global_result_dict: The list of results out of which the dependency
                               results are picked.
    :return:                   None if bear has no dependencies, False if
                               dependencies are not met, the dependency dict
                               otherwise.
    """
    try:
        deps = bear_instance.BEAR_DEPS
        if not deps:
            return None
    except AttributeError:
        return None
    dependency_results = {}
    for dep in deps:
        depname = dep.__name__
        if depname not in global_result_dict:
            return False
        dependency_results[depname] = global_result_dict[depname]
    return dependency_results


def __estimate_dimension(pcm):
    """
    Estimates the intrinsic dimension of the given manifold.
    """
    raise NotImplementedError()


def __new__(cls):
    """Validate the Meta class."""
    cls._meta = getattr(cls, 'Meta', type('Meta', (), {}))
    if 'class_list' not in cls._meta.__dict__:
        raise AttributeError("'class_list' is a required Meta class property")
    if 'navitems' not in cls._meta.__dict__:
        raise AttributeError("'navitems' is a required Meta class property")
    return super().__new__(cls)


def model_query_scope_is_project(context, model):
    """Determine if a model should be scoped to a project.

    :param context: The context to check for admin and advsvc rights.
    :param model: The model to check the project_id of.
    :returns: True if the context is not admin and not advsvc and the model
        has a project_id. False otherwise.
    """
    return (not context.is_admin and hasattr(model, 'project_id')) and (not
        context.is_advsvc and hasattr(model, 'project_id'))


def local_exec(exec_instance_p, local_shell_cmds_p, exec_cmd_shortcut_p,
    d_vars_p, ret_stdout=False):
    """Helper function with EXEC CLASS"""
    template = local_shell_cmds_p[exec_cmd_shortcut_p]
    exec_instance_p.lexec(template % d_vars_p)
    if ret_stdout:
        return exec_instance_p.stdout[0]


def snap_cursor_to_selected():
    """Snap cursor to center of selected points

    """
    pass


def build_authorization_arg(authdict):
    """
  Create an "Authorization" header value from an authdict (created by generate_response()).
  """
    vallist = []
    for k in list(authdict.keys()):
        vallist += ['%s=%s' % (k, authdict[k])]
    return 'Digest ' + ', '.join(vallist)


@classmethod
def route(cls, *args, **kwargs):
    """
        Adds an HTTP route.
        """
    return cls.add_meta_deco({'type': 'http.add_route', 'args': args,
        'kwargs': kwargs})


def actions_python(filename='pythonapp.yml'):
    """
    Returns a Python Github Actions template.
    """
    with open(filename, 'w') as f:
        f.write(
            """name: Python App

on: [push]

jobs:
  build:

    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v1
    - name: Set up Python 3.7
      uses: actions/setup-python@v1
      with:
        python-version: 3.7
    - name: Install dependencies
      run: |
        python -m pip install --upgrade pip
        pip install -r requirements.txt
    - name: Lint with flake8
      run: |
        # stop the build if there are Python syntax errors or undefined names
        flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
        # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
        flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
    - name: Test with pytest
      run: |
        pytest -v --cov"""
            )


def is_disjoint(set1, set2, warn):
    """
    Checks if elements of set2 are in set1.

    :param set1: a set of values
    :param set2: a set of values
    :param warn: the error message that should be thrown
     when the sets are NOT disjoint
    :return: returns true no elements of set2 are in set1
    """
    for elem in set2:
        if elem in set1:
            raise ValueError(warn)
    return True


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

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

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

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

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

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


def show_diff(original, modified, prefix='', suffix='', prefix_unchanged=
    ' ', suffix_unchanged='', prefix_removed='-', suffix_removed='',
    prefix_added='+', suffix_added=''):
    """Return the diff view between original and modified strings.

    Function checks both arguments line by line and returns a string
    with a:
    - prefix_unchanged when line is common to both sequences
    - prefix_removed when line is unique to sequence 1
    - prefix_added when line is unique to sequence 2
    and a corresponding suffix in each line
    :param original: base string
    :param modified: changed string
    :param prefix: prefix of the output string
    :param suffix: suffix of the output string
    :param prefix_unchanged: prefix of the unchanged line
    :param suffix_unchanged: suffix of the unchanged line
    :param prefix_removed: prefix of the removed line
    :param suffix_removed: suffix of the removed line
    :param prefix_added: prefix of the added line
    :param suffix_added: suffix of the added line

    :return: string with the comparison of the records
    :rtype: string
    """
    import difflib
    differ = difflib.Differ()
    result = [prefix]
    for line in differ.compare(modified.splitlines(), original.splitlines()):
        if line[0] == ' ':
            result.append(prefix_unchanged + line[2:].strip() +
                suffix_unchanged)
        elif line[0] == '-':
            result.append(prefix_removed + line[2:].strip() + suffix_removed)
        elif line[0] == '+':
            result.append(prefix_added + line[2:].strip() + suffix_added)
    result.append(suffix)
    return '\n'.join(result)


def pytest_xdist_rsyncstart(source, gateways):
    """ called before rsyncing a directory to remote gateways takes place. """


@staticmethod
def add_opts(parser):
    """Populate and return the parser with the options for this plugin.

        If the plugin does not need any options, it should return the same
        parser untouched.
        """
    return parser


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

        :param AllowDownloadEnabledType val:
        :rtype: EventType
        """
    return cls('allow_download_enabled', val)


def gen_mlsag_assert(pk, xx, kLRki, mscout, index, dsRows):
    """
    Conditions check for gen_mlsag_ext.
    :param pk:
    :param xx:
    :param kLRki:
    :param mscout:
    :param index:
    :param dsRows:
    :return:
    """
    cols = len(pk)
    if cols <= 1:
        raise ValueError('Cols == 1')
    if index >= cols:
        raise ValueError('Index out of range')
    rows = len(pk[0])
    if rows == 0:
        raise ValueError('Empty pk')
    for i in range(cols):
        if len(pk[i]) != rows:
            raise ValueError('pk is not rectangular')
    if len(xx) != rows:
        raise ValueError('Bad xx size')
    if dsRows > rows:
        raise ValueError('Bad dsRows size')
    if (not kLRki or not mscout) and (kLRki or mscout):
        raise ValueError('Only one of kLRki/mscout is present')
    if kLRki and dsRows != 1:
        raise ValueError('Multisig requires exactly 1 dsRows')
    return rows, cols


def parse_subargs(t):
    """
    Parse sub arguments which formed like:

        '[ foo bar --baz 1 --qux ]'

    and returns like:

        ('foo', [bar], {baz: 1, qux: True})

    Parameters
    ----
    t : Target string of subargs

    Returns
    ----
    Tuple of (first-arg, args-array, kwargs-dict)
    """
    if t.startswith('[ ') and t.endswith(' ]'):
        args = iter(t.split()[1:-1])
        name = next(args)
        n_args = []
        kw_args = {}
        a = next(args, None)
        while a is not None:
            if a.startswith('--'):
                a = a.strip('^--')
                v = next(args, None)
                if v is None:
                    kw_args[a] = True
                    break
                else:
                    kw_args[a] = v
            else:
                n_args.append(a)
            a = next(args, None)
    else:
        return t, [], {}
    return name, n_args, kw_args


def objective_function(v):
    """function used for ObjectiveMechanism of lvoc
     v[0] = output of DDM: [probability of color naming, probability of word reading]
     v[1] = reward:        [color naming rewarded, word reading rewarded]
     """
    prob_upper = v[0]
    prob_lower = v[1]
    reward_upper = v[2][0]
    reward_lower = v[2][1]
    return prob_upper * reward_upper + prob_lower * reward_lower


def fields_to_vocabs(fields):
    """
    Extract Vocab Dictionary from Fields Dictionary.
       Args:
          fields: A dict mapping field names to Field objects
       Returns:
          vocab: A dict mapping field names to Vocabularies
    """
    vocabs = {}
    for name, field in fields.items():
        if field is not None and 'vocab' in field.__dict__:
            vocabs[name] = field.vocab
    return vocabs


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 get_bit(value: int, index: int) ->int:
    """
    Get the bit on index.

    Parameters
    ----------
    index : int
        The index of the bit to get
    value : int
        The value of the byte (represented by an int) from which to get the index bit

    Returns
    -------
    int
        The changed value (with the set bit)
    """
    return value & 1 << index != 0


def get_first_valid_entry(input_dict, key_list):
    """Iterates over key_list and returns the value of the first key that exists in the dictionary. Or returns None"""
    for key in key_list:
        if key in input_dict:
            return input_dict.get(key)
    return None


def _is_tabular(structure):
    """ Determines if a PDS4 structure can be shown as a table.

    Tabular structures are either:
        (1) Tables, or
        (2) Arrays

    Parameters
    ----------
    structure : Structure
        PDS4 structure to check.

    Returns
    -------
    bool
        True if *structure* can be displayed as a table, False otherwise.
    """
    return structure.is_table() or structure.is_array()


def connect(r=0.75):
    """ Connector (circle)

        Parameters
        ----------
        r: float
            Radius of connector circle
    """
    elem = {'name': 'CONNECT', 'extend': False, 'lblloc': 'center',
        'lblofst': 0, 'theta': -90}
    elem['anchors'] = {'W': [r, -r], 'E': [r, r], 'S': [2 * r, 0], 'N': [0, 0]}
    elem['move_cur'] = False
    elem['shapes'] = [{'shape': 'circle', 'center': [r, 0], 'radius': r}]
    return elem


def values():
    """The values of the pending event data, all of which are strings."""


def registerPreDelete(preDeleteFn):
    """ Register a callback that is called just before a node deletion.

        The function C{preDeletedFn} is added to a list of functions to be
        called just before deletion of a node. The callback C{preDeleteFn} is
        called with the C{nodeIdentifier} that is about to be deleted and
        should return a deferred that returns a list of deferreds that are to
        be fired after deletion. The backend collects the lists from all these
        callbacks before actually deleting the node in question.  After
        deletion all collected deferreds are fired to do post-processing.

        The idea is that you want to be able to collect data from the node
        before deleting it, for example to get a list of subscribers that have
        to be notified after the node has been deleted. To do this,
        C{preDeleteFn} fetches the subscriber list and passes this list to a
        callback attached to a deferred that it sets up. This deferred is
        returned in the list of deferreds.
        """


def on_store_opened(cursor, restart=False):
    """Create the temporary table for storing objects.

        This method may be None, meaning no store connection
        initialization is required.
        """


def create_widget_less(ext_name, path_destination):
    """
    Create the widget.less file
    :param ext_name: string
    :param path_destination: string
    :return: void
    """
    with open(path_destination + '/widget/' + ext_name + '/less/' +
        'widget.less', 'w') as outfile:
        outfile.write('/* Your CSS code */')


def check_field_exists(data, parameter):
    """Utility to check json field is present."""
    present = False
    if data and parameter:
        fields = parameter.split('.')
        curdata = data
        if fields:
            allfields = True
            for field in fields:
                if curdata:
                    if field in curdata and isinstance(curdata, dict):
                        curdata = curdata[field]
                    else:
                        allfields = False
            if allfields:
                present = True
    return present


def get_pull_requests_with_base_branch(repo, base_branch_name, head=None,
    state=None):
    """Returns a list of pull requests with the given base branch"""
    if head:
        head = repo.owner.login + ':' + head
    return list(repo.pull_requests(base=base_branch_name, head=head, state=
        state))


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

        :param str val:
        :rtype: GroupSelector
        """
    return cls('group_external_id', val)


@classmethod
def serialisable(cls, key, obj):
    """Determines what can be serialised and what shouldn't
        """
    if key.startswith('_Serialisable'.format(cls.__name__)):
        return False
    if key in obj.__whitelist:
        return True
    if '__' in key:
        return False
    if key in obj.__blacklist:
        return False
    if callable(getattr(obj, key)):
        return False
    if hasattr(obj.__class__, key):
        if isinstance(getattr(obj.__class__, key), property):
            return False
    return True


def load_site(finder, module):
    """the site module optionally loads the sitecustomize and usercustomize
       modules; ignore the error if these modules do not exist."""
    module.IgnoreName('sitecustomize')
    module.IgnoreName('usercustomize')


@classmethod
def from_stream(cls, stream_rdr, offset):
    """
        Return an |_IfdEntry| subclass instance containing the tag and value
        of the tag parsed from *stream_rdr* at *offset*. Note this method is
        common to all subclasses. Override the ``_parse_value()`` method to
        provide distinctive behavior based on field type.
        """
    tag_code = stream_rdr.read_short(offset, 0)
    value_count = stream_rdr.read_long(offset, 4)
    value_offset = stream_rdr.read_long(offset, 8)
    value = cls._parse_value(stream_rdr, offset, value_count, value_offset)
    return cls(tag_code, value)


def append_csv_data(file_strings):
    """ Append data from multiple csv files for the same time period

    Parameters
    -----------
    file_strings : array-like
        Lists or arrays of strings, where each string contains one file of data

    Returns
    -------
    out_string : string
        String with all data, ready for output to a file

    """
    out_lines = list()
    head_line = None
    for fstrings in file_strings:
        file_lines = fstrings.split('\n')
        head_line = file_lines.pop(0)
        out_lines.extend(file_lines)
    out_lines.sort()
    i = 0
    while len(out_lines[i]) == 0:
        out_lines.pop(i)
    out_lines.insert(0, head_line)
    out_lines.append('')
    out_string = '\n'.join(out_lines)
    return out_string


def remove_keys(_dict, keys):
    """Remove keys from a dictionary."""
    if not _dict:
        return None
    new = dict(_dict)
    for key in keys:
        new.pop(key, None)
    return new


def check_file_existence(file_name):
    """ check whether a file exists
    """
    try:
        file_h = open(file_name, 'r')
        file_h.close()
    except FileNotFoundError:
        raise


def add(isdsAppliance, address, netmask, network_type, ipFqdn, prefix='',
    interface='P.1', check_mode=False, force=False):
    """
    Adding an address to an interface
    """
    if check_mode is True:
        return isdsAppliance.create_return_object(changed=True)
    else:
        return isdsAppliance.invoke_post(
            'Creating a new address for an interface',
            '/application_interfaces/' + interface + '/addresses', {
            'address': address, 'netmask': netmask, 'type': network_type,
            'ipFqdn': ipFqdn})


def isparent(path1, path2):
    """Check if ``path1`` is a parent directory of ``path2``.

    Arguments:
        path1 (str): A PyFilesytem path.
        path2 (str): A PyFilesytem path.

    Returns:
        bool: `True` if ``path1`` is a parent directory of ``path2``

    Example:
        >>> isparent("foo/bar", "foo/bar/spam.txt")
        True
        >>> isparent("foo/bar/", "foo/bar")
        True
        >>> isparent("foo/barry", "foo/baz/bar")
        False
        >>> isparent("foo/bar/baz/", "foo/baz/bar")
        False

    """
    bits1 = path1.split('/')
    bits2 = path2.split('/')
    while bits1 and bits1[-1] == '':
        bits1.pop()
    if len(bits1) > len(bits2):
        return False
    for bit1, bit2 in zip(bits1, bits2):
        if bit1 != bit2:
            return False
    return True


@staticmethod
def get_dpi(value=1):
    """
        Returns current DPI used by DCC
        :param value: float
        :return: float
        """
    return 1.0


def StrFlatten(mylist):
    """Takes a list of strings, mylist, and makes one string from it. Returns
    the string.
    """
    if mylist == []:
        raise IndexError
    s = ''
    for x in mylist:
        s += '%s' % x
    return s


def print_result_header(xp_result):
    """Print header for XPath result(s)."""
    if isinstance(xp_result, list):
        list_result = xp_result
    else:
        list_result = [xp_result]
    xp_r_len = len(list_result)
    if xp_r_len == 0:
        print('no results.')
    elif xp_r_len == 1:
        if isinstance(list_result[0], tuple):
            print('1 XML namespace result')
        else:
            print('1 result.')
    elif isinstance(list_result[0], tuple):
        print('%d XML namespace results.' % xp_r_len)
    else:
        print('%d results.' % xp_r_len)


def _print_dri(marker, offset, info):
    """String output for a DRI segment."""
    m_bytes, fill, info = info
    ss = []
    ss.append('\n{:-^63}'.format(' {} marker at offset {}, length {} '.
        format(marker, offset, info['Lr'] + 2)))
    ss.append('Ri={}'.format(info['Ri']))
    return '\n'.join(ss)


@classmethod
def _get_sample_projection(cls):
    """Returns None. May be subclassed to return a projection that
        can be used when creating a subplot"""
    pass


def _check(isamAppliance, certificate, password):
    """
    TODO replace placeholder
    requires additionally pyOpenSSL to load the p12 and extract the issuer, subject, etc
    """
    return False


def class_maker(name, classname):
    """
    This will dynamically make a class object from a
    dynamically imported module. This is so a user
    can call the class whatever they want.
    """
    mod = __import__(name)
    comps = name.split('.')
    for comp in comps[1:]:
        mod = getattr(mod, comp)
    _class = getattr(mod, classname)
    return _class


@staticmethod
def any_i18n(*args):
    """ Return True if any argument appears to be an i18n string. """
    for a in args:
        if a is not None and not isinstance(a, str):
            return True
    return False


def parse_timeout(timeout):
    """Returns a tuple of timeout consist of connect timeout and
    read timeout.

    :param proxies: float or tuple
    :rtype: tuple
    """
    if isinstance(timeout, tuple):
        try:
            c, r = timeout
        except ValueError as e:
            err = (
                'Invalid timeout {0}. Pass a (connect, read) timeout tuple, or a single float to set both timeouts to the same value'
                .format(timeout))
            raise ValueError(err)
    else:
        c, r = timeout, timeout
    return c, r


def history(roomJID, messages):
    """
        Send history to create a MUC based on a one on one chat.

        See: http://xmpp.org/extensions/xep-0045.html#continue

        @param roomJID: The room jabber/xmpp entity id.
        @type roomJID: L{JID<twisted.words.protocols.jabber.jid.JID>}

        @param messages: The history to send to the room as an ordered list of
            message, represented by a dictionary with the keys C{'stanza'},
            holding the original stanza a
            L{Element<twisted.words.xish.domish.Element>}, and C{'timestamp'}
            with the timestamp.
        @type messages: C{list} of
            L{Element<twisted.words.xish.domish.Element>}
        """


def make_collection_name(git_repo, git_repo_dir, kitchen_name):
    """
    Generate the name of a mongodb collection from git and kitchen details.

    :param git_repo: Git repository name
    :param git_repo_dir: Git repository directory name
    :param kitchen_name: Kitchen name
    :return:
    """
    return '{}{}{}'.format(git_repo, git_repo_dir, kitchen_name)


def bitmask_set(bm, mn, f):
    """
     sets the flag f in mn as defined by the bitmask bm to True (or 1)
     throws KeyError if f is not defined

     :param bm: bitmask
     :param mn: magic number
     :param f: flag
    """
    return mn | bm[f]


@staticmethod
def _equalOrNone(mfi1, mfi2):
    """This is not a strict comparison between self and other but this is
        needed, especially for unit test in the case an empty filePath is equal
        to a MatrixFileInfo set to None.
        :warning: Direct inheritance from url.DataUrl.__str__ is not possible
        because enter in conflict with the url.DataUrl source code.
        """
    if mfi1 is not None and mfi2 is None:
        return mfi1.file_path() in (None, '')
    elif mfi2 is not None and mfi1 is None:
        return mfi2.file_path() in (None, '')
    else:
        return mfi1 == mfi2


def _generateSpecialOrthoOptsCentre(displayCtx, xax, yax, canvas):
    """Used by the generation functions for the ``xcentre``, ``ycentre``,
    and ``zcentre`` options.
    """
    x, y = canvas.getDisplayCentre()
    xlo = displayCtx.bounds.getLo(xax)
    ylo = displayCtx.bounds.getLo(yax)
    xlen = displayCtx.bounds.getLen(xax)
    ylen = displayCtx.bounds.getLen(yax)
    x = -1 + 2 * (x - xlo) / xlen
    y = -1 + 2 * (y - ylo) / ylen
    return ['{: 0.5f}'.format(x), '{: 0.5f}'.format(y)]


@staticmethod
def compare_results(save, best_hsp, tmp_results, tmp_gene_split,
    allowed_overlap):
    """
            Function for comparing hits and saving only the best hit
        """
    hit_id = best_hsp['hit_id']
    new_start_query = best_hsp['query_start']
    new_end_query = best_hsp['query_end']
    new_start_sbjct = int(best_hsp['sbjct_start'])
    new_end_sbjct = int(best_hsp['sbjct_end'])
    new_score = best_hsp['cal_score']
    new_db_hit = best_hsp['sbjct_header']
    new_contig = best_hsp['contig_name']
    new_HSP = best_hsp['HSP_length']
    keys = list(tmp_results.keys())
    for hit in keys:
        hit_data = tmp_results[hit]
        old_start_query = hit_data['query_start']
        old_end_query = hit_data['query_end']
        old_start_sbjct = int(hit_data['sbjct_start'])
        old_end_sbjct = int(hit_data['sbjct_end'])
        old_score = hit_data['cal_score']
        old_db_hit = hit_data['sbjct_header']
        old_contig = hit_data['contig_name']
        old_HSP = hit_data['HSP_length']
        remove_old = 0
        if new_db_hit == old_db_hit:
            if old_contig != new_contig:
                if (new_db_hit in tmp_gene_split and hit_id not in
                    tmp_gene_split[new_db_hit]):
                    tmp_gene_split[new_db_hit][hit_id] = 1
            elif new_start_sbjct < old_start_sbjct or new_end_sbjct > old_end_sbjct:
                tmp_gene_split[old_db_hit][hit_id] = 1
                if hit not in tmp_gene_split[old_db_hit]:
                    tmp_gene_split[old_db_hit][hit] = 1
        if new_contig == old_contig:
            print('Same contig: {} == {}'.format(new_contig, old_contig))
            print('\t{} vs {}'.format(new_db_hit, old_db_hit))
            hit_union_length = max(old_end_query, new_end_query) - min(
                old_start_query, new_start_query)
            hit_lengths_sum = old_end_query - old_start_query + (new_end_query
                 - new_start_query)
            overlap_len = hit_lengths_sum - hit_union_length
            if overlap_len < allowed_overlap:
                print('\tignore overlap ({}): {}'.format(overlap_len,
                    new_db_hit))
                continue
            print('\toverlap found ({}): {}'.format(overlap_len, new_db_hit))
            if (old_start_query == new_start_query and old_end_query ==
                new_end_query):
                if best_hsp['perc_ident'] > hit_data['perc_ident']:
                    remove_old = 1
                    if (new_db_hit in tmp_gene_split and hit_id not in
                        tmp_gene_split[new_db_hit]):
                        tmp_gene_split[new_db_hit][hit_id] = 1
                elif best_hsp['perc_ident'] == hit_data['perc_ident']:
                    if (new_db_hit in tmp_gene_split and hit_id not in
                        tmp_gene_split[new_db_hit]):
                        tmp_gene_split[new_db_hit][hit_id] = 1
                else:
                    save = 0
                    if (new_db_hit in tmp_gene_split and hit_id in
                        tmp_gene_split[new_db_hit]):
                        del tmp_gene_split[new_db_hit][hit_id]
                    break
            elif hit_union_length <= hit_lengths_sum:
                print('\t{} <= {}'.format(hit_union_length, hit_lengths_sum))
                print('\t\tScores: {} cmp {}'.format(new_score, old_score))
                if new_score > old_score:
                    remove_old = 1
                    if (new_db_hit in tmp_gene_split and hit_id not in
                        tmp_gene_split[new_db_hit]):
                        tmp_gene_split[new_db_hit][hit_id] = 1
                elif new_score == old_score:
                    if int(best_hsp['perc_coverage']) == int(hit_data[
                        'perc_coverage']) and new_HSP > old_HSP:
                        remove_old = 1
                    elif int(best_hsp['perc_coverage']) == int(hit_data[
                        'perc_coverage']) and old_HSP > new_HSP:
                        save = 0
                    elif int(best_hsp['perc_coverage']) == int(hit_data[
                        'perc_coverage']) and old_HSP == new_HSP:
                        pass
                    if (new_db_hit in tmp_gene_split and hit_id not in
                        tmp_gene_split[new_db_hit]):
                        tmp_gene_split[new_db_hit][hit_id] = 1
                else:
                    if (new_db_hit in tmp_gene_split and hit_id in
                        tmp_gene_split[new_db_hit]):
                        del tmp_gene_split[new_db_hit][hit_id]
                    save = 0
                    break
        if remove_old == 1:
            del tmp_results[hit]
            if old_db_hit in tmp_gene_split and hit in tmp_gene_split[
                old_db_hit]:
                del tmp_gene_split[old_db_hit][hit]
    return save, tmp_gene_split, tmp_results


def check_list_type(L, t):
    """Checks that every element in L is of type t."""
    for i, l in enumerate(L):
        if not isinstance(l, t):
            raise TypeError("type '{}' not found in list at index [{}]".
                format(t, i))
    return True


def get_monthly_sums(transactions_df):
    """Calculate the total charged for purchases each month."""
    months = transactions_df.transaction_date.dt.to_period('M')
    monthly_sums = transactions_df.groupby(months).sum()
    return monthly_sums


@staticmethod
def get_requirement(name, requires):
    """
        Yield matching requirement strings.

        The strings are presented in the format demanded by
        distutils.versionpredicate.VersionPredicate. Hopefully
        I'll be able to figure out a better way to handle this
        in the future. Perhaps figure out how pip does it's
        version satisfaction tests and see if it is offloadable?

        FYI there should only really be ONE matching requirement
        string, but I want to be able to process additional ones
        in case a certain package does something funky and splits
        up the requirements over multiple entries.
        """
    for require in requires:
        if name.lower() == require.project_name.lower() and require.specs:
            safe_name = require.project_name.replace('-', '_')
            yield '%s (%s)' % (safe_name, require.specifier)


def write_file(filename, content, mode='w'):
    """write_file will open a file, "filename" and write content, "content"
    and properly close the file
    """
    with open(filename, mode) as filey:
        filey.writelines(content)
    return filename


def group_membership_v1_timeout(group_state: 'GroupState'):
    """
    v1 host timer associated with group GroupState object has expired
    """
    group_state.group_state_logger.debug(
        'Querier CheckingMembership: group_membership_v1_timeout')
    return


def popattr(obj, attr, value=None):
    """Returns attribute `attr` from `obj` and delete it afterwards.
    If attribute does not exist, return `value`"""
    try:
        result = getattr(obj, attr)
    except AttributeError:
        return value
    else:
        delattr(obj, attr)
        return result


@classmethod
def just_after_fork(cls):
    """
        http://docs.sqlalchemy.org/en/latest/core/pooling.html        #using-connection-pools-with-multiprocessing
        """
    from joker.broker.interfaces.sequel import SQLInterface
    for rb in cls.cached_instances.values():
        for res in rb.resources.values():
            if isinstance(res, SQLInterface):
                res.just_after_fork()


def getWidget(id, check_visibility=True, check_permissions=True,
    check_condition=True, retJson=True):
    """ Return the specific widget's information.

        @param id
        id of the wanted widget

        @param check_visibility
        if True, return only action whose "visible" flag is set.

        @param check_permissions
        if True, return only action for whose permissions the current user is
        authorized.

        @param check_condition
        if True, return only action whose condition expression evaluates True.

        @param retJson
        format return value to json format or not( default True )

        @return
        a dict with the following format:
        {
            'success': True,
            'msg': 'Get widget success.',
            'id': '',
            'title': '',
            'description': '',
            'icon': ''
        }

        """


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 parse_int(val):
    """Parse int from str."""
    return int(float(val))


def fix_numbering(code, start):
    """Start is the lowest number from which we should remove 2"""
    for i, l in enumerate(code):
        if abs(l[0]) >= start:
            l[0] = l[0] / abs(l[0]) * (abs(l[0]) - 2)
        if abs(l[1]) >= start:
            l[1] = l[1] / abs(l[1]) * (abs(l[1]) - 2)
        code[i] = l
    return code


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


def register_cross_account_access_role(roleArn=None):
    """
    Registers the IAM role that Amazon Inspector uses to list your EC2 instances at the start of the assessment run or when you call the  PreviewAgents action.
    See also: AWS API Documentation

    Examples
    Registers the IAM role that Amazon Inspector uses to list your EC2 instances at the start of the assessment run or when you call the PreviewAgents action.
    Expected Output:

    :example: response = client.register_cross_account_access_role(
        roleArn='string'
    )

    :type roleArn: string
    :param roleArn: [REQUIRED]
            The ARN of the IAM role that Amazon Inspector uses to list your EC2 instances during the assessment run or when you call the PreviewAgents action.

    :return: response = client.register_cross_account_access_role(
        roleArn='arn:aws:iam::123456789012:role/inspector',
    )

    print(response)

    """
    pass


@classmethod
def name(cls):
    """Get the name of the plugin"""
    return cls.id


@classmethod
def from_http_response(cls, resp):
    """
        Build a ``Response`` from the provided ``HTTPResponse`` object.

        This function will call `.read()` to consume the body of the ``HTTPResponse`` object.

        :param resp: ``HTTPResponse`` object to build the ``Response`` from
        :type resp: ``HTTPResponse``
        :rtype: ``Response``
        :returns: A new ``Response``
        """
    return cls(status=resp.status, body=resp.read(), reason=getattr(resp,
        'reason', None), msg=getattr(resp, 'msg', None))


def get_in(obj, keys):
    """
    >>> get_in({'a': {'b': 1}}, 'a.b')
    1
    """
    if isinstance(keys, str):
        keys = keys.split('.')
    for key in keys:
        if not obj or key not in obj:
            return None
        obj = obj[key]
    return obj


def generate_urn(gallery_image):
    """
    This function takes an azure gallery image and outputs a corresponding URN
    :param gallery_image: a GalleryImageReference object
    :return: URN as string
    """
    reference_dict = gallery_image.as_dict()
    return ':'.join([reference_dict['publisher'], reference_dict['offer'],
        reference_dict['sku'], reference_dict['version']])


@classmethod
def _define_char(cls, prev: str, current: str) ->bool:
    """
        Helper method that'll tell us if a character has to be treated as a
        special one or it is part of the text that 's intended to be printed
        out.

        Takes the previous character and the current character, in case it is
        one of the special characters defined in the class and is prepended by
        a '' means that it has not to be treated as a special one

        Returns True if it's a special character
        """
    if current in cls.special_chars:
        if prev != '\\':
            return True
    return False


def listUndoableTransactionsFor(object, first_transaction=None,
    last_transaction=None, PrincipiaUndoBatchSize=None):
    """ List all transaction IDs the user is allowed to undo on 'object'.

        o Return a list of "transaction info" objects, using the given
          parameters to batch the results.

        o ???:  this needs documentation / testing.

        o Permission:  Undo changes
        """


def get_bucket_replication(Bucket=None):
    """
    Returns the replication configuration of a bucket.
    See also: AWS API Documentation

    :example: response = client.get_bucket_replication(
        Bucket='string'
    )

    :type Bucket: string
    :param Bucket: [REQUIRED]

    :rtype: dict
    :return: {
        'ReplicationConfiguration': {
            'Role': 'string',
            'Rules': [
                {
                    'ID': 'string',
                    'Prefix': 'string',
                    'Status': 'Enabled'|'Disabled',
                    'Destination': {
                        'Bucket': 'string',
                        'StorageClass': 'STANDARD'|'REDUCED_REDUNDANCY'|'STANDARD_IA'
                    }
                },
            ]
        }
    }

    """
    pass


def add_parser_arguments(parser):
    """ Add additional subcommands onto this command """
    return parser