def parse_free(free, n, r, N):
    """Parses the free parameters vector and returns it's components.

    free : ndarray, shape(n * N + m * M + q)
        The free parameters of the system.
    n : integer
        The number of states.
    r : integer
        The number of free specified inputs.
    N : integer
        The number of time steps.

    Returns
    -------
    states : ndarray, shape(n, N)
        The array of n states through N time steps.
    specified_values : ndarray, shape(r, N) or shape(N,), or None
        The array of r specified inputs through N time steps.
    constant_values : ndarray, shape(q,)
        The array of q constants.

    """
    len_states = n * N
    len_specified = r * N
    free_states = free[:len_states].reshape((n, N))
    if r == 0:
        free_specified = None
    else:
        free_specified = free[len_states:len_states + len_specified]
        if r > 1:
            free_specified = free_specified.reshape((r, N))
    free_constants = free[len_states + len_specified:]
    return free_states, free_specified, free_constants


def db2dbm(quality):
    """
    Converts the Radio (Received) Signal Strength Indicator (in db) to a dBm
    value.  Please see http://stackoverflow.com/a/15798024/1013960
    """
    dbm = int(quality / 2 - 100)
    return min(max(dbm, -100), -50)


def stopDebugServer():
    """Stop the debug server"""


def coverage_shortest(seq_query, seq_target, seq_len):
    """
    Return coverage of the shortest sequence in the alignment.

    >>> coverage_shortest("AAAA----", "AAAAAAAA", 8)
    50.0
    """
    res_query = len(seq_query.replace('-', ''))
    res_target = len(seq_target.replace('-', ''))
    return 100.0 * min(res_query, res_target) / seq_len


@staticmethod
def _tag(val, tag):
    """Surround val with <tag></tag>"""
    if isinstance(val, str):
        val = bytes(val, 'utf-8')
    return bytes('<' + tag + '>', 'utf-8') + val + bytes('</' + tag + '>',
        'utf-8')


@classmethod
def add_arguments(cls, parser, sys_arg_list=None):
    """
        Arguments for the configfile mode.

        """
    parser.add_argument('-f', '--file', dest='file', required=True, help=
        'config file for routing groups (only in configfile mode)')
    return ['file']


def float_to_format(value, target_format):
    """Convert float to specified format"""
    if target_format == int:
        ret = int(value)
    elif target_format == str:
        ret = str(value)
    else:
        ret = value
    return ret


def get_public_tree_all(depth=-1):
    """Get flattened tree with all public content, excluding
        subpublications.  The 'depth' argument limits the number of
        levels, defaults to unlimited.  This is a list of indent,
        object tuples.
        """


def get_bounding_box(font):
    """ Returns max and min bbox of given truetype font """
    ymin = 0
    ymax = 0
    if font.sfntVersion == 'OTTO':
        ymin = font['head'].yMin
        ymax = font['head'].yMax
    else:
        for g in font['glyf'].glyphs:
            char = font['glyf'][g]
            if hasattr(char, 'yMin') and ymin > char.yMin:
                ymin = char.yMin
            if hasattr(char, 'yMax') and ymax < char.yMax:
                ymax = char.yMax
    return ymin, ymax


def prepare_ann_file(args):
    """
    Create custom ann_file for Coral
    """


def parse_wyckoff_csv(wyckoff_file):
    """Parse Wyckoff.csv
    There are 530 data sets. For one example:
    9:C 1 2 1:::::::
    ::4:c:1:(x,y,z):(-x,y,-z)::
    ::2:b:2:(0,y,1/2):::
    ::2:a:2:(0,y,0):::
    """
    rowdata = []
    points = []
    hP_nums = [433, 436, 444, 450, 452, 458, 460]
    for i, line in enumerate(wyckoff_file):
        if line.strip() == 'end of data':
            break
        rowdata.append(line.strip().split(':'))
        if rowdata[-1][0].isdigit():
            points.append(i)
    points.append(i)
    wyckoff = []
    for i in range(len(points) - 1):
        symbol = rowdata[points[i]][1]
        if i + 1 in hP_nums:
            symbol = symbol.replace('R', 'H', 1)
        wyckoff.append({'symbol': symbol.strip()})
    for i in range(len(points) - 1):
        count = 0
        wyckoff[i]['wyckoff'] = []
        for j in range(points[i] + 1, points[i + 1]):
            if rowdata[j][2].isdigit():
                pos = []
                w = {'letter': rowdata[j][3].strip(), 'multiplicity': int(
                    rowdata[j][2]), 'site_symmetry': rowdata[j][4].strip(),
                    'positions': pos}
                wyckoff[i]['wyckoff'].append(w)
                for k in range(4):
                    if rowdata[j][k + 5]:
                        count += 1
                        pos.append(rowdata[j][k + 5])
            else:
                for k in range(4):
                    if rowdata[j][k + 5]:
                        count += 1
                        pos.append(rowdata[j][k + 5])
    return wyckoff


def _is_equal_position(first: tuple, second: tuple, position):
    """Whether both position are equal in the given tuples."""
    if len(first) > position:
        if len(second) > position:
            return first[position] == second[position]
        return first[position] is None
    if len(second) > position:
        return second[position] is None
    return True


@staticmethod
def _tcx_filename(activity):
    """Format a (non-directory) file name for ``activity``."""
    return f'{activity.start_date_str}_{activity.id}.tcx'


def load_handlers(name):
    """Load the (URL pattern, handler) tuples for each component."""
    mod = __import__(name, fromlist=['default_handlers'])
    return mod.default_handlers


def delete_db_cluster_parameter_group(DBClusterParameterGroupName=None):
    """
    Deletes a specified DB cluster parameter group. The DB cluster parameter group to be deleted cannot be associated with any DB clusters.
    For more information on Amazon Aurora, see Aurora on Amazon RDS in the Amazon RDS User Guide.
    See also: AWS API Documentation

    Examples
    This example deletes the specified DB cluster parameter group.
    Expected Output:

    :example: response = client.delete_db_cluster_parameter_group(
        DBClusterParameterGroupName='string'
    )

    :type DBClusterParameterGroupName: string
    :param DBClusterParameterGroupName: [REQUIRED]
            The name of the DB cluster parameter group.
            Constraints:
            Must be the name of an existing DB cluster parameter group.
            You cannot delete a default DB cluster parameter group.
            Cannot be associated with any DB clusters.

    :return: response = client.delete_db_cluster_parameter_group(
        DBClusterParameterGroupName='mydbclusterparametergroup',
    )

    print(response)

    """
    pass


def app_template_install(overwrite: bool=True, filepath: str='',
    filter_folder: bool=True, filter_glob: str='*.zip'):
    """Install an application-template

    :param overwrite: Overwrite, Remove existing template with the same ID
    :type overwrite: bool
    :param filepath: filepath
    :type filepath: str
    :param filter_folder: Filter folders
    :type filter_folder: bool
    :param filter_glob: filter_glob
    :type filter_glob: str
    """
    pass


def subdivision_custom_handler(subdivision):
    """
    Manages special cases on a subdivision object.
    """
    pass


def modify():
    """Modify a scheduled task"""
    raise NotImplementedError


def str2bool(v):
    """
    Convert a string to a boolean

    :return boolean: Returns True if string is a true-type string.
    """
    return v.lower() in ('true', 't', '1', 'yes', 'y')


def success(contract, adjust):
    """
    Calculates the success rate of the customers.
    """
    accomp = adjust / contract
    return accomp


@classmethod
def names(cls):
    """Returns all provider names in registry."""
    return cls._REGISTRY.keys()


@staticmethod
def disc_factor_from_rate(start, end, dcc, rate):
    """
        calculates discount factor between given dates (start date excluded, end date included) from given rate

        :param BusinessDate start : start date of BusinessPeriod
        :param BusinessDate end : end date of BusinessPeriod
        :param dcc dcc : BusinessPeriod day count convention
        :param double rate : discount rate
        :return double : discount factor
        """
    pass


def txcost(x):
    """Transmission cost expression."""
    return 0 if x == 0 else 965 if x > 5000 else 16319 * x ** -0.332


def convertListToDic(l):
    """Takes a list of strings such as "'1:2', 'a:b'" and returns
    a dictionary.
    """
    d = {}
    for item in l:
        isplit = item.split(':')
        d[isplit[0]] = isplit[1]
    return d


@classmethod
def get_perceval_params_from_url(cls, url):
    """ Get the perceval params given a URL for the data source """
    params = []
    tokens = url.split(' ')
    repo = tokens[0]
    owner = repo.split('/')[-2]
    repository = repo.split('/')[-1]
    params.append(owner)
    params.append(repository)
    if len(tokens) > 1:
        params.extend(tokens[1:])
    return params


def perm_delete_replicas(issuer, kwargs):
    """
    Checks if an account can delete replicas.

    :param issuer: Account identifier which issues the command.
    :param kwargs: List of arguments for the action.
    :returns: True if account is allowed, otherwise False
    """
    return False


def is_two_byte(val):
    """ A tag is at least two bytes long if the least significant
        5 bits of the first byte are set. """
    return val & 31 == 31


def delete_vault_notifications(accountId=None, vaultName=None):
    """
    This operation deletes the notification configuration set for a vault. The operation is eventually consistent; that is, it might take some time for Amazon Glacier to completely disable the notifications and you might still receive some notifications for a short time after you send the delete request.
    An AWS account has full permission to perform all operations (actions). However, AWS Identity and Access Management (IAM) users don't have any permissions by default. You must grant them explicit permission to perform specific actions. For more information, see Access Control Using AWS Identity and Access Management (IAM) .
    For conceptual information and underlying REST API, see Configuring Vault Notifications in Amazon Glacier and Delete Vault Notification Configuration in the Amazon Glacier Developer Guide.
    See also: AWS API Documentation

    Examples
    The example deletes the notification configuration set for the vault named examplevault.
    Expected Output:

    :example: response = client.delete_vault_notifications(
        vaultName='string'
    )

    :type accountId: string
    :param accountId: The AccountId value is the AWS account ID of the account that owns the vault. You can either specify an AWS account ID or optionally a single '- ' (hyphen), in which case Amazon Glacier uses the AWS account ID associated with the credentials used to sign the request. If you use an account ID, do not include any hyphens ('-') in the ID.
            Note: this parameter is set to '-' bydefault if no value is not specified.

    :type vaultName: string
    :param vaultName: [REQUIRED]
            The name of the vault.

    :return: response = client.delete_vault_notifications(
        accountId='-',
        vaultName='examplevault',
    )

    print(response)

    """
    pass


def _pipe_segment_with_colons(align, colwidth):
    """Return a segment of a horizontal line with optional colons which
    indicate column's alignment (as in `pipe` output format)."""
    w = colwidth
    if align in ['right', 'decimal']:
        return '-' * (w - 1) + ':'
    elif align == 'center':
        return ':' + '-' * (w - 2) + ':'
    elif align == 'left':
        return ':' + '-' * (w - 1)
    else:
        return '-' * w


def month():
    """Return the month of the object as an integer"""


