def getDefaultFileDoc(fName, anchor):
    """Provides a body (i.e. help) of the default auto doc"""
    return (
        """Codimension supports markdown for the documentation purposes.

A doc link to this file has been inserted into your python file. When it
is clicked on the graphics pane this file will be displayed.

The source code doc link also has a generated anchor (${anchor}) so the
documentation can refer specifically to that doc link. To do so use the
following format:

```
[See in the source code](file:${fName}#${anchor})
```

When clicked, the source code file will be opened and scrolled to the doc link.

Please discard these instructions, provide the required content and save as
needed.
"""
        .replace('${fName}', fName).replace('${anchor}', anchor))


def filter_entity(entity_ref):
    """Filter out private items in an entity dict.

    :param entity_ref:  the entity dictionary. The 'dn' field will be removed.
        'dn' is used in LDAP, but should not be returned to the user.  This
        value may be modified.

    :returns: entity_ref

    """
    if entity_ref:
        entity_ref.pop('dn', None)
    return entity_ref


def _preprocess(statement):
    """Preprocess the input statement."""
    statement = statement.strip()
    statement = statement.replace('"', "'")
    if statement[-1] != ';':
        statement += ';'
    return statement


def sorted_by_ufl_id(seq):
    """Sort a sequence by the item.ufl_id()."""
    return sorted(seq, key=lambda x: x.ufl_id())


def generatePandaEnumCols(pandaFtrain, cname, nrows, domainL):
    """
    For an H2O Enum column, we perform one-hot-encoding here and add one more column, "missing(NA)" to it.

    :param pandaFtrain: panda frame derived from H2OFrame
    :param cname: column name of enum col
    :param nrows: number of rows of enum col
    :return: panda frame with enum col encoded correctly for native XGBoost
    """
    import numpy as np
    import pandas as pd
    cmissingNames = [cname + '.missing(NA)']
    tempnp = np.zeros((nrows, 1), dtype=np.int)
    colVals = pandaFtrain[cname]
    for ind in range(nrows):
        try:
            if not colVals[ind] in domainL:
                tempnp[ind] = 1
        except ValueError:
            pass
    zeroFrame = pd.DataFrame(tempnp)
    zeroFrame.columns = cmissingNames
    temp = pd.get_dummies(pandaFtrain[cname], prefix=cname, drop_first=False)
    tempNames = list(temp)
    colLength = len(tempNames)
    newNames = ['a'] * colLength
    for ind in range(0, colLength):
        newNames[ind] = cname + '_' + domainL[ind]
    ftemp = temp[newNames]
    ctemp = pd.concat([ftemp, zeroFrame], axis=1)
    return ctemp


def DBG(text):
    """DBG - temporary debugging function

    Args:
        text (str): text to print
    """
    print(f'LEP: {text}')


def rect_compare(rect1, rect2, area):
    """Calculate the ratio of overlap between two rectangles and the given area

    :param rect1: rectangle specified as (x, y, w, h)
    :type rect1: tuple
    :param rect2: rectangle specificed as (x, y, w, h)
    :type rect2: tuple
    :param area: the area to compare to
    :type area: float
    :return: the ratio of the overlap of rect1 and rect2 to the area, e.g overlap(rect1, rect2)/area
    :rtype: float
    """
    xx1 = max(rect1[0], rect2[0])
    yy1 = max(rect1[1], rect2[1])
    xx2 = min(rect1[0] + rect1[2], rect2[0] + rect2[2])
    yy2 = min(rect1[1] + rect1[3], rect2[1] + rect2[3])
    w = max(0, xx2 - xx1 + 1)
    h = max(0, yy2 - yy1 + 1)
    return float(w * h) / area


@classmethod
def fromString(cls, worldString, CellClass=None, rule=None, eol='\n'):
    """
        XXX missing doc string
        """
    w = cls(CellClass, 0, 0)
    w.addPattern(worldString, 0, 0, rule=rule, eol=eol, resize=True)
    return w


def set_location(value):
    """Sets the location"""


def unpack_object_id(object_id):
    """Return ``(table_name, id)`` for ``object_id``::

          >>> unpack_object_id(u'questions#1234')
          (u'questions', 1234)
          >>> unpack_object_id(u'questions#*')
          (u'questions', None)

    """
    parts = object_id.split('#')
    try:
        parts[1] = int(parts[1])
    except ValueError:
        parts[1] = None
    return tuple(parts)


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 is_float(string):
    """Check if string can be converted to float."""
    try:
        float(string)
    except:
        return False
    else:
        return True


@classmethod
def _strategy_by_name(cls, name):
    """
        Return the strategy by its name.
        :param name: the name of the strategy
        """
    if not hasattr(cls, 'strategies'):
        cls.strategies = getattr(__import__('simplevisor.strategies'),
            'strategies')
    return getattr(cls.strategies, name)


def translate_ambiguous(seq):
    """Translate ambiguous characters from curly bracket format
    to single letter format and remove spaces from sequences.
    """
    seq = seq.replace('{GT}', 'K')
    seq = seq.replace('{AC}', 'M')
    seq = seq.replace('{AG}', 'R')
    seq = seq.replace('{CT}', 'Y')
    seq = seq.replace('{CG}', 'S')
    seq = seq.replace('{AT}', 'W')
    seq = seq.replace('{CGT}', 'B')
    seq = seq.replace('{ACG}', 'V')
    seq = seq.replace('{ACT}', 'H')
    seq = seq.replace('{AGT}', 'D')
    seq = seq.replace('{GATC}', 'N')
    seq = seq.replace(' ', '')
    return seq


def identity(arg):
    """
    Function which returns the argument. Used as a default lambda function.

    >>> obj = object()
    >>> obj is identity(obj)
    True

    :param arg: object to take identity of
    :return: return arg
    """
    return arg


@classmethod
def update_event(cls, event, form):
    """Updates ``event``, syncing changes to Google Calendar.

        Calls either :func:`update_series`, :func:`update_single_event`, or
        :func:`update_single_event_from_series` depending on whether the
        event is recurring and whether all updates in a series should be
        updated.

        If the event is being made recurring, or a recurrence is being removed,
        :func:`convert_to_series` or :func:`convert_to_single_event` will
        be called instead.

        :param event: The event to update.
        :type event: :class:`Event`
        :param form: The WTForms form from which the updates come.
        :type form: :class:`CreateEventForm` or a subclass.

        :raises: :class:`GoogleCalendarAPIError` and it's subclasses

        :returns: Response from the Google Calendar API.
        :rtype: dict
        """
    move_to = None
    if event.published != form.published.data:
        move_to = cls.PUBLIC if form.published.data else cls.PRIVATE
    if event.is_recurring != form.is_recurring.data:
        if event.is_recurring:
            return cls.convert_to_single_event(event, form, move_to=move_to)
        return cls.convert_to_series(event, form, move_to=move_to)
    elif event.is_recurring:
        if form.update_all.data:
            return cls.update_series(event, form, move_to=move_to)
        return cls.update_single_event_from_series(event, form)
    return cls.update_single_event(event, form, move_to=move_to)


def __filter_params(params):
    """Filter the params and return the way to find the object (by_element or by_attribute).

    Parameters:
    - params [dict] : A dict that contains elements to search the element for
    Returns:
    - by_element [dict] : A dict that contains Selenium filters
    - by_attribute [dict] : A dict that contains attributes filters
    """
    params = params.copy()
    by_element_list = ['id', 'name', 'xpath', 'link_text',
        'partial_link_text', 'tag_name', 'class_name', 'css_selector']
    by_element = {}
    by_attribute = {}
    while len(params) > 0:
        key = next(iter(params))
        if key in by_element_list:
            by_element[key] = params.get(key)
        else:
            by_attribute[key] = params.get(key)
        del params[key]
    return by_element, by_attribute


def is_good_response(resp):
    """
    Returns True if the response seems to be HTML, False otherwise.
    """
    content_type = resp.headers['Content-Type'].lower()
    return (resp.status_code == 200 and content_type is not None and
        content_type.find('html') > -1)


def converge(lhs, rhs):
    """
    Determine convergence factor.

    :param lhs: (flt)
    :param rhs: (flt)
    :param div: (flt)
    :return: multiplication factor (flt) ((lhs / rhs) - 1) / div + 1
    """
    lhs = abs(lhs)
    rhs = abs(rhs)
    div = max(lhs, rhs) / min(lhs, rhs) * 2
    return (rhs / lhs - 1) / div + 1


def convert(sk_obj, input_features=None, output_feature_names=None):
    """
    Convert scikit-learn pipeline, classifier, or regressor to Core ML format.

    Parameters
    ----------
    sk_obj: model | [model] of scikit-learn format.
        Scikit learn model(s) to convert to a Core ML format.

        The input model may be a single scikit learn model, a scikit learn
        pipeline model, or a list of scikit learn models.

        Currently supported scikit learn models are:

        -   Linear and Logistic Regression
        -   LinearSVC and LinearSVR
        -   SVC and SVR
        -   NuSVC and NuSVR
        -   Gradient Boosting Classifier and Regressor
        -   Decision Tree Classifier and Regressor
        -   Random Forest Classifier and Regressor
        -   Normalizer
        -   Imputer
        -   Standard Scaler
        -   DictVectorizer
        -   One Hot Encoder

        The input model, or the last model in a pipeline or list of models,
        determines whether this is exposed as a Transformer, Regressor,
        or Classifier.

        Note that there may not be a one-to-one correspondence between scikit
        learn models and which Core ML models are used to represent them.  For
        example, many scikit learn models are embedded in a pipeline to handle
        processing of input features.

    input_features: str | dict | list

        Optional name(s) that can be given to the inputs of the scikit-learn
        model. Defaults to 'input'.

        Input features can be specified in a number of forms.

        -   Single string: In this case, the input is assumed to be a single
            array, with the number of dimensions set using num_dimensions.

        -   List of strings: In this case, the overall input dimensions to the
            scikit-learn model is assumed to be the length of the list.  If
            neighboring names are identical, they are assumed to be an input
            array of that length.  For example:

               ["a", "b", "c"]

            resolves to

                [("a", Double), ("b", Double), ("c", Double)].

            And:

                ["a", "a", "b"]

            resolves to

                [("a", Array(2)), ("b", Double)].

        - Dictionary: Where the keys are the names and the indices or ranges of
          feature indices.

            In this case, it's presented as a mapping from keys to indices or
            ranges of contiguous indices.  For example,

                {"a" : 0, "b" : [2,3], "c" : 1}

            Resolves to

                [("a", Double), ("c", Double), ("b", Array(2))].

            Note that the ordering is determined by the indices.

        -   List of tuples of the form `(name, datatype)`.  Here, `name` is the
            name of the exposed feature, and `datatype` is an instance of
            `String`, `Double`, `Int64`, `Array`, or `Dictionary`.

    output_feature_names: string or list of strings
            Optional name(s) that can be given to the inputs of the scikit-learn
            model.

        The output_feature_names is interpreted according to the model type:

        - If the scikit-learn model is a transformer, it is the name of the
          array feature output by the final sequence of the transformer
          (defaults to "output").
        - If it is a classifier, it should be a 2-tuple of names giving the top
          class prediction and the array of scores for each class (defaults to
          "classLabel" and "classScores").
        - If it is a regressor, it should give the name of the prediction value
          (defaults to "prediction").

    Returns
    -------
    model:MLModel
        Returns an MLModel instance representing a Core ML model.

    Examples
    --------
    .. sourcecode:: python

        >>> from sklearn.linear_model import LinearRegression
        >>> import pandas as pd

        # Load data
        >>> data = pd.read_csv('houses.csv')

        # Train a model
        >>> model = LinearRegression()
        >>> model.fit(data[["bedroom", "bath", "size"]], data["price"])

         # Convert and save the scikit-learn model
        >>> import coremltools
        >>> coreml_model = coremltools.converters.sklearn.convert(model,
                                                                 ["bedroom", "bath", "size"],
                                                                 "price")
        >>> coreml_model.save('HousePricer.mlmodel')
    """
    from ...models import MLModel
    from ._converter_internal import _convert_sklearn_model
    spec = _convert_sklearn_model(sk_obj, input_features,
        output_feature_names, class_labels=None)
    return MLModel(spec)


