def parse_darknet_ann_list_to_cls_box(annotations):
    """Parse darknet annotation format into two lists for class and bounding box.

    Input list of [[class, x, y, w, h], ...], return two list of [class ...] and [[x, y, w, h], ...].

    Parameters
    ------------
    annotations : list of list
        A list of class and bounding boxes of images e.g. [[class, x, y, w, h], ...]

    Returns
    -------
    list of int
        List of class labels.

    list of list of 4 numbers
        List of bounding box.

    """
    class_list = []
    bbox_list = []
    for ann in annotations:
        class_list.append(ann[0])
        bbox_list.append(ann[1:])
    return class_list, bbox_list


def references(record, oids=None):
    """Scan the given record for object ids

        A list of object ids is returned.  If a list is passed in,
        then it will be used and augmented. Otherwise, a new list will
        be created and returned.
        """


def cstrencode(pystr):
    """
    encode a string into bytes.  If already bytes, do nothing.
    """
    try:
        return pystr.encode('utf-8')
    except UnicodeDecodeError:
        return pystr.decode('utf-8').encode('utf-8')
    except AttributeError:
        return pystr


def betabin_expval(alpha, beta, n):
    """
    Expected value of beta-binomial distribution.
    """
    return n * alpha / (alpha + beta)


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

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


def cumulative_len(x):
    """
    for x, y in enumerate(len_y):
        plt.plot(x, y)
    """
    len_y = [0]
    for l in sorted(x)[::-1]:
        len_y.append(len_y[-1] + l)
    return len_y


def _get_ax_freq(ax):
    """
    Get the freq attribute of the ax object if set.
    Also checks shared axes (eg when using secondary yaxis, sharex=True
    or twinx)
    """
    ax_freq = getattr(ax, 'freq', None)
    if ax_freq is None:
        if hasattr(ax, 'left_ax'):
            ax_freq = getattr(ax.left_ax, 'freq', None)
        elif hasattr(ax, 'right_ax'):
            ax_freq = getattr(ax.right_ax, 'freq', None)
    if ax_freq is None:
        shared_axes = ax.get_shared_x_axes().get_siblings(ax)
        if len(shared_axes) > 1:
            for shared_ax in shared_axes:
                ax_freq = getattr(shared_ax, 'freq', None)
                if ax_freq is not None:
                    break
    return ax_freq


def false_if_all_empty_filter(*value):
    """
    Returns false if all provided values are empty.

    Args:
      value (list): a list of inputs
    Result:
      bool: true if at least one provided value is non-empty, false if all are empty, or the list is empty.
    """
    for v in value:
        if isinstance(v, bool) or v:
            return True
    return False


@staticmethod
def fg24(r, g, b):
    """Return 24-bit fg color ANSI escape sequence from an rgb value"""
    return '\x1b[38;2;{};{};{}m'.format(r, g, b)


def weight_hashtags(text, hashtags, ntimes):
    """gives ntimes weight to the hashtags identified in the given text"""
    weighted_hashtags = hashtags * (ntimes - 1)
    text = ' '.join(weighted_hashtags) + ' ' + text
    return text


@staticmethod
def _get_updated_on_mapping(updated_on):
    """
        Get the Jira value mapping for the modification date field.

        :param updated_on: Issue modification date
        :return: Jira value mapping for the modification date
        """
    return updated_on.isoformat()


def set_prefs(prefs):
    """This function is called before opening the project"""
    prefs['ignored_resources'] = ['*.pyc', '*~', '.ropeproject', '.hg',
        '.svn', '_svn', '.git', '.tox']
    prefs['save_objectdb'] = True
    prefs['compress_objectdb'] = False
    prefs['automatic_soa'] = True
    prefs['soa_followed_calls'] = 0
    prefs['perform_doa'] = True
    prefs['validate_objectdb'] = True
    prefs['max_history_items'] = 32
    prefs['save_history'] = True
    prefs['compress_history'] = False
    prefs['indent_size'] = 4
    prefs['extension_modules'] = []
    prefs['import_dynload_stdmods'] = True
    prefs['ignore_syntax_errors'] = False
    prefs['ignore_bad_imports'] = False
    prefs['prefer_module_from_imports'] = False
    prefs['split_imports'] = False
    prefs['pull_imports_to_top'] = True
    prefs['sort_imports_alphabetically'] = False
    prefs['type_hinting_factory'
        ] = 'rope.base.oi.type_hinting.factory.default_type_hinting_factory'


def bit_is_set(bitmask: int, bit: int) ->bool:
    """Return True if a specific bit is set in a bitmask.

    Uses the low bit is 1 and the high bit is 8.
    """
    return bool(bitmask & 1 << bit)


def dpad_topright_heading(controller):
    """
    Callback function that is triggered, when the direction top right was pressed

    :param controller:              the controller that triggered the action
    :type controller:               steuer.Controller
    """
    print('DIRECTION:' + str(controller.number) + ':' + controller.name +
        ':DPAD Top Right heading')


def google_fixed_width_font(style):
    """check if the css of the current element defines a fixed width font"""
    font_family = ''
    if 'font-family' in style:
        font_family = style['font-family']
    if 'Courier New' == font_family or 'Consolas' == font_family:
        return True
    return False


def _draw_line_extra_text(polyline, segment, pos0, pos1):
    """Shows the proportions of this line height compared to the previous segment."""
    prev_text = None
    for text in polyline.texts:
        if prev_text is not None and text.segment == segment:
            h0 = prev_text.segment.handles[0]['item']
            h1 = prev_text.segment.handles[1]['item']
            if polyline.vb.y_positive:
                prev_change = h1.pos().y() / h0.pos().y() - 1
                this_change = pos1.y() / pos0.y() - 1
            else:
                prev_change = h1.pos().y() - h0.pos().y()
                this_change = pos1.y() - pos0.y()
            if not abs(prev_change) > 1e-08:
                break
            change_part = abs(this_change / prev_change)
            return ' = 1:%.2f ' % change_part
        prev_text = text
    return ''


def vectors_difference(v1, v2, prefix=''):
    """ Given two mixed feature vectors, return another vector with the
	differences amongst them, taking the features of the first vector. For
	numerical features, absolute value difference is computed. For categorical
	features, Gower distance is used. """
    res = {}
    for feat in v1:
        if type(v1[feat]) == str:
            res[prefix + feat] = 0 if v1[feat] == v2[feat] else 1
        else:
            res[prefix + feat] = abs(v1[feat] - v2[feat])
    return res


def update_tags_for_set(client, obj, parsed_args):
    """Set the tags on an object.

    :param client: The service client to use setting the tags.
    :param obj: The object (Resource) to set the tags on.
    :param parsed_args: Parsed argument object returned by argparse parse_args.
    """
    if parsed_args.no_tag:
        tags = set()
    else:
        tags = set(obj.tags or [])
    if parsed_args.tags:
        tags |= set(parsed_args.tags)
    if set(obj.tags or []) != tags:
        client.set_tags(obj, sorted(list(tags)))


def minify_js(input_files, output_file):
    """
    Minifies the input javascript files to the output file.

    Output file may be same as input to minify in place.

    In debug mode this function just concatenates the files
    without minifying.
    """
    from .modules import minify, utils
    if not isinstance(input_files, (list, tuple)):
        raise RuntimeError('JS minifier takes a list of input files.')
    return {'dependencies_fn': utils.no_dependencies, 'compiler_fn': minify
        .minify_js, 'input': input_files, 'output': output_file, 'kwargs': {}}


def move(frames: int=0):
    """Move selected time marker(s)

    :param frames: Frames
    :type frames: int
    """
    pass


def set_log_level_from_verbose(console_handler, args, logger):
    """Set logging level handler for script"""
    if not args.verbose:
        console_handler.setLevel('INFO')
    elif args.verbose == 1:
        console_handler.setLevel('WARNING')
    elif args.verbose == 2:
        console_handler.setLevel('INFO')
    elif args.verbose >= 3:
        console_handler.setLevel('DEBUG')
    else:
        logger.critical("LOGGER level doesn't exist")


def _rename_magnetic_pars(pars):
    """
    Change from M0:par to par_M0, etc.
    """
    keys = list(pars.items())
    for k in keys:
        if k.startswith('M0:'):
            pars[k[3:] + '_M0'] = pars.pop(k)
        elif k.startswith('mtheta:'):
            pars[k[7:] + '_mtheta'] = pars.pop(k)
        elif k.startswith('mphi:'):
            pars[k[5:] + '_mphi'] = pars.pop(k)
        elif k.startswith('up:'):
            pars['up_' + k[3:]] = pars.pop(k)
    return pars


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 _make_todos(name, paths, mkdocs, git, github_username):
    """
    Make a formatted str of things to do from here. Mostly so the user can copy
    urls and so on (to quickly set up hooks, git remote)
    """
    todos = [f'Actually write some tests: {name}/tests.py']
    if '.coveragerc' in paths:
        todos.append('Set up codecov and a git hook for it.')
    if mkdocs:
        rtd = 'https://readthedocs.org/dashboard/import'
        todos.append(f'Set up a readthedocs and a git hook for it: {rtd}')
    if git:
        url = (
            f'git remote set-url origin https://github.com/{github_username}/{name}'
            )
        todos.append(f'Set git remote: (e.g.) {url}')
    return '\n* '.join(todos)


@classmethod
def _remove_xml_namespaces(cls, element):
    """Prunes namespaces from XML element

        :param element: element to be trimmed
        :returns: element with namespaces trimmed
        :rtype: :class:`xml.etree.ElementTree.Element`
        """
    for key, value in vars(cls._namespaces).items():
        if key.startswith('__'):
            continue
        element = cls._remove_xml_etree_namespace(element, value)
    return element


def _restore_original(word):
    """If the `word` is a Quoted string, restores it to original.
    """
    if getattr(word, 'is_single_quoted', False):
        return "'%s'" % word
    if getattr(word, 'is_double_quoted', False):
        return '"%s"' % word
    return word


def report_missing_files():
    """Report all missing external files

    """
    pass


def get_color_for_cfn_stack_event_type(event_status):
    """ Map CFN event status strings to red/green/blue colors (matching the CFN console) """
    if event_status in ['CREATE_IN_PROGRESS', 'DELETE_IN_PROGRESS',
        'UPDATE_IN_PROGRESS']:
        return 'blue'
    elif event_status in ['CREATE_COMPLETE', 'DELETE_COMPLETE',
        'UPDATE_COMPLETE']:
        return 'green'
    elif event_status in ['CREATE_FAILED', 'DELETE_FAILED', 'UPDATE_FAILED']:
        return 'red'
    else:
        return 'black'


