def setup_random_number_swait(swait, **kw):
    """setup swait record to generate random numbers"""
    swait.reset()
    swait.scanning_rate.put('Passive')
    swait.description.put('uniform random numbers')
    swait.calculation.put('RNDM')
    swait.scanning_rate.put('.1 second')
    swait.read_attrs = ['calculated_value']
    swait.hints = {'fields': swait.read_attrs}


def cycle_sort(sequence):
    """ Sort a sequence in place and yield swaps.
		based on: https://rosettacode.org/wiki/Sorting_algorithms/Cycle_sort#Python
	"""
    for cycle_start, item in enumerate(sequence):
        pos = cycle_start
        for item2 in sequence[cycle_start + 1:]:
            if item2 < item:
                pos += 1
        if pos == cycle_start:
            continue
        while item == sequence[pos]:
            pos += 1
        sequence[pos], item = item, sequence[pos]
        yield cycle_start, pos
        while pos != cycle_start:
            pos = cycle_start
            for item2 in sequence[cycle_start + 1:]:
                if item2 < item:
                    pos += 1
            while item == sequence[pos]:
                pos += 1
            sequence[pos], item = item, sequence[pos]
            if pos != cycle_start:
                yield cycle_start, pos


def _split_tokens(tokens, token, value):
    """Split a list of tokens on the specified token pair (token, value),
    where *token* is the token type (i.e. its code) and *value* its actual
    value in the code.
    """
    res = [[]]
    for token_values in tokens:
        if (token, value) == token_values[:2]:
            res.append([])
            continue
        res[-1].append(token_values)
    return res


def fill_function_call(fn, requirements, activity, context):
    """Fill a function calls from values from the context to the variable.

    Args:
        fn (callable): the function to call.
        requirements (dict): the requirements. The key represent the variable
            name and the value represents where the value is in the context.
        activity (ActivityWorker): the current activity worker.
        context (dict): the current context.

    Return:
        dict: The arguments to call the method with.
    """
    function_arguments = fn.__code__.co_varnames[:fn.__code__.co_argcount]
    kwargs = dict()
    for argument in function_arguments:
        param = requirements.get(argument, None)
        value = None
        if argument == 'context':
            raise Exception(
                'Data used from the context should be explicit. A task should not randomly access information from the context.'
                )
        elif argument == 'activity':
            value = activity
        elif param:
            value = param.get_data(context)
        kwargs.update({argument: value})
    return kwargs


def filter_for_ascii(text, placeholder='_'):
    """Some unicode characters are used in the eCalendar, and some command line consoles don't like this, so this script replaces characters that give Exceptions
    placeholder is '_' by default """
    result = ''
    for letter in text:
        try:
            result += str(letter)
        except Exception:
            result += placeholder
    return result


def getObject():
    """Return the actual object that this aggregate holds the metadata
        for."""


def prettyTime(diffInSecs):
    """Returns a human-readable string from time-difference (in seconds).
    Uses absolute value of time-diff, and thus does not care about before/after.

    Args:
        diffInSecs (int): Timedifference in seconds.
    """
    intervals = [('minute', 60), ('hour', 60), ('day', 24), ('week', 7), (
        'month', 4.34811904762), ('year', 12)]
    unit, number = 'second', abs(diffInSecs)
    for new_unit, ratio in intervals:
        new_number = float(number) / ratio
        if new_number < 1:
            break
        unit, number = new_unit, new_number
    shown_num = int(number)
    return '{} {}'.format(shown_num, unit + ('' if shown_num == 1 else 's'))


def make_color_tuple(color):
    """
    turn something like "#000000" into 0,0,0
    or "#FFFFFF into "255,255,255"
    """
    R = color[1:3]
    G = color[3:5]
    B = color[5:7]
    R = int(R, 16)
    G = int(G, 16)
    B = int(B, 16)
    return R, G, B


def add_ago_to_since(since: str) ->str:
    """
    Backwards compatibility hack. Without this slices with since: 7 days will
    be treated as 7 days in the future.

    :param str since:
    :returns: Since with ago added if necessary
    :rtype: str
    """
    since_words = since.split(' ')
    grains = ['days', 'years', 'hours', 'day', 'year', 'weeks']
    if len(since_words) == 2 and since_words[1] in grains:
        since += ' ago'
    return since


def add_tags_to_resource(ResourceName=None, Tags=None):
    """
    Adds metadata tags to an Amazon RDS resource. These tags can also be used with cost allocation reporting to track cost associated with Amazon RDS resources, or used in a Condition statement in an IAM policy for Amazon RDS.
    For an overview on tagging Amazon RDS resources, see Tagging Amazon RDS Resources .
    See also: AWS API Documentation

    Examples
    This example adds a tag to an option group.
    Expected Output:

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

    :type ResourceName: string
    :param ResourceName: [REQUIRED]
            The Amazon RDS resource the tags will be added to. This value is an Amazon Resource Name (ARN). For information about creating an ARN, see Constructing an RDS Amazon Resource Name (ARN) .

    :type Tags: list
    :param Tags: [REQUIRED]
            The tags to be assigned to the Amazon RDS resource.
            (dict) --Metadata assigned to an Amazon RDS resource consisting of a key-value pair.
            Key (string) --A key is the required name of the tag. The string value can be from 1 to 128 Unicode characters in length and cannot be prefixed with 'aws:' or 'rds:'. The string can only contain only the set of Unicode letters, digits, white-space, '_', '.', '/', '=', '+', '-' (Java regex: '^([\\p{L}\\p{Z}\\p{N}_.:/=+\\-]*)$').
            Value (string) --A value is the optional value of the tag. The string value can be from 1 to 256 Unicode characters in length and cannot be prefixed with 'aws:' or 'rds:'. The string can only contain only the set of Unicode letters, digits, white-space, '_', '.', '/', '=', '+', '-' (Java regex: '^([\\p{L}\\p{Z}\\p{N}_.:/=+\\-]*)$').

    :return: response = client.add_tags_to_resource(
        ResourceName='arn:aws:rds:us-east-1:992648334831:og:mymysqloptiongroup',
        Tags=[
            {
                'Key': 'Staging',
                'Value': 'LocationDB',
            },
        ],
    )

    print(response)

    """
    pass


@staticmethod
def _extract_bdm(block_device_info):
    """Returns the block device mapping out of the block device info.

        The block device mapping is a list of instances of block device
        classes from nova.virt.block_device.  Each block device
        represents one volume connection.

        An example string representation of a DriverVolumeBlockDevice
        from the early Liberty time frame is:
        {'guest_format': None,
        'boot_index': 0,
        'mount_device': u'/dev/sda',
        'connection_info': {u'driver_volume_type': u'fibre_channel',
                            u'serial': u'e11765ea-dd14-4aa9-a953-4fd6b4999635',
                            u'data': {u'initiator_target_map':
                                        {u'21000024ff747e59':
                                            [u'500507680220E522',
                                            u'500507680210E522'],
                                        u'21000024ff747e58':
                                            [u'500507680220E522',
                                            u'500507680210E522']},
                                        u'vendor': u'IBM',
                                        u'target_discovered':False,
                                        u'target_UID': u'600507680282...',
                                        u'qos_specs': None,
                                        u'volume_id': u'e11765ea-...',
                                        u'target_lun': u'2',
                                        u'access_mode': u'rw',
                                        u'target_wwn': u'500507680220E522'}
                            },
        'disk_bus': None,
        'device_type': u'disk',
        'delete_on_termination': True}
        """
    if block_device_info is None:
        return []
    return block_device_info.get('block_device_mapping', [])


def merge_dicts(source_dicts, merge_dicts, join_key, merge_keys):
    """
    Insert specified fields from a merge dictionary to a source dictionary
    based on a matching key/val. Join field must exist in both source and
    merge dictionaries
    """
    merged = []
    for merge_dict in merge_dicts:
        for source_dict in source_dicts:
            try:
                if str(merge_dict[join_key]) == str(source_dict[join_key]):
                    for key in merge_dict:
                        if key in merge_keys:
                            source_dict[key] = merge_dict[key]
                    merged.append(source_dict)
                    continue
            except KeyError:
                continue
    return merged


def _format_duration_field(status_information):
    """Format the *duration* field.

    :param status_information: The various fields information
    :type status_information: :class:`collections.defaultdict`
    :returns: The updated status informations
    :rtype: :class:`collections.defaultdict`
    """
    try:
        duration = int(''.join(status_information['duration']))
        status_information['duration'] = '{0:02d}:{1:02d}'.format(duration //
            60, duration % 60)
    except ValueError:
        status_information.pop('duration', None)
    return status_information


@classmethod
def _as_mpl_axes(cls):
    """Support placement in figure using the `projection` keyword argument.

        See http://matplotlib.org/devel/add_new_projection.html.
        """
    return cls, {}


def to_marshallable_type(obj):
    """
    Helper for converting an object to a dictionary only if it is not
    dictionary already or an indexable object nor a simple type
    """
    if obj is None:
        return None
    if hasattr(obj, '__marshallable__'):
        return obj.__marshallable__()
    if hasattr(obj, '__getitem__'):
        return obj
    return dict(obj.__dict__)


def get_bmap(net, m, bmap):
    """
    Updates the B-map with the invisibles enabling marking m

    Parameters
    --------------
    net
        Petri net
    m
        Marking
    bmap
        B-map

    Returns
    --------------
    trans_list
        List of invisibles that enable m
    """
    if m not in bmap:
        bmap[m] = []
        for t in net.transitions:
            if t.label is None:
                if m <= t.out_marking:
                    bmap[m].append(t)
    return bmap[m]


def get_context_for_address(memory_handler, address):
    """
    Returns the haystack.reverse.context.HeapContext of the process
    for the HEAP that hosts this address
    """
    return memory_handler.get_reverse_context().get_context_for_address(address
        )


def lammps_pos_text_charged(structure, charges, species):
    """Create LAMMPS position text for a system of charged particles."""
    pos_text = '\n'
    for count, (pos, chrg, spec) in enumerate(zip(structure.positions,
        charges, species)):
        pos_text += '%i %i %f %f %f %f \n' % (count + 1, spec, chrg, pos[0],
            pos[1], pos[2])
    return pos_text


def disp_notfound():
    """ Display 'bad request -/- not found in red. """
    from x84.bbs import getterminal, echo
    term = getterminal()
    echo(u'\r\n\r\n{bad_req} {decorator} {not_found}'.format(bad_req=term.
        bold(u'bad request'), decorator=term.bold_red(u'-/-'), not_found=
        term.bold(u'not found.')))


def func_best_model(scan_object, metric='val_acc', asc=False):
    """Picks the best model based on a given metric and
    returns the index number for the model.

    NOTE: for loss 'asc' should be True"""
    import warnings as warnings
    warnings.simplefilter('ignore')
    from ..utils.best_model import best_model, activate_model
    model_no = best_model(scan_object, metric, asc)
    out = activate_model(scan_object, model_no)
    return out


def _filter_func_regressors_by_participants(participants, age_group):
    """ Filter functional and regressors based on participants
    """
    valid_age_groups = 'both', 'child', 'adult'
    if age_group not in valid_age_groups:
        raise ValueError(
            'Wrong value for age_group={0}. Valid arguments are: {1}'.
            format(age_group, valid_age_groups))
    child_adult = participants['Child_Adult'].tolist()
    if age_group != 'adult':
        child_count = child_adult.count('child')
    else:
        child_count = 0
    if age_group != 'child':
        adult_count = child_adult.count('adult')
    else:
        adult_count = 0
    return adult_count, child_count


