@staticmethod
def _sort_query(query, sort=None):
    """
        Adds sorting clauses to the query.

        :param query: base SQL query
        :param sort: optional dictionary where keys are column names to sort by, and values are
         the order (asc/desc)
        :return: SQLAlchemy AppenderQuery object
        """
    if sort:
        for column, order in sort.items():
            if order == 'desc':
                column = column.desc()
            query = query.order_by(column)
    return query


def dameraulevenshtein(seq1, seq2):
    """Calculate the Damerau-Levenshtein distance between sequences.

    This distance is the number of additions, deletions, substitutions,
    and transpositions needed to transform the first sequence into the
    second. Although generally used with strings, any sequences of
    comparable objects will work.

    Transpositions are exchanges of *consecutive* characters; all other
    operations are self-explanatory.

    This implementation is O(N*M) time and O(M) space, for N and M the
    lengths of the two sequences.

    Written by Michael Homer
    """
    oneago = None
    thisrow = list(range(1, len(seq2) + 1)) + [0]
    seq1_size = len(seq1)
    seq2_size = len(seq2)
    for x in range(seq1_size):
        twoago, oneago, thisrow = oneago, thisrow, [0] * len(seq2) + [x + 1]
        for y in range(seq2_size):
            delcost = oneago[y] + 1
            addcost = thisrow[y - 1] + 1
            subcost = oneago[y - 1] + (seq1[x] != seq2[y])
            thisrow[y] = min(delcost, addcost, subcost)
            if x > 0 and y > 0 and seq1[x] == seq2[y - 1] and seq1[x - 1
                ] == seq2[y] and seq1[x] != seq2[y]:
                thisrow[y] = min(thisrow[y], twoago[y - 2] + 1)
    return thisrow[len(seq2) - 1]


@classmethod
def dark_red(cls):
    """A factory method that returns a :class:`Colour` with a value of ``0x992d22``."""
    return cls(10038562)


def _anonymous_model_data(ops_data):
    """Returns a dict representing an anonymous model.

    ops_data must be a dict representing the model operations. It will
    be used unmodified for the model `operations` attribute.
    """
    return {'model': '', 'operations': ops_data}


@classmethod
def create(cls):
    """ creates a new link object"""
    pass


def dtime2doy(dt):
    """
    Returns day of year of a datetime object.

    Parameters
    ----------
    dt : datetime

    Returns
    -------
    doy : int
        Day of year
    """
    return int(dt.strftime('%j'))


def join(chars=[]):
    """
    Join a list of characters into a string.

    :param chars: list of chars
    """
    return b''.join(chars).decode()


@staticmethod
def defaultSymbol():
    """
        Returns the default symbol path for this node.

        :returns: symbol path (or resource).
        """
    return ':/symbols/vbox_guest.svg'


def clear_refine(tree):
    """
    Set all refinemnet flags to False
    """
    tree.walk(leaf_func=lambda x: setattr(x, 'rflag', False))


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

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


def coerce_to_uint32(a, scaling_factor):
    """
    Returns a copy of the array as uint32, applying a scaling factor to
    maintain precision if supplied.
    """
    return (a * scaling_factor).round().astype('uint32')


def count_and_log(message, i, total, log_every_n):
    """Print a message to reflect the progress of processing once a while.

    Parameters
    ----------
    message : str
        Message to print.
    i : int
        Current index.
    total : int
        Total count.
    log_every_n : None or int
        Molecule related computation can take a long time for a large dataset and we want
        to learn the progress of processing. This can be done by printing a message whenever
        a batch of ``log_every_n`` molecules have been processed. If None, no messages will
        be printed.
    """
    if log_every_n is not None and (i + 1) % log_every_n == 0:
        print('{} {:d}/{:d}'.format(message, i + 1, total))


def _pullbundle2extraprepare(pullop, kwargs):
    """hook function so that extensions can extend the getbundle call"""


def bitceil(N):
    """
    Find the bit (i.e. power of 2) immediately greater than or equal to N
    Note: this works for numbers up to 2 ** 64.
    Roughly equivalent to int(2 ** np.ceil(np.log2(N)))
    """
    return 1 << int(N - 1).bit_length()


def clean_exit():
    """
    If we call this, we are exiting based on user input and not because of an
    error.
    """
    print('Thank you for using Pounce.')
    exit(0)


def set_platform(identifier):
    """Set the platform string identifier returned by get_platform().

    Note that this change doesn't impact the value returned by
    sysconfig.get_platform(); it is local to distutils2.
    """
    global _PLATFORM
    _PLATFORM = identifier


def sequence_minus(seq1, seq2):
    """Calculate difference of two sequences.

    Result contains the elements from first sequence that are not
    present in second sequence, in original order. Works even
    if sequence elements are not hashable.
    """
    result = list(seq1)
    for item in seq2:
        try:
            result.remove(item)
        except ValueError:
            pass
    return result


def _parallel_compare_helper(class_obj, pairs, x, x_link=None):
    """Internal function to overcome pickling problem in python2."""
    return class_obj._compute(pairs, x, x_link)


def looks_like_ansi_color(text):
    """Return whether the text looks like it has ANSI color codes."""
    return '\x1b[' in text


def default_engine_has_exhausted_gas_recirculation(fuel_type):
    """
    Returns the default engine has exhaust gas recirculation value [-].

    :param fuel_type:
        Fuel type (diesel, gasoline, LPG, NG, ethanol, methanol, biodiesel,
        propane).
    :type fuel_type: str

    :return:
        Does the engine have exhaust gas recirculation technology?
    :rtype: bool
    """
    return fuel_type in ('diesel', 'biodiesel')


def tweakmode_enter(isolate_action: bool=False):
    """Enter tweaking mode for the action referenced by the active strip to edit its keyframes

    :param isolate_action: Isolate Action, Enable ‘solo’ on the NLA Track containing the active strip, to edit it without seeing the effects of the NLA stack
    :type isolate_action: bool
    """
    pass


def psi_Ca_Mg_HSO4_HMW84(T, P):
    """c-c'-a: calcium magnesium bisulfate [HMW84]."""
    psi = 0.0
    valid = T == 298.15
    return psi, valid


def is_disabled(context, name):
    """Whether a specific pattern is disabled.

    The context object might define an inclusion list (includes) or an exclusion list (excludes)
    A pattern is considered disabled if it's found in the exclusion list or
    it's not found in the inclusion list and the inclusion list is not empty or not defined.

    :param context:
    :param name:
    :return:
    """
    if not context:
        return False
    excludes = context.get('excludes')
    if excludes and name in excludes:
        return True
    includes = context.get('includes')
    return includes and name not in includes


def _cert_filename(file_prefix):
    """
    Construct the name of a file for use in storing a certificate.
    :param str file_prefix: base file name for the certificate (without the
        extension)
    :return: certificate file name
    :rtype: str
    """
    return file_prefix + '.crt'