def _pad_dims(tensor, rank):
    """Append empty dimensions to the tensor until it is of the given rank."""
    for _ in range(rank - tensor.shape.ndims):
        tensor = tensor[..., None]
    return tensor


@classmethod
def by_name(cls, name: str):
    """Get service type by its name."""
    if name is None:
        return cls.GITHUB
    name = name.lower()
    if name == 'github':
        return cls.GITHUB
    elif name == 'gitlab':
        return cls.GITLAB
    else:
        raise NotImplementedError(
            f"Unsupported service {name!r}, available ones are 'github' and 'gitlab'"
            )


def to_hours(timedelta):
    """
    timedelta : timedelta value
    """
    return float(timedelta.days) * 24 + float(timedelta.seconds) / (60 * 60)


def is_even_for_rounding(c, exp):
    """General-purpose tiebreak used when rounding to even.
    If the significand is less than two bits,
    decide evenness based on the representation of the exponent.
    """
    if c.bit_length() > 1:
        return c & 1 == 0
    else:
        return exp & 1 == 0


def validate_list(integer_list):
    """
    Ensure that the user-supplied input is a list of integers, or a list of strings
    that can be parsed as integers.
    """
    if not integer_list:
        raise Exception(
            'No bugs to migrate! Call `migrate` with a list of bug ids.')
    if not isinstance(integer_list, list):
        raise Exception('Expected a list of integers. Instead recieved a(n) {}'
            .format(type(integer_list)))
        for i in integer_list:
            try:
                int(i)
            except ValueError:
                raise Exception(
                    '{} is not able to be parsed as an integer, and is therefore an invalid bug id.'
                    .format(i))


def email_for_user(username, check_exists=True):
    """Return email for a user.

    Currently, just appends @ocf.berkeley.edu, but could eventually do
    something more complicated.
    """
    if check_exists:
        from ocflib.account.search import user_exists
        if not user_exists(username):
            raise ValueError('Account "{}" does not exist.'.format(username))
    return '{}@ocf.berkeley.edu'.format(username)


@classmethod
def _get_attribute_list(cls):
    """Calculate the list of all attributes of this structure."""
    attrs = []
    for base in cls.__bases__:
        try:
            attrs.extend(base._get_attribute_list())
        except AttributeError:
            pass
    attrs.extend(cls._attrs)
    return attrs


def EWT_beta(x):
    """
    Beta = EWT_beta(x)
    function used in the construction of Meyer's wavelet
    """
    if x < 0:
        bm = 0
    elif x > 1:
        bm = 1
    else:
        bm = x ** 4 * (35.0 - 84.0 * x + 70.0 * x ** 2 - 20.0 * x ** 3)
    return bm


def get_doc():
    """Get documentation of this resource

    :return: rst string
    :rtype: str
    """
    return """
    The ``actiondowntime`` contains the downtimes requested and processed.

    To schedule a downtime for an host/service the client post on this endpoint to create a new
    downtime request that will be managed by the Alignak backend Broker module to build an
    external command notified to the Alignak framework.

    **Note** that the Alignak Web Services module allow to use more external commands.
    """


@staticmethod
def _F1(a, b):
    """Integration term. See Yeadon 1990-ii Appendix 2."""
    return 1.0 + (a + b) * 0.5 + a * b / 3.0


def copy_files(in_out_path_pairs):
    """Dumb way to copy files"""
    for in_path, out_path in in_out_path_pairs:
        with in_path.open('r') as r:
            with out_path.open('w') as w:
                w.write(r.read())