def flight_data_and_axis(new_frames):
    """Returns list of lists with the following structure:
    [[flight, [data source, [name, unit, data],[name, unit, data]]], [flight, [data source, [name, unit, data],
    [name, unit, data]]]]."""
    values_list = []
    flight_identifier = new_frames[0].columns[0][-16:]
    for frame in new_frames:
        data_lists = []
        data_lists.append(frame.columns[0].split('_')[-3])
        for column in frame.columns:
            y = frame[column].tolist()
            name = ''
            unit = ''
            b = 0
            if len(column.split('_')) == 5:
                a = 0
                unit_present = True
            elif len(column.split('_')) == 4:
                unit_present = False
                a = 0
            else:
                a = 5 - len(column.split('_'))
            for letter in column:
                if b == 0:
                    name = letter.upper()
                    b = 1
                elif a <= 0:
                    if letter != '_':
                        name = name + letter
                    else:
                        a += 1
                        if a <= 0:
                            name += ' '
                elif letter != '_' and unit_present is True:
                    unit = unit + letter
                elif unit_present is False:
                    unit = 'no unit'
                    break
                else:
                    break
            if 'per' in unit:
                unit_split = unit.split('per')
                denominators = []
                a = 0
                for count in range(1, len(unit_split)):
                    for item in denominators:
                        if unit_split[count] in item[0]:
                            item[1] = item[1] + 1
                            a = 1
                    if a == 1:
                        a = 0
                    else:
                        denominators.append([unit_split[count], 1])
                unit = unit_split[0]
                for denominator in denominators:
                    unit = unit + denominator[0] + '$^{-' + str(denominator[1]
                        ) + '}$'
            data_lists.append([name, unit, y])
        values_list.append(data_lists)
    return [flight_identifier, values_list]


@staticmethod
def min(tensor):
    """The min value in a tensor.

        Parameters
        ----------
        tensor : tensor

        Returns
        -------
        scalar
        """
    raise NotImplementedError


def edit_mesh_extrude_individual_move():
    """Extrude individual elements and move

    """
    pass


def move_from_temp(cursor, tid, txn_has_blobs):
    """
        Move the temporarily stored objects to permanent storage.

        *tid* is the integer tid of the transaction being committed.

        Returns nothing.

        The steps should be as follows:

            - If we are preserving history, then ``INSERT`` into
              ``object_state`` the values stored in ``temp_store``,
              remembering to coalesce the
              ``LENGTH(temp_store.state)``.

            - Otherwise, when we are not preserving history,
              ``INSERT`` missing rows from ``object_state`` into
              ``temp_store``, and ``UPDATE`` rows that were already
              there. (This is best done with an upsert). If blobs are
              involved, then ``DELETE`` from ``blob_chunk`` where the
              OID is in ``temp_store``.

            - For both types of storage, ``INSERT`` into
              ``blob_chunk`` the values from ``temp_blob_chunk``. In a
              history-free storage, this may be combined with the last
              step in an ``UPSERT``.
        """


def getUserName():
    """Get the name used by the user to log into the system.

        Note that this may not be identical to the user's 'getId' (to allow
        users to change their login names without changing their identity).
        """


def in_farm(name):
    """Returns flag indicating whether you are (mule) belong
    to the given farm.

    :param str|unicode name: Farm name.

    :rtype: bool
    """
    return False


@classmethod
def rsync(cls, *args):
    """
        executes rsync with the given arguments
        :param args:
        :return:
        """
    return cls.execute('rsync', args)


def should_include_path(path, includes=None, excludes=None, isRemotePath=False
    ):
    """Return True iff the given path should be included."""
    from os.path import basename
    from fnmatch import fnmatch, fnmatchcase
    if isRemotePath:
        fnmatch = fnmatchcase
    base = basename(path)
    if includes:
        for include in includes:
            if fnmatch(base, include):
                break
        else:
            return False
    if excludes:
        for exclude in excludes:
            if fnmatch(base, exclude):
                return False
    return True


def get_schema():
    """Schema structure of this resource

    :return: schema dictionary
    :rtype: dict
    """
    return {'schema': {'schema_version': {'type': 'integer', 'default': 2},
        'name': {'schema_version': 1, 'title': 'Graphite connection name',
        'comment': 'Unique Graphite connection name', 'type': 'string',
        'required': True, 'empty': False, 'unique': True}, 'carbon_address':
        {'schema_version': 1, 'title': 'Carbon daemon address', 'comment':
        '', 'type': 'string', 'required': True, 'empty': False},
        'carbon_port': {'schema_version': 1, 'title': 'Carbon daemon port',
        'comment': '', 'type': 'integer', 'empty': False, 'default': 2004},
        'graphite_address': {'schema_version': 1, 'title':
        'Graphite address', 'comment': '', 'type': 'string', 'required':
        True, 'empty': False}, 'graphite_port': {'schema_version': 1,
        'title': 'Graphite port', 'comment': '', 'type': 'integer', 'empty':
        False, 'default': 8080}, 'prefix': {'schema_version': 1, 'title':
        'Metrics prefix', 'comment':
        'Prefix that will be prepended to the metrics sent to this TS DB.',
        'type': 'string', 'default': ''}, 'realms_prefix': {
        'schema_version': 2, 'title': 'Realms prefix', 'comment':
        'Include the realms prefix for the metrics sent to this TS DB.',
        'type': 'boolean', 'default': True}, 'grafana': {'schema_version':
        1, 'title': 'Grafana relation', 'comment':
        'If set, the Alignak backend will use this Grafana relation for the metrics sent to the Influx DB. It will create/update the Grafana panels accordindgly.'
        , 'type': 'objectid', 'data_relation': {'resource': 'grafana',
        'embeddable': True}, 'nullable': True, 'default': None}, 'statsd':
        {'schema_version': 1, 'title': 'StatsD relation', 'comment':
        'If set, the Alignak backend will use this StatsD relation for the metrics sent to the Influx DB.'
        , 'type': 'objectid', 'data_relation': {'resource': 'statsd',
        'embeddable': True}, 'nullable': True, 'default': None}, '_realm':
        {'schema_version': 1, 'title': 'Realm', 'comment':
        'Realm this element belongs to.', 'type': 'objectid',
        'data_relation': {'resource': 'realm', 'embeddable': True},
        'required': True}, '_sub_realm': {'schema_version': 1, 'title':
        'Sub-realms', 'comment':
        'Is this element visible in the sub-realms of its realm?', 'type':
        'boolean', 'default': True}, '_users_read': {'schema_version': 1,
        'type': 'list', 'schema': {'type': 'objectid', 'data_relation': {
        'resource': 'user', 'embeddable': True}}}, '_users_update': {
        'schema_version': 1, 'type': 'list', 'schema': {'type': 'objectid',
        'data_relation': {'resource': 'user', 'embeddable': True}}},
        '_users_delete': {'schema_version': 1, 'type': 'list', 'schema': {
        'type': 'objectid', 'data_relation': {'resource': 'user',
        'embeddable': True}}}}, 'schema_deleted': {}}


def histogram(ratings, min_rating=None, max_rating=None):
    """
    Returns the counts of each type of rating that a rater made
    """
    if min_rating is None:
        min_rating = min(ratings)
    if max_rating is None:
        max_rating = max(ratings)
    num_ratings = int(max_rating - min_rating + 1)
    hist_ratings = [(0) for x in range(num_ratings)]
    for r in ratings:
        hist_ratings[r - min_rating] += 1
    return hist_ratings


@classmethod
def decode_ssh_private(cls, packet):
    """Decode an SSH format EC private key"""
    curve_id = packet.get_string()
    public_key = packet.get_string()
    private_key = packet.get_mpint()
    return curve_id, private_key, public_key


def can_access(security_manager, permission_name, view_name):
    """Protecting from has_access failing from missing perms/view"""
    try:
        return security_manager.has_access(permission_name, view_name)
    except:
        pass
    return False


def make_fpfList(options):
    """
    aggregate default fpf values and user-defined fpf values where enrichment factor calculations will be attempted.
    :param options: SplitInput object
    :return defaults: list includes default fpf values & unique user-defined values
    """
    user_values = options.fpf
    defaults = ['0.0001', '0.001', '0.01', '0.05']
    if user_values:
        for fpf in user_values:
            if fpf not in defaults:
                defaults.append(fpf)
        defaults.sort()
    return defaults


def combine_hex(data):
    """ Combine list of integer values to one big integer """
    output = 0
    for i, value in enumerate(reversed(data)):
        output |= value << i * 8
    return output


def isclose(vala, valb, rel_tol=1e-09, abs_tol=0.0):
    """
    Whether two values are close to each other.

    Identical to math.isclose() in Python 3.5.
    """
    return abs(vala - valb) <= max(rel_tol * max(abs(vala), abs(valb)), abs_tol
        )