def _getDecoratorsName(node):
    """
    Return a list with names of decorators attached to this node.

    @param node: current node of pylint
    """
    decorators = []
    if not node.decorators:
        return decorators
    for decorator in node.decorators.nodes:
        decorators.append(decorator.as_string())
    return decorators


def last_arg_byref(args):
    """Return the last C argument's value by reference."""
    return args[-1]._obj.value


@classmethod
def normalise(cls, query_comparator):
    """Get a normalised form of the representation of a query.

        :return: None, a matcher or something suitable for AnyMapping.
        """
    if query_comparator is None:
        return None
    if isinstance(query_comparator, str):
        return cls._from_query_string(query_comparator)
    return query_comparator


def get_lt(hdr):
    """Obtain the LTV and LTM keyword values.

    Note that this returns the values just as read from the header,
    which means in particular that the LTV values are for one-indexed
    pixel coordinates.

    LTM keywords are the diagonal elements of MWCS linear
    transformation matrix, while LTV's are MWCS linear transformation
    vector (1-indexed).

    .. note:: Translated from ``calacs/lib/getlt.c``.

    Parameters
    ----------
    hdr : obj
        Extension header.

    Returns
    -------
    ltm, ltv : tuple of float
        ``(LTM1_1, LTM2_2)`` and ``(LTV1, LTV2)``.
        Values are ``(1, 1)`` and ``(0, 0)`` if not found,
        to accomodate reference files with missing info.

    Raises
    ------
    ValueError
        Invalid LTM* values.

    """
    ltm = hdr.get('LTM1_1', 1.0), hdr.get('LTM2_2', 1.0)
    if ltm[0] <= 0 or ltm[1] <= 0:
        raise ValueError(f'(LTM1_1, LTM2_2) = {ltm} is invalid')
    ltv = hdr.get('LTV1', 0.0), hdr.get('LTV2', 0.0)
    return ltm, ltv


def apply(obj, **data):
    """ Called when applying changes to an object
        """


def process_file(path, processor, encoding='utf-8', mode='rt', *args, **kwargs
    ):
    """ Process a text file's content. If the file name ends with .gz, read it as gzip file """
    if mode not in ('rU', 'rt', 'rb', 'r'):
        raise Exception('Invalid file reading mode')
    with open(path, *args, encoding=encoding, mode=mode, **kwargs) as infile:
        return processor(infile)


def label(code):
    """ Return a (filename, first_lineno, func_name) tuple for a given code
    object.
    """
    if isinstance(code, str):
        return '~', 0, code
    elif isinstance(code, tuple):
        return code
    else:
        return code.co_filename, code.co_firstlineno, code.co_name


@staticmethod
def single_channel():
    """Check if algorithm run on single channel"""
    return True


@classmethod
def RegisterDecrypters(cls, decrypters):
    """Registers decrypters.

    The decrypters are identified based on their lower case encryption method.

    Args:
      decrypters (list[type]): decrypter classes.

    Raises:
      KeyError: if decrypters is already set for the corresponding
          encryption method.
    """
    for decrypter in decrypters:
        cls.RegisterDecrypter(decrypter)


def default_notification_widget():
    """
    Content of notification widget.

    Arguments:
    None

    Return:
    Content items as list
    """
    items = [['Bot token', '', str, '', 'PLAIN', '', 'Telegram Bot token.'],
        ['Default names telegram',
        'name1:telegram_name1;name2:telegram_name2', str, '', 'PLAIN', '',
        'Default names for the Notification area.'], ['SMTP server', '',
        str, '', 'PLAIN', '', 'SMTP Mail server'], ['E-Mail adress', '',
        str, '', 'PLAIN', '', 'E-Mail address used to send e-mails'], [
        'Default names email', 'name1:telegram_name1;name2:telegram_name2',
        str, '', 'PLAIN', '', 'Default names for the Notification area.'],
        ['Number of users', '3', int, '', 'PLAIN', '',
        'Number of freely choosable users in addition to the default users.']]
    return items


def ndo_double(data, n):
    """mimic of gmx_fio_ndo_double in gromacs"""
    return [data.unpack_double() for i in range(n)]


@classmethod
def register_namespace(cls, shorthand: str, namespace: str) ->None:
    """
        Register shorthand for a namespace.

        :param shorthand: The shorthand, e.g. 'xsd'
        :param namespace The namespace, e.g. 'http://www.w3.org/2001/XMLSchema#'
        """
    cls._namespaces[shorthand] = namespace


def dbh_html(path, contenttype, extension, roottag, nsurl):
    """ Generic Web Page Handler - Returns html_generic for Web Pages """
    if extension.lower() == 'html' or extension.lower() == 'htm':
        return 'db_webpage_viewer'
    else:
        return False


def mul_or_none(a, b):
    """Return the element wise multiplicative of the inputs.
    If either input is None, we return None.

    Parameters
    ----------
    a
        A tensor input.
    b
        Another tensor input with the same type as a.

    Returns
    -------
    None if either input is None. Otherwise returns a * b.
    """
    if a is None or b is None:
        return None
    return a * b


def sphericalPolar_2_cartesian(positionVectorSphericalPolar):
    """Convert spherical-polar coordinates (in radians), into Cartesian coordinates.

The origin of the Cartesian frame of reference is located at the centre of the sphere, the positive half of x-axis goes through 0 deg E, 0 deg N, the positive half of y-axis goes through 90 deg E, 0 deg N and the positive half of the z-axis goes through the North Pole equivalent."""
    import numpy as np
    [radius, theta, phi] = positionVectorSphericalPolar
    x = radius * np.sin(theta) * np.cos(phi)
    y = radius * np.sin(theta) * np.sin(phi)
    z = radius * np.cos(theta)
    return [x, y, z]


def dbh_specimen(path, contenttype, extension, roottag, nsurl):
    """ Generic XML Handler - Returns xml_generic for all XML files """
    if extension == 'sdb':
        return 'db_specimen'
    else:
        return False


def nearest(items, pivot):
    """Find nearest value in array, including datetimes

    Args
    ----
    items: iterable
        List of values from which to find nearest value to `pivot`
    pivot: int or float
        Value to find nearest of in `items`

    Returns
    -------
    nearest: int or float
        Value in items nearest to `pivot`
    """
    return min(items, key=lambda x: abs(x - pivot))


@classmethod
def make_separator(cls, value):
    """Create a separator token"""
    assert value in (',', ';')
    subtype = cls.ARG if value == ',' else cls.ROW
    return cls(value, cls.SEP, subtype)


def l4_invoke(expr):
    """
    Use datahub http server to instantiate and manipulate process.

    :return: A proxy object to a DatasetL4 object acquired via the the http server
    """
    raise Exception


@classmethod
def extra_table_metadata(cls, database, table_name, schema_name):
    """Returns engine-specific table metadata"""
    return {}


def histogram(values, mode=0, bin_function=None):
    """Return a list of (value, count) pairs, summarizing the input values.
    Sorted by increasing value, or if mode=1, by decreasing count.
    If bin_function is given, map it over values first."""
    if bin_function:
        values = map(bin_function, values)
    bins = {}
    for val in values:
        bins[val] = bins.get(val, 0) + 1
    if mode:
        return sorted(list(bins.items()), key=lambda x: (x[1], x[0]),
            reverse=True)
    else:
        return sorted(bins.items())


def resource_isdir(resource_name):
    """Is the named resource a directory?  (like ``os.path.isdir()``)"""


def get_milliseconds(t):
    """
    格式化时长字符串为毫秒（00:00:25.173 -> 毫秒数）

    :param t: 时长h:m:s或h:m:s.ms或m:s.ms格式字符串
    :returns: 毫秒数
    """
    millisecond = 0
    t = t.split('.')
    if len(t) > 1 and t[1].isdigit():
        millisecond += int(t[1])
    s = t[0].split(':')
    if len(s) == 3:
        millisecond += int(s[0]) * 60 * 60 * 1000
        millisecond += int(s[1]) * 60 * 1000
        millisecond += int(s[2]) * 1000
    elif len(s) == 2:
        millisecond += int(s[0]) * 60 * 1000
        millisecond += int(s[1]) * 1000
    return millisecond


def fixed_for_sql(text):
    """makes essential fixes for use in sql"""
    return str(text).replace('\\', '\\\\').replace("'", "\\'")


def translate(bbox, x_offset=0, y_offset=0):
    """Translate bounding boxes by offsets.

    Parameters
    ----------
    bbox : numpy.ndarray
        Numpy.ndarray with shape (N, 4+) where N is the number of bounding boxes.
        The second axis represents attributes of the bounding box.
        Specifically, these are :math:`(x_{min}, y_{min}, x_{max}, y_{max})`,
        we allow additional attributes other than coordinates, which stay intact
        during bounding box transformations.
    x_offset : int or float
        Offset along x axis.
    y_offset : int or float
        Offset along y axis.

    Returns
    -------
    numpy.ndarray
        Translated bounding boxes with original shape.
    """
    bbox = bbox.copy()
    bbox[:, :2] += x_offset, y_offset
    bbox[:, 2:4] += x_offset, y_offset
    return bbox


def intdivceil(x, y):
    """
    Returns the exact value of ceil(x // y).
    No floating point calculations are used.
    Requires positive integer types. The result
    is undefined if at least one of the inputs
    is floating point.
    """
    result = x // y
    if x % y:
        result += 1
    return result


