def parse_header(header):
    """Parse parts of the PDB header."""
    id = compile('HEADER\\s{4}\\S+.*\\S+\\s*\\S{9}\\s+(\\S{4})\\s*$'), 'id'
    dt = compile('HEADER\\s{4}\\S+.*\\S+\\s+(\\S{9})\\s+\\S{4}\\s*$'), 'date'
    nm = compile('HEADER\\s{4}(\\S+.*\\S+)\\s+\\S{9}\\s+\\S{4}\\s*$'), 'name'
    mc = compile(
        'REMARK 280\\s+MATTHEWS COEFFICIENT,\\s+VM\\s+\\(ANGSTROMS\\*\\*3/DA\\):\\s+(\\d+\\.\\d+)'
        ), 'matthews'
    sc = compile(
        'REMARK 280\\s+SOLVENT CONTENT,\\s+VS\\s+\\(%\\):\\s+(\\d+\\.\\d+)'
        ), 'solvent_content'
    sg = compile('REMARK 290\\s+SYMMETRY OPERATORS FOR SPACE GROUP:\\s+(.*\\S)'
        ), 'space_group'
    xt = compile('REMARK 200\\s+EXPERIMENT TYPE\\s+:\\s+(.*\\S)'
        ), 'experiment_type'
    rs = compile('REMARK   2\\s+RESOLUTION\\.\\s+(\\d+\\.\\d+)\\s+ANGSTROMS\\.'
        ), 'resolution'
    rf = compile('REMARK   3\\s+FREE R VALUE\\s+:\\s+(\\d+\\.\\d+)'), 'r_free'
    xd = compile('EXPDTA\\s+([\\w\\-]+).*'), 'expdta'
    c1 = compile('CRYST1\\s+((\\d+\\.\\d+\\s+){6})'), 'cryst1'
    ra = compile(
        'DBREF\\s+\\S{4}\\s+\\S\\s+\\d+\\s+\\d+\\s+\\S+\\s+(\\S+)\\s+\\S+\\s+\\d+\\s+\\d+\\s+$'
        ), 'dbref_acc'
    rx = compile(
        'DBREF\\s+\\S{4}\\s+\\S\\s+\\d+\\s+\\d+\\s+\\S+\\s+\\S+\\s+(\\S+)\\s+\\d+\\s+\\d+\\s+$'
        ), 'dbref_acc_full'
    tests = [id, dt, nm, mc, sc, sg, xt, rs, rf, xd, c1, ra, rx]
    results = {}
    for line in header:
        for regexp, name in tests:
            try:
                results.update({name: regexp.search(line).group(1).strip()})
                continue
            except AttributeError:
                pass
    return results


@staticmethod
def horizontal_to_enu(r, el, az):
    """ Get ENU from Horizontal (local Topocentric)
        """
    e = el.cos() * az.sin()
    n = el.cos() * az.cos()
    u = el.sin()
    return [r * e, r * n, r * u]


@staticmethod
def _createDialog(parent):
    """Create the dialog if not already existing

        :parent QWidget parent: Parent of the new colormap
        :rtype: ColormapDialog
        """
    from silx.gui.dialog.ColormapDialog import ColormapDialog
    dialog = ColormapDialog(parent=parent)
    dialog.setModal(False)
    return dialog


@staticmethod
def cast(value: str, name: str='') ->str:
    """Cast `value` to a grouped regular expression when `name` is provided."""
    return f'(?P<{name}>{value})' if name else f'{value}'


def lower(string):
    """
    Convert all cased characters in a string to lowercase.
    """
    return string.lower()


def _parabolic(f, x):
    """Quadratic interpolation for estimating the true position of an
    inter-sample maximum when nearby samples are known.

    f: a vector (an array of sampled values over a regular grid)
    x: index for that vector

    Returns (vx, vy), the coordinates of the vertex of a parabola that goes
    through point x and its two neighbors.

    Example
    =======

    Defining a vector f with a local maximum at index 3 (= 6), find local
    maximum if points 2, 3, and 4 actually defined a parabola.

    >>> f = [2, 3, 1, 6, 4, 2, 3, 1]

    >>> parabolic(f, 3)
    Out[4]: (3.2142857142857144, 6.1607142857142856)

    """
    xv = 1 / 2.0 * (f[x - 1] - f[x + 1]) / (f[x - 1] - 2 * f[x] + f[x + 1]) + x
    yv = f[x] - 1 / 4.0 * (f[x - 1] - f[x + 1]) * (xv - x)
    return xv, yv


def _add_resend_arg(arg_parser, resend_help):
    """
    Adds resend parameter to a parser.
    :param arg_parser: ArgumentParser parser to add this argument to.
    :param type_str
    """
    arg_parser.add_argument('--resend', action='store_true', default=False,
        dest='resend', help=resend_help)


@staticmethod
def __imbalancedSplit(datasize, data, test_ratio, val_ratio):
    """
        Get an imbalanced subdivision of the data in the following structure:
        {
            class1: {
                train: [img1.jpg, img2.jpg, ...]
                test : [img3.jpg, img4.jpg, ...]
                val  : [...]
            }
            class2: {
                train: [img5.jpg, img6.jpg, ...]
                test : [img7.jpg, img8.jpg, ...]
                val  : [...]
            }
            classN: {
                train: [img9.jpg , img10.jpg, ...]
                test : [img11.jpg, img12.jpg, ...]
                val  : [...]
            }
        }
        """
    _data = {}
    for c in datasize.keys():
        class_size = datasize[c]
        test_size = round(class_size * test_ratio)
        train_size = int(class_size - test_size)
        try:
            _data[c]
        except KeyError:
            _data[c] = {}
            _data[c]['train'] = []
            _data[c]['test'] = []
            _data[c]['val'] = []
        finally:
            _data[c]['train'] = data[c][:train_size]
            _data[c]['test'] = data[c][train_size:]
        if val_ratio > 0.0:
            val_size = round(train_size * val_ratio)
            _data[c]['val'] = _data[c]['train'][:val_size]
            _data[c]['train'] = _data[c]['train'][val_size:]
    return _data


def collection_duplicate():
    """Recursively duplicate the collection, all its children, objects and object data

    """
    pass


def get_eta_days(trip):
    """
    Returns the Eta Days of the trip
    :param trip: Object
    :return: eta_days of the trip
    """
    if 'eta_days' in trip.keys():
        eta_days = trip['eta_days']
        eta_days = str(eta_days) or eta_days
        try:
            return float(eta_days)
        except ValueError as e:
            return None
    else:
        return None