def fulltext():
    """Returns a string containing all the words of all content.

        For fulltext ZCatalog search.
        XXX This should really be on an interface in the Silva core"""


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

    """
    pass


def determineException(vm, m):
    """
    Returns try-catch handler inside the method.

    :param vm: a :class:`~DalvikVMFormat`
    :param m: a :class:`~EncodedMethod`
    :return:
    """
    if m.get_code().get_tries_size() <= 0:
        return []
    h_off = {}
    handler_catch_list = m.get_code().get_handlers()
    for try_item in m.get_code().get_tries():
        offset_handler = try_item.get_handler_off(
            ) + handler_catch_list.get_off()
        if offset_handler in h_off:
            h_off[offset_handler].append([try_item])
        else:
            h_off[offset_handler] = []
            h_off[offset_handler].append([try_item])
    for handler_catch in handler_catch_list.get_list():
        if handler_catch.get_off() not in h_off:
            continue
        for i in h_off[handler_catch.get_off()]:
            i.append(handler_catch)
    exceptions = []
    for i in h_off:
        for value in h_off[i]:
            try_value = value[0]
            z = [try_value.get_start_addr() * 2, try_value.get_start_addr() *
                2 + try_value.get_insn_count() * 2 - 1]
            handler_catch = value[1]
            if handler_catch.get_size() <= 0:
                z.append(['Ljava/lang/Throwable;', handler_catch.
                    get_catch_all_addr() * 2])
            for handler in handler_catch.get_handlers():
                z.append([vm.get_cm_type(handler.get_type_idx()), handler.
                    get_addr() * 2])
            exceptions.append(z)
    return exceptions


@staticmethod
def user_parse(data):
    """Parse information from provider."""
    id_ = data.get('id')
    yield 'id', id_
    yield 'email', data.get('email')
    yield 'first_name', data.get('first_name')
    yield 'last_name', data.get('last_name')
    yield 'username', data.get('name')
    yield 'picture', 'http://graph.facebook.com/{0}/picture?type=large'.format(
        id_)
    yield 'link', data.get('link')
    yield 'locale', data.get('locale')
    yield 'gender', data.get('gender')
    location = data.get('location', {}).get('name')
    if location:
        split_location = location.split(', ')
        yield 'city', split_location[0].strip()
        if len(split_location) > 1:
            yield 'country', split_location[1].strip()


@staticmethod
def denormalize_attachment(attachment):
    """convert attachment metadata from archivant to es format"""
    res = dict()
    ext = ['id', 'url']
    for k in ext:
        if k in attachment['metadata']:
            raise ValueError(
                "metadata section could not contain special key '{}'".format(k)
                )
        res[k] = attachment[k]
    res.update(attachment['metadata'])
    return res


def update_with_tokens(dict_gt, nusc, token_sd):
    """
    Update with tokens corresponding to the token_sd
    """
    table_sample_data = nusc.get('sample_data', token_sd)
    token_sample = table_sample_data['sample_token']
    table_sample = nusc.get('sample', token_sample)
    token_scene = table_sample['scene_token']
    dict_gt['token_sample_data'] = token_sd
    dict_gt['token_sample'] = token_sample
    dict_gt['token_scene'] = token_scene
    return dict_gt


def to_upper(string, conv=str):
    """
    Convert the input to a string and uppercase it.

    Conversion is done by `conv`, which is normally :py:class:`str`, but
    :py:func:`repr` is sometimes a good choice as well.
    """
    return conv(string).upper()


def _wrap(begin, text, parts, end, tail):
    """Wrap some iterable parts in beginning and ending fenceposts. Simply
    yields begin, then each part, then end."""
    if begin:
        yield begin
    if text:
        yield text
    for part in parts:
        yield part
    if end:
        yield end
    if tail:
        yield tail


def __init__(cls, name, bases, attrs):
    """
		Some central control logic later goes in here.
		"""
    pass


def group_dict_by_value(d: dict) ->dict:
    """
    Group a dictionary by values.

    Parameters
    ----------
    d : dict
        Input dictionary

    Returns
    -------
    dict
        Output dictionary. The keys are the values of the initial dictionary
        and the values ae given by a list of keys corresponding to the value.

    >>> group_dict_by_value({2: 3, 1: 2, 3: 1})
    {3: [2], 2: [1], 1: [3]}
    >>> group_dict_by_value({2: 3, 1: 2, 3: 1, 10:1, 12: 3})
    {3: [2, 12], 2: [1], 1: [3, 10]}
    """
    d_out = {}
    for k, v in d.items():
        if v in d_out:
            d_out[v].append(k)
        else:
            d_out[v] = [k]
    return d_out


def mapM_(monad, mf, xs):
    """ Map a monadic  action to a structure, evaluate from left to right and ignore results. """
    list(map(mf, xs))
    return monad.of(xs)


def uninstall(context):
    """Uninstall script"""
    if context.readDataFile('collectiveredirectpage_uninstall.txt') is None:
        return


@classmethod
def _get_starting_name_delimiter(cls):
    """
        Return the string that prefaces the object name within the dn
        :return: string that prefaces the object name within the dn
        """
    delimiters = cls._get_name_dn_delimiters()
    if len(delimiters) == 0:
        return None
    return delimiters[0]


@staticmethod
def read(reader, _index):
    """
        Reads Zserio float64 type from the bit stream.

        :param reader: Bit stream from which to read.
        :param _index: Not used.
        """
    return reader.readFloat64()


def _host_is_same(host1: str, host2: str) ->bool:
    """Check if host1 and host2 are the same."""
    return host1.split(':')[0] == host2.split(':')[0]


def material_slot_copy():
    """Copy material to selected objects

    """
    pass


def _validate_attribute_values_are_ddb_items(instance, attribute, value):
    """Validate that dictionary values in ``value`` match the structure of DynamoDB JSON
    items.

    .. note::

        We are not trying to validate the full structure of the item with this validator.
        This is just meant to verify that the values roughly match the correct format.
    """
    for data in value.values():
        if len(list(data.values())) != 1:
            raise TypeError('"{}" values do not look like DynamoDB items'.
                format(attribute.name))


def cards(title, text, card_type='Simple', image=None):
    """
    Returns alexa cards

    :param str title: A string containing the title of the card.
    :param str text: A string containing the text content for a Standard card
        (not applicable for cards of type Simple)
    :param str card_type: A string describing the type of card to render. Valid types are:
        * "Simple": A card that contains a title and plain text content.
        * "Standard": A card that contains a title, text content, and an image to display.
    :param dict image: An image object that specifies the URLs for the image to display on a Standard card.
        Only applicable for Standard cards.
        You can provide two URLs, for use on different sized screens.
        * smallImageUrl
        * largeImageUrl
    :return: Dictionary with cards details
    :rtype: dict

    Alexa API Reference:
        https://developer.amazon.com/docs/custom-skills/request-and-response-json-reference.html#card-object

    """
    cards = {'type': card_type, 'title': title}
    if card_type == 'Standard':
        cards['text'] = text
    else:
        cards['content'] = text
    if image:
        cards['image'] = image
    return cards


def get_latest_paths_from_hd_wallet_addresses(wallet_addresses):
    """
    Returns a list of dicts like this (note these are full paths):

    [
        {'subchain_index': 0, 'latest_path': 'm/0/2', 'latest_address':  '1foo',},
        {'subchain_index': 1, 'latest_path': None, 'latest_address':  None,},
        ...
    ]

    Note that if there is no subchain_index, it will return a singleton list
    with a 'subchain_index' entry set to None.
    """
    latest_paths = []
    for chain in wallet_addresses['chains']:
        latest_path = None
        latest_address = None
        if chain['chain_addresses']:
            latest_address = chain['chain_addresses'][-1].get('address')
            latest_path = chain['chain_addresses'][-1].get('path')
        latest_path_dict = {'latest_path': latest_path, 'latest_address':
            latest_address}
        if 'index' in chain:
            index = chain['index']
            latest_path_dict['subchain_index'] = index
        else:
            latest_path_dict['subchain_index'] = None
        latest_paths.append(latest_path_dict)
    return latest_paths


def non_zero_division_NA(x, y):
    """Ensures safe division of x by y, assuming that the result will be zero if x is 0, and NA if y is zero."""
    if y == 0:
        return 'NA'
    elif x == 0:
        return int(0)
    else:
        return x / y


def clean_string(string):
    """
    Clean up a string.

    TODO: This is dumb
    """
    return string.strip('\n\r ').rstrip('\n\r ').replace('\n\r', ' ').replace(
        '\r\n', ' ').replace('\n', ' ').replace('\r', ' ').replace('  ', ' ')


def add_column(colname, desc=None, type=None, nullable=True):
    """Adds column in the form of dict."""
    col_dict = {'name': colname, 'desc': desc}
    if type is not None:
        col_dict['type'] = str(type)
    if not nullable:
        col_dict['nullable'] = False
    return col_dict


@classmethod
def find_by_product(cls, store, product):
    """find results for this view that references *product*

        :param store: the store that will be used to find the results
        :param product: the |product| used to filter the results
        :returns: the matching views
        :rtype: a sequence of :class:`InventoryItemView`
        """
    return store.find(cls, product_id=product.id)


def plot_nphist2d_contour(ax, hist, bins, level, color=None, label=None, **
    kwargs):
    """Draw level contour for the 2D numpy histogram.

    Parameters
    ----------
    ax : Axes
        Matplotlib axes on which contours will be plotted.
    hist : ndarray, shape (N,M)
        Histogram to be plotted.
    bins : (ndarray, ndarray)
        Bind edges for the histograms.
    level : float or list of float
        Value of level(s) at which contour(s) will be drawn.
    color : str or list of str or None, optional
        Colors for each contour to be drawn. If `color` is a str then
        all contours will have the same color.
    label : str or list of str or None, optional
        Labels for contours. If `label` is str, then only the first contour
        will be labeled.
    kwargs : dict, optional
        Additional parameters to pass directly to the pyplot.contour function

    Returns
    -------
    pyplot.contour.QuadContourSet
        Matplotlib contour set
    """
    bins_x = bins[0]
    bins_y = bins[1]
    range_x = bins_x[0], bins_x[-1]
    range_y = bins_y[0], bins_y[-1]
    centers_x = (bins_x[1:] + bins_x[:-1]) / 2
    centers_y = (bins_y[1:] + bins_y[:-1]) / 2
    if isinstance(level, (tuple, list)):
        levels = level
    else:
        levels = [level]
    contour_set = ax.contour(centers_x, centers_y, hist.T, levels=levels,
        origin='lower', extent=range_x + range_y, colors=color, **kwargs)
    if label is not None:
        if isinstance(label, (tuple, list)):
            for l, c in zip(label, contour_set.collections):
                c.set_label(l)
        else:
            contour_set.collections[0].set_label(label)
    return contour_set


def frame_jump():
    """Place the cursor on the midpoint of selected keyframes

    """
    pass


def finish_publishing():
    """
        Do anything necessary to finish writing the share to a remote
        server. I require that no further publishing needs to take place
        after this method has been called.
        """


@staticmethod
def _sign_of_tetrahedron_face(tetrahedron, face):
    """
        Recall the comments from _index_of_tetrahedron_face

        A regina triangle has two embeddings and thus yields
        two (tetrahedron, face) pairs representing a face class,
        albeit with different signs.
        We assume that the first embedding always represents the
        + face class and the second one - face class.

        In addl_code/ptolemy_equations.c, this was done in
        _fill_tet_face_to_index_data . There, the choice was made
        that the pair (tetrahedron, face) with the lower tetrahedron
        index (face index in case tie) represents + face class.
        """
    triangle = tetrahedron.getTriangle(face)
    embedding = triangle.getEmbedding(0)
    if tetrahedron == embedding.getTetrahedron() and embedding.getFace(
        ) == face:
        return +1
    else:
        return -1


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

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

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


def describe_trusted_advisor_check_refresh_statuses(checkIds=None):
    """
    Returns the refresh status of the Trusted Advisor checks that have the specified check IDs. Check IDs can be obtained by calling  DescribeTrustedAdvisorChecks .
    See also: AWS API Documentation

    :example: response = client.describe_trusted_advisor_check_refresh_statuses(
        checkIds=[
            'string',
        ]
    )

    :type checkIds: list
    :param checkIds: [REQUIRED]
            The IDs of the Trusted Advisor checks to get the status of. Note: Specifying the check ID of a check that is automatically refreshed causes an InvalidParameterValue error.
            (string) --

    :rtype: dict
    :return: {
        'statuses': [
            {
                'checkId': 'string',
                'status': 'string',
                'millisUntilNextRefreshable': 123
            },
        ]
    }

    """
    pass


@staticmethod
def construct_condition_name(flow_name, idx):
    """Create condition name for a dump.

        :param flow_name: flow name
        :type flow_name: str
        :param idx: index of condition within the flow
        :type idx: int
        :return: condition function representation
        """
    assert idx >= 0
    return '_condition_{}_{}_cond'.format(flow_name, idx)


def eq_6_1_characteristic_fire_diameter(Q_star: float, rho_0: float=1.204,
    c_p: float=1.005, T_0: float=293, g: float=9.807):
    """
    This function calculates the characteristic fire diameter as defined in Section 6.3.6 FDS user's manual.

    Quote from the document:

    <q>
    The quantity D∗ / δx can be thought of as the number of computational cells spanning the characteristic (not
    necessarily the physical) diameter of the fire. The more cells spanning the fire, the better the resolution of the
    calculation. It is better to assess the quality of the mesh in terms of this non-dimensional parameter, rather than
    an absolute mesh cell size. For example, a cell size of 10 cm may be “adequate,” in some sense, for evaluating the
    spread of smoke and heat through a building from a sizable fire, but may not be appropriate to study a very small,
    smoldering source [fn1].

    [fn1]   For the validation study sponsored by the U.S. Nuclear Regulatory Commission, the D∗ / δx values ranged
            from 4 to 16.
    </q>

    :param Q_star: total heat release rate of the fire.
    :param rho_0: ambient air density.
    :param c_p: ambient air heat capacity.
    :param T_0: ambient air temperature.
    :param g: gravity.
    :return D_star: characteristic fire size.
    """
    D_star = (Q_star / (rho_0 * c_p * T_0 * g ** 0.5)) ** (2 / 5)
    return D_star


@staticmethod
def conform_name(name):
    '\n        Checks to see whether a symbol name is valid by removing all whitespace from it\n        Removes spaces, \r, \n, \t\n        Throws exception if result is an empty string, otherwise it returns the string\n        '
    name = ''.join(name.split())
    if len(name) < 1:
        raise Exception('Invalid symbol name `' + name + '` ' +
            'Scriptax.SymbolScope@conform_name')
    else:
        return name


def bake_from_cache():
    """Bake from cache

    """
    pass


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


@classmethod
def valueToString(cls, value):
    """Returns a string representation of value."""
    if isinstance(value, (list, tuple)):
        return cls._listToString(value)
    else:
        return str(value)


def get_more_permissive_class(a, b):
    """Return the most permissive class of a, b."""
    a_cls = a.__class__
    b_cls = b.__class__
    return b_cls if issubclass(a_cls, b_cls) else a_cls


def to_list(value):
    """Converts anything to a list"""
    if not isinstance(value, list):
        return [value] if value is not None else []
    return value


def size_table_name(model_selector):
    """
    Returns canonical name of injected destination desired_size table

    Parameters
    ----------
    model_selector : str
        e.g. school or workplace

    Returns
    -------
    table_name : str
    """
    return '%s_destination_size' % model_selector


def writegive(giveup, g):
    """Write giveup data."""
    try:
        outfile = open(giveup, 'w')
    except Exception:
        print('Unable to write a file:', giveup)
        return
    for i in range(3):
        for j in g[i]:
            outfile.write(j.strip() + '\n')
    for i in g[3]:
        outfile.write('g ' + str(i[0]) + ' ' + i[1] + '\n')
    outfile.close
    return


@classmethod
def filters(cls, bins, norm, **kwargs):
    """
        Create a list with filters for the given bins.

        Parameters
        ----------
        bins : list or numpy array
            Center/crossover bins of the filters.
        norm : bool
            Normalize the area of the filter(s) to 1.
        kwargs : dict, optional
            Additional parameters passed to :func:`band_bins`
            (e.g. if the filters should overlap or not).

        Returns
        -------
        filters : list
            Filter(s) for the given bins.

        """
    filters = []
    for filter_args in cls.band_bins(bins, **kwargs):
        filters.append(cls(*filter_args, norm=norm))
    return filters


def _clean_response(response):
    """Allow for `ext` or `.ext` format.

    The user can, for example, use either `.csv` or `csv` in the response kwarg.

    """
    return response.lstrip('.')


def _decrypt(data):
    """Low level decrypt interface"""


def _is_sunder(name):
    """Returns True if a _sunder_ name, False otherwise."""
    return name[0] == name[-1] == '_' and name[1:2] != '_' and name[-2:-1
        ] != '_' and len(name) > 2


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

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

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


def number_to_string(n, alphabet):
    """
    Given an non-negative integer ``n``, convert it to a string composed of
    the given ``alphabet`` mapping, where the position of each element in
    ``alphabet`` is its radix value.

    Examples::

        >>> number_to_string(12345678, '01')
        '101111000110000101001110'

        >>> number_to_string(12345678, 'ab')
        'babbbbaaabbaaaababaabbba'

        >>> number_to_string(12345678, string.ascii_letters + string.digits)
        'ZXP0'

        >>> number_to_string(12345, ['zero ', 'one ', 'two ', 'three ', 'four ', 'five ', 'six ', 'seven ', 'eight ', 'nine '])
        'one two three four five '

    """
    result = ''
    base = len(alphabet)
    current = int(n)
    if current < 0:
        raise ValueError('invalid n (must be non-negative): %s', n)
    while current:
        result = alphabet[current % base] + result
        current = current // base
    return result


def make_plural(string):
    """
    Function to convert a string to its plural form.

    :param string: initial string
    :type string: str
    :return: plural string
    :rtype: str
    """
    if string[-3:] == 'sis':
        string = string[:-3] + 'ses'
    else:
        string += 's'
    return string


def parser(subparsers, func, name, help):
    """
    Return a new parser attached to a subparsers object.
    """
    parser = subparsers.add_parser(name=name, help=help)
    parser.set_defaults(func=func)
    return parser


def peak_horizontal_load(r_toty, rho_w, D, C_y, U, V) ->'F_y':
    """Peak horizontal load for on-bottom stability check.
    Reference:
    DNVGL-RP-F109 (2017-05)
        sec:3.6.4, eq:3.40, page:32
    """
    F_y = r_toty * 0.5 * rho_w * D * C_y * (U + V) ** 2
    return F_y


def finish(func, handler, args, kwargs):
    """
    Wrap the handler ``on_finish`` method to finish the Span for the
    given request, if available.
    """
    ret = func(*args, **kwargs)
    tracing = handler.settings.get('opentracing_tracing')
    if len(args) >= 1:
        chunk = args[0]
        biz_code = chunk.get('code') if isinstance(chunk, dict) else ''
    else:
        biz_code = ''
    tracing._finish_tracing(handler, biz_code=biz_code)
    return ret


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

        :param EnterpriseSettingsLockingDetails val:
        :rtype: EventDetails
        """
    return cls('enterprise_settings_locking_details', val)