@staticmethod
def _directive_get_attribute(directive_body):
    """Directive for :py:meth:`get_attribute`"""
    instance, attribute_name = directive_body
    return getattr(instance, attribute_name)


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

        :param es_major: major version of Elasticsearch, as string
        :returns:        dictionary with a key, 'items', with the mapping
        """
    mapping = """
        {
            "properties": {
                "fullDisplayName_analyzed": {
                    "type": "text",
                    "index": true
                }
           }
        } """
    return {'items': mapping}


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

    The ".dev0" means dirty.

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


def parse_content_type(value):
    """
    Parse out the content type from a content type header.

    >>> parse_content_type('application/json; charset=utf8')
    'application/json'

    """
    if not value:
        return ''
    return value.split(';')[0].strip()


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

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


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


def p_for_stmt(p):
    """for_stmt : FOR id_list IN testlist_star_expr suite
                | FOR "[" id_list "]" IN testlist_star_expr suite """
    if len(p) == 6:
        p[0] = ['FOR', p[2], p[4], p[5]]
    else:
        p[0] = ['FOR', p[3], p[6], p[7]]


def one_of_k_encoding_unk(x, allowable_set):
    """Maps inputs not in the allowable set to the last element."""
    if x not in allowable_set:
        x = allowable_set[-1]
    return list(map(lambda s: int(x == s), allowable_set))


def states_for_display():
    """Get the available transitions for this issue.
        """


def polynomial(x, y, z, n):
    """used for interpolation

    Parameters
    ----------
    x : ndarray
        the integer values from 0 through n-1 inclusive (but float64)
    y : ndarray
        a 2-D array, axis 0 of length n
    z : float
        n / 2.
    n : int
        1 + order of polynomial fit
    """
    t = n * [0.0]
    for k in range(n):
        t[k] = y[k]
        for j in range(k - 1, -1, -1):
            t[j] = t[j + 1] + (t[j + 1] - t[j]) / ((z - x.item(j)) / (z - x
                .item(k)) - 1.0)
    return t[0]


def closest_point_in_path(pt, path):
    """returns (|path.seg.point(t)-pt|, t, seg_idx) where t and seg_idx
    minimize the distance between pt and curve path[idx].point(t) for 0<=t<=1
    and any seg_idx.
    Warning:  Multiple such global minima can exist.  This will only return
    one."""
    return path.radialrange(pt)[0]


def predict_generator(data_set, model, **kwargs):
    """
    Produces predictions with a trained Keras model where inputs are generators

    :param DataSet data_set: A DataSet with a KerasIteratorFeaturesDataWrapper called "features"
    :param model: A (fitted) Keras model
    :param kwargs: Additional parameters to be passed to model.predict
    :return: A NumpyDataWrapper with an array of predictions as its underlying
    """
    prediction_array = model.predict_generator(generator=data_set.features.
        underlying, **kwargs)
    from mercury_ml.common.data_wrappers.numpy import NumpyDataWrapper
    return NumpyDataWrapper(underlying=prediction_array, field_names=
        data_set.features.underlying.get_labels_dummies())


def interval_overlap(i1, i2):
    """
    The function judge whether two intervals overlap with each other. i1 and i2 should be list or tuple with two elements.
    We require the first element of the interval is start and the second is end. start < end. start and end are 0-based
    Return a bool. True for overlap.
    """
    if i1[0] > i1[1] or i2[0] > i2[1]:
        raise Exception('Error: not standard interval!', i1, i2)
    if i1[0] == i1[1] or i2[0] == i2[1]:
        flag = False
    else:
        flag = i1[1] > i2[0] and i1[0] < i2[1]
    return flag


def load_scipy_linalg_interface_gen(finder, module):
    """the scipy.linalg.interface_gen module optionally imports the pre module;
       ignore the error if this module cannot be found"""
    module.IgnoreName('pre')


def commonprefix(m):
    """Given a list of pathnames, returns the longest common leading component"""
    if not m:
        return ''
    prefix = m[0]
    for item in m:
        for i in range(len(prefix)):
            if prefix[:i + 1].lower() != item[:i + 1].lower():
                prefix = prefix[:i]
                if i == 0:
                    return ''
                break
    return prefix


def replace_node_field(reg, label, change):
    """ Call one of the field appropriate methods if we're changing just
    a field on a node. """
    if change['action'] == 'PUT' and change['field'] == '[text]':
        reg.replace_node_text(label, change)
    elif change['action'] == 'PUT' and change['field'] == '[title]':
        reg.replace_node_title(label, change)
    elif change['action'] == 'PUT' and change['field'] == '[heading]':
        reg.replace_node_heading(label, change)


def make_an_event(new_state):
    """Turns a new/target state into an event name."""
    return ('on_%s' % new_state).lower()


def _concat_cell_style_array(style_array1, style_array2):
    """Concat elements from any_array_2 into any_array_1."""
    if len(style_array1.styles) == 0:
        style_array1.CopyFrom(style_array2)
        return
    style_array1.styles.extend(style_array2.styles)


def enforce_access_rights(update):
    """
    Check that the update should be allowed.
    """
    if update.old:
        if update.user != update.old.get_owner() and update.user.role not in [
            'admin', 'owner']:
            raise Exception('Not permitted to modify existing chute {}'.
                format(update.old.name))


def fulltext(html, language='en'):
    """Takes article HTML string input and outputs the fulltext
    Input string is decoded via UnicodeDammit if needed
    """
    from .cleaners import DocumentCleaner
    from .configuration import Configuration
    from .extractors import ContentExtractor
    from .outputformatters import OutputFormatter
    config = Configuration()
    config.language = language
    extractor = ContentExtractor(config)
    document_cleaner = DocumentCleaner(config)
    output_formatter = OutputFormatter(config)
    doc = config.get_parser().fromstring(html)
    doc = document_cleaner.clean(doc)
    top_node = extractor.calculate_best_node(doc)
    top_node = extractor.post_cleanup(top_node)
    text, article_html = output_formatter.get_formatted(top_node)
    return text


def reflect_x(x, y, matrix):
    """Reflect the index vertically."""
    return matrix.columns - 1 - x, y


def get_except(data, i, ndata, end_value):
    """helper method for expand that gets the values until the end of an
    EXCEPT chain"""
    removed = []
    ivalue_old = 0
    while i < len(data):
        value = data[i]
        if isinstance(value, int):
            ivalue = value
        elif value.isdigit():
            ivalue = int(value)
        elif value == 'THRU':
            ivalue_old = int(data[i - 1])
            ivalue_new = int(data[i + 1])
            rangei = range(ivalue_old, ivalue_new + 1)
            removed.extend(rangei)
            i += 2
            continue
        else:
            raise NotImplementedError('data[%i] = %s; data=%s' % (i, value,
                data))
        if ivalue > end_value and ivalue > ivalue_old:
            break
        removed.append(ivalue)
        ivalue_old = ivalue
        i += 1
    removed_set = set(removed)
    return i, removed_set


def tick():
    """
            Run on every tick.
        """
    raise NotImplementedError('Abstract method tick called.')


def default_manage_exception(e: Exception) ->None:
    """If not changed, this raise the exceptions encounter in run_update"""
    print('')
    raise e


def update_wcc(node_to_update, node_to_add, l, node_2_status,
    tmp_components, comp_2_nb_links):
    """
    Update a component with a new node
    :param node_to_update:
    :param node_to_add:
    :param t0:
    :param t1:
    :param node_2_status:
    :param tmp_components:
    :param comp_2_nb_links:
    :return:
    """
    u, v = l[3], l[4]
    n_current_comp = node_2_status[node_to_update][1]
    comp_2_nb_links[n_current_comp] += 1
    node_2_status[node_to_update][0] += 1
    node_2_status[node_to_add] = [1, n_current_comp]
    current_comp = tmp_components[n_current_comp]
    current_comp.links.append(l)
    current_comp.active_links.add((u, v))


def cancel_command(CommandId=None, InstanceIds=None):
    """
    Attempts to cancel the command specified by the Command ID. There is no guarantee that the command will be terminated and the underlying process stopped.
    See also: AWS API Documentation

    :example: response = client.cancel_command(
        CommandId='string',
        InstanceIds=[
            'string',
        ]
    )

    :type CommandId: string
    :param CommandId: [REQUIRED]
            The ID of the command you want to cancel.

    :type InstanceIds: list
    :param InstanceIds: (Optional) A list of instance IDs on which you want to cancel the command. If not provided, the command is canceled on every instance on which it was requested.
            (string) --

    :rtype: dict
    :return: {}

    """
    pass


def sparse_matrix(data, index, shape, force_format=False):
    """Create a sparse matrix.

    NOTE: Please make sure that the data and index tensors are not
    copied. This is critical to the performance.

    Parameters
    ----------
    data : Tensor
        Data tensor. It should be of shape (nnz,).
    index : tuple
        This is used to support different sparse formats.
        For COO format:
          index=('coo', coord), where coord is of shape (2, nnz).
          coord[0,:] should be the row index and coord[1,:] should be
          the column index.
        For CSR format:
          index=('csr', indices, indptr), where indices is of shape (nnz,)
          and indptr is of shape (nrows+1,). See ``scipy.sparse.csr_matrix``
          for more documents on what each array means.
    shape : tuple of int
        The shape.
    force_format : bool
        If true, the returned sparse matrix must be stored in the same
        format as the given index.

    Returns
    -------
    SparseMatrix
        The framework-specific sparse matrix. It can be stored in any format
        unless force_format is True.
    Tensor
        The data convert index due to sparse format change.
        None if no conversion is needed.
    """
    pass


def get(name):
    """Return the named style or None.

        :type name: string
        :param name: A style name.
        :return: the named `IStyle` or None if the style doesn't exist.
        """


def _format_range_unified(start, stop):
    """Convert range to the "ed" format"""
    beginning = start + 1
    length = stop - start
    if length == 1:
        return '{}'.format(beginning)
    if not length:
        beginning -= 1
    return '{},{}'.format(beginning, length)


def to_conll(passage, test=False, tree=False, preprocess=True, **kwargs):
    """ Convert from a Passage object to a string in CoNLL-X format (conll)

    :param passage: the Passage object to convert
    :param test: whether to omit the head and deprel columns. Defaults to False
    :param tree: whether to omit rows for non-primary parents. Defaults to False
    :param preprocess: preprocess the converted dependency graph before returning it?

    :return list of lines representing the dependencies in the passage
    """
    from semstr.conversion.conll import ConllConverter
    return ConllConverter(tree=tree).to_format(passage, test, preprocess=
        preprocess, format=kwargs.get('format'))


@staticmethod
def list_compare(list1, list2):
    """
        Compare two lists. If lists are same, return True.

        :return: True or False
        """
    if len(list1) != len(list2):
        return False
    for i in range(len(list1)):
        if list1[i] != list2[i]:
            return False
    return True


def triangleArea(a, b, c):
    """Calculates the area of a triangle spanned by three points.
    Note that the area will be negative if the points are not given in counter-clockwise order.

    Keyword arguments:
    a -- First point
    b -- Second point
    c -- Third point

    Returns:
    Area of triangle
    """
    return (b[0] - a[0]) * (c[1] - a[1]) - (c[0] - a[0]) * (b[1] - a[1])


def resolve_list(value):
    """Resolve list (convert provided value if not list).

    :param value: Value
    :type value: any
    """
    if value is None:
        return []
    if isinstance(value, list):
        return [value]
    return value


def _siftdown_max(heap, startpos, pos):
    """Maxheap variant of _siftdown"""
    newitem = heap[pos]
    while pos > startpos:
        parentpos = pos - 1 >> 1
        parent = heap[parentpos]
        if parent < newitem:
            heap[pos] = parent
            pos = parentpos
            continue
        break
    heap[pos] = newitem


def _add_expression_arg(parser):
    """Add the expression argument to a parser."""
    parser.add_argument('expression', nargs='*', help=
        """Boolean expression to process; surround it in quotes to
avoid escaping control characters in your terminal"""
        )


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

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

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


def check_str_arg(result, func, cargs):
    """
    This is for the OSRGet[Angular|Linear]Units functions, which
    require that the returned string pointer not be freed.  This
    returns both the double and string values.
    """
    dbl = result
    ptr = cargs[-1]._obj
    return dbl, ptr.value.decode()


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

    The ".dev0" means dirty.

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


def is_valid_boolstr(val):
    """Check if the provided string is a valid bool string or not."""
    val = str(val).lower()
    return val in ('true', 'false', 'yes', 'no', 'y', 'n', '1', '0')


def combine_dicts(*dicts):
    """
    When passed in one or more dictionaries, return a new dictionary
    with items combined from all input dictionaries. If the same key
    exists in more than one dictionaries, the last dictionary's value
    for the key will be used.
    """
    combined = {}
    for d in dicts:
        if d is None:
            continue
        for k, v in d.items():
            combined[k] = v
    return combined


@staticmethod
def _noopCallback(eventDict):
    """Default no-op callback."""
    pass


def set_hopping(list_hop, n_max):
    """
    Check method *set_hopping*.

    :raises TypeError: Parameter *list_hop* must be a list.
    :raises TypeError: Parameter *list_hop* must be a list of dictionary.
    :raises KeyError: "n" and "t" must be dictionary keys.
    :raises KeyError: "tag" or "ang" must be a key.
    :raises KeyError: "tag" and "ang" must be a key.
    :raises ValueError: Dictionaries must be of length 2, 4, or 4.
    :raises ValueError: "n" must be between 1 and nmax"

    """
    if not isinstance(list_hop, list):
        raise TypeError('\n\nParameter *list_hop* must be a list.\n')
    for dic in list_hop:
        if not isinstance(dic, dict):
            raise TypeError(
                '\n\nParameter *list_hop* must be a list of dictionary.\n')
        if 'n' not in dic or 't' not in dic:
            raise KeyError('\n\n"n" and "t" must be dictionary keys.\n')
        if not isinstance(dic['n'], int):
            raise TypeError('\n\n"n" value must be an integer.\n')
        if not 0 < dic['n'] <= n_max:
            raise ValueError('\n\n"n" value must be between 1 and nmax".\n')
        if not isinstance(dic['t'], (int, float, complex)):
            raise TypeError('\n\n"t" value must be a real or complex number.\n'
                )
        if len(dic) == 3:
            if not ('tag' not in dic or 'ang' not in dic):
                raise KeyError('\n\n"tag" or "ang" must be a key.\n')
        elif len(dic) == 4:
            if 'tag' not in dic and 'ang' not in dic:
                raise KeyError('\n\n"tag" or "ang" must be a key.\n')
        elif len(dic) > 4:
            raise ValueError('\n\nDictionaries must be of length 2, 3, or 4.\n'
                )
        if 'tag' in dic:
            if not isinstance(dic['tag'], bytes):
                raise TypeError('\n\n"tag" value must be a binary string.\n')
            if len(dic['tag']) != 2:
                raise ValueError(
                    '\n\n"tag" value must be a binary string of length 2.\n')
        if 'ang' in dic:
            if not isinstance(dic['ang'], (int, float)):
                raise TypeError('\n\n"ang" value must be a real number.\n')


def _create_ansi_color_dict(color_cls):
    """ Create a table that maps the 16 named ansi colors to their Windows code. """
    return {'ansidefault': color_cls.BLACK, 'ansiblack': color_cls.BLACK,
        'ansigray': color_cls.GRAY, 'ansibrightblack': color_cls.BLACK |
        color_cls.INTENSITY, 'ansiwhite': color_cls.GRAY | color_cls.
        INTENSITY, 'ansired': color_cls.RED, 'ansigreen': color_cls.GREEN,
        'ansiyellow': color_cls.YELLOW, 'ansiblue': color_cls.BLUE,
        'ansimagenta': color_cls.MAGENTA, 'ansicyan': color_cls.CYAN,
        'ansibrightred': color_cls.RED | color_cls.INTENSITY,
        'ansibrightgreen': color_cls.GREEN | color_cls.INTENSITY,
        'ansibrightyellow': color_cls.YELLOW | color_cls.INTENSITY,
        'ansibrightblue': color_cls.BLUE | color_cls.INTENSITY,
        'ansibrightmagenta': color_cls.MAGENTA | color_cls.INTENSITY,
        'ansibrightcyan': color_cls.CYAN | color_cls.INTENSITY}


def hide(unselected: bool=False):
    """Hide (un)selected vertices, edges or faces

    :param unselected: Unselected, Hide unselected rather than selected
    :type unselected: bool
    """
    pass


@classmethod
def set_celery_app(cls, celery_app):
    """Set celery application that should be used.

        :param celery_app: celery app instance
        """
    from .dispatcher import Dispatcher
    from .task_envelope import SelinonTaskEnvelope
    cls._logger.debug('Registering Selinon to Celery context')
    cls.celery_app = celery_app
    celery_app.tasks.register(Dispatcher())
    celery_app.tasks.register(SelinonTaskEnvelope())


@classmethod
def run_offline_backup(cls, options=None):
    """Build foreman-maintain backup offline"""
    cls.command_sub = 'offline'
    if options is None:
        options = {}
    result = cls._construct_command(options)
    return result


def space_to_kebab(s):
    """Replace spaces with dashes.

    Parameters
    ----------
    s : str
        String that may contain " " characters.
    """
    return '-'.join(s.split(' '))


def delete_queue(name):
    """Beanstalkd backends don't provide a way to do this."""
    raise NotImplementedError