def s_to_min(value):
    """Convert seconds to minutes."""
    return '{}:{:02d}'.format(int(value // 60), int(value % 60))


def swap_bytes(word_val):
    """swap lsb and msb of a word"""
    msb = word_val >> 8 & 255
    lsb = word_val & 255
    return (lsb << 8) + msb


def elemwise_add(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.

    Example
    -------

    >>> x = mx.nd.array([1, 2, 3, 4])
    >>> y = mx.nd.array([1.1, 2.1, 3.1, 4.1])
    >>> mx.nd.elemwise_add(x, y).asnumpy()
    array([ 2.0999999 ,  4.0999999 ,  6.0999999 ,  8.10000038], dtype=float32)
    """
    return 0,


def no_log_warn(logical_line):
    """Disallow 'LOG.warn('

    https://bugs.launchpad.net/tempest/+bug/1508442

    C301
    """
    if logical_line.startswith('LOG.warn('):
        yield 0, 'C301 Use LOG.warning() rather than LOG.warn()'


@staticmethod
def phase(true_phase, phase_shift):
    """
        correction in phase

        :param true_phase: Union[numpy.array, float];
        :param phase_shift: numpy.float;
        :return: Union[numpy.array, float];
        """
    return true_phase - phase_shift


def _get_object(lst, _id):
    """
    Internal function to grab data referenced inside response['included']
    """
    for item in lst:
        if item['id'] == _id:
            return item


def clear_orientations(link):
    """
    Resets the orientations on the crossings of a link to default values
    """
    link.link_components = None
    for i in link.crossings:
        i.sign = 0
        i.directions.clear()


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

        :param PasswordChangeType val:
        :rtype: EventType
        """
    return cls('password_change', val)


@classmethod
def list(cls, context, limit=None, marker=None, sort_key=None, sort_dir=None):
    """Return a list of Chassis objects.

        :param cls: the :class:`Chassis`
        :param context: Security context.
        :param limit: maximum number of resources to return in a single result.
        :param marker: pagination marker for large data sets.
        :param sort_key: column to sort results by.
        :param sort_dir: direction to sort. "asc" or "desc".
        :returns: a list of :class:`Chassis` object.

        """
    db_chassis = cls.dbapi.get_chassis_list(limit=limit, marker=marker,
        sort_key=sort_key, sort_dir=sort_dir)
    return cls._from_db_object_list(context, db_chassis)


def rename_col(tbl):
    """Convert column names as per snakelowercase standards"""
    tbl.columns = tbl.columns.str.strip().str.lower()
    pairs = [(' ', '_'), ('_x', '_'), ('_y', '_'), ('.', '_'), (',', '_'),
        ('/', '_'), ('(', '_'), (')', '')]
    for a, b in pairs:
        tbl.columns = tbl.columns.str.replace(a, b)
    return tbl.columns


def _intern_atom(conn, name):
    """Get an atom for a string.

    :param xcffib.Connection: XCB connection
    :param str name: string to look up
    :returns: atom
    :rtype: int
    """
    return conn.core.InternAtom(False, len(name), name).reply().atom


@staticmethod
def points_earned(status):
    """Return dictionary of values for winning/losing a round."""
    points = {'w': 2, 'n': 0, 'p': -1}
    return points[status]


def Identity(x):
    """Returns the object given to it"""
    return x


def _filter_select_columns(col_filter, cols, meta):
    """
    Checks ?_c=col&_c=-col for filter(). Takes values of ?_c= as col_filter and
    data column names as cols. Returns 2 lists: show_cols as columns to show.
    ignored_cols has column names not in the list, i.e. the ?_c= parameters that
    are ignored.
    """
    selected_cols, excluded_cols, ignored_cols = [], set(), []
    for col in col_filter:
        if col in cols:
            selected_cols.append(col)
        elif col.startswith('-') and col[1:] in cols:
            excluded_cols.add(col[1:])
        else:
            ignored_cols.append(col)
    if len(excluded_cols) > 0 and len(selected_cols) == 0:
        selected_cols = cols
    show_cols = [col for col in selected_cols if col not in excluded_cols]
    meta['excluded'] = list(excluded_cols)
    return show_cols, ignored_cols


def _traverse_parent(node, objtypes):
    """
    Traverse up the node's parents until you hit the ``objtypes`` referenced.

    Can either be a single type,
    or a tuple of types.
    """
    curr_node = node.parent
    while curr_node is not None:
        if isinstance(curr_node, objtypes):
            return curr_node
        curr_node = curr_node.parent
    return None


def b2s(b):
    """
    Binary to string.
    """
    ret = []
    for pos in range(0, len(b), 8):
        ret.append(chr(int(b[pos:pos + 8], 2)))
    return ''.join(ret)


@staticmethod
def _remove_line_ending(line: bytes):
    """
        To not have to deal with line endings in the data we can use this to
        remove them.
        """
    if line.endswith(b'\r\n'):
        return line[:-2]
    else:
        return line


def keying_set_export(filepath: str='', filter_folder: bool=True,
    filter_text: bool=True, filter_python: bool=True):
    """Export Keying Set to a python script

    :param filepath: filepath
    :type filepath: str
    :param filter_folder: Filter folders
    :type filter_folder: bool
    :param filter_text: Filter text
    :type filter_text: bool
    :param filter_python: Filter python
    :type filter_python: bool
    """
    pass


def ENUM(iterable, start=0, increment=1):
    """Enumerate an iterable without all the fuss!"""
    n = start
    for i in iterable:
        tmp = n
        n += increment
        yield tmp, i


def skeletonize(packages, output_dir='.'):
    """This is the main work function that coordinates retrieval of the foreign recipe and outputs
    the conda recipe skeleton.

    Arguments here should match the arguments for the parser below."""
    print(packages)
    print(output_dir)


@classmethod
def from_array(cls, array, threshold, **kwargs):
    """
        Construct a DistanceBand weights from an array. Supports all the same options
        as :class:`libpysal.weights.DistanceBand`

        """
    return cls(array, threshold, **kwargs)


@classmethod
def connect(cls, node, part, path, headers, watchdog, conn_timeout,
    node_timeout, write_timeout, send_exception_handler, logger=None,
    chunked=False, **kwargs):
    """
        Connect to a backend node and send the headers.

        :returns: Putter instance

        :raises ConnectionTimeout: if initial connection timed out
        :raises ResponseTimeout: if header retrieval timed out
        :raises InsufficientStorage: on 507 response from node
        :raises PutterConnectError: on non-507 server error response from node
        """
    conn, expect_resp, final_resp, connect_duration = cls._make_connection(node
        , part, path, headers, conn_timeout, node_timeout)
    return cls(conn, node, final_resp, path, connect_duration, watchdog,
        write_timeout, send_exception_handler, logger, chunked=chunked)


def keysplit(strng):
    """Split an activity key joined into a single string using the magic sequence `⊡|⊡`"""
    return tuple(strng.split('⊡|⊡'))


def preview_html():
    """html meant for preview of the newsletter in browser.
        """


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 roi2rect(roi, inverse=False):
    """Convert ROI to rectangle coordinates or vice versa.

    :param list roi: list containing ROI corner coords ``[x0 , y0, x1, y1]``
        (input can also be tuple)
    :param bool inverse:  if True, input param ``roi`` is assumed to be of
        format ``[x0, y0, w, h]`` and will be converted into ROI
    :return:
        - tuple, (x0, y0, w, h) if param ``inverse == False``
        - tuple, (x0, y0, x1, y1) if param ``inverse == True``

    """
    x0, y0, x1, y1 = roi
    if not inverse:
        return x0, y0, x1 - x0, y1 - y0
    return x0, y0, x0 + x1, y0 + y1


def coroutine_annotation(f):
    """In docs, annotate a function that returns a Future with 'coroutine'.

    Unlike @motor_coroutine, this doesn't affect behavior.
    """
    f.coroutine_annotation = True
    return f


def psi_K_HSO4_SO4_HMW84(T, P):
    """c-a-a': potassium bisulfate sulfate [HMW84]."""
    psi = -0.0677
    valid = T == 298.15
    return psi, valid


@staticmethod
def _collect_mdsec_elements(files):
    """
        Return all dmdSec and amdSec classes associated with the files.

        Returns all dmdSecs, then all amdSecs, so they only need to be
        serialized before being appended to the METS document.

        :param List files: List of :class:`FSEntry` to collect MDSecs for.
        :returns: List of AMDSecs and SubSections
        """
    dmdsecs = []
    amdsecs = []
    for f in files:
        for d in f.dmdsecs:
            dmdsecs.append(d)
        for a in f.amdsecs:
            amdsecs.append(a)
    dmdsecs.sort(key=lambda x: x.id_string)
    amdsecs.sort(key=lambda x: x.id_string)
    return dmdsecs + amdsecs


@staticmethod
def bitSizeOf(bitPosition, value):
    """
        Returns length of Zserio object type stored in the bit stream in bits.

        :param bitPosition: Current bit position in bit stream.
        :param value: Zserio object type value.
        :returns: Length of given Zserio object type in bits.
        """
    return value.bitSizeOf(bitPosition)


def value(_, val, *args):
    """Calculate fill value in VALUE mode."""
    return val


def low_pass_filter(freq, f3dB, alpha=0):
    """
    Produces the relative PSD of a signal that, to a factor (1-alpha²), is
    filtered by a 1st-order low-pass filter.

    This, in particular, describes the filtering of a quadrant photo-diode:
    Only a fraction of the photons that reach the diode is absorped in the
    depletion region, the other fraction get's absorped outside that region.
    The electron-hole pairs need to diffuse to the depletion region until
    they produce a photo-current. This process causes an effective low-pass
    filter for these photons. The in the power spectrum the function looks
    like this:

     F(f) = alpha² + (1 - alpha²) / (1 + (f / f3dB)**2)

    Arguments
    ---------
    freq : array(float)
        Frequency vector.
    f3dB : float
        Cut-off frequency of the low-pass filter.
    alpha : float
        Filter efficiency. Only a fraction (0 <= alpha <= 1) of the signal that
        is not low pass filtered. Thus, alpha = 1, will produce no low-pass
        filter at all, whereas alpha = 0, will produce a 1st-order low-pass
        filter.

    References
    ----------
    Equ. (35) in:
        Berg-Sørensen, K., & Flyvbjerg, H. (2004)
        Power spectrum analysis for optical tweezers. Review of Scientific
        Instruments, 75(3), 594–612.
        http://doi.org/10.1063/1.1645654
    Equ. (20) in:
        Berg-So̸rensen, K., et al. (2006)
        Power spectrum analysis for optical tweezers. II: Laser wavelength
        dependence of parasitic filtering, and how to achieve high bandwidth.
        Review of Scientific Instruments, 77(6), 063106.
        http://doi.org/10.1063/1.2204589
    """
    return alpha ** 2 + (1 - alpha ** 2) / (1 + (freq / f3dB) ** 2)


def get_support_value(supports):
    """ Returns the total support value """
    support_value = 0
    for support in supports:
        if support[0] == 'pin':
            support_value += 1
        elif support[0] == 'fixed':
            support_value += 3
        elif support[0] == 'roller':
            support_value += 7
    return support_value


def get(isamAppliance, check_mode=False, force=False):
    """
    Retrieving a list of all server connections
    """
    return isamAppliance.invoke_get(
        'Retrieving a list of all server connections',
        '/mga/server_connections/v1')


def _buildaddot(ad, drop_nodes=None):
    """Constructs a dotfile of a topology described by an advertisement rspec.  Only works on very basic GENIv3 advertisements,
  and probably has lots of broken edge cases."""
    if not drop_nodes:
        drop_nodes = []
    dot_data = []
    dda = dot_data.append
    dda('graph {')
    for node in ad.nodes:
        if node.name in drop_nodes:
            continue
        if node.available:
            dda('"%s"' % node.name)
        else:
            dda('"%s" [style=dashed]' % node.name)
    for link in ad.links:
        if not len(link.interface_refs) == 2:
            print('Link with more than 2 interfaces:')
            print(link.text)
        name_1 = link.interface_refs[0].split(':')[-2].split('+')[-1]
        name_2 = link.interface_refs[1].split(':')[-2].split('+')[-1]
        if name_1 in drop_nodes or name_2 in drop_nodes:
            continue
        dda('"%s" -- "%s"' % (name_1, name_2))
    dda('}')
    return '\n'.join(dot_data)


@classmethod
def reload(cls):
    """Reload the data from the file(s) on disk"""
    if cls.file_path is None:
        raise AssertionError(
            'You must load the config once with a valid filename before forcing a reload'
            )
    cls._data = None
    return cls(cls.file_path)


def collide_rect(left, right):
    """collision detection between two sprites, using rects.

    pygame.sprite.collide_rect(left, right): return bool

    Tests for collision between two sprites. Uses the pygame.Rect colliderect
    function to calculate the collision. It is intended to be passed as a
    collided callback function to the *collide functions. Sprites must have
    "rect" attributes.

    New in pygame 1.8.0

    """
    return left.rect.colliderect(right.rect)


def _ccx_v_chain_uncompute(qc, control_qubits, ancillary_qubits):
    """
    Second half (uncompute) of the multi-control basic mode. It progressively compute the
    ccx of the control qubits and put the final result in the last ancillary
    qubit
    Args:
        qc (QuantumCircuit): the Quantum Circuit
        control_qubits (list): the list of control qubits
        ancillary_qubits (list): the list of ancillary qubits
    """
    anci_idx = len(ancillary_qubits) - 1
    for idx in range(2, len(control_qubits))[::-1]:
        qc.ccx(control_qubits[idx], ancillary_qubits[anci_idx - 1],
            ancillary_qubits[anci_idx])
        anci_idx -= 1
    qc.ccx(control_qubits[0], control_qubits[1], ancillary_qubits[anci_idx])


def _is_random_variable(x):
    """
    Check if the matrix x correspond to a random variable.

    The matrix is considered a random variable if it is a vector
    or a matrix corresponding to a column vector. Otherwise,
    the matrix correspond to a random vector.
    """
    return len(x.shape) == 1 or x.shape[1] == 1


def compile_bc_Livneh2013_locations(maptable):
    """
    Compile a list of file URLs for bias corrected Livneh et al. 2013 (CIG)

    maptable: (dataframe) a dataframe that contains the FID, LAT, LONG_, and ELEV for each interpolated data file
    """
    locations = []
    for ind, row in maptable.iterrows():
        basename = '_'.join(['data', str(row['LAT']), str(row['LONG_'])])
        url = [
            'http://cses.washington.edu/rocinante/Livneh/bcLivneh_WWA_2013/forcings_ascii/'
            , basename]
        locations.append(''.join(url))
    return locations


def generateColumnName(variable, visit, instance):
    """Generate a column name for the given variable, visit and instance.

    :arg variable: Integer variable ID
    :arg visit:    Visit number
    :arg instance: Instance number
    """
    return '{}-{}.{}'.format(variable, visit, instance)


def _next_regular(target):
    """
    Find the next regular number greater than or equal to target.
    Regular numbers are composites of the prime factors 2, 3, and 5.
    Also known as 5-smooth numbers or Hamming numbers, these are the optimal
    size for inputs to FFTPACK.

    Target must be a positive integer.
    """
    if target <= 6:
        return target
    if not target & target - 1:
        return target
    match = float('inf')
    p5 = 1
    while p5 < target:
        p35 = p5
        while p35 < target:
            quotient = -(-target // p35)
            try:
                p2 = 2 ** (quotient - 1).bit_length()
            except AttributeError:
                p2 = 2 ** (len(bin(quotient - 1)) - 2)
            N = p2 * p35
            if N == target:
                return N
            elif N < match:
                match = N
            p35 *= 3
            if p35 == target:
                return p35
        if p35 < match:
            match = p35
        p5 *= 5
        if p5 == target:
            return p5
    if p5 < match:
        match = p5
    return match


def relative_script(lines):
    """Return a script that'll work in a relocatable environment."""
    activate = (
        "import os; activate_this=os.path.join(os.path.dirname(os.path.realpath(__file__)), 'activate_this.py'); exec(compile(open(activate_this).read(), activate_this, 'exec'), dict(__file__=activate_this)); del os, activate_this"
        )
    activate_at = None
    for idx, line in reversed(list(enumerate(lines))):
        if line.split()[:3] == ['from', '__future__', 'import']:
            activate_at = idx + 1
            break
    if activate_at is None:
        activate_at = 1
    return lines[:activate_at] + ['', activate, ''] + lines[activate_at:]


def clean_str(source_str, replace='?'):
    """Ensure :ref:`ASCII` characters, and replace any non ascii

    :param source_str: The source str to clean
    :type source_str: str
    :param replace: The character(s) to replace non ascii characters with
    :type replace: str
    :return: a `tuple` containing

             - The ascii string
             - `True` if a non ascii character was encounteres, otherwise `False`
    """
    illegal = False
    try:
        sss = source_str.decode('ascii')
        return sss, illegal
    except UnicodeDecodeError:
        safeS = ''
        illegal = True
        for cIdx in range(0, len(source_str)):
            singleS = source_str[cIdx]
            if ord(singleS) < 128:
                safeS += singleS
            else:
                safeS += replace
    return safeS, illegal


def readJsonFile(fname):
    """Reads data from file using the JSON format.

   :param fname: file name
   :type fname: string
   :returns: data
   :rtype: dict/list

   :Example:

   >>> from westpy import *
   >>> data = readJsonFile("mass.json")

   .. note:: The file will be read from the current directory.
   """
    import json
    with open(fname, 'r') as file:
        data = json.load(file)
        print('')
        print('File read : ', fname)
    return data


def _get_key(redis_key: str) ->str:
    """ Trying to create a namespace for django_query_profiler keys.  We could have used redis key-space as well """
    redis_key_prefix = 'django_query_profiler_'
    return f'{redis_key_prefix}:{redis_key}'


def structure_torrent_data(target_dict, hash_str, data):
    """Updated target dict with torrent data structured suitably
    for config storage.

    :param target_dict: dict - dictionary to update
    :param hash_str: str - torrent identifying hash
    :param data: dict - torrent data received from RPC (see parse_torrent())
    :return:
    """
    data = dict(data)
    if 'hash' not in data:
        data['hash'] = hash_str
    if 'name' not in data:
        data['name'] = None
    if 'url' not in data:
        data['url'] = None
    target_dict[hash_str] = {'hash': data['hash'], 'name': data['name'],
        'url': data['url']}


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 is_special(ip_address):
    """Determine if the address is SPECIAL
       Note: This is super bad, improve it
    """
    special = {'224.0.0.251': 'multicast_dns', 'ff02::fb': 'multicast_dns'}
    return special[ip_address] if ip_address in special else False


@staticmethod
def _patch_for_ios_system(orig_file, patch_file):
    """ iOS doesn't have system() and the POSIX module uses hard-coded
        configurations rather than the normal configure by introspection
        process.
        """
    for line in orig_file:
        minimal = line.strip().replace(' ', '')
        if minimal != '#defineHAVE_SYSTEM1':
            patch_file.write(line)


@staticmethod
def p_if_data_memory_layout_optional(p):
    """if_data_memory_layout_optional : dp_blob dp_data
                                          | ba_blob pa_data"""


def GetCurrentDateCode(*args, **kwargs):
    """ Stub Anduin function."""
    print('GetCurrentDateCode', args, kwargs)


@classmethod
def get_metadata(cls):
    """Spider classes should override this method to return
        a dict represention of a JSON document which describes the
        spider.

        See the sample spiders for a broad variety of metadata
        examples.
        """
    fmt = "%s must implememt class method 'get_metadata()'"
    raise NotImplementedError(fmt % cls)


def calculate_heartbeats(shb, chb):
    """
    Given a heartbeat string from the server, and a heartbeat tuple from the client,
    calculate what the actual heartbeat settings should be.

    :param shb: server heartbeat numbers
    :param chb: client heartbeat numbers
    """
    sx, sy = shb
    cx, cy = chb
    x = 0
    y = 0
    if cx != 0 and sy != '0':
        x = max(cx, int(sy))
    if cy != 0 and sx != '0':
        y = max(cy, int(sx))
    return x, y


def get_rsa_from_jwks(jwks, jwt_kid):
    """
    Searches the JWKS for the signing key used
    for the JWT. Returns a dict of the JWK
    properties if found, None otherwise.
    :param jwks: The set of JWKs from Auth0
    :param jwt_kid: The key ID of the signing key
    :return: dict
    """
    for key in jwks['keys']:
        if key['kid'] == jwt_kid:
            rsa_key = {'kty': key['kty'], 'kid': key['kid'], 'use': key[
                'use'], 'n': key['n'], 'e': key['e']}
            return rsa_key
    return None


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

        :param SfAllowNonMembersToViewSharedLinksDetails val:
        :rtype: EventDetails
        """
    return cls('sf_allow_non_members_to_view_shared_links_details', val)


def register_data_obj(do):
    """
    save a new piece of data into the persistent cache
    :param do:
    :return:
    """
    from . import _x as x
    c = x.data_cache
    if do.generator_name not in c:
        c[do.generator_name] = {}
    if do.generator_hash not in c[do.generator_name]:
        c[do.generator_name][do.generator_hash] = {}
    if do.param_hash not in c[do.generator_name][do.generator_hash]:
        c[do.generator_name][do.generator_hash][do.param_hash] = {}
    if do.name not in c[do.generator_name][do.generator_hash][do.param_hash]:
        c[do.generator_name][do.generator_hash][do.param_hash][do.name] = do
    elif c[do.generator_name][do.generator_hash][do.param_hash][do.name] != do:
        if x.verbosity > 1:
            x.log('updating data in cache')
        c[do.generator_name][do.generator_hash][do.param_hash][do.name] = do
    x.data_cache = c


def seed():
    """
    Apply a seed to the python random module to reproduce my results
    """
    import random
    random.seed(1992)


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

    The ".dev0" means dirty.

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


def autodec(fwhm):
    """
    Automatically calculates the appropriate decimal place to track based on a full-width-at-half-maximum

    :param fwhm: full-width-at-half-maximum
    :return: decimal power
    :rtype: int
    """
    shift = fwhm
    n = 0
    while shift < 1.0:
        n += 1
        shift = fwhm * 10 ** n
    return n + 1


def default_csv_filename(filename='aws_s3_export.csv'):
    """
    Return the given filename or set up a default one.
        :param filename='aws_s3_export.csv': String - given filename
    """
    return filename


def read_parm_old(parmfn):
    """
    Read .parm which comes along with .seis file
    Return parm defining the grid mesh
    """
    print('Reading', parmfn)
    f = open(parmfn, 'r')
    for line in f:
        line = line.strip()
        columns = line.split()
        if columns[0] == 'NTRACE':
            ntrace = int(columns[1])
        if columns[0] == 'NPANEL':
            npanel = int(columns[1])
        if columns[0] == 'NSAMPLE':
            nsample = int(columns[1])
        if columns[0] == 'TRACE_START':
            ox = float(columns[1])
        if columns[0] == 'PANEL_START':
            oy = float(columns[1])
        if columns[0] == 'SAMPLE_START':
            oz = float(columns[1])
        if columns[0] == 'SAMPLE_INC':
            dz = float(columns[1])
        if columns[0] == 'DX':
            TRDX = float(columns[1])
            TRDY = float(columns[2])
        if columns[0] == 'DY':
            PNDX = float(columns[1])
            PNDY = float(columns[2])
    f.close()
    return ntrace, npanel, nsample, ox, oy, oz, dz, TRDX, TRDY, PNDX, PNDY


@classmethod
def from_vge(cls, vge_type_name):
    """Create a DataType from a vge header data type string"""
    for name, data_type in cls.types.items():
        if data_type.vge_type == vge_type_name:
            return cls(template_name=name, byte_order_msb=True)
    raise ValueError('Unknown type: ' + vge_type_name)


def cohort_membership_model():
    """
    Return the course_groups.models.CohortMembership model.
    """
    from course_groups.models import CohortMembership
    return CohortMembership


@staticmethod
def _real_key(key):
    """Strip the leading '_' if `key` is string'"""
    return key[1:] if isinstance(key, str) and key[0] is '_' else key


def copy_attributes_between_objects(from_object, to_object, attributes=[],
    defaults=dict(), not_found_value=None):
    """Copy attributes from one object to another

    Looks up `attributes` in `from_obj` and copies them to `to_object`.  If
    not present in `from_object` the corresponding attribute in `to_object`
    will be set to `defaults` or `not_found_value` if not in `defaults`.

    Parameters
    ----------
    from_object : object or module
        Object to copy attributes from.
    to_object : object or module
        Object to copy attributes to.
    attributes : list of strings
        A list of attribute names to copy from `from_object` to `object_to`.
    defaults : dict of string-value pairs
        Dictionary specifying the default value of each attribute that is not
        found in `from_object`.
    not_found_value : optional
        Default value to set attribute to if not found in `from_object` or in
        `defaults`.  Default not_found_value=None.

    Returns
    -------
    None

    """
    for v in attributes:
        to_object.__setattr__(v, from_object.__dict__.get(v, defaults.get(v,
            not_found_value)))
    return


def check_status(resp, statuses):
    """
    Raise Exception when response code is not one of statuses.
    This function is not required once https://github.com/twisted/treq/issues/62 is fixed
    """
    if resp.code not in statuses:
        raise Exception('unexpected resp code: {}'.format(resp.code))
    return resp


def make_crash(report):
    """Return JSON-serializable crash details."""
    try:
        crash = report.longrepr.reprcrash
    except AttributeError:
        return {}
    return {'crash': {'path': crash.path, 'lineno': crash.lineno, 'message':
        crash.message}}


@classmethod
def is_type(cls, file):
    """returns True if the given file object describes this format

        takes a seekable file pointer rewound to the start of the file"""
    return file.read(4) == 'MAC '


def delete_volume(DryRun=None, VolumeId=None):
    """
    Deletes the specified EBS volume. The volume must be in the available state (not attached to an instance).
    For more information, see Deleting an Amazon EBS Volume in the Amazon Elastic Compute Cloud User Guide .
    See also: AWS API Documentation

    Examples
    This example deletes an available volume with the volume ID of vol-049df61146c4d7901. If the command succeeds, no output is returned.
    Expected Output:

    :example: response = client.delete_volume(
        DryRun=True|False,
        VolumeId='string'
    )

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

    :type VolumeId: string
    :param VolumeId: [REQUIRED]
            The ID of the volume.

    :return: response = client.delete_volume(
        VolumeId='vol-049df61146c4d7901',
    )

    print(response)

    """
    pass


def add_base64_padding(b):
    """Add padding to base64 encoded bytes.

    Padding can be removed when sending the messages.

    @param b bytes to be padded.
    @return a padded bytes.
    """
    return b + b'=' * (-len(b) % 4)


def equals_or_in(item, collection):
    """
    Return true if the item is the collection, or is in the collection.
    Guard against possible TypeError exceptions (ie, testing if `int` is
    in `str` can raise this).
    """
    if item == collection:
        return True
    if hasattr(collection, '__contains__'):
        try:
            if item in collection:
                return True
        except TypeError:
            pass
    return False


def get_mounts(ns):
    """
    Return all instances of LMI_MountedFileSystem.

    :rtype: list of LMI_MountedFileSystem
    """
    return ns.LMI_MountedFileSystem.instances()


@classmethod
def get_route(klass, id=None):
    """
        Returns the route to the object for id if specified

        """
    if id is not None:
        return '{}{}/{}{}'.format(klass.quanta.site_route, klass.BASE_ROUTE,
            id, klass.ROUTE_SUFFIX)
    else:
        return '{}{}{}'.format(klass.quanta.site_route, klass.BASE_ROUTE,
            klass.ROUTE_SUFFIX)


def _assert_type(data, key, tpe, default=None):
    """Extract and verify if a key in a dictionary has a given type."""
    value = data.get(key, default)
    if not isinstance(value, tpe):
        raise ValueError(
            f'Config error: {key}: expected {tpe}, found {type(value)}')
    return value


def parser_add_options(parser, options):
    """Adds the options to the sucommand parser

    """
    for option, properties in sorted(options.items(), key=lambda x: x[0]):
        parser.add_argument(option, **properties)


def get_extra_element_count(curr_count, opt_count, extra_allowed_cnt):
    """Evaluate and return extra same element count based on given values.

    :key-term:
    group:  In here group can be any base where elements are place
            i.e. replication-group while placing replicas (elements)
            or  brokers while placing partitions (elements).
    element:  Generic term for units which are optimally placed over group.

    :params:
    curr_count: Given count
    opt_count:  Optimal count for each group.
    extra_allowed_cnt:  Count of groups which can have 1 extra element
                   _    on each group.
    """
    if curr_count > opt_count:
        if extra_allowed_cnt > 0:
            extra_allowed_cnt -= 1
            extra_cnt = curr_count - opt_count - 1
        else:
            extra_cnt = curr_count - opt_count
    else:
        extra_cnt = 0
    return extra_cnt, extra_allowed_cnt


def index_which(ol, value, which):
    """
        from elist.elist import *
        ol = [1,'a',3,'a',4,'a',5]
        index_which(ol,'a',0)
        index_which(ol,'a',1)
        index_which(ol,'a',2)
        index_which(ol,'a',3) == None
    """
    length = ol.__len__()
    seq = -1
    for i in range(0, length):
        if value == ol[i]:
            seq = seq + 1
            if seq == which:
                return i
            else:
                pass
        else:
            pass
    return None


def box_fit_2d(points):
    """Returns an angle that best fits the points to an axis aligned rectangle.

	Parameters:
	points (list) – list of 2d points.

	Returns: angle

	Return type: float"""
    return 1.0


@classmethod
def get_annotated_list(cls, parent=None, max_depth=None):
    """
        Gets an annotated list from a tree branch.

        :param parent:

            The node whose descendants will be annotated. The node itself
            will be included in the list. If not given, the entire tree
            will be annotated.

        :param max_depth:

            Optionally limit to specified depth
        """
    result, info = [], {}
    start_depth, prev_depth = None, None
    qs = cls.get_tree(parent)
    if max_depth:
        qs = qs.filter(depth__lte=max_depth)
    return cls.get_annotated_list_qs(qs)


def get_row_section(df, start_value=None, end_value=None):
    """Return a section of rows from a df, based on the start and/or end value to be found in the first column."""
    if start_value:
        first_row_index = df.loc[df.iloc[:, (0)] == start_value].index[0]
    else:
        first_row_index = 0
    if end_value:
        last_row_index = df.loc[df.iloc[:, (0)] == end_value].index[0]
    else:
        last_row_index = len(df.index)
    section = df.iloc[first_row_index:last_row_index + 1, :]
    return section


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 is_good_quartet_OLD(path, BMG):
    """Determine whether an induced P4 is a good quartet in the BMG."""
    if BMG.has_edge(path[0], path[2]) and BMG.has_edge(path[3], path[1]
        ) and BMG.nodes[path[0]]['color'] == BMG.nodes[path[3]]['color']:
        return True
    else:
        return False


def default(f):
    """Decorator to tell Skal that the method/function is the default.

    """
    raise NotImplementedError


@classmethod
def string_contains_colors(cls, colored_string):
    """Checks to see if a string contains colors."""
    return len(cls.ANSI_REG.findall(colored_string)) > 0


def add_string_to_exception(value, string):
    """Add string to the exception parameter."""
    assert type(value.args) == tuple
    nb_args = len(value.args)
    if string:
        if nb_args:
            value.args = tuple([value.args[0] + string] + list(value.args[1:]))
            assert len(value.args) == nb_args
        else:
            value.args = string,
        if hasattr(value, 'msg'):
            value.msg += string


def _set_text(fig, text, hh, **kwargs):
    """Auxiliar function to print text in an image"""
    fig.text(0.05, 1 - hh, text, verticalalignment='bottom',
        horizontalalignment='left', transform=fig.transFigure, fontsize=15,
        **kwargs)


def parse_commit_range(repo, committishs):
    """Parse a string referring to a range of commits.

    :param repo: A `Repo` object
    :param committishs: A string referring to a range of commits.
    :return: An iterator over `Commit` objects
    :raise KeyError: When the reference commits can not be found
    :raise ValueError: If the range can not be parsed
    """
    return iter([repo[committishs]])


def vertex_group_remove_from():
    """Remove the selected vertices from active or all vertex group(s)

    """
    pass


@classmethod
def _check_template_missing_keys(cls, dictionary):
    """Checks if the loaded template is complete.

        Parameters
        ----------
        dictionary : dict
            Template's dictionary to be evaluated

        Returns
        -------
        missing_keys : list[str]
            List of missing keys
        """
    necessary_keys = ['OPEN_HTML', 'OPEN_GENERAL', 'OPEN_GENERAL_UL',
        'GENERAL_LI', 'CLOSE_GENERAL_UL', 'CLOSE_GENERAL', 'OPEN_ITEMS',
        'OPEN_ITEMS_UL', 'ITEMS_LI', 'CLOSE_ITEMS_UL', 'CLOSE_ITEMS',
        'OPEN_HEROES', 'OPEN_HEROES_UL', 'HEROES_LI', 'CLOSE_HEROES_UL',
        'CLOSE_HEROES', 'CLOSE_HTML']
    missing_keys = []
    for item in necessary_keys:
        if item not in dictionary.keys():
            missing_keys.append(item)
    return missing_keys


def freestyle_module_add():
    """Add a style module into the list of modules

    """
    pass


def get_uid(instance):
    """ 获取实例的 uid (hex). get hex uid from instance.

    Examples::

        data = {
            'uid': instance.uid.hex if instance else None,
            'related_uid': instance.related.uid.hex if instance.related else None,
        }

        data = {
            'uid': get_uid(instance),
            'related_uid': get_uid(instance.related),
        }

    :rtype: str | None
    """
    return instance.uid.hex if instance else None


def module_name_split(name):
    """
    Split the module name into package name and module name.
    """
    if '.' in name:
        package_name, module = name.rsplit('.', 1)
    else:
        package_name, module = '', name
    return package_name, module


def reduce_list(*args):
    """Reduce array to a single list"""
    ret = []
    for val in args[-1]:
        ret.append(val)
    return [ret]


def pick_gpus_nvidia(cuda_gpus, n_gpus):
    """
    Pick one or more Nvidia GPUs.
    """
    if len(cuda_gpus) < n_gpus:
        raise ValueError(
            'Not enough Nvidia GPU: requested %d, but can get only %d' % (
            n_gpus, len(cuda_gpus)))
    gpus_cc = []
    for gpu_id, gpu in cuda_gpus.items():
        cc = gpu['compute_capability']
        gpus_cc.append((gpu_id, cc[0] + 0.1 * cc[1]))
    gpus_cc_sorted = sorted(gpus_cc, key=lambda x: x[1], reverse=True)
    res = []
    for i in range(n_gpus):
        res.append(cuda_gpus[gpus_cc_sorted[i][0]])
    return res


def merge_bases_attribute(cls, attr_name, init, default, merge_func=lambda
    a, b: a + b):
    """
    Merge all values of attribute defined in all bases classes (using `__mro__`).
    Return resulting value. Use default every time a class does not have given attribute.

    Be careful, `merge_func` must be a pure function.
    """
    value = init
    for base in cls.__mro__:
        value = merge_func(value, getattr(base, attr_name, default))
    return value


@staticmethod
def format_resource_name(name):
    """format resource name

        Util method to format resource names to make them compatible with BCF.

        Replaces special characters with its corresponding BCF compatible
        encoding.

        :param name non empty string which is the name of the resource
        :rtype string name with special characters replaced
        """
    return name.replace('_', '__').replace(' ', '_s').replace("'", '_a'
        ).replace('/', '_f').replace('[', '_l').replace(']', '_r')


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

        :param EmmErrorType val:
        :rtype: EventType
        """
    return cls('emm_error', val)


def apply_mapping(sample, mappings, start, end):
    """Helper applying maps in defined threshold."""
    for mapping in mappings[start:end]:
        sample = mapping(sample)
    return sample


def split_timecode(time_code):
    """ Takes a timecode string and returns the hours, minutes and seconds. Does not simplify timecode.

    :param time_code: String of format "HH:MM:SS.S" ex. "01:23:45.6"
    :return: HH (float), MM (float), SS (float)
    """
    hh, mm, ss = time_code.split(':')
    hh = float(hh)
    mm = float(mm)
    ss = float(ss)
    return hh, mm, ss


def get_input():
    """
    Fetch input from command line. Requests user input for number of rows, columns and zip file path.
    :return:
    """
    file_path = input('Enter the zip file path: ')
    title = input('Enter the title for the web tour: ')
    num_rows = int(input('Enter number of rows: '))
    num_col = int(input('Enter number of columns: '))
    return file_path, title, num_rows, num_col


def slo(request):
    """
        generate a SAML2 single logout request, return url
        """


def kronestring(kr):
    """Return a string version of the integer value ``kr``, with
       space as the thousand-separator.
    """
    if kr == 0:
        return '0'
    res = ''
    if kr < 0:
        sign = '-'
        kr = -kr
    else:
        sign = ''
    while kr:
        kr, tusen = divmod(kr, 1000)
        res = ' '.join(['%03d' % tusen, res])
    return sign + res.rstrip(' ').lstrip('0')


def filter_edges_by_attributes(graph, attr_key, attr_cond):
    """Filter graph edges by attributes.

    Removes all the edges of the graph (inplace) that do not
    satisfy `attr_cond`.

    Parameters
    ----------
    graph : regraph.Graph
    attrs_key : attribute key
    attrs_cond : callable
        Condition for an attribute to satisfy: callable that returns
        `True` if condition is satisfied, `False` otherwise.

    """
    graph.filter_edges_by_attributes(attr_key, attr_cond)


def add(content):
    """Add a new content to the order list, if possible.
        """


def K_motionless_mixer(K, L, D, fd):
    """Calculates loss coefficient of a motionless mixer with a regression
    parameter in [1]_ and originally in [2]_.

    .. math::
        K = K_{L/T}f\\frac{L}{D}

    Parameters
    ----------
    K : float
        Correlation parameter specific to a mixer's design, [-]
        Also specific to laminar or turbulent regime.
    L : float
        Length of the motionless mixer [m]
    D : float
        Diameter of pipe [m]
    fd : float
        Darcy friction factor [-]

    Returns
    -------
    K : float
        Loss coefficient of mixer [-]

    Notes
    -----
    Related to example 7-8.3.2 in [1]_.

    Examples
    --------
    >>> K_motionless_mixer(K=150, L=.762*5, D=.762, fd=.01)
    7.5

    References
    ----------
    .. [1] Paul, Edward L, Victor A Atiemo-Obeng, and Suzanne M Kresta.
       Handbook of Industrial Mixing: Science and Practice.
       Hoboken, N.J.: Wiley-Interscience, 2004.
    .. [2] Streiff, F. A., S. Jaffer, and G. Schneider (1999). Design and
       application of motionless mixer technology, Proc. ISMIP3, Osaka,
       pp. 107-114.
    """
    return L / D * fd * K


def tag_string(message):
    """Convert a gRPC V3Tag message to its corresponding tag string.

    Args:
        message (V3Tag): The tag message to convert to its string representation.

    Returns:
        str: The string representation of the tag message.
    """
    tag = ''
    if message.namespace:
        tag += f'{message.namespace}/'
    if message.annotation:
        tag += f'{message.annotation}:'
    tag += message.label
    return tag


def KK_RC71_fit(params, w, t_values):
    """
    Kramers-Kronig Function: -RC-

    Kristian B. Knudsen (kknu@berkeley.edu / kristianbknudsen@gmail.com)
    """
    Rs = params['Rs']
    R1 = params['R1']
    R2 = params['R2']
    R3 = params['R3']
    R4 = params['R4']
    R5 = params['R5']
    R6 = params['R6']
    R7 = params['R7']
    R8 = params['R8']
    R9 = params['R9']
    R10 = params['R10']
    R11 = params['R11']
    R12 = params['R12']
    R13 = params['R13']
    R14 = params['R14']
    R15 = params['R15']
    R16 = params['R16']
    R17 = params['R17']
    R18 = params['R18']
    R19 = params['R19']
    R20 = params['R20']
    R21 = params['R21']
    R22 = params['R22']
    R23 = params['R23']
    R24 = params['R24']
    R25 = params['R25']
    R26 = params['R26']
    R27 = params['R27']
    R28 = params['R28']
    R29 = params['R29']
    R30 = params['R30']
    R31 = params['R31']
    R32 = params['R32']
    R33 = params['R33']
    R34 = params['R34']
    R35 = params['R35']
    R36 = params['R36']
    R37 = params['R37']
    R38 = params['R38']
    R39 = params['R39']
    R40 = params['R40']
    R41 = params['R41']
    R42 = params['R42']
    R43 = params['R43']
    R44 = params['R44']
    R45 = params['R45']
    R46 = params['R46']
    R47 = params['R47']
    R48 = params['R48']
    R49 = params['R49']
    R50 = params['R50']
    R51 = params['R51']
    R52 = params['R52']
    R53 = params['R53']
    R54 = params['R54']
    R55 = params['R55']
    R56 = params['R56']
    R57 = params['R57']
    R58 = params['R58']
    R59 = params['R59']
    R60 = params['R60']
    R61 = params['R61']
    R62 = params['R62']
    R63 = params['R63']
    R64 = params['R64']
    R65 = params['R65']
    R66 = params['R66']
    R67 = params['R67']
    R68 = params['R68']
    R69 = params['R69']
    R70 = params['R70']
    R71 = params['R71']
    return Rs + R1 / (1 + w * 1.0j * t_values[0]) + R2 / (1 + w * 1.0j *
        t_values[1]) + R3 / (1 + w * 1.0j * t_values[2]) + R4 / (1 + w *
        1.0j * t_values[3]) + R5 / (1 + w * 1.0j * t_values[4]) + R6 / (1 +
        w * 1.0j * t_values[5]) + R7 / (1 + w * 1.0j * t_values[6]) + R8 / (
        1 + w * 1.0j * t_values[7]) + R9 / (1 + w * 1.0j * t_values[8]
        ) + R10 / (1 + w * 1.0j * t_values[9]) + R11 / (1 + w * 1.0j *
        t_values[10]) + R12 / (1 + w * 1.0j * t_values[11]) + R13 / (1 + w *
        1.0j * t_values[12]) + R14 / (1 + w * 1.0j * t_values[13]) + R15 / (
        1 + w * 1.0j * t_values[14]) + R16 / (1 + w * 1.0j * t_values[15]
        ) + R17 / (1 + w * 1.0j * t_values[16]) + R18 / (1 + w * 1.0j *
        t_values[17]) + R19 / (1 + w * 1.0j * t_values[18]) + R20 / (1 + w *
        1.0j * t_values[19]) + R21 / (1 + w * 1.0j * t_values[20]) + R22 / (
        1 + w * 1.0j * t_values[21]) + R23 / (1 + w * 1.0j * t_values[22]
        ) + R24 / (1 + w * 1.0j * t_values[23]) + R25 / (1 + w * 1.0j *
        t_values[24]) + R26 / (1 + w * 1.0j * t_values[25]) + R27 / (1 + w *
        1.0j * t_values[26]) + R28 / (1 + w * 1.0j * t_values[27]) + R29 / (
        1 + w * 1.0j * t_values[28]) + R30 / (1 + w * 1.0j * t_values[29]
        ) + R31 / (1 + w * 1.0j * t_values[30]) + R32 / (1 + w * 1.0j *
        t_values[31]) + R33 / (1 + w * 1.0j * t_values[32]) + R34 / (1 + w *
        1.0j * t_values[33]) + R35 / (1 + w * 1.0j * t_values[34]) + R36 / (
        1 + w * 1.0j * t_values[35]) + R37 / (1 + w * 1.0j * t_values[36]
        ) + R38 / (1 + w * 1.0j * t_values[37]) + R39 / (1 + w * 1.0j *
        t_values[38]) + R40 / (1 + w * 1.0j * t_values[39]) + R41 / (1 + w *
        1.0j * t_values[40]) + R42 / (1 + w * 1.0j * t_values[41]) + R43 / (
        1 + w * 1.0j * t_values[42]) + R44 / (1 + w * 1.0j * t_values[43]
        ) + R45 / (1 + w * 1.0j * t_values[44]) + R46 / (1 + w * 1.0j *
        t_values[45]) + R47 / (1 + w * 1.0j * t_values[46]) + R48 / (1 + w *
        1.0j * t_values[47]) + R49 / (1 + w * 1.0j * t_values[48]) + R50 / (
        1 + w * 1.0j * t_values[49]) + R51 / (1 + w * 1.0j * t_values[50]
        ) + R52 / (1 + w * 1.0j * t_values[51]) + R53 / (1 + w * 1.0j *
        t_values[52]) + R54 / (1 + w * 1.0j * t_values[53]) + R55 / (1 + w *
        1.0j * t_values[54]) + R56 / (1 + w * 1.0j * t_values[55]) + R57 / (
        1 + w * 1.0j * t_values[56]) + R58 / (1 + w * 1.0j * t_values[57]
        ) + R59 / (1 + w * 1.0j * t_values[58]) + R60 / (1 + w * 1.0j *
        t_values[59]) + R61 / (1 + w * 1.0j * t_values[60]) + R62 / (1 + w *
        1.0j * t_values[61]) + R63 / (1 + w * 1.0j * t_values[62]) + R64 / (
        1 + w * 1.0j * t_values[63]) + R65 / (1 + w * 1.0j * t_values[64]
        ) + R66 / (1 + w * 1.0j * t_values[65]) + R67 / (1 + w * 1.0j *
        t_values[66]) + R68 / (1 + w * 1.0j * t_values[67]) + R69 / (1 + w *
        1.0j * t_values[68]) + R70 / (1 + w * 1.0j * t_values[69]) + R71 / (
        1 + w * 1.0j * t_values[70])


def get_tables():
    """
    Returns hardcoded list of tables which have ``tenant_id`` column.

    DB head can be changed. To prevent possible problems, when models will be
    updated, return hardcoded list of tables, up-to-date for this day.

    Output retrieved by using:

    >>> metadata = head.get_metadata()
    >>> all_tables = metadata.sorted_tables
    >>> tenant_tables = []
    >>> for table in all_tables:
    ...     for column in table.columns:
    ...         if column.name == 'tenant_id':
    ...             tenant_tables.append((table, column))

    """
    tables = ['vips', 'members', 'pools', 'healthmonitors', 'lbaas_members',
        'lbaas_healthmonitors', 'lbaas_loadbalancers', 'lbaas_pools',
        'lbaas_l7rules', 'lbaas_l7policies', 'lbaas_listeners']
    return tables


def land_temp_prob(tirs1, tlow, thigh):
    """Temperature-based probability of cloud over land

    Equation 14 (Zhu and Woodcock, 2012)

    Parameters
    ----------
    tirs1: ndarray
    tlow: float
        Low (17.5 percentile) temperature of land
    thigh: float
        High (82.5 percentile) temperature of land

    Output
    ------
    ndarray :
        probability of cloud over land based on temperature
    """
    temp_diff = 4
    return (thigh + temp_diff - tirs1) / (thigh + 4 - (tlow - 4))


def parse_nodes_coords(osm_response):
    """
    Parse node coordinates from OSM response. Some nodes are
    standalone points of interest, others are vertices in
    polygonal (areal) POIs.

    Parameters
    ----------
    osm_response : string
        OSM response JSON string

    Returns
    -------
    coords : dict
        dict of node IDs and their lat, lon coordinates
    """
    coords = {}
    for result in osm_response['elements']:
        if 'type' in result and result['type'] == 'node':
            coords[result['id']] = {'lat': result['lat'], 'lon': result['lon']}
    return coords


def convert_float(value):
    """ Returns an float or None for empty strings. """
    if not value:
        return None
    else:
        return float(value)


def vertex_color_remove():
    """Remove vertex color layer

    """
    pass


def current_piv(power, voltage):
    """Usage: current_piv(power, voltage)"""
    return power / voltage


def dBu_to_V(dBu):
    """Converts dBu to V."""
    return 0.775 * 10 ** (dBu / 20.0)


@classmethod
def cli_to_config(cls, cli_cmd_str):
    """Translate awscli's create-cluster command to boto3.emr.run_job_flow parameters

        This is helpful when you manually configured EMR in AWS console and then export cli string
        for repeated use.
        """
    raise NotImplementedError


@classmethod
def _validate_doc(cls, doc):
    """Emit a warning or raise an exception if the document is invalid. Returns doc."""
    try:
        for key in doc.keys():
            cls._validate_doc(doc[cls._validate_key(key)])
    except AttributeError:
        return
    return doc


@classmethod
def from_wif(cls, wif):
    """Creates key from WIFC or WIF format key"""
    return cls(wif=wif)


def replace_missing_remove_row(x_train, x_test=None, cols_to_remove=[]):
    """
    Remove rows where the value of a column for those rows is missing.

    Parameters
    ----------
    x_train : DataFrame
        Dataset

    x_test : DataFrame
        Testing Dataset, by default None

    cols_to_remove : list
        List of columns you want to check to see if they have missing values in a row

    Returns
    -------
    Dataframe, *Dataframe:
        Cleaned columns of the Dataframe(s) provides with the provided constant.

    Returns 2 Dataframes if x_test is provided.
    """
    x_train = x_train.dropna(axis=0, subset=cols_to_remove)
    if x_test is not None:
        x_test = x_test.dropna(axis=0, subset=cols_to_remove)
    return x_train, x_test


def reduce_headers(content, level, indent=1):
    """
    replaces the #* with level number of #

    :param content:
    :type content:
    :param level:
    :type level:
    :param indent:
    :type indent:
    :return:
    :rtype:
    """
    ignore = False
    lines = content.splitlines()
    headers = []
    out = []
    for line in lines:
        if line.startswith('`'):
            ignore = not ignore
        if line.startswith('#') and not ignore:
            line = line.replace('#' * level, '#')
            line = line.replace('# ', '#' * (indent - 1) + ' ')
        out.append(line)
    return out


def force_mfd(moment, distance_from_pivot):
    """Usage: Calculate force from moment and the perpendicular distance from the pivot"""
    return moment / distance_from_pivot


@classmethod
def via_usb_raw(cls, serial_number=None, manufacturer_id=None, model_code=
    None, name=None, board=0, **kwargs):
    """Return a Driver with an underlying USB RAW resource.

        Parameters
        ----------
        serial_number :
            The serial number of the instrument. (Default value = None)
        manufacturer_id :
            The unique identification number of the manufacturer. (Default value = None)
        model_code :
            The unique identification number of the product. (Default value = None)
        name :
            Unique name given within Lantz to the instrument for logging purposes.
            Defaults to one generated based on the class name if not provided.
        board :
            USB Board to use (Default value = 0)
        kwargs :
            keyword arguments passed to the Resource constructor on initialize.
        **kwargs :

        Returns
        -------

        """
    return cls._via_usb('RAW', serial_number, manufacturer_id, model_code,
        name, board, **kwargs)


def old_norm_constant(id_string: str) ->float:
    """Normalization constants for Figueira et al 2016.

    These are the manual values to achieve a SNR of 100 at 1.25 micro
    for the set of parameter combinations presented.
    """
    if 'M0' in id_string and ('1.0' in id_string or '5.0' in id_string or
        '10.0' in id_string):
        norm_constant = 1607
    elif 'M3' in id_string and ('1.0' in id_string or '5.0' in id_string or
        '10.0' in id_string):
        norm_constant = 1373
    elif 'M6' in id_string and '1.0' in id_string:
        norm_constant = 933
    elif 'M6' in id_string and '5.0' in id_string:
        norm_constant = 967
    elif 'M6' in id_string and '10.0' in id_string:
        norm_constant = 989
    elif 'M9' in id_string and '1.0' in id_string:
        norm_constant = 810
    elif 'M9' in id_string and '5.0' in id_string:
        norm_constant = 853
    elif 'M9' in id_string and '10.0' in id_string:
        norm_constant = 879
    else:
        print('Constant not defined. Aborting...')
        raise ValueError('Bad ID string')
    return (norm_constant / 100.0) ** 2.0


def getProcessName(pid):
    """Gets process name from process id"""
    truncProcessName = open('/proc/%s/status' % pid).readline()[6:-1]
    processName = truncProcessName
    line = open('/proc/%s/cmdline' % pid).readline()
    parts = line.split('\x00')
    for part in parts:
        cmdName = part.split('/')[-1]
        if cmdName.startswith(truncProcessName):
            processName = cmdName
    return processName


@staticmethod
def join_ops(ops1, ops2):
    """For internal use."""
    i = len(ops1) - 1
    j = 0
    while i >= 0 and j < len(ops2):
        if ops1[i] == ops2[j]:
            i -= 1
            j += 1
        else:
            break
    return ops1[:i + 1] + ops2[j:]


def N_chi2(flux, fluxerr, fluxmod, mask=None):
    """ compute the non-reduced chi2 between data with uncertainties and
        perfectly known models

    Parameters
    ----------
    flux:    np.ndarray[float, ndim=1]
        array of fluxes

    fluxerr: np.ndarray[float, ndim=1]
        array of flux errors

    fluxmod: np.ndarray[float, ndim=2]
        array of modeled fluxes (nfilters , nmodels)

    mask:    np.ndarray[bool, ndim=1]
        mask array to apply during the calculations mask.shape = flux.shape

    Returns
    -------
    chi2:    np.ndarray[float, ndim=1]
        array of chi2 values (nmodels)
    """
    if mask is None:
        temp = flux[(None), :] - fluxmod
        _e = fluxerr
    else:
        _m = ~mask.astype(bool)
        temp = flux[_m]
        temp = temp[(None), :] - fluxmod[:, (_m)]
        _e = fluxerr[_m]
    for j in range(len(_e)):
        if _e[j] > 0:
            temp[:, (j)] /= _e[j]
    return (temp ** 2).sum(axis=1)


def getPath():
    """Return the Python path of the module."""


def vert_select_ungrouped(extend: bool=False):
    """Select vertices without a group

    :param extend: Extend, Extend the selection
    :type extend: bool
    """
    pass


@staticmethod
def get_compatable_connection_types():
    """
        This is needed so the build system knows which
        connection types this connection is compatable.
        return::['str'] A list of the compatable socket types.
        """
    return ['publisher']


def __version():
    """ return the current version and date released """
    return '3.1.0', '2019-11-23'


def broadcast_greater(lhs=None, rhs=None, out=None, name=None, **kwargs):
    """Returns the result of element-wise **greater than** (>) comparison operation with broadcasting.

    Example::

       x = [[ 1.,  1.,  1.],
            [ 1.,  1.,  1.]]

       y = [[ 0.],
            [ 1.]]

       broadcast_greater(x, y) = [[ 1.,  1.,  1.],
                                  [ 0.,  0.,  0.]]

    Defined in src/operator/tensor/elemwise_binary_broadcast_op_logic.cc:L82

    Parameters
    ----------
    lhs : NDArray
        First input to the function
    rhs : NDArray
        Second input to the function

    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 multi_sum_sq(*data, **kwargs):
    """Compute the sums of squares of multiple arrays

    Defined in src/operator/contrib/multi_sum_sq.cc:L36

    Parameters
    ----------
    data : Symbol[]
        Arrays
    num_arrays : int, required
        number of input arrays.

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

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


def MiniBatchDiscrimination(x):
    """
    To create mini batch diversity
    applyied in discriminator in GAN
    :param x: projected (bs,hs) tensor
    :return: tensor in size (bs,hs)
    """
    bs = x.size(0)
    return -(x.unsqueeze(0).repeat([bs, 1, 1]) - x.unsqueeze(-1).repeat([1,
        1, bs]).permute(0, 2, 1)).sum(1)


def get_root(node):
    """Navigates up the given node and returns the root node."""
    try:
        while node.parent:
            node = node.parent
    except AttributeError:
        pass
    return node


def _cli_parse(args):
    """
        python -m six_web 输出的帮助文档
    :param args: 参数输入
    :return:
    """
    from argparse import ArgumentParser
    parser = ArgumentParser(prog=args[0], usage=
        '%(prog)s [options] package.moudle:app', epilog=
        'Life is short, love python!', description=
        'Coding to change the world for better.')
    opt = parser.add_argument
    opt('-v', '--version', action='store_true', help='show version number')
    opt('-b', '--bind', metavar='ip:port', help=
        'bind address, default localhost:8080')
    opt('-s', '--server', metavar='SERVER', help='user SERVER as backend')
    opt('-C', '--param', metavar='NAME=VALUE', help='overwrite config value')
    opt('--debug', help='run server in debug mode')
    opt('--reload', help='auto reload on file changes')
    parser.parse_args()


def crypt(stream, parameters):
    """
        Method to encrypt streams using a PDF security handler (NOT IMPLEMENTED YET)

        @param stream: A PDF stream
        @return: A tuple (status,statusContent), where statusContent is the encrypted PDF stream in case status = 0 or an error in case status = -1
    """
    if parameters is None or parameters == {}:
        return 0, stream
    elif '/Name' not in parameters or parameters['/Name'] is None:
        return 0, stream
    else:
        cryptFilterName = parameters['/Name'].getValue()
        if cryptFilterName == 'Identity':
            return 0, stream
        else:
            return -1, 'Crypt not supported yet'


def startswith_str(text, prefix, start=None, end=None):
    """
    Determines if ``text`` starts with the specified prefix.

    The prefix can also be a tuple of prefixes to look for. With optional parameter ``start``,
    the test will begin at that position. With optional parameter ``end``, the test will
    stop comparing at that position.

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

    :param prefix: The prefix to search for
    :type prefix:  ``str`` or ``tuple`` of ``str``

    :param start: The start of the search range
    :type start:  ``int``

    :param end: The end of the search range
    :type end:  ``int``

    :return: True if ``text`` starts with the specified prefix, otherwise return False.
    :rtype:  ``int``
    """
    assert isinstance(text, str), '%s is not a string' % text
    return text.startswith(prefix, start, end)


@staticmethod
def sanitise_path(path):
    """
        Adds a '/' to the path if it does not exist.
        :param path: Path that is to be sanitised.
        :return: string
        """
    if path[0] != '/':
        path = '/' + path
    return path


@classmethod
def get_vdw(cls, atom):
    """Returns van der waals radius of a given element"""
    atnum = cls.get_atnum(atom)
    return float(cls.ptable[atom.atnum][-1])


def durRisingSlopes(Frames, threshold=0.0):
    """Computes durations (counted in number of frames)
    of RISING slopes.Returns an array of
    all durations of RISING slopes in the signal.

    ARGUMENTS:
        Frames: List of values of pitch or energy.
        threshold: Helping variable (belongs to [0,1] range)
                   that is used to ignore small falling slopes
                   between two more dominant rising slopes.

    RETURNS:
        List of duration of all rising slopes."""
    counter, previous, durations = 1, Frames[0], []
    for i in range(len(Frames)):
        if Frames[i] > previous:
            counter = counter + 1
            peak = Frames[i]
        elif counter > 1:
            if Frames[i] > (1 - threshold) * peak:
                counter = counter + 1
            else:
                durations.append(counter)
                counter = 1
        previous = Frames[i]
    if counter > 1:
        durations.append(counter)
    return durations


def check_options(options):
    """Check options provided ny user, or assigned by defaults
    are valid arguments.

    Keyword arguments:
    options -- contains all options used to fit model (dictionary)
    """
    if options['batch'] not in (True, False):
        raise ValueError(
            'User Error: Invalid argument provided for batch type.')
    if options['sigmoid_type'] not in ('norm', 'logistic', 'gumbel',
        'weibull', 'quick', 'log-quick', 'hyperbolic'):
        raise ValueError(
            'User Error: Sigmoid type specified is not one made available by the module.'
            )
    if options['logspace'] not in (True, False):
        raise ValueError(
            'User/Internal Error: Invalid argument for log-spacing of x-values provided.'
            )
    if options['nafc'] not in (1, 2, 3, 4, 5, 6, 7, 8, 9, 10):
        raise ValueError(
            'Warning: Value provided for nAFC is greater than 10, or less than zero!'
            )
    if isinstance(options['threshold'], (int, float, complex)) is False:
        raise ValueError(
            'Please provide a numerical argument for proportion correct estimate of threshold.'
            )
    if not 0 <= options['threshold'] <= 1:
        raise ValueError(
            'User Error: Value provided for threshold estimate not between zero and one!'
            )
    if isinstance(options['nafc'], int) is False:
        raise ValueError(
            'User Error: Please provide a integer for nAFC argument.')
    if isinstance(options['param_ests'], list) is False:
        raise ValueError(
            'User Error: Please provide a argument of type list for the parameter estimates of the model.'
            )
    if isinstance(options['param_free'], list) is False:
        raise ValueError(
            """User Error: Please provide a argument of type list for the
                           parameter constraints of the model."""
            )
    if isinstance(options['density'], int) is False:
        raise ValueError(
            'User Error: Please provide a integer for density of grid.')


def UdJH_to_UJ(Ud, JH):
    """
    Given :math:`U_d` and :math:`J_H`, return Kanamori :math:`U` and :math:`J`,
    for :math:`t2g`-orbitals.

    Parameters
    ----------
    Ud: float
        Coulomb interaction :math:`U_d`.
    JH: float
        Hund's coupling :math:`J_H`.

    Returns
    -------
    U: float
        Coulomb interaction :math:`U` in Kanamori form.
    J: float
        Hund's coupling :math:`J` in Kanamori form.
    """
    F2 = 14.0 / 1.625 * JH
    F4 = 0.625 * F2
    J = 3.0 / 49.0 * F2 + 20 / 441.0 * F4
    U = Ud + 4.0 / 49.0 * (F2 + F4)
    return U, J


@classmethod
def sorted(cls, connections):
    """Sort all connections from 'connections' sequence in ascending order by position.
		The sorted list is returned.
		"""
    return sorted(connections, key=lambda c: c.pos)


def get_vocab_size(bow):
    """
    Gets the vocab size from a traditional bag of words

    :param bow : traditional bag of words mapping words to a count of their occurences.
    :type  bow : dict

    :return    : the vocab size of the dataset
    """
    return len(bow)


def int_to_brightness(x: int) ->int:
    """"Return brightness (0-100) from integer."""
    return x >> 24


@classmethod
def scan(cls):
    """
			Used to scan the I2C bus, returning a list of I2C address attached to the computer.

			:return: A list of I2C addresses. If no devices are attached, an empty list is returned.
			:rtype: list

		"""
    return None


@classmethod
def construct_index(cls, name):
    """
        Force the query to use a certain index

        Parameters
        ----------
        name : str

        Returns
        -------
        condition : :class:`.Condition`

        """
    c = cls()
    c.index_name = name
    return c


def lines(list):
    """
	Prints the lines in a list.
	"""
    for i in list:
        print(i)
    return


def default_col_widths(dtype, col_header):
    """
    Assigns default column widths depending on the dtype.
    Used in _str_ representation.
    """
    col_widths = []
    values = list(zip(*list(dtype.fields.values())))[0]
    for t in values:
        if t.kind == 'S':
            col_widths.append(t.itemsize + 5)
        else:
            col_widths.append(len(col_header) + 5)
    return col_widths


def relax(prev_frame: int=0, next_frame: int=0, percentage: float=0.5):
    """Make the current pose more similar to its surrounding ones

    :param prev_frame: Previous Keyframe, Frame number of keyframe immediately before the current frame
    :type prev_frame: int
    :param next_frame: Next Keyframe, Frame number of keyframe immediately after the current frame
    :type next_frame: int
    :param percentage: Percentage, Weighting factor for the sliding operation
    :type percentage: float
    """
    pass


def _positive_int(integer_string, strict=False, cutoff=None):
    """
    Cast a string to a strictly positive integer.
    """
    ret = int(integer_string)
    if ret < 0 or ret == 0 and strict:
        raise ValueError()
    if cutoff:
        return min(ret, cutoff)
    return ret


def linear_extrap(ys, xs):
    """
    Linearly extrapolate from two x,y pairs to x = 0.

    ys: y values from x,y pairs. Note that these can be arrays of values.
    xs: x values from x,y pairs. These should be scalars.

    Returns extrapolated y at x=0.
    """
    y1, y2 = ys
    x1, x2 = xs
    return (x2 * y1 - x1 * y2) / (x2 - x1)


@staticmethod
def failure_node_name(flow_name, failure_node):
    """Create a failure node name representation for generated Python config.

        :param flow_name: name of flow for which the representation should be created
        :param failure_node: a node from graph of all failure permutations
        :return: variable name
        :rtype: str
        """
    return '_%s_fail_%s' % (flow_name, '_'.join(failure_node.traversed))


@classmethod
def from_yamlData(cls, yamlData):
    """
        Recover contacts data from YAML data structure.

        :param yamlData: YAML data loaded using ``yaml.load`` or ``yaml.safeload``.

        :return: Constructed ``Contacts`` object.
        """
    contactObject = cls()
    if yamlData is not None:
        contactObject.__parseGroups(yamlData)
        contactObject.__parseClusters(yamlData)
    return contactObject


def ensure_list(x, except_false=True):
    """
    若传入的对象不为列表，则转化为列表

    :param x: 输入对象
    :param except_false: None, False 等例外，会直接返回原值
    :return: 列表，或 None, False 等
    :rtype: list
    """
    if isinstance(x, (list, tuple)) or not x and except_false:
        return x
    return [x]


def _get_config(event, task_name):
    """
    * Returns the configuration for the task with the given name, or an empty object if no
    * such task is configured.
    * @param {*} event An event in the Cumulus message format with remote parts resolved
    * @param {*} task_name The name of the Cumulus task
    * @returns {*} The configuration object
    """
    config = {}
    if 'workflow_config' in event and task_name in event['workflow_config']:
        config = event['workflow_config'][task_name]
    return config


@classmethod
def add_hook(cls, hook_type, hook_func):
    """Add a new hook of specified type.

        :param cls: class that registers hooks
        :param hook_type: hook type, e.g., '__pre_parse_args__'
        :param hook_func: hook function
        """
    if hook_type not in cls._hooks_map:
        cls._hooks_map[hook_type] = []
    cls._hooks_map[hook_type].append(hook_func)


def check_in_session(swimmer, wanted_session, allowed):
    """Check swimmer in session."""
    in_session = False
    if swimmer.find_session_substr(wanted_session):
        in_session = True
    if allowed and in_session is False:
        for allow in allowed:
            if swimmer.find_group(allow):
                in_session = True
    if in_session is False:
        if swimmer.no_session_ok:
            return True
        if swimmer.is_coach:
            return True
        return False
    return True


def _recv_n_create_rsp(event):
    """Logging handler when an N-CREATE-RSP is received.

    Parameters
    ----------
    event : events.Event
        The evt.EVT_DIMSE_RECV event that occurred.
    """
    pass


def get_matching_providers(machines, providers):
    """Get providers managing machines.

    :return: generator yielding tuples of provides instance and
    machines list"""
    for provider in providers:
        common_machines = list(set(provider.machines).intersection(set(
            machines)))
        if len(common_machines) > 0:
            yield provider, common_machines


def add_vectors_xy(u, v):
    """Add two vectors, assuming they lie in the XY-plane.

    Parameters
    ----------
    u : sequence of float
        XY(Z) components of the first vector.
    v : sequence of float
        XY(Z) components of the second vector.

    Returns
    -------
    list
        Resulting vector in the XY-plane (Z = 0.0)

    Examples
    --------
    >>>

    """
    return [u[0] + v[0], u[1] + v[1], 0.0]


def _remove_intercept_patsy(terms):
    """
    Remove intercept from Patsy terms.
    """
    from patsy.desc import INTERCEPT
    if INTERCEPT in terms:
        terms.remove(INTERCEPT)
    return terms


def hide(obj):
    """
    Mark object as private.
    """
    obj._spec__is_private = True
    return obj


def extract_metadata(name):
    """ Try to determine metadata from video title. """
    seps = name.count(' - ')
    artist = title = None
    if seps == 1:
        pos = name.find(' - ')
        artist = name[:pos].strip()
        title = name[pos + 3:].strip()
    else:
        title = name.strip()
    return dict(artist=artist, title=title)


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

    The ".dev0" means dirty.

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


def 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 palette_remove():
    """Remove active Grease Pencil palette

    """
    pass


def p_statement_equals(t):
    """statement : expression EQUALS expression"""
    t[0] = t[1] == t[3]


def red(s):
    """
    Return the given string (``s``) surrounded by the ANSI escape codes to
    print it in red.
    :param s: string to console-color red
    :type s: str
    :returns: s surrounded by ANSI color escapes for red text
    :rtype: str
    """
    return '\x1b[0;31m' + s + '\x1b[0m'