def _use_transactions(c):
    """Return True if the given ADODB.Connection supports transactions."""
    for prop in c.Properties:
        if prop.Name == 'Transaction DDL':
            return prop.Value > 0
    return False


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

    """
    pass


def currency_codes():
    """Retrurns currency codes."""


def is_hsl(in_col):
    """
	Check whether an input is a valid HSL color.
	Return True if it is, otherwise False.
	"""
    if len(in_col) == 3 and type(in_col) == tuple:
        if 0 <= in_col[0] <= 1 and 0 <= in_col[1] <= 1 and 0 <= in_col[2] <= 1:
            return True
        else:
            return False
    else:
        return False


def co_code_findloadednames(co):
    """Find in the code of a code object, all loaded names.
    (by LOAD_NAME, LOAD_GLOBAL or LOAD_FAST) """
    import dis
    from opcode import HAVE_ARGUMENT, opmap
    hasloadname = opmap['LOAD_NAME'], opmap['LOAD_GLOBAL'], opmap['LOAD_FAST']
    insns = dis.get_instructions(co)
    len_co_names = len(co.co_names)
    indexset = {}
    for insn in insns:
        if insn.opcode >= HAVE_ARGUMENT:
            if insn.opcode in hasloadname:
                indexset[insn.argval] = 1
                if len(indexset) >= len_co_names:
                    break
    for name in co.co_varnames:
        try:
            del indexset[name]
        except KeyError:
            pass
    return indexset


def dot_to_dict(values):
    """Convert dot notation to a dict. For example: ["token.pos", "token._.xyz"]
    become {"token": {"pos": True, "_": {"xyz": True }}}.

    values (iterable): The values to convert.
    RETURNS (dict): The converted values.
    """
    result = {}
    for value in values:
        path = result
        parts = value.lower().split('.')
        for i, item in enumerate(parts):
            is_last = i == len(parts) - 1
            path = path.setdefault(item, True if is_last else {})
    return result


def gauge(stat, value, rate=1, buf=None, rate_applied=False):
    """
        Update a gauge value.

        ``stat`` is the name of the metric to record and ``value`` is
        the new gauge value. A gauge represents a persistent value
        such as a pool size. Because gauges from different machines
        often conflict, a suffix is usually applied to gauge names;
        this may be done manually or with `MetricMod`.
        """


def read_nexus_field(parent, dataset_name, astype=None):
    """
    get a dataset from the HDF5 parent group

    :param obj parent: h5py parent object
    :param str dataset_name: name of the dataset (NeXus field) to be read
    :param obj astype: option to return as different data type
    """
    if dataset_name not in parent:
        return None
    dataset = parent[dataset_name]
    dtype = dataset.dtype
    if astype is not None:
        dtype = astype
    if len(dataset.shape) > 1:
        raise RuntimeError('unexpected %d-D data' % len(dataset.shape))
    if dataset.size > 1:
        return dataset[...].astype(dtype)
    else:
        return dataset[0].astype(dtype)


def _has_dimensions(quant, dim):
    """Checks the argument has the right dimensionality.

    Parameters
    ----------
    quant : :py:class:`unyt.array.unyt_quantity`
        Quantity whose dimensionality we want to check.
    dim : :py:class:`sympy.core.symbol.Symbol`
        SI base unit (or combination of units), eg. length/time

    Returns
    -------
    bool
        True if check successful.

    Examples
    --------
    >>> import unyt as u
    >>> from unyt.dimensions import length, time
    >>> _has_dimensions(3 * u.m/u.s, length/time)
    True
    >>> _has_dimensions(3, length)
    False
    """
    try:
        arg_dim = quant.units.dimensions
    except AttributeError:
        arg_dim = None
    return arg_dim == dim


def _component_code_key(val):
    """
    Compare two single character component codes according to sane ZNE/ZRT/LQT
    order. Any other characters are sorted afterwards alphabetically.

    >>> from random import shuffle
    >>> from string import ascii_lowercase, ascii_uppercase
    >>> lowercase = list(ascii_lowercase)
    >>> uppercase = list(ascii_uppercase)
    >>> shuffle(lowercase)
    >>> shuffle(uppercase)
    >>> component_codes = lowercase + uppercase
    >>> component_codes = sorted(component_codes,
    ...                          key=_component_code_key)
    >>> print(component_codes)  # doctest: +NORMALIZE_WHITESPACE
    ['z', 'Z', 'n', 'N', 'e', 'E', 'r', 'R', 'l', 'L', 'q', 'Q', 't', 'T', 'a',
        'A', 'b', 'B', 'c', 'C', 'd', 'D', 'f', 'F', 'g', 'G', 'h', 'H', 'i',
        'I', 'j', 'J', 'k', 'K', 'm', 'M', 'o', 'O', 'p', 'P', 's', 'S', 'u',
        'U', 'v', 'V', 'w', 'W', 'x', 'X', 'y', 'Y']
    """
    order = 'ZNERLQT'
    val = val.upper()
    try:
        return chr(order.index(val) + 32)
    except ValueError:
        return val


def reset():
    """Empty stack and set to identity.

    """
    pass


def is_bool(value):
    """ Checks if the value is a bool """
    return value.lower() in ['true', 'false', 'yes', 'no', 'on', 'off']


def t_CPP_COMMENT1(t):
    """(/\\*(.|\\n)*?\\*/)"""
    ncr = t.value.count('\n')
    t.lexer.lineno += ncr
    t.type = 'CPP_WS'
    t.value = '\n' * ncr if ncr else ' '
    return t


def close_event(event):
    """
    Closes a Pilatus event retrieved from HiDRA.

    The HiDRA event does not need to be closed, so this function actually does nothing.

    NOTE: This function is designed to be injected as a member function into an
    :class:`~onda.utils.data_event.DataEvent` object.

    Arguments:

        event (:class:`~onda.utils.data_event.DataEvent`): an object storing the event
            data.
    """
    del event


def transition(content, request, transition_name, context=None, guards=()):
    """ Execute a transition using a transition name.
        """


def cleanup(mcurl):
    """Clean-up MultiCurl handles"""
    for curl in mcurl.handles:
        if curl.hbuf is not None:
            curl.hbuf.close()
            curl.hbuf = None
        if curl.bbuf is not None:
            curl.bbuf.close()
            curl.bbuf = None
        curl.close()
    mcurl.close()


@classmethod
def buildORMModelInstance(cls, model, attributes):
    """ build model instance """
    return model(origin_attributes=attributes)


def search_ancestor(node, *node_types):
    """
    Recursively looks at the parents of a node and returns the first found node
    that matches node_types. Returns ``None`` if no matching node is found.

    :param node: The ancestors of this node will be checked.
    :param node_types: type names that are searched for.
    :type node_types: tuple of str
    """
    while True:
        node = node.parent
        if node is None or node.type in node_types:
            return node


@staticmethod
def name(source):
    """Instead of hashable, return description from given value."""
    return 'trigger_%s-%s' % (source.name, source.sourcefile)


def page_element_unicode0(element):
    """Get Unicode string of the first text result."""
    if element.get_TextEquiv():
        return element.get_TextEquiv()[0].Unicode
    else:
        return ''


def unshift_flags(tcp_flags):
    """
    De-shift the TCP flags to a string repr
    """
    return (tcp_flags & 1, tcp_flags >> 1 & 1, tcp_flags >> 2 & 1,
        tcp_flags >> 3 & 1, tcp_flags >> 4 & 1, tcp_flags >> 5 & 1)


def _get_unpatched(cls):
    """Protect against re-patching the distutils if reloaded

    Also ensures that no other distutils extension monkeypatched the distutils
    first.
    """
    while cls.__module__.startswith('setuptools'):
        cls, = cls.__bases__
    if not cls.__module__.startswith('distutils'):
        raise AssertionError('distutils has already been patched by %r' % cls)
    return cls


@classmethod
def untranslated_fields(cls):
    """
        The fields that should not be translated on this object.

        :rtype:
            `tuple`
        """
    return cls._untranslated_fields


def findInteraction(interactions, roadUserNum1, roadUserNum2):
    """Returns the right interaction in the set"""
    i = 0
    while i < len(interactions) and set([roadUserNum1, roadUserNum2]
        ) != interactions[i].getRoadUserNumbers():
        i += 1
    if i < len(interactions):
        return interactions[i]
    else:
        return None


def get_prometheus_base_config():
    """
    Generate a basic configuration dictionary for prometheus
    :return: dictionary
    """
    conf = dict()
    conf['global'] = {'evaluation_interval': '5s', 'scrape_interval': '5s'}
    conf['scrape_configs'] = []
    return conf


def get_gps_time(tnow):
    """return gps_week and gps_week_ms for current time"""
    leapseconds = 18
    SEC_PER_WEEK = 7 * 86400
    epoch = 86400 * (10 * 365 + (1980 - 1969) / 4 + 1 + 6 - 2) - leapseconds
    epoch_seconds = int(tnow - epoch)
    week = int(epoch_seconds) // SEC_PER_WEEK
    t_ms = int(tnow * 1000) % 1000
    week_ms = epoch_seconds % SEC_PER_WEEK * 1000 + t_ms // 200 * 200
    return week, week_ms


def is_win(c):
    """
    Return True if remote SSH server is running Windows, False otherwise.

    The idea is based on echoing quoted text: \\*NIX systems will echo quoted
    text only, while Windows echoes quotation marks as well.

    .. note::

       This function is derived from one copied from fabric v1.
    """
    result = c.run('echo "Will you echo quotation marks"', warn=True)
    return '"' in result.stdout


def find(s, start, seq, l):
    """ extract till a sequence occurs """
    wlen = len(seq)
    cc = s[start:start + wlen]
    while cc != seq and start < l:
        start += 1
        cc = s[start:wlen + start]
    return start


def get_permuted_peers(service_name, key):
    """Returns an ordered list of (peerid, rref) tuples, selecting from
        the connections that provide SERVICE_NAME, using a hash-based
        permutation keyed by KEY. This randomizes the service list in a
        repeatable way, to distribute load over many peers.
        """


def get_texts_and_labels(sentence_chunk):
    """Given a sentence chunk, extract original texts and labels."""
    words = sentence_chunk.split('\n')
    texts = []
    labels = []
    for word in words:
        word = word.strip()
        if len(word) > 0:
            toks = word.split('\t')
            texts.append(toks[0].strip())
            labels.append(toks[-1].strip())
    return texts, labels


def show(*args, **kwargs):
    """show(x, y, z=z) # print names & values of arguments
    names of args will be determined only if possible
    names of kwargs will be known as it is explicitely given
    """
    import miscutils.insp as insp
    from peepshow.core import show as core
    from peepshow.utils import python as utils
    if args or kwargs:
        if args:
            names = utils.arg_names()
        else:
            names = []
        names += [*kwargs.keys()]
        values = [*args] + [*kwargs.values()]
    else:
        env = utils.caller_gloloc()
        is_user_var = lambda item: not insp.isaccess(item[0]).special
        user_vars = filter(is_user_var, env.initial.items())
        names, values = zip(*user_vars)
    core.show(names, values)


def simplegoo(com, kw=[''], tsl=0):
    """
    Google companies plus the keyword given.
    com and kw must be lists, excluding NaN elements.
    tsl is the time sleep level when opening each tab.
    """
    import time
    import numpy as np
    from selenium import webdriver
    from selenium.webdriver.common.keys import Keys
    wh = 'https://www.google.com/'
    js = "window.open('https://www.google.com/')"
    sch = webdriver.Chrome()
    li = []
    for i in com:
        for j in kw:
            b = str(i) + ' ' + str(j)
            li.append(b)
    n = 1
    for i in li:
        a = i
        sch.get(wh)
        sch.find_element_by_name('q').send_keys(a)
        sch.find_element_by_name('q').send_keys(Keys.ENTER)
        time.sleep(tsl * np.random.rand() + 0.002)
        sch.execute_script(js)
        handles = sch.window_handles
        sch.switch_to.window(handles[n])
        n += 1
    sch.close()
    sch.switch_to.window(handles[0])


def create_list_from_file(file_name):
    """Given a file, create a list from its contents.

    :param file_name: the path to the file -- str
    :returns: file contents -- list
    """
    with open(file_name) as f:
        list_item = f.readlines()
    raw_list = map(lambda s: s.strip(), list_item)
    return list(raw_list)


@classmethod
def from_sqla(cls, sqla_obj):
    """ Create a yalchemy ForeignKey from a sqlalchemy ForeignKeyConstraint

        Arguments:
            sqla_obj: The sqlalchemy ForeignKeyConstraint object.
        """
    assert len(sqla_obj.column_keys) == 1
    assert len(sqla_obj.elements) == 1
    target_table, target_col = sqla_obj.elements[0].target_fullname.rsplit('.',
        1)
    return cls(sqla_obj.column_keys[0], target_table, target_col)


def load_cluster_data(clusters_file):
    """
    Loads into  a dictionary the coords of each cluster center
    :param clusters_file: name of the MSM clusters file
    :return: dict with the clusters as keys and the coords as values
    """
    clusters_data = {}
    with open(clusters_file, 'r') as inputfile:
        for line in inputfile:
            line = line.split()
            clusters_data[int(line[1])] = [float(line[-6]), float(line[-5]),
                float(line[-4])]
    return clusters_data


@classmethod
def zero(cls):
    """Returns the zero vector (0 | 0 | 0)"""
    return cls(0, 0, 0)


def generate_slices(sliceable_set, batch_len=1, length=None, start_batch=0):
    """Iterate through a sequence (or generator) in batches of length `batch_len`

    See Also:
      pug.dj.db.generate_queryset_batches

    References:
      http://stackoverflow.com/a/761125/623735

    Examples:
      >>  [batch for batch in generate_slices(range(7), 3)]
      [(0, 1, 2), (3, 4, 5), (6,)]
      >>  from django.contrib.auth.models import User, Permission
      >>  len(list(generate_slices(User.objects.all(), 2)))       == max(math.ceil(User.objects.count() / 2.), 1)
      True
      >>  len(list(generate_slices(Permission.objects.all(), 2))) == max(math.ceil(Permission.objects.count() / 2.), 1)
      True
    """
    if length is None:
        try:
            length = sliceable_set.count()
        except (IndexError, ValueError, AttributeError, TypeError):
            length = len(sliceable_set)
    length = int(length)
    for i in range(int(length / batch_len + 1)):
        if i < start_batch:
            continue
        start = i * batch_len
        end = min((i + 1) * batch_len, length)
        if start != end:
            yield tuple(sliceable_set[start:end])
    raise StopIteration


def include_hostnames(nmap_host):
    """
        Function to filter out hosts with hostnames
    """
    if nmap_host.hostnames:
        return True
    return False


@classmethod
def _consume_and_drop(cls, notifications):
    """RPC endpoint for useless notification level"""


@staticmethod
def AccessToCSV(accessArray, outputFilename):
    """

        Writes access to a CSV file.

        Parameters:
            accessArray (list): List of all access times.
            outputFilename (str): Name of the csv file to be written.

        """
    outputFile = open(outputFilename, 'w')
    for i in range(len(accessArray)):
        for n in range(len(accessArray[i])):
            if n == len(accessArray[i]) - 1:
                delimiter = '\n'
            else:
                delimiter = ','
            outputFile.write(str(accessArray[i][n]) + delimiter)
    outputFile.close()


def _add_doc(func, doc):
    """Add documentation to a function."""
    func.__doc__ = doc


def default_tool_type():
    """ Returns the default type of tool, valid for this installation"""


def remove_matching_braces(latex):
    """
    If `latex` is surrounded by matching braces, remove them. They are not
    necessary.

    Parameters
    ----------
    latex : string

    Returns
    -------
    string

    Examples
    --------
    >>> remove_matching_braces('{2+2}')
    '2+2'
    >>> remove_matching_braces('{2+2')
    '{2+2'
    """
    if latex.startswith('{') and latex.endswith('}'):
        opened = 1
        matches = True
        for char in latex[1:-1]:
            if char == '{':
                opened += 1
            elif char == '}':
                opened -= 1
            if opened == 0:
                matches = False
        if matches:
            latex = latex[1:-1]
    return latex


@classmethod
def clear_all_releases_cache(cls):
    """Clear up Release cache."""
    cls._all_releases = None


def glIndex(c: 'Buffer'):
    """Set the current color index

    :param c: Specifies a pointer to a one element array that contains the new value for the current color index.
    :type c: 'Buffer'
    """
    pass


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

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

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


def split_str(string):
    """Split string in half to return two strings"""
    split = string.split(' ')
    return ' '.join(split[:len(split) // 2]), ' '.join(split[len(split) // 2:])


@staticmethod
def _require_callback(callback):
    """Require that callback is callable and is not None

        :raises: TypeError

        """
    if not callable(callback):
        raise TypeError('Callback must be callable, but got %r' % (callback,))


def __pickle_method__(m):
    """
    Pickling override for using pickle with instance methods.
    """
    if m.__self__ is None:
        return getattr, (m.__self__.__class__, m.__func__.__name__)
    else:
        return getattr, (m.__self__, m.__func__.__name__)


def shallow_copy(vtk_object):
    """Create a shallow copy of a given `vtkObject` object."""
    copy = vtk_object.NewInstance()
    copy.ShallowCopy(vtk_object)
    return copy


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

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


def slice_axis(data, axis, begin, end):
    """Slice along a given axis.
    Returns an array slice along a given axis starting from :attr:`begin` index to :attr:`end` index.

    Parameters
    ----------
    data : Tensor
        The data tensor.
    axis : int
        The axis along to slice the tensor.
    begin : int
        Indicates the begin index.
    end : int
        Indicates the end index.
    Returns:
    --------
    Tensor
        The sliced tensor.
    """
    pass


def _default_interface():
    """Return the default interface name for common operating systems."""
    import platform
    system = platform.system()
    if system == 'Linux':
        return 'eth0'
    elif system == 'Darwin':
        return 'en0'
    return None


def split_text_in_three(text, start_line, start_chr, end_line, end_chr):
    """Split the text in three using 2 (line, column) control points"""
    lines = text.split('\n')
    before = '\n'.join(lines[:start_line] + [lines[start_line][:start_chr]])
    if start_line == end_line:
        excerpt = lines[start_line][start_chr:end_chr]
    else:
        excerpt = '\n'.join([lines[start_line][start_chr:]] + ['\n'.join(
            lines[start_line + 1:end_line])] + [lines[end_line][:end_chr]])
    after = '\n'.join([lines[end_line][end_chr:]] + lines[end_line + 1:])
    return before, excerpt, after


def _migrate_files_project(client):
    """Ensure dataset files have correct project."""
    for dataset in client.datasets.values():
        for file_ in dataset.files:
            file_._project = dataset._project
        dataset.to_yaml()


def parse_type_encoding(encoding):
    """Takes a type encoding string and outputs a list of the separated type codes.
    Currently does not handle unions or bitfields and strips out any field width
    specifiers or type specifiers from the encoding.  For Python 3.2+, encoding is
    assumed to be a bytes object and not unicode.

    Examples:
    parse_type_encoding('^v16@0:8') --> ['^v', '@', ':']
    parse_type_encoding('{CGSize=dd}40@0:8{CGSize=dd}16Q32') --> ['{CGSize=dd}', '@', ':', '{CGSize=dd}', 'Q']
    """
    type_encodings = []
    brace_count = 0
    bracket_count = 0
    typecode = b''
    for c in encoding:
        if isinstance(c, int):
            c = bytes([c])
        if c == b'{':
            if typecode and typecode[-1:
                ] != b'^' and brace_count == 0 and bracket_count == 0:
                type_encodings.append(typecode)
                typecode = b''
            typecode += c
            brace_count += 1
        elif c == b'}':
            typecode += c
            brace_count -= 1
            assert brace_count >= 0
        elif c == b'[':
            if typecode and typecode[-1:
                ] != b'^' and brace_count == 0 and bracket_count == 0:
                type_encodings.append(typecode)
                typecode = b''
            typecode += c
            bracket_count += 1
        elif c == b']':
            typecode += c
            bracket_count -= 1
            assert bracket_count >= 0
        elif brace_count or bracket_count:
            typecode += c
        elif c in b'0123456789':
            pass
        elif c in b'rnNoORV':
            pass
        elif c in b'^cislqCISLQfdBv*@#:b?':
            if typecode and typecode[-1:] == b'^':
                typecode += c
            else:
                if typecode:
                    type_encodings.append(typecode)
                typecode = c
    if typecode:
        type_encodings.append(typecode)
    return type_encodings


def note_frequency(note, sharp=0, flat=0, octave=4, scientific=False):
    """
    Returns the frequency (in hertzs) associated to a given note.

    All the frequencies are based on the standard concert pitch or standard
    piano key frequencies, meaning that A4 (using scientific picth notation)
    is at 440 hertzs.

    Parameters
    ----------
    note : string
        Note to calculate the associated frequency from. Valid notes are
        characters from A to G.
    octave : int
        Octave position. Middle C and A440 being in the 4th octave.
    sharp : int
        Return a frequency higher in pitch by `sharp` semitones.
    flat : int
        Return a frequency lower in pitch by `flat` semitones.
    scientific : bool
        Use scientific pitch instead: C4 is set to 256 Hz.

    Returns
    -------
    float
        The frequency (in hertzs) associated to the given note.
    """
    if note not in list('ABCDEFG'):
        raise ValueError('Invalid note {}'.format(note))
    if sharp and flat:
        raise ValueError('Cannot set both sharp and flat parameters!')
    position = dict(C=0, D=2, E=4, F=5, G=7, A=9, B=11)
    if scientific:
        base_note = 'C'
        base_octave = 4
        base_frequency = 256.0
    else:
        base_note = 'A'
        base_octave = 4
        base_frequency = 440.0
    note_position = position[note] - position[base_note] + (octave -
        base_octave) * 12
    note_position += sharp
    note_position -= flat
    frequency = 2 ** (note_position / 12.0) * base_frequency
    return frequency


@classmethod
def get_importers(cls):
    """ Returns a tuple of currently active importers in use for the
        framework.

        """
    return tuple(cls.__importers)


@classmethod
def seasons(cls, title):
    """
        Returns basic season info for a show.

        :param title: Either the slug (i.e. the-walking-dead) or TVDB ID
        """
    return cls._get('show/seasons', title)


def sql_flush(style, connection, only_django=False, reset_sequences=True,
    allow_cascade=False):
    """
    Returns a list of the SQL statements used to flush the database.

    If only_django is True, then only table names that have associated Django
    models and are in INSTALLED_APPS will be included.
    """
    if only_django:
        tables = connection.introspection.django_table_names(only_existing=True
            )
    else:
        tables = connection.introspection.table_names()
    seqs = connection.introspection.sequence_list() if reset_sequences else ()
    statements = connection.ops.sql_flush(style, tables, seqs, allow_cascade)
    return statements


def transform_list(coords, matrix):
    """ Apply transformation to a list of coordinates. """
    return matrix.dot(coords.T).T


def getKnownGroupEffects(fulldata, batchfilename):
    """ Check the input file for KNOWN possible group effects
    Exclude those that may not exist such as TREATMENT. Make no
    assumptions about order or sorting. Return list in arbitrary
    order. Independent of list provided by the user
    """
    foundColumns = list()
    listOneHotEncoded = list()
    if batchfilename == False:
        print('Using prechosen batch effect names')
        currentPossibleColumnEffects = ['TREATMENT', 'MOUSE', 'SEX', 'DATE',
            'NODEID']
        allColumns = fulldata.columns.values
        listOneHotEncoded = ['MOUSE']
        foundColumns = list(set(allColumns) & set(currentPossibleColumnEffects)
            )
    else:
        foundColumnsCombined = list()
        with open(batchfilename) as f:
            tempColumns = f.read().splitlines()
            for effect in tempColumns:
                foundColumnsCombined.append(effect)
            for ipair in foundColumnsCombined:
                name, typeEnc = ipair.strip().split(' ')
                foundColumns.append(name)
                if typeEnc == 'ONEHOT':
                    listOneHotEncoded.append(name)
    print('Number of Possible batch effects found/specified is ' + str(len(
        foundColumns)))
    print('Number of groupeffect columns in data is ' + str(foundColumns))
    return foundColumns, listOneHotEncoded


@classmethod
def get_oauthlib_core(cls):
    """
        Cache and return `OAuthlibCore` instance so it will be created only on first request
        """
    if not hasattr(cls, '_oauthlib_core'):
        server = cls.get_server()
        core_class = cls.get_oauthlib_backend_class()
        cls._oauthlib_core = core_class(server)
    return cls._oauthlib_core


@staticmethod
def getBinDir(virtualenvDirectory):
    """
            getBinDir - Gets the "bin" dir of a virtualenv
                i.e. the directory that contains executables.

            NOTE: This is overridden on import with the platform-specific version.

            @param virtualenvDirectory <str> - The path to the root directory of the virtualenv

            @return <str> - Path to the "bin" directory of the virtualenv
        """
    raise NotImplementedError(
        'getBinDir should have been overridden by platform-specific version.')


def payment_receipt_print(text):
    """Prints the payment receipt text

        @param text: text to be printed
        """


def couple_to_string(couple):
    """Return a deduplicated string representation of the given couple."""
    if couple[0] == couple[1]:
        return str(couple[0])
    else:
        return f'{couple[0]}-{couple[1]}'


def describe_product_view(AcceptLanguage=None, Id=None):
    """
    Retrieves information about a specified product.
    This operation is functionally identical to  DescribeProduct except that it takes as input ProductViewId instead of ProductId .
    See also: AWS API Documentation

    :example: response = client.describe_product_view(
        AcceptLanguage='string',
        Id='string'
    )

    :type AcceptLanguage: string
    :param AcceptLanguage: The language code to use for this operation. Supported language codes are as follows:
            'en' (English)
            'jp' (Japanese)
            'zh' (Chinese)
            If no code is specified, 'en' is used as the default.

    :type Id: string
    :param Id: [REQUIRED]
            The ProductViewId of the product to describe.

    :rtype: dict
    :return: {
        'ProductViewSummary': {
            'Id': 'string',
            'ProductId': 'string',
            'Name': 'string',
            'Owner': 'string',
            'ShortDescription': 'string',
            'Type': 'CLOUD_FORMATION_TEMPLATE',
            'Distributor': 'string',
            'HasDefaultPath': True|False,
            'SupportEmail': 'string',
            'SupportDescription': 'string',
            'SupportUrl': 'string'
        },
        'ProvisioningArtifacts': [
            {
                'Id': 'string',
                'Name': 'string',
                'Description': 'string',
                'CreatedTime': datetime(2015, 1, 1)
            },
        ]
    }

    """
    pass


def channel_is_superelevated(z, riv, behind, channel_depth, super_ratio,
    sea_level):
    """Check if a channel location is super-elevated.

    Parameters
    ----------
    z : ndarray
        2D-array of elevations.
    sub : tuple of int
        Row-column subscripts into *z*.
    channel_depth : float
        The depth of the channel.
    super_ratio : float
        Ratio of bankfull elevation to out-of-channel elevation for
        channel to be super-elevated.

    Returns
    -------
    boolean
        `True` if channel is super-elevated. Otherwise, `False`.
    """
    superelev = 0
    z_bankfull = z[riv] + channel_depth
    if behind[0] + 1 == riv[0]:
        if riv[1] == 0:
            adj1 = z[riv[0], riv[1] + 1]
            adj2 = z[riv[0], riv[1] + 1]
        elif riv[1] == z.shape[1] - 1:
            adj1 = z[riv[0], riv[1] - 1]
            adj2 = z[riv[0], riv[1] - 1]
        else:
            adj1, adj2 = z[riv[0], riv[1] - 1], z[riv[0], riv[1] + 1]
    if behind[0] == riv[0]:
        if riv[0] == z.shape[0] - 1:
            adj1 = z[riv[0] + 1, riv[1]]
            adj2 = z[riv[0] + 1, riv[1]]
        else:
            adj1, adj2 = z[riv[0] + 1, riv[1]], z[riv[0] - 1, riv[1]]
    threshold = super_ratio * channel_depth
    if adj1 < sea_level and adj2 < sea_level:
        superelev = 0
    elif adj1 < sea_level:
        if z_bankfull - adj2 >= threshold:
            superelev = 1
    elif adj2 < sea_level:
        if z_bankfull - adj1 >= threshold:
            superelev = 1
    elif (z_bankfull - adj2 or z_bankfull - adj1) >= threshold:
        superelev = 1
    return superelev


@staticmethod
def create(token, repository, title, body=''):
    """
        Create a new issue in repository.
        """
    raise NotImplementedError


@classmethod
def validate(cls, name, config, admin=None, users=None, task=None):
    """Semantic check of benchmark arguments."""
    if cls.meta(name, 'admin_only') is True:
        print('Admin Access')
    if cls.meta(name, 'operator') is True:
        print('Operator')


def model_to_dict(instance):
    """
    serializes a model.object to dict, including non editable fields as well as
    ManyToManyField fields
    """
    field_dicts = []
    for x in instance._meta.get_fields():
        f_type = '{}'.format(type(x))
        field_dict = {'name': x.name, 'help_text': getattr(x, 'help_text', '')}
        try:
            field_dict['extra_fields'] = x.extra
        except AttributeError:
            field_dict['extra_fields'] = None
        if 'reverse_related' in f_type:
            values = getattr(instance, x.name, None)
            if values is not None:
                field_dict['value'] = values.all()
            else:
                field_dict['value'] = []
            if getattr(x, 'related_name', None) is not None:
                field_dict['verbose_name'] = getattr(x, 'related_name', x.name)
            else:
                field_dict['verbose_name'] = getattr(x, 'verbose_name', x.name)
            field_dict['f_type'] = 'REVRESE_RELATION'
        elif 'related.ForeignKey' in f_type:
            field_dict['verbose_name'] = getattr(x, 'verbose_name', x.name)
            field_dict['value'] = getattr(instance, x.name, '')
            field_dict['f_type'] = 'FK'
        elif 'TreeForeignKey' in f_type:
            field_dict['verbose_name'] = getattr(x, 'verbose_name', x.name)
            field_dict['value'] = getattr(instance, x.name, '')
            field_dict['f_type'] = 'FK'
        elif 'related.ManyToManyField' in f_type:
            values = getattr(instance, x.name, None)
            if values is not None:
                field_dict['value'] = values.all()
            else:
                field_dict['value'] = []
            field_dict['verbose_name'] = getattr(x, 'verbose_name', x.name)
            field_dict['f_type'] = 'M2M'
        elif 'fields.DateTimeField' in f_type:
            field_value = getattr(instance, x.name, '')
            field_dict['verbose_name'] = getattr(x, 'verbose_name', x.name)
            field_dict['f_type'] = 'DateTime'
            if field_value:
                field_dict['value'] = field_value.strftime('%Y-%m-%d %H:%M:%S')
        else:
            field_dict['verbose_name'] = getattr(x, 'verbose_name', x.name)
            field_dict['value'] = f"{getattr(instance, x.name, '')}"
            field_dict['f_type'] = 'SIMPLE'
        field_dicts.append(field_dict)
    return field_dicts


def p_ExtendedAttributes_empty(p):
    """ExtendedAttributes : """
    p[0] = []


def _minus(lhs=None, rhs=None, name=None, attr=None, out=None, **kwargs):
    """Subtracts arguments element-wise.

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

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

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

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

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