def _default_bootstrap(n_samples, num_subsamples, prng):
    """Returns an array of integers (0, n_samples-1)^num_subsamples."""
    return prng.permutation(n_samples)[:num_subsamples]


def str_find_between_tags(string, start='', end='', case=True):
    """ Returns a substring between two string tags """
    if not case:
        string_orig = string
        string = string.lower()
        start = start.lower()
        end = end.lower()
    if start:
        s = string.find(start)
    else:
        s = 0
    if end:
        e = string.find(end, s + len(start))
    else:
        e = len(string)
    if s < 0 or e < 0:
        return ''
    if not case:
        return string_orig[s + len(start):e]
    return string[s + len(start):e]


def _invert_signs(signs):
    """ Shall we invert signs?
    Invert if first (most probable) term is negative.
    """
    return signs[0] < 0


def base_msg_type(type_):
    """
    Compute the base data type, e.g. for arrays, get the underlying array item type
    @param type_: ROS msg type (e.g. 'std_msgs/String')
    @type  type_: str
    @return: base type
    @rtype: str
    """
    if type_ is None:
        return None
    if '[' in type_:
        return type_[:type_.find('[')]
    return type_


def get_resource_url(resource, href, **kwargs):
    """Return the canonical URL for displaying the given resource.

        :param resource: a `Resource`
        :param href: an `Href` used for creating the URL

        Note that if there's no special rule associated to this realm for
        creating URLs (i.e. the standard convention of using realm/id applies),
        then it's OK to not define this method.
        """


def my_callback(file_path):
    """Callback for new file"""
    print('New File Created: {:s}'.format(file_path))


def delete_portfolio_share(AcceptLanguage=None, PortfolioId=None, AccountId
    =None):
    """
    Deletes the specified portfolio share.
    See also: AWS API Documentation

    :example: response = client.delete_portfolio_share(
        AcceptLanguage='string',
        PortfolioId='string',
        AccountId='string'
    )

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

    :type PortfolioId: string
    :param PortfolioId: [REQUIRED]
            The portfolio identifier.

    :type AccountId: string
    :param AccountId: [REQUIRED]
            The account ID associated with the share to delete.

    :rtype: dict
    :return: {}

    :returns:
    (dict) --

    """
    pass


def coll_iter(coll):
    """Iterate over items in RooAbsCollection."""
    it = coll.fwdIterator()
    obj = it.next()
    while obj:
        yield obj
        obj = it.next()


def validate_jtype(instruction) ->bool:
    """Validates J-Type instructions

    Parameters
    ----------
    instruction : J-Type

    Returns
    -------
    bool
        [Syntax correct or not]
    """
    address = instruction.address
    check = address is not None
    return check


def particle_system_remove():
    """Remove the selected particle system

    """
    pass


@staticmethod
def set_variable(variable, value):
    """Set the given variable's value from the database."""
    variable.set(value, from_db=True)


def setState(state):
    """ set the state of the queue, i.e. its contents """


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 to_01(samples):
    """Converts a tensor of spins from the :math:`\\sigma_i = -1, +1` convention
    to the :math:`\\sigma_i = 0, 1` convention.
    :param samples: A tensor of spins to convert.
                    Must be using the :math:`\\sigma_i = -1, +1` convention.
    :type samples: torch.Tensor
    """
    return samples.add(1.0).div(2.0)


def lambd_NH3_HCOO_CB89(T, P):
    """n-a: ammonia methanoate [CB89]."""
    lambd = 0.048
    valid = T == 298.15
    return lambd, valid


def gps_topic_pull():
    """
    This synchronously pulls a single message from a pubsub topic.

    TODO: finish this

    """


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

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

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


def resolve_name(name):
    """Resolve a name like ``module.object`` to an object and return it.

    Raise `ImportError` if the module or name is not found.
    """
    parts = name.split('.')
    cursor = len(parts) - 1
    module_name = parts[:cursor]
    attr_name = parts[-1]
    while cursor > 0:
        try:
            ret = __import__('.'.join(module_name), fromlist=[attr_name])
            break
        except ImportError:
            if cursor == 0:
                raise
            cursor -= 1
            module_name = parts[:cursor]
            attr_name = parts[cursor]
            ret = ''
    for part in parts[cursor:]:
        try:
            ret = getattr(ret, part)
        except AttributeError:
            raise ImportError(name)
    return ret


@classmethod
def make(cls, string):
    """
        A helper method to return itself and workaround the fact that
        the str object doesn't allow extra arguments passed in to the
        constructor
        """
    obj = cls(string)
    obj._set_attributes()
    return obj


def sound_exposure(pressure, fs, axis=-1):
    """
    Sound exposure :math:`E_{T}`.

    :param pressure: Instantaneous sound pressure :math:`p`.
    :param fs: Sample frequency :math:`f_s`.
    :param axis: Axis.

    .. math:: E_T = \\int_{t_1}^{t_2} p^2 (t) \\mathrm{d}t

    """
    return (pressure ** 2.0 / fs).sum(axis=axis)


def isImageType(t):
    """
    Checks if an object is an image object.

    .. warning::

       This function is for internal use only.

    :param t: object to check if it's an image
    :returns: True if the object is an image
    """
    return hasattr(t, 'im')


def is_command(text):
    """
    Checks if `text` is a command. Telegram chat commands start with the '/' character.
    :param text: Text to check.
    :return: True if `text` is a command, else False.
    """
    return text.startswith('/')


def box(text: str, lang: str='') ->str:
    """Get the given text in a code block.

    Parameters
    ----------
    text : str
        The text to be marked up.
    lang : `str`, optional
        The syntax highlighting language for the codeblock.

    Returns
    -------
    str
        The marked up text.

    """
    ret = '```{}\n{}\n```'.format(lang, text)
    return ret


def nside2npix(nside):
    """Give the number of pixels for the given nside.

    Parameters
    ----------
    nside : int
      healpix nside parameter

    Returns
    -------
    npix : int
      corresponding number of pixels

    Examples
    --------
    >>> import healpy as hp
    >>> import numpy as np
    >>> hp.nside2npix(8)
    768

    >>> np.all([hp.nside2npix(nside) == 12 * nside**2 for nside in [2**n for n in range(12)]])
    True

    >>> hp.nside2npix(7)
    588
    """
    return 12 * nside * nside


def _test():
    """Run ``doctest`` on this module."""
    import doctest
    doctest.testmod()


def snake2camel(s):
    """Convert snake_case to CamelCase"""
    return ''.join(s.title().split('_'))


@classmethod
def is_compatible(cls, d):
    """
        Checks the dictionary contains the correct header information for the data class.

        Returns True if the correct class, group, version and type attributes are defined,
        False is returned otherwise.

        :param d: Dictionary containing serialised class data.
        :returns: True if compatible, False otherwise.
        """
    try:
        data_class = d['_class']
        group = d['_group']
        version = d['_version']
    except KeyError:
        return False
    return (data_class == cls.CLASS and group == cls.GROUP and version ==
        cls.VERSION)


@classmethod
def from_tag(cls, tag, schemas, ext='.rnc'):
    """load a schema using an element's tag. schemas can be a string or a list of strings"""
    return cls(fn=cls.filename(tag, schemas, ext=ext))


def create_export_data(export_data, lines, maximum_string):
    """
    Write export data to file.

    export_data - Data to export.
    file_name - Name of the file to write to.

    Returns:
    In place modificaion of lines
    """
    for row in export_data:
        row_string = []
        for name in export_data.dtype.names:
            if name == 'mic_number':
                continue
            elif name == 'image':
                continue
            else:
                pass
            value = row[name]
            if isinstance(value, int):
                row_string.append('{0: 7d}'.format(value))
            elif isinstance(value, float):
                row_string.append('{0: 14f}'.format(value))
            else:
                length = maximum_string[name]
                row_string.append('{0:{1}s}'.format(value, length))
        lines.append('{0}\n'.format('\t'.join(row_string)))


def session_started(method):
    """Apply this decorator to a method of class :class:`.HermesSnipsComponent`
    to register it as a callback to be triggered when the dialogue manager
    queues starts a new session.
    """
    method.subscribe_method = 'subscribe_session_started'
    return method


@classmethod
def from_wfs_element(cls, feature, namespace):
    """Build an instance of this type from a WFS feature element.

        Parameters
        ----------
        feature : etree.Element
            XML element representing a single record of the WFS layer.
        namespace : str
            Namespace associated with this WFS featuretype.

        Raises
        ------
        NotImplementedError
            This is an abstract method that should be implemented in a
            subclass.

        """
    raise NotImplementedError('This should be implemented in a subclass.')


def clearKnownMenuNames():
    """keep a list of all known menus so a recursive configuration will be found"""
    global known_menu_names
    known_menu_names = []


def sort_1d(input):
    """Sort a 1D tensor (in ascending order) and also return the original index.

    Parameters
    ----------
    input : Tensor
        The tensor to be sorted.

    Returns
    -------
    Tensor
        Sorted tensor.
    Tensor
        Index tensor of the elements in the original input.
    """
    pass


def replace_seq(text, start, end, replacement=''):
    """Replace slice of string given coordinates and replacement character."""
    length = end - start
    return '{}{}{}'.format(text[:start], replacement * length, text[end:])


def get_v_structures(g):
    """
    Gets all the v-structures in g. For three nodes, a, b, c, where a is connected to b,
    b is connected c, and a and c are not connected, this configuration is called a v-structure.

    :param g: Undirected graph.
    :return: List of tuples representing v-structure.
    """
    v_structures = []
    nodes = list(g.nodes)
    for node in nodes:
        neighbors = list(g.adj[node])
        for ne1 in neighbors:
            for ne2 in neighbors:
                if ne1 < ne2 and ne1 not in g.adj[ne2] and ne2 not in g.adj[ne1
                    ]:
                    t = ne1, node, ne2
                    v_structures.append(t)
    return v_structures


def _str_trunc(x):
    """Helper function of :func:`recursive_diff`.

    Convert x to string. If it is longer than 80 characters, or spans
    multiple lines, truncate it
    """
    x = str(x)
    if len(x) <= 80 and '\n' not in x:
        return x
    return x.splitlines()[0][:76] + ' ...'