def noop(*args, **kwargs):
    """Placeholder callable that does nothing for any input"""
    pass


def check_input(expr, inp, chk, varname):
    """Simple wrapper to test the validity of an input

    Arguments:
    - expr: the assessed expression (must be TRUE or FALSE)
    - inp: the input value. It should have a way to be converted to a `str`.
    - varname (str): the name of the input variable
    - chk (str): a human-readable string of acceptable(s) inputs

    Returns: None
    """
    if not expr:
        raise TypeError("ERROR (Invalid setting): '{}'={}. '{}' must be {}"
            .format(varname, inp, varname, chk))


def find_prefixed(root, prefix):
    """finds all elements in root that begin with the prefix, case insensitive"""
    l_prefix = prefix.lower()
    for x in root.iterdir():
        if x.name.lower().startswith(l_prefix):
            yield x


def _new_object(cls):
    """Helper function for pickle"""
    return cls.__new__(cls)


@classmethod
def probs(cls, x, y, rope=0, runs=1):
    """
        Compute and return probabilities

        Probabilities are not computed from a sample posterior but
        from cumulative Student distribution.

        Args:
            x (np.array): a vector of scores for the first model
            y (np.array): a vector of scores for the second model
            rope (float): the width of the region of practical equivalence (default: 0)
            runs (int): number of repetitions of cross validation (default: 1)

        Returns:
            `(p_left, p_rope, p_right)` if `rope > 0`;
            otherwise `(p_left, p_right)`.
        """
    return cls(x, y, rope, runs).probs()


def is_updated(ml):
    """lets you know if the list is already migrated"""


def doCheckIndent(context, match):
    """Ensures that the indent requirement is matched."""
    return True
    v = context.getVariables()
    tab_match = context.getVariables().get('tabs')
    tab_indent = len(tab_match[0])
    req_indent = v.get('requiredIndent') or 0
    return tab_indent == req_indent


def replace_path(path, new_path=None):
    """Return replaced <a> soup object with *new_path*.
    *path* is a <a> soup object returned by make_soup func."""
    if new_path is not None:
        path['href'] = new_path
    else:
        path = path
    return path['href']


def next():
    """Advance to the next value in the iteration, if possible

        Return a true value if it was possible to advance and return
        a false value otherwise.
        """


def custom_train_test_split(game_data, train_size, first_week, last_week):
    """
  Splits the game data into (shuffled) train and test sets.
  ----------
  Parameters
  ----------
    game_data: DataFrame
      The total data from which the train and test sets are drawn
    train_size: float
      The proportion of the relevant data to be used for training
    first_week, last_weeks: int
      The first and last weeks of the season from which data is drawn
  """
    game_data_range = game_data[(game_data.week >= first_week) & (game_data
        .week <= min(19, last_week))].reset_index(drop=True)
    train = game_data_range.iloc[:int(len(game_data_range) * train_size)
        ].sample(frac=1).reset_index(drop=True)
    test = game_data_range.iloc[int(len(game_data_range) * train_size):
        ].reset_index(drop=True)
    return train, test


def is_child(t, s):
    """Whether t is s's child."""
    return s is t.parent


def _cmake_string_representation(value):
    """Escapes the specified string for use in a CMake command surrounded with double quotes
       :param value the string to escape"""
    return '"{0}"'.format(value.replace('\\', '\\\\').replace('$', '\\$').
        replace('"', '\\"'))


def face_split_edgenet(face: 'bmesh.types.BMFace', edgenet:
    'bmesh.types.BMEdge') ->'bmesh.types.BMFace':
    """Splits a face into any number of regions defined by an edgenet.

    :param face: The face to split.
    :type face: 'bmesh.types.BMFace'
    :param face: The face to split.
    :param edgenet: Sequence of edges.
    :type edgenet: 'bmesh.types.BMEdge'
    :return:  The newly created faces.
    """
    pass


def polyblend(time, time_f, signal_i, signal_f):
    """A smooth blend between two levels of a signal. Suitable for
    approximating thrust variations associated with spool-up and
    spool-down, etc.
    """
    normtime = time / time_f
    scale = signal_f - signal_i
    if time < 0:
        return signal_i
    if time >= time_f:
        return signal_f
    return signal_i + scale * normtime ** 2 * (3 - 2 * normtime)


@staticmethod
def concatenate(tensors, axis=0):
    """Concatenate tensors along an axis.

        Parameters
        ----------
        tensors : list of tensor
            The tensors to concatenate. Non-empty tensors provided must have the
            same shape, except along the specified axis.
        axis : int, optional
            The axis to concatenate on. Default is 0.

        Returns
        -------
        tensor
        """
    raise NotImplementedError


def object_attributes(thing, all=False):
    """
    Return a sorted list of names defined by thing that are not also names in
    a standard object, except include __doc__.
    """
    standard_names = set(dir(object()))
    things_names = set(dir(thing))
    if not all:
        things_names -= standard_names
        things_names |= set(['__doc__'])
    return sorted(things_names)


def _read_count_byRead(bins, read_sets):
    """
Utility function to be called by "read_count".

"""
    sample_number = len(read_sets)
    cnts = []
    for bs in bins.values():
        for b in bs:
            cnts.append([0] * sample_number)
    within = [0] * sample_number
    for j, read_set in enumerate(read_sets):
        for ch in read_set:
            if ch not in bins:
                continue
            reads = read_set[ch]
            if len(reads) == 0:
                continue
            rmax = reads[-1]
            bs = bins[ch]
            bi = 0
            for locus in reads:
                while bi < len(bs) and bs[bi][1] <= locus:
                    bi += 1
                if bi == len(bs) or bs[bi][0] > rmax:
                    break
                temp = bi
                flag = False
                while temp < len(bs):
                    b = bs[temp]
                    if b[0] > locus:
                        break
                    flag = True
                    cnts[b[-1] - 1][j] = cnts[b[-1] - 1][j] + 1
                    temp += 1
                if flag:
                    within[j] = within[j] + 1
    return cnts, within


@classmethod
def _generate_fake_password(cls):
    """
        Returns a random fake password
        """
    import string
    from random import choice
    size = 9
    try:
        string.letters
    except AttributeError:
        string.letters = string.ascii_letters
    password = ''.join([choice(string.letters + string.digits) for i in
        range(size)])
    return password.lower()


@classmethod
def get_arthur_params_from_url(cls, url):
    """ Get the arthur params given a URL for the data source """
    params = {}
    owner = url.split('/')[-2]
    repository = url.split('/')[-1]
    params['owner'] = owner
    params['repository'] = repository
    return params


def normalize_parameter(kv):
    """
	Translate a parameter into standard form.
	"""
    k, v = kv
    if k[0] == 'requiressl' and v in ('1', True):
        k[0] = 'sslmode'
        v = 'require'
    elif k[0] == 'dbname':
        k[0] = 'database'
    elif k[0] == 'sslmode':
        v = v.lower()
    return tuple(k), v


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 rsort(iterable, key=None):
    """Reverse sorts an iterable"""
    return sorted(iterable, key=key, reverse=True)


def decorate_transitions_prepostset(net):
    """
    Decorate transitions with sub and addition markings

    Parameters
    -------------
    net
        Petri net
    """
    from pm4py.objects.petri.petrinet import Marking
    for trans in net.transitions:
        sub_marking = Marking()
        add_marking = Marking()
        for arc in trans.in_arcs:
            sub_marking[arc.source] = arc.weight
            add_marking[arc.source] = -arc.weight
        for arc in trans.out_arcs:
            if arc.target in add_marking:
                add_marking[arc.target] = arc.weight + add_marking[arc.target]
            else:
                add_marking[arc.target] = arc.weight
        trans.sub_marking = sub_marking
        trans.add_marking = add_marking


def is_model(cls):
    """
    Check whether *cls* is a class with ``attrs`` attributes.

    :param type cls: Class to introspect.
    :raise TypeError: If *cls* is not a class.

    :rtype: :class:`bool`
    """
    return getattr(cls, '__attrs_attrs__', None) is not None


def binaryForm(n, nbDigs=0):
    """Generates the bits of n in binary form.

    If the sequence has less than nbDigs digits, it is left-padded with zeros.
    """
    digits = []
    while n:
        digits.append(n & 1)
        n >>= 1
    return reversed(digits + [0] * (nbDigs - len(digits)))


def _prettify_dict(key):
    """Return a human readable format of a key (dict).

    Example:

    Description:   My Wonderful Key
    Uid:           a54d6de1-922a-4998-ad34-cb838646daaa
    Created_At:    2016-09-15T12:42:32
    Metadata:      owner=me;
    Modified_At:   2016-09-15T12:42:32
    Value:         secret_key=my_secret_key;access_key=my_access_key
    Name:          aws
    """
    assert isinstance(key, dict)
    pretty_key = ''
    for key, value in key.items():
        if isinstance(value, dict):
            pretty_value = ''
            for k, v in value.items():
                pretty_value += '{0}={1};'.format(k, v)
            value = pretty_value
        pretty_key += '{0:15}{1}\n'.format(key.title() + ':', value)
    return pretty_key


def get_time_steps(json_file):
    """ Get time step of calculation by scenario settings.

    Parameters
    ----------
    json_file : :obj:`dict`
        Dictionary of the ``scenario_setting.json`` file

    Returns
    -------
    time_step : int
        Number of timesteps of the calculation.
    """
    end = json_file['eTraGo'].get('end_snapshot')
    start = json_file['eTraGo'].get('start_snapshot')
    time_step = end - start
    return time_step


def applyChanges(content):
    """Validate the user input data and apply it to the content.

        Return a boolean indicating whether a change was actually applied.

        This raises an error if there is no user input.
        """


@classmethod
def parse_qrcode_uuid(cls, res_js):
    """Parse qrcode uuid javascript response."""
    window = cls.exec_js(res_js)
    return {'code': window.QRLogin.code, 'uuid': window.QRLogin.uuid}


def format_md(res):
    """builds a markdown table from res"""


def identify_first_last_gear_box_ratios(gear_box_ratios):
    """
    Identify the gear box ratio of first and last gears.

    :param gear_box_ratios:
        Gear box ratios [-].
    :type gear_box_ratios: dict[int | float]

    :return:
        Gear box ratio of first and last gears [-, -].
    :return: float, float
    """
    return gear_box_ratios[1], max(gear_box_ratios.items())[1]


@classmethod
def FromLineNum(cls, filename, linenum):
    """
        Initialize from filename, and the next matrix after line number

        >>> qmat = QCMatrix.FromLineNum('test.out', 1)
        """
    c = cls(filename)
    cls.linenum = linenum
    c._get_next_matrix()
    return c