def similarity_args_unpack(args, ignore_abundance, downsample):
    """Helper function to unpack the arguments. Written to use in pool.imap
    as it can only be given one argument."""
    sig1, sig2 = args
    return sig1.similarity(sig2, ignore_abundance=ignore_abundance,
        downsample=downsample)


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


def minimum(rule, artifact):
    """Evaluate artifact's value to be minimum of values returned by rule's
    subrules.

    This evaluation function ignores subrule weights.
    """
    m = 1.0
    for i in range(len(rule.R)):
        e = rule.R[i](artifact)
        if e is not None:
            if e < m:
                m = e
    return m


def _parse_idxref_index_origin(lp_file_lines):
    """Parse the LP file for the possible index origin etc."""
    origins = {}
    i = 0
    while i < len(lp_file_lines):
        line = lp_file_lines[i]
        i += 1
        if 'INDEX_' in line and 'QUALITY' in line and 'DELTA' in line:
            while not 'SELECTED' in line:
                line = lp_file_lines[i]
                i += 1
                try:
                    hkl = tuple(map(int, line.split()[:3]))
                    quality, delta, xd, yd = tuple(map(float, line.split()[
                        3:7]))
                    origins[hkl] = quality, delta, xd, yd
                except Exception:
                    pass
            return origins
    raise RuntimeError('should never reach this point')