def is_point_in_polygon(point, polygon):
    """
    test wether point lie in polygon

    :param point: pypex.poly2d.point.Point
    :param polygon: pypex.poly2d.polygon.Polygon
    :return:
    """
    if len(polygon) < 3:
        raise ValueError(
            'invalid polygon shape, expected at least 3 corners polygon')
    return polygon.mplpath.contains_point(point.to_array())


def density_conv(D, from_units, to_units):
    """
    Convert density values between kg/m**3, slug/ft**3 and lb/ft**3.

    The incoming value is first converted to kg/m**3, then it is converted
    to desired return value.

    There are no default units. Both the from_units and the to_units must
    be specified.

    Example:

    Convert 1.225 kg per metre cubed to lb per foot cubed:
    >>> density_conv(1.225, from_units = 'kg/m**3', to_units = 'lb/ft**3')
    0.076474253491112101

    """
    if from_units == 'kg/m**3':
        pass
    elif from_units == 'slug/ft**3':
        D *= 515.37882
    elif from_units == 'lb/ft**3':
        D *= 16.018463
    else:
        raise ValueError(
            'from_units must be one of "kg/m**3", "slug/ft**3" and "lb/ft**3".'
            )
    if to_units == 'kg/m**3':
        return D
    elif to_units == 'slug/ft**3':
        return D / 515.37882
    elif to_units == 'lb/ft**3':
        return D / 16.018463
    else:
        raise ValueError(
            'to_units must be one of "kg/m**3", "slug/ft**3" and "lb/ft**3".')


@classmethod
def fix_supply_use(cls, array, vector):
    """Make technosphere inputs negative."""
    mask = cls.get_technosphere_inputs_mask(array)
    vector[mask] = -1 * vector[mask]
    return vector


@staticmethod
def check_pad_value_by_mode(op_name, pad_mode, padding):
    """Validate value of padding according to pad_mode"""
    if pad_mode != 'pad' and padding != 0:
        raise ValueError(
            f"For op '{op_name}', padding must be zero when pad_mode is '{pad_mode}'."
            )
    return padding


@staticmethod
def _isHidden(filePath):
    """
        This is a function that checks whether filePath is hidden

        :param str filePath: Path to the file under consideration
        :return: A boolean indicating whether the file is hidden or not.
        :rtype: bool
        """
    assert isinstance(filePath, (str, bytes))
    return filePath[0] in ('.', '_')


def _check_regularize(regularize):
    """Ensure regularize is valid."""
    if not (regularize is None or isinstance(regularize, str) and
        regularize in ('in',)):
        raise ValueError('regularize must be None or "in"')


@classmethod
def match(cls, jedec):
    """Tells whether this class support this JEDEC identifier"""
    manufacturer, capacity, revision = jedec[:3]
    if manufacturer != cls.JEDEC_ID:
        return False
    if revision > 1:
        return False
    if capacity not in cls.SIZES:
        return False
    return True


@classmethod
def on_write_connection(cls):
    """
        Begin querying the model on the write connection.

        :return: A Builder instance
        :rtype: QueryBuilder
        """
    instance = cls()
    return instance.new_query().use_write_connection()


def parse_arn(arn):
    """
    Given an ARN, split up the ARN into the ARN namespacing schema dictated by the AWS docs.
    """
    elements = arn.split(':', 5)
    result = {'arn': elements[0], 'partition': elements[1], 'service':
        elements[2], 'region': elements[3], 'account': elements[4],
        'resource': elements[5], 'resource_path': None}
    if '/' in result['resource']:
        result['resource'], result['resource_path'] = result['resource'].split(
            '/', 1)
    elif ':' in result['resource']:
        result['resource'], result['resource_path'] = result['resource'].split(
            ':', 1)
    return result


def compareonvar(map_df, colvar='all'):
    """
    subsetting a dataframe based on some columns of interest

    map_df: (dataframe) the dataframe of the mappingfile table
    colvar: (str or list) the column(s) to use for subsetting; 'None' returns an outerjoin, 'all' returns an innerjoin
    """
    if isinstance(colvar, type(None)):
        return map_df
    if colvar is 'all':
        return map_df.dropna()
    else:
        return map_df.dropna(subset=colvar)


def read_pid_from_pidfile(pidfile_path):
    """ Read the PID recorded in the named PID file.

        Read and return the numeric PID recorded as text in the named
        PID file. If the PID file cannot be read, or if the content is
        not a valid PID, return ``None``.

        """
    pid = None
    try:
        pidfile = open(pidfile_path, 'r')
    except IOError:
        pass
    else:
        line = pidfile.readline().strip()
        try:
            pid = int(line)
        except ValueError:
            pass
        pidfile.close()
    return pid


def parse_tmrna_seqfeature(seqfeature):
    """Parses a Biopython tRNA SeqFeature and returns a pdm_utils Tmrna object.
    """
    tmrna = ''
    return tmrna


def expand_as_pair(input_):
    """Return a pair of same element if the input is not a pair.
    """
    if isinstance(input_, tuple):
        return input_
    else:
        return input_, input_


def _prd_to_f_beta(precision, recall, beta=1, epsilon=1e-10):
    """Computes F_beta scores for the given precision/recall values.

  The F_beta scores for all precision/recall pairs will be computed and
  returned.

  For precision p and recall r, the F_beta score is defined as:
  F_beta = (1 + beta^2) * (p * r) / ((beta^2 * p) + r)

  Args:
    precision: 1D NumPy array of precision values in [0, 1].
    recall: 1D NumPy array of precision values in [0, 1].
    beta: Beta parameter. Must be positive. The default value is 1.
    epsilon: Small constant to avoid numerical instability caused by division
             by 0 when precision and recall are close to zero.

  Returns:
    NumPy array of same shape as precision and recall with the F_beta scores for
    each pair of precision/recall.

  Raises:
    ValueError: If any value in precision or recall is outside of [0, 1].
    ValueError: If beta is not positive.
  """
    if not ((precision >= 0).all() and (precision <= 1).all()):
        raise ValueError('All values in precision must be in [0, 1].')
    if not ((recall >= 0).all() and (recall <= 1).all()):
        raise ValueError('All values in recall must be in [0, 1].')
    if beta <= 0:
        raise ValueError('Given parameter beta %s must be positive.' % str(
            beta))
    return (1 + beta ** 2) * (precision * recall) / (beta ** 2 * precision +
        recall + epsilon)


@classmethod
def input_of_type(cls, input_type):
    """Returns an XPath to find an HTML <input> with type attribute `input_type`."""
    return '//input[@type="%s"]' % input_type


def has_pythonX_package(pkg_name, name_by_version, version):
    """Given the package name, check if python<version>-<pkg_name>
    or <pkg_name>-python<version> exists in name_by_version.

    Return: (bool) True if such package name exists, False otherwise
    """
    return 'python{}-{}'.format(version, pkg_name) in name_by_version[version
        ] or '{}-python{}'.format(pkg_name, version) in name_by_version[version
        ]


def from_like_context(ctx, param, value):
    """Return the value for an option from the context if the option
    or `--all` is given, else return None."""
    if ctx.obj and ctx.obj.get('like') and (value == 'like' or ctx.obj.get(
        'all_like')):
        return ctx.obj['like'][param.name]
    else:
        return None


def register_reference(target, count=1):
    """Register new references to the given target."""


def get_num_aliens(ai_settings, alien_width):
    """determine number of aliens that fit in a row"""
    available_space_x = ai_settings.screen_width - 2 * alien_width
    num_aliens_x = int(available_space_x / (2 * alien_width))
    return num_aliens_x


def window_sum(wsize, numbers):
    """
    >>> numbers = [1, 10, 100, 1000, 10000, 100000]
    >>> list(window_sum(3, numbers))
    [111, 1110, 11100, 111000]

    :param wsize: integer, size of the moving window
    :param numbers: an iterable of numbers
    """
    import collections
    queue = collections.deque(maxlen=wsize)
    for num in numbers:
        queue.append(num)
        if len(queue) >= wsize:
            yield sum(queue)


def try_parse(val, fn=int):
    """ 'try parse' (with fn) """
    try:
        return fn(val)
    except Exception:
        return val


def parse_block(lines, header=False):
    """Parse and return a single block, popping off the start of `lines`.

    If parsing a header block, we stop after we reach a line that is not a
    comment. Otherwise, we stop after reaching an empty line.

    :param lines: list of lines
    :param header: whether we are parsing a header block
    :return: list of lines that form the single block
    """
    block_lines = []
    while lines and lines[0] and (not header or lines[0].startswith('#')):
        block_lines.append(lines.pop(0))
    return block_lines