def _format_usage_without_prefix(parser):
    """
    Use private argparse APIs to get the usage string without
    the 'usage: ' prefix.
    """
    fmt = parser._get_formatter()
    fmt.add_usage(parser.usage, parser._actions, parser.
        _mutually_exclusive_groups, prefix='')
    return fmt.format_help().strip()


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


@staticmethod
def _get_artifacts(values):
    """Get artifacts from workflow values."""
    artifacts = []
    templates = values.get('templates')
    flow = values.get('flow')
    for template in templates:
        artifacts.extend(template.artifacts)
    for task in flow.tasks:
        args = task.arguments
        if not args:
            continue
        if not args.artifacts:
            continue
        artifacts.extend(args.artifacts)
    inputs = values.get('inputs')
    if inputs and inputs.artifacts:
        artifacts.extend(inputs.artifacts)
    outputs = values.get('outputs')
    if outputs and outputs.artifacts:
        artifacts.extend(outputs.artifacts)
    return artifacts


def _str_to_lint(astr, sep=',', sep2='-'):
    """Returns a list of integers for a given structured string of numbers.

    Parameters
    ----------
    s : str
        Comma separated nonnegative integers. E.g. 3,6,7 or 3,7-10,12
    sep : str, optional
        Separator, which is by default ",".
    sep2 : str, optional
        Separator 2, which is by default "-".

    """
    lint = []
    try:
        for items in astr.strip().split(sep):
            item = items.strip().split(sep2)
            if len(item) == 1:
                lint += [int(item[0])]
            elif len(item) == 2:
                lint += range(int(item[0]), int(item[1]) + 1)
            else:
                return False
    except (TypeError, ValueError):
        return False
    return lint