def default_payment_handler(request, order_form, order):
    """
    Default payment handler - called when the final step of the
    checkout process with payment information is submitted. Implement
    your own and specify the path to import it from via the setting
    ``SHOP_HANDLER_PAYMENT``. This function will typically contain
    integration with a payment gateway. Raise
    cartridge.shop.checkout.CheckoutError("error message") if payment
    is unsuccessful.
    """
    pass


def hazard_id(value):
    """
    >>> hazard_id('')
    ()
    >>> hazard_id('-1')
    (-1,)
    >>> hazard_id('42')
    (42,)
    >>> hazard_id('42,3')
    (42, 3)
    >>> hazard_id('42,3,4')
    (42, 3, 4)
    >>> hazard_id('42:3')
    Traceback (most recent call last):
       ...
    ValueError: Invalid hazard_id '42:3'
    """
    if not value:
        return ()
    try:
        return tuple(map(int, value.split(',')))
    except Exception:
        raise ValueError('Invalid hazard_id %r' % value)


def p_allow_deny_ignore_params_scope_ctxt(p):
    """ allow_deny_ignore_params_scope_ctxt : UNKNOWN_CLIENTS
                                            | BOOTP
                                            | BOOTING
                                            | DECLINES
    """
    p[0] = p[1]


@staticmethod
def _cert_names_sort(e):
    """
        Sorting parameter for certificates
        :param e:
        :type e: TokenRecord
        :return:
        """
    return e.priority


def padl(text, n, c):
    """
    left pad of text with character c
    """
    text = str(text)
    return str(c) * (n - len(text)) + text


def sync():
    """
        shift outgoing things to incoming things, clearing incoming things
        """


def pop_execute_query_kwargs(keyword_arguments):
    """ pop the optional execute query arguments from arbitrary kwargs;
        return non-None query kwargs in a dict
    """
    query_kwargs = {}
    for key in ('transaction', 'isolate', 'pool'):
        val = keyword_arguments.pop(key, None)
        if val is not None:
            query_kwargs[key] = val
    return query_kwargs


def format_weather(weather_dict):
    """Make the weather pretty for the terminal

    Args:
        weather_dict (dict): Dict with an api response
        from the forcast.io api

    Returns: String summarizing the current weather
    """
    return u'Currently: {} - {}'.format(weather_dict['daily']['icon'],
        weather_dict['daily']['summary'])


@classmethod
def canonical_record_name(cls, record_name, domain_name):
    """
        Strip the domain name from the record name, as Alwaysdata expects name ``foo.bar`` when
        adding the ``foo.bar.domain.com`` record.

        :param str record_name: the full record name
        :param str domain_name: the domain name managing the DNS record
        """
    return record_name[:record_name.rindex('.' + domain_name)]


@staticmethod
def get_connection_type():
    """
        This is needed so the build system knows what
        connection type this connection is considered.
        return::str The socket type of this connection.
        """
    return 'publisher'


@classmethod
def create(cls, netlink, ip_range=None, netlink_role='active'):
    """
        Create a multilink member. Multilink members are added to an
        Outbound Multilink configuration and define the ip range, static
        netlink to use, and the role. This element can be passed to the
        Multilink constructor to simplify creation of the outbound multilink.

        :param StaticNetlink,DynamicNetlink netlink: static netlink element to
            use as member
        :param str ip_range: the IP range for source NAT for this member. The
            IP range should be part of the defined network range used by this
            netlink. Not required for dynamic netlink
        :param str netlink_role: role of this netlink, 'active' or 'standby'
        :raises ElementNotFound: Specified netlink could not be found
        :rtype: MultilinkMember
        """
    member_def = dict(netlink_ref=netlink.href, netlink_role=netlink_role,
        ip_range=ip_range if netlink.typeof == 'netlink' else '0.0.0.0')
    if netlink.typeof == 'netlink':
        member_def.update(network_ref=netlink.network[0].href)
    return cls(member_def)


def generic_duple_range(start, end, step):
    """
    Sort of like range(), but it supports anything where you can check
    if start < end and do start += step.

    Also returns each value + the next value
    """
    while start < end:
        next = start + step
        yield start, next
        start = next


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

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


def rl_testrule(x):
    """
    Rule for tests. Do nothing.
    """
    return x


def edges(ax, **kw):
    """
    Plot regular edges and rays (edges whose one endpoint is at infinity)
    """
    verts = kw['vertices']
    edges = kw['edges']
    for beg, end in edges:
        x0, y0 = verts[(beg), :]
        x1, y1 = verts[(end), :]
        ax.fill([x0, x1], [y0, y1], facecolor='none', edgecolor='k',
            linewidth=0.5)
    if 'ray_origins' not in kw or 'ray_directions' not in kw:
        return
    lim = ax.axis()
    ray_origin = kw['ray_origins']
    ray_direct = kw['ray_directions']
    for beg, (vx, vy) in zip(ray_origin.flatten(), ray_direct):
        x0, y0 = verts[(beg), :]
        scale = 100.0
        x1, y1 = x0 + scale * vx, y0 + scale * vy
        ax.fill([x0, x1], [y0, y1], facecolor='none', edgecolor='k',
            linewidth=0.5)
    ax.axis(lim)


def delta_encode(in_array):
    """A function to delta decode an int array.

    :param in_array: the inut array to be delta encoded
    :return the encoded integer array"""
    if len(in_array) == 0:
        return []
    curr_ans = in_array[0]
    out_array = [curr_ans]
    for in_int in in_array[1:]:
        out_array.append(in_int - curr_ans)
        curr_ans = in_int
    return out_array


def qual_chars2nums(qual_chars, qual_format):
    """
    This converts the phred qualities from the ASCII format to numbers.

    :param qual_chars: phred score in ASCII format (str).
    :param qual_format: phred score in numbers (list).
    """
    qual_nums = []
    for char in qual_chars.rstrip('\n'):
        qual_nums.append(ord(char) - qual_format)
    return qual_nums


def define(hub):
    """
    Return the definition used by the runtime to insert the conditions of the
    given requisite
    """
    return {'result': [True, None]}


@staticmethod
def __add_match_list(match_list, match_str, front_chars=list(), end_chars=
    list()):
    """
        将匹配参数添加到匹配列表，函数需判断重复，若重复则不添加

        @param {dict} match_list - 要检索的匹配字符清单字典，格式 @see FormulaTool/match_list
        @param {string} match_str - 匹配字符串
        @param {string[]} front_chars=list() - 前置字符列表，@see FormulaTool/match_list
        @param {string[]} end_chars=list() - 后置字符列表，@see FormulaTool/match_list

        """
    if match_str not in match_list.keys():
        match_list[match_str] = front_chars, end_chars
    else:
        _front_chars = match_list[match_str][0]
        _end_chars = match_list[match_str][1]
        if front_chars is None or len(front_chars) == 0:
            _front_chars.append('\\*')
        else:
            _front_chars.extend(front_chars)
        if end_chars is None or len(end_chars) == 0:
            _end_chars.append('\\*')
        else:
            _end_chars.extend(end_chars)
        match_list[match_str] = list(set(_front_chars)), list(set(_end_chars))


@classmethod
def client_factory_kwargs(cls, instance):
    """
        Return keyword arguments for the client_factory.

        Method should be derived and modified, A dictionary may be substituted.
        The default return value is an empty dictionary.

        :rtype dict
        """
    return dict()


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


def utf_8_encoder(unicode_csv_data):
    """
    Work around for csv module's utf-8 issues.

    See: https://docs.python.org/2.7/library/csv.html
    """
    for line in unicode_csv_data:
        yield line.encode('utf-8')


@classmethod
def build_from_edge_label_tuples(cls, tuples, additional_labels=None
    ) ->'Graph':
    """
        Build a graph from a iterator of edge label tuples.
        """
    graph = cls()
    graph._init_label_to_node(tuples, additional_labels)
    return graph


def parse_bool(val):
    """Parse a bool value.

    Handles a series of values, but you should probably standardize on
    "true" and "false".

    >>> parse_bool('y')
    True
    >>> parse_bool('FALSE')
    False

    """
    true_vals = 't', 'true', 'yes', 'y', '1', 'on'
    false_vals = 'f', 'false', 'no', 'n', '0', 'off'
    val = val.lower()
    if val in true_vals:
        return True
    if val in false_vals:
        return False
    raise ValueError('"%s" is not a valid bool value' % val)


def log_ip_flow(from_ip, to_ip, prediction, proba):
    """
        Log the ip flow information

        Args:
            out_info - a Zip object containing:
                from_ip    - pandas series
                to_ip list - pandas series
                prediction - np array of prediction
                proba      - np array of pred probabilities

        Returns:
            Return the output buffer for writing to files
    """
    src = f'Src IP: {from_ip}'
    dst = f'Dst IP: {to_ip}'
    pred = f"Prediction: {'Malicious' if prediction else 'Safe'}"
    prob = f'Probabilities:'
    safe = f' - Safe - {proba[0] * 100:.2f}%'
    mal = f' - Malicious - {proba[1] * 100:.2f}%'
    print('---IP---')
    print(src)
    print(dst)
    print(pred)
    print(prob)
    print(safe)
    print(mal)
    print('--------')
    return '---IP BLOCK---', src, dst, pred, prob, safe, mal, '--------'