@classmethod
def is_valid(cls, channel):
    """Validates channel

        :param channel: channel to validate
        :type channel: int
        :return: True if channel is valid, False otherwise
        :rtype: boolean
        """
    return (channel >= cls.MIN_ANALOG_CHANNEL and channel <= cls.
        MAX_ANALOG_CHANNEL)


@classmethod
def get_matching_state_for_esi_state(cls, esi_state_name) ->int:
    """returns matching state for esi state name of Upwell structures"""
    return cls._STATES_ESI_MAP[esi_state_name
        ] if esi_state_name in cls._STATES_ESI_MAP else cls.STATE_UNKNOWN


def set_sticky_config(ts):
    """Assign permanently 'ts' as the one and only drift config. Useful for tests."""
    global _sticky_ts
    _sticky_ts = ts


def filter_query(filter_dict, required_keys):
    """Ensure that the dict has all of the information available. If not, return what does"""
    if not isinstance(filter_dict, dict):
        raise TypeError('dict_list is not a list. Please try again')
    if not isinstance(required_keys, list):
        raise TypeError('dict_list is not a list. Please try again')
    available = []
    for k, v in filter_dict.items():
        if k in required_keys:
            available.append(k)
    return available


def calc_cpi(base_cpi, mix, miss_rates, penalties):
    """
    Compute the CPI using the miss_rates and penalties.
    """
    penalty_per_memaccess = penalties[0]
    for mp, mr in zip(penalties[1:], miss_rates):
        penalty_per_memaccess += mp * mr
    return base_cpi + mix * penalty_per_memaccess


def _sort_list_float(elem):
    """Get the first element of the array as float. for sorting.

    Args:
        elem: The 2d list

    Returns:
        The a float value of the first list element.
    """
    return float(elem[0])


def forceWrite(this, key, val):
    """
        Always writes through to MBUS
        """
    this.log.debug('fored-write: ' + str(key) + ':' + str(val))
    assert key in this.names
    mem_addr = this.base_addr + this.offsets[key]
    this.mbus.write_mem(mem_addr, val, 32)


def _scale_size(size, scale):
    """Rescale a size by a ratio.

    Args:
        size (tuple): w, h.
        scale (float): Scaling factor.

    Returns:
        tuple[int]: scaled size.
    """
    w, h = size
    return int(w * float(scale) + 0.5), int(h * float(scale) + 0.5)


def extract_method(wrapped_method):
    """Gets original method if wrapped_method was decorated

    :rtype: any([types.FunctionType, types.MethodType])
    """
    return wrapped_method.orig_func if hasattr(wrapped_method, 'orig_func'
        ) else wrapped_method


def _remove_noon_off_on_italics(collection):
    """Removes pairs of off-on italics nodes, that don't surround any other
    node

    :type collection: list[_InstructionNode]
    :return: list[_InstructionNode]
    """
    new_collection = []
    to_commit = None
    for node in collection:
        if node.is_italics_node() and node.sets_italics_off():
            to_commit = node
            continue
        elif node.is_italics_node() and node.sets_italics_on():
            if to_commit:
                to_commit = None
                continue
        elif to_commit:
            new_collection.append(to_commit)
            to_commit = None
        new_collection.append(node)
    if to_commit:
        new_collection.append(to_commit)
    return new_collection


def getNodes(requestor, service, nodeIdentifier):
    """
        Get all nodes contained by this node.

        @param requestor: The entity the request originated from.
        @type requestor: L{JID<twisted.words.protocols.jabber.jid.JID>}
        @param service: The publish-subscribe service entity.
        @type service: L{JID<twisted.words.protocols.jabber.jid.JID>}
        @param nodeIdentifier: Identifier of the node to request the childs
            for.
        @type nodeIdentifier: C{unicode}
        @return: A deferred that fires with a list of child node identifiers.
        @rtype: L{Deferred<twisted.internet.defer.Deferred>}
        """


def disjoint_bounds(bounds1, bounds2):
    """Compare two bounds and determine if they are disjoint.

    Parameters
    ----------
    bounds1: 4-tuple
        rasterio bounds tuple (left, bottom, right, top)
    bounds2: 4-tuple
        rasterio bounds tuple

    Returns
    -------
    boolean
    ``True`` if bounds are disjoint,
    ``False`` if bounds overlap
    """
    bounds1_north_up = bounds1[3] > bounds1[1]
    bounds2_north_up = bounds2[3] > bounds2[1]
    if not bounds1_north_up and bounds2_north_up:
        raise ValueError('Bounds must both have the same orientation')
    if bounds1_north_up:
        return bounds1[0] > bounds2[2] or bounds2[0] > bounds1[2] or bounds1[1
            ] > bounds2[3] or bounds2[1] > bounds1[3]
    else:
        return bounds1[0] > bounds2[2] or bounds2[0] > bounds1[2] or bounds1[3
            ] > bounds2[1] or bounds2[3] > bounds1[1]


def dated(zelf, *args, **kwargs):
    """ retrieve the creation time of an ding. """
    val = ''
    if 'Date' in zelf:
        val = zelf.Date
    elif 'date' in zelf:
        val = zelf.date
    elif 'published' in zelf:
        val = zelf.published
    elif 'added' in zelf:
        val = zelf.added
    elif 'saved' in zelf:
        val = zelf.saved
    elif 'timed' in zelf:
        val = zelf.timed
    return val


def int_to_alpha(n, upper=True):
    """Generates alphanumeric labels of form A-Z, AA-ZZ etc."""
    casenum = 65 if upper else 97
    label = ''
    count = 0
    if n == 0:
        return str(chr(n + casenum))
    while n >= 0:
        mod, div = n % 26, n
        for _ in range(count):
            div //= 26
        div %= 26
        if count == 0:
            val = mod
        else:
            val = div
        label += str(chr(val + casenum))
        count += 1
        n -= 26 ** count
    return label[::-1]


@staticmethod
def payload_for_create(email, phone_number, ip, name, alias, entity_type,
    entity_scope, birth_day, birth_month, birth_year, address_street,
    address_city, address_subdivision, address_postal_code,
    address_country_code):
    """Build the API 'add documents' payload from property values."""
    payload = {'documents': [{'email': email, 'phone_number': phone_number,
        'ip': ip, 'name': name, 'alias': alias, 'entity_type': entity_type,
        'entity_scope': entity_scope, 'day': birth_day, 'month':
        birth_month, 'year': birth_year, 'address_street': address_street,
        'address_city': address_city, 'address_subdivision':
        address_subdivision, 'address_postal_code': address_postal_code,
        'address_country_code': address_country_code}]}
    return payload


def __is_floatable(num):
    """

    Check if 'num' can be converted to float. If yes, return :code:`True`, else
    return :code:`False`.

    """
    try:
        float(num)
        return True
    except ValueError:
        return False


def extract_container_id(line):
    """
        Extract container id from a Running in line

         ---> Running in 816abeca3961
    """
    parts = line.strip().split(' ')
    if len(parts) == 4:
        return parts[3]
    else:
        raise Exception('Unrecognized docker running in line: ' + line)


@staticmethod
def value_resolution(data):
    """Returns a tuple (width, height)"""
    width = data.get('width', None)
    height = data.get('height', None)
    if width == None and height == None:
        return None, (0, 0)
    try:
        return (width, height), (int(float(width)), int(float(height)))
    except (ValueError, TypeError):
        return (width, height), (0, 0)


def _render_file(env, path, dest_path, render_data):
    """jinja render file"""
    content = env.get_template(path.replace('\\', '/')).render(render_data)
    with open(dest_path, mode='w', encoding='utf-8') as f:
        f.write(content)


def search_dict_list(l, key, value):
    """ Search a list of dict
        * return dict with specific value & key """
    for i in l:
        if i.get(key) == value:
            return i


def getrepr(obj, *args) ->str:
    """generate generic reprs for objects."""
    classname = obj.__class__.__name__
    argstr = ', '.join(map(repr, args))
    return '{}({})'.format(classname, argstr)