def datetime_is_naive(dateTime):
    """ Returns True if dateTime is naive."""
    return dateTime.tzinfo is None or dateTime.tzinfo.utcoffset(dateTime
        ) is None


def labels(indices, node_labels=None):
    """Get the labels for a tuple of mechanism indices."""
    if node_labels is None:
        return tuple(map(str, indices))
    return node_labels.indices2labels(indices)


def getId():
    """Returns the ruleset's ID, which must be unique among rulesets."""


def parse_rwl(response):
    """Parse the json response for a RWL Hue remote."""
    press = str(response['state']['buttonevent'])
    if press[-1] in ['0', '2']:
        button = str(press)[0] + '_click'
    else:
        button = str(press)[0] + '_hold'
    data = {'model': 'RWL', 'name': response['name'], 'state': button,
        'battery': response['config']['battery'], 'last_updated': response[
        'state']['lastupdated'].split('T')}
    return data


def _use_constant_crc_table(opt):
    """
    Return True is the CRC table is constant.
    """
    if (opt.width is not None and opt.poly is not None and opt.reflect_in
         is not None):
        return True
    else:
        return False


def _decoder(conv_func):
    """ The Python sqlite3 interface returns always byte strings.
        This function converts the received value to a regular string before
        passing it to the receiver function.
    """
    return lambda s: conv_func(s.decode('utf-8'))


def construct_formula(label, rel_cols, label_side='l'):
    """
    Constructs a generic formula string from column names and a label name.
    label ~ Col1+Col2+...+ColN

    :param label: Label or class which should be regressed for. (case/control, treatment/untreated etc.)
    :param rel_cols: Relevant columns for the formula
    :return: formula string
    """
    cols = rel_cols[:]
    if label in rel_cols:
        cols.remove(label)
    if label_side == 'left' or label_side == 'l':
        formula = label + ' ~ ' + '+'.join(cols)
    elif label_side == 'right' or label_side == 'r':
        formula = '+'.join(cols) + ' ~ ' + label
    return formula


@classmethod
def parse(cls, text):
    """
        Parse the given text. Returns a tuple:
        (list_of_parts, start_pos_of_the_last_part).
        """
    OUTSIDE, IN_DOUBLE, IN_SINGLE = 0, 1, 2
    iterator = enumerate(text)
    state = OUTSIDE
    parts = []
    current_part = ''
    part_start_pos = 0
    for i, c in iterator:
        if state == OUTSIDE:
            if c.isspace():
                if current_part:
                    parts.append(current_part)
                part_start_pos = i + 1
                current_part = ''
            elif c == '"':
                state = IN_DOUBLE
            elif c == "'":
                state = IN_SINGLE
            else:
                current_part += c
        elif state == IN_SINGLE:
            if c == "'":
                state = OUTSIDE
            elif c == '\\':
                next(iterator)
                current_part += c
            else:
                current_part += c
        elif state == IN_DOUBLE:
            if c == '"':
                state = OUTSIDE
            elif c == '\\':
                next(iterator)
                current_part += c
            else:
                current_part += c
    parts.append(current_part)
    return parts, part_start_pos


def _show_ase(exec_name, structure_list):
    """
    Plugin to show the structure with the ASE visualizer
    """
    try:
        from ase.visualize import view
        for structure in structure_list:
            view(structure.get_ase())
    except ImportError:
        raise


def service_update_flags(target_rep_size=None, instance_count=None,
    rep_restart_wait=None, quorum_loss_wait=None, standby_rep_keep=None,
    min_rep_size=None, placement_constraints=None, placement_policy=None,
    correlation=None, metrics=None, move_cost=None, scaling_policy=None,
    service_placement_time=None):
    """Calculate an integer representation of flag arguments for updating
    stateful services"""
    flag_sum = 0
    if target_rep_size is not None or instance_count is not None:
        flag_sum += 1
    if rep_restart_wait is not None:
        flag_sum += 2
    if quorum_loss_wait is not None:
        flag_sum += 4
    if standby_rep_keep is not None:
        flag_sum += 8
    if min_rep_size is not None:
        flag_sum += 16
    if placement_constraints is not None:
        flag_sum += 32
    if placement_policy is not None:
        flag_sum += 64
    if correlation is not None:
        flag_sum += 128
    if metrics is not None:
        flag_sum += 256
    if move_cost is not None:
        flag_sum += 512
    if scaling_policy is not None:
        flag_sum += 1024
    if service_placement_time is not None:
        flag_sum += 2048
    return flag_sum


def dayOfWeek(y, m, d):
    """return integer representing day of week, Mon=0, Tue=1, etc."""
    if m == 1 or m == 2:
        m = m + 12
        y = y - 1
    return (d + 2 * m + 3 * (m + 1) // 5 + y + y // 4 - y // 100 + y // 400
        ) % 7


def restore_botocore_session_send():
    """Restores the original botocore session send method"""
    try:
        from botocore.httpsession import URLLib3Session as BotocoreSession
    except ImportError:
        pass
    else:
        if hasattr(BotocoreSession.send, '__wrapped__'):
            setattr(BotocoreSession, 'send', BotocoreSession.send.__wrapped__)


def add_station_sheet(wbb, stations):
    """ Add a worksheet called Stations to the workbook with details of the stations
    referenced. Certificate details for each station will appear in a seperate sheet
    (one per station).
    """
    ws = wbb.add_sheet('Stations')
    row = 0
    col = 0
    ws.write(row, 0, 'Station Details')
    row = 2
    for tit in ['Name', 'Accreditation Number', 'Scheme', 'Technology',
        'Capapcity']:
        ws.write(row, col, tit)
        col += 1
    row += 1
    for station in stations:
        ws.write(row, 0, station.name)
        ws.write(row, 1, station.generator_id)
        ws.write(row, 2, station.scheme)
        ws.write(row, 3, station.technology)
        ws.write(row, 4, station.capacity)
        row += 1


def assert_float_eq_int(vfloat, vint, message=''):
    """
    Check the given float value is equal to the given int value. Print the
    optional message if not equal.
    """
    if abs(vfloat - vint) > 1:
        raise AssertionError(message + ' {} != {}'.format(vfloat, vint))


def scale_plot_size(factor=1.5):
    """Scale plot size in jupyter notebook."""
    import matplotlib as mpl
    default_dpi = mpl.rcParamsDefault['figure.dpi']
    mpl.rcParams['figure.dpi'] = default_dpi * factor


def alpha_spinorbital(MO):
    """ Return the corresponding alpha spinorbital index given a molecular orbital (MO) index
    Args:
        MO(int):     molecular orbital index
    Returns:
        (2*MO)(int): alpha spin-orbital index
    """
    return 2 * MO


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


def list_traffic_policy_instances_by_hosted_zone(HostedZoneId=None,
    TrafficPolicyInstanceNameMarker=None, TrafficPolicyInstanceTypeMarker=
    None, MaxItems=None):
    """
    Gets information about the traffic policy instances that you created in a specified hosted zone.
    Amazon Route 53 returns a maximum of 100 items in each response. If you have a lot of traffic policy instances, you can use the MaxItems parameter to list them in groups of up to 100.
    See also: AWS API Documentation

    :example: response = client.list_traffic_policy_instances_by_hosted_zone(
        HostedZoneId='string',
        TrafficPolicyInstanceNameMarker='string',
        TrafficPolicyInstanceTypeMarker='SOA'|'A'|'TXT'|'NS'|'CNAME'|'MX'|'NAPTR'|'PTR'|'SRV'|'SPF'|'AAAA',
        MaxItems='string'
    )

    :type HostedZoneId: string
    :param HostedZoneId: [REQUIRED]
            The ID of the hosted zone that you want to list traffic policy instances for.

    :type TrafficPolicyInstanceNameMarker: string
    :param TrafficPolicyInstanceNameMarker: If the value of IsTruncated in the previous response is true, you have more traffic policy instances. To get more traffic policy instances, submit another ListTrafficPolicyInstances request. For the value of trafficpolicyinstancename , specify the value of TrafficPolicyInstanceNameMarker from the previous response, which is the name of the first traffic policy instance in the next group of traffic policy instances.
            If the value of IsTruncated in the previous response was false , there are no more traffic policy instances to get.

    :type TrafficPolicyInstanceTypeMarker: string
    :param TrafficPolicyInstanceTypeMarker: If the value of IsTruncated in the previous response is true, you have more traffic policy instances. To get more traffic policy instances, submit another ListTrafficPolicyInstances request. For the value of trafficpolicyinstancetype , specify the value of TrafficPolicyInstanceTypeMarker from the previous response, which is the type of the first traffic policy instance in the next group of traffic policy instances.
            If the value of IsTruncated in the previous response was false , there are no more traffic policy instances to get.

    :type MaxItems: string
    :param MaxItems: The maximum number of traffic policy instances to be included in the response body for this request. If you have more than MaxItems traffic policy instances, the value of the IsTruncated element in the response is true , and the values of HostedZoneIdMarker , TrafficPolicyInstanceNameMarker , and TrafficPolicyInstanceTypeMarker represent the first traffic policy instance that Amazon Route 53 will return if you submit another request.

    :rtype: dict
    :return: {
        'TrafficPolicyInstances': [
            {
                'Id': 'string',
                'HostedZoneId': 'string',
                'Name': 'string',
                'TTL': 123,
                'State': 'string',
                'Message': 'string',
                'TrafficPolicyId': 'string',
                'TrafficPolicyVersion': 123,
                'TrafficPolicyType': 'SOA'|'A'|'TXT'|'NS'|'CNAME'|'MX'|'NAPTR'|'PTR'|'SRV'|'SPF'|'AAAA'
            },
        ],
        'TrafficPolicyInstanceNameMarker': 'string',
        'TrafficPolicyInstanceTypeMarker': 'SOA'|'A'|'TXT'|'NS'|'CNAME'|'MX'|'NAPTR'|'PTR'|'SRV'|'SPF'|'AAAA',
        'IsTruncated': True|False,
        'MaxItems': 'string'
    }

    """
    pass


def _get_batch_size(params, hparams, config):
    """Batch size determined by params dict, HParams, and RunConfig."""
    batch_size = params and params.get('batch_size')
    if not batch_size:
        batch_size = hparams.tpu_batch_size_per_shard
        if config:
            batch_size *= config.t2t_device_info['num_shards']
    return batch_size