def str_to_bool(value):
    """
	False and 'False' => False
	otherwise => True
	"""
    return bool(value) and value.lower() != 'false'


@classmethod
def selector(C, style):
    """return the selector for the given stylemap style"""
    clas = C.classname(style.name)
    if style.type == 'paragraph':
        outlineLvl = int((style.properties.get('outlineLvl') or {}).get(
            'val') or 8) + 1
        if outlineLvl < 9:
            tag = 'h%d' % outlineLvl
        else:
            tag = 'p'
    elif style.type == 'character':
        tag = 'span'
    elif style.type == 'table':
        tag = 'table'
    elif style.type == 'numbering':
        tag = 'ol'
    return '%s.%s' % (tag, clas)


@classmethod
def _value_encode(cls, member, value):
    """
        Internal method used to encode values into the hash.

        :param member: str
        :param value: multi
        :return: bytes
        """
    try:
        field_validator = cls.fields[member]
    except KeyError:
        return cls.valueparse.encode(value)
    return field_validator.encode(value)


def calc_delta(a, max_val):
    """
    Calculates ideal Delta value for an A value < 1 and for a desired absoulte
    max value of the integrator

    Parameters
    ----------
    a : float
        'A' decay cte value, where 0 < A < 1
    max_val : Desired absolute max value that the integrator can have

    Returns
    -------
    integer
        Delta value archieve the desired constrain of keeping the integrator
        absolute value below of max_val

    """
    if a <= 0 or a >= 1:
        raise Exception('Invalid A value %f. Must be 0 < A < 1.' % a, a)
    if max_val <= 0:
        raise Exception('Invalid max_val value %d. Must be > 0' % max_val,
            max_val)
    return max_val * (1 - a)


@staticmethod
def _wrap_encode_items(items):
    """Return `items` encoded as bytes.

        Parameters
        ----------
        items : list of PDU items
            The items to encode.

        Returns
        -------
        bytes
            The encoded items.
        """
    bytestream = bytes()
    for item in items:
        bytestream += item.encode()
    return bytestream


def update_domain_contact(DomainName=None, AdminContact=None,
    RegistrantContact=None, TechContact=None):
    """
    This operation updates the contact information for a particular domain. Information for at least one contact (registrant, administrator, or technical) must be supplied for update.
    If the update is successful, this method returns an operation ID that you can use to track the progress and completion of the action. If the request is not completed successfully, the domain registrant will be notified by email.
    See also: AWS API Documentation

    :example: response = client.update_domain_contact(
        DomainName='string',
        AdminContact={
            'FirstName': 'string',
            'LastName': 'string',
            'ContactType': 'PERSON'|'COMPANY'|'ASSOCIATION'|'PUBLIC_BODY'|'RESELLER',
            'OrganizationName': 'string',
            'AddressLine1': 'string',
            'AddressLine2': 'string',
            'City': 'string',
            'State': 'string',
            'CountryCode': 'AD'|'AE'|'AF'|'AG'|'AI'|'AL'|'AM'|'AN'|'AO'|'AQ'|'AR'|'AS'|'AT'|'AU'|'AW'|'AZ'|'BA'|'BB'|'BD'|'BE'|'BF'|'BG'|'BH'|'BI'|'BJ'|'BL'|'BM'|'BN'|'BO'|'BR'|'BS'|'BT'|'BW'|'BY'|'BZ'|'CA'|'CC'|'CD'|'CF'|'CG'|'CH'|'CI'|'CK'|'CL'|'CM'|'CN'|'CO'|'CR'|'CU'|'CV'|'CX'|'CY'|'CZ'|'DE'|'DJ'|'DK'|'DM'|'DO'|'DZ'|'EC'|'EE'|'EG'|'ER'|'ES'|'ET'|'FI'|'FJ'|'FK'|'FM'|'FO'|'FR'|'GA'|'GB'|'GD'|'GE'|'GH'|'GI'|'GL'|'GM'|'GN'|'GQ'|'GR'|'GT'|'GU'|'GW'|'GY'|'HK'|'HN'|'HR'|'HT'|'HU'|'ID'|'IE'|'IL'|'IM'|'IN'|'IQ'|'IR'|'IS'|'IT'|'JM'|'JO'|'JP'|'KE'|'KG'|'KH'|'KI'|'KM'|'KN'|'KP'|'KR'|'KW'|'KY'|'KZ'|'LA'|'LB'|'LC'|'LI'|'LK'|'LR'|'LS'|'LT'|'LU'|'LV'|'LY'|'MA'|'MC'|'MD'|'ME'|'MF'|'MG'|'MH'|'MK'|'ML'|'MM'|'MN'|'MO'|'MP'|'MR'|'MS'|'MT'|'MU'|'MV'|'MW'|'MX'|'MY'|'MZ'|'NA'|'NC'|'NE'|'NG'|'NI'|'NL'|'NO'|'NP'|'NR'|'NU'|'NZ'|'OM'|'PA'|'PE'|'PF'|'PG'|'PH'|'PK'|'PL'|'PM'|'PN'|'PR'|'PT'|'PW'|'PY'|'QA'|'RO'|'RS'|'RU'|'RW'|'SA'|'SB'|'SC'|'SD'|'SE'|'SG'|'SH'|'SI'|'SK'|'SL'|'SM'|'SN'|'SO'|'SR'|'ST'|'SV'|'SY'|'SZ'|'TC'|'TD'|'TG'|'TH'|'TJ'|'TK'|'TL'|'TM'|'TN'|'TO'|'TR'|'TT'|'TV'|'TW'|'TZ'|'UA'|'UG'|'US'|'UY'|'UZ'|'VA'|'VC'|'VE'|'VG'|'VI'|'VN'|'VU'|'WF'|'WS'|'YE'|'YT'|'ZA'|'ZM'|'ZW',
            'ZipCode': 'string',
            'PhoneNumber': 'string',
            'Email': 'string',
            'Fax': 'string',
            'ExtraParams': [
                {
                    'Name': 'DUNS_NUMBER'|'BRAND_NUMBER'|'BIRTH_DEPARTMENT'|'BIRTH_DATE_IN_YYYY_MM_DD'|'BIRTH_COUNTRY'|'BIRTH_CITY'|'DOCUMENT_NUMBER'|'AU_ID_NUMBER'|'AU_ID_TYPE'|'CA_LEGAL_TYPE'|'CA_BUSINESS_ENTITY_TYPE'|'ES_IDENTIFICATION'|'ES_IDENTIFICATION_TYPE'|'ES_LEGAL_FORM'|'FI_BUSINESS_NUMBER'|'FI_ID_NUMBER'|'IT_PIN'|'RU_PASSPORT_DATA'|'SE_ID_NUMBER'|'SG_ID_NUMBER'|'VAT_NUMBER',
                    'Value': 'string'
                },
            ]
        },
        RegistrantContact={
            'FirstName': 'string',
            'LastName': 'string',
            'ContactType': 'PERSON'|'COMPANY'|'ASSOCIATION'|'PUBLIC_BODY'|'RESELLER',
            'OrganizationName': 'string',
            'AddressLine1': 'string',
            'AddressLine2': 'string',
            'City': 'string',
            'State': 'string',
            'CountryCode': 'AD'|'AE'|'AF'|'AG'|'AI'|'AL'|'AM'|'AN'|'AO'|'AQ'|'AR'|'AS'|'AT'|'AU'|'AW'|'AZ'|'BA'|'BB'|'BD'|'BE'|'BF'|'BG'|'BH'|'BI'|'BJ'|'BL'|'BM'|'BN'|'BO'|'BR'|'BS'|'BT'|'BW'|'BY'|'BZ'|'CA'|'CC'|'CD'|'CF'|'CG'|'CH'|'CI'|'CK'|'CL'|'CM'|'CN'|'CO'|'CR'|'CU'|'CV'|'CX'|'CY'|'CZ'|'DE'|'DJ'|'DK'|'DM'|'DO'|'DZ'|'EC'|'EE'|'EG'|'ER'|'ES'|'ET'|'FI'|'FJ'|'FK'|'FM'|'FO'|'FR'|'GA'|'GB'|'GD'|'GE'|'GH'|'GI'|'GL'|'GM'|'GN'|'GQ'|'GR'|'GT'|'GU'|'GW'|'GY'|'HK'|'HN'|'HR'|'HT'|'HU'|'ID'|'IE'|'IL'|'IM'|'IN'|'IQ'|'IR'|'IS'|'IT'|'JM'|'JO'|'JP'|'KE'|'KG'|'KH'|'KI'|'KM'|'KN'|'KP'|'KR'|'KW'|'KY'|'KZ'|'LA'|'LB'|'LC'|'LI'|'LK'|'LR'|'LS'|'LT'|'LU'|'LV'|'LY'|'MA'|'MC'|'MD'|'ME'|'MF'|'MG'|'MH'|'MK'|'ML'|'MM'|'MN'|'MO'|'MP'|'MR'|'MS'|'MT'|'MU'|'MV'|'MW'|'MX'|'MY'|'MZ'|'NA'|'NC'|'NE'|'NG'|'NI'|'NL'|'NO'|'NP'|'NR'|'NU'|'NZ'|'OM'|'PA'|'PE'|'PF'|'PG'|'PH'|'PK'|'PL'|'PM'|'PN'|'PR'|'PT'|'PW'|'PY'|'QA'|'RO'|'RS'|'RU'|'RW'|'SA'|'SB'|'SC'|'SD'|'SE'|'SG'|'SH'|'SI'|'SK'|'SL'|'SM'|'SN'|'SO'|'SR'|'ST'|'SV'|'SY'|'SZ'|'TC'|'TD'|'TG'|'TH'|'TJ'|'TK'|'TL'|'TM'|'TN'|'TO'|'TR'|'TT'|'TV'|'TW'|'TZ'|'UA'|'UG'|'US'|'UY'|'UZ'|'VA'|'VC'|'VE'|'VG'|'VI'|'VN'|'VU'|'WF'|'WS'|'YE'|'YT'|'ZA'|'ZM'|'ZW',
            'ZipCode': 'string',
            'PhoneNumber': 'string',
            'Email': 'string',
            'Fax': 'string',
            'ExtraParams': [
                {
                    'Name': 'DUNS_NUMBER'|'BRAND_NUMBER'|'BIRTH_DEPARTMENT'|'BIRTH_DATE_IN_YYYY_MM_DD'|'BIRTH_COUNTRY'|'BIRTH_CITY'|'DOCUMENT_NUMBER'|'AU_ID_NUMBER'|'AU_ID_TYPE'|'CA_LEGAL_TYPE'|'CA_BUSINESS_ENTITY_TYPE'|'ES_IDENTIFICATION'|'ES_IDENTIFICATION_TYPE'|'ES_LEGAL_FORM'|'FI_BUSINESS_NUMBER'|'FI_ID_NUMBER'|'IT_PIN'|'RU_PASSPORT_DATA'|'SE_ID_NUMBER'|'SG_ID_NUMBER'|'VAT_NUMBER',
                    'Value': 'string'
                },
            ]
        },
        TechContact={
            'FirstName': 'string',
            'LastName': 'string',
            'ContactType': 'PERSON'|'COMPANY'|'ASSOCIATION'|'PUBLIC_BODY'|'RESELLER',
            'OrganizationName': 'string',
            'AddressLine1': 'string',
            'AddressLine2': 'string',
            'City': 'string',
            'State': 'string',
            'CountryCode': 'AD'|'AE'|'AF'|'AG'|'AI'|'AL'|'AM'|'AN'|'AO'|'AQ'|'AR'|'AS'|'AT'|'AU'|'AW'|'AZ'|'BA'|'BB'|'BD'|'BE'|'BF'|'BG'|'BH'|'BI'|'BJ'|'BL'|'BM'|'BN'|'BO'|'BR'|'BS'|'BT'|'BW'|'BY'|'BZ'|'CA'|'CC'|'CD'|'CF'|'CG'|'CH'|'CI'|'CK'|'CL'|'CM'|'CN'|'CO'|'CR'|'CU'|'CV'|'CX'|'CY'|'CZ'|'DE'|'DJ'|'DK'|'DM'|'DO'|'DZ'|'EC'|'EE'|'EG'|'ER'|'ES'|'ET'|'FI'|'FJ'|'FK'|'FM'|'FO'|'FR'|'GA'|'GB'|'GD'|'GE'|'GH'|'GI'|'GL'|'GM'|'GN'|'GQ'|'GR'|'GT'|'GU'|'GW'|'GY'|'HK'|'HN'|'HR'|'HT'|'HU'|'ID'|'IE'|'IL'|'IM'|'IN'|'IQ'|'IR'|'IS'|'IT'|'JM'|'JO'|'JP'|'KE'|'KG'|'KH'|'KI'|'KM'|'KN'|'KP'|'KR'|'KW'|'KY'|'KZ'|'LA'|'LB'|'LC'|'LI'|'LK'|'LR'|'LS'|'LT'|'LU'|'LV'|'LY'|'MA'|'MC'|'MD'|'ME'|'MF'|'MG'|'MH'|'MK'|'ML'|'MM'|'MN'|'MO'|'MP'|'MR'|'MS'|'MT'|'MU'|'MV'|'MW'|'MX'|'MY'|'MZ'|'NA'|'NC'|'NE'|'NG'|'NI'|'NL'|'NO'|'NP'|'NR'|'NU'|'NZ'|'OM'|'PA'|'PE'|'PF'|'PG'|'PH'|'PK'|'PL'|'PM'|'PN'|'PR'|'PT'|'PW'|'PY'|'QA'|'RO'|'RS'|'RU'|'RW'|'SA'|'SB'|'SC'|'SD'|'SE'|'SG'|'SH'|'SI'|'SK'|'SL'|'SM'|'SN'|'SO'|'SR'|'ST'|'SV'|'SY'|'SZ'|'TC'|'TD'|'TG'|'TH'|'TJ'|'TK'|'TL'|'TM'|'TN'|'TO'|'TR'|'TT'|'TV'|'TW'|'TZ'|'UA'|'UG'|'US'|'UY'|'UZ'|'VA'|'VC'|'VE'|'VG'|'VI'|'VN'|'VU'|'WF'|'WS'|'YE'|'YT'|'ZA'|'ZM'|'ZW',
            'ZipCode': 'string',
            'PhoneNumber': 'string',
            'Email': 'string',
            'Fax': 'string',
            'ExtraParams': [
                {
                    'Name': 'DUNS_NUMBER'|'BRAND_NUMBER'|'BIRTH_DEPARTMENT'|'BIRTH_DATE_IN_YYYY_MM_DD'|'BIRTH_COUNTRY'|'BIRTH_CITY'|'DOCUMENT_NUMBER'|'AU_ID_NUMBER'|'AU_ID_TYPE'|'CA_LEGAL_TYPE'|'CA_BUSINESS_ENTITY_TYPE'|'ES_IDENTIFICATION'|'ES_IDENTIFICATION_TYPE'|'ES_LEGAL_FORM'|'FI_BUSINESS_NUMBER'|'FI_ID_NUMBER'|'IT_PIN'|'RU_PASSPORT_DATA'|'SE_ID_NUMBER'|'SG_ID_NUMBER'|'VAT_NUMBER',
                    'Value': 'string'
                },
            ]
        }
    )

    :type DomainName: string
    :param DomainName: [REQUIRED]
            The name of the domain that you want to update contact information for.

    :type AdminContact: dict
    :param AdminContact: Provides detailed contact information.
            FirstName (string) --First name of contact.
            LastName (string) --Last name of contact.
            ContactType (string) --Indicates whether the contact is a person, company, association, or public organization. If you choose an option other than PERSON , you must enter an organization name, and you can't enable privacy protection for the contact.
            OrganizationName (string) --Name of the organization for contact types other than PERSON .
            AddressLine1 (string) --First line of the contact's address.
            AddressLine2 (string) --Second line of contact's address, if any.
            City (string) --The city of the contact's address.
            State (string) --The state or province of the contact's city.
            CountryCode (string) --Code for the country of the contact's address.
            ZipCode (string) --The zip or postal code of the contact's address.
            PhoneNumber (string) --The phone number of the contact.
            Constraints: Phone number must be specified in the format '+[country dialing code].[number including any area code]'. For example, a US phone number might appear as '+1.1234567890' .
            Email (string) --Email address of the contact.
            Fax (string) --Fax number of the contact.
            Constraints: Phone number must be specified in the format '+[country dialing code].[number including any area code]'. For example, a US phone number might appear as '+1.1234567890' .
            ExtraParams (list) --A list of name-value pairs for parameters required by certain top-level domains.
            (dict) --ExtraParam includes the following elements.
            Name (string) -- [REQUIRED]Name of the additional parameter required by the top-level domain.
            Value (string) -- [REQUIRED]Values corresponding to the additional parameter names required by some top-level domains.

    :type RegistrantContact: dict
    :param RegistrantContact: Provides detailed contact information.
            FirstName (string) --First name of contact.
            LastName (string) --Last name of contact.
            ContactType (string) --Indicates whether the contact is a person, company, association, or public organization. If you choose an option other than PERSON , you must enter an organization name, and you can't enable privacy protection for the contact.
            OrganizationName (string) --Name of the organization for contact types other than PERSON .
            AddressLine1 (string) --First line of the contact's address.
            AddressLine2 (string) --Second line of contact's address, if any.
            City (string) --The city of the contact's address.
            State (string) --The state or province of the contact's city.
            CountryCode (string) --Code for the country of the contact's address.
            ZipCode (string) --The zip or postal code of the contact's address.
            PhoneNumber (string) --The phone number of the contact.
            Constraints: Phone number must be specified in the format '+[country dialing code].[number including any area code]'. For example, a US phone number might appear as '+1.1234567890' .
            Email (string) --Email address of the contact.
            Fax (string) --Fax number of the contact.
            Constraints: Phone number must be specified in the format '+[country dialing code].[number including any area code]'. For example, a US phone number might appear as '+1.1234567890' .
            ExtraParams (list) --A list of name-value pairs for parameters required by certain top-level domains.
            (dict) --ExtraParam includes the following elements.
            Name (string) -- [REQUIRED]Name of the additional parameter required by the top-level domain.
            Value (string) -- [REQUIRED]Values corresponding to the additional parameter names required by some top-level domains.

    :type TechContact: dict
    :param TechContact: Provides detailed contact information.
            FirstName (string) --First name of contact.
            LastName (string) --Last name of contact.
            ContactType (string) --Indicates whether the contact is a person, company, association, or public organization. If you choose an option other than PERSON , you must enter an organization name, and you can't enable privacy protection for the contact.
            OrganizationName (string) --Name of the organization for contact types other than PERSON .
            AddressLine1 (string) --First line of the contact's address.
            AddressLine2 (string) --Second line of contact's address, if any.
            City (string) --The city of the contact's address.
            State (string) --The state or province of the contact's city.
            CountryCode (string) --Code for the country of the contact's address.
            ZipCode (string) --The zip or postal code of the contact's address.
            PhoneNumber (string) --The phone number of the contact.
            Constraints: Phone number must be specified in the format '+[country dialing code].[number including any area code]'. For example, a US phone number might appear as '+1.1234567890' .
            Email (string) --Email address of the contact.
            Fax (string) --Fax number of the contact.
            Constraints: Phone number must be specified in the format '+[country dialing code].[number including any area code]'. For example, a US phone number might appear as '+1.1234567890' .
            ExtraParams (list) --A list of name-value pairs for parameters required by certain top-level domains.
            (dict) --ExtraParam includes the following elements.
            Name (string) -- [REQUIRED]Name of the additional parameter required by the top-level domain.
            Value (string) -- [REQUIRED]Values corresponding to the additional parameter names required by some top-level domains.

    :rtype: dict
    :return: {
        'OperationId': 'string'
    }

    """
    pass