def _handle_string(val):
    """
    Replaces Comments: and any newline found.

    Input is a cell of type 'string'.
    """
    return val.replace('Comments: ', '').replace('\r\n', ' ')


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 render_git_describe_long(pieces):
    """TAG-DISTANCE-gHEX[-dirty].

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

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


def 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 unzip(groups):
    """Simple wrapper around zip(*groups). Providing a name is a lot clearer
    than having the raw code around and someone wondering what it's doing.

    [(1,'a'), (2, 'b'), (3, 'c')] -> [(1,2,3), ('a', 'b', 'c')]
    """
    return zip(*groups)


def get_version() ->str:
    """Get the installed version of instawow."""
    try:
        from ._version import __version__
    except ImportError:
        return 'dev'
    else:
        return __version__


def get_model_name(model):
    """
    Get the name of a Django model

    >>> get_model_name(Country)
    country
    """
    return model._meta.model_name


@classmethod
def match_header(cls, header):
    """
        Matches any extension HDU that is not one of the standard extension HDU
        types.
        """
    card = header.cards[0]
    xtension = card.value
    if isinstance(xtension, str):
        xtension = xtension.rstrip()
    standard_xtensions = 'IMAGE', 'TABLE', 'BINTABLE', 'A3DTABLE'
    return card.keyword == 'XTENSION' and xtension not in standard_xtensions


def format_folia(lemma: str, pos_tag: str, word: str) ->str:
    """
    Lexical assignment of the lemma and postag.
    """
    return '[ @folia {0} {1} {2} ]'.format(lemma, pos_tag, word
        ) if word else ''


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


def formula_2017_01_01(foyer_fiscal, period, parameters):
    """
        Investissements dans les DOM-TOM dans le cadre d'une entreprise.
        """
    fhaa = foyer_fiscal('fhaa', period)
    fhab = foyer_fiscal('fhab', period)
    fhac = foyer_fiscal('fhac', period)
    fhae = foyer_fiscal('fhae', period)
    fhaf = foyer_fiscal('fhaf', period)
    fhag = foyer_fiscal('fhag', period)
    fhah = foyer_fiscal('fhah', period)
    fhaj = foyer_fiscal('fhaj', period)
    fhak = foyer_fiscal('fhak', period)
    fhal = foyer_fiscal('fhal', period)
    fham = foyer_fiscal('fhal', period)
    fhao = foyer_fiscal('fhao', period)
    fhap = foyer_fiscal('fhap', period)
    fhaq = foyer_fiscal('fhaq', period)
    fhar = foyer_fiscal('fhar', period)
    fhat = foyer_fiscal('fhat', period)
    fhau = foyer_fiscal('fhau', period)
    fhav = foyer_fiscal('fhav', period)
    fhaw = foyer_fiscal('fhaw', period)
    fhay = foyer_fiscal('fhay', period)
    fhba = foyer_fiscal('fhba', period)
    fhbb = foyer_fiscal('fhbb', period)
    fhbe = foyer_fiscal('fhbe', period)
    fhbg = foyer_fiscal('fhbg', period)
    fhbi = foyer_fiscal('fhbi', period)
    fhbj = foyer_fiscal('fhbj', period)
    fhbk = foyer_fiscal('fhbk', period)
    fhbm = foyer_fiscal('fhbm', period)
    fhbn = foyer_fiscal('fhbn', period)
    fhbo = foyer_fiscal('fhbo', period)
    fhbp = foyer_fiscal('fhbp', period)
    fhbr = foyer_fiscal('fhbr', period)
    fhbs = foyer_fiscal('fhbs', period)
    fhbt = foyer_fiscal('fhbt', period)
    fhbu = foyer_fiscal('fhbu', period)
    fhbw = foyer_fiscal('fhbw', period)
    fhbx = foyer_fiscal('fhbx', period)
    fhby = foyer_fiscal('fhby', period)
    fhbz = foyer_fiscal('fhbz', period)
    fhcb = foyer_fiscal('fhcb', period)
    fhcc = foyer_fiscal('fhcc', period)
    fhcd = foyer_fiscal('fhcd', period)
    fhce = foyer_fiscal('fhce', period)
    fhcg = foyer_fiscal('fhcg', period)
    fhci = foyer_fiscal('fhci', period)
    fhcj = foyer_fiscal('fhcj', period)
    fhck = foyer_fiscal('fhck', period)
    fhcm = foyer_fiscal('fhcm', period)
    fhcn = foyer_fiscal('fhcn', period)
    fhco = foyer_fiscal('fhco', period)
    fhcp = foyer_fiscal('fhcp', period)
    fhcr = foyer_fiscal('fhcr', period)
    fhcs = foyer_fiscal('fhcs', period)
    fhct = foyer_fiscal('fhct', period)
    fhcu = foyer_fiscal('fhcu', period)
    fhcw = foyer_fiscal('fhcw', period)
    fhdi = foyer_fiscal('fhdi', period)
    fhdj = foyer_fiscal('fhdj', period)
    fhdk = foyer_fiscal('fhdk', period)
    fhdl = foyer_fiscal('fhdl', period)
    fhdm = foyer_fiscal('fhdm', period)
    fhdn = foyer_fiscal('fhdn', period)
    fhdo = foyer_fiscal('fhdo', period)
    fhdp = foyer_fiscal('fhdp', period)
    fhdq = foyer_fiscal('fhdq', period)
    fhdr = foyer_fiscal('fhdr', period)
    fhds = foyer_fiscal('fhds', period)
    fhdt = foyer_fiscal('fhdt', period)
    fhdu = foyer_fiscal('fhdu', period)
    fhdv = foyer_fiscal('fhdv', period)
    fhdw = foyer_fiscal('fhdw', period)
    fhnu = foyer_fiscal('fhnu', period)
    fhnv = foyer_fiscal('fhnv', period)
    fhnw = foyer_fiscal('fhnw', period)
    fhny = foyer_fiscal('fhny', period)
    fhpm = foyer_fiscal('fhpm', period)
    fhpn = foyer_fiscal('fhpn', period)
    fhpo = foyer_fiscal('fhpo', period)
    fhpp = foyer_fiscal('fhpp', period)
    fhpr = foyer_fiscal('fhpr', period)
    fhps = foyer_fiscal('fhps', period)
    fhpt = foyer_fiscal('fhpt', period)
    fhpu = foyer_fiscal('fhpu', period)
    fhpw = foyer_fiscal('fhpw', period)
    fhpx = foyer_fiscal('fhpx', period)
    fhpy = foyer_fiscal('fhpy', period)
    fhrg = foyer_fiscal('fhrg', period)
    fhri = foyer_fiscal('fhri', period)
    fhrj = foyer_fiscal('fhrj', period)
    fhrk = foyer_fiscal('fhrk', period)
    fhrl = foyer_fiscal('fhrl', period)
    fhrm = foyer_fiscal('fhrm', period)
    fhro = foyer_fiscal('fhro', period)
    fhrp = foyer_fiscal('fhrp', period)
    fhrq = foyer_fiscal('fhrq', period)
    fhrr = foyer_fiscal('fhrr', period)
    fhrt = foyer_fiscal('fhrt', period)
    fhru = foyer_fiscal('fhru', period)
    fhrv = foyer_fiscal('fhrv', period)
    fhrw = foyer_fiscal('fhrw', period)
    fhry = foyer_fiscal('fhry', period)
    fhsa = foyer_fiscal('fhsa', period)
    fhsb = foyer_fiscal('fhsb', period)
    fhsc = foyer_fiscal('fhsc', period)
    fhse = foyer_fiscal('fhse', period)
    fhsf = foyer_fiscal('fhsf', period)
    fhsg = foyer_fiscal('fhsg', period)
    fhsh = foyer_fiscal('fhsh', period)
    fhsj = foyer_fiscal('fhsj', period)
    fhsk = foyer_fiscal('fhsk', period)
    fhsl = foyer_fiscal('fhsl', period)
    fhsm = foyer_fiscal('fhsm', period)
    fhso = foyer_fiscal('fhso', period)
    fhsp = foyer_fiscal('fhsp', period)
    fhsq = foyer_fiscal('fhsq', period)
    fhsr = foyer_fiscal('fhsr', period)
    fhst = foyer_fiscal('fhst', period)
    fhsu = foyer_fiscal('fhsu', period)
    fhsv = foyer_fiscal('fhsv', period)
    fhsw = foyer_fiscal('fhsw', period)
    fhsz = foyer_fiscal('fhsz', period)
    fhta = foyer_fiscal('fhta', period)
    fhtb = foyer_fiscal('fhtb', period)
    fhtd = foyer_fiscal('fhtd', period)
    report_reduction_2012 = (fhnu + fhnv + fhnw + fhny + fhpm + fhpn + fhpo +
        fhpp + fhpr + fhps + fhpt + fhpu + fhpw + fhpx + fhpy + fhrg + fhri +
        fhrj + fhrk + fhrl + fhrm + fhro + fhrp + fhrq + fhrr + fhrt + fhru +
        fhrv + fhrw + fhry)
    report_reduction_2013 = (fhsa + fhsb + fhsf + fhsg + fhsc + fhsh + fhse +
        fhsj + fhsk + fhsl + fhsp + fhsq + fhsm + fhsr + fhso + fhst + fhsu +
        fhsv + fhsw + fhsz + fhta + fhtb + fhtd)
    report_reduction_2014 = (fhaa + fhab + fhac + fhae + fhaf + fhag + fhah +
        fhaj + fhak + fhal + fham + fhao + fhap + fhaq + fhar + fhat + fhau +
        fhav + fhaw + fhay + fhba + fhbb + fhbe + fhbg)
    report_reduction_2015 = (fhbi + fhbj + fhbk + fhbm + fhbn + fhbo + fhbp +
        fhbr + fhbs + fhbt + fhbu + fhbw + fhbx + fhby + fhbz + fhcb + fhcc +
        fhcd + fhce + fhcg)
    report_reduction_2016 = (fhci + fhcj + fhck + fhcm + fhcn + fhco + fhcp +
        fhcr + fhcs + fhct + fhcu + fhcw)
    reduction_invest_2017 = (fhdi + fhdj + fhdk + fhdl + fhdm + fhdn + fhdo +
        fhdp + fhdq + fhdr + fhds + fhdt + fhdu + fhdv + fhdw)
    return (report_reduction_2012 + report_reduction_2013 +
        report_reduction_2014 + report_reduction_2015 +
        report_reduction_2016 + reduction_invest_2017)


def with_np_offset(operations):
    """Add the np_offset variable to the operations' directives."""
    offset = 0
    for operation in operations:
        operation.directives.setdefault('np_offset', offset)
        offset += operation.directives['np']
    return operations


def search_phrase(phrase):
    """Execute a search on a phrase given as a string.

        Return an IFBtree mapping docid to score.
        """


def _format_size(size):
    """
    Format size in bytes, kb, or mb
    """
    if size < 1000:
        return f'{size} bytes'
    if size >= 1000000:
        return f'{size / 1000000:.2f} MB'
    if size >= 1000:
        return f'{size / 1000:.2f} kB'


def properties(cls, *ps):
    """Change attrs in `cls` with names in `ps` to properties"""
    for p in ps:
        setattr(cls, p, property(getattr(cls, p)))


def markdown_comment(ext):
    """Markdown escape for given notebook extension"""
    return '' if ext in ['.Rmd', '.md'] else "#'" if ext == '.R' else '#'


@classmethod
def set(cls, zone_id, version_id):
    """Set active version of a zone."""
    return cls.call('domain.zone.version.set', zone_id, version_id)


def safe_eval(s):
    """
    Try to parse `s` as an integer; if successful, return its integer
    value.  Else try to parse it as a float, and return that value.
    Otherwise, return `s` converted to a string.

    Example::

      >>> safe_eval("42")
      42
      >>> safe_eval("42.0")
      42.0
      >>> safe_eval("forty-two")
      'forty-two'

    """
    try:
        return int(s)
    except ValueError:
        pass
    try:
        return float(s)
    except ValueError:
        pass
    return str(s)


def unique_name(key, name, name_dict, name_max=-1, clean_func=None, sep='.'):
    """
    Helper function for storing unique names which may have special characters
    stripped and restricted to a maximum length.

    :arg key: unique item this name belongs to, name_dict[key] will be reused
       when available.
       This can be the object, mesh, material, etc instance its self.
    :type key: any hashable object associated with the *name*.
    :arg name: The name used to create a unique value in *name_dict*.
    :type name: string
    :arg name_dict: This is used to cache namespace to ensure no collisions
       occur, this should be an empty dict initially and only modified by this
       function.
    :type name_dict: dict
    :arg clean_func: Function to call on *name* before creating a unique value.
    :type clean_func: function
    :arg sep: Separator to use when between the name and a number when a
       duplicate name is found.
    :type sep: string
    """
    name_new = name_dict.get(key)
    if name_new is None:
        count = 1
        name_dict_values = name_dict.values()
        name_new = name_new_orig = name if clean_func is None else clean_func(
            name)
        if name_max == -1:
            while name_new in name_dict_values:
                name_new = '%s%s%03d' % (name_new_orig, sep, count)
                count += 1
        else:
            name_new = name_new[:name_max]
            while name_new in name_dict_values:
                count_str = '%03d' % count
                name_new = '%.*s%s%s' % (name_max - (len(count_str) + 1),
                    name_new_orig, sep, count_str)
                count += 1
        name_dict[key] = name_new
    return name_new


def _check_lr_seg(tmpList):
    """
    Helper method to validate the LR Segment.

    :param tmpList: List of LRSegment

    :return: None. In case of error, assert will fail.

    """
    assert len(tmpList) > 0
    assert tmpList[0].hasPred is False
    for i in range(len(tmpList)):
        if i == 0:
            assert tmpList[i].hasPred is False
        else:
            assert tmpList[i].hasPred is True
        assert tmpList[i].encrypted == tmpList[0].encrypted
        assert tmpList[i].isEFLR == tmpList[0].isEFLR
        assert tmpList[i].hasTrailingLength == tmpList[0].hasTrailingLength