def _si(number):
    """Format a number using base-2 SI prefixes"""
    prefixes = ['', 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']
    while number > 1024:
        number /= 1024.0
        prefixes.pop(0)
    return '%0.2f%s' % (number, prefixes.pop(0))


def sanitize_bool_for_api(bool_val):
    """Sanitizes a boolean value for use in the API."""
    return str(bool_val).lower()


def get_frac_dels(var):
    """
    Returns the fraction of reads containing spanning deletions,
    or None if it isn't present in the VCF.
    """
    return var.INFO.get('Dels')


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

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


def _get_plotly_axis_labels(i, j, ncols):
    """Gets plotly axis labels from subplot indices i, j"""
    plot_ind = i * ncols + j + 1
    return 'xaxis%d' % plot_ind, 'yaxis%d' % plot_ind


def setStyleSheet(css):
    """
    Function generating a script to set a user style sheet.

    @param css style sheet to be applied
    @type str
    @return script to set a user style sheet
    @rtype str
    """
    source = """
(function() {{
    var css = document.createElement('style');
    css.setAttribute('type', 'text/css');
    css.appendChild(document.createTextNode('{0}'));
    document.getElementsByTagName('head')[0].appendChild(css);
}})()"""
    style = css.replace("'", "\\'").replace('\n', '\\n')
    return source.format(style)


def save_pair(connection, digest, word):
    """Save both the original word and its digest into the database.

  Parameters:
    - connection: The connection to the SQLite database.
    - digest: The digest of the plaintext word; acts as the primary key.
    - word: The plaintext word.

  """
    cursor = connection.cursor()
    _t = digest, word
    cursor.execute("""INSERT INTO rainbow
    VALUES (NULL, ?, ?)""", _t)
    connection.commit()


def linalg_potri(A=None, out=None, name=None, **kwargs):
    """Performs matrix inversion from a Cholesky factorization.
    Input is a tensor *A* of dimension *n >= 2*.

    If *n=2*, *A* is a triangular matrix (entries of upper or lower triangle are all zero)
    with positive diagonal. We compute:

      *out* = *A*\\ :sup:`-T` \\* *A*\\ :sup:`-1` if *lower* = *true*
      *out* = *A*\\ :sup:`-1` \\* *A*\\ :sup:`-T` if *lower* = *false*

    In other words, if *A* is the Cholesky factor of a symmetric positive definite matrix
    *B* (obtained by *potrf*), then

      *out* = *B*\\ :sup:`-1`

    If *n>2*, *potri* is performed separately on the trailing two dimensions for all inputs
    (batch mode).

    .. note:: The operator supports float32 and float64 data types only.

    .. note:: Use this operator only if you are certain you need the inverse of *B*, and
              cannot use the Cholesky factor *A* (*potrf*), together with backsubstitution
              (*trsm*). The latter is numerically much safer, and also cheaper.

    Examples::

       Single matrix inverse
       A = [[2.0, 0], [0.5, 2.0]]
       potri(A) = [[0.26563, -0.0625], [-0.0625, 0.25]]

       Batch matrix inverse
       A = [[[2.0, 0], [0.5, 2.0]], [[4.0, 0], [1.0, 4.0]]]
       potri(A) = [[[0.26563, -0.0625], [-0.0625, 0.25]],
                   [[0.06641, -0.01562], [-0.01562, 0,0625]]]

    Defined in src/operator/tensor/la_op.cc:L275

    Parameters
    ----------
    A : NDArray
        Tensor of lower triangular matrices

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

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


def pypi_url(varmap):
    """Return the PyPI URL for program ``name`` from the setup vars.
    """
    return 'http://pypi.org/project/{}'.format(varmap['name'])


def _check_deps():
    """Raise RuntimeError if a dependency is not found. These dependencies are
    not included in `requirements.txt`.
    """
    import shutil
    msg = "Dependency '{}' not found."
    if shutil.which('rsync') is None:
        raise RuntimeError(msg.format('rsync'))
    try:
        import reprozip
    except Exception:
        raise RuntimeError(msg.format('reprozip'))


def _ensure_can_send(thing):
    """
    It's easy to accidentally pass in a str instead of bytes when send()ing.
    This gives a more informative message if a ``str`` was accidentally passed
    to a send method.

    """
    if isinstance(thing, str):
        raise ValueError(
            'Cannot send type str. Maybe you left out a ".encode()" somewhere?'
            )


def get_keywords():
    """Get the keywords needed to look up the version information."""
    git_refnames = '$Format:%d$'
    git_full = '$Format:%H$'
    keywords = {'refnames': git_refnames, 'full': git_full}
    return keywords


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

        :param list of [str] val:
        :rtype: GroupsSelector
        """
    return cls('group_external_ids', val)


def rejectbadchan():
    """Class to reject bad channels.
    """
    pass


def zerocopy_to_numpy(input):
    """Create a numpy ndarray that shares the input memory.

    Parameters
    ----------
    input : Tensor
        The input tensor

    Returns
    -------
    numpy.ndarray
        A numpy ndarray.
    """
    pass


def controlRow(inputList=[]):
    """
    *generate a form row*

    **Key Arguments:**
        - ``inputList`` -- list of inputs for the control row

    **Return:**
        - ``controlRow`` -- the controlRow
    """
    if len(inputList) > 1:
        row = 'controls-row'
    else:
        row = ''
    content = ''
    for iinput in inputList:
        content = '%(content)s %(iinput)s' % locals()
    controlRow = (
        """
        <div class="controls %(row)s">
            %(content)s
        </div>"""
         % locals())
    return controlRow


@classmethod
def register_serializer(cls, name, method):
    """Add `method` as `name` to the set of serializers to pick from
        in :meth:`serialize`

        Parameters
        ----------
        name : str
            The name of the serializer
        method : Callable
            A callable object that when called with a :class:`Monosaccharide` returns a :class:`str`
        """
    cls._serializers[name.lower()] = method


def apply_or_none(fcn, value):
    """
    If the value is None, return None, otherwise return the result of applying the function to it.
    """
    if value is None:
        return None
    else:
        return fcn(value)


@staticmethod
def _get_qt_library_subdir(arch):
    """ Return the name of the sub-directory in the Qt installation
        containing the libraries.
        """
    return 'bin' if arch == 'win' else 'lib'


def get_mem_size_bytes(num: int) ->int:
    """ Compute memory size of bytes taken by integer """
    return 1 if num == 0 else (num.bit_length() + 7) // 8


@classmethod
def register(cls, subparser):
    """
        Most frequent style: generate 1 report file from multiple input files
        :param subparser: argparse.ArgumentParser(..).add_subparsers(..)
        :return: the same subparser with arguments added
        """
    subparser.add_argument('--rude', action='store_true', help=
        'overwriting existing files if needed')
    subparser.add_argument('-o', '--out', metavar='filename', help=
        'output filename')
    subparser.add_argument('-c', '--concise', action='store_true', help=
        'concise mode reading fasta data')
    subparser.add_argument('-q', '--quiet', action='store_true', help=
        'suppress messages')
    subparser.add_argument('filenames', metavar='filename', nargs='*', help
        ='input filenames; if empty, stdin is used')
    return subparser


@classmethod
def authorize_draft(cls, deposition, draft, action):
    """Authorize draft."""
    if action == 'update':
        return cls.authorize(deposition, 'add_draft')
    return cls.authorize(deposition, 'add_draft')


def hide_inverse(model):
    """
    This is a convenience function intended to disable automatic generation
    of the inverse in compound models by disabling one of the constituent
    model's inverse. This is to handle cases where user provided inverse
    functions are not compatible within an expression.

    Example:
        compound_model.inverse = hide_inverse(m1) + m2 + m3

    This will insure that the defined inverse itself won't attempt to
    build its own inverse, which would otherwise fail in this example
    (e.g., m = m1 + m2 + m3 happens to raises an exception for this
    reason.)

    Note that this permanently disables it. To prevent that either copy
    the model or restore the inverse later.
    """
    del model.inverse
    return model


def p_expression_group(p):
    """expression : LPAREN expression RPAREN"""
    p[0] = p[2]


def dflt_kwargs(k, dflt, **kwargs):
    """
       counts = dflt_kwargs("counts",100,**kwargs)
    """
    if k in kwargs:
        v = kwargs[k]
    else:
        v = dflt
    return v


def feedback(all_data, marked_data_indexes):
    """
    Print information about marked point(s).

    Parameters
    ----------
    all_data : ndarray
        The whole data coming from the main input file without a header.
    marked_data_indexes : ndarray
        A list containing indexes of points from data variable. The indexes
        come from marked points.
    """
    for object_index, index in enumerate(marked_data_indexes):
        print('# object {}'.format(object_index + 1))
        print(int(all_data[index][0]))
        for parameter in all_data[index][1:]:
            print(parameter)


@classmethod
def color_map(cls, group):
    """
        Change default color behavior.

        Map certain states always to the same colors (similar to MMS).
        """
    colors = {'opened': 'green', 'closed': 'red', 'total': 'black'}
    return colors[group], cls.markers[0]


def setup(builder=None, default=None, **kwargs):
    """ NOTE: setup functionality is now in main(), setup() is kept for
        backward compatibility and should not be used in new scripts.

        Setup the default Builder (or an instance of given builder if "builder"
        is not None) with the same keyword arguments as for Builder().
        "default" is the name of the default function to run when the build
        script is run with no command line arguments. """
    global _setup_builder, _setup_default, _setup_kwargs
    _setup_builder = builder
    _setup_default = default
    _setup_kwargs = kwargs


def is_float(number):
    """
    function to determine if the input value can be converted into a float
    by using the try/except technique, filtering out True and 'NaN' (which can be converted to floats)

    :param number: the value to test
    :return: True/False
             if True, the value can be converted to a float
             if False, the value cannot be converted to a float
    """
    try:
        n = str(number)
    except ValueError:
        return False
    except TypeError:
        return False
    false_floats = str(True), str(False), str(None), 'Nan'
    if n in false_floats:
        return False
    try:
        float(number)
        return True
    except ValueError:
        return False
    except TypeError:
        return False


def encode(in_bytes):
    """Encode a string using Consistent Overhead Byte Stuffing (COBS).

    Input is any byte string. Output is also a byte string.

    Encoding guarantees no zero bytes in the output. The output
    string will be expanded slightly, by a predictable amount.

    An empty string is encoded to '\\x01'"""
    final_zero = True
    out_bytes = []
    idx = 0
    search_start_idx = 0
    for in_char in in_bytes:
        if in_char == '\x00':
            final_zero = True
            out_bytes.append(chr(idx - search_start_idx + 1))
            out_bytes.append(in_bytes[search_start_idx:idx])
            search_start_idx = idx + 1
        elif idx - search_start_idx == 253:
            final_zero = False
            out_bytes.append('ÿ')
            out_bytes.append(in_bytes[search_start_idx:idx + 1])
            search_start_idx = idx + 1
        idx += 1
    if idx != search_start_idx or final_zero:
        out_bytes.append(chr(idx - search_start_idx + 1))
        out_bytes.append(in_bytes[search_start_idx:idx])
    return ''.join(out_bytes)


def hyperheader2dic(head):
    """
    Convert a hypercomplex block header into a Python dictionary.
    """
    dic = dict()
    dic['s_spare1'] = head[0]
    dic['status'] = head[1]
    dic['s_spare2'] = head[2]
    dic['s_spare3'] = head[3]
    dic['l_spare1'] = head[4]
    dic['lpval1'] = head[5]
    dic['rpval1'] = head[6]
    dic['f_spare1'] = head[7]
    dic['f_spare2'] = head[8]
    dic['UHYPERCOMPLEX'] = (dic['status'] & 2) // 2
    return dic


def is_pandigital(value):
    """
    Check that each digit appears once only.

    :param value: integer value (can also be negative)
    :retuns: true when given number is pandigital

    see http://en.wikipedia.org/wiki/Pandigital_number

    >>> is_pandigital(1234567890)
    True
    >>> is_pandigital(12345678900)
    False
    >>> is_pandigital(9876543210)
    True
    >>> is_pandigital(10240)
    False
    """
    value = abs(value)
    digits = set()
    counter = 0
    while value > 0:
        digits.add(value % 10)
        counter += 1
        value //= 10
    return counter == len(digits)


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


@classmethod
def atomic(cls):
    """Get the atomic context or decorator."""
    return cls._meta.database.atomic()


@classmethod
def extract(cls, ds, ds_slice, scale_attr='scale_factor', add_attr=
    'add_offset', unscale=True):
    """
        Extract data from Resource Dataset

        Parameters
        ----------
        ds : h5py.dataset
            Open .h5 dataset instance to extract data from
        ds_slice : slice | list | ndarray
            slice, list, or vector of points to extract
        scale_attr : str, optional
            Name of scale factor attribute, by default 'scale_factor'
        add_attr : str, optional
            Name of add offset attribute, by default 'add_offset'
        unscale : bool, optional
            Flag to unscale dataset data, by default True
        """
    dset = cls(ds, scale_attr=scale_attr, add_attr=add_attr, unscale=unscale)
    return dset[ds_slice]


def calc_custom(custom, genome, scaffold, sequence, scaffold_coverage,
    total_bases):
    """
	custom = {(reads mapped to scaffold)/(total reads for sample)}/(length of scaffold)
	"""
    index = 0
    if scaffold in scaffold_coverage:
        if genome not in custom:
            custom[genome] = [[] for i in scaffold_coverage[scaffold]]
        for cov in scaffold_coverage[scaffold]:
            length = float(len(sequence[1]))
            bases = cov * length
            custom_value = bases / total_bases[index] / length
            custom[genome][index].append(custom_value)
            index += 1
    return custom


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


def dt_weekdayname_long(dt):
    """Return long weekday name for datetime.
    """
    return dt.strftime('%A')


@staticmethod
def log(string):
    """
        Logging function.
        :param string: Message to log.
        """
    print(string)


def t_error(t):
    """Error handling rule"""
    print("Illegal character '{0}'".format(t.value[0]))
    t.lexer.skip(1)


def _get_amount(kwargs):
    """Helper function intended for internal use. Checks validity of `amount` kwarg."""
    amount = kwargs['amount']
    if not isinstance(amount, int):
        raise TypeError('Expected integer amount')
    if not amount >= 0:
        raise ValueError('Expected non-negative amount')
    return amount


def extract_signed_data(data, extra):
    """Filters out non-white-listed items from the ``extra`` dictionary given.

    :param dict data:
    :param list extra:
    :return dict:
    """
    extracted_extra = dict(data)
    for key, value in data.items():
        if key not in extra:
            extracted_extra.pop(key)
    return extracted_extra


def isupper(text):
    """
    Checks if all cased characters in ``text`` are uppercase and there is at least one cased character.

    Cased characters are defined by the Unicode standard.  All alphabetic characters in the
    ASCII character set are cased.

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

    :return: True if all cased characters in ``text`` are uppercase and there is at least one cased character, False otherwise.
    :rtype:  ``bool``
    """
    assert isinstance(text, str), '%s is not a string' % text
    return text.isupper()


@classmethod
def registerfunction(cls, function):
    """Decorator to register a jinja2 function"""
    cls.functions[function.__name__] = function
    return function


def loseConnection():
    """
        Close the connection sending a close frame first.
        """


def _hash_token(application, token):
    """Creates a hashable object for given token then we could use it as a
    dictionary key.
    """
    if isinstance(token, dict):
        hashed_token = tuple(sorted(token.items()))
    elif isinstance(token, tuple):
        hashed_token = token
    else:
        raise TypeError('%r is unknown type of token' % token)
    return application.__class__.__name__, application.name, hashed_token


@classmethod
def strptime(cls, dt_string, dt_format):
    """ strptime to patch in """
    func = cls.__get_strptime(dt_format)
    if func is None:
        return cls._old_strptime(dt_string, dt_format)
    return func(dt_string)


@classmethod
def from_der(cls, der_string):
    """Read a single DER-encoded certificate from a string.

        This is just an alias to __init__ to match from_pem().

        Args:
            der_string: the certificate string.

        Returns:
            a Certificate object.
        """
    return cls(der_string)


@classmethod
def name_aliases(cls):
    """
        Provides alternative names for the command (so, for example, "listgames"
        can be also available as "lg"). All aliases should be returned as a list.

        By default the list is empty, there are no aliases.
        """
    return []


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

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

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


@staticmethod
def keys():
    """
        @param: empty parameter inteneded
        return a list of keys in string
        """
    return ['name', 'index', 'namespace', 'author', 'dataset', 'params',
        'output', 'comment', 'create_date', 'persistor', 'serializer']


def p_table_wild(p):
    """table_wild : identifier '.' '*' """
    p[0] = '*', p[1]


def _get_index_from_direction(direction):
    """Returns numerical index from direction
    """
    directions = ['x', 'y', 'z']
    try:
        if direction in 'lr':
            index = 0
        else:
            index = directions.index(direction)
    except ValueError:
        message = (
            "{0} is not a valid direction. Allowed values are 'l', 'r', 'x', 'y' and 'z'"
            .format(direction))
        raise ValueError(message)
    return index


def check(condition, message, *args, **kwargs):
    """Check state and raise exception if not valid"""
    if not condition:
        raise ValueError(message.format(*args, **kwargs))


def clamp(value, low, high):
    """Clamp value to be at least low and at most high."""
    return min(max(value, low), high)


def describe_user_import_job(UserPoolId=None, JobId=None):
    """
    Describes the user import job.
    See also: AWS API Documentation

    :example: response = client.describe_user_import_job(
        UserPoolId='string',
        JobId='string'
    )

    :type UserPoolId: string
    :param UserPoolId: [REQUIRED]
            The user pool ID for the user pool that the users are being imported into.

    :type JobId: string
    :param JobId: [REQUIRED]
            The job ID for the user import job.

    :rtype: dict
    :return: {
        'UserImportJob': {
            'JobName': 'string',
            'JobId': 'string',
            'UserPoolId': 'string',
            'PreSignedUrl': 'string',
            'CreationDate': datetime(2015, 1, 1),
            'StartDate': datetime(2015, 1, 1),
            'CompletionDate': datetime(2015, 1, 1),
            'Status': 'Created'|'Pending'|'InProgress'|'Stopping'|'Expired'|'Stopped'|'Failed'|'Succeeded',
            'CloudWatchLogsRoleArn': 'string',
            'ImportedUsers': 123,
            'SkippedUsers': 123,
            'FailedUsers': 123,
            'CompletionMessage': 'string'
        }
    }

    :returns:
    Created - The job was created but not started.
    Pending - A transition state. You have started the job, but it has not begun importing users yet.
    InProgress - The job has started, and users are being imported.
    Stopping - You have stopped the job, but the job has not stopped importing users yet.
    Stopped - You have stopped the job, and the job has stopped importing users.
    Succeeded - The job has completed successfully.
    Failed - The job has stopped due to an error.
    Expired - You created a job, but did not start the job within 24-48 hours. All data associated with the job was deleted, and the job cannot be started.

    """
    pass


def assign_tensor_placeholders(placeholder_dict, data_dict):
    """
    Builds feed dictionary for Tensorflow from the placeholder
    dictionary, which holds placeholders of all gates in the circuit,
    and a global data dictionary.

    Parameters
    ----------
    placeholder_dict : dict
           Dictionary of {tensorflow.placeholder : data_key} pairs
    data_dict : dict
           Dictionary of {data_key : np.array} pairs

    Returns
    -------
    feed_dict : dict
          Dictionary to feed in Tensorflow session
    """
    feed_dict = {}
    for placeholder, data_key in placeholder_dict.items():
        try:
            feed_dict[placeholder] = data_dict[data_key]
        except KeyError:
            pass
    return feed_dict


def get_div_winners(df_sim):
    """Calculate division winners with summarised simulation data

  :param df_sim: data frame with simulated scores summarised by iteration
  :return: data frame with division winners per iteration
  """
    return df_sim.sort_values(by=['tot_wins', 'tot_pts'], ascending=[False,
        False]).groupby(['iteration', 'divisionId']).head(1).sort_values(by
        =['divisionId', 'iteration']).reset_index(drop=True)


def file_path(path):
    """Return path with file protocol
    Ignore if it already starts with file path or http
    """
    if not path.startswith('http') and not path.startswith('file'):
        path = 'file://{0}'.format(path)
    return path


@staticmethod
def __add_optional_fields(dict_to_add, **kwargs):
    """
        Add optional field to dict
        Additional field(s) will be preceded with underscore in front of the field name

        :param dict_to_add: Dict to be added with optional field(s)
        :param kwargs: Optional field(s)
        :return: Dict with optional field(s)
        """
    for key, value in kwargs.items():
        key = '_' + str(key)
        dict_to_add[key] = value
    return dict_to_add


def maybe(f, default):
    """Evaluate f and return the value; return default on error."""
    try:
        return f()
    except:
        return default


def get_plugin_name(plugin):
    """
    Return the PyPI name of the given plugin.
    """
    return 'taxi-' + plugin


@classmethod
def hexagonal(cls, a, c, lattice_type='P'):
    """Factory for hexagonal lattices

        :param a: unit cell length
        :param c: unit cell length
        """
    a = float(a)
    self = cls(a, a, float(c), 90, 90, 120, lattice='hexagonal',
        lattice_type=lattice_type)
    return self


def _set_atom_charges(compounds, id_, content):
    """Short description.

    Parameters
    ----------
    Compounds : dict
    id_ : str
    content : str(int int)
        Are of form "(8 -1)", we only need the second part
    """
    compounds[id_]['charge'] += float(content[1:-1].split()[-1])


def __sub__(other):
    """Substract from this month.

        Given an `int` compute a previous month.
        Given an `IMonth` compute the interval.

        """


@classmethod
def section_tag_remove(cls, string, symbol_or_re, is_re=False):
    """Remove lines tagged with :attr:`section_delimiters`.

        >>> tpl = AdHoc.get_named_template("col-param-closure")
        >>> res = AdHoc.section_tag_remove(tpl, "adhoc_run_time_section")
        >>> res = '\\n'.join(res.splitlines()[:4])
        >>> printf(str(res)) #doctest: +ELLIPSIS
            @classmethod
            def col_param_closure(cls):...
                ...Closure for setting up maximum width, padding and separator
                for table columns.
        """
    transform = lambda blob: ''
    return cls.transform_lines(transform, string, symbol_or_re, is_re, cls.
        section_delimiters)


def display_name_to_filepath(name):
    """Performs the reverse of display_name using literal versions of characters which aren’t supported in a filepath.

    """
    pass


def next():
    """Move to next folder

    """
    pass


def get_app_wx(*args, **kwargs):
    """Create a new wx app or return an exiting one."""
    import wx
    app = wx.GetApp()
    if app is None:
        if 'redirect' not in kwargs:
            kwargs['redirect'] = False
        app = wx.App(*args, **kwargs)
    return app


def _determine_fields_from_ions(ds, ion_list, fields, ftype, sampling_type):
    """
    Figure out what fields need to be added based on the ions present
    and the particle type

    For sph (determined by sampling_type):
    Identify if the number_density fields for the desired ions already
    exist on the dataset, and if so, just add them to the list
    of fields to be added to the ray.
    If not, add these ion fields to the dataset as particle fields,
    which prompts them being smoothed to the grid, and add the resulting
    smoothed fields (e.g. ("gas", "x_number_density")) to the list of fields
    to be added to the ray.  Include the 'temperature' field for
    calculating the width of voigt profiles in the absorption spectrum.

    For grid:
    Check if the number_density fields for these ions exist, and if so, add
    them to field list. If not, leave them off, as they'll be generated
    on the fly by SpectrumGenerator as long as we include the 'density',
    'temperature', and appropriate 'metallicity' fields.
    """
    fields_to_add_to_ds = []
    for ion in ion_list:
        atom = ion[0].capitalize()
        ion_state = ion[1]
        nuclei_field = '%s_nuclei_mass_density' % atom
        metallicity_field = '%s_metallicity' % atom
        field = '%s_p%d_number_density' % (atom, ion_state - 1)
        if ion_state == 1:
            alias_field = '%s_number_density' % atom
        else:
            alias_field = field
        if (ftype, field) not in ds.derived_field_list:
            if (ftype, alias_field) not in ds.derived_field_list:
                if sampling_type == 'particle':
                    fields_to_add_to_ds.append((atom, ion_state))
                    fields.append(('gas', field))
                else:
                    fields.append(('gas', 'density'))
                    if ('gas', metallicity_field) in ds.derived_field_list:
                        fields.append(('gas', metallicity_field))
                    elif ('gas', nuclei_field) in ds.derived_field_list:
                        fields.append(('gas', nuclei_field))
                    elif atom != 'H':
                        fields.append(('gas', 'metallicity'))
                    else:
                        pass
            else:
                fields.append(('gas', alias_field))
        else:
            fields.append(('gas', field))
    return fields, fields_to_add_to_ds


def _validate_split_param(split_algo, split_param, algo_config):
    """
    validate param for editing, also returns param type
    """
    valid_params = algo_config['algo_params'][split_algo]
    if split_param in valid_params:
        if isinstance(valid_params[split_param], bool):
            cast_type = bool
        else:
            cast_type = int
        return True, cast_type
    else:
        return False, None


def rel_to_abs(target: str, namespace: str):
    """Convert name relative to namespace to absolute"""
    ns = namespace.split('.')
    nslen = len(ns)
    dots = 0
    while dots < len(target) and target[dots] == '.':
        dots += 1
    shared = nslen - dots + 1
    tg = target[dots:].split('.') if dots < len(target) else []
    abs = ns[:shared] + tg
    return '.'.join(abs)


def adapt_name_for_rest(name):
    """
    Modifies a user-provided name for use in API calls.
    Basically we want an alias like 'MDB:OPS Name/SIMULATOR_BatteryVoltage2'
    to be prepended with a slash.
    """
    if name.startswith('/'):
        return name
    elif '/' not in name:
        raise ValueError('Provided name is not a fully-qualified XTCE name.')
    return '/' + name


def start_frame_set():
    """Set the start frame

    """
    pass


def toCMISValue(value):
    """
    Utility function to convert Python values to CMIS string values
    """
    if value is False:
        return 'false'
    elif value is True:
        return 'true'
    elif value is None:
        return 'none'
    else:
        return value


@classmethod
def remove_verbs(cls, *verbs):
    """Remove verbs from this shell.

        :param str verbs: A sequence of verbs to remove
        :returns None:

        """
    for verb in verbs:
        command = cls._verbs.get(verb)
        if command:
            del cls._verbs[verb]
            verb = verb[:-1]
            while verb:
                if cls._verbs.get(verb) is command:
                    del cls._verbs[verb]
                verb = verb[:-1]


def test_jpeg3(h, f):
    """JPEG data in JFIF or Exif format"""
    if h[6:10] in (b'JFIF', b'Exif') or h[:2] == b'\xff\xd8':
        return 'jpeg'


def create_db_subnet_group(DBSubnetGroupName=None, DBSubnetGroupDescription
    =None, SubnetIds=None, Tags=None):
    """
    Creates a new DB subnet group. DB subnet groups must contain at least one subnet in at least two AZs in the region.
    See also: AWS API Documentation

    Examples
    This example creates a DB subnet group.
    Expected Output:

    :example: response = client.create_db_subnet_group(
        DBSubnetGroupName='string',
        DBSubnetGroupDescription='string',
        SubnetIds=[
            'string',
        ],
        Tags=[
            {
                'Key': 'string',
                'Value': 'string'
            },
        ]
    )

    :type DBSubnetGroupName: string
    :param DBSubnetGroupName: [REQUIRED]
            The name for the DB subnet group. This value is stored as a lowercase string.
            Constraints: Must contain no more than 255 alphanumeric characters, periods, underscores, spaces, or hyphens. Must not be default.
            Example: mySubnetgroup

    :type DBSubnetGroupDescription: string
    :param DBSubnetGroupDescription: [REQUIRED]
            The description for the DB subnet group.

    :type SubnetIds: list
    :param SubnetIds: [REQUIRED]
            The EC2 Subnet IDs for the DB subnet group.
            (string) --

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

    :rtype: dict
    :return: {
        'DBSubnetGroup': {
            'DBSubnetGroupName': 'string',
            'DBSubnetGroupDescription': 'string',
            'VpcId': 'string',
            'SubnetGroupStatus': 'string',
            'Subnets': [
                {
                    'SubnetIdentifier': 'string',
                    'SubnetAvailabilityZone': {
                        'Name': 'string'
                    },
                    'SubnetStatus': 'string'
                },
            ],
            'DBSubnetGroupArn': 'string'
        }
    }

    :returns:
    CreateDBSubnetGroup
    ModifyDBSubnetGroup
    DescribeDBSubnetGroups
    DeleteDBSubnetGroup

    """
    pass


@classmethod
def key_for(cls, job_id):
    """The Redis key that is used to store job hash under."""
    return (cls.redis_job_namespace_prefix + job_id).encode('utf-8')


@classmethod
def from_details(cls, details: dict):
    """Parse from decorator details."""
    return cls(passing=cls.normalize_from_details('passing', details),
        complete=cls.normalize_from_details('complete', details))


@conf
def common_flags_gdc(conf):
    """
	Sets the flags required by *gdc*
	"""
    v = conf.env
    v.DFLAGS = []
    v.D_SRC_F = ['-c']
    v.D_TGT_F = '-o%s'
    v.D_LINKER = v.D
    v.DLNK_SRC_F = ''
    v.DLNK_TGT_F = '-o%s'
    v.DINC_ST = '-I%s'
    v.DSHLIB_MARKER = v.DSTLIB_MARKER = ''
    v.DSTLIB_ST = v.DSHLIB_ST = '-l%s'
    v.DSTLIBPATH_ST = v.DLIBPATH_ST = '-L%s'
    v.LINKFLAGS_dshlib = ['-shared']
    v.DHEADER_ext = '.di'
    v.DFLAGS_d_with_header = '-fintfc'
    v.D_HDR_F = '-fintfc-file=%s'


def clean_spaces(m):
    """Replace unencoded spaces in string.

    :param str m: a match object
    :return: the cleaned string
    """
    return m.group(0).replace(' ', '=20')


def add_object_align_init(context: 'bpy.types.Context', operator:
    'bpy.types.Operator') ->'mathutils.Matrix':
    """Return a matrix using the operator settings and view context.

    :param context: The context to use.
    :type context: 'bpy.types.Context'
    :param operator: The operator, checked for location and rotation properties.
    :type operator: 'bpy.types.Operator'
    :return:  the matrix from the context and settings.
    """
    pass


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


def next_command(file_name):
    """ Get the first file line - truncate to the current pointer position."""
    with open(file_name, 'r+') as f:
        line = f.readline()
        remaining_lines = f.readlines()
        f.seek(0)
        f.writelines(remaining_lines)
        f.truncate()
    return line


def wrap_generator(func):
    """Identity decorator (only needed for async compatibility)"""
    return func


def kilograms(kilograms, format_spec=''):
    """Return a string with the unit appended."""
    return ('{:' + format_spec + '} kg').format(kilograms)


def calculate_hounsfield_unit(mu, mu_water, mu_air):
    """
    Given linear attenuation coefficients the function calculates the corresponding Hounsfield units.
    :param mu: Attenuation coefficient to determine corresponding Hounsfield unit.
    :param mu_water: Constant linear attenuation coefficient for water
    :param mu_air: Constant linear attenuation coefficient for air
    :return: Hounsfield unit corresponding to mu
    """
    HU = 1000 * ((mu - mu_water) / (mu_water - mu_air))
    return HU


def defval(val, default=None):
    """
    Returns val if is not None, default instead
    :param val:
    :param default:
    :return:
    """
    return val if val is not None else default


def index_find(string, start, end):
    """
    version of substring that matches
    :param string: string
    :param start: string to start splitting
    :param end: string to end splitting
    :return: string between start and end
    """
    return string.partition(start)[2].partition(end)[0]


def lower(text):
    """
    Creates a copy of ``text`` with all the cased characters converted to lowercase.

    The lowercasing algorithm used is described in section 3.13 of the Unicode Standard.

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

    :return: A copy of ``text`` with all the cased characters converted to lowercase.
    :rtype: ``str``
    """
    assert isinstance(text, str), '%s is not a string' % text
    return text.lower()


def getLines(fl, begin, end):
    """getLines(list,begin,end) --> get lines inclusive from begin to end"""
    add = 0
    for line in fl:
        if line in [begin]:
            chunk = line
            if end is begin:
                return chunk
            add = 1
        elif line in [end]:
            chunk += line
            add = 0
        elif add == 1:
            chunk += line
    return chunk


@classmethod
def discardConsoleEntries(cls):
    """Discards collected exceptions and console API calls.
        """
    return cls.build_send_payload('discardConsoleEntries', {}), None


def delete_cloud_front_origin_access_identity(Id=None, IfMatch=None):
    """
    Delete an origin access identity.
    See also: AWS API Documentation

    :example: response = client.delete_cloud_front_origin_access_identity(
        Id='string',
        IfMatch='string'
    )

    :type Id: string
    :param Id: [REQUIRED]
            The origin access identity's ID.

    :type IfMatch: string
    :param IfMatch: The value of the ETag header you received from a previous GET or PUT request. For example: E2QWRUHAPOMQZL .

    """
    pass


def setRecursionLimit(limit):
    """
    Module function to set the recursion limit.

    @param limit recursion limit (integer)
    """
    global gRecursionLimit
    gRecursionLimit = limit


def _is_version_range(req):
    """Returns true if requirements specify a version range."""
    assert len(req.specifier) > 0
    specs = list(req.specifier)
    if len(specs) == 1:
        return specs[0].operator != '=='
    else:
        return True


@staticmethod
def formatdict(data, key, value, fmt, sep):
    """convert dict or key-value pairs to appropriate dict format"""
    return dict(data)


@staticmethod
def _to_id(id_):
    """Converts the argument to a object suitable as an identifier.

        :return: a hashable object
        """
    return tuple(id_) if isinstance(id_, list) else id_


def check_has_key(dictionary, key_ref):
    """
    Check whether the dictionary has the specified key

    Parameters
    ----------
        dictionary: dict
            The dictionary to look through

        key_ref: str
            The key to look for
    """
    if key_ref not in dictionary.keys():
        raise KeyError('%r should contain the %r key' % (dictionary, key_ref))


def _get_movie_title_and_year(film):
    """A function to pull movie title and release year for further consumption.

    args:
        film: the IMDb 'Movie' object to pull info from.

    returns:
        a dictionary containing the films name and release year.
    """
    title = film.data.get('title')
    title = title if '()' not in title else title[:-3]
    year = film.data.get('year')
    year = year if year is not None else 3000
    return {'title': title, 'year': year}


def replacePlaceholders(txt, vals):
    """
    Replaces placeholders ``vals`` (dict) in a template ``txt``.
    """
    txt = txt.replace('\r', '').format(**vals)
    return txt


def increment_byte_string(bs):
    """Return the lexicographically next byte string of the same length.

    Return None if there is none (when the input is all 0xff bytes)."""
    for n in range(1, len(bs) + 1):
        if bs[-n] != 255:
            return bs[:-n] + bytes([bs[-n] + 1]) + bytes(n - 1)
    return None


def _list(element):
    """Regular expression for a gambit list"""
    return '{(\\s+' + element + ')+\\s+}'


def remove_quotes(string):
    """
    Remove quotes from string.

    Ex.:
      "foo" -> foo
      'foo' -> foo
      'foo  -> 'foo

    """
    quotes = '"', "'"
    if string.startswith(quotes) and string.endswith(quotes):
        return string[1:-1]
    return string


def view_center_cursor():
    """Center the view so that the cursor is in the middle of the view

    """
    pass


def merge_with_prev_year(df, year_delta, year_col='year', player_col=
    'player_url'):
    """Merge player stats from previous year."""
    if year_delta < 1:
        raise ValueError('year_delta must be >= 1, got {}!'.format(year_delta))
    prev_year_df = df.copy()
    prev_year_df[year_col] += year_delta
    merged_df = df.merge(prev_year_df, how='left', on=[player_col, year_col
        ], suffixes=('', '___{}'.format(year_delta)))
    return merged_df


def get_ssh_public_key(UserName=None, SSHPublicKeyId=None, Encoding=None):
    """
    Retrieves the specified SSH public key, including metadata about the key.
    The SSH public key retrieved by this action is used only for authenticating the associated IAM user to an AWS CodeCommit repository. For more information about using SSH keys to authenticate to an AWS CodeCommit repository, see Set up AWS CodeCommit for SSH Connections in the AWS CodeCommit User Guide .
    See also: AWS API Documentation

    :example: response = client.get_ssh_public_key(
        UserName='string',
        SSHPublicKeyId='string',
        Encoding='SSH'|'PEM'
    )

    :type UserName: string
    :param UserName: [REQUIRED]
            The name of the IAM user associated with the SSH public key.
            This parameter allows (per its regex pattern ) a string of characters consisting of upper and lowercase alphanumeric characters with no spaces. You can also include any of the following characters: =,.@-

    :type SSHPublicKeyId: string
    :param SSHPublicKeyId: [REQUIRED]
            The unique identifier for the SSH public key.
            This parameter allows (per its regex pattern ) a string of characters that can consist of any upper or lowercased letter or digit.

    :type Encoding: string
    :param Encoding: [REQUIRED]
            Specifies the public key encoding format to use in the response. To retrieve the public key in ssh-rsa format, use SSH . To retrieve the public key in PEM format, use PEM .

    :rtype: dict
    :return: {
        'SSHPublicKey': {
            'UserName': 'string',
            'SSHPublicKeyId': 'string',
            'Fingerprint': 'string',
            'SSHPublicKeyBody': 'string',
            'Status': 'Active'|'Inactive',
            'UploadDate': datetime(2015, 1, 1)
        }
    }

    """
    pass


def _related_used_by(remote, entry):
    """Factory returning related storage resources for `used_by`."""
    collections = remote.containers, remote.images, remote.profiles
    for collection in collections:
        if entry.startswith(collection.uri):
            return collection.get_resource(entry)
    return entry


@staticmethod
def urlizer(title):
    """
        This just a fancy name for a simple slug method.

        Keyword Arguments:
        title -- the actual title to make a slug
        """
    return '-'.join(title.lower().split())


def get_pipeline_url(environment: str, enterprise_id: str, pipeline_id: str
    =None) ->str:
    """
    Build and return pipeline url for scapi endpoint
    :param environment:
    :param enterprise_id:
    :param pipeline_id:
    :param stage_id:
    :param operation_id:
    :return: Url
    """
    url = (
        f'https://{environment}-api.esper.cloud/api/v1/enterprise/{enterprise_id}/pipeline/'
        )
    if pipeline_id:
        url += f'{pipeline_id}/'
    return url


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 '+'


@classmethod
def link_starting_with_text(cls, text):
    """Returns an XPath to find an HTML <a> containing text that starts with the contents of `text`."""
    return cls('//a[starts-with(node(), "%s")]' % text)


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

        :param FileAddType val:
        :rtype: EventType
        """
    return cls('file_add', val)


def readFasta(file):
    """
    Read textual input from the file object `file`, which is assumed to
    be in FASTA format.  Yields the sequence of (name, sequence) tuples.
    """
    nm = None
    seq = []
    for l in file:
        l = l.strip()
        if len(l) and l[0] == '>':
            if nm is not None:
                yield nm, ''.join(seq)
            nm = l[1:].strip()
            seq = []
        else:
            seq.append(l)
    if nm is not None:
        yield nm, ''.join(seq)


def ExpMag(x: float, params):
    """Compute surface brightness for a profile consisting of an exponential,
    given input parameters in vector params:
        params[0] = mu_0
        params[1] = h
    """
    mu_0 = params[0]
    h = params[1]
    return mu_0 + 1.085736 * (x / h)


def getNode(node, tagpath):
    """returns the *first* matching node for given tag path."""
    if tagpath == '':
        return node
    assert type(tagpath) == str
    tags = tagpath.split('/')
    assert len(tags) > 0
    for tag in tags:
        currentNode = None
        for child in node.tags():
            if child.name() == tag:
                currentNode = child
                break
        if not currentNode:
            return None
        else:
            node = currentNode
    return currentNode


@staticmethod
def _getTagValue(src, tag):
    """Helper function: looks for the given tag in the source, or in its sub-objects"""
    for obj in (src, src.pos, src.flux, getattr(src, 'shape', None),
        getattr(src, 'spectrum', None)):
        if obj is not None and hasattr(obj, tag):
            return getattr(obj, tag)
    return None


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 get_hr(A):
    """ Return the half-right of the given array.
    """
    nx, _ = A.shape
    li = int(nx / 2)
    return A[:, li:]


def compact(**kwargs):
    """Trigger a compaction operation.

    http://docs.couchdb.org/en/stable/api/database/compact.html#post--db-_compact

    :param kwargs: (optional) Arguments that :meth:`requests.Session.request` takes.
    :rtype: (str, str, dict)
    """
    if 'headers' not in kwargs or not isinstance(kwargs['headers'], dict):
        kwargs['headers'] = {}
    kwargs['headers']['Content-Type'] = 'application/json'
    return 'POST', '_compact', kwargs


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

        :param SmartSyncNotOptOutDetails val:
        :rtype: EventDetails
        """
    return cls('smart_sync_not_opt_out_details', val)


def cmip():
    """
    Download CMIP5 model data.

    Warning
    -------
    Not yet implemented.
    """
    raise NotImplementedError


def atom_explicit_valence(atom):
    """Get the explicit valence of an atom.

    Parameters
    ----------
    atom : rdkit.Chem.rdchem.Atom
        RDKit atom instance.

    Returns
    -------
    list
        List containing one int only.

    See Also
    --------
    atom_explicit_valence_one_hot
    """
    return [atom.GetExplicitValence()]


def decode_response(client_message, to_object=None):
    """ Decode response from client message"""
    parameters = dict(response=None)
    parameters['response'] = client_message.read_str()
    return parameters


def unpack(value):
    """
    Return a three tuple of data, code, and headers
    """
    if not isinstance(value, tuple):
        return value, 200, {}
    try:
        data, code, headers = value
        return data, code, headers
    except ValueError:
        pass
    try:
        data, code = value
        return data, code, {}
    except ValueError:
        pass
    return value, 200, {}


def setOwner(segments, owner):
    """
        Set file/folder owner.
        """


def py_type_name(type_name):
    """Get the Python type name for a given model type.

        >>> py_type_name('list')
        'list'
        >>> py_type_name('structure')
        'dict'

    :rtype: string
    """
    return {'blob': 'bytes', 'character': 'string', 'double': 'float',
        'long': 'integer', 'map': 'dict', 'structure': 'dict', 'timestamp':
        'datetime'}.get(type_name, type_name)


def extract_coefficient_spaces(forms):
    """Extract a list of tuples

      (classname, finite_element_classname, dofmap_classname)

    for the coefficient spaces in the set of given forms. This can
    then be used for input to the function space template."""
    spaces = {}
    for form in forms:
        for i, name in enumerate(form.coefficient_names):
            if name in spaces:
                continue
            spaces[name] = ('CoefficientSpace_%s' % name, form.
                ufc_finite_element_classnames[form.rank + i], form.
                ufc_dofmap_classnames[form.rank + i])
    names = sorted(spaces.keys())
    return [spaces[name] for name in names]


def replace(language, items):
    """Replace all items for a given language.

        Items are given as (path, identifier) tuples.

        Note that order will be assigned naively. It is assumed that
        items are given in depth-first order.
        """


def print_table_format(headers, values):
    """Formats and prints tabular formatted data.

    headers = ['col1', 'col2']
    values  = [
        ['row1col1', 'row2col1'],
        ['row1col2', 'row2col2']
    ]

    Output:
    col1     col2
    -------- --------
    row1col1 row2col1
    row1col2 row2col2

    Args:
        headers: A list of the headers for each column.
        values: A list of lists, each list containing a column of data.
    """
    if len(headers) != len(values):
        raise Exception('Not enough headers for columns.')
    row_format = ''
    max_lens = []
    for i, v in enumerate(values):
        row_format += '{{{0}:<{{{1}}}}} '.format(i * 2, i * 2 + 1)
        v.insert(0, headers[i])
        max_len = len(max(v, key=len))
        max_lens.append(max_len)
        v.insert(1, '-' * max_len)
    row_len = len(values) + len(max_lens)
    for row_items in zip(*values):
        row = [None] * row_len
        row[::2] = row_items
        row[1::2] = max_lens
        print(row_format.format(*row))


def clonebundles():
    """Obtains the clone bundles manifest for the repo.

        Returns the manifest as unparsed bytes.
        """


def varintdecode(data):
    """Varint decoding."""
    shift = 0
    result = 0
    for c in data:
        b = ord(c)
        result |= (b & 127) << shift
        if not b & 128:
            break
        shift += 7
    return result


def nodetype(anode):
    """return the type of node"""
    try:
        return anode[1]
    except IndexError as e:
        return None


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

        :param TfaAddSecurityKeyType val:
        :rtype: EventType
        """
    return cls('tfa_add_security_key', val)


def index(indexes=None):
    """Index the content in the catalog. If a list of indexes
        names is given as argument, only those indexes will be indexed.
        """


@classmethod
def _map_tuning_objective(cls, objective_type, objective_metric_name):
    """
        Construct a dictionary of tuning objective from the arguments

        Args:
            objective_type (str): The type of the objective metric for evaluating training jobs.
                This value can be either 'Minimize' or 'Maximize'.
            objective_metric_name (str): Name of the metric for evaluating training jobs.

        Returns:
            A dictionary of tuning objective. For format details, please refer to
            HyperParameterTuningJobObjective as described in
            https://botocore.readthedocs.io/en/latest/reference/services/sagemaker.html#SageMaker.Client.create_hyper_parameter_tuning_job
        """
    tuning_objective = None
    if objective_type is not None or objective_metric_name is not None:
        tuning_objective = {}
    if objective_type is not None:
        tuning_objective['Type'] = objective_type
    if objective_metric_name is not None:
        tuning_objective['MetricName'] = objective_metric_name
    return tuning_objective


def match_items(lines, content_old):
    """Create items for mangled lines.

    This function tries to match the lines in ``lines`` with the items (source
    file references and line numbers) in ``content_old``. The
    ``mangle_docstrings`` function changes the actual docstrings, but doesn't
    keep track of where each line came from. The manging does many operations
    on the original lines, which are hard to track afterwards.

    Many of the line changes come from deleting or inserting blank lines. This
    function tries to match lines by ignoring blank lines. All other changes
    (such as inserting figures or changes in the references) are completely
    ignored, so the generated line numbers will be off if ``mangle_docstrings``
    does anything non-trivial.

    This is a best-effort function and the real fix would be to make
    ``mangle_docstrings`` actually keep track of the ``items`` together with
    the ``lines``.

    Examples
    --------
    >>> lines = ['', 'A', '', 'B', '   ', '', 'C', 'D']
    >>> lines_old = ['a', '', '', 'b', '', 'c']
    >>> items_old = [('file1.py', 0), ('file1.py', 1), ('file1.py', 2),
    ...              ('file2.py', 0), ('file2.py', 1), ('file2.py', 2)]
    >>> content_old = ViewList(lines_old, items=items_old)
    >>> match_items(lines, content_old) # doctest: +NORMALIZE_WHITESPACE
    [('file1.py', 0), ('file1.py', 0), ('file2.py', 0), ('file2.py', 0),
     ('file2.py', 2), ('file2.py', 2), ('file2.py', 2), ('file2.py', 2)]
    >>> # first 2 ``lines`` are matched to 'a', second 2 to 'b', rest to 'c'
    >>> # actual content is completely ignored.

    Notes
    -----
    The algorithm tries to match any line in ``lines`` with one in
    ``lines_old``.  It skips over all empty lines in ``lines_old`` and assigns
    this line number to all lines in ``lines``, unless a non-empty line is
    found in ``lines`` in which case it goes to the next line in ``lines_old``.

    """
    items_new = []
    lines_old = content_old.data
    items_old = content_old.items
    j = 0
    for i, line in enumerate(lines):
        while j < len(lines_old) - 1 and not lines_old[j].strip():
            j += 1
        items_new.append(items_old[j])
        if line.strip() and j < len(lines_old) - 1:
            j += 1
    assert len(items_new) == len(lines)
    return items_new


def _get_output_filename(dataset_dir, split_name):
    """Creates the output filename.

  Args:
    dataset_dir: The dataset directory where the dataset is stored.
    split_name: The name of the train/test split.

  Returns:
    An absolute file path.
  """
    return '%s/cifar10_%s.tfrecord' % (dataset_dir, split_name)


def cb_dataValid():
    """Return true if clipboard data seems valid.
        """


def flatten(fields):
    """
    Return a list which is a single level of flattening of the original list.
    """
    flat = []
    for field in fields:
        if isinstance(field, (list, tuple)):
            flat.extend(field)
        else:
            flat.append(field)
    return flat


def _createMeshName(mesh, outputDir='./output', index=None):
    """
    Returns a string - "outputDir/Mesh_res_time.h5"

    """
    if not index == None:
        if not isinstance(index, int):
            ValueError("'index' must be None or type int")
    tmp = map(str, mesh.elementRes)
    st = ''
    for x in tmp:
        st += str(x) + 'x'
    st = st[:-1]
    if index == None:
        return '{0}/Mesh_{1}.h5'.format(outputDir, st)
    else:
        return '{0}/Mesh_{1}.{2}.h5'.format(outputDir, st, index)


def bisect_right(a, x, lo=0, hi=None):
    """Return the index where to insert item x in list a, assuming a is sorted.

    The return value i is such that all e in a[:i] have e <= x, and all e in
    a[i:] have e > x.  So if x already appears in the list, a.insert(x) will
    insert just after the rightmost x already there.

    Optional args lo (default 0) and hi (default len(a)) bound the
    slice of a to be searched.
    """
    if lo < 0:
        raise ValueError('lo must be non-negative')
    if hi is None:
        hi = len(a)
    while lo < hi:
        mid = (lo + hi) // 2
        if x < a[mid]:
            hi = mid
        else:
            lo = mid + 1
    return lo