def get_similarity_difference(similarity, groupby=('ksize', 'alphabet',
    'num_hashes')):
    """Calculate difference in similarity from "true" aka maximum sampling
    similarity

    Parameters
    ----------
    similiarity : pandas.DataFrame
        tidy dataframe with "cell1", "cell2", "similarity" columns,
        plus groupby columns

    """
    CELL_INDEX = ['cell1', 'cell2']
    max_num_hashes = similarity.num_hashes.max()
    true_similarity = similarity.query('num_hashes == @max_num_hashes')
    true_similarity = true_similarity.set_index(CELL_INDEX).sort_index()
    test_similarity = similarity.query('num_hashes != @max_num_hashes')
    test_similarity = test_similarity.set_index(CELL_INDEX).sort_index()
    similarity_difference = test_similarity.groupby(groupby).apply(lambda x:
        x['similarity'].subtract(true_similarity['similarity']))
    similarity_difference = similarity_difference.unstack(level=[0, 1, 2]
        ).reset_index()
    similarity_difference = similarity_difference.rename(columns={(0):
        'similarity_difference'})
    return similarity_difference


@classmethod
def default(cls):
    """Returns a ``Config`` instance with default values for all properties.

        :rtype: ldclient.config.Config
        """
    return cls()


def write_text_list(textfile, a_list):
    """Write list of str to a file with new lines."""
    with open(textfile, 'w') as f:
        f.write('\n'.join(a_list) + '\n')


def is_block_range(start, end):
    """Checks for a valid block number."""
    return start.isdigit() and 0 <= int(start) <= 99999999 and end.isdigit(
        ) and 0 <= int(end) <= 99999999


def stripnull(string):
    """Return string truncated at first null character."""
    i = string.find(b'\x00')
    return string if i < 0 else string[:i]


@staticmethod
def _is_alphanum(word, valid_punctuation_marks='-'):
    """Check if a word is valid, i.e. it contains only alpha-numeric
        characters and valid punctuation marks.

        Args:
            word (string): a word.
            valid_punctuation_marks (str): punctuation marks that are valid
                    for a candidate, defaults to '-'.
        """
    for punct in valid_punctuation_marks.split():
        word = word.replace(punct, '')
    return word.isalnum()


def file_ext(filename):
    """return the file extension, including the ``.``

    >>> file_ext('foo.tar.gz')
    '.tar.gz'

    >>> file_ext('.emacs')
    ''

    >>> file_ext('.mrjob.conf')
    '.conf'
    """
    stripped_name = filename.lstrip('.')
    dot_index = stripped_name.find('.')
    if dot_index == -1:
        return ''
    return stripped_name[dot_index:]


def parse_masked(seq, min_len):
    """
    parse masked sequence into non-masked and masked regions
    """
    nm, masked = [[]], [[]]
    prev = None
    for base in seq[1]:
        if base.isupper():
            nm[-1].append(base)
            if masked != [[]] and len(masked[-1]) < min_len:
                nm.extend(masked[-1])
                del masked[-1]
            prev = False
        elif base.islower():
            if prev is False:
                masked.append([])
                nm.append([])
            masked[-1].append(base)
            prev = True
    return nm, masked


def ol(itemList=[]):
    """
    *An ordered list*

    **Key Arguments:**
        - ``itemList`` -- a list of items to be included in the ordered list

    **Return:**
        - ol
    """
    thisList = ''
    for item in itemList:
        if '<li' in item[:5]:
            thisList = '%(thisList)s\n%(item)s' % locals()
        else:
            thisList = '%(thisList)s
%(item)s
\n' % locals()
    ol = ("""

            %(thisList)s

    """ %
        locals())
    return ol


def lookupSchema():
    """Return an InterfaceClass that represents the schema of this type.
        Raises a ValueError if it cannot be found.

        If a schema interface is specified, return this. Otherwise, look up
        the model from either the TTW model source string or a specified
        model XML file, and build a schema from the unnamed schema
        specified in this model.
        """


def bundle1allowed(repo, action):
    """Whether a bundle1 operation is allowed from the server.

    Priority is:

    1. server.bundle1gd.<action> (if generaldelta active)
    2. server.bundle1.<action>
    3. server.bundle1gd (if generaldelta active)
    4. server.bundle1
    """
    ui = repo.ui
    gd = b'generaldelta' in repo.requirements
    if gd:
        v = ui.configbool(b'server', b'bundle1gd.%s' % action)
        if v is not None:
            return v
    v = ui.configbool(b'server', b'bundle1.%s' % action)
    if v is not None:
        return v
    if gd:
        v = ui.configbool(b'server', b'bundle1gd')
        if v is not None:
            return v
    return ui.configbool(b'server', b'bundle1')