def prioritize_dicts(*dicts):
    """
    Creates a new dict, prioritizing a more previous dict's keys/values from a later dict's keys/values.
    All of the first dict's keys/values will be present in the return dict.
    The other dicts' keys/values will be present only if no previous dictionaries had the same key.

    :param dicts: any number of dictionaries to prioritize between.
    :type dicts: dicts

    :return: A final dict
    :rtype: dict
    """
    final_dict = {}
    for dct in dicts:
        for key, value in dct.items():
            if key not in final_dict:
                final_dict[key] = value
    return final_dict


@staticmethod
def getdistsquared(loc1, loc2):
    """returns squared distance between coords"""
    return sum((loc2 - loc1) ** 2)


def delete_policy(PolicyId=None):
    """
    Deletes the specified policy from your organization. Before you perform this operation, you must first detach the policy from all OUs, roots, and accounts.
    This operation can be called only from the organization's master account.
    See also: AWS API Documentation

    :example: response = client.delete_policy(
        PolicyId='string'
    )

    :type PolicyId: string
    :param PolicyId: [REQUIRED]
            The unique identifier (ID) of the policy that you want to delete. You can get the ID from the ListPolicies or ListPoliciesForTarget operations.
            The regex pattern for a policy ID string requires 'p-' followed by from 8 to 128 lower-case letters or digits.

    """
    pass


def index_to_coord(width, i):
    """Return the 2D position (x, y) which corresponds to 1D index.

    Examples:
      If we have a 2D grid like this:

      0 1 2
      3 4 5
      6 7 8

      We can assert that element 8 is of the coordinate (2, 2):
      >>> (2, 2) == index_to_coord(3, 8)
      True

    """
    if i == 0:
        return 0, 0
    else:
        return i % width, i // width


@classmethod
def from_index(cls, *args, **kwargs):
    """Create index from another index. """
    return cls(*args, **kwargs)


@classmethod
def merge(cls, spans):
    """Merges overlapping and touches spans in the given list of spans.

        Note that this modifies the original list.

        >>> spans = [Span(1,2), Span(3)]
        >>> Span.merge(spans)
        >>> spans
        [<1-3>]
        """
    i = 0
    while i < len(spans) - 1:
        here = spans[i]
        j = i + 1
        while j < len(spans):
            there = spans[j]
            if there.start > here.end + 1:
                break
            if here.touches(there) or here.overlaps(there):
                here = here.to(there)
                spans[i] = here
                del spans[j]
            else:
                j += 1
        i += 1
    return spans


def dump_response(r, line_break=b'\r\n', encoding='UTF-8'):
    """    Return a byte-string representation of the given response, as for a HTTP
    response.
    """
    output = []
    output.append(r.status.encode('ascii'))
    output.append(line_break)
    for k, v in sorted(r.headers):
        output.append(k.encode('ascii'))
        output.append(b': ')
        output.append(v.encode('ascii'))
        output.append(line_break)
    output.append(line_break)
    output.extend(r.content_iterator)
    s = b''.join(output)
    if encoding:
        return s.decode(encoding)
    return s


def derive_names(name):
    """Get name of network, firewall & boot instance from boot disk"""
    network = name + '-network'
    firewall = name + '-firewall-allow-all'
    boot = name
    return network, firewall, boot


def _get_point_on_line(x1, y1, x2, y2, n):
    """Returns the (x, y) tuple of the point that has progressed a proportion
    n along the line defined by the two x, y coordinates.
    """
    x = (x2 - x1) * n + x1
    y = (y2 - y1) * n + y1
    return x, y


def rfind(indexable, item):
    """
    Iterates through the collection in reverse order and returns the index of
    an item
    """
    length = len(indexable)
    for i in range(length - 1, -1, -1):
        if indexable[i] == item:
            return i
    return -1


def reverse_bintree(parents):
    """construct {parent:[children]} dict from {child:parent}

    keys are the nodes in the tree, and values are the lists of children
    of that node in the tree.

    reverse_tree[None] is the root node

    >>> tree = bintree(range(7))
    >>> reverse_bintree(tree)
    {None: 0, 0: [1, 4], 4: [5, 6], 1: [2, 3]}
    """
    children = {}
    for child, parent in parents.iteritems():
        if parent is None:
            children[None] = child
            continue
        elif parent not in children:
            children[parent] = []
        children[parent].append(child)
    return children


def CheckForMultilineCommentsAndStrings(filename, clean_lines, linenum, error):
    """Logs an error if we see /* ... */ or "..." that extend past one line.

  /* ... */ comments are legit inside macros, for one line.
  Otherwise, we prefer // comments, so it's ok to warn about the
  other.  Likewise, it's ok for strings to extend across multiple
  lines, as long as a line continuation character (backslash)
  terminates each line. Although not currently prohibited by the C++
  style guide, it's ugly and unnecessary. We don't do well with either
  in this lint program, so we warn about both.

  Args:
    filename: The name of the current file.
    clean_lines: A CleansedLines instance containing the file.
    linenum: The number of the line to check.
    error: The function to call with any errors found.
  """
    line = clean_lines.elided[linenum]
    line = line.replace('\\\\', '')
    if line.count('/*') > line.count('*/'):
        error(filename, linenum, 'readability/multiline_comment', 5,
            'Complex multi-line /*...*/-style comment found. Lint may give bogus warnings.  Consider replacing these with //-style comments, with #if 0...#endif, or with more clearly structured multi-line comments.'
            )
    if (line.count('"') - line.count('\\"')) % 2:
        error(filename, linenum, 'readability/multiline_string', 5,
            'Multi-line string ("...") found.  This lint script doesn\'t do well with such strings, and may give bogus warnings.  Use C++11 raw strings or concatenation instead.'
            )


def get_model(project_dir, train_seq, hparams, logger, args):
    """
    Initializes a tf.keras Model from mpunet.models as specified in
    hparams['build']. If args.continue_training, the best previous model stored
    in [project_dir]/models will be loaded.

    If hparams["build"]["biased_output_layer"] is True, sets the bias weights
    on the final conv. layer so that a zero-input gives an output of class
    probabilities equal to the class frequencies of the training set.

    Args:
        project_dir: A path to a mpunet project folder
        train_seq: A mpunet.sequences object for the training data
        hparams: A mpunet YAMLHParams object
        logger: A mpunet logging object
        args: argparse arguments

    Returns:
        model: The model to fit
        org_model: The original, non-GPU-distributed model
                   (Same as model if num_GPUs==1)
    """
    from mpunet.models import model_initializer
    hparams['build']['flatten_output'] = True
    model = model_initializer(hparams=hparams, continue_training=args.
        continue_training, project_dir=project_dir, logger=logger)
    if not args.continue_training and hparams['build'].get(
        'biased_output_layer'):
        from mpunet.utils.utils import set_bias_weights_on_all_outputs
        set_bias_weights_on_all_outputs(model, train_seq, hparams, logger)
    return model


def readB423Header(hdrStr: str):
    """Read B423 header for a single Lemi B423 file

    Parameters
    ----------
    hdrStr : str
        The headers as a string

    Returns
    -------
    dict
        A dictionary of header values
    """
    hdr = hdrStr.decode()
    hdr = hdr.split('\r\n')
    headers = dict()
    for idx, h in enumerate(hdr):
        hdr[idx] = h.replace('%', '')
        if '=' in h:
            sp = hdr[idx].split('=')
            key = sp[0].strip()
            value = float(sp[1].strip())
            headers[key] = value
        if 'Lat' in h or 'Lon' in h or 'Alt' in h:
            key = hdr[idx][0:3]
            value = hdr[idx][3:].strip()
            headers[key] = value
    return headers


def representAccents(text):
    """Exchange consonants such as k->g, p->b, t->d and s->z

    Note
    ----
    Not implemented

    """
    pass


def parse(name, content, releases, get_head_fn):
    """
    Parses the given content for a valid changelog
    :param name: str, package name
    :param content: str, content
    :param releases: list, releases
    :param get_head_fn: function
    :return: dict, changelog
    """
    changelog = {}
    releases = frozenset(releases)
    head = False
    for line in content.splitlines():
        new_head = get_head_fn(name=name, line=line, releases=releases)
        if new_head:
            head = new_head
            changelog[head] = ''
            continue
        if not head:
            continue
        line = line.replace('@', '')
        line = line.replace('#', '')
        changelog[head] += line + '\n'
    return changelog


@staticmethod
def _normalize_cmd(command):
    """Specific trailing newline for Mikrotik"""
    command = command.rstrip('\n')
    command += '\r'
    return command


def screen(image1, image2):
    """
    Superimposes two inverted images on top of each other. At least one of the
    images must have mode "1".

    .. code-block:: python

        out = MAX - ((MAX - image1) * (MAX - image2) / MAX)

    :rtype: :py:class:`~PIL.Image.Image`
    """
    image1.load()
    image2.load()
    return image1._new(image1.im.chop_screen(image2.im))


def euler_filter():
    """Fix large jumps and flips in the selected Euler Rotation F-Curves arising from rotation values being clipped when baking physics

    """
    pass


def urljoin(*args):
    """
    Joins given arguments into a url, removing duplicate slashes
    Thanks http://stackoverflow.com/a/11326230/1267398

    >>> urljoin('/lol', '///lol', '/lol//')
    '/lol/lol/lol'
    """
    value = '/'.join(map(lambda x: str(x).strip('/'), args))
    return '/{}'.format(value)


def open(*unused_args, **unused_kwargs):
    """Method os.open() is forbidden"""
    raise RuntimeError(
        'Usage of os.open() is forbidden. Use certbot.compat.filesystem.open() instead.'
        )


def GetWSAActionInput(operation):
    """Find wsa:Action attribute, and return value or the default."""
    attr = operation.input.action
    if attr is not None:
        return attr
    portType = operation.getPortType()
    targetNamespace = portType.getTargetNamespace()
    ptName = portType.name
    msgName = operation.input.name
    if not msgName:
        msgName = operation.name + 'Request'
    if targetNamespace.endswith('/'):
        return '%s%s/%s' % (targetNamespace, ptName, msgName)
    return '%s/%s/%s' % (targetNamespace, ptName, msgName)


@staticmethod
def dim_all_outputs(percent, ramp, is1805=False):
    """Generate a dim command for all output-ports.

        :param    int    percent:    Brightness in percent 0..100
        :param    int    ramp:       Ramp value
        :param    bool   is1805:     True if the target module's firmware is
                                     180501 or newer, otherwise False
        :return:    The PCK command (without address header) as text
        :rtype:    str
        """
    percent_round = round(percent * 2)
    if is1805:
        pck = 'OY{0:03d}{0:03d}{0:03d}{0:03d}{1:03d}'.format(percent_round,
            ramp)
    elif percent_round == 0:
        pck = 'AA{:03d}'.format(ramp)
    elif percent_round == 200:
        pck = 'AE{:03d}'.format(ramp)
    else:
        pck = 'AH{:03d}'.format(percent_round / 2)
    return pck