def arcade_mode(resolution=(960, 640), blocksize=16, width=20, height=70):
    """Builds regular boring, but scalable, rectangular walls.

    If given values that are too much to fit at the resolution and blocksize,
    it just fits as many as it can with some amount of space for next blocks,
    the hold block, stats...

    Args::

        resolution: (x, y) tuple of total screen width and height
        blocksize: pixel height per block
        width: integer number of blocks wide for the map
        height: integer number of blocks high for the map

    Returns::

        a tuple of a list of (x, y) coords of all walls (includes invisible),
        and a list of (x, y) coords of all visible walls for sprites/images
    """
    blocks_wide = int(resolution[0] / blocksize)
    blocks_high = int(resolution[1] / blocksize)
    centre_block = int(blocks_wide / 2)
    spread = int(width / 2)
    walls = []
    wall_blocks = []
    for x_coord in range(centre_block - (spread + 1), centre_block + (width -
        spread) + 1):
        for y_coord in range(blocks_high):
            if x_coord == centre_block - (spread + 1
                ) or x_coord == centre_block + (width - spread
                ) or y_coord == blocks_high - 2:
                coord = x_coord * blocksize, y_coord * blocksize
                if blocks_high - height < y_coord < blocks_high - 1:
                    wall_blocks.append(coord)
                walls.append(coord)
    return walls, wall_blocks


def location_clear(clear_delta: bool=False):
    """Clear the object’s location

    :param clear_delta: Clear Delta, Clear delta location in addition to clearing the normal location transform
    :type clear_delta: bool
    """
    pass


def load_cx_Oracle(finder, module):
    """the cx_Oracle module implicitly imports datetime; make sure this
       happens."""
    finder.IncludeModule('datetime')
    try:
        finder.IncludeModule('decimal')
    except ImportError:
        pass


def chunk(end: int, chunksize: int):
    """Generate tuples of (start_idx, end_idx) that breaks a sequence into
    slices of `chunksize` length"""
    _start = 0
    if end > chunksize:
        for _end in range(chunksize, end, chunksize or 1):
            yield _start, _end
            _start = _end
    yield _start, end


@classmethod
def _indexed_root(cls, poly, index):
    """Get a root of a composite polynomial by index."""
    _, factors = poly.factor_list()
    reals = cls._get_reals(factors)
    reals_count = cls._count_roots(reals)
    if index < reals_count:
        reals = cls._reals_sorted(reals)
        return cls._reals_index(reals, index)
    else:
        complexes = cls._get_complexes(factors)
        complexes = cls._refine_imaginaries(complexes)
        complexes = cls._complexes_sorted(complexes)
        return cls._complexes_index(complexes, index - reals_count)


def _parse_error(hstore_str, pos):
    """format an unmarshalling error."""
    ctx = 20
    hslen = len(hstore_str)
    parsed_tail = hstore_str[max(pos - ctx - 1, 0):min(pos, hslen)]
    residual = hstore_str[min(pos, hslen):min(pos + ctx + 1, hslen)]
    if len(parsed_tail) > ctx:
        parsed_tail = '[...]' + parsed_tail[1:]
    if len(residual) > ctx:
        residual = residual[:-1] + '[...]'
    return 'After %r, could not parse residual at position %d: %r' % (
        parsed_tail, pos, residual)


@classmethod
def schema(cls):
    """Override this in a subclass to define model <=> API mappings"""
    raise NotImplementedError()


def _generate_implicit_chunks(npoints, explicit_chunks):
    """
    Make implicit chunk parameters explicit.

    Parameters
    ----------
    npoints : int
        The number of points.
    explicit_chunks : list
        The explicit chunks.

    Returns
    -------
    chunks : list
        The chunks including both explicit and implicit chunks.

    See Also
    --------
    _expand_buffer : Function using the present function.

    """
    chunks = []
    point_index = 0
    point_chunks = []
    stop_chunk = {'attrs': {'pointIndex': npoints, 'label': '_emptychunk_'}}
    for chunk in (explicit_chunks + [stop_chunk]):
        index = chunk['attrs'].get('pointIndex', 0)
        for point_index in range(point_index + 1, index):
            for point_chunk in point_chunks:
                point_chunk = point_chunk.copy()
                point_chunk['attrs'] = point_chunk['attrs'].copy()
                point_chunk['attrs']['pointIndex'] = point_index
                chunks.append(point_chunk)
        if chunk['attrs'].get('label', '').lower(
            ) == '_emptychunk_' and index <= npoints:
            break
        if point_index < index < npoints:
            point_index = point_index + 1
            point_chunks = []
        if index != point_index:
            raise IOError("The 'chunk' buffer parameter indices are erroneous."
                )
        chunks.append(chunk)
        point_chunks.append(chunk)
    return chunks


def change_indexes_0_to_1(key):
    """('RU') Функция используется в drange в __getitem__().
	a[1] > a[0]
	Она смещает в последовательностях номер первого элемента с [0] на [1] чтобы показать вам.
	если при a[arg] передается один аргумент, он int и пишется в keys
	если пытаешься брать срез, keys присваивается объект среза вида: slice(1, None, None)
	rev. 5
	"""
    if type(key) == int:
        if key >= 0:
            key += 1
    elif type(key) == slice:
        if key.step and key.step < 0:
            if key.start and key.start >= 0:
                start = key.start + 1
            else:
                start = key.start
            if key.stop != None:
                if key.stop >= 0:
                    stop = key.stop + 2
                else:
                    stop = key.stop
            else:
                stop = None
            key = slice(start, stop, key.step)
        else:
            if key.start >= 0:
                start = key.start + 1
            key = slice(start, key.stop, key.step)
    return key


def find_end_index(start_index, lines):
    """
    Given a start index and lines of data, finds the first line that
    contains only '' and returns the index for that line.
    """
    end_index = None
    for line in lines[start_index:]:
        if line == '':
            end_index = lines.index(line, start_index)
            break
    return end_index


def populate_step(registry):
    """ Populate data step.

    :param registry: Pyramid :py:class:`pyramid.registry.Registry` object
    """


def sparse_matrix_indices(spmat):
    """Return the indices of the given sparse matrix.

    Parameters
    ----------
    spmat : SparseMatrix
        The framework-specific sparse matrix.

    Returns
    -------
    index : tuple
        This is used to support different sparse formats.
        For COO format:
          index=('coo', coord), where coord is of shape (2, nnz).
          coord[0,:] should be the row index and coord[1,:] should be
          the column index.
        For CSR format:
          index=('csr', indices, indptr), where indices is of shape (nnz,)
          and indptr is of shape (nrows+1,). See ``scipy.sparse.csr_matrix``
          for more documents on what each array means.
    """
    pass


def set_pyami_proxy(proxy):
    """
    Pick the hostname or group to use for the pyami connection.

    Parameters
    ----------
    proxy: ``str`` or ``int``
        Either the server name or group number
    """
    globals()['ami_proxy'] = proxy


def future_set_result_unless_cancelled(future, value):
    """Set the given ``value`` as the `Future`'s result, if not cancelled.

    Avoids asyncio.InvalidStateError when calling set_result() on
    a cancelled `asyncio.Future`.

    .. versionadded:: 5.0
    """
    if not future.cancelled():
        future.set_result(value)


def enqueue_output(out, queue):
    """A utility method for consuming piped output from a subprocess.

    Reads content from `out` one line at a time, and puts it onto
    queue for consumption in a separate thread.
    """
    for line in iter(out.readline, b''):
        queue.put(line.strip().decode('utf-8'))
    out.close()


def collapse():
    """Collapse this node.
        """


def escape(s, quote=False):
    """Replace special characters "&", "<" and ">" to HTML-safe sequences.  If
    the optional flag `quote` is `True`, the quotation mark character is
    also translated.

    There is a special handling for `None` which escapes to an empty string.

    :param s: the string to escape.
    :param quote: set to true to also escape double quotes.
    """
    if s is None:
        return ''
    if not isinstance(s, (str, bytes)):
        s = str(s)
    if isinstance(s, bytes):
        try:
            s.decode('ascii')
        except UnicodeDecodeError:
            s = s.decode('utf-8', 'replace')
    s = s.replace('&', '&').replace('<', '<').replace('>', '>')
    if quote:
        s = s.replace('"', '"')
    return s


def get_index_lists(partition_columns):
    """
    Find lists of indices for partition_ids level-sets

    :param partition_columns: non-empty list of lists of list of hashables/comparables
    :return: dictionary of index lists for each level-set of the keys
    """
    index_lists = {}
    for i in range(len(partition_columns[0])):
        pi = []
        for j in range(len(partition_columns)):
            pi.append(partition_columns[j][i])
        pi = tuple(pi)
        try:
            lst = index_lists[pi]
        except KeyError:
            lst = []
            index_lists[pi] = lst
        lst.append(i)
    return index_lists


@staticmethod
def cacheable(cache_key):
    """Indicates whether artifacts associated with the given `cache_key` should be cached.

        :return: `True` if the `cache_key` represents a cacheable set of target artifacts.
        :rtype: bool
        """
    return cache_key.cacheable


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 lambd_NH3_HCOO_CB89(T, P):
    """n-a: ammonia methanoate [CB89]."""
    lambd = 0.048
    valid = T == 298.15
    return lambd, valid


@classmethod
def getJobStore(cls, locator):
    """
        Create an instance of the concrete job store implementation that matches the given locator.

        :param str locator: The location of the job store to be represent by the instance

        :return: an instance of a concrete subclass of AbstractJobStore
        :rtype: toil.jobStores.abstractJobStore.AbstractJobStore
        """
    name, rest = cls.parseLocator(locator)
    if name == 'file':
        from toil.jobStores.fileJobStore import FileJobStore
        return FileJobStore(rest)
    elif name == 'aws':
        from toil.jobStores.aws.jobStore import AWSJobStore
        return AWSJobStore(rest)
    elif name == 'google':
        from toil.jobStores.googleJobStore import GoogleJobStore
        return GoogleJobStore(rest)
    else:
        raise RuntimeError("Unknown job store implementation '%s'" % name)


def create_name_behavior_id(name: str, team_id: int) ->str:
    """
   Reconstructs fully qualified behavior name from name and team_id
   :param name: brain name
   :param team_id: team ID
   :return: name_behavior_id
   """
    return name + '?team=' + str(team_id)


def component_name(relative_path):
    """Returns a component name. This method must be a
        class- or static method."""


def mouse_aabb(mpos, size, pos):
    """
    AABB Collision checker that can be used for most axis-aligned collisions.

    Intended for use in widgets to check if the mouse is within the bounds of a particular widget.
    """
    return pos[0] <= mpos[0] <= pos[0] + size[0] and pos[1] <= mpos[1] <= pos[1
        ] + size[1]


def div(numer, denom):
    """PFA division behavior: inf and -inf for a finite number divided by zero and nan for 0/0.

    Also ensures that return type of any two numbers (including integers) is floating point.

    :type numer: number
    :param numer: the numerator
    :type denom: number
    :param denom: the denominator
    :rtype: float
    :return: fraction, including non-numeric possibilities
    """
    try:
        return numer / float(denom)
    except ZeroDivisionError:
        if numer > 0.0:
            return float('inf')
        elif numer < 0.0:
            return float('-inf')
        else:
            return float('nan')


@classmethod
def project_path(cls, project):
    """Returns a fully-qualified project resource name string."""
    return cls._PROJECT_PATH_TEMPLATE.render({'project': project})


def read(schemaNode, schema):
    """Called once the schema in the given <schema /> node has been
        read. schema is the schema interface that was read.
        """