@staticmethod
def p_bit_timimg(p):
    """bit_timing : BS_ COLON bit_timing_optional"""
    p[0] = p[3]


def write_info_src(f):
    """
    Preallocate info structure
    """
    f.write('// Define info\n')
    f.write(
        'OSQPInfo info = {0, "Unsolved", OSQP_UNSOLVED, 0.0, 0.0, 0.0};\n\n')


def validation_simple(value, obj=None):
    """
    Validates that at least one character has been entered.
    Not change is made to the value.
    """
    if len(value) >= 1:
        return True, value
    else:
        return False, value


def clean(feed: 'Feed') ->'Feed':
    """
    Apply the following functions to the given Feed in order and return the resulting
    Feed.

    #. :func:`clean_ids`
    #. :func:`clean_times`
    #. :func:`clean_route_short_names`
    #. :func:`drop_zombies`

    """
    feed = feed.copy()
    ops = ['clean_ids', 'clean_times', 'clean_route_short_names',
        'drop_zombies']
    for op in ops:
        feed = globals()[op](feed)
    return feed


@staticmethod
def get_headers(request: dict, body_is_json: bool) ->dict:
    """
        Treat special value 'json' as Content-Type: application/json
        """
    predefined = {'json': {'Content-Type': 'application/json'}}
    if 'headers' in request and isinstance(request['headers'], str):
        for known in predefined:
            if request['headers'].lower() == known:
                return predefined[known]
    result = {}
    for name, val in request.get('headers', {}).items():
        for known in predefined:
            if name.lower() == known:
                result.update(predefined[known])
                break
        else:
            result.update({name: val})
    if body_is_json and 'Content-Type' not in result:
        result.update(predefined['json'])
    return result


@classmethod
def CreateScale(cls, x=1, y=1, z=1):
    """
        Scales this matrix (in-place) by the given amount

        :param x: x-coordinate of the scale (default 1)
        :type x:  ``int`` or ``float``

        :param y: y-coordinate of the scale (default 1)
        :type Y:  ``int`` or ``float``

        :param z: z-coordinate of the scale (default 1)
        :type Z:  ``int`` or ``float``
        """
    result = cls()
    result.scale(x, y, z)
    return result


def create_trail(Name=None, S3BucketName=None, S3KeyPrefix=None,
    SnsTopicName=None, IncludeGlobalServiceEvents=None, IsMultiRegionTrail=
    None, EnableLogFileValidation=None, CloudWatchLogsLogGroupArn=None,
    CloudWatchLogsRoleArn=None, KmsKeyId=None):
    """
    Creates a trail that specifies the settings for delivery of log data to an Amazon S3 bucket. A maximum of five trails can exist in a region, irrespective of the region in which they were created.
    See also: AWS API Documentation

    :example: response = client.create_trail(
        Name='string',
        S3BucketName='string',
        S3KeyPrefix='string',
        SnsTopicName='string',
        IncludeGlobalServiceEvents=True|False,
        IsMultiRegionTrail=True|False,
        EnableLogFileValidation=True|False,
        CloudWatchLogsLogGroupArn='string',
        CloudWatchLogsRoleArn='string',
        KmsKeyId='string'
    )

    :type Name: string
    :param Name: [REQUIRED]
            Specifies the name of the trail. The name must meet the following requirements:
            Contain only ASCII letters (a-z, A-Z), numbers (0-9), periods (.), underscores (_), or dashes (-)
            Start with a letter or number, and end with a letter or number
            Be between 3 and 128 characters
            Have no adjacent periods, underscores or dashes. Names like my-_namespace and my--namespace are invalid.
            Not be in IP address format (for example, 192.168.5.4)

    :type S3BucketName: string
    :param S3BucketName: [REQUIRED]
            Specifies the name of the Amazon S3 bucket designated for publishing log files. See Amazon S3 Bucket Naming Requirements .

    :type S3KeyPrefix: string
    :param S3KeyPrefix: Specifies the Amazon S3 key prefix that comes after the name of the bucket you have designated for log file delivery. For more information, see Finding Your CloudTrail Log Files . The maximum length is 200 characters.

    :type SnsTopicName: string
    :param SnsTopicName: Specifies the name of the Amazon SNS topic defined for notification of log file delivery. The maximum length is 256 characters.

    :type IncludeGlobalServiceEvents: boolean
    :param IncludeGlobalServiceEvents: Specifies whether the trail is publishing events from global services such as IAM to the log files.

    :type IsMultiRegionTrail: boolean
    :param IsMultiRegionTrail: Specifies whether the trail is created in the current region or in all regions. The default is false.

    :type EnableLogFileValidation: boolean
    :param EnableLogFileValidation: Specifies whether log file integrity validation is enabled. The default is false.
            Note
            When you disable log file integrity validation, the chain of digest files is broken after one hour. CloudTrail will not create digest files for log files that were delivered during a period in which log file integrity validation was disabled. For example, if you enable log file integrity validation at noon on January 1, disable it at noon on January 2, and re-enable it at noon on January 10, digest files will not be created for the log files delivered from noon on January 2 to noon on January 10. The same applies whenever you stop CloudTrail logging or delete a trail.

    :type CloudWatchLogsLogGroupArn: string
    :param CloudWatchLogsLogGroupArn: Specifies a log group name using an Amazon Resource Name (ARN), a unique identifier that represents the log group to which CloudTrail logs will be delivered. Not required unless you specify CloudWatchLogsRoleArn.

    :type CloudWatchLogsRoleArn: string
    :param CloudWatchLogsRoleArn: Specifies the role for the CloudWatch Logs endpoint to assume to write to a user's log group.

    :type KmsKeyId: string
    :param KmsKeyId: Specifies the KMS key ID to use to encrypt the logs delivered by CloudTrail. The value can be an alias name prefixed by 'alias/', a fully specified ARN to an alias, a fully specified ARN to a key, or a globally unique identifier.
            Examples:
            alias/MyAliasName
            arn:aws:kms:us-east-1:123456789012:alias/MyAliasName
            arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012
            12345678-1234-1234-1234-123456789012

    :rtype: dict
    :return: {
        'Name': 'string',
        'S3BucketName': 'string',
        'S3KeyPrefix': 'string',
        'SnsTopicName': 'string',
        'SnsTopicARN': 'string',
        'IncludeGlobalServiceEvents': True|False,
        'IsMultiRegionTrail': True|False,
        'TrailARN': 'string',
        'LogFileValidationEnabled': True|False,
        'CloudWatchLogsLogGroupArn': 'string',
        'CloudWatchLogsRoleArn': 'string',
        'KmsKeyId': 'string'
    }

    """
    pass


def iteritems(obj, **kwargs):
    """replacement for six's iteritems for Python2/3 compat
       uses 'iteritems' if available and otherwise uses 'items'.

       Passes kwargs to method.
    """
    func = getattr(obj, 'iteritems', None)
    if not func:
        func = obj.items
    return func(**kwargs)


@classmethod
def _get_apic_classes(cls):
    """
        Get the APIC classes used by this acitoolkit class.

        :returns: list of strings containing APIC class names
        """
    return [cls._get_contract_code()]


@classmethod
def get_output_oriented_model(cls, use_super_efficiency, non_discr_categories):
    """ Returns output-oriented model used in ModelBase.

            Args:
                use_super_efficiency (bool): true if super efficiency model
                    should be created, false otherwise.
                non_discr_categories (list of str): list of non-discretionary
                    categories. If empty, all categories are considered
                    discretionary.

            Returns:
                OutputOrientedModel: allocated output-oriented model.
        """
    raise NotImplementedError()


def convert2boolean(arg):
    """convert2boolean is used for environmental variables
    that must be returned as boolean"""
    if not isinstance(arg, bool):
        return arg.lower() in ('yes', 'true', 't', '1', 'y')
    return arg


def gen_line_cells(data, widths=None, float_precision=4, minimum_cell_width=9):
    """
    Generate the content of the cells for a line in the summary file.

    See gen_line_str (above) for doc.

    Returns
    -------
    cells : List
    new_widths : List

    """
    if widths is None:
        new_widths = []
    else:
        new_widths = widths
    cells = []
    for i, entry in enumerate(data):
        if not isinstance(entry, str):
            entry = format(float(entry), '.' + str(float_precision) + 'g')
        if widths is None:
            cell_width = max(minimum_cell_width, len(entry))
            new_widths.append(cell_width)
        else:
            cell_width = widths[i]
        cell_cont = format(entry, '<' + str(cell_width))
        cells.append(cell_cont)
    return cells, new_widths


def make_drop_list(columns):
    """The canvas exports will have some annoying fields
        These should be added to the droppable list
        If there are columns with a common initial string (e.g., 1.0, 1.0.1, ...) just
        add the common part
    """
    droppable = ['1.', 'Unnamed']
    to_drop = ['n correct', 'n incorrect']
    for c in columns:
        try:
            if float(c):
                to_drop.append(c)
        except ValueError:
            for d in droppable:
                if c[:len(d)] == d:
                    to_drop.append(c)
    return to_drop


def get_intersections(b__, boundaries):
    """Get the intersections of *b__* with *boundaries*.
    Returns both the intersection coordinates and the concerned boundaries.
    """
    intersections = []
    bounds = []
    for other_b in boundaries:
        inter = b__.intersection(other_b)
        if inter is not None:
            intersections.append(inter)
            bounds.append(other_b)
    return intersections, bounds


def createGUI(root):
    """Create the main window
    @param root: main window"""


@classmethod
def from_exception(cls, exception):
    """Creates a failure object from a exception instance."""
    exc_info = type(exception), exception, getattr(exception,
        '__traceback__', None)
    return cls(exc_info=exc_info)


def timestamp_seconds(ts):
    """Returns seconds float from value generated by `timestamp`."""
    return float(ts / 1000000)


def backup_db(db_path):
    """Create a backup of the database file by copying it into clementine_backup.db file

    :param db_path: Path to the database
    :type db_path: string
    :return: None
    """
    print('Backing up database into {0}'.format(db_path))
    raise NotImplementedError


def parse_ffl_number(ffl_number, parse_values=True):
    """
    This take an FFL number a dictionary representation of the appropriate fields
    :param ffl_number: String with the FFL number, this can be in the format of X-XX-XXX-XX-XX-XXXXX or just the string
    :param parse_values: Parse the values as an int or string, int is useful for working in databases
    :return: dict of parsed FFL number
    """
    ffl_number = ffl_number.replace('-', '')
    if len(ffl_number) != 15:
        raise ValueError('Invalid ffl Length: %s for %s' % (len(ffl_number),
            ffl_number))
    if parse_values:
        render = int
    else:
        render = str
    return {'FFLRegion': render(ffl_number[0]), 'FFLDistrict': render(
        ffl_number[1:3]), 'FFLCounty': render(ffl_number[3:6]), 'FFLType':
        render(ffl_number[6:8]), 'FFLExpiration': ffl_number[8:10],
        'FFLSequence': render(ffl_number[10:]), 'FFLNumber': ffl_number}


def call_menu(name: str=''):
    """Call (draw) a pre-defined menu

    :param name: Name, Name of the menu
    :type name: str
    """
    pass


def compareVersions(v1, v2):
    """Compares two ``dcm2niix`` versions ``v1`` and ``v2``.  The versions are
    assumed to be in the format returned by :func:`installedVersion`.

    :returns: - 1 if ``v1`` is newer than ``v2``
              - -1 if ``v1`` is older than ``v2``
              - 0 if ``v1`` the same as ``v2``.
    """
    for iv1, iv2 in zip(v1, v2):
        if iv1 > iv2:
            return 1
        elif iv1 < iv2:
            return -1
    return 0


def _get_str_from_bin(src: bytearray) ->str:
    """Join data in list to the string.

    :param src: source to process
    :type src: bytearray
    :return: decoded string
    :rtype: str
    """
    return src.strip().decode(encoding='utf-8', errors='backslashreplace')