def merge(f):
    """Mark a file merged."""


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

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


def path_list_is_leaf(leaf, pathlist, **kwargs):
    """
        from xdict.utils import *
        path_list_is_leaf(['c'],['a','b','c'])
        path_list_is_leaf(['','c'],['a','b','c'])
        path_list_is_leaf([''],['a','b','c'])
        path_list_is_leaf(['c',''],['a','b','c',''])
        path_list_is_leaf([''],['a','b','c',''])
    """
    pks = pathlist
    if pks[-1] == leaf[0]:
        return 1
    else:
        return 0


def can_paginate(operation_name=None):
    """
    Check if an operation can be paginated.

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

    """
    pass


def select_solvent(topology, cutoff=0.6):
    """
    Compute solvent molecules with a maximum of `cutoff` distance away from an
    atom selection

    :param topology:        atom selection to compute solvent content of
    :type topology:         :interact:TopologyDataFrame
    :param cutoff:          cutoff distance in nm.
    :type cutoff:           :py:float

    :return:                new TopologyDataFrame with solvent selection
    :rtype:                 :interact:TopologyDataFrame
    """
    solvent = topology._parent[(topology._parent['resName'] == 'HOH') & (
        topology._parent['name'] == 'O')]
    sol_distances = topology.distances(target=solvent)
    contacts = sol_distances.loc[topology['serial'], solvent['serial']]
    contacts = contacts.unstack().reset_index()
    contacts.columns = ['target', 'source', 'distance']
    interface_solvents = contacts.loc[contacts['distance'] <= cutoff, 'target']
    interface_solvents = topology._parent[topology._parent['serial'].isin(
        set(interface_solvents))]
    return interface_solvents.extend()


def check_all_nan(df, cols=None):
    """
    Checker function to test whether all data within a column of a dataframe is :attr:`numpy:numpy.nan`

    :param df: dataframe whose data needs to be checked
    :type df: :class:`pandas:pandas.DataFrame`
    :param cols: columns to test
    :type cols: list of str
    :raises Exception: if all data within a column is :attr:`numpy:numpy.nan`
    """
    for col in (cols or df.columns):
        if df[col].isnull().all():
            raise Exception('All data for column "{}" is NaN!'.format(col))


def millis():
    """Return the millisecond since the epoch in GMT."""


@staticmethod
def __round_int(num: float) ->int:
    """Rounds numbers to nearest integer

        Keyword arguments:
            :param num: Number to be rounded

        :returns: Rounded integer
        """
    return int(num + 0.5)


@classmethod
def filter_active_routes(cls, route_list, date=None):
    """
        filter an input list of route (orm) objects via is_active
        :return new list of routes filtered by date
        """
    ret_val = []
    for r in route_list:
        if r and r.is_active(date):
            ret_val.append(r)
    return ret_val


def between(pairs):
    """Obtain nodes between pairs of nodes.

        ``pairs`` is an iterable of node pairs.

        Returns an iterable of iterables of nodes corresponding to each
        requested pair.
        """


@classmethod
def create(cls, model, **kwargs):
    """Create a inline for the given model

        Usage::

            ContentEditorInline.create(MyPlugin, form=MyPluginForm, ...)
        """
    kwargs['model'] = model
    return type(str('ContentEditorInline_%s_%s' % (model._meta.app_label,
        model._meta.model_name)), (cls,), kwargs)


def check(hub, rlist):
    """
    Check if any of the required list passes. If a single check passes then
    all is well, only return the errors is ALL FAIL
    """
    errors = []
    good = False
    for rdat in rlist:
        err = rdat.get('errors', [])
        if not err:
            good = True
        errors.extend(rdat.get('errors', []))
    if good:
        return []
    return errors


def hide_view_clear():
    """Reveal the layer by setting the hide flag

    """
    pass


def PyplotArtistBoxPlots():
    """
    =========================================
    Demo of artist customization in box plots
    =========================================

    This example demonstrates how to use the various kwargs
    to fully customize box plots. The first figure demonstrates
    how to remove and add individual components (note that the
    mean is the only value not shown by default). The second
    figure demonstrates how the styles of the artists can
    be customized. It also demonstrates how to set the limit
    of the whiskers to specific percentiles (lower right axes)

    A good general reference on boxplots and their history can be found
    here: http://vita.had.co.nz/papers/boxplots.pdf

    """
    import numpy as np
    import matplotlib.pyplot as plt
    np.random.seed(937)
    data = np.random.lognormal(size=(37, 4), mean=1.5, sigma=1.75)
    labels = list('ABCD')
    fs = 10
    fig, axes = plt.subplots(nrows=2, ncols=3, figsize=(6, 6), sharey=True)
    axes[0, 0].boxplot(data, labels=labels)
    axes[0, 0].set_title('Default', fontsize=fs)
    axes[0, 1].boxplot(data, labels=labels, showmeans=True)
    axes[0, 1].set_title('showmeans=True', fontsize=fs)
    axes[0, 2].boxplot(data, labels=labels, showmeans=True, meanline=True)
    axes[0, 2].set_title('showmeans=True,\nmeanline=True', fontsize=fs)
    axes[1, 0].boxplot(data, labels=labels, showbox=False, showcaps=False)
    tufte_title = 'Tufte Style \n(showbox=False,\nshowcaps=False)'
    axes[1, 0].set_title(tufte_title, fontsize=fs)
    axes[1, 1].boxplot(data, labels=labels, notch=True, bootstrap=10000)
    axes[1, 1].set_title('notch=True,\nbootstrap=10000', fontsize=fs)
    axes[1, 2].boxplot(data, labels=labels, showfliers=False)
    axes[1, 2].set_title('showfliers=False', fontsize=fs)
    for ax in axes.flatten():
        ax.set_yscale('log')
        ax.set_yticklabels([])
    fig.subplots_adjust(hspace=0.4)
    return fig


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

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


def wrap(i_min: int, i_max: int, i: int) ->int:
    """Wrap i between i_min and i_max."""
    assert isinstance(i_min, int)
    assert isinstance(i_max, int)
    assert isinstance(i, int)
    assert i_min <= i_max
    i_range = i_max + 1 - i_min
    return ((i - i_min) % i_range + i_range) % i_range + i_min


def deadband(val, dead=0.2, scale=1):
    """Return the deadband value for the controller Axis.

    Args:
        val (float): Raw controller value -1 to 1.
        dead (float)[0.2]: Deadband value
        scale (int) [1]: 100, 10, 1 indicates the range -100 to 100 ...
    """
    val = float(val)
    dead = abs(float(dead))
    if dead == scale:
        dead = scale * 0.99
    if val >= dead:
        val -= dead
    elif val <= -dead:
        val += dead
    else:
        val = 0
    val = val / (scale - dead) * scale
    return val


def table_to_root(table, filename, **kwargs):
    """Write a Table to a ROOT file
    """
    import root_numpy
    root_numpy.array2root(table.as_array(), filename, **kwargs)


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


def _validate_dependencies_met():
    """
    Verifies that PyOpenSSL's package-level dependencies have been met.
    Throws `ImportError` if they are not met.
    """
    from cryptography.x509.extensions import Extensions
    if getattr(Extensions, 'get_extension_for_class', None) is None:
        raise ImportError(
            "'cryptography' module missing required functionality.  Try upgrading to v1.3.4 or newer."
            )
    from OpenSSL.crypto import X509
    x509 = X509()
    if getattr(x509, '_x509', None) is None:
        raise ImportError(
            "'pyOpenSSL' module missing required functionality. Try upgrading to v0.14 or newer."
            )


@classmethod
def sort(cls):
    """
        Sort the items by their value.

        Used for example by :mod:`lino_xl.lib.orders` where we add a journal
        group to :class:`lino_xl.lib.ledger.JournalGroups` and want it to come
        before the other groups.

        """
    cls.choices.sort(key=lambda x: x[0].value)


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


def glGetShaderSource(shader: int, bufSize: int, length: int, source: 'Buffer'
    ):
    """Returns the source code string from a shader object

    :param shader: Specifies the shader object to be queried.
    :type shader: int
    :param bufSize: Specifies the size of the character buffer for storing the returned source code string.
    :type bufSize: int
    :param length: Returns the length of the string returned in source (excluding the null terminator).
    :type length: int
    :param source: Specifies an array of characters that is used to return the source code string.
    :type source: 'Buffer'
    """
    pass


def hex_to_signed(source):
    """Convert a string hex value to a signed hexidecimal value.
    This assumes that source is the proper length, and the sign bit
    is the first bit in the first byte of the correct length.
    hex_to_signed("F") should return -1.
    hex_to_signed("0F") should return 15.
    """
    if not isinstance(source, str):
        raise ValueError('string type required')
    sign_bit_mask = 1 << len(source) * 4 - 1
    other_bits_mask = sign_bit_mask - 1
    value = int(source, 16)
    return -(value & sign_bit_mask) | value & other_bits_mask


def up(cursor):
    """Replace current_modules with correct logic"""
    cursor.execute(
        """
DROP VIEW current_modules;
CREATE OR REPLACE VIEW current_modules AS
WITH latest_idents (module_ident) AS (
          SELECT module_ident FROM modules m2 join modulestates ms
                on m2.stateid = ms.stateid
                WHERE m2.major_version = (
                    SELECT max(major_version) FROM modules m3
                        WHERE m2.uuid = m3.uuid
                )
                AND
                (m2.minor_version IS NULL OR
                 m2.minor_version = (
                    SELECT max(minor_version) FROM modules m4
                        WHERE m2.uuid = m4.uuid AND
                        m2.major_version = m4.major_version
                    )
                )
                AND ms.statename = 'current'
        )
SELECT m.* FROM latest_idents li JOIN modules m
ON m.module_ident = li.module_ident;
"""
        )
    cursor.execute('UPDATE modules SET stateid = 1 WHERE stateid IS NULL')
    cursor.execute(
        """CREATE TABLE datamigrations.corrected_latest AS
            SELECT * FROM current_modules cm
                WHERE NOT EXISTS (
                    SELECT 1 FROM latest_modules lm
                        WHERE cm.module_ident = lm.module_ident)"""
        )
    cursor.execute(
        """CREATE TABLE datamigrations.wrong_latest AS
            SELECT * FROM latest_modules WHERE uuid IN
            (SELECT uuid FROM datamigrations.corrected_latest);
            DELETE FROM latest_modules WHERE uuid IN
            (SELECT uuid FROM datamigrations.corrected_latest);
            INSERT INTO latest_modules
                SELECT * from datamigrations.corrected_latest"""
        )


def is_year(my_potential_year):
    """
    A simple module to detect if a given string is a year. Notice than when using
    datetime module is not possible to make the difference and detect if 1894 is just
    a year compared to 1st Jan 1894 when using strptime
    """
    try:
        year = int(my_potential_year)
        if year > 2990:
            return False
        return True
    except ValueError:
        return False