def WriteControls(filename, data):
    """Write current values to a .imctrl (Image Controls) file"""
    File = open(filename, 'w')
    keys = ['type', 'color', 'wavelength', 'calibrant', 'distance',
        'center', 'Oblique', 'tilt', 'rotation', 'azmthOff',
        'fullIntegrate', 'LRazimuth', 'setdist', 'IOtth', 'outChannels',
        'outAzimuths', 'invert_x', 'invert_y', 'DetDepth', 'calibskip',
        'pixLimit', 'cutoff', 'calibdmin', 'Flat Bkg', 'varyList',
        'binType', 'SampleShape', 'PolaVal', 'SampleAbs', 'dark image',
        'background image', 'twoth']
    for key in keys:
        if key not in data:
            continue
        File.write(key + ':' + str(data[key]) + '\n')
    File.close()


def _do_not_track_lock_file(client):
    """Add lock file to .gitingore if not already exists."""
    lock_file = '.renku.lock'
    gitignore = client.path / '.gitignore'
    if lock_file not in gitignore.read_text():
        gitignore.open('a').write('\n{0}\n'.format(lock_file))


def check_no_slash(path):
    """ Make sure that a slash doesn't terminate the string """
    if path[-1] == '/':
        return path[:-1]
    else:
        return path


def isiterable(obj):
    """
    Return TRUE if object is iterable; else, FALSE.
    USAGE:
      boolean = isiterable( object )
    """
    try:
        _ = obj.__getitem__
        return True
    except:
        return False


@staticmethod
def positional_to_model(value):
    """Converts a positional argument to a model value"""
    return value


def split(x, sizes, axis=1):
    """
    Splits an array along a particular axis into multiple sub-arrays.

    Parameters:
    ----------
    x : Symbol or NDArray
        Input tensor.
    sizes : tuple/list of int
        Sizes of chunks.
    axis : int, default 1
        Axis along which to split.

    Returns
    -------
    Tuple of Symbol or NDArray
        Resulted tensor.
    """
    x_outs = []
    begin = 0
    for size in sizes:
        end = begin + size
        x_outs += [x.slice_axis(axis=axis, begin=begin, end=end)]
        begin = end
    return tuple(x_outs)


def rm_regions(a, b, a_start_ind, a_stop_ind):
    """Remove contiguous regions in `a` before region `b`

    Boolean arrays `a` and `b` should have alternating occuances of regions of
    `True` values. This routine removes additional contiguous regions in `a`
    that occur before a complimentary region in `b` has occured

    Args
    ----
    a: ndarray
        Boolean array with regions of contiguous `True` values
    b: ndarray
        Boolean array with regions of contiguous `True` values
    a_start_ind: ndarray
        indices of start of `a` regions
    a_stop_ind: ndarray
        indices of stop of `a` regions

    Returns
    -------
    a: ndarray
        Boolean array with regions for which began before a complimentary
        region in `b` have occured
    """
    import numpy
    for i in range(len(a_stop_ind)):
        next_a_start = numpy.argmax(a[a_stop_ind[i]:])
        next_b_start = numpy.argmax(b[a_stop_ind[i]:])
        if next_b_start > next_a_start:
            a[a_start_ind[i]:a_stop_ind[i]] = False
        return a


@classmethod
def signed_from_df(cls, df, sign_dict=None, flattening_method=None,
    weight_mapping=None):
    """Create a signed graph from a pandas DataFrame."""
    net = cls.from_df(df)
    return net.to_signed_graph(sign_dict=sign_dict, flattening_method=
        flattening_method, weight_mapping=weight_mapping)


def stringify(prettify=False):
    """Transformation to JSON string representation"""


def get_module_version(module_name):
    """Return the version of a module if installed, N/A otherwise"""
    try:
        from importlib import import_module
        module = import_module(module_name)
        if 'qtpy' in module_name:
            from qtpy import API_NAME, PYQT_VERSION
            qt_version = module.__version__
            return '{}, {} {}'.format(qt_version, API_NAME, PYQT_VERSION)
        elif '__version__' in dir(module):
            return module.__version__
        elif '__VERSION__' in dir(module):
            return module.__VERSION__
        else:
            return 'N/A'
    except ImportError:
        return 'N/A'


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


def correlate(class_, iterable):
    """Build a Counter from an iterable in one step.

        This is the same as adding each item individually.
        """
    counter = class_()
    for elm in iterable:
        counter(elm)
    return counter


def getArtFromTag(tag, type_=None):
    """Returns a list of eyed3.id3.frames.ImageFrame objects matching ``type_``,
    all if ``type_`` is None, or empty if tag does not contain art."""
    art = []
    for img in tag.images:
        if not type_ or type_ == img.picture_type:
            art.append(img)
    return art


def p_main_notext(t):
    """main : main COMMENT
            | main RAW
            | main HEADING
            | main SLIDE
            | main SCISSOR
            | main MACRO
            | main YAML
            | nil"""
    if len(t) > 2:
        t[0] = t[1]
        t[0].append(t[2])
    else:
        t[0] = []


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 _ensure_has_len(seq):
    """
    If seq is an iterator, put its values into a list.
    """
    try:
        len(seq)
    except TypeError:
        return list(seq)
    else:
        return seq


def extract_sub_dict(dict, path):
    """Get values from a given path of keys"""
    for item in path:
        dict = dict[item]
    return dict


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

        :param DeviceLinkFailType val:
        :rtype: EventType
        """
    return cls('device_link_fail', val)


def slurp(fname: str) ->str:
    """
    Reads a file and all its contents, returns a single string
    """
    with open(fname, 'r') as f:
        data = f.read()
    return data


def _get_distribution(filepath):
    """Return Linux distribution from the first run of a config.yml file."""
    import yaml
    with open(filepath, 'r') as fp:
        config = yaml.load(fp)
    return config['runs'][0]['distribution']


def warn_if_redirected(req, ui):
    """
    test whether a request was redirect.
    Log a warning to the user if it was redirected
    """
    if req is None:
        return
    history = req.history
    if history:
        first = history[0]
        if first.is_redirect:
            starting_endpoint = first.url
            redirect_endpoint = first.headers.get('Location')
            if str(starting_endpoint) != str(redirect_endpoint):
                ui.warning(
                    'The requested URL:\n\t{}\n\twas redirected by the webserver to:\n\t{}'
                    .format(starting_endpoint, redirect_endpoint))


def delete(property):
    """
        Удалить свойство из домена.

        При следующем обращении к свойству оно будет получено через предка домена,
        т.е. это эквивалентно сбросу на "значение по умолчанию".

        @param property: имя свойства
        @type property: C{str}
        @return: Deferred о результате операции
        @rtype: C{twisted.internet.defer.Deferred}
        """


def _filter_split(values, filter_list):
    """Filter space separated list and return iterable."""
    value_set = set(values.split())
    if filter_list:
        value_set &= set(filter_list)
    return sorted(value_set)


@classmethod
def create_from_collected_values(cls, contextual_vals, option_vals):
    """
        When the menu class in not model-based, this method is called by
        ``render_from_tag()`` to 'create' a menu object appropriate
        for the provided contextual and option values.
        """
    raise NotImplementedError(
        "Subclasses of 'Menu' must define their own 'create_from_collected_values' method."
        )


def create_category_index(categories):
    """Creates dictionary of COCO compatible categories keyed by category id.

    Args:
      categories: a list of dicts, each of which has the following keys:
        'id': (required) an integer id uniquely identifying this category.
        'name': (required) string representing category name
          e.g., 'cat', 'dog', 'pizza'.

    Returns:
      category_index: a dict containing the same entries as categories, but keyed
        by the 'id' field of each category.
    """
    category_index = {}
    for cat in categories:
        category_index[cat['id']] = cat
    return category_index


@classmethod
def mutate_event(cls, root, info, **kwargs):
    """
        Override this method. Return an event object, probably an instance of the class you defined.

        This is where you want to do authorization and validation of the input. If it all validates okay, then
        return an event object (Either the class you define this method or another event of (ObjectType, BaseEventMixin)

        Args:
            root: Passed from graphene
            info: Passed from graphene, the current context.
            **kwargs: This will be the args from the Arguments class you define as part of the mutation.

        Returns:
            A populated (ObjectType, BaseEventMixin) object.
        """
    raise NotImplementedError('Must implement this method instead of `mutate`')


def index_documents(DomainName=None):
    """
    Tells the search domain to start indexing its documents using the latest indexing options. This operation must be invoked to activate options whose  OptionStatus is RequiresIndexDocuments .
    See also: AWS API Documentation

    :example: response = client.index_documents(
        DomainName='string'
    )

    :type DomainName: string
    :param DomainName: [REQUIRED]
            A string that represents the name of a domain. Domain names are unique across the domains owned by an account within an AWS region. Domain names start with a letter or number and can contain the following characters: a-z (lowercase), 0-9, and - (hyphen).

    :rtype: dict
    :return: {
        'FieldNames': [
            'string',
        ]
    }

    """
    pass


def _linear(b, c):
    """Simple linear root solution"""
    return -c / b


def dasherize(word):
    """Replace underscores with dashes in the string.

    Example::

        >>> dasherize("foo_bar")
        "foo-bar"

    Args:
        word (str): input word

    Returns:
        input word with underscores replaced by dashes
    """
    return word.replace('_', '-')


def _update_case_key(key, elemental_quantities, seti2, eid_map, nid_map):
    """Updates a Case Control SET card.  A set may have an elemental result
    or a nodal result."""
    values2 = []
    eids_missing = []
    nids_missing = []
    if key in elemental_quantities:
        for eid in seti2:
            if eid not in eid_map:
                eids_missing.append(eid)
                continue
            eid_new = eid_map[eid]
            values2.append(eid_new)
    else:
        for nid in seti2:
            if nid not in nid_map:
                nids_missing.append(nid)
                continue
            nid_new = nid_map[nid]
            values2.append(nid_new)
    return eids_missing, nids_missing, values2


@classmethod
def _convert_nexthops(cls, nexthops):
    """ Convert list of nexthop objects into command list. """
    nextargs = []
    for nexthop in nexthops:
        nextargs.append('nexthop')
        for key in ('via', 'dev', 'weight'):
            nextargs.append(key)
            nextargs.append(str(getattr(nexthop, key)))
    return nextargs


def get_atomtrailer_list(r):
    """Capture only the leading dotted name list.

    A full sequence typically includes function calls and parameters.
    pkg_a.pkg_b.pkg_c.one_call(arg1, arg2, arg3=4)

    """
    dot_set = set()
    for n in r.find_all(('atomtrailers',)):
        name_list = []
        for x in n.value:
            if x.type != 'name':
                break
            name_list.append(x.value)
        if name_list:
            dot_set.add(tuple(name_list))
    return sorted(dot_set)


@staticmethod
def remove(layer, select):
    """Delete selection (list of ids) of units from parameter arrays. """
    layer['bias'] = layer['bias'][0, [select]]
    return True


def is_hot(G):
    """
    A Game is hot if it is not numberish; that is, it's left and right stops do not coincide.

    Parameters
    ----------
    G : Game
        The Game of interest.

    Returns
    -------
    hot : bool
        Whether the Game is hot or not.
    """
    return not G.is_numberish


def write_record_pair(read1, read2, fileobj):
    """Write a pair of sequence records to 'fileobj' in FASTA/FASTQ format."""
    _rec_pair = '@%s\n%s\n+\n%s\n' * 2
    _rec_pair_no_qual = '>%s\n%s\n' * 2
    if hasattr(read1, 'quality'):
        assert hasattr(read2, 'quality')
        recstr = _rec_pair % (read1.name, read1.sequence, read1.quality,
            read2.name, read2.sequence, read2.quality)
    else:
        recstr = _rec_pair_no_qual % (read1.name, read1.sequence, read2.
            name, read2.sequence)
    try:
        fileobj.write(bytes(recstr, 'ascii'))
    except TypeError:
        fileobj.write(recstr)


@staticmethod
def modify_snapshot_prefix(snapshot_name, manage=False, unmanage=False):
    """Modify a Snapshot prefix on PowerMax/VMAX backend.

        Prepare a snapshot name for manage/unmanage snapshot process either
        by adding or removing 'OS-' prefix.

        :param snapshot_name: the old snapshot backend display name
        :param manage: (bool) if the operation is managing a snapshot
        :param unmanage: (bool) if the operation is unmanaging a snapshot
        :return: snapshot name ready for backend PowerMax/VMAX assignment
        """
    new_snap_name = None
    if manage:
        new_snap_name = '%(prefix)s%(snapshot_name)s' % {'prefix': 'OS-',
            'snapshot_name': snapshot_name}
    if unmanage:
        snap_split = snapshot_name.split('-', 1)
        if snap_split[0] == 'OS':
            new_snap_name = snap_split[1]
    return new_snap_name


def diagonal_matrix_tiling(start, stop, bandwidth, edge=0, verbose=False):
    """
    Generate a stream of tiling coordinates that guarantee to cover a diagonal
    area of the matrix of size 'bandwidth'. cis-signal only!

    Parameters
    ----------
    start : int
        Starting position of the matrix slice to be tiled (inclusive, bins,
        0-based).
    stop : int
        End position of the matrix slice to be tiled (exclusive, bins, 0-based).
    edge : int
        Small edge around each tile to be included in the yielded coordinates.
    bandwidth : int
        Diagonal tiling is guaranteed to cover a diagonal are of width
        'bandwidth'.

    Yields
    ------
    Pairs of indices for every chunk use those indices [cstart:cstop) to fetch
    chunks from the cooler-object:
    >>> clr.matrix()[cstart:cstop, cstart:cstop]

    Notes
    -----
    Specify a [start,stop) region of a matrix you want to tile diagonally.
    Each slice is characterized by the coordinate of the top-left corner and
    size.

    * * * * * * * * * * *  0-th slice
    *       *           *
    *       *           *
    *   * * * * *       *  i-th slice
    *   *   *   *       *
    * * * * *   *       *
    *   *       *       *
    *   * * * * *       *
    *                   *
    *              ...  *  ...
    *                   *
    *                   *
    * * * * * * * * * * *

    These slices are supposed to cover up a diagonal band of size 'bandwidth'.

    """
    size = stop - start
    tiles = size // bandwidth + bool(size % bandwidth)
    if verbose:
        print('matrix of size {}X{} to be split so that\n'.format(size,
            size) + """  diagonal region of size {} would be completely
"""
            .format(bandwidth) +
            '  covered by the tiling, additionally keeping\n' +
            """  a small 'edge' of size w={}, to allow for
""".format(edge) +
            '  meaningfull convolution around boundaries.\n' +
            '  Resulting number of tiles is {}'.format(tiles - 1) +
            '  Non-edge case size of each tile is {}X{}'.format(2 * (
            bandwidth + edge), 2 * (bandwidth + edge)))
    for t in range(1, tiles):
        lw = max(0, bandwidth * (t - 1) - edge)
        rw = min(size, bandwidth * (t + 1) + edge)
        yield lw + start, rw + start


@staticmethod
def get_intent_name(payload):
    """ Return the simple intent name. An intent has the form:

           {
               "input": "turn the lights green",
               "intent": {
                   "intentName": "user_BJW0GIoCx__Lights",
                   ...
               },
               "slots": [...]
           }

           and this function extracts the last part of the intent
           name ("Lights"), i.e. removing the user id.

        :param payload: the intent, in JSON format.
        :return: the simpe intent name.
        """
    if 'intent' in payload and 'intentName' in payload['intent']:
        return payload['intent']['intentName'].split('__')[-1]
    return None


def _bold(text: str) ->str:
    """
    Returns bold formatted text.

    >>> _bold('Hello!')
    '\\x1b[1mHello!\\x1b[0m'

    """
    return '\x1b[1m{0}\x1b[0m'.format(text)


def iter_first(sequence):
    """Get the first element from an iterable or raise a ValueError if
    the iterator generates no values.
    """
    it = iter(sequence)
    try:
        return next(it)
    except StopIteration:
        raise ValueError()


@staticmethod
def _get_parent_class():
    """
        Gets the class of the parent object

        :returns: class of parent object
        """
    return None


def operator_preset_add(name: str='', remove_name: bool=False,
    remove_active: bool=False, operator: str=''):
    """Add or remove an Operator Preset

    :param name: Name, Name of the preset, used to make the path name
    :type name: str
    :param remove_name: remove_name
    :type remove_name: bool
    :param remove_active: remove_active
    :type remove_active: bool
    :param operator: Operator
    :type operator: str
    """
    pass


def before_flush(f):
    """
        Use to decorate an instance method so that it is called before flush.
        This method will only be called on an instance if it is new or dirty.
        (i.e. it is in session.new or session.dirty).

        This decorated methods will be called before validation takes place.
    """
    f._sav_before_flush = 'yes'
    return f


@classmethod
def valid(cls, data, context=None):
    """Shortcut to create a VALID Token."""
    return cls(cls.TagType.VALID, data, context)


def tagslist():
    """Return a list of tags ordered by revision."""


@classmethod
def read_null_terminated(cls, fobj):
    """Read a null-terminated string."""
    result = ''
    while True:
        char = fobj.read(1)
        if not char or char == '\x00':
            break
        result += char
    return result


def video_build_url(video_id):
    """Build video url."""
    return 'https://cds.cern.ch/api/deposits/video/{0}'.format(str(video_id))


def jd_to_mjd(jd):
    """
    Converts Julian Date to Modified Julian Date.

    Parameters
    ----------

    jd : float
        The Julian date measured at UTC.

    Returns
    -------

    mjd : float
        `mjd = jd - 2400000.5`

    """
    return jd - 2400000.5


def serialize_resource(resource, ctx):
    """
    Serialize resource by schema.

    :param resource: Resource instance
    :param ctx: Request context
    :return: Serialized resource
    """
    schema_cls, _ = ctx.registry[resource]
    return schema_cls(ctx).serialize_resource(resource)


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 clean_whitespace(string, compact=False):
    """Return string with compressed whitespace."""
    for a, b in (('\r\n', '\n'), ('\r', '\n'), ('\n\n', '\n'), ('\t', ' '),
        ('  ', ' ')):
        string = string.replace(a, b)
    if compact:
        for a, b in (('\n', ' '), ('[ ', '['), ('  ', ' '), ('  ', ' '), (
            '  ', ' ')):
            string = string.replace(a, b)
    return string.strip()


def div_list_count(original_list, count):
    """
    Yield successive count chunks from original_list
    original_list ==> count of div_list
    :param original_list:
    :param count:
    :return:
    """
    original_list_len = len(original_list)
    if original_list_len < count:
        yield original_list
    else:
        div_len = original_list_len // count
        for i in range(0, original_list_len, div_len):
            yield original_list[i:i + div_len]


def build_dependencies(intertable_dependencies):
    """Figure out which tables depend on which other ones (through foreign keys)

    intertable_dependencies is a dict with values of Dependency objects.

    Returns two things:
        1. a dictionary allowing easy lookup of dependencies by parent table
        2. a dictionary allowing lookups by (tablename, fieldname) pairs
    """
    dependencies = {}
    reference_fields = {}
    for dep in intertable_dependencies:
        table_deps = dependencies.setdefault(dep.table_name_from, set())
        table_deps.add(dep)
        reference_fields[dep.table_name_from, dep.field_name
            ] = dep.table_name_to
    return dependencies, reference_fields


def cut_prefix(s, prefix):
    """Cuts prefix from given string if it's present."""
    return s[len(prefix):] if s.startswith(prefix) else s


@staticmethod
def in_bbox(point, a, b):
    """Return True if `point` is in the bounding box defined by `a`
        and `b`.

        >>> bmin = (0, 0)
        >>> bmax = (100, 100)
        >>> Vector.in_bbox((50, 50), bmin, bmax)
        True
        >>> Vector.in_bbox((647, -10), bmin, bmax)
        False

        """
    return (point[0] <= a[0] and point[0] >= b[0] or point[0] <= b[0] and
        point[0] >= a[0]) and (point[1] <= a[1] and point[1] >= b[1] or
        point[1] <= b[1] and point[1] >= a[1])


@staticmethod
def service_name() ->str:
    """
        Returns a service name that this custom resource manages.

        :return: Service name.
        """
    return 'CodeCommit'


@classmethod
def save(cls, corpus, file_path, **kwargs):
    """Save a *corpus* in Parsed CONLL-U format to CONLL-U file"""
    with open(file_path, mode='wt', encoding='utf-8') as f:
        for line in cls.get_as_text(corpus, **kwargs):
            print(line, end='', file=f)


def s3_url(bucket: str, key: str) ->str:
    """ Turn a bucket + key into a S3 url """
    return '/'.join(['s3:/', bucket, key])


def set_x_axis_parameters(list_of_dicts):
    """ Load the x_parameters list related to a plot by using the ontology annotation part dedicated to this task
    We never need to query the database to get the x_parameters

    Args:
        list_of_dicts:

    Returns:

    """
    x_parameters = []
    for x_dict in list_of_dicts:
        x_parameters.append(x_dict['name'])
    return x_parameters


@staticmethod
def on_disconnect_finished(client, result):
    """called when the xively service responds to our disconnection request

        result -- the Xively Error Code, possible values are :

            xec.XI_STATE_OK : Connection successful"""
    pass


def _ex_type_str(exobj):
    """ Returns a string corresponding to the exception type """
    return str(exobj).split('.')[-1][:-2]


def __rshift_rows(ciphertext):
    """
        Input: ciphertext - List of lists (4x4 Matrix)

        Output: ciphertext - List of lists (4x4 Matrix)

        Reversed ShiftRows step of the algorithm. This step rotates elements in rows each by different
        amount depending on the row. First row stays the same, second is rotated to the right
        by one, third is rotated to the right by two, and fourth is rotated to the right by three.
    """
    for i in range(4):
        ciphertext[i] = ciphertext[i][-i:] + ciphertext[i][:-i]
    return ciphertext


def _create_rest_url(host, version, sid, category, resource, subcategory=
    None, query_id=None, second_query_id=None, **options):
    """Creates the URL for querying the REST service"""
    url = '/'.join([host, 'webservices/rest', version, category])
    if query_id is not None:
        url += '/' + query_id
    url += '/' + resource
    if second_query_id is not None:
        url += '/' + second_query_id
    if subcategory is not None:
        url += '/' + subcategory
    header = {'Accept-Encoding': 'gzip'}
    if sid is not None:
        header['Authorization'] = 'Bearer {}'.format(sid)
    if options is not None:
        opts = []
        for k, v in options.items():
            opts.append(k + '=' + str(v))
        if opts:
            url += '?' + '&'.join(opts)
    return url, header


def _float_to_bits(value, lower=-90.0, middle=0.0, upper=90.0, length=15):
    """Convert a float to a list of GeoHash bits."""
    ret = []
    for _ in range(length):
        if value >= middle:
            lower = middle
            ret.append(1)
        else:
            upper = middle
            ret.append(0)
        middle = (upper + lower) / 2
    return ret


@staticmethod
def opposite(direction: int) ->int:
    """
        Returns the opposite direction
        :param direction: the specified direction
        :return: the opposite direction
        """
    return (direction + 2) % 4


def mask_headers(headers, masks):
    """
    filters any headers (a dictionary) with key that matches those in the
    masks (a list)
    This have a sideeffect, so please make a deepcopy before using.
    """
    if headers is None:
        return headers
    if masks is None:
        return headers
    for member in masks:
        headers.pop(member, None)
    return headers


def transform_aabb(transform, aabb):
    """ Apply a transformation to an axis aligned bounding box.

    The result is a new AABB in the same coordinate system as the original AABB.
    The new AABB contains all corner points of the original AABB after applying the given transformation.

    Args
        transform: The transformation to apply.
        x1:        The minimum x value of the AABB.
        y1:        The minimum y value of the AABB.
        x2:        The maximum x value of the AABB.
        y2:        The maximum y value of the AABB.
    Returns
        The new AABB as tuple (x1, y1, x2, y2)
    """
    x1, y1, x2, y2 = aabb
    points = transform.dot([[x1, x2, x1, x2], [y1, y2, y2, y1], [1, 1, 1, 1]])
    min_corner = points.min(axis=1)
    max_corner = points.max(axis=1)
    return [min_corner[0], min_corner[1], max_corner[0], max_corner[1]]


def get_text(xs, read):
    """
    Read a Numerical value from the Leaf of a tree
    """
    if isinstance(xs, list):
        rs = list(map(lambda x: read(getattr(x, 'text')), xs))
    else:
        rs = read(xs.text)
    return rs


def is_port_mode(sWord):
    """
    Returns True if given word is a valid port mode.

    Returns False if given word is not a valid port mode.

    Parameters:

      sWord: (string)

    Returns: (boolean)
    """
    lKeywords = []
    lKeywords.append('in')
    lKeywords.append('out')
    lKeywords.append('inout')
    lKeywords.append('buffer')
    lKeywords.append('linkage')
    if sWord.lower() in lKeywords:
        return True
    else:
        return False


def search_sub_exp(ope, op1, op2, com, sub_dict):
    """
    search if an expression a op b was already translated to clause constraints
    @param ope: operator (string)
    @param op1: left operand (literal)
    @param op2: right operand (literal)
    @param com: bool - true if operator is commutative
    @param sub_dict:directory of sub expressions
    """
    key = ope + '#' + op1.code_name() + '#' + op2.code_name()
    try:
        val_var = sub_dict[key]
        return val_var
    except KeyError:
        if com:
            key = ope + '#' + op2.code_name() + '#' + op1.code_name()
            try:
                val_var = sub_dict[key]
                return val_var
            except KeyError:
                return None
        else:
            return None


def referencealbedo_prospectparams():
    """
    Returns the PROSPECT parameters required for creating the  reference albedo
    based on Knyazikhin et al. (2013), PNAS, section "SI Text 4" (Supporting Information)
    all prospect versions in prospect have four positional arguments N,Cab,Cw,Cm

    :return: list of 4 values corresponding to the prospect positional parameters
    """
    return 1.2, 16, 0.005, 0.002


def whoami(ctx):
    """Returns current user name."""
    return ctx.run('whoami').stdout.strip()


@staticmethod
def _cyclic_three_perm_sign(v0, v1, v2):
    """
        Returns +1 or -1. It is +1 if and only if (v0, v1, v2) is in the
        orbit of (0, 1, 2) under the A4-action.
        """
    for t in [(v0, v1, v2), (v1, v2, v0), (v2, v0, v1)]:
        if t in [(0, 1, 2), (1, 3, 2), (2, 3, 0), (3, 1, 0)]:
            return +1
    return -1


@classmethod
def is_notifying(cls, user_or_email_, object_id=None, **filters):
    """Return whether the user/email is watching this event (either
        active or inactive watches), conditional on meeting the criteria in
        ``filters``.

        Count only watches that match the given filters exactly--not ones which
        match merely a superset of them. This lets callers distinguish between
        watches which overlap in scope. Equivalently, this lets callers check
        whether :meth:`notify()` has been called with these arguments.

        Implementations in subclasses may take different arguments--for
        example, to assume certain filters--though most will probably just use
        this. However, subclasses should clearly document what filters they
        supports and the meaning of each.

        Passing this an ``AnonymousUser`` always returns ``False``. This means
        you can always pass it ``request.user`` in a view and get a sensible
        response.

        """
    return cls._watches_belonging_to_user(user_or_email_, object_id=
        object_id, **filters).exists()


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 EwkrwksT(k, r, s, d1, d2, ExxT, EggT, L):
    """
    Slower vesion of this function
    """
    K = L.shape[-1]
    N = ExxT.shape[0] // K
    D = L.shape[0]
    EgrgsT = EggT[r * N:(r + 1) * N, s * N:(s + 1) * N]
    wkrwksT = 0.0
    for i in range(K):
        for j in range(K):
            wkrwksT += ExxT[i * N:(i + 1) * N, j * N:(j + 1) * N] * L[d1, k, i
                ] * L[d2, k, j]
    return EgrgsT * wkrwksT


@property
def __members__(cls):
    """Returns a mapping of member name->value.

        This mapping lists all enum members, including aliases. Note that this
        is a copy of the internal mapping.

        """
    return cls._member_map_.copy()


def _upload(project, subject, session, scan, dcm_dir, volume_files,
    time_series=None):
    """
    Uploads the staged files.

    :param project: the project name
    :param subject: the subject name
    :param session: the session name
    :param scan: the scan number
    :param dcm_dir: the input staged directory
    :param volume_files: the 3D scan volume files
    :param time_series: the 4D scan time series file, if the scan is
        multi-volume
    """
    from qipipe.pipeline.staging import upload_dicom, upload_nifti
    upload_dicom(project, subject, session, scan, dcm_dir)
    if time_series:
        nii_files = volume_files + [time_series]
    else:
        nii_files = volume_files
    upload_nifti(project, subject, session, scan, nii_files)


@classmethod
def from_c_grid_dataset(cls, filenames, variables, dimensions, indices=None,
    mesh='spherical', allow_time_extrapolation=None, time_periodic=False,
    tracer_interp_method='cgrid_tracer', **kwargs):
    """Initialises FieldSet object from NetCDF files of Curvilinear NEMO fields.

        :param filenames: Dictionary mapping variables to file(s). The
               filepath may contain wildcards to indicate multiple files,
               or be a list of file.
               filenames can be a list [files], a dictionary {var:[files]},
               a dictionary {dim:[files]} (if lon, lat, depth and/or data not stored in same files as data),
               or a dictionary of dictionaries {var:{dim:[files]}}
               time values are in filenames[data]
        :param variables: Dictionary mapping variables to variable
               names in the netCDF file(s).
        :param dimensions: Dictionary mapping data dimensions (lon,
               lat, depth, time, data) to dimensions in the netCF file(s).
               Note that dimensions can also be a dictionary of dictionaries if
               dimension names are different for each variable.
               Watch out: NEMO is discretised on a C-grid:
               U and V velocities are not located on the same nodes (see https://www.nemo-ocean.eu/doc/node19.html ).
                _________________V[k,j+1,i+1]________________
               |                                             |
               |                                             |
               U[k,j+1,i]   W[k:k+2,j+1,i+1], T[k,j+1,i+1]   U[k,j+1,i+1]
               |                                             |
               |                                             |
               |_________________V[k,j,i+1]__________________|
               To interpolate U, V velocities on the C-grid, Parcels needs to read the f-nodes,
               which are located on the corners of the cells.
               (for indexing details: https://www.nemo-ocean.eu/doc/img360.png )
               In 3D, the depth is the one corresponding to W nodes
        :param indices: Optional dictionary of indices for each dimension
               to read from file(s), to allow for reading of subset of data.
               Default is to read the full extent of each dimension.
               Note that negative indices are not allowed.
        :param mesh: String indicating the type of mesh coordinates and
               units used during velocity interpolation:

               1. spherical (default): Lat and lon in degree, with a
                  correction for zonal velocity U near the poles.
               2. flat: No conversion, lat/lon are assumed to be in m.
        :param allow_time_extrapolation: boolean whether to allow for extrapolation
               (i.e. beyond the last available time snapshot)
               Default is False if dimensions includes time, else True
        :param time_periodic: boolean whether to loop periodically over the time component of the FieldSet
               This flag overrides the allow_time_interpolation and sets it to False
        :param tracer_interp_method: Method for interpolation of tracer fields. It is recommended to use 'cgrid_tracer' (default)
               Note that in the case of from_nemo() and from_cgrid(), the velocity fields are default to 'cgrid_velocity'

        """
    if 'U' in dimensions and 'V' in dimensions and dimensions['U'
        ] != dimensions['V']:
        raise RuntimeError(
            'On a c-grid discretisation like NEMO, U and V should have the same dimensions'
            )
    if 'U' in dimensions and 'W' in dimensions and dimensions['U'
        ] != dimensions['W']:
        raise RuntimeError(
            'On a c-grid discretisation like NEMO, U, V and W should have the same dimensions'
            )
    interp_method = {}
    for v in variables:
        if v in ['U', 'V', 'W']:
            interp_method[v] = 'cgrid_velocity'
        else:
            interp_method[v] = tracer_interp_method
    if 'creation_log' not in kwargs.keys():
        kwargs['creation_log'] = 'from_c_grid_dataset'
    return cls.from_netcdf(filenames, variables, dimensions, mesh=mesh,
        indices=indices, time_periodic=time_periodic,
        allow_time_extrapolation=allow_time_extrapolation, interp_method=
        interp_method, **kwargs)


def _computer_get_remote_username(transport, scheduler, authinfo):
    """Internal test to check if it is possible to determine the username on the remote.

    :param transport: an open transport
    :param scheduler: the corresponding scheduler class
    :param authinfo: the AuthInfo object
    :return: tuple of boolean indicating success or failure and an optional string message
    """
    remote_user = transport.whoami()
    return True, remote_user


def gru_unit(**kwargs):
    """
    We cannot pass param_attr or bias_attr to paddle.fluid.layers.gru_unit yet.
    """
    raise NotImplementedError()


def _init_label_matrix(n_samples, n_classes):
    """Create and return zero matrix

    Parameters
    ----------
    n_samples : integer
        The number of nodes (samples) on the input graph
    n_classes : integer
        The number of classes (distinct labels) on the input graph

    Returns
    ----------
    F : numpy array, shape = [n_samples, n_classes]
        Label matrix
    """
    import numpy as np
    F = np.zeros((n_samples, n_classes))
    return F


@classmethod
def to_string(cls, type_):
    """ Return ID representation (string) of a type
        """
    return cls.TYPE_NAMES[type_]


def broadcast_logical_or(lhs=None, rhs=None, out=None, name=None, **kwargs):
    """Returns the result of element-wise **logical or** with broadcasting.

    Example::

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

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

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

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

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

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

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


def add_arg(func, *args, **kwargs):
    """Bind CLI arguments to a shell.py `do_foo` function."""
    if not hasattr(func, 'arguments'):
        func.arguments = []
    if (args, kwargs) not in func.arguments:
        func.arguments.insert(0, (args, kwargs))


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

        :param PaperDocViewType val:
        :rtype: EventType
        """
    return cls('paper_doc_view', val)


def bone_layers(layers: bool=(False, False, False, False, False, False,
    False, False, False, False, False, False, False, False, False, False,
    False, False, False, False, False, False, False, False, False, False,
    False, False, False, False, False, False)):
    """Change the layers that the selected bones belong to

    :param layers: Layer, Armature layers that bone belongs to
    :type layers: bool
    """
    pass


def filter_df(db, annot_colname, norm_df):
    """
    Filter DataFrame to non-missing and valid terms

    :param db: Relevant database
    :param annot_colname: Name of column with terms (NCBI, GO, or EC)
    :param norm_df: Dataframe with one term per row
    :return: DataFrame with only non-missing terms and those present in the database
    """
    is_not_nan = ~norm_df[annot_colname].isnull()
    is_in_db = norm_df[annot_colname].apply(db.is_in_db)
    df_clean = norm_df.loc[is_not_nan & is_in_db].copy(deep=True)
    return df_clean


def set_viewport_background():
    """Set current movie clip as a camera background in 3D view-port (works only when a 3D view-port is visible)

    """
    pass


def itervalues(dictionary):
    """
  Function to use the generator-based value iterator over built-in
  dictionaries in both Python 2 and 3.
  """
    try:
        return getattr(dictionary, 'itervalues')()
    except AttributeError:
        return iter(getattr(dictionary, 'values')())


def list_nodes(base):
    """Utility function that lists Senlin nodes."""
    res = base.client.list_objs('nodes')
    return res['body']


def fill_width(bytes_, width):
    """
    Ensure a byte string representing a positive integer is a specific width
    (in bytes)

    :param bytes_:
        The integer byte string

    :param width:
        The desired width as an integer

    :return:
        A byte string of the width specified
    """
    while len(bytes_) < width:
        bytes_ = b'\x00' + bytes_
    return bytes_


def mean(data):
    """Calculate the mean of a list of numbers

    Parameters:

    *data*
        a list of numbers whose mean to calculate

    """
    return float(sum(data)) / len(data)


def __call__(request, elements, kw):
    """ A pregenerator is a function associated by a developer with a
        :term:`route`. The pregenerator for a route is called by
        :meth:`pyramid.request.Request.route_url` in order to adjust the set
        of arguments passed to it by the user for special purposes, such as
        Pylons 'subdomain' support.  It will influence the URL returned by
        ``route_url``.

        A pregenerator should return a two-tuple of ``(elements, kw)``
        after examining the originals passed to this function, which
        are the arguments ``(request, elements, kw)``.  The simplest
        pregenerator is::

            def pregenerator(request, elements, kw):
                return elements, kw

        You can employ a pregenerator by passing a ``pregenerator``
        argument to the
        :meth:`pyramid.config.Configurator.add_route`
        function.

        """


def null_write_block(encoder, block_bytes, compression_level):
    """Write block in "null" codec."""
    encoder.write_long(len(block_bytes))
    encoder._fo.write(block_bytes)


def blend_strings_utf8_validate():
    """Check and fix all strings in current .blend file to be valid UTF-8 Unicode (needed for some old, 2.4x area files)

    """
    pass


def find_closest_positive_divisor(a, b):
    """Return non-trivial positive integer divisor (bh) of (a) closest to (b) in abs(b-bh) such that a % bh == 0.  This uses exhaustive search, which is inefficient for large a."""
    assert a > 0 and b > 0
    if a <= b:
        return a
    for k in range(0, a - b + 1):
        bh = b + k
        if bh > 1 and a % bh == 0:
            return bh
        bh = b - k
        if bh > 1 and a % bh == 0:
            return bh
    return a


def associate_virtual_interface(virtualInterfaceId=None, connectionId=None):
    """
    Associates a virtual interface with a specified link aggregation group (LAG) or connection. Connectivity to AWS is temporarily interrupted as the virtual interface is being migrated. If the target connection or LAG has an associated virtual interface with a conflicting VLAN number or a conflicting IP address, the operation fails.
    Virtual interfaces associated with a hosted connection cannot be associated with a LAG; hosted connections must be migrated along with their virtual interfaces using  AssociateHostedConnection .
    Hosted virtual interfaces (an interface for which the owner of the connection is not the owner of physical connection) can only be reassociated by the owner of the physical connection.
    See also: AWS API Documentation

    :example: response = client.associate_virtual_interface(
        virtualInterfaceId='string',
        connectionId='string'
    )

    :type virtualInterfaceId: string
    :param virtualInterfaceId: [REQUIRED]
            The ID of the virtual interface.
            Example: dxvif-123dfg56
            Default: None

    :type connectionId: string
    :param connectionId: [REQUIRED]
            The ID of the LAG or connection with which to associate the virtual interface.
            Example: dxlag-abc123 or dxcon-abc123
            Default: None

    :rtype: dict
    :return: {
        'ownerAccount': 'string',
        'virtualInterfaceId': 'string',
        'location': 'string',
        'connectionId': 'string',
        'virtualInterfaceType': 'string',
        'virtualInterfaceName': 'string',
        'vlan': 123,
        'asn': 123,
        'authKey': 'string',
        'amazonAddress': 'string',
        'customerAddress': 'string',
        'addressFamily': 'ipv4'|'ipv6',
        'virtualInterfaceState': 'confirming'|'verifying'|'pending'|'available'|'down'|'deleting'|'deleted'|'rejected',
        'customerRouterConfig': 'string',
        'virtualGatewayId': 'string',
        'routeFilterPrefixes': [
            {
                'cidr': 'string'
            },
        ],
        'bgpPeers': [
            {
                'asn': 123,
                'authKey': 'string',
                'addressFamily': 'ipv4'|'ipv6',
                'amazonAddress': 'string',
                'customerAddress': 'string',
                'bgpPeerState': 'verifying'|'pending'|'available'|'deleting'|'deleted',
                'bgpStatus': 'up'|'down'
            },
        ]
    }

    :returns:
    ipv4 : IPv4 address family
    ipv6 : IPv6 address family

    """
    pass


def camel_splitter(x):
    """Make tokens from camelCase strings

    :param x: The filepath of string.
    :type x: WindowsFilePath, PosixFilePath, str

    :return: list of tokens (strings)
    :return_type: list
    """
    raise NotImplementedError


def is_url_connectable(port):
    """
    Tries to connect to the HTTP server at /status path
    and specified port to see if it responds successfully.

    :Args:
     - port - The port to connect.
    """
    try:
        from urllib import request as url_request
    except ImportError:
        import urllib2 as url_request
    try:
        res = url_request.urlopen('http://127.0.0.1:%s/status' % port)
        if res.getcode() == 200:
            return True
        else:
            return False
    except Exception:
        return False


@staticmethod
def calculate(vm, arg):
    """
        Calculate the result of the unary operation, given a concrete argument.

        The virtual machine is passed in so that the overflow and carry flags can be
        set if necessary.
        """
    raise NotImplementedError


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


@classmethod
def accepts_default_mpiprocs_per_machine(cls):
    """
        Return True if this JobResource accepts a 'default_mpiprocs_per_machine'
        key, False otherwise.

        Should be implemented in each subclass.
        """
    raise NotImplementedError


def worktime(ticket, resource):
    """ Returns the work time for the given ticket and resource
        """


def replaceText(infile, sub={}, outfile=None):
    """replaceText(infile,[sub,outfile]) --> replace text {old:new} in a file
    this function uses regular expressions, if a pattern is given as old text
    Note: this may fail if order of substitution is important"""
    if outfile == None:
        outfile = infile
    input = open(infile, 'r')
    filestring = input.read()
    input.close()
    import re
    for old, new in list(sub.items()):
        filestring = re.compile(old).sub(new, filestring)
    output = open(outfile, 'w')
    output.write(filestring)
    output.close()
    return


def get_dim_as_int(dim):
    """Utility to get v1 or v2 TensorShape dim as an int.

  Args:
    dim: The TensorShape dimension to get as an int

  Returns:
    None or an int.
  """
    try:
        return dim.value
    except AttributeError:
        return dim


def _sshv1respondbytes(fout, value):
    """Send a bytes response for protocol version 1."""
    fout.write(b'%d\n' % len(value))
    fout.write(value)
    fout.flush()


@classmethod
def get_from_name(cls, name):
    """Return the corresponding SIPMetadataType."""
    return cls.query.filter_by(name=name).one()


def split_by_pivot(arr, pivots):
    """
    Takes a numpy array and splits it according to pivot points.
    Yields each slice.
    Examples:
    split_by_pivot([0,1,2,3,4,5], [2]) => [[0,1],[2,3,4,5]]
    split_by_pivot([0,1,2,3,4,5], [2,4]) => [[0,1],[2,3],[4,5]]

    Parameters
    ----------
    arr : any sliceable iterable
        The array to return slice froms
    pivots : iterable of ints
        The pivot points to split at
    """
    idxs = [0] + list(pivots) + [len(arr)]
    for start, end in zip(idxs[:-1], idxs[1:]):
        yield arr[start:end]


def get_env_attr(env, attr, default='__ERROR__', max_depth=100):
    """
    Get the given attribute from a potentially wrapped environment.

    Note that the wrapped envs are traversed from the outside in. Once the
    attribute is found, the search stops. This means that an inner wrapped env
    may carry the same (possibly conflicting) attribute. This situation is
    *not* resolved by this function.

    Parameters
    ----------
    env : gym environment

        A potentially wrapped environment.

    attr : str

        The attribute name.

    max_depth : positive int, optional

        The maximum depth of wrappers to traverse.

    """
    e = env
    for i in range(max_depth):
        if hasattr(e, attr):
            return getattr(e, attr)
        if not hasattr(e, 'env'):
            break
        e = e.env
    if default == '__ERROR__':
        raise AttributeError('env is missing attribute: {}'.format(attr))
    return default


def clip_pad(tensor, pad_shape):
    """
    Clip boxes of the pad area.
    :param tensor: [n, c, H, W]
    :param pad_shape: [h, w]
    :return: [n, c, h, w]
    """
    H, W = tensor.shape[2:]
    h, w = pad_shape
    if h < H or w < W:
        tensor = tensor[:, :, :h, :w].copy()
    return tensor


def variable_value(request, field_name):
    """Check field in POST/GET request and return field value

    Depreciated : It will be replaced by getvar
    """
    if request.method == 'GET':
        if field_name in request.GET:
            field_name = request.GET[field_name]
        else:
            field_name = ''
    if request.method == 'POST':
        if field_name in request.POST:
            field_name = request.POST[field_name]
        else:
            field_name = ''
    return field_name


def acquire(interface):
    """Traverse parents until interface provided. Return first parent
        providing interface or None if no parent matches.
        """


def is_bearish_engolfing(body, open, close):
    """ Se existir engolfo de baixa retorna True."""
    if body[1] < 0 and body[0] > 0:
        if open[1] >= close[0] and close[1] <= open[0]:
            return True
    return False


def join_with_and(strings):
    """Join a list of strings.

    >>> join_with_and(['a','b','c'])
    'a, b, and c'
    >>> join_with_and(['a','b'])
    'a and b'
    >>> join_with_and(['a'])
    'a'
    """
    ret = [strings[0]]
    for i, s in enumerate(strings[1:]):
        if len(strings) > 2:
            ret.append(', ')
        else:
            ret.append(' ')
        if i == len(strings) - 2:
            ret.append('and ')
        ret.append(s)
    return ''.join(ret)


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

        :param FilePermanentlyDeleteType val:
        :rtype: EventType
        """
    return cls('file_permanently_delete', val)


def determineactions(repo, deficiencies, sourcereqs, destreqs):
    """Determine upgrade actions that will be performed.

    Given a list of improvements as returned by ``finddeficiencies`` and
    ``findoptimizations``, determine the list of upgrade actions that
    will be performed.

    The role of this function is to filter improvements if needed, apply
    recommended optimizations from the improvements list that make sense,
    etc.

    Returns a list of action names.
    """
    newactions = []
    for d in deficiencies:
        name = d._requirement
        if name is not None and name not in destreqs:
            continue
        newactions.append(d)
    return newactions


def expm1(data=None, name=None, attr=None, out=None, **kwargs):
    """Returns ``exp(x) - 1`` computed element-wise on the input.

    This function provides greater precision than ``exp(x) - 1`` for small values of ``x``.

    The storage type of ``expm1`` output depends upon the input storage type:

       - expm1(default) = default
       - expm1(row_sparse) = row_sparse
       - expm1(csr) = csr

    Defined in src/operator/tensor/elemwise_unary_op_logexp.cc:L224

    Parameters
    ----------
    data : Symbol
        The input array.

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

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


def alt(key):
    """Make a string that tmux will parse as the alt key (:kbd:`Alt`) and
    ``key`` pressed at the same time.

    .. note::

       The ``key`` parameter is case-sensitive. If ``key`` is uppercase, it's
       equivalent to entering :kbd:`Shift` and the key.

       .. doctest::

          >>> from oraide.keys import alt
          >>> alt('a')  # alt + a
          'A-a'
          >>> alt('A')  # alt + shift + a
          'A-A'
    """
    return 'A-{}'.format(key)


def delete_workunit(connection, wuid, max_attempts=3, max_sleep=15):
    """
    Delete a workunit

    Parameters
    ----------
    connection: `Connection`
        HPCC Connection instance, see also `Connection`.
    wuid: string
        Workunit ID
    max_attempts: int, optional
        Maximum number of times url should be queried in the
        case of an exception being raised. 3 by default.
    max_sleep: int, optional
        Maximum time, in seconds, to sleep between attempts.
        The true sleep time is a random int between  `max_sleep` and
        `max_sleep` * 0.75. 5 by default.

    Returns
    -------
    True:
        If the workunit is deleted successfully.

    Raises
    ------
    ValueError:
        If the workunit could not be deleted.

    """
    url = (
        'http://{}:{}/WsWorkunits/WUDelete.json?Wuids={}&BlockTillFinishTimer=True'
        .format(connection.server, connection.port, wuid))
    r = connection.run_url_request(url, max_attempts, max_sleep)
    rj = r.json()
    if rj == {'WUDeleteResponse': {}}:
        return True
    else:
        raise ValueError(rj)


def values():
    """ Return a list of values from the dictionary """


def pad(text, **kwargs):
    """ Return a padded text filled with a given character based on a given
    orientation.
    The padded text is sized by default as 79 characters to default as a valid
    pep8 line of code. Add a size parameter will change the padded text size.

    :param text: The text to be padded.
    :param fill: Character to be used to pad the text.
    :param orientation: Orientation to place the fill character. Default is
    'left' but it can be also 'center' and 'right'.
    :param size: Size to be used to pad the text. By default is 79.
    :return: A padded text. """
    size = kwargs.get('size', 79)
    fill = kwargs.get('fill', ' ')
    orientation = kwargs.get('orientation', 'left').lower()
    align = '<'
    if orientation == 'center':
        align = '^'
    elif orientation == 'right':
        align = '>'
    pad_format = ''.join(['{0:{fill}{align}', str(size), '}'])
    return pad_format.format(text, fill=fill, align=align)


def gen_find_method(ele_type, multiple=True, extra_maps=None):
    """
    将 ele_type 转换成对应的元素查找方法
    e.g::

        make_elt(ele_type=name, False) => find_element_by_name
        make_elt(ele_type=name, True) => find_elements_by_name

    :param ele_type:
    :type ele_type:
    :param multiple:
    :type multiple:
    :param extra_maps:
    :type extra_maps:
    :return:
    """
    _ = 'elements' if multiple else 'element'
    d = {'class': 'class_name'}
    if isinstance(extra_maps, dict):
        d = dict(d, **extra_maps)
    return 'find_{}_by_{}'.format(_, d.get(ele_type, ele_type))


def construct_hostname(region, account):
    """
    Constructs hostname from region and account
    """
    if region == u'us-west-2':
        region = ''
    if region:
        if account.find(u'.') > 0:
            account = account[0:account.find(u'.')]
        host = u'{}.{}.snowflakecomputing.com'.format(account, region)
    else:
        host = u'{}.snowflakecomputing.com'.format(account)
    return host


def _to_latex(string):
    """Latex-decorate a string."""
    return '$' + string + '$'


def golds_to_gold_tuples(docs, golds):
    """Get out the annoying 'tuples' format used by begin_training, given the
    GoldParse objects."""
    tuples = []
    for doc, gold in zip(docs, golds):
        text = doc.text
        ids, words, tags, heads, labels, iob = zip(*gold.orig_annot)
        sents = [((ids, words, tags, heads, labels, iob), [])]
        tuples.append((text, sents))
    return tuples


def list_instance_groups(ClusterId=None, Marker=None):
    """
    Provides all available details about the instance groups in a cluster.
    See also: AWS API Documentation

    :example: response = client.list_instance_groups(
        ClusterId='string',
        Marker='string'
    )

    :type ClusterId: string
    :param ClusterId: [REQUIRED]
            The identifier of the cluster for which to list the instance groups.

    :type Marker: string
    :param Marker: The pagination token that indicates the next set of results to retrieve.

    :rtype: dict
    :return: {
        'InstanceGroups': [
            {
                'Id': 'string',
                'Name': 'string',
                'Market': 'ON_DEMAND'|'SPOT',
                'InstanceGroupType': 'MASTER'|'CORE'|'TASK',
                'BidPrice': 'string',
                'InstanceType': 'string',
                'RequestedInstanceCount': 123,
                'RunningInstanceCount': 123,
                'Status': {
                    'State': 'PROVISIONING'|'BOOTSTRAPPING'|'RUNNING'|'RESIZING'|'SUSPENDED'|'TERMINATING'|'TERMINATED'|'ARRESTED'|'SHUTTING_DOWN'|'ENDED',
                    'StateChangeReason': {
                        'Code': 'INTERNAL_ERROR'|'VALIDATION_ERROR'|'INSTANCE_FAILURE'|'CLUSTER_TERMINATED',
                        'Message': 'string'
                    },
                    'Timeline': {
                        'CreationDateTime': datetime(2015, 1, 1),
                        'ReadyDateTime': datetime(2015, 1, 1),
                        'EndDateTime': datetime(2015, 1, 1)
                    }
                },
                'Configurations': [
                    {
                        'Classification': 'string',
                        'Configurations': {'... recursive ...'},
                        'Properties': {
                            'string': 'string'
                        }
                    },
                ],
                'EbsBlockDevices': [
                    {
                        'VolumeSpecification': {
                            'VolumeType': 'string',
                            'Iops': 123,
                            'SizeInGB': 123
                        },
                        'Device': 'string'
                    },
                ],
                'EbsOptimized': True|False,
                'ShrinkPolicy': {
                    'DecommissionTimeout': 123,
                    'InstanceResizePolicy': {
                        'InstancesToTerminate': [
                            'string',
                        ],
                        'InstancesToProtect': [
                            'string',
                        ],
                        'InstanceTerminationTimeout': 123
                    }
                },
                'AutoScalingPolicy': {
                    'Status': {
                        'State': 'PENDING'|'ATTACHING'|'ATTACHED'|'DETACHING'|'DETACHED'|'FAILED',
                        'StateChangeReason': {
                            'Code': 'USER_REQUEST'|'PROVISION_FAILURE'|'CLEANUP_FAILURE',
                            'Message': 'string'
                        }
                    },
                    'Constraints': {
                        'MinCapacity': 123,
                        'MaxCapacity': 123
                    },
                    'Rules': [
                        {
                            'Name': 'string',
                            'Description': 'string',
                            'Action': {
                                'Market': 'ON_DEMAND'|'SPOT',
                                'SimpleScalingPolicyConfiguration': {
                                    'AdjustmentType': 'CHANGE_IN_CAPACITY'|'PERCENT_CHANGE_IN_CAPACITY'|'EXACT_CAPACITY',
                                    'ScalingAdjustment': 123,
                                    'CoolDown': 123
                                }
                            },
                            'Trigger': {
                                'CloudWatchAlarmDefinition': {
                                    'ComparisonOperator': 'GREATER_THAN_OR_EQUAL'|'GREATER_THAN'|'LESS_THAN'|'LESS_THAN_OR_EQUAL',
                                    'EvaluationPeriods': 123,
                                    'MetricName': 'string',
                                    'Namespace': 'string',
                                    'Period': 123,
                                    'Statistic': 'SAMPLE_COUNT'|'AVERAGE'|'SUM'|'MINIMUM'|'MAXIMUM',
                                    'Threshold': 123.0,
                                    'Unit': 'NONE'|'SECONDS'|'MICRO_SECONDS'|'MILLI_SECONDS'|'BYTES'|'KILO_BYTES'|'MEGA_BYTES'|'GIGA_BYTES'|'TERA_BYTES'|'BITS'|'KILO_BITS'|'MEGA_BITS'|'GIGA_BITS'|'TERA_BITS'|'PERCENT'|'COUNT'|'BYTES_PER_SECOND'|'KILO_BYTES_PER_SECOND'|'MEGA_BYTES_PER_SECOND'|'GIGA_BYTES_PER_SECOND'|'TERA_BYTES_PER_SECOND'|'BITS_PER_SECOND'|'KILO_BITS_PER_SECOND'|'MEGA_BITS_PER_SECOND'|'GIGA_BITS_PER_SECOND'|'TERA_BITS_PER_SECOND'|'COUNT_PER_SECOND',
                                    'Dimensions': [
                                        {
                                            'Key': 'string',
                                            'Value': 'string'
                                        },
                                    ]
                                }
                            }
                        },
                    ]
                }
            },
        ],
        'Marker': 'string'
    }

    :returns:
    (string) --
    (string) --

    """
    pass


@classmethod
def _adapt_text_array(cls, v):
    """Adapt a text type array parameter."""
    if isinstance(v, list):
        adapt = cls._adapt_text_array
        return '{%s}' % ','.join(adapt(v) for v in v)
    if v is None:
        return 'null'
    if not v:
        return '""'
    v = str(v)
    if cls._re_array_quote.search(v):
        v = '"%s"' % cls._re_array_escape.sub('\\\\\\1', v)
    return v


def gcd(x, y):
    """
    Function to find gcm (greatest common divisor) of two numbers
    :param x: first number
    :param y: second number
    :return: gcd of x and y
    """
    while y != 0:
        x, y = y, x % y
    return x


def show_lightcone(eca, cell):
    """Show the light cone for the specified cell.

    The darker the cell, the more times it has been counted.

    Parameters
    ----------
    cell : 2-tuple
        A 2-tuple (t, s) where t is the row index and s is the column
        index of the cell.

    """
    pass


def checkNull(df, columnName, acceptableAmount):
    """

     # Run QA checks to confirm data population
    isNameValid = checkNull(df,'full_name',.9)
    isAgeValid = checkNull(df,'age',.9)
    isGenderValid = checkNull(df,'gender',1)

    :param df:
    :param columnName:
    :param acceptableAmount:
    :return:
    """
    acceptableQuality = False
    nullPercent = df[columnName].isnull().sum() / df[columnName].count()
    if nullPercent >= acceptableAmount:
        acceptableQuality = True
    return acceptableQuality


def __combine_windows(w1, w2):
    """
    Joins two windows (defined by tuple of slices) such that their maximum
    combined extend is covered by the new returned window.
    """
    res = []
    for s1, s2 in zip(w1, w2):
        res.append(slice(min(s1.start, s2.start), max(s1.stop, s2.stop)))
    return tuple(res)


@classmethod
def loop(cls, config, options):
    """iterate through repositories from config"""
    for i in config.configuration.get('repositories', []):
        tag, name = i[:2]
        args = i[2:]
        yield cls.by_tag(tag, name, config, *args)


def parameterize(D):
    """Identity function.

        Parameters
        ----------
        D : :obj:`DataSet`
            A dataset.

        Returns
        -------
        :obj:`list` of :obj:`ndarray`
            The a list of each vector in the dataset.

        """
    return list(map(lambda j: D.getResource(j), range(D.n)))


def _gcd(a, b):
    """Calculate the Greatest Common Divisor of a and b.

    Unless b==0, the result will have the same sign as b (so that when
    b is divided by it, the result comes out positive).
    """
    while b:
        a, b = b, a % b
    return a


def compute_num_processes_and_threads(max_cpu_cores, threads_per_process):
    """Compute the number of allowed processes and threads given the maximum allowed
    number of CPUs and requested number of threads per process.

    Parameters
    ----------
    max_cpu_cores : int or None
        The maximum allowed number of CPU cores to consume by all instances of the process.
        If set the None, it implies no limit to the number of CPU cores that can be used.
    threads_per_process : int
        The user-requested number of threads to use.

    Returns
    -------
    num_processes : int or None
        The computed maximum number of allowed concurrent processes, or None to allow unlimited.
    threads_per_process : int
        The number of threads per process instance which might be less than requested if the
        number of allowed cpus is less than the requested number of threads.

    Examples
    --------
    # max CPU not set
    >>> compute_num_processes_and_threads(None, 8)
    (None, 8)

    # max CPU set, not multiple of threads
    >>> compute_num_processes_and_threads(20, 8)
    (2, 8)

    # max CPU set, multiple of threads
    >>> compute_num_processes_and_threads(24, 8)
    (3, 8)

    # max CPU less than desired threads
    >>> compute_num_processes_and_threads(2, 8)
    (1, 2)
    """
    if max_cpu_cores is None:
        num_processes = None
    elif max_cpu_cores >= threads_per_process:
        num_processes = int(max_cpu_cores / threads_per_process)
    else:
        num_processes = 1
        threads_per_process = max_cpu_cores
    return num_processes, threads_per_process


def syntax_highlighter(input: str) ->str:
    """.repo-metadata.json language field to syntax highlighter name."""
    if input == 'nodejs':
        return 'javascript'
    return input


@classmethod
def indent(cls, fmt):
    """Get a new format string with indentation."""
    return '| ' * cls.level + fmt


def bayes(prior, sensitivity, specitivity):
    """Compute Bayes rule over the prior, sensitivity, and specitivity."""
    joint1 = prior * sensitivity
    joint2 = (1.0 - prior) * (1.0 - specitivity)
    normalizer = joint1 + joint2
    return joint1 / normalizer


def unquote(s):
    """Return copy of s without first and last characters
    if they are both double quotes"""
    if s[:1] == '"' and s[-1:] == '"':
        return s[1:-1]
    else:
        return s


def subtract(attrs, inputs, cls):
    """Subtracting two tensors"""
    new_attr = {}
    if 'broadcast' in attrs and attrs['broadcast'] == 1:
        return 'broadcast_sub', new_attr, inputs
    return 'elemwise_sub', new_attr, inputs


def get_url(ip_address=None):
    """Converts the supplied IP address to the associated URL for
    crawling and parsing."""
    print('get_url()')


def request_check(r):
    """return a valid json response with meta data from request"""
    request = {'status': 'ok'}
    if r.args.get('data'):
        request['data'] = r.args.get('data')
    if r.args.get('method'):
        request['method'] = r.args.get('method')
    if r.args.get('resource'):
        request['resource'] = r.args.get('resource')
    return request


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

        :param LockingErrorTag val:
        :rtype: RenameErrorTagUnion
        """
    return cls('locking_error', val)


@classmethod
def apply_query_lt(cls, queryset, options, value):
    """Apply `lt` functional query.

        Syntax:

            /endpoint/?field_name__lt={value}__{boost}
            /endpoint/?field_name__lt={value}

        Example:

            http://localhost:8000/api/articles/?id__lt=1__2.0
            http://localhost:8000/api/articles/?id__lt=1

        :param queryset: Original queryset.
        :param options: Filter options.
        :param value: value to filter on.
        :type queryset: elasticsearch_dsl.search.Search
        :type options: dict
        :type value: str
        :return: Modified queryset.
        :rtype: elasticsearch_dsl.search.Search
        """
    return cls.apply_filter(queryset=queryset, options=options, args=[
        'range'], kwargs={options['field']: cls.get_gte_lte_params(value,
        'lt')})


@staticmethod
def conjugates(x):
    """
        Returns the conjugates of a given element. See :cite:`Lin.Costello.04` (Sec. 2.5) for more details.
        """
    conjugate_list = []
    exponent = 0
    while True:
        y = x ** 2 ** exponent
        if y not in conjugate_list:
            conjugate_list.append(y)
        else:
            break
        exponent += 1
    return conjugate_list


def train_shapenet():
    """
    Trains a single shapenet with config file from comandline arguments

    See Also
    --------
    :class:`delira.training.PyTorchNetworkTrainer`

    """
    import logging
    import numpy as np
    import torch
    from shapedata.single_shape import SingleShapeDataset
    from delira.training import PyTorchNetworkTrainer
    from ..utils import Config
    from ..layer import HomogeneousShapeLayer
    from ..networks import SingleShapeNetwork
    from delira.logging import TrixiHandler
    from trixi.logger import PytorchVisdomLogger
    from delira.training.callbacks import ReduceLROnPlateauCallbackPyTorch
    from delira.data_loading import BaseDataManager, RandomSampler, SequentialSampler
    import os
    import argparse
    parser = argparse.ArgumentParser()
    parser.add_argument('-c', '--config', type=str, help=
        'Path to configuration file')
    parser.add_argument('-v', '--verbose', action='store_true')
    args = parser.parse_args()
    config = Config()
    config_dict = config(os.path.abspath(args.config))
    shapes = np.load(os.path.abspath(config_dict['layer'].pop('pca_path')))[
        'shapes'][:config_dict['layer'].pop('num_shape_params') + 1]
    net = SingleShapeNetwork(HomogeneousShapeLayer, {'shapes': shapes, **
        config_dict['layer']}, img_size=config_dict['data']['img_size'], **
        config_dict['network'])
    num_params = 0
    for param in net.parameters():
        num_params += param.numel()
    if args.verbose:
        print('Number of Parameters: %d' % num_params)
    criterions = {'L1': torch.nn.L1Loss()}
    metrics = {'MSE': torch.nn.MSELoss()}
    mixed_prec = config_dict['training'].pop('mixed_prec', False)
    config_dict['training']['save_path'] = os.path.abspath(config_dict[
        'training']['save_path'])
    trainer = PyTorchNetworkTrainer(net, criterions=criterions, metrics=
        metrics, lr_scheduler_cls=ReduceLROnPlateauCallbackPyTorch,
        lr_scheduler_params=config_dict['scheduler'], optimizer_cls=torch.
        optim.Adam, optimizer_params=config_dict['optimizer'],
        mixed_precision=mixed_prec, **config_dict['training'])
    if args.verbose:
        print(trainer.input_device)
        print('Load Data')
    dset_train = SingleShapeDataset(os.path.abspath(config_dict['data'][
        'train_path']), config_dict['data']['img_size'], config_dict['data'
        ]['crop'], config_dict['data']['landmark_extension_train'], cached=
        config_dict['data']['cached'], rotate=config_dict['data'][
        'rotate_train'], random_offset=config_dict['data']['offset_train'])
    if config_dict['data']['test_path']:
        dset_val = SingleShapeDataset(os.path.abspath(config_dict['data'][
            'test_path']), config_dict['data']['img_size'], config_dict[
            'data']['crop'], config_dict['data']['landmark_extension_test'],
            cached=config_dict['data']['cached'], rotate=config_dict['data'
            ]['rotate_test'], random_offset=config_dict['data']['offset_test'])
    else:
        dset_val = None
    mgr_train = BaseDataManager(dset_train, batch_size=config_dict['data'][
        'batch_size'], n_process_augmentation=config_dict['data'][
        'num_workers'], transforms=None, sampler_cls=RandomSampler)
    mgr_val = BaseDataManager(dset_val, batch_size=config_dict['data'][
        'batch_size'], n_process_augmentation=config_dict['data'][
        'num_workers'], transforms=None, sampler_cls=SequentialSampler)
    if args.verbose:
        print('Data loaded')
    if config_dict['logging'].pop('enable', False):
        logger_cls = PytorchVisdomLogger
        logging.basicConfig(level=logging.INFO, handlers=[TrixiHandler(
            logger_cls, **config_dict['logging'])])
    else:
        logging.basicConfig(level=logging.INFO, handlers=[logging.
            NullHandler()])
    logger = logging.getLogger('Test Logger')
    logger.info('Start Training')
    if args.verbose:
        print('Start Training')
    trainer.train(config_dict['training']['num_epochs'], mgr_train, mgr_val,
        config_dict['training']['val_score_key'], val_score_mode='lowest')


def quote(str):
    """Prepare string to be used in a quoted string.

    Turns backslash and double quote characters into quoted pairs.  These
    are the only characters that need to be quoted inside a quoted string.
    Does not add the surrounding double quotes.
    """
    return str.replace('\\', '\\\\').replace('"', '\\"')


def seg2rgb(seg, palette, n_segmentation_classes):
    """Color each pixel by segmentation class.

	Parameters
	----------
	seg:array
		Segmentation mask.
	palette:palette
		Color to RGB map.
	n_segmentation_classes:int
		Total number segmentation classes.

	Returns
	-------
	array
		Returned segmentation image.
	"""
    img = (palette(seg / n_segmentation_classes)[(...), :3] * 255).astype(int)
    return img


def select_more():
    """Select more strips adjacent to the current selection

    """
    pass


@staticmethod
def to_wikidata_field(*_, **__):
    """
        Get the portion of a SPARQL query that specifies the field name.

        Returns (Literal[""]):

        """
    return ''


def register_handler(handler):
    """
    Install application-specific BUFR image handler.

    :param handler: Handler object.
    """
    global _handler
    _handler = handler


def cleanup_commandline(commandline):
    """Clean up the commandline: remove trailing spaces and comments"""
    commandline = commandline.strip()
    instring = None
    for i in range(len(commandline)):
        if commandline[i] in ['"', "'"]:
            if instring == commandline[i]:
                instring = None
            elif instring is None:
                instring = commandline[i]
        if commandline[i] == '#' and instring is None:
            return commandline[:i].strip()
    if instring is not None:
        raise ValueError('Unterminated string in command line', commandline)
    return commandline.strip()
    return commandline.strip()


def scale_demand_by(context, factor):
    """
    Scale demand by factor%.

    >>> class C: pass
    >>> c = C()
    >>> c.demand = pd.DataFrame([0, 1, 2])
    >>> scale_demand_by(c, 1.2)
    >>> print(c.demand)
         0
    0  0.0
    1  1.2
    2  2.4
    """
    context.demand *= factor


@classmethod
def ring(cls):
    """
        Return the source ring.
        """
    return cls._ring


def desalt_smiles(smiles: str) ->str:
    """Removes all salts from the specified SMILES strings.

    This is a very simple and quick desalting algorithm that returns
    the longest component withing the input string. This will fail
    for cases with embedded components (e.g. 'c1cc([O-].[Na+])cccc1')
    or where individual components are actually connected
    (e.g. ethane represented as 'C1.C1').

    Args:
        smiles: The input SMILES string.

    Returns:
        The desalted SMILES string.
    """
    components = smiles.split('.')
    return max(components, key=len)


def trimlist(*args):
    """ Takes in number list or float and removes leading zeros """
    store = []
    values = []
    for mylist in args:
        each = []
        for x in mylist:
            if type(x) == float:
                each.append(float('%.4f' % x))
            elif type(x) == list:
                inner = []
                for y in x:
                    if type(y) == float:
                        inner.append(float('%.4f' % y))
                    else:
                        inner.append(y)
                each.append(inner)
            else:
                each.append(x)
        values.append(each)
    store.append(values)
    return store[0]


@classmethod
def deserialize_hex(cls, raw: str) ->'EthTx':
    """Serialize a transaction from hex."""
    r = raw
    if r[:2] == '0x':
        r = r[2:]
    return cls.deserialize(bytes.fromhex(r))


def getExceptionMessage(exceptionDetails: dict) ->str:
    """Get exception message from `exceptionDetails` object."""
    exception = exceptionDetails.get('exception')
    if exception:
        return exception.get('description') or exception.get('value')
    message = exceptionDetails.get('text', '')
    stackTrace = exceptionDetails.get('stackTrace', dict())
    if stackTrace:
        for callframe in stackTrace.get('callFrames'):
            location = str(callframe.get('url', '')) + ':' + str(callframe.
                get('lineNumber', '')) + ':' + str(callframe.get(
                'columnNumber'))
            functionName = callframe.get('functionName', '<anonymous>')
            message = message + f'\n    at {functionName} ({location})'
    return message


def relation_to_json(rel):
    """Convert relation to json-serializable."""
    json_data = {}
    for k, v in rel.items():
        json_data[k] = list(v)
    return json_data


def is_iter(obj):
    """
    evalua si el objeto se puede iterar

    Arguments
    ---------
    obj: any type

    Returns
    -------
    bool
        True if the object is iterable
    """
    try:
        iter(obj)
        return True
    except TypeError:
        return False


@classmethod
def get_updated(cls):
    """The timestamp when the API definition was last updated."""
    cls._assert_api_definition('UPDATED_TIMESTAMP')
    return cls.api_definition.UPDATED_TIMESTAMP


def get_grouped_by_powers(bases, powers):
    """
    Groups the powers and bases in the given
    `~astropy.units.CompositeUnit` into positive powers and
    negative powers for easy display on either side of a solidus.

    Parameters
    ----------
    bases : list of `astropy.units.UnitBase` instances

    powers : list of ints

    Returns
    -------
    positives, negatives : tuple of lists
       Each element in each list is tuple of the form (*base*,
       *power*).  The negatives have the sign of their power reversed
       (i.e. the powers are all positive).
    """
    positive = []
    negative = []
    for base, power in zip(bases, powers):
        if power < 0:
            negative.append((base, -power))
        elif power > 0:
            positive.append((base, power))
        else:
            raise ValueError('Unit with 0 power')
    return positive, negative


def _itemsview_isdisjoint(view, other):
    """Return True if two sets have a null intersection."""
    for v in other:
        if v in view:
            return False
    return True


def copy_splines():
    """Copy selected splines to clipboard

    """
    pass


def pytest_addoption(parser):
    """ Adding repeat argument for parser. """
    parser.addoption('--repeat', action='store', help=
        'Number of times to repeat each test')


def __call__():
    """Render a layout template which is calling widget/render"""


def get_image_media_type(img_ext):
    """Return media type for image based on extension.
  """
    if '.' in img_ext:
        img_ext = img_ext.split('.')[-1]
    img_ext = img_ext.lower()
    assert img_ext in ['bmp', 'tiff', 'tif', 'png', 'jpg', 'jpeg'
        ], 'image format must be one of png, jpg, jpeg, tif, tiff, bmp.'
    if img_ext in ['jpg', 'jpeg']:
        return 'image/jpeg'
    if img_ext == 'png':
        return 'image/png'
    if img_ext in ['bmp']:
        return 'image/bmp'
    if img_ext in ['tif', 'tiff']:
        return 'image/tiff'


def graph_delete_knot():
    """Delete curve knots

    """
    pass


def ar_7(provider):
    """Issue P-DATA-TF PDU."""
    provider.dul_socket.send(provider.primitive.encode())
    return 'Sta8'


def loads(s):
    """Parse the ripple.txt file, return a dict of lists.
    """
    current_section = ''
    sections = {}
    for line in s.splitlines():
        if not line or line.startswith('#'):
            continue
        if line.startswith('[') and line.endswith(']'):
            current_section = sections.setdefault(line[1:-1], [])
            continue
        line = line.strip()
        if line:
            current_section.append(line)
    return sections


def add_non_tree_strings(strings, strings_to_add, add_separator=True):
    """
    Adding training stage strings
    to the experiment description

    Parameters
    ----------
    strings : list of strings
        description of the experiment
    strings_to_add : dict of lists of strings
        new information to add to the experiment
    add_separator : bool
        make pretty separation line
        at the end of this strings (Default value = True)

    Returns
    -------
    strings : list of strings
        description of the experiment
    """
    separation_string = ''
    for id_string in range(len(strings_to_add[0])):
        string = ' '
        for id_stage, value in strings_to_add.items():
            string += value[id_string] + ' | '
            if len(separation_string) < len(string):
                separation_string += '─' * (len(value[id_string]) + 2) + '+'
        string = string[:-3]
        strings.append(string)
    if add_separator:
        strings.append(separation_string[:-3])
    return strings


def published_news_items():
    """Returns 5 most recently published News Items in reverse
           chronological order
        """


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

    The ".dev0" means dirty.

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


@staticmethod
def configuration_key_prefix():
    """Return "detector"."""
    return 'detector'


def bed_heater_control(percent):
    """ Hot bed heater control.
    :param percent: heater power in percent 0..100. 0 turns heater off.
    """
    pass


def exp(input):
    """Returns a new tensor with the exponential of the elements of the input tensor `input`.

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

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


def positive_int(x) ->int:
    """
    Checks that the provided input is a positive integer. Used for PID
    validation in the CLI arguments.

    Parameters
    ----------
    x
        A positive integer

    Returns
    -------

    """
    x = int(x)
    if x < 0:
        raise ValueError('A positive integer is expected')
    return x


def rect(T):
    """create a centered rectangular pulse of width $T"""
    return lambda t: (-T / 2 <= t) & (t < T / 2)