@classmethod
def preload_SAM(cls, h5_path, sites, hub_heights, unscale=True, str_decode=
    True, require_wind_dir=False, precip_rate=False, icing=False, means=False):
    """
        Placeholder for classmethod that will pre-load project_points for SAM

        Parameters
        ----------
        h5_path : str
            Path to directory containing multi-file resource file sets.
            Available formats:
                /h5_dir/
                /h5_dir/prefix*suffix
        sites : list
            List of sites to be provided to SAM
        hub_heights : int | float | list
            Hub heights to extract for SAM
        unscale : bool
            Boolean flag to automatically unscale variables on extraction
        str_decode : bool
            Boolean flag to decode the bytestring meta data into normal
            strings. Setting this to False will speed up the meta data read.
        require_wind_dir : bool
            Boolean flag as to whether wind direction will be loaded.
        precip_rate : bool
            Boolean flag as to whether precipitationrate_0m will be preloaded
        icing : bool
            Boolean flag as to whether icing is analyzed.
            This will preload relative humidity.
        means : bool
            Boolean flag to compute mean resource when res_array is set

        Returns
        -------
        SAM_res : SAMResource
            Instance of SAMResource pre-loaded with Solar resource for sites
            in project_points
        """
    with cls(h5_path, unscale=unscale, str_decode=str_decode) as res:
        SAM_res = res._preload_SAM(sites, hub_heights, require_wind_dir=
            require_wind_dir, precip_rate=precip_rate, icing=icing, means=means
            )
    return SAM_res


@staticmethod
def _vec_2tuple(obj):
    """
        Return a tuple from a list or tuple object.

        :param obj: Object
        :type obj: list, tuple
        :return: Tuple
        :rtype: tuple
        """
    if isinstance(obj, tuple):
        return obj
    elif isinstance(obj, list):
        return obj[0], obj[1]
    else:
        raise ValueError('object is not a 2 vector')


def check_pairwise(a, func):
    """
    Check whether a condition (computed by `func`) holds pairwise for elements
    in the sequence `a`. Assumes `func` is symmetric for the two operands.
    """
    if len(a) < 2:
        return True
    for i, x in enumerate(a, 1):
        for y in a[i:]:
            if not func(x, y):
                return False
    return True


def checkrange(value, lo, hi, msg=''):
    """Check value for membership; raise ValueError if fails."""
    if value < lo or value > hi:
        raise ValueError(f'ERROR {msg}: {value} should be in range {lo} {hi}')


def _print_pgfplot_libs_message(data):
    """Prints message to screen indicating the use of PGFPlots and its
    libraries."""
    pgfplotslibs = ','.join(list(data['pgfplots libs']))
    tikzlibs = ','.join(list(data['tikz libs']))
    print(70 * '=')
    print('Please add the following lines to your LaTeX preamble:\n')
    print('\\usepackage[utf8]{inputenc}')
    print('\\usepackage{fontspec}  % This line only for XeLaTeX and LuaLaTeX')
    print('\\usepackage{pgfplots}')
    if tikzlibs:
        print('\\usetikzlibrary{' + tikzlibs + '}')
    if pgfplotslibs:
        print('\\usepgfplotslibrary{' + pgfplotslibs + '}')
    print(70 * '=')
    return


@staticmethod
def mono(s):
    """
        Format text to be monospaced.

        Args:
            s (str): string to format

        Returns:
            str: formatted string
        """
    return '<pre raw_pre="{{code}}" raw_post="{{code}}">{0}</pre>'.format(s)


@classmethod
def from_api_repr(cls, resource, zone):
    """Factory:  construct a record set given its API representation

        :type resource: dict
        :param resource: record sets representation returned from the API

        :type zone: :class:`gcloud.dns.zone.ManagedZone`
        :param zone: A zone which holds one or more record sets.

        :rtype: :class:`gcloud.dns.zone.ResourceRecordSet`
        :returns: RRS parsed from ``resource``.
        """
    name = resource['name']
    record_type = resource['type']
    ttl = int(resource['ttl'])
    rrdatas = resource['rrdatas']
    return cls(name, record_type, ttl, rrdatas, zone=zone)


def list_get(input_list, index):
    """Get an item from a list and handle out-of bounds errors.

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

    Parameters
    ----------
    input_list : list
        The list to pick from.
    index : integer
        The index to pick.

    """
    try:
        return input_list[index]
    except IndexError:
        return input_list[-1]


def set_contract_backend(backend):
    """Set the default backend used for tensor contractions, via 'opt_einsum'.

    See Also
    --------
    get_contract_backend, set_tensor_linop_backend, get_tensor_linop_backend,
    tensor_contract
    """
    global _CONTRACT_BACKEND
    _CONTRACT_BACKEND = backend


def get_external_stack_name(project_code, stack_name):
    """
    Returns the name given to a stack in CloudFormation.

    :param project_code: The project code, as defined in config.yaml.
    :type project_code: str
    :param stack_name: The name of the stack.
    :type stack_name: str
    :returns: The name given to the stack in CloudFormation.
    :rtype: str
    """
    return '-'.join([project_code, stack_name.replace('/', '-')])


def str_spec(name):
    """ Split into a tuple of name and specifier, delimited by ``{...}``.

    Parameters
    ----------
    name : str
       string to split

    Returns
    -------
    tuple of str
       returns the name and the specifier (without delimiter) in a tuple

    Examples
    --------
    >>> str_spec('hello')
    ('hello', None)
    >>> str_spec('hello{TEST}')
    ('hello', 'TEST')
    """
    if not name.endswith('}'):
        return name, None
    lname = name[:-1].split('{')
    return '{'.join(lname[:-1]), lname[-1]


def stripascii(string):
    """Return string truncated at last byte that is 7-bit ASCII.

    Clean NULL separated and terminated TIFF strings.

    >>> stripascii(b'string\\x00string\\n\\x01\\x00')
    b'string\\x00string\\n'
    >>> stripascii(b'\\x00')
    b''

    """
    i = len(string)
    while i:
        i -= 1
        if 8 < string[i] < 127:
            break
    else:
        i = -1
    return string[:i + 1]


def is_empty_line(text):
    """
    Check if a text is empty or contains only whitespace.

    :param text: The text to check for "emptiness" (a string).
    :returns: :data:`True` if the text is empty or contains only whitespace,
              :data:`False` otherwise.
    """
    return len(text) == 0 or text.isspace()


def mutual_information_calc(response_entropy, conditional_entropy):
    """
    Calculate mutual information.

    :param response_entropy:  response entropy
    :type response_entropy : float
    :param conditional_entropy:  conditional entropy
    :type conditional_entropy : float
    :return: mutual information as float
    """
    try:
        return response_entropy - conditional_entropy
    except Exception:
        return 'None'


def to_tuple(dataseq):
    """Converts a ctypes array to a tuple."""
    return tuple(dataseq)


def get_snapshot_limits(DirectoryId=None):
    """
    Obtains the manual snapshot limits for a directory.
    See also: AWS API Documentation

    :example: response = client.get_snapshot_limits(
        DirectoryId='string'
    )

    :type DirectoryId: string
    :param DirectoryId: [REQUIRED]
            Contains the identifier of the directory to obtain the limits for.

    :rtype: dict
    :return: {
        'SnapshotLimits': {
            'ManualSnapshotsLimit': 123,
            'ManualSnapshotsCurrentCount': 123,
            'ManualSnapshotsLimitReached': True|False
        }
    }

    """
    pass


def mkdir(path):
    """Create a directory.

        If it is not possible or allowed to create the directory, an `OSError`
        should be raised describing the reason of failure.
        """


def within_delta(dt1, dt2, delta):
    """
    Useful for comparing two datetimes that may a negilible difference
    to be considered equal.
    """
    difference = dt1 - dt2
    return -delta <= difference <= delta


def checkPermission(permission, object, context):
    """Check whether the current user has a permission w.r.t. an object.
        """


@classmethod
def del_record(cls, fqdn, name, type):
    """Delete record for a domain."""
    meta = cls.get_fqdn_info(fqdn)
    url = meta['domain_records_href']
    delete_url = url
    if name:
        delete_url = '%s/%s' % (delete_url, name)
    if type:
        delete_url = '%s/%s' % (delete_url, type)
    return cls.json_delete(delete_url)


def air2vac(w_air):
    """
	Air to vacuum conversion formula derived by N. Piskunov
	IAU standard:
	http://www.astro.uu.se/valdwiki/Air-to-vacuum%20conversion

	Parameters
	----------
	w_air : array-like
		Array of air wavelengths assumed to be in Angstroms

	Returns
	-------
	w_vac : array-like
		Array of vacuum wavelengths converted from w_air
	"""
    s = 10 ** 4 / w_air
    n = 1 + 8.336624212083e-05 + 0.02408926869968 / (130.1065924522 - s ** 2
        ) + 0.0001599740894897 / (38.92568793293 - s ** 2)
    w_vac = w_air * n
    return w_vac


@classmethod
def get_command_type(cls, options):
    """
        Gets the command type from the options, verifying that it is valid.
        """
    valid_command_types = [cls.COMMAND_TYPE_CONTROL, cls.COMMAND_TYPE_FORMAT]
    command_type = options.pop('type', cls.COMMAND_TYPE_FORMAT)
    if command_type not in valid_command_types:
        raise TypeError('command_type must be in {}'.format(', '.join(
            valid_command_types)))
    return command_type


def accuracy(inputs, targs):
    """Computes accuracy with `targs` when `input` is bs * n_classes.
    """
    n = targs.shape[0]
    inputs = inputs.argmax(dim=-1).view(n, -1)
    targs = targs.view(n, -1)
    return (inputs == targs).float().mean()


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

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

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


@staticmethod
def get_jenkins_plugin_name():
    """Gets the name of the Jenkins plugin associated with this PyJen plugin

        This static method is used by the PyJen plugin API to associate this
        class with a specific Jenkins plugin, as it is encoded in the config.xml

        :rtype: :class:`str`
        """
    return 'hudson.plugins.sectioned_view.SectionedView'


def _find_atom_index(struct, idx):
    """
    Returns the atom with the given index in the structure. This is required
    because atom indices may not start from 1 and may contain gaps in a PDB
    file. This tries to find atoms quickly, assuming that indices *do* start
    from 1 and have no gaps. It then looks up or down, depending on whether we
    hit an index too high or too low. So it *assumes* that the sequence is
    monotonically increasing. If the atom can't be found, None is returned
    """
    idx0 = min(max(idx - 1, 0), len(struct.atoms) - 1)
    if struct[idx0].number == idx:
        return struct[idx0]
    if struct[idx0].number < idx:
        idx0 += 1
        while idx0 < len(struct.atoms):
            if struct[idx0].number == idx:
                return struct[idx0]
            idx0 += 1
        return None
    else:
        idx0 -= 1
        while idx0 > 0:
            if struct[idx0].number == idx:
                return struct[idx0]
            idx0 -= 1
        return None


@staticmethod
def _from_db_object(registry, db_registry):
    """Converts a database entity to a formal object."""
    for field in registry.fields:
        setattr(registry, field, db_registry[field])
    registry.obj_reset_changes()
    return registry


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


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

        :param FileResolveCommentType val:
        :rtype: EventType
        """
    return cls('file_resolve_comment', val)


def previewrange_set():
    """Automatically set Preview Range based on range of keyframes

    """
    pass


def get_conversations():
    """Return all conversations stored in the inbox."""


def renderPublicWidget():
    """Render a widget for the public to input search data to use
        in the query.
        """


@staticmethod
def from_array(array, force_copy=False, force_numpy=True, try_optimizing=
    False, wrapped=True):
    """
        Build a new object of the type corresponding to the wrapper from the supplied `array` (a 1D numpy array or a list).

        If ``force_copy==True``, make a copy of supplied array.
        For a :class:`Column1DWrapper`, if `column` is a list and ``force_numpy==True``, turn it into a numpy array and return :class:`.ArrayDataColumn`
        (by default lists are wrapped into :class:`.ListDataColumn`).
        For a :class:`Column1DWrapper`, if ``try_optimizing==True``, check if the column can be turned into a :class:`.LinearDataColumn`.
        If ``wrapped==True``, return a new wrapper contating the column; otherwise, just return the column.
        """
    raise NotImplementedError('I1DWrapper.from_array')