def latexify_number(str_float):
    """Change exponential notation into something nicer for latex.

    This will change exponential notation, e.g ``1.2e-03``, into
    ``1.2 \\times 10^{-3}`` for latex output which should be rendered
    like :math:`1.2 \\times 10^{-3}`.

    Parameters
    ----------
    str_float : string
        This is the string representation of a float.

    Returns
    -------
    out : string
        A formatted string for latex.

    """
    if 'e' in str_float:
        base, exp = str_float.split('e')
        return '${0} \\times 10^{{{1}}}$'.format(base, int(exp))
    return '${}$'.format(str_float)


def marthas_columns(data, verbose=0):
    """
    This program is named  in honor of my one of students who came up with the idea for it.
    It's a neat way of looking at data compared to the boring describe() function in Pandas.
    """
    data = data[:]
    print('Data Set Shape: %d rows, %d cols\n' % data.shape)
    if data.shape[1] > 25:
        print('Too many columns to print')
    elif verbose == 1:
        print('Data Set columns info:')
        for col in data.columns:
            print('* %s: %d nulls, %d unique vals, most common: %s' % (col,
                data[col].isnull().sum(), data[col].nunique(), data[col].
                value_counts().head(2).to_dict()))
        print('\n------\n')


def ensure_only_one_of(collection, elements):
    """Raise ValueError if collection contains more than one of elements.

    Only distinct elements are considered. For mappings, the keys are
    considered.

    Args:
        collection: An iterable container.

        elements: A set of elements that must not appear together.

    Raises:
        ValueError: If *collection* contains more than one (distinct) element
            of *elements*.

    """
    found = set(collection) & set(elements)
    if len(found) > 1:
        raise ValueError('Mutually exclusive: {!r}'.format(found))


def statistics(xds, dv='IMAGE', mode='classic'):
    """
    Generate statistics on specified image data contents

    Resulting data is placed in the attributes section of the dataset

    Parameters
    ----------
    xds : xarray.core.dataset.Dataset
        input Image Dataset
    dv : str
        name of data_var in xds to compute statistics on. Default is 'IMAGE'
    mode : str
        algorithm mode to use ('classic', 'fit-half', 'hinges-fences', 'chauvenet', 'biweight'). Default is 'classic'

    Returns
    -------
    xarray.core.dataset.Dataset
        output Image
    """
    return xds


def _normalize(string):
    """ Normalize whitepace in a string according to PDS4 Standards.

    Notes
    -----
    There are a number of ways to implement this method. The employed implementation is generally
    either the fastest or close to the fastest between the various platforms.

    Parameters
    ----------
    string : str or unicode
        String to normalize.

    Returns
    -------
    str or unicode
        Whitespace-collapsed string. Collapses contiguous spaces (including line feeds, carriage returns,
        tabs) into a single space character, and removes leading and trailing spaces entirely.
         white space collapsed
    """
    return ' '.join(string.split())


def detect_cycle(history, min_size=1, max_size=12, offset=0):
    """Detects cycles in the sequence history.

    Mainly used by hunter strategies.

    Parameters
    ----------
    history: sequence of C and D
        The sequence to look for cycles within
    min_size: int, 1
        The minimum length of the cycle
    max_size: int, 12
        The maximum length of the cycle
    offset: int, 0
        The amount of history to skip initially

    Returns
    -------
    Tuple of C and D
        The cycle detected in the input history
    """
    history_tail = history[offset:]
    new_max_size = min(len(history_tail) // 2, max_size)
    for i in range(min_size, new_max_size + 1):
        has_cycle = True
        cycle = tuple(history_tail[:i])
        for j, elem in enumerate(history_tail):
            if elem != cycle[j % len(cycle)]:
                has_cycle = False
                break
        if has_cycle:
            return cycle
    return None


@staticmethod
def _mart_from_xml(xml):
    """Extract mart information from XML.

        Parse the xml to extract name and display name of each mart.

        Args:
            xml: ElementTree retrieved from Biomart

        Returns:
            generator for each node in the xml
        """
    for child in xml.findall('MartURLLocation'):
        yield child.attrib['name'], child.attrib['displayName']


def error_with_message(subcommand, reason, slack=None):
    """Raises a :py:exc:`RuntimeError` with `reason`, but if `slack` is not
    :py:not before sending
    a message to Slack"""
    if slack:
        slack.post(subcommand, reason, color='xkcd:red')
    raise RuntimeError(reason)


def move_relaydomain_to_transport(apps, schema_editor):
    """Transform relaydomains to transports."""
    RelayDomain = apps.get_model('relaydomains', 'RelayDomain')
    RecipientAccess = apps.get_model('relaydomains', 'RecipientAccess')
    Transport = apps.get_model('transport', 'Transport')
    ra_to_create = []
    for rd in RelayDomain.objects.select_related('domain', 'service'):
        next_hop = '[{}]:{}'.format(rd.target_host, rd.target_port)
        tr = Transport.objects.create(pattern=rd.domain.name, service=
            'relay', next_hop=next_hop, _settings={'relay_target_host': rd.
            target_host, 'relay_target_port': rd.target_port,
            'relay_verify_recipients': rd.verify_recipients})
        rd.domain.transport = tr
        rd.domain.save(update_fields=['transport'])
        if not rd.verify_recipients:
            continue
        ra_to_create.append(RecipientAccess(pattern=rd.domain.name, action=
            'reject_unverified_recipient'))
    RecipientAccess.objects.bulk_create(ra_to_create)


def findall(root, xpath, attribute_name=None, attribute_value=None):
    """Find elements recursively from given root element based on
    xpath and possibly given attribute

    :param root: Element root element where to start search
    :param xpath: xpath defintion, like {http://foo/bar/namespace}ElementName
    :param attribute_name: name of possible attribute of given element
    :param attribute_value: value of the attribute
    :return: list of elements or None
    """
    found_elements = []
    if attribute_name is not None and attribute_value is not None:
        xpath = '%s[@%s="%s"]' % (xpath, attribute_name, attribute_value)
    found_elements = root.findall('.//' + xpath)
    if found_elements == []:
        found_elements = None
    return found_elements


@staticmethod
def truncate(slider):
    """
        Used to truncate slider values since ttk doesn't support the resolution option.
        :return:
        """
    value = slider.get()
    if int(value) != value:
        slider.set(int(value))


def convert_value_to_type(str_value, python_type_name):
    """
    Converts a value to a specific Python primitive type.

    :param python_type_name: Python primitive type name (case insensitive)
    :raises ~exceptions.ValueError: for unsupported types or conversion failure
    """
    python_type_name = python_type_name.lower()
    try:
        if python_type_name in ('str', 'unicode'):
            return str_value.decode('utf-8')
        elif python_type_name == 'int':
            return int(str_value)
        elif python_type_name == 'bool':
            return bool(str_value)
        elif python_type_name == 'float':
            return float(str_value)
        else:
            raise ValueError('Unsupported Python type name: {0}'.format(
                python_type_name))
    except ValueError:
        raise ValueError('Failed to to convert {0} to {1}'.format(str_value,
            python_type_name))


def second_order_moments(S1, S2):
    """Calculates the combined second order moment.

    Given the partial centered moments of two partitions (S1 and S2) of a data
    set S, calculates the second order moments of S = S1 ∪ S2.

    Parameters
    ----------
    S1 : array
       Contains `(T1, mu1, M1)` where `T1` is an integer (number of elements
       in the partition, e.g., the number of time frames), `mu1` is an
       `n x m` array of the means for `n` atoms (and for example, `m=3` for
       the center of geometry), `M1` is also an `n x m` array of the sum of
       squares.
    S2 : array
       Contains `(T2, mu2, M2)` where `T2` is an integer (number of elements
       in the partition, e.g., the number of time frames), `mu2` is an
       `n x m` array of the means for `n` atoms (and for example, `m=3` for
       the center of geometry), `M2` is also an `n x m` array of the sum of
       squares.

    Returns
    -------
    S : (T, mu, M)
       The returned tuple contains the total number of elements in the
       partition `T`, the mean `mu` and the "second moment" `M` (sum of
       squares) for the combined data.

    Notes
    -----
    For a given set of data, the sum of squares, also known as the second
    order moment about the mean, is defined as the sum of the squares of the
    differences between each data point and the mean (sum of the individual
    deviations from the mean) of the data set,

    .. math::

        M_{2, S_{i}} = \\sum_{t=t_{0}}^{T}(x_{t} - \\mu_{i})^2,

    where :math:`\\mu_{i}` is the time average of :math:`x_{t}`. If the
    average of the squares of the individual deviations is taken (instead of
    the sum), this yields the variance:

    .. math::

        \\sigma_{i}^{2} = \\frac{1}{T}\\sum_{t=t_{0}}^{T}(x_{t} - \\mu_{i})^2

    In order to combine the mean and second order moments of two separate
    partitions, [CGL1979]_ derived the following formulae:

    .. math::

        \\mu = \\frac{T_{1}\\mu_{1} + T_{2}\\mu_{2}}{T}

    and

    .. math::

        M_{2, S} = M_{2, S_{1}} + M_{2, S_{2}} + \\
        \\frac{T_{1}T_{2}}{T}(\\mu_{2} - \\mu_{1})^{2},

    where :math:`T`, :math:`T_{1}`, and :math:`T_{2}` are the respective
    cardinalities of :math:`S`, :math:`S_{1}`, and :math:`S_{2}`, :math:`\\mu`,
    :math:`\\mu_{1}`, and :math:`\\mu_{2}` are the respective means of
    :math:`S`, :math:`S_{1}`, and :math:`S_{2}`, and :math:`M_{2, S}`,
    :math:`M_{2, S_{1}}`, and :math:`M_{2, S_{2}}` are the respective second
    order moments of :math:`S`, :math:`S_{1}`, and :math:`S_{2}`. This is
    similar notation to [Pebay2008]_. With a combined sum of squares and mean,
    it is possible to calculate the root-mean-square fluctuations, otherwise
    known as the population standard deviation:

    .. math::

        \\sigma_{i} = \\sqrt{\\frac{1}{T} \\
        \\sum_{t=t_{0}}^{T}(x_{t} - \\mu_{i})^2}

    References
    ----------
    .. [CGL1979] T. F. Chan, G. H. Golub, and R. J. LeVeque. "Updating
       formulae and a pairwise algorithm for computing sample variances."
       Technical Report STAN-CS-79-773, Stanford University, Department of
       Computer Science, 1979.
    .. [Pebay2008] P. Pebay. "Formulas for robust one-pass parallel
       computation of co-variances and arbitrary-order statistical moments."
       Technical Report SAND2008-6212, 2008.

    .. versionadded:: 0.3.0
    """
    T = S1[0] + S2[0]
    mu = (S1[0] * S1[1] + S2[0] * S2[1]) / T
    M = S1[2] + S2[2] + S1[0] * S2[0] / T * (S2[1] - S1[1]) ** 2
    S = T, mu, M
    return S


@classmethod
def from_config(cls, name, config):
    """Create a DataSource from a datasource config"""
    return cls(name, reflect=True, config=config)


@staticmethod
def _drop_keys(obj, keys):
    """
        Remove the specified keys from the object.

        :param obj: target object
        :param keys: list of keys
        :return:
        """
    if not obj:
        return obj
    for k in keys:
        obj.pop(k, None)


def min_if_exist(n1, n2):
    """
    Returns the minimum between two numbers, or the only defined number
    (in case the other is `None`) or `None` if none of the numbers are defined.
    """
    if n1 is None and n2 is None:
        return None
    elif n1 is None:
        return n2
    elif n2 is None:
        return n1
    return min(n1, n2)


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

    The ".dev0" means dirty.

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


def store_assign_analysis_code(apps, schema_editor):
    """Assign the Internet AalysisCode to all existing sales"""
    sale_analysis_code_class = apps.get_model('Store', 'SaleAnalysisCode')
    sale_class = apps.get_model('Store', 'Sale')
    sale_analysis_code = sale_analysis_code_class.objects.get_or_create(name
        =u'Internet')[0]
    for sale in sale_class.objects.filter(analysis_code__isnull=True):
        sale.analysis_code = sale_analysis_code
        sale.save()


def roundup(num, bits):
    """ Round up a number to nearest multiple of 2^bits. The result is a number
        where the least significant bits passed in bits are 0.
    """
    return (num - 1 | (1 << bits) - 1) + 1


def canAddToGroup(group_id):
    """True iff member can be added to group."""


def to_datetimepicker_format(python_format_string):
    """
    Given a python datetime format string, attempts to convert it to
    the nearest PHP datetime format string possible.
    """
    python2PHP = {'%a': 'D', '%A': 'l', '%b': 'M', '%B': 'F', '%c': '',
        '%d': 'd', '%H': 'H', '%I': 'h', '%j': 'z', '%m': 'm', '%M': 'i',
        '%p': 'A', '%S': 's', '%U': '', '%w': 'w', '%W': 'W', '%x': '',
        '%X': '', '%y': 'y', '%Y': 'Y', '%Z': 'e'}
    php_format_string = python_format_string
    for py, php in python2PHP.items():
        php_format_string = php_format_string.replace(py, php)
    return php_format_string


def get_google_vision_version():
    """Get Google Vision version"""
    return f'Google Vision 0.33.0'


def _user_dir_get_symbol(directory_type: str, directories_table: dict,
    unexisting_msg: str) ->str:
    """
    Check that the requested directory type is defined in the selected user directories table
    and return the directory symbol corresponding to this type.

    :param directory_type: the code of some user directory
    :param directories_table: for each directory type, provides its associated symbol
    :param unexisting_msg: part of the exception message raised when directory type is not found
    :raises KeyError: when the directory type is unsupported in the selected configuration
    :returns: the directory symbol to use for this directory type
    """
    if directory_type not in directories_table:
        msg = 'User directory type "{}" is {}. Please choose one from {}.'
        raise KeyError(msg.format(directory_type, unexisting_msg,
            directories_table))
    return directories_table[directory_type]


def get_cache_key(page, language):
    """
    Create the cache key for the current page and language
    """
    from cms.cache import _get_cache_key
    try:
        site_id = page.node.site_id
    except AttributeError:
        site_id = page.site_id
    return _get_cache_key('page_meta', page, language, site_id)


def describe_tags(Filters=None, NextToken=None, MaxRecords=None):
    """
    Describes the specified tags.
    You can use filters to limit the results. For example, you can query for the tags for a specific Auto Scaling group. You can specify multiple values for a filter. A tag must match at least one of the specified values for it to be included in the results.
    You can also specify multiple filters. The result includes information for a particular tag only if it matches all the filters. If there's no match, no special message is returned.
    See also: AWS API Documentation

    Examples
    This example describes the tags for the specified Auto Scaling group.
    Expected Output:

    :example: response = client.describe_tags(
        Filters=[
            {
                'Name': 'string',
                'Values': [
                    'string',
                ]
            },
        ],
        NextToken='string',
        MaxRecords=123
    )

    :type Filters: list
    :param Filters: A filter used to scope the tags to return.
            (dict) --Describes a filter.
            Name (string) --The name of the filter. The valid values are: 'auto-scaling-group' , 'key' , 'value' , and 'propagate-at-launch' .
            Values (list) --The value of the filter.
            (string) --

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

    :type MaxRecords: integer
    :param MaxRecords: The maximum number of items to return with this call. The default value is 50 and the maximum value is 100.

    :rtype: dict
    :return: {
        'Tags': [
            {
                'ResourceId': 'string',
                'ResourceType': 'string',
                'Key': 'string',
                'Value': 'string',
                'PropagateAtLaunch': True|False
            },
        ],
        'NextToken': 'string'
    }

    """
    pass


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

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

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


def fs15f16(x):
    """Convert float to ICC s15Fixed16Number (as a Python ``int``)."""
    return int(round(x * 2 ** 16))


@staticmethod
def get_environment_metadata():
    """
        For debugging purposes, returns a dict containing information
        about the environment, like the version of the SCM client, or
        version of libraries involved.
        Suggest considering keywords "version", "dependency", "features" first.
        :returns: a dict containing relevant information
        :rtype: dict
        """
    raise NotImplementedError(
        'Base class get_environment_metadata method must be overridden')


@staticmethod
def upgrade():
    """Migrate the database to `version` or the most recent version."""


@staticmethod
def get_addresses_model():
    """
        This is needed so the BaseState can validate the
        provided addresses and throw an error if any are missing.
        As well as automatically generate documentation.
        NOTE: types must always be "str"
        return = {
            'required_addresses': {
                'req_address_name_1': str,
                'req_address_name_2': str,
            },
            'optional_addresses': {
                'opt_address_name_1': str,
                'opt_address_name_2': str,
            },
        }
        """
    return {'required_addresses': {'subscriber': str, 'requester': str},
        'optional_addresses': {}}


def _switch(session: 'DebugSession', connection_name: str):
    """ Switch to a different connection

    :param session: Current DebugSession
    :param connection_name: Name of the connection
    """
    session.current_connection_name = connection_name


def idxfold(dlist, idx):
    """ Find the index corresponding to the folded version of a tensor from the flatten version

    :param list,int dlist: list of integers containing the dimensions of the tensor
    :param int idx: tensor flatten index

    :returns: list of int -- the index for the folded version

    :note: this routine can be used to get the indexes of a TTmat from indices of a matkron (matrix obtained using np.kron): (i,j) \\in N^d x N^d -> ((i_1,..,i_d),(j_1,..,j_d)) \\in (N x .. x N) x (N x .. x N)

    """
    n = len(dlist)
    cc = [1]
    for val in reversed(dlist):
        cc.append(cc[-1] * val)
    if idx >= cc[-1]:
        raise NameError('TensorToolbox.core.idxunfold: Index out of bounds')
    ii = []
    tmp = idx
    for i in range(n):
        ii.append(tmp // cc[n - i - 1])
        tmp = tmp % cc[n - i - 1]
    return tuple(ii)


def mayDelete(context):
    """
          This method returns True if current context is deletable.
          The default implementation does the work for checking 'Delete objects' on the
          object we want to delete, not that permission on the parent.
        """


def boundary(costheta, a=1, epsilon=0.1, nu=0):
    """Projected boundary of a prolate spheroid

    Compute the boundary according to equation (4) in
    :cite:`Boyde2009` with the addition of the
    Poisson's ratio of the object.

    .. math::

       B(\\theta) = a (1+\\epsilon)
       \\left[ (1+\\epsilon)^2 - \\epsilon (1+\\nu)
       (2+\\epsilon (1-\\nu)) \\cos^2 \\theta \\right]^{-1/2}

    This boundary function was derived for a prolate spheroid under
    the assumption that the semi-major axis :math:`a` and the
    semi-minor axes :math:`b=c` are defined as

    .. math::

       a = b \\cdot \\frac{1+ \\epsilon}{1- \\nu \\epsilon}

    The boundary function :math:`B(\\theta)` can be derived with
    the above relation using the equation for a prolate spheroid.

    Parameters
    ----------
    costheta: float or np.ndarray
        Cosine of polar coordinates :math:`\\theta`
        at which to compute the boundary.
    a: float
        Equatorial radii of prolate spheroid (semi-minor axis).
    epsilon: float
        Stretch ratio; defines size of semi-major axis:
        :math:`a = (1+\\epsilon) b`. Note that this is not
        the eccentricity of the prolate spheroid.
    nu: float
        Poisson's ratio :math:`\\nu` of the material.

    Returns
    -------
    B: 1d ndarray
        Radial object boundary in dependence of theta
        :math:`B(\\theta)`.

    Notes
    -----
    For :math:`\\nu=0`, the above equation becomes
    equation (4) in :cite:`Boyde2009`.
    """
    x = costheta
    B = a * (1 + epsilon) / ((1 + epsilon) ** 2 - epsilon * (1 + nu) * (2 +
        epsilon * (1 - nu)) * x ** 2) ** 0.5
    return B


def encode_key_as_entity(obj):
    """Get the Entity from the ndb.Key for further encoding."""
    return obj.get_async()


def point_plane_intersection(plane_normal, plane_point, line_a, line_b,
    epsilon=1e-06):
    """
    Determines the intersection point of a plane defined by a point and a normal vector and the line
    defined by line_a and line_b. All should be numpy arrays.

    :param plane_normal:
    :param plane_point:
    :param line_a:
    :param line_b:
    :param epsilon:
    :return:
    """
    line_direction = line_b - line_a
    if abs(plane_normal.dot(line_direction)) < epsilon:
        return None
    delta = line_a - plane_point
    projection = -plane_normal.dot(delta) / plane_normal.dot(line_direction)
    return delta + projection * line_direction + plane_point


def _init_2d_nested_dict(keys1, keys2):
    """Creates 2-dimensional nested dict that are meant to hold a variable.

    :param keys1: Keys for the first level as a list-like element
    :param keys2: Keys for the second level as a list-like element
    """
    var = dict.fromkeys(keys1)
    for k1 in keys1:
        var[k1] = dict.fromkeys(keys2)
    return var


def sum_them_all(student_marks):
    """Sum all marks of a student."""
    total_mark = 0
    for i in range(0, len(student_marks)):
        total_mark += int(student_marks[i]['student_mark'])
    return total_mark


def trim_trailing_lines(lines):
    """
    Trim trailing blank lines.
    """
    lines = list(lines)
    while lines and not lines[-1]:
        lines.pop(-1)
    return lines


def _from_future(action, *, future):
    """Return the coros from the action that are children of the future."""
    coros = []
    future_matched = False
    while action.source:
        coros.append(action.coro)
        if getattr(action.source, 'future', None) is future:
            future_matched = True
            break
        action = action.source
    if not future_matched:
        return []
    else:
        return coros


def has_time_series(args):
    """Returns whether there's some kind of time-series ID

    """
    return args.time_series or args.time_series_set or args.time_series_file


@classmethod
def is_datasource_for(cls, data, header, **kwargs):
    """Determines if header corresponds to an COR image"""
    return str(header.get('detector', '')).startswith('COR')


def __len__():
    """Return the number of entries in the manifest."""


@classmethod
def get_version(cls, settings, path):
    """Generate the version string to be used in static URLs.
        ``settings`` is the `Application.settings` dictionary and ``path``
        is the relative location of the requested asset on the filesystem.
        The returned value should be a string, or ``None`` if no version
        could be determined.
        .. versionchanged:: 3.1
           This method was previously recommended for subclasses to override;
           `get_content_version` is now preferred as it allows the base
           class to handle caching of the result.
        """
    abs_path = cls.get_absolute_path(settings['static_path'], path)
    return cls._get_cached_version(abs_path)


def _del(isdsAppliance, uuid):
    """
    Remove all UUIDs - should be everything pertaining to an advanced tuning parameter "key"

    :param isdsAppliance:
    :param uuid:
    :return:
    """
    ret_obj = isdsAppliance.create_return_object()
    ret_obj['data'] = []
    for u in uuid:
        r = isdsAppliance.invoke_delete(
            'Deleting existing advanced tuning parameter',
            '/adv_params/{0}'.format(u))
        ret_obj['changed'] = ret_obj['changed'] or r['changed']
        ret_obj['data'].append(r['data'])
        ret_obj['warnings'].extend(r['warnings'])
        ret_obj['rc'] += r['rc']
    return ret_obj


def choose_words(words):
    """
        Submit the final words.

        This should be called when the user is finished typing in the code,
        and terminates the code-entry process.  It does not return anything,
        but will cause the Wormhole's ``w.get_code()`` to fire, and initiates
        the wormhole connection process.

        It accepts a string like "purple-sausages", without the leading
        nameplate (which must have been submitted to ``choose_nameplate()``
        earlier) or its hyphen.  If ``choose_nameplate()`` was not called
        first, this will raise ``MustChooseNameplateFirstError``.

        This may only be called once, otherwise ``AlreadyChoseWordsError``
        will be raised.

        :param str words: the 'words' portion of the wormhole code

        :return: None
        """


@classmethod
def parse(cls, buff, offset):
    """
        Given a buffer and offset, returns the parsed value and new offset.

        Calls `parse()` on the given buffer for each sub-part in order and
        creates a new instance with the results.
        """
    values = {}
    for name, part in cls.parts:
        value, new_offset = part.parse(buff, offset)
        values[name] = value
        offset = new_offset
    return cls(**values), offset


def get(name, default=None, aggregate=False, depth=-1, breakiface=None):
    """Acquire data from node.

        @param name: key of requested data.
        @param default: default return value.
        @param aggregate: Flag wether to aggregate requested value.
        @param depth: recurion depth. default ``-1`` is recurion until root.
        @param breakiface: ``zope.Interface`` defining the acquisition break
                           point.
        """


def _preprocess_line(raw_line):
    """Replaces tabs with spaces and removes trailing end of line markers.

    >>> _preprocess_line('foo \\r\\n\\n')
    'foo '

    """
    return raw_line.expandtabs(4).rstrip('\r\n')


def round_channels(channels, divisor=8):
    """
    Round weighted channel number (make divisible operation).

    Parameters:
    ----------
    channels : int or float
        Original number of channels.
    divisor : int, default 8
        Alignment value.

    Returns
    -------
    int
        Weighted number of channels.
    """
    rounded_channels = max(int(channels + divisor / 2.0) // divisor *
        divisor, divisor)
    if float(rounded_channels) < 0.9 * channels:
        rounded_channels += divisor
    return rounded_channels


@staticmethod
def find_frequent_items(transactions, threshold):
    """
        Create a dictionary of items with occurrences above the threshold.
        """
    items = {}
    for transaction in transactions:
        for item in transaction:
            if item in items:
                items[item] += 1
            else:
                items[item] = 1
    for key in list(items.keys()):
        if items[key] < threshold:
            del items[key]
    return items


def splice(l, a, b, c):
    """ JS's Array.prototype.splice
    var x = [1, 2, 3],
        y = x.splice(0, 2, 1337);
    eq
    x = [1, 2, 3]
    x, y = splice(x, 0, 2, 1337)
    """
    return l[:a] + [c] + l[a + b:], l[a:a + b]


def use_production(flag):
    """调用生产环境 / 开发环境的 cloud func / cloud hook
    默认调用生产环境。
    """
    global USE_PRODUCTION
    USE_PRODUCTION = '1' if flag else '0'


def get_columns_diff(changes):
    """Add the changed columns as a diff attribute.

    - changes: a list of changes (get_model_changes query.all())

    Return: the same list, to which elements we added a "diff"
    attribute containing the changed columns. Diff defaults to [].
    """
    for change in changes:
        change.diff = []
        elt_changes = change.get_changes()
        if elt_changes:
            change.diff = elt_changes.columns
    return changes


@staticmethod
def serialize_bytes(data):
    """Write bytes by using Telegram guidelines"""
    if not isinstance(data, bytes):
        if isinstance(data, str):
            data = data.encode('utf-8')
        else:
            raise TypeError('bytes or str expected, not {}'.format(type(data)))
    r = []
    if len(data) < 254:
        padding = (len(data) + 1) % 4
        if padding != 0:
            padding = 4 - padding
        r.append(bytes([len(data)]))
        r.append(data)
    else:
        padding = len(data) % 4
        if padding != 0:
            padding = 4 - padding
        r.append(bytes([254, len(data) % 256, (len(data) >> 8) % 256, (len(
            data) >> 16) % 256]))
        r.append(data)
    r.append(bytes(padding))
    return b''.join(r)


def maybe_set(t):
    """Return tuple of one element if ``t`` is a scalar."""
    return t if t is None or isinstance(t, set) else {t}


def load_GifImagePlugin(finder, module):
    """The GifImagePlugin module optionally imports the _imaging_gif module"""
    module.IgnoreName('_imaging_gif')


def get_aparc_aseg(files):
    """Return the aparc+aseg.mgz file"""
    for name in files:
        if 'aparc+aseg.mgz' in name:
            return name
    raise ValueError('aparc+aseg.mgz not found')


def moleccm3_2_ppb(concentration):
    """Turns molecules/cm3 into ppb assuming Air Molar Volume of 22.4 L/mol
    """
    Na = 6.022e+23
    return concentration / (1 / 22400.0 * Na) * 10 ** 6


@classmethod
def from_string(cls, s):
    """
        Create Register object from string.

        :param s: must have the form: "llvm_type:constraint_char"
        """
    llvm_type, constraint_char = s.split(':', 1)
    valid_cc = 'rx'
    if constraint_char not in valid_cc:
        raise ValueError('Invalid constraint character, must be one of {!r}'
            .format(valid_cc))
    return cls(llvm_type, constraint_char)


@staticmethod
def is_backtestable() ->bool:
    """
        Should be overwritten
        :return: True if the TradingMode can be used in a backtesting else False
        """
    return True


def get_typename(x):
    """Returns the name of the type of x, if x is an object.  Otherwise, returns the name of x.
    """
    if isinstance(x, type):
        ret = x.__name__
    else:
        ret = x.__class__.__name__
    return ret


def format_print_text(text, color_fg=None, color_bg=None):
    """Format given text using ANSI formatting escape sequences.

    Could be useful gfor print command.

    :param str|unicode text:
    :param str|unicode color_fg: text (foreground) color
    :param str|unicode color_bg: text (background) color
    :rtype: str|unicode
    """
    from .config import Section
    color_fg = {'black': '30', 'red': '31', 'reder': '91', 'green': '32',
        'greener': '92', 'yellow': '33', 'yellower': '93', 'blue': '34',
        'bluer': '94', 'magenta': '35', 'magenter': '95', 'cyan': '36',
        'cyaner': '96', 'gray': '37', 'grayer': '90', 'white': '97'}.get(
        color_fg, '39')
    color_bg = {'black': '40', 'red': '41', 'reder': '101', 'green': '42',
        'greener': '102', 'yellow': '43', 'yellower': '103', 'blue': '44',
        'bluer': '104', 'magenta': '45', 'magenter': '105', 'cyan': '46',
        'cyaner': '106', 'gray': '47', 'grayer': '100', 'white': '107'}.get(
        color_bg, '49')
    mod = ';'.join([color_fg, color_bg])
    text = '%(esc)s[%(mod)sm%(value)s%(end)s' % {'esc': Section.vars.
        FORMAT_ESCAPE, 'end': Section.vars.FORMAT_END, 'mod': mod, 'value':
        text}
    return text


def append_url_params(base_url, param_dict):
    """Append parameters to a base url.

  Args:
    base_url: the basic url, end with ?
    param_dict: dictionary of parameters.
  Returns:
    a complete url.
  """
    url = base_url
    started = False
    for key, val in param_dict.iteritems():
        if val is not None:
            url = url + '&' if started else url
            url += '{}={}'.format(key, val)
            started = True
    return url


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

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

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


def __ne__(A, other):
    """Returns true if both objects are not equal"""
    return not A == other


def addEnvPath(env, name, value):
    """ concat a path for this name """
    try:
        oldval = env[name]
        if not oldval.endswith(';'):
            oldval = oldval + ';'
    except KeyError:
        oldval = ''
    if not value.endswith(';'):
        value = value + ';'
    env[name] = oldval + value


def format_rel_url(url):
    """ Formats from the form path/to to /path/to, if required.

    @return: formatted string
    @rtype: string
    """
    if not url:
        return url
    if not url.startswith('/'):
        return '/%s' % url
    else:
        return url


def select_pattern(pattern: str='*', case_sensitive: bool=False, extend:
    bool=True):
    """Select objects matching a naming pattern

    :param pattern: Pattern, Name filter using ‘*’, ‘?’ and ‘[abc]’ unix style wildcards
    :type pattern: str
    :param case_sensitive: Case Sensitive, Do a case sensitive compare
    :type case_sensitive: bool
    :param extend: Extend, Extend the existing selection
    :type extend: bool
    """
    pass


@classmethod
def from_dict(cls, d):
    """
        Creates an instance of the class from a dictionary representation.
        :return: The instance.
        """
    raise NotImplementedError()


def arange(start, stop):
    """Create a 1D range int64 tensor.

    Parameters
    ----------
    start : int
        The range start.
    stop : int
        The range stop.

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


def _str_to_bool(text: str) ->bool:
    """
    Converts the text to a boolean value.
    """
    if text == '0':
        return False
    elif text == '1':
        return True
    else:
        raise ValueError('Cannot convert text "' + text + '" to bool.')


@staticmethod
def to_newton(rankine):
    """ Convert rankine to newton """
    return (rankine - 491.67) * 11 / 60


def psi_H_Mg_Cl_RGB80(T, P):
    """c-c': hydrogen magnesium chloride [RGB80]."""
    theta = 0.001
    valid = T == 298.15
    return theta, valid