@classmethod
def from_file(cls, handle, name=None):
    """
        Load the *k*-mer profile from a file.

        :arg h5py.File handle: Open readable *k*-mer profile file handle.
        :arg str name: Profile name.

        :return: A *k*-mer profile.
        :rtype: Profile
        """
    name = name or sorted(handle['profiles'].keys())[0]
    counts = handle['profiles/' + name][:]
    return cls(counts, name=name)


def add_attachment(filename, data):
    """
        Add a binary attachment.
        Can be called multiple times to attach multiple files.
        """


def update_default_level(default_level):
    """Update the logging level for logger.

    Parameters
    ----------
    default_level: const int
        A value in the set {logging.DEBUG, logging.INFO, logging.WARNING,
        logging.ERROR, logging.CRITICAL}
    """
    global DEFAULT_LEVEL
    DEFAULT_LEVEL = default_level


def _noprint(*args, **kwargs):
    """Do nothing with the arguments. Used for suppressing print output."""


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


def append_index_id(id, ids):
    """
    add index to id to make it unique wrt ids
    """
    index = 1
    mod = '%s_%s' % (id, index)
    while mod in ids:
        index += 1
        mod = '%s_%s' % (id, index)
    ids.append(mod)
    return mod, ids


def do_insertions(insertions, tokens):
    """
    Helper for lexers which must combine the results of several
    sublexers.

    ``insertions`` is a list of ``(index, itokens)`` pairs.
    Each ``itokens`` iterable should be inserted at position
    ``index`` into the token stream given by the ``tokens``
    argument.

    The result is a combined token stream.

    TODO: clean up the code here.
    """
    insertions = iter(insertions)
    try:
        index, itokens = next(insertions)
    except StopIteration:
        for item in tokens:
            yield item
        return
    realpos = None
    insleft = True
    for i, t, v in tokens:
        if realpos is None:
            realpos = i
        oldi = 0
        while insleft and i + len(v) >= index:
            tmpval = v[oldi:index - i]
            yield realpos, t, tmpval
            realpos += len(tmpval)
            for it_index, it_token, it_value in itokens:
                yield realpos, it_token, it_value
                realpos += len(it_value)
            oldi = index - i
            try:
                index, itokens = next(insertions)
            except StopIteration:
                insleft = False
                break
        yield realpos, t, v[oldi:]
        realpos += len(v) - oldi
    while insleft:
        realpos = realpos or 0
        for p, t, v in itokens:
            yield realpos, t, v
            realpos += len(v)
        try:
            index, itokens = next(insertions)
        except StopIteration:
            insleft = False
            break


def _tablerow(option, indentaion=0):
    """Return a reST list-table row describing an :class:`Option`."""
    spaces = ' ' * indentaion
    return (
        '{}- * {{0}}\n{}  * ``{{1}}``\n{}  * .. _option_{{0}}:\n\n{}    {{2}}'
        .format(*(4 * (spaces,))).format(option.name, str(option.default),
        '\n{}    '.format(spaces).join(option.description.splitlines())))


def save(content, path, binary=False):
    """Save the provided content in a file"""
    if binary:
        mode = 'wb'
    else:
        mode = 'w'
    fd = open(path, mode)
    fd.write(content)
    fd.close()


def hms(s):
    """
    conversion of seconds into hours, minutes and secondes
    :param s:
    :return: int, int, float
    """
    h = int(s) // 3600
    s %= 3600
    m = int(s) // 60
    s %= 60
    return '{:d}:{:d}:{:.2f}'.format(h, m, s)


def assign(data, K, pairwise_operation):
    """Assign list values of an iterable to a numpy array while calculating a pairwise operation."""
    for d in data:
        K[d[0][0], d[0][1]] = pairwise_operation(d[1][0], d[1][1])


def calc_duration(audio, rate):
    """Calculates the length of the audio in seconds.
    params:
        audio: A numpy ndarray, which has 1 dimension and values within
               -1.0 to 1.0 (inclusive)
        rate: An integer, which is the rate at which samples are taken
    return: A float
    """
    return audio.size / rate


@classmethod
def tostring(cls, familyenum):
    """!Gets a string representation of a FileCipherFamily enum value.
        @param
            familyenum (int): File type enumeration

        @return
            A text string containing a short label for the enum
        """
    stringlookup = {cls.UNKNOWN: 'unknown', cls.GENERIC: 'generic', cls.
        AUTO: 'auto', cls.PDF: 'pdf', cls.CSV: 'csv', cls.CMS: 'cms'}
    return stringlookup.get(familyenum, 'unknown')


def _one_crosscorr(seq, window, scale):
    """Private function used for calculating cross-correlated pydpi_py3 for 1 given sequence, window and an AA scale.
    This function is used by the :py:func:`calculate_crosscorr` method of :py:class:`PeptideDescriptor`.

    :param seq: {str} amino acid sequence to calculate descriptor for
    :param window: {int} correlation-window size
    :param scale: {str} amino acid scale to be used to calculate descriptor
    :return: {numpy.array} calculated descriptor data
    """
    try:
        m = list()
        for l in range(len(seq)):
            m.append(scale[str(seq[l])])
        seqdesc = list()
        for val in range(len(scale['A'])):
            for cc in range(len(scale['A'])):
                if val + cc < len(scale['A']):
                    for dist in range(window):
                        cntr = float()
                        valsum = list()
                        for pos in range(len(seq)):
                            if pos + dist < len(seq):
                                cntr += 1
                                valsum.append(m[pos][val] * m[pos + dist][
                                    val + cc])
                        seqdesc.append(sum(valsum) / cntr)
        return seqdesc
    except ZeroDivisionError:
        print(
            'ERROR!\nThe chosen correlation window % i is larger than the sequence %s !'
             % (window, seq))


@classmethod
def process(cls, *, context=None, parameter=None):
    """ Evaluate the PUSH command. """
    context.stack.append(int(parameter['param'], 2))


@staticmethod
def _map_preds(pred):
    """Map the predicted label to another integer or char to be written
        to .csv file"""
    if pred == 0:
        res = 'w'
    elif pred == 1:
        res = 'n'
    elif pred == 2:
        res = 'r'
    else:
        res = pred.cpu().numpy() - 2
    return str(res)


def isGeoreferenceable():
    """Returns True if an object is Georeferenceable

        :returns: return True if context can be geo referenced
        :rtype: boolean
        """


@classmethod
def text(cls):
    """A factory method that creates a :class:`Permissions` with all
        "Text" permissions from the official Discord UI set to True."""
    return cls(523328)


def hdbscan(X, min_cluster_size=5, gen_min_span_tree=True, **kwargs):
    """Clustering with Hierarchical DBSCAN.

    Parameters
    ----------
    X : array-like
         n x k attribute data
    min_cluster_size : int, default: 5
        the minimum number of points necessary to generate a cluster
    gen_min_span_tree : bool
        Description of parameter `gen_min_span_tree` (the default is True).
    kwargs

    Returns
    -------
    fitted cluster instance: hdbscan.hdbscan.HDBSCAN

    """
    try:
        from hdbscan import HDBSCAN
    except ImportError:
        raise ImportError(
            'You must have the hdbscan package installed to use this function')
    model = HDBSCAN(min_cluster_size=min_cluster_size)
    model.fit(X)
    return model


@classmethod
def get_transactions_by_addresses(cls, addresses):
    """Gets latest 50 transactions in dict related to an address.

        :param addresses: bch addresse(s)
        :type addresses: ``str`` or ''list'' of ''str''
        :raises ConnectionError: If all API services fail.
        :rtype: ``list'' of ``dict``
        :return: All transactions in dict related to the address
        """
    for api_call in cls.GET_TXS_BY_ADDRESSES:
        try:
            return api_call(addresses)
        except cls.IGNORED_ERRORS:
            pass
    raise ConnectionError('All APIs are unreachable.')


def spaced_bin_int(intg):
    """binint to human readable string conversion."""
    bs = '{:096b}'.format(intg)
    spaced_str = bs[0:16] + ' ' + bs[16:32] + ' ' + bs[32:48] + ' ' + bs[48:64
        ] + ' ' + bs[64:80] + ' ' + bs[80:96]
    return spaced_str


def _idnaBytes(text):
    """
    Convert some text typed by a human into some ASCII bytes.

    This is provided to allow us to use the U{partially-broken IDNA
    implementation in the standard library <http://bugs.python.org/issue17305>}
    if the more-correct U{idna <https://pypi.python.org/pypi/idna>} package is
    not available; C{service_identity} is somewhat stricter about this.

    @param text: A domain name, hopefully.
    @type text: L{unicode}

    @return: The domain name's IDNA representation, encoded as bytes.
    @rtype: L{bytes}
    """
    try:
        import idna
    except ImportError:
        return text.encode('idna')
    else:
        return idna.encode(text)


def FileDlgFixExt(dlg, file):
    """this is needed to fix a problem in linux wx.FileDialog"""
    ext = dlg.GetWildcard().split('|')[2 * dlg.GetFilterIndex() + 1].strip('*')
    if ext not in file:
        file += ext
    return file


def str_lowerstrip(s):
    """
    把字符串进行lower跟strip操作
    """
    return s.lower().strip() if s else ''


def get_inkscape_path():
    """ Return the Inkscape path """
    from six.moves import winreg
    try:
        svgexepath = winreg.QueryValue(winreg.HKEY_LOCAL_MACHINE,
            'Software\\Classes\\svgfile\\shell\\Inkscape\\command')
    except OSError:
        svgexepath = winreg.QueryValue(winreg.HKEY_LOCAL_MACHINE,
            'Software\\Classes\\inkscape.svg\\shell\\open\\command')
    svgexepath = svgexepath.replace('"%1"', '')
    return svgexepath.replace('"', '')


def options(configuration):
    """ A single place to add program options """
    configuration.add_option('api.host', default='0.0.0.0', help_string=
        'The host address to bind to')
    configuration.add_option('api.port', default=9005, special_type=int,
        help_string='The host address to bind to')
    configuration.add_option('api.inventory.inventory_router',
        '--api-inventory-router', default='tcp://127.0.0.1:9000',
        help_string='The inventory router url')
    configuration.add_option('api.rpc.rpc_router', '--api-rpc-router',
        default='tcp://127.0.0.1:9001', help_string='The RPC router url')
    configuration.add_option('api.paging.limit', default=250, special_type=
        int, help_string='The number of return results')
    configuration.add_option('api.paging.offset_id', default=None,
        help_string='The paging offset id')
    configuration.add_option('api.paging.sort_direction', default=1,
        special_type=int, help_string=
        'The paging sort direction, default is 1 (ascending)')
    configuration.add_option('api.logging.log_file', default=
        'mercury-api.log', help_string='The log file path')
    configuration.add_option('api.logging.level', default='DEBUG',
        help_string='The app log level')
    configuration.add_option('api.logging.console_out', default=True,
        special_type=bool, help_string='Stream log output to the console')


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

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

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


@staticmethod
def use_fatal_exceptions():
    """Return True if use fatal exceptions by raising them."""
    return False


def sample_categorical(probas, rng):
    """
    Sample from a Categorical(probas) distribution.
    """
    cdf = probas.cumsum()
    u = rng.rand(probas.shape[0])
    return (u < cdf).argmax()


def strip_grid_from_method_docstring(funcs):
    """Remove 'grid' from the parameters of a dict of functions' docstrings.

    Note that the docstring must be close to numpydoc standards for this to
    work.

    Parameters
    ----------
    funcs : dict
        Dictionary of functions to modify. Keys are the function names,
        values are the functions themselves.

    Examples
    --------
    >>> from landlab.grid.mappers import dummy_func_to_demonstrate_docstring_modification as dummy_func
    >>> funcs = {'dummy_func_to_demonstrate_docstring_modification':
    ...          dummy_func}
    >>> help(dummy_func)
    Help on function dummy_func_to_demonstrate_docstring_modification in module landlab.grid.mappers:
    <BLANKLINE>
    dummy_func_to_demonstrate_docstring_modification(grid, some_arg)
        A dummy function to demonstrate automated docstring changes.
    <BLANKLINE>
        Parameters
        ----------
        grid : ModelGrid
            A Landlab modelgrid.
        some_arg : whatever
            A dummy argument.
    <BLANKLINE>
        Examples
        --------
        ...
    <BLANKLINE>
    >>> strip_grid_from_method_docstring(funcs)
    >>> help(dummy_func)
    Help on function dummy_func_to_demonstrate_docstring_modification in module landlab.grid.mappers:
    <BLANKLINE>
    dummy_func_to_demonstrate_docstring_modification(grid, some_arg)
        A dummy function to demonstrate automated docstring changes.
    <BLANKLINE>
        Parameters
        ----------
        some_arg : whatever
            A dummy argument.
    <BLANKLINE>
        Examples
        --------
        ...
    <BLANKLINE>
    """
    import re
    for name, func in funcs.items():
        func.__doc__ = re.sub('grid *:.*?\n.*?\n *', '', func.__doc__)
        match_2_lines = re.search(func.__name__ +
            '\\(grid,[^\\)]*?\\n.*?\\)', func.__doc__)
        try:
            lines_were = match_2_lines.group()
        except AttributeError:
            pass
        else:
            end_chars = re.search('    .*?\\)', lines_were).group()[4:]
            lines_are_now = re.sub('    .*?\\)', '         ' + end_chars,
                lines_were)
            func.__doc__ = func.__doc__[:match_2_lines.start()
                ] + lines_are_now + func.__doc__[match_2_lines.end():]
        func.__doc__ = re.sub(func.__name__ + '\\(grid, ', 'grid.' + func.
            __name__ + '(', func.__doc__)


def attach_subscriptions(obj, dispatcher):
    """
    Attach subscriptions to an actual event dispatcher.

    :param object obj:
    :param EventDispatcher dispatcher:
    :return:
    """
    for k in dir(obj):
        f = getattr(obj, k)
        if k[0] != '_' and callable(f) and hasattr(f, '__subscriptions__'):
            for event_id, priority in f.__subscriptions__.items():
                dispatcher.add_listener(event_id, f, priority=priority)


def face_flip(faces):
    """Flip the faces direction.

    :param face: Face to flip.
    :type face: 'bmesh.types.BMFace'
    """
    pass


def prtOptions():
    """Print a list of command-line options and arguments."""
    print('The command-line options are:')
    print('  --version (print the version number and exit)')
    print('  -r (print the full version string and exit)')
    print('  -v (verbose)')
    print('  -t (print timestamps)')
    print('')
    print('Following the options, list one or more input file names,')
    print('  enclosed in quotes if more than one file name is specified')
    print('  and/or if wildcards are used.')
    print('One or more output file names may be specified (the same number')
    print('  as the input file names).')


def setup_survey_pages(form_model, survey_pages):
    """
    Helper function to set up a list of survey pages with a common form model
    (a dynamically generated survey model class).
    """
    for i, page in enumerate(survey_pages):
        page.setup_survey(form_model, i)


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


def _rssify_author(author):
    """
    Convert author from whatever it is to a plain old email string for
    use in an RSS 2.0 feed.
    """
    if type(author) is dict:
        return author.get('email', None)
    elif '@' in author and '.' in author:
        return author
    else:
        return None


def result_max_ge_CurResult_combination(condition_money, max, productListA,
    result_moeny, condition, number):
    """
    判断组合商品金额是否大于当前倍数
    :param condition_money: 满足条件的金额
    :param max: 倍数
    :param productListA:可以参与活动的商品
    :param result_moeny: 当前金额
    :param condition: 满足条件
    :param number: 控制是组合2还是组合1用于判断
    :return:
    """
    for product in productListA:
        for seat in product.productSeatList:
            if result_moeny // condition_money > max:
                return 'ok'
            if seat.seat == False and seat.is_run_other_pro == True:
                result_moeny += getattr(seat, condition)
            if number == 1:
                if hasattr(seat, 'intersection2'):
                    result_moeny += getattr(seat, condition)
    if result_moeny // condition_money > max:
        return 'ok'
    else:
        return 'off'


def unindent():
    """Delete 4 spaces from line beginning

    """
    pass


def select_pipes(pipes):
    """
    Select pipes which have the same load as the first pipe of the dataframe
    *pipes*.

    Parameters
    ----------
    pipes: DataFrame
        Dataframe of the TST pipes.

    Returns
    -------
    DataFrame
        Dataframe of the selected pipes (same load as the first pipe).
    """
    load = pipes.at[0, 'load']
    pipes_selection = pipes.loc[pipes['load'] == load].copy()
    return pipes_selection


def _format_blockstr(long_line):
    """ Wraps a urlsafe ghid.
    """
    shortened_length = 36
    indent = '    '
    out = []
    for slice_start in range(0, len(long_line), shortened_length):
        out.append(indent + long_line[slice_start:slice_start +
            shortened_length])
    return '\n'.join(out)


@classmethod
def none(cls):
    """Returns a null object version of :class:`CommandResult`

        Returns:
            ExecutionResult: with all values set to 0 or None
        """
    return cls(0, 0, None)


def get_tile_start_end_index(tile_number, tile_size, tile_offset=None,
    tile_separation=None):
    """Calculate the starting and ending index along a single dimension"""
    if not tile_separation:
        tile_separation = tile_size
    if not tile_offset:
        tile_offset = 0
    start_index = tile_number * tile_separation + tile_offset
    end_index = start_index + tile_size
    return start_index, end_index


@classmethod
def process_ray_collision_contacts(cls, ray, other_geom, contacts):
    """Process special case of collision between a ray and a regular geom.

		.. seealso::
		   For regular geoms collision, see :meth:`process_collision_contacts`.

		Since rays have no attached body, they can't "really" collide
		with other geoms. However, they do intersect, which is of
		interest to non-physical aspects of the simulation. A common
		use case is that of laser distance sensors.

		.. warning::
		   Collision between two rays is a singularity and should never happen.

		:param ray:
		:type ray: type of :attr:`Ray.inner_object`
		:param other_geom:
		:type other_geom: type of :attr:`Geom.inner_object`
		:param contacts: collision data returned by :meth:`calc_collision`
		:type contacts: list of contact data objects

		"""
    raise NotImplementedError()


def create_field_image(fieldmodule, image_filename, name='image'):
    """
    Create an image field using the given fieldmodule.  The image filename must exist and
    be a known image type.

    :param fieldmodule: The fieldmodule to create the field in.
    :param image_filename: Image filename.
    :param name: Optional name of the image field, defaults to 'image'.
    :return: The image field created.
    """
    image_field = fieldmodule.createFieldImage()
    image_field.setName(name)
    image_field.setFilterMode(image_field.FILTER_MODE_LINEAR)
    stream_information = image_field.createStreaminformationImage()
    stream_information.createStreamresourceFile(image_filename)
    image_field.read(stream_information)
    return image_field


def loopfirstlast(iterable):
    """
    A function combining `firstloop` and` lastloop`.

    Yield True if the first and last element of the iterator object,
    False otherwise.
    """
    it = iterable
    last_index = len(it) - 1
    for i, val in enumerate(it):
        yield i == 0 or i == last_index, val


def kpathstr_to_xticks(path):
    """Split path into individual labels"""
    tick_labels = []
    combine_labels = False
    for i, char in enumerate(path):
        if char not in [',', '|', ' ']:
            if combine_labels:
                tick_labels[-1] = tick_labels[-1] + '|' + char
                combine_labels = False
                tick_labels.append('')
            else:
                tick_labels.append(char)
        else:
            combine_labels = True
    return tick_labels


def _set_node_metadata(ptr, token, names, lengths):
    """Inplace update of names and lengths given token details"""
    name = None
    length = 0.0
    if token.startswith(':'):
        length = float(token[1:])
    elif ':' in token:
        name, length = token.rsplit(':', 1)
        length = float(length)
        name = name.replace("'", '').replace('"', '')
    else:
        name = token.replace("'", '').replace('"', '')
    names[ptr] = name
    lengths[ptr] = length


@classmethod
def set_fields(cls, category, products):
    """ Sets the base_fields on this _ProductsForm to allow selecting
        from the provided products. """
    pass


def intersect_line_line_2d(lineA_p1: 'mathutils.Vector', lineA_p2:
    'mathutils.Vector', lineB_p1: 'mathutils.Vector', lineB_p2:
    'mathutils.Vector') ->'mathutils.Vector':
    """Takes 2 segments (defined by 4 vectors) and returns a vector for their point of intersection or None.

    :param lineA_p1: First point of the first line
    :type lineA_p1: 'mathutils.Vector'
    :param lineA_p2: Second point of the first line
    :type lineA_p2: 'mathutils.Vector'
    :param lineB_p1: First point of the second line
    :type lineB_p1: 'mathutils.Vector'
    :param lineB_p2: Second point of the second line
    :type lineB_p2: 'mathutils.Vector'
    :return:  The point of intersection or None when not found
    """
    pass


def write_predictions(identifier2prediction, filepath):
    """
    Create a predictions file.

    Parameters
    ----------
    identifier2prediction : Dict[str, str]
        Map an identifier (as used in write_gt) to a prediction.
        The prediction is a single class, not a distribution.
    filepath : str
        Write to this CSV file.
    """
    with open(filepath, 'w') as f:
        for identifier, prediction in identifier2prediction.items():
            f.write('{};{}\n'.format(identifier, prediction))


def get_dataset_fields(datasetdescr):
    """
    splits the dataset type descriptor and provides each individual member

    Parameters
    ----------
    datasetdescr : str
        dataset type. Format : [processing level]:[dataset type]

    Returns
    -------
    proclevel : str
        dataset processing level

    dataset : str
        dataset type, i.e. dBZ, ZDR, ISO0, ...

    """
    descrfields = datasetdescr.split(':')
    if len(descrfields) == 1:
        proclevel = 'l00'
        dataset = descrfields[0]
    else:
        proclevel = descrfields[0]
        dataset = descrfields[1]
        if len(proclevel) == 2:
            proclevel = proclevel[0] + '0' + proclevel[1]
    return proclevel, dataset


def sorted_list_indexes(list_to_sort, key=None, reverse=False):
    """
    Sorts a list but returns the order of the index values of the list for the sort and not the values themselves.
    For example is the list provided is ['b', 'a', 'c'] then the result will be [2, 1, 3]

    :param list_to_sort: list to sort
    :param key: if not None then a function of one argument that is used to extract a comparison key from each
                list element
    :param reverse: if True then the list elements are sorted as if each comparison were reversed.
    :return: list of sorted index values
    """
    if key is not None:

        def key_func(i):
            return key(list_to_sort.__getitem__(i))
    else:
        key_func = list_to_sort.__getitem__
    return sorted(range(len(list_to_sort)), key=key_func, reverse=reverse)


def versions(configuration):
    """Displays all the versions of a named configuration

    :param ElementTree configuration: the configuration document whose versions should be displayed.
    """
    v = configuration.find('default-version')
    if None == v or None == v.text:
        defaultUrl = None
        defaultNote = ''
    else:
        defaultUrl = v.text
        defaultNote = ' (* indicates the default version)'
    v = configuration.findall('known-versions/known-version')
    print('Currently active version for configuration "' + configuration.
        find('name').text + '"' + defaultNote)
    for vers in v:
        if defaultUrl == vers.find('uri').text:
            header = '* '
        else:
            header = '  '
        if None == vers.find('description') or None == vers.find('description'
            ).text:
            descriptionToUse = ''
        else:
            descriptionToUse = ': ' + vers.find('description').text
        print(header + vers.find('name').text + descriptionToUse)
    print()


def queue_as_list(queue):
    """
    Get all the items in the queue as a `list` without removing them.

    Note: This was designed for `Queue.Queue`. Don't try to use this, for
    example, on `multiprocessing.Queue`.
    """
    with queue.mutex:
        return list(queue.queue)


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 find_atm_si_multiplicators(atm_containers):
    """
    Get atm flux and wavelength multiplicator from `atm_containers`.
    It assume, all containers have the same multiplicators, so it returns values from first one.

    :param atm_containers: List[AtmDatacontainer];
    :return: Tuple[float, float];

    ::

        (flux multiplicator, wavelength multiplicator)

    """
    for atm_container in atm_containers:
        return atm_container.flux_to_si_mult, atm_container.wave_to_si_mult
    raise ValueError(
        'No valid atmospheric container has been supplied to method.')


def dictSort(d):
    """returns a dictionary sorted by keys

    >>> d = {"a": "1", "b": "3", "c": "2"}

    >>> dictSort(d)
    {'a': '1', 'c': '2', 'b': '3'}
    """
    our_list = d.items()
    our_list.sort()
    k = {}
    for item in our_list:
        k[item[0]] = item[1]
    return k


@classmethod
def _new1(cls, rate, *args):
    """
        This method returns a single instance of the UGen, not multichannel
        expanded. It is called inside _multi_new_list, whenever a new single
        instance is needed.
        """
    obj = cls()
    obj._rate = rate
    obj._add_to_synth()
    return obj._init_ugen(*args)


def n_hours(intervalstring):
    """
    Convert an interval string like 1D, 6H etc. to the
    number of hours it represents.
    """
    multid = {'H': 1, 'D': 24}
    multi = multid[intervalstring[-1].upper()]
    hours = multi * int(intervalstring[:-1])
    return hours


def local(name, catalog=None):
    """
    Create a session spec for connecting to a store on the local server.

    :param name: Store name.
    :type name: string
    :param catalog: Catalog name (None = root catalog).
    :type catalog: string
    :return: A session spec string.
    :rtype: string
    """
    if catalog:
        return '<%s:%s>' % (catalog, name)
    else:
        return '<%s>' % name


@staticmethod
def get_common(data: list, account_id: str, file_id: int, replay_date: str
    ) ->list:
    """
        Extracts the common data from the battle replay.
        """
    raw_data = data[0]['common']
    response = [{'replay_date': replay_date, 'file_id': file_id,
        'account_id': account_id, 'division': raw_data.get('division', None
        ), 'gui_type': raw_data.get('guiType', None), 'arena_create_time':
        raw_data.get('arenaCreateTime', None), 'duration': raw_data.get(
        'duration', None), 'arena_type_id': raw_data.get('arenaTypeID',
        None), 'gas_attack_winner_team': raw_data.get('gasAttackWinnerTeam',
        None), 'winner_team': raw_data.get('winnerTeam', None),
        'veh_lock_mode': raw_data.get('vehLockMode', None), 'bonus_type':
        raw_data.get('bonusType', None)}]
    return response


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

        :param TeamMergeRequestSentShownToSecondaryTeamType val:
        :rtype: EventType
        """
    return cls('team_merge_request_sent_shown_to_secondary_team', val)


@staticmethod
def set_list_index(data, index, value):
    """Set value in list at specified index.
        All the values before target index should stay unchanged
        or be filled with None.
        :param data: List where value should be set
        :param index: String or Int of target index
        :param value: Target value to put under index
        """
    for _ in range(len(data), int(index) + 1):
        data.append(None)
    else:
        data[int(index)] = value


def read_multiline_str_from_stdin():
    """Read a multi-line string from STDIN"""
    input_string = ''
    while True:
        try:
            line = input()
            input_string += '{}\n'.format(line)
        except EOFError:
            return input_string


def coefficient_fmc(friction_force, normal_force):
    """Usage: Find friction coefficent using force of friction and normal force"""
    return friction_force / normal_force


def add_topology_args(parser):
    """Add arguments for specifying SpiNNaker machine topologies and their
	folding."""
    topology_group = parser.add_argument_group('machine topology dimensions')
    system_size_group = topology_group.add_mutually_exclusive_group(required
        =True)
    system_size_group.add_argument('--num-boards', '-n', type=int, metavar=
        'N', help="build the 'squarest' system with this many boards")
    system_size_group.add_argument('--triads', '-t', type=int, nargs=2,
        metavar=('W', 'H'), help=
        'build a system with the specified number of triads of boards in each dimension (yielding 3*W*H boards)'
        )
    folding_group = parser.add_argument_group('topology folding options')
    folding_group.add_argument('--transformation', '-T', choices=['shear',
        'slice'], help=
        'the transformation function to use from hexagonal torus to rectangular Cartesian grid (selected automatically if omitted)'
        )
    folding_group.add_argument('--uncrinkle-direction', choices=['columns',
        'rows'], help=
        'direction in which to uncrinkle the hexagonal mesh to form a regular grid (default: rows)'
        )
    folding_group.add_argument('--folds', '-F', type=int, nargs=2, default=
        None, metavar=('X', 'Y'), help=
        'the number of pieces to fold into in each dimension (default: (2, 2)) ignored if --transformation is not given'
        )


@staticmethod
def get(context):
    """Get source object from a given source context."""
    return context['job'].table


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

        :param str val:
        :rtype: ResendSecondaryEmailResult
        """
    return cls('rate_limited', val)


def classify_commute(trip):
    """
    Count the time spent commuting between either home and work or home and study.

    :param `py:class:Trip` trip: An itinerum-tripkit trip object
    """
    commute_label = None
    if trip.start.label == 'home':
        if trip.end.label == 'work':
            commute_label = 'work'
        elif trip.end.label == 'study':
            commute_label = 'study'
    elif trip.start.label == 'work' and trip.end.label == 'home':
        commute_label = 'work'
    elif trip.start.label == 'study' and trip.end.label == 'home':
        commute_label = 'study'
    return commute_label


@classmethod
def delete_rule(cls, sec_group_rule_id, context, region_name):
    """Deletes a rule from an existing security group."""
    driver = cls.get_driver(context, region_name)
    driver.delete_security_group_rule(sec_group_rule_id)


def set_selected_solo_rhythm(c_2, current_bar_num):
    """sets solo rhythm type depending on bar number and number of bars in current part"""
    if c_2['num_bars_in_part'] == 1:
        c_2['selected_solo_rhythm'] = c_2['solo_rhythm'][c_2['double_select']]
    elif c_2['num_bars_in_part'] == 2:
        if current_bar_num == 0:
            c_2['selected_solo_rhythm'] = c_2['solo_rhythm'][c_2[
                'intro_select']]
        else:
            c_2['selected_solo_rhythm'] = c_2['solo_rhythm'][c_2['end_select']]
    elif c_2['num_bars_in_part'] == 3:
        if current_bar_num == 0:
            c_2['selected_solo_rhythm'] = c_2['solo_rhythm'][c_2[
                'intro_select']]
        elif current_bar_num == c_2['num_bars_in_part'] - 1:
            c_2['selected_solo_rhythm'] = c_2['solo_rhythm'][c_2['end_select']]
        else:
            c_2['selected_solo_rhythm'] = c_2['solo_rhythm'][c_2[
                'double_select']]
    elif c_2['num_bars_in_part'] >= 4:
        if current_bar_num == 0:
            c_2['selected_solo_rhythm'] = c_2['solo_rhythm'][1]
        elif current_bar_num == c_2['num_bars_in_part'] - 1:
            c_2['selected_solo_rhythm'] = c_2['solo_rhythm'][2]
        else:
            c_2['selected_solo_rhythm'] = c_2['solo_rhythm'][c_2[
                'double_select']]


def select_less():
    """Deselect keyframes on ends of selection islands

    """
    pass


def get_route_name(request):
    """ Get a route name from URL Dispatch or Traversal """
    if request.matched_route:
        return request.matched_route.name.lower()
    else:
        try:
            ctx_class = request.context.__class__
        except AttributeError:
            return None
        ctx_name = ctx_class.__name__
        ctx_module = ctx_class.__module__.rsplit('.', 1)[-1]
        route_name = '%s_%s' % (ctx_module, ctx_name)
        return route_name.lower()


def effective(ticket, resource, costunit):
    """ Returns the effective worked time of the given ticket, resource and cost unit
        """


def exec_result(obj, local, stream):
    """Reproduce default exec behavior (print and builtins._)"""
    local['_'] = obj
    if obj is not None:
        print(repr(obj), file=stream)


def check_wanted(zelf, *args, **kwargs):
    """ whether an thing is desired. """
    want = args[0]
    for key, value in want.items():
        if key == 'format':
            continue
        if key not in zelf:
            continue
        if value.startswith('-'):
            continue
        if value not in str(zelf[key]):
            return False
    return True


def update_translations(icu_file, form_changes):
    """
    Takes in a ``mobetta.icu.models.IcuFile`` object and a list of changes to
    apply.

    Format of changes:
        [
            (<form>, [
                {
                'msgid': <msgid>,
                'field': '<field_name>',
                'from': '<old_value>',
                'to': '<new_value>',
                },
                ...
            ]),
            ...
        ]
    """
    applied_changes = []
    rejected_changes = []
    for form, changes in form_changes:
        for change in changes:
            key = change['msgid']
            if key not in icu_file.contents:
                raise RuntimeError('Entry not found')
            if change['field'] == 'translation':
                if change['from'] == icu_file.contents[key]:
                    icu_file.contents[key] = change['to']
                    applied_changes.append((form, change))
                else:
                    change['current_value'] = icu_file.contents[key]
                    rejected_changes.append((form, change))
            else:
                raise RuntimeError('Unexpected field changed!')
    return applied_changes, rejected_changes


def aDay():
    """Return the abreviated name of the day of the week"""


def addItems(action, targets):
    """Add new items to the clipboard"""


def AutoPredict(scan_object, x_val, y_val, x_pred, task, metric='val_acc',
    n_models=10, folds=5, shuffle=True, asc=False):
    """Automatically handles the process of finding the best models from a
    completed `Scan()` experiment, evaluates those models, and uses the winner
    to make predictions on input data.

    NOTE: the input data must be in same format as 'x' that was
    used in `Scan()`.

    Parameters
    ----------
    scan_object : Scan() object
        A Scan() process needs to be completed first, and then the resulting
        object can be used as input here.
    x_val : ndarray or list of ndarray
        Data to be used for 'x' in evaluation. Note that should be in the same
        format as the data which was used in the Scan() but not the same data.
    y_val : ndarray or list of ndarray
        Data to be used for 'y' in evaluation. Note that should be in the same
        format as the data which was used in the Scan() but not the same data.
    y_pred : ndarray or list of ndarray
        Input data to be used for the actual predictions in evaluation. Note
        it should be in the same format as the data which was used in the
        Scan() but not the same data.
    task : string
        'binary', 'multi_class', 'multi_label', or 'continuous'.
    metric : str
        The metric to be used for deciding which models are promising.
        Basically the 'n' argument and 'metric' argument are combined to pick
        'n' best performing models based on 'metric'.
    n_models : str
        Number of promising models to be included in the evaluation process.
        Time increase linearly with number of models.
    folds : int
        Number of folds to be used in cross-validation.
    shuffle : bool
        If the data should be shuffled before cross-validation.
    average : str
        This parameter is required for multiclass/multilabel targets. If None,
        the scores for each class are returned. Otherwise, this determines
        the type of averaging performed on the data:

        'binary':
        Only report results for the class specified by pos_label.
        This is applicable only if targets (y_{true,pred}) are binary.

        'micro':
        Calculate metrics globally by counting the total true positives,
        false negatives and false positives.

        'macro':
        Calculate metrics for each label, and find their unweighted mean.
        This does not take label imbalance into account.

        'weighted':
        Calculate metrics for each label, and find their average weighted
        by support (the number of true instances for each label). This alters
        'macro' to account for label imbalance; it can result in an F-score
        that is not between precision and recall.

        'samples':
        Calculate metrics for each instance, and find their average
        (only meaningful for multilabel classification where this differs
        from accuracy_score).
    asc : bool
        This needs to be True for evaluation metrics that need to be minimized,
        and False when a metric needs to be maximized.

    """
    scan_object.evaluate_models(x_val, y_val, n_models=n_models, task=task,
        metric=metric, folds=folds, shuffle=shuffle, asc=False)
    scan_object.preds_model = scan_object.best_model('eval_f1score_mean')
    scan_object.preds_probabilities = scan_object.preds_model.predict(x_pred)
    scan_object.preds_classes = scan_object.preds_model.predict_classes(x_pred)
    scan_object.preds_parameters = scan_object.data.sort_values(
        'eval_f1score_mean', ascending=False).iloc[0]
    print(
        '>> Added model, probabilities, classes, and parameters to scan_object'
        )
    return scan_object


def ctx4(**kw):
    """swap to four-armed context"""


@classmethod
def breakline(cls):
    """Creates breakline Chunk.

    Returns:
      A chunk (:obj:`budou.chunk.Chunk`)
    """
    chunk = cls(u'\n', cls._BREAK_POS)
    return chunk


def generate_random_spec():
    """generate_random_spec is the main function to generate a random
    spec file. Depending on the file, a different command (eg package
    manager) will be run to download software.
    """
    print('Vanessa needs to write me!')


def AllDifferent(members):
    """
    DisjointClasses(' description description { description } ')'

    """
    pass


def jwt_create_response_payload(token, user=None, request=None, issued_at=None
    ):
    """
    Return data ready to be passed to serializer.

    Override this function if you need to include any additional data for
    serializer.

    Note that we are using `pk` field here - this is for forward compatibility
    with drf add-ons that might require `pk` field in order (eg. jsonapi).
    """
    return {'pk': issued_at, 'token': token}


def to_whole_minutes(seconds):
    """Divide `seconds` by 60 to convert to whole minutes."""
    minutes = seconds // 60
    return minutes


def file_format(path):
    """
    Return corresponding file format for a file
    (loop through all the lines, get maximum matched dictionary key)
    usage: input(file path)
    Format Usage with double equal  in control flow ==
    'Window(LF|CR)'  -> for Window MS(dos)
    'Unix/MacOS(LF)' -> for Linux, MacOS
    'Macintosh(CR)' -> for Older version of MacOS
    'Unknown' -> Undefined format
    """
    with open(path, 'rb') as f:
        carriage_dict = {'Unknown': 0, 'Window': 0, 'Linux': 0, 'Macintosh': 0}
        for index, line in enumerate(f, 1):
            if b'\r\n' in line:
                carriage_dict['Window'] += 1
            elif b'\n' in line:
                carriage_dict['Linux'] += 1
            elif b'\r' in line:
                carriage_dict['Macintosh'] += 1
            else:
                carriage_dict['Unknown'] += 1
        return max(carriage_dict, key=carriage_dict.get)


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


def validate_minmax_axis(axis):
    """
    Ensure that the axis argument passed to min, max, argmin, or argmax is
    zero or None, as otherwise it will be incorrectly ignored.

    Parameters
    ----------
    axis : int or None

    Raises
    ------
    ValueError
    """
    ndim = 1
    if axis is None:
        return
    if axis >= ndim or axis < 0 and ndim + axis < 0:
        raise ValueError(
            f'`axis` must be fewer than the number of dimensions ({ndim})')


def _spvec2pow(specvec):
    """Convert a spectrum envelope into a power

    Parameters
    ----------
    specvec : vector, shape (`fftlen / 2 + 1`)
        Vector of specturm envelope |H(w)|^2

    Return
    ------
    power : scala,
        Power of a frame

    """
    fftl2 = len(specvec) - 1
    fftl = fftl2 * 2
    power = specvec[0] + specvec[fftl2]
    for k in range(1, fftl2):
        power += 2.0 * specvec[k]
    power /= fftl
    return power


def districts_within_tolerance(partition, attribute_name='population',
    percentage=0.1):
    """Check if all districts are within a certain percentage of the "smallest"
    district, as defined by the given attribute.

    :param partition: partition class instance
    :param attrName: string that is the name of an updater in partition
    :param percentage: what percent difference is allowed
    :return: whether the districts are within specified tolerance
    :rtype: bool
    """
    if percentage >= 1:
        percentage *= 0.01
    values = partition[attribute_name].values()
    max_difference = max(values) - min(values)
    within_tolerance = max_difference <= percentage * min(values)
    return within_tolerance


def assert_list_data(value: list) ->None:
    """Asserts value is list type."""
    assert isinstance(value, list
        ), f'Input value type must be a list. Actual type: {type(value)}, value: {value}'


def order_cancel_success(message, futures):
    """Intercepts order cancel messages (oc) and check for
    Future objets with a matching cid.

    Parameters
    ----------
    message : str
        The unaltered response message returned by bitfinex.
    futures : dict
        A dict of intercept_id's and future objects.
        dict{intercept_id, future_object}

    """
    order_id = message[2][0]
    order_cid = message[2][2]
    future_id = f'oc_{order_id}'
    future_id_cid = f'oc_{order_cid}'
    if future_id in futures.keys():
        future = futures[future_id]
    elif future_id_cid in futures.keys():
        future = futures[future_id_cid]
    if message[2][13] == 'IOC CANCELED':
        future.set_result({'status': 'IOC CANCELED', 'id': message[2][0],
            'cid': message[2][2], 'response': message[2], 'comment': None})
    else:
        future.set_result({'status': 'SUCCESS', 'id': message[2][0], 'cid':
            message[2][2], 'response': message[2], 'comment': None})
    if future_id in futures:
        del futures[future_id]
    elif future_id_cid in futures:
        del futures[future_id_cid]


def stripEncaseQuotes(strFile):
    """
    Strip single quote at start and end of file name
    if they are found

    Args:
        strFile (str): file name

    Returns:
        str:

        file name without start and end single quoute
    """
    s = str(strFile)
    if s[0:1] == "'" and s[-1:] == "'":
        s = s[1:-1]
    return s


def convert_to(data, inunit, outunit, inplace_units=False, key=None):
    """
    Converts data from one unit to the other

    Parameters
    -----------
    data: pandas.series
        to be chanhed from one unit to the other
    inunit: pint.quantity or dict
        unit(s) that the data is in
    outunit: str
        convert to this unit
    inplace_units: bool
        if inunit is a dict, the dict is update in place. "key" keyword must be provided
    key: str
        if inunit is a dict, it is the name of the variable to be changed
    """
    from .. import Q_
    if key:
        Q = inunit[key].to(outunit)
    else:
        Q = inunit.to(outunit)
    coef = Q.magnitude
    outunit = Q.units
    if inplace_units:
        inunit.update({key: outunit})
        return data * coef
    else:
        return data * coef, outunit


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

    The ".dev0" means dirty.

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


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


def simulate_flat(detector, exposure, source):
    """Simulate a FLAT array,"""
    detector.expose(source=source, time=exposure)
    final = detector.readout()
    return final


def render_widget(widget, name):
    """ render the widget with this skin
        """


def get_client_useragent(request):
    """
    Returns the user agent, if present, from request meta
    """
    return request.META.get('HTTP_USER_AGENT', None)


def write2file(fp, text):
    """Helper to write to a file."""
    with open(fp, 'w') as f:
        f.write(text)


@staticmethod
def p_maybespace(symbols):
    """maybespace : SPACE
                      | empty
        """
    symbols[0] = None


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

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


def set_flag(request, flag_name, active=True, session_only=False):
    """Set a flag value on a request object."""
    if not hasattr(request, 'waffles'):
        request.waffles = {}
    request.waffles[flag_name] = [active, session_only]


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

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


def exgcd(a, b):
    """
    Bézout coefficients (u,v) of (a,b) as:

        a*u + b*v = gcd(a,b)

    Result is the tuple: (u, v, gcd(a,b)). Examples:

    >>> exgcd(7*3, 15*3)
    (-2, 1, 3)
    >>> exgcd(24157817, 39088169)    #sequential Fibonacci numbers
    (-14930352, 9227465, 1)

    Algorithm source: Pierre L. Douillet
    http://www.douillet.info/~douillet/working_papers/bezout/node2.html
    """
    u, v, s, t = 1, 0, 0, 1
    while b != 0:
        q, r = divmod(a, b)
        a, b = b, r
        u, s = s, u - q * s
        v, t = t, v - q * t
    return u, v, a


def create_mount_target(FileSystemId=None, SubnetId=None, IpAddress=None,
    SecurityGroups=None):
    """
    Creates a mount target for a file system. You can then mount the file system on EC2 instances via the mount target.
    You can create one mount target in each Availability Zone in your VPC. All EC2 instances in a VPC within a given Availability Zone share a single mount target for a given file system. If you have multiple subnets in an Availability Zone, you create a mount target in one of the subnets. EC2 instances do not need to be in the same subnet as the mount target in order to access their file system. For more information, see Amazon EFS: How it Works .
    In the request, you also specify a file system ID for which you are creating the mount target and the file system's lifecycle state must be available . For more information, see  DescribeFileSystems .
    In the request, you also provide a subnet ID, which determines the following:
    After creating the mount target, Amazon EFS returns a response that includes, a MountTargetId and an IpAddress . You use this IP address when mounting the file system in an EC2 instance. You can also use the mount target's DNS name when mounting the file system. The EC2 instance on which you mount the file system via the mount target can resolve the mount target's DNS name to its IP address. For more information, see How it Works: Implementation Overview .
    Note that you can create mount targets for a file system in only one VPC, and there can be only one mount target per Availability Zone. That is, if the file system already has one or more mount targets created for it, the subnet specified in the request to add another mount target must meet the following requirements:
    If the request satisfies the requirements, Amazon EFS does the following:
    Each Amazon EFS mount target has one corresponding requester-managed EC2 network interface. After the network interface is created, Amazon EFS sets the NetworkInterfaceId field in the mount target's description to the network interface ID, and the IpAddress field to its address. If network interface creation fails, the entire CreateMountTarget operation fails.
    We recommend you create a mount target in each of the Availability Zones. There are cost considerations for using a file system in an Availability Zone through a mount target created in another Availability Zone. For more information, see Amazon EFS . In addition, by always using a mount target local to the instance's Availability Zone, you eliminate a partial failure scenario. If the Availability Zone in which your mount target is created goes down, then you won't be able to access your file system through that mount target.
    This operation requires permissions for the following action on the file system:
    This operation also requires permissions for the following Amazon EC2 actions:
    See also: AWS API Documentation

    Examples
    This operation creates a new mount target for an EFS file system.
    Expected Output:

    :example: response = client.create_mount_target(
        FileSystemId='string',
        SubnetId='string',
        IpAddress='string',
        SecurityGroups=[
            'string',
        ]
    )

    :type FileSystemId: string
    :param FileSystemId: [REQUIRED]
            ID of the file system for which to create the mount target.

    :type SubnetId: string
    :param SubnetId: [REQUIRED]
            ID of the subnet to add the mount target in.

    :type IpAddress: string
    :param IpAddress: Valid IPv4 address within the address range of the specified subnet.

    :type SecurityGroups: list
    :param SecurityGroups: Up to five VPC security group IDs, of the form sg-xxxxxxxx . These must be for the same VPC as subnet specified.
            (string) --

    :rtype: dict
    :return: {
        'OwnerId': 'string',
        'MountTargetId': 'string',
        'FileSystemId': 'string',
        'SubnetId': 'string',
        'LifeCycleState': 'creating'|'available'|'deleting'|'deleted',
        'IpAddress': 'string',
        'NetworkInterfaceId': 'string'
    }

    :returns:
    Must belong to the same VPC as the subnets of the existing mount targets
    Must not be in the same Availability Zone as any of the subnets of the existing mount targets

    """
    pass


def camel_case_to_lower_case_underscore(text):
    """
    Converts camel case string to underscore separate string
    :param text: str, string to convert
    :return: str
    """
    words = list()
    char_pos = 0
    for curr_char_pos, char in enumerate(text):
        if char.isupper() and char_pos < text:
            words.append(text[char_pos:curr_char_pos].lower())
            char_pos = curr_char_pos
    words.append(text[char_pos:].lower())
    return '_'.join(words)


@staticmethod
def dtype(x):
    """Enforce a homogeneous string datatype."""
    return str(x)


def overlap(t1start, t1end, t2start, t2end):
    """
    Find if two date ranges overlap.

    Parameters
    ----------
    datastart, dataend : datetime, float
        Observation start and end datetimes.
    modelstart, modelend : datetime, float
        Observation start and end datetimes.

    Returns
    -------
    overlap : bool
        True if the two periods overlap at all, False otherwise.

    References
    ----------
    Shamelessly copied from http://stackoverflow.com/questions/3721249

    """
    return t1start <= t2start <= t1end or t2start <= t1start <= t2end


def nicenumber(x):
    """
    Return a nice number close to x.
    """
    if x == 0:
        return x
    n = 1.0
    while x > 10:
        x /= 10
        n *= 10
    while x < 1:
        x *= 10
        n /= 10
    return int(x) * n


@classmethod
def conf(cls, proj, prefix, source_dir, build_dir, env, build_type,
    builder_args, args):
    """Calls configure using setuptools."""
    return True


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

        :param AccountCaptureChangePolicyDetails val:
        :rtype: EventDetails
        """
    return cls('account_capture_change_policy_details', val)


def func_upper(parser, text):
    """Returns ``text`` in upper case."""
    return text.upper()


@staticmethod
def __gettype(obj):
    """
        python 3 returns <class 'something'> instead of <type 'something'>.
        For backward compatibility, we replace class with type.
        """
    return str(type(obj)).replace('class', 'type')


@staticmethod
def can_unpack_subitems(value):
    """
        Function that confirms / decides on input data a known list.
        If so, then unpack_subitems can be used afterwards.

        Example::

            def parse_response(self, response):
                for parser in self.get_parsers():
                    if parser.can_unpack_subitems(response):
                        yield from parser.unpack_subitems(response)

        """
    return False


def suggestDType(x):
    """Return a suitable dtype for x"""
    if isinstance(x, list) or isinstance(x, tuple):
        if len(x) == 0:
            raise Exception('can not determine dtype for empty list')
        x = x[0]
    if hasattr(x, 'dtype'):
        return x.dtype
    elif isinstance(x, float):
        return float
    elif isinstance(x, int):
        return int
    else:
        return object


def get_sconstruct_dir(the_env):
    """Returns the directory containing the SConstruct file."""
    return the_env.Dir(the_env.fs.SConstruct_dir)


def str2float(s):
    """Convert variable string to float."""
    try:
        return float(s)
    except ValueError:
        significand, exponent = s[:-4], s[-4:]
        return float('{}e{}'.format(significand, exponent))


def format_hex(row_hash, col_hash, size=8):
    """Format dhash integers as hex string of size*size//2 total hex digits
    (row_hash and col_hash concatenated).

    >>> format_hex(19409, 14959, size=4)
    '4bd13a6f'
    >>> format_hex(1, 2, size=4)
    '00010002'
    """
    hex_length = size * size // 4
    return '{0:0{2}x}{1:0{2}x}'.format(row_hash, col_hash, hex_length)


def _gap_insert_sort(lst, start, gap):
    """Shell sort helper function"""
    for i in range(start + gap, len(lst), gap):
        cur_val = lst[i]
        cur_pos = i
        while cur_pos >= gap and lst[cur_pos - gap] > cur_val:
            lst[cur_pos] = lst[cur_pos - gap]
            cur_pos = cur_pos - gap
        lst[cur_pos] = cur_val


def convert_falselike_to_bool(input_item, convert_int=False, convert_float=
    False):
    """Converts false-like values ("false", 0, FALSE", "FALSCH", etc) to python boolean False.

    Taken from korbinian python package by Mark Teese. This is allowed under the permissive MIT license.

    Parameters
    ----------
    input_item : string or int
        Item to be converted to bool (e.g. "FALSE", 0, "FALSCH" or the equivalent in several languagues)
    convert_float: bool
        Convert floats to bool.
        If True, "0.0" will be converted to True

    Returns
    -------
    return_value : False, or input_item
        If input_item is False-like, returns python bool False. Otherwise, returns the input_item.

    Usage
    -----
    # convert a single value or string
    convert_falselike_to_bool("false")
    # convert a column in a pandas DataFrame
    df["column_name"] = df["column_name"].apply(convert_falselike_to_bool)
    """
    list_False_items = [False, 'False', 'false', 'FALSE', 'F', 'f',
        'falsch', 'FALSCH', 'valse', 'lažna', 'fals', 'NEPRAVDA', 'falsk',
        'vals', 'faux', 'pa vre', 'tsis tseeb', 'hamis', 'palsu', 'uongo',
        'ngeb', 'viltus', 'klaidinga', 'falz', 'falso', 'USANN',
        'wartosc false', 'falošné', 'falskt', 'yanlis', 'sai', 'ffug',
        'VALSE', 'LAŽNA', 'FALS', 'FALSK', 'VALS', 'FAUX', 'PA VRE',
        'TSIS TSEEB', 'HAMIS', 'PALSU', 'UONGO', 'NGEB', 'VILTUS',
        'KLAIDINGA', 'FALZ', 'FALSO', 'WARTOSC FALSE', 'FALOŠNÉ', 'FALSKT',
        'YANLIS', 'SAI', 'FFUG']
    if convert_int:
        list_False_items += [0, '0']
    if convert_float:
        list_False_items += [0.0, '0.0']
    return_value = False if input_item in list_False_items else input_item
    return return_value


def list_datasets():
    """
  list all known datasets
  :return:
  """
    return list(iter())


def define_expression(DomainName=None, Expression=None):
    """
    Configures an `` Expression`` for the search domain. Used to create new expressions and modify existing ones. If the expression exists, the new configuration replaces the old one. For more information, see Configuring Expressions in the Amazon CloudSearch Developer Guide .
    See also: AWS API Documentation

    :example: response = client.define_expression(
        DomainName='string',
        Expression={
            'ExpressionName': 'string',
            'ExpressionValue': '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).

    :type Expression: dict
    :param Expression: [REQUIRED]
            A named expression that can be evaluated at search time. Can be used to sort the search results, define other expressions, or return computed information in the search results.
            ExpressionName (string) -- [REQUIRED]Names must begin with a letter and can contain the following characters: a-z (lowercase), 0-9, and _ (underscore).
            ExpressionValue (string) -- [REQUIRED]The expression to evaluate for sorting while processing a search request. The Expression syntax is based on JavaScript expressions. For more information, see Configuring Expressions in the Amazon CloudSearch Developer Guide .

    :rtype: dict
    :return: {
        'Expression': {
            'Options': {
                'ExpressionName': 'string',
                'ExpressionValue': 'string'
            },
            'Status': {
                'CreationDate': datetime(2015, 1, 1),
                'UpdateDate': datetime(2015, 1, 1),
                'UpdateVersion': 123,
                'State': 'RequiresIndexDocuments'|'Processing'|'Active'|'FailedToValidate',
                'PendingDeletion': True|False
            }
        }
    }

    :returns:
    RequiresIndexDocuments : the option's latest value will not be deployed until  IndexDocuments has been called and indexing is complete.
    Processing : the option's latest value is in the process of being activated.
    Active : the option's latest value is completely deployed.
    FailedToValidate : the option value is not compatible with the domain's data and cannot be used to index the data. You must either modify the option value or update or remove the incompatible documents.

    """
    pass


def get_step(s, step_name):
    """Gets the Step object with the given name.

    Args:
      step_name: A string representing the name of the step from :py:meth:`Step.get_name`
    """
    return s._steps[step_name]


def _trash_ratio(text):
    """
    Return ratio of non-common symbols.
    """
    trash_count = 0
    for char in text:
        if char in list(u'.\'"+-!?()[]{}*+@#$%^&_=|/\\'):
            trash_count += 1
    return trash_count / float(len(text))


@classmethod
def setDefaultPanelClass(klass, other):
    """
        This method returns the Class used to open new object panels on double-click (TaurusDevicePanel by default)
        """
    klass._defaultClass = other


def setup_rpyc_namespace(connection: 'rpyc.core.protocol.Connection'):
    """
    setup_rpyc_namespace - Register certain modules and variables in the namespace
                           of cortexcontrol that will be needed for this module.
    :param connection:  RPyC connection to cortexcontrol.
    """
    connection.namespace['_USE_RPYC'] = True
    connection.namespace['copy'] = connection.modules.copy
    connection.namespace['os'] = connection.modules.os
    connection.namespace['ctxdynapse'] = connection.modules.CtxDynapse
    connection.namespace['rpyc'] = connection.modules.rpyc
    connection.namespace['tools'] = connection.modules.tools
    connection.namespace['params'] = connection.modules.params
    if 'initialized_chips' not in connection.modules.tools.storage.keys():
        connection.modules.tools.store_var('initialized_chips', [])
    else:
        print('dynapse_control: Already initialized chips: {}'.format(
            connection.modules.tools.storage['initialized_chips']))
    if 'initialized_neurons' not in connection.modules.tools.storage.keys():
        connection.modules.tools.store_var('initialized_neurons', [])
    print('dynapse_control: RPyC namespace complete.')


def extract_image_from_mjpeg(stream):
    """Take in a MJPEG stream object, return the jpg from it."""
    data = b''
    for chunk in stream:
        data += chunk
        jpg_end = data.find(b'\xff\xd9')
        if jpg_end == -1:
            continue
        jpg_start = data.find(b'\xff\xd8')
        if jpg_start == -1:
            continue
        return data[jpg_start:jpg_end + 2]


def read_input_from_file(file_path) ->str:
    """ Reads data from file path as a string.

    :param file_path: file path
    :type file_path: str
    :return: data
    :rtype: str
    """
    with open(file_path) as file:
        return file.read()


@staticmethod
def _get_or_add_xml_to_member(clsdict):
    """
        Add the xml -> enum value mapping to the enumeration class state
        """
    if '_xml_to_member' not in clsdict:
        clsdict['_xml_to_member'] = dict()
    return clsdict['_xml_to_member']


def version_micro():
    """
    Returns the package micro version
    as defined in configure.ac
    as integer
    """
    return 0


def defstyle(style=None):
    """
    Create a defs element that wraps a CSS style.

    Args:
        style (string): A CSS string.

    Returns:
        str (unicode in Python 2)
    """
    if style:
        return (u'<defs><style type="text/css"><![CDATA[{}]]></style></defs>'
            .format(style))
    else:
        return u'<defs />'


def duration(config_duration: str) ->int:
    """
    Convert the config duration to an integer.

    :param config_duration: The duration as a string
    :return: The duration as an integer
    """
    my_duration = int(config_duration)
    if my_duration < 1:
        raise ValueError('A slot must be at least 1 second long')
    return my_duration


def _for_id(sid):
    """Return a string specifying the object id for logger messages."""
    return " for '{0}'".format(sid)


def peer():
    """Obtain an object conforming to the ``peer`` interface."""


def set_name_h(name_x, name_q):
    """Set the full instruments names in regression; return generic name if user
    provides no explicit name."

    Parameters
    ----------
    name_x      : list of strings
                  User provided exogenous variable names.
    name_q      : list of strings
                  User provided instrument variable names.

    Returns
    -------
    name_h      : list of strings

    """
    return name_x + name_q


def pytest_runtest_setup(item):
    """ called before ``pytest_runtest_call(item)``. """


def listify_and_unify(*args):
    """util to handle listing together dict.keys() sequences"""
    out = []
    for x in args:
        if type(x) == list:
            out += x
        else:
            out += list(x)
    return sorted(list(set(out)))


def run_wf(wf, plugin='MultiProc', n_cpus=2, **plugin_kwargs):
    """ Execute `wf` with `plugin`.

    Parameters
    ----------
    wf: nipype Workflow

    plugin: str
        The pipeline execution plugin.
        See wf.run docstring for choices.

    n_cpus: int
        Number of CPUs to use with the 'MultiProc' plugin.

    plugin_kwargs: keyword argumens
        Keyword arguments for the plugin if using something different
        then 'MultiProc'.
    """
    if plugin == 'MultiProc' or n_cpus > 1:
        wf.run('MultiProc', plugin_args={'n_procs': n_cpus})
    elif not plugin or plugin is None or n_cpus <= 1:
        wf.run(plugin=None)
    else:
        wf.run(plugin=plugin, **plugin_kwargs)


def create_cryolo_v1_0_4_command(picking_name, file_input, file_output,
    settings, name):
    """Create the crYOLO v1.0.4 command"""
    command = []
    ignore_list = []
    ignore_list.append('Filter micrographs')
    ignore_list.append('Filter value high pass (A)')
    ignore_list.append('Filter value low pass (A)')
    ignore_list.append('Pixel size (A/px)')
    ignore_list.append('Box size')
    ignore_list.append('Split Gpu?')
    ignore_list.append('--gpu')
    command.append('{0}'.format(settings['Path'][picking_name]))
    command.append('-i')
    command.append('{0}'.format(' '.join(file_input)))
    command.append('-o')
    command.append('{0}'.format(file_output))
    command.append('--write_empty')
    if settings[picking_name]['Split Gpu?'] == 'True':
        try:
            gpu_id = int(name.split('_')[-1]) - 1
        except ValueError:
            gpu_id = 0
        try:
            gpu = settings[picking_name]['--gpu'].split()[gpu_id]
        except IndexError:
            raise UserWarning(
                'There are less gpus provided than threads available! Please restart with the same number of pipeline processors as GPUs provided and restart! Stopping this thread!'
                )
    else:
        gpu = settings[picking_name]['--gpu']
    command.append('--gpu')
    command.append('{0}'.format(gpu))
    for key in settings[picking_name]:
        if key in ignore_list:
            continue
        else:
            command.append(key)
            command.append('{0}'.format(settings[picking_name][key]))
    return ' '.join(command), gpu


def _mergeEntityList(A, B):
    """Return merged entityList os A and B."""
    for i in range(len(B)):
        for key, val in B[i].items():
            if key in A[i]:
                for item in val:
                    A[i][key].append(item)
            else:
                A[i][key] = val
    return A


def spin(center: float=(0.0, 0.0, 0.0), axis: float=(0.0, 0.0, 0.0)):
    """Extrude selected boundary row around pivot point and current view axis

    :param center: Center, Center in global view space
    :type center: float
    :param axis: Axis, Axis in global view space
    :type axis: float
    """
    pass


def coordinates_controlpanel_install(context):
    """Coordinates controlpanel script"""


def copy_to(input, ctx):
    """Copy the given tensor to the context.

    Parameters
    ----------
    input : Tensor
        The input tensor
    ctx :
        A framework-specific context object.

    Returns
    -------
    Tensor
        The tensor on the given context.
    """
    pass


@classmethod
def from_csl_item(cls, csl_item):
    """
        Create an Unpaywall object for `csl_item`.
        """
    from .csl_item import CSL_Item
    csl_item = CSL_Item(csl_item)
    doi = csl_item.get('DOI')
    if doi:
        return cls.from_citekey(f'doi:{doi}', csl_item=csl_item)
    csl_item.infer_id()
    return cls.from_citekey(csl_item['id'], csl_item=csl_item)


def get_number_of_lines_in_string(str_string):
    """Get number of not empty code lines in the string

    Parameters
    ----------

    Returns
    -------
    int
        Number of not empty code lines in the string
    """
    int_lines = 0
    for str_line in str_string.splitlines():
        if str_line.strip():
            int_lines += 1
    return int_lines


def fix_relative(html, url):
    """ this is fucking cheesy """
    try:
        base = '/'.join(url.split('/')[:3])
        html = html.replace("src='//", "src='http://")
        html = html.replace('src="//', 'src="http://')
        html = html.replace("src='/", "src='%s/" % base)
        html = html.replace('src="/', 'src="%s/' % base)
    except Exception as ex:
        pass
    return html


def module_names(path: str, recursive: bool=False) ->list:
    """Return a list of modules which can be imported from path.

    :param path: a directory to scan.
    :type path: str
    :param recursive: Also return submodule names for packages.
    :type recursive: bool
    :return:  a list of string pairs (module_name, module_file).
    """
    pass


@staticmethod
def format_value(value):
    """Format value for rendering."""
    if isinstance(value, float):
        return '{0:.1f}'.format(value)
    if isinstance(value, int):
        return '{0}'.format(value)
    if value is None:
        return ''
    if hasattr(value, 'to_value'):
        return value.to_value()
    return value


def _copy_future_state(source, dest):
    """Internal helper to copy state from another Future.

    The other Future may be a concurrent.futures.Future.
    """
    assert source.done()
    if dest.cancelled():
        return
    assert not dest.done()
    if source.cancelled():
        dest.cancel()
    else:
        exception = source.exception()
        if exception is not None:
            dest.set_exception(exception)
        else:
            result = source.result()
            dest.set_result(result)


def code_point_order(cp):
    """Ordering function for code points."""
    return cp if isinstance(cp, int) else cp[0]


def str2bool(value):
    """
    String to Boolean
    """
    return value.lower() in ('true', 't', '1')


def get_tasks_from_base_classes(bases, class_dict):
    """
    Function used by both TaskSetMeta and LocustMeta for collecting all declared tasks
    on the TaskSet/Locust class and all it's base classes
    """
    new_tasks = []
    for base in bases:
        if hasattr(base, 'tasks') and base.tasks:
            new_tasks += base.tasks
    if 'tasks' in class_dict and class_dict['tasks'] is not None:
        tasks = class_dict['tasks']
        if isinstance(tasks, dict):
            tasks = tasks.items()
        for task in tasks:
            if isinstance(task, tuple):
                task, count = task
                for i in range(count):
                    new_tasks.append(task)
            else:
                new_tasks.append(task)
    for item in class_dict.values():
        if 'locust_task_weight' in dir(item):
            for i in range(0, item.locust_task_weight):
                new_tasks.append(item)
    return new_tasks


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

    The ".dev0" means dirty.

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


def PrintMatchingResults(bestmat_list, stats_res_list):
    """
    print on stdout  matching results
    """
    print('\n-----------------------------------------')
    print('results:')
    print('matrix:                                         matching results')
    if len(stats_res_list) == 1 and len(bestmat_list) != 1:
        bestmat_list = [bestmat_list]
    for mat_elem, stat_elem in zip(bestmat_list, stats_res_list):
        mean_angular_residues = stat_elem[2]
        matching_rate = 100.0 * stat_elem[0] / stat_elem[1]
        for kkk in list(range(3)):
            txt = '%s        ' % str(mat_elem[kkk])
            if kkk == 0:
                txt += 'res: %s %.3f %.2f' % (str(stat_elem[:2]),
                    mean_angular_residues, matching_rate)
            if len(stat_elem) > 3:
                if kkk == 1:
                    txt += 'spot indices %s' % str(stat_elem[3])
                if kkk == 2:
                    txt += 'planes %s' % str(stat_elem[4].tolist())
            print('%s' % txt)
        print('')


def append_date_string(url, day_time, date_key=None, date_format='%Y-%m-%d',
    trailing_slash=False):
    """Add date string to the URL.

    >>> url = "https://mochart.com"
    >>> dt = datetime(2018, 11, 17)
    >>> append_date_string(url, dt)
    'https://mochart.com/2018-11-17'
    """
    dt_str = day_time.strftime(date_format)
    slash = ''
    if trailing_slash:
        slash = '/'
    if date_key:
        return f'{url}?{date_key}={dt_str}{slash}'
    return f'{url}/{dt_str}{slash}'


def mapRtoQ(ABCDr):
    """Map a real ABCD matrix to a quadrature one.

    **Parameters:**

    ABCDr : ndarray
        A real matrix describing a quadrature system.

    ``ABCDr`` has its states paired (real, imaginary).

    **Returns:**

    (ABCDq, ABCDp) : tuple

    Where:

    ABCDq : ndarray
        is the quadrature (complex) version of ABCDr.
    ABCDp : ndarray
        is the mirror-image system matrix.

    .. note:: ``ABCDp`` is zero if ``ABCDr`` has no quadrature errors.
    """
    ABCD11 = ABCDr[::2, ::2]
    ABCD12 = ABCDr[::2, 1::2]
    ABCD21 = ABCDr[1::2, ::2]
    ABCD22 = ABCDr[1::2, 1::2]
    ABCDq = 0.5 * (ABCD11 + ABCD22) + 0.5j * (ABCD21 - ABCD12)
    ABCDp = 0.5 * (ABCD11 - ABCD22) + 0.5j * (ABCD21 + ABCD12)
    return ABCDq, ABCDp


def bezout(a, b):
    """ bezout function finds a particular integer solution
    (u, v) to the diophantine equation a.u + b.v = gcd(a, b)
    Returns (u, v, gcd(a, b))
    Usage: bezout(5, 8) -> (-3, 2, 1)

    Implements extended Euclide's algorithm.

    :type a:    int
    :type b:    int (a and b not both 0)

    :return:  (u, v, gcd(a,b))
    :rtype:   int x3

    :Example:

    >>> bezout(0, 0)
    Traceback (most recent call last):
    ...
    ValueError: a and b shall not be both 0

    >>> bezout(7.8, 9)
    Traceback (most recent call last):
    ...
    ValueError: a and b shall be integers

    >>> bezout(120, 23); bezout(-120, 23); bezout(-120, -23); bezout(120, -23)
    (-9, 47, 1)
    (9, 47, 1)
    (9, -47, 1)
    (-9, -47, 1)
    >>> bezout(1, 10); bezout(1, -10); bezout(10, 1); bezout(-10, 1)
    (1, 0, 1)
    (1, 0, 1)
    (0, 1, 1)
    (0, 1, 1)
    >>> bezout(-1, 10); bezout(-1, -10); bezout(10, -1); bezout(-10, -1)
    (-1, 0, 1)
    (-1, 0, 1)
    (0, -1, 1)
    (0, -1, 1)
    >>> bezout(0, 10); bezout(0, -10); bezout(-10, 0); bezout(10, 0)
    (0, 1, 10)
    (0, -1, 10)
    (-1, 0, 10)
    (1, 0, 10)
    >>> bezout(1, 0); bezout(-1, 0)
    (1, 0, 1)
    (-1, 0, 1)
    >>> bezout(1, 1); bezout(-1, 1); bezout(1, -1); bezout(-1, -1)
    (0, 1, 1)
    (0, 1, 1)
    (0, -1, 1)
    (0, -1, 1)
    >>> def test_bezout(a, b):
    ...     u, v, g = bezout(a, b)
    ...     return a*u+b*v==g and g==gcd(a, b)
    >>> all(test_bezout(a, b)     for a in range(-1000, 2000, 99) for b in range(-1000, 1000, 51))
    True
    """
    if a == 0 and b == 0:
        raise ValueError('a and b shall not be both 0')
    if not type(a) is type(b) is int:
        raise ValueError('a and b shall be integers')
    sign_a = 1
    if a < 0:
        a = -a
        sign_a = -1
    sign_b = 1
    if b < 0:
        b = -b
        sign_b = -1
    if a == 0:
        return 0, sign_b, b
    if b == 0:
        return sign_a, 0, a
    u1, v1 = 1, 0
    u2, v2 = 0, 1
    while True:
        q, r = divmod(a, b)
        if r == 0:
            return sign_a * u2, sign_b * v2, b
        u1, v1, u2, v2 = u2, v2, u1 - q * u2, v1 - q * v2
        a, b = b, r


def compcolor(color):
    """Compute the complementary color of the given color.

    color: the color to be computed
    returns a RGB tuple.
    """
    return 255 - color[0], 255 - color[1], 255 - color[2]


def _parent_key(d):
    """
    Return the function path of the parent of function specified by 'id' in the given dict.
    """
    parts = d['id'].rsplit('|', 1)
    if len(parts) == 1:
        return ''
    return parts[0]


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

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

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

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

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

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

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

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

    Examples::

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

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

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

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

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

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


def _get_comparable_seq(seq_i, seq_j, start_phase, end_phase):
    """
    Return the residues of the exon/subexon that can be shared.

    It takes into account that first/last residue could be different
    if the start/end phase is different from 0 or -1.

    >>> _get_comparable_seq("ASMGSLTSSPSSL", "TSMGSLTSSPSSC", 1, 2)
    ('SMGSLTSSPSS', 'SMGSLTSSPSS')
    """
    if start_phase in [1, 2]:
        seq_i = seq_i[1:]
        seq_j = seq_j[1:]
    if end_phase in [1, 2]:
        seq_i = seq_i[:-1]
        seq_j = seq_j[:-1]
    return seq_i, seq_j


def upper_active_layer(da, is_ibound=True, include_constant_head=False):
    """
    Function to get the upper active layer from ibound xarray.DataArray

    Parameters
    ----------
    da : xarray.DataArray
        A 3D DataArray
    is_ibound: bool, optional
        If True, ``da`` is interpreted as ibound, with values 0: inactive, 1: active, -1 constant head.
        If False, ``upper_active_layer`` is interpreted as first layer that has data.
        Default is True.
    include_constant_head : bool, optional
        If True and ``is_ibound``, also include constant head cells.
        Default is False.

    Returns
    -------
    2d xr.DataArray of layernumber of upper active model layer
    """
    if is_ibound:
        if not da.astype(int).equals(da):
            raise ValueError(
                'Passed DataArray is no ibound, while is_bound was set to True'
                )
        if include_constant_head:
            is_active = da.fillna(0) != 0
        else:
            is_active = da.fillna(0) > 0
    else:
        is_active = ~da.isnull()
    da = is_active.layer.isel(layer=is_active.argmax(dim='layer'))
    da = da.drop('layer')
    return da.where(is_active.sum(dim='layer') > 0)


def make_pathable_string(s, replacewith='_'):
    """
    Removes symbols from a string to be compatible with directory structure.

    :param s: string
    """
    import re
    return re.sub('[^\\w+/.]', replacewith, s).replace('+', '_').replace(
        '/My_Drive/', '/My Drive/')


def add_text_before(elem, text):
    """ Add text before elem """
    prev = elem.getprevious()
    if prev is not None:
        prev.tail = (prev.tail or '') + text
    else:
        parent = elem.getparent()
        parent.text = (parent.text or '') + text


def rotatedXOR(values, width, rotator):
    """Rotated XOR cipher.
    """
    cs = 0
    for value in values:
        cs ^= value
        cs = rotator(cs)
    return cs % 2 ** width


def _get_order_and_prefix_from_prefix(prefix):
    """
    Convert a prefix into a numerical value.
    """
    prefix_from_prefix = None
    order_from_prefix = 0
    if not prefix:
        return prefix_from_prefix, order_from_prefix
    prefix_from_prefix = prefix
    if prefix[0] == '+':
        order_from_prefix = len(prefix)
    elif prefix[0] == '-':
        order_from_prefix = -len(prefix)
    else:
        order_from_prefix = prefix
    return prefix_from_prefix, order_from_prefix


def is_hsts(domain):
    """
    Domain has HSTS if its canonical HTTPS endpoint has HSTS.
    """
    canonical, https, httpswww = (domain.canonical, domain.https, domain.
        httpswww)
    if canonical.host == 'www':
        canonical_https = httpswww
    else:
        canonical_https = https
    return canonical_https.hsts


def _relative_time_string(time_seconds, no_ms=False):
    """Converts the given `time_seconds` into a relative, human-readable
    string representation.

    Args:
        time_seconds (int or float): The relative time to convert
        no_ms (bool): If set the `999ms` style representation is not chosen

    Returns:
        String: The string representation is chosen on the value of
                seconds to be either of the form `999ms`, `99.9s`,
                `59:59m`, or `99:59:59h`. If `None` is supplied, `-`
                is returned.
    """
    if time_seconds == None:
        return '-'
    milliseconds = int(time_seconds * 1000.0)
    if abs(milliseconds) < 1000 and not no_ms:
        return '%dms' % milliseconds
    seconds = time_seconds
    if abs(seconds) < 100.0:
        return '%.1fs' % seconds
    minutes = int(seconds / 60)
    seconds = abs(seconds - minutes * 60)
    if abs(minutes) < 60:
        return '%d:%02dm' % (minutes, seconds)
    hours = int(minutes / 60)
    minutes = abs(minutes - hours * 60)
    return '%d:%02d:%02dh' % (hours, minutes, seconds)


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


@classmethod
def is_request(cls, payload):
    """Returns True if the payload (which has a method) is a request.
        False means it is a notification."""
    return 'id' in payload


def start(st_reg_number):
    """Checks the number valiaty for the Piaui state"""
    divisor = 11
    if len(st_reg_number) > 9:
        return False
    if len(st_reg_number) < 9:
        return False
    sum_total = 0
    peso = 9
    for i in range(len(st_reg_number) - 1):
        sum_total = sum_total + int(st_reg_number[i]) * peso
        peso = peso - 1
    rest_division = sum_total % divisor
    digit = divisor - rest_division
    if digit == 10 or digit == 11:
        digit = 0
    return digit == int(st_reg_number[len(st_reg_number) - 1])


@classmethod
def _meta_get(cls, key, default=None):
    """Get value corresponding to key in meta data."""
    cls._meta_is_inited()
    return cls._meta.get(key, default)


def get_root_thematic_for_phase(phase):
    """Return root thematic for the given phase `phase`.
    """
    if phase.is_thematics_table:
        return phase.root_idea
    return phase.discussion.root_idea


def loopToWord(loop):
    """
    Write a loop in gap notation using the standard generators of pi_1(D).

    The return format is a list of integers with the following meaning:
        [1, -2] = x_1 x_2^{-1}
    ...where x_i (1 <= i <= n) is the anticlockwise loop around puncture i.

    By convention, path composition is left-to-right. That is, "x_1 x_2"
    means "follow x_1, then follow x_2".

    """
    if loop[0] < 0:
        raise NotImplementedError
    i = iter(loop)
    ans = []
    while True:
        try:
            up = i.next()
        except StopIteration:
            break
        down = -i.next()
        if down == up:
            continue
        elif down > up:
            down = -down
            up = -up
        else:
            down -= 1
            up -= 1
        ans.extend(range(up, down, -1))
    return ans


@staticmethod
def is_client_health(client):
    """Check health of the client
        """
    return client.check_health()


def _get_freq(name):
    """
    Check if name read contains counts (_xNumber)
    """
    try:
        counts = int(name.split('_x')[1])
    except:
        return 0
    return counts


def query_bunches(query, bunch_by):
    """
    Queries output by yield_per sqlalchemy function
    (which in a for loop returns rows one by one).
    Groups the query rows in bunches of bunch_by
    elements and returns list of bunches.
    :param query: sqlalchemy session query
    :param bunch_by: integer number
    :returns: [[bunch_of_tuples_1],[bunch_of_tuples_2],...]

    """
    filtered_bunches = []
    item_bunch = []
    for i in query.yield_per(bunch_by):
        if not isinstance(i, tuple) and not isinstance(i, list):
            item_bunch.append(i)
        else:
            item_bunch += i
        if len(item_bunch) % bunch_by == 0:
            filtered_bunches.append(item_bunch)
            item_bunch = []
    if item_bunch:
        filtered_bunches.append(item_bunch)
    return filtered_bunches


def neg_number(dash, number):
    """
        If a dash is provided, then the number is negative
        """
    if dash is not None:
        number = number * -1
    return number


def get_number_of_lines_in_string(str_string):
    """Get number of not empty code lines in the string

    Parameters
    ----------

    Returns
    -------
    int
        Number of not empty code lines in the string
    """
    int_lines = 0
    for str_line in str_string.splitlines():
        if str_line.strip():
            int_lines += 1
    return int_lines


def zeta_NH3_Ca_Cl_CB89(T, P):
    """n-c-a: ammonia calcium chloride [CB89]."""
    zeta = -0.00134
    valid = T == 298.15
    return zeta, valid


@classmethod
def append_unknown_error(cls, message, **kwds):
    """Unknown error is fatal and should break any further progress"""
    cls.append_message(message, message_type='unknown_error', **kwds)


def vertex_group_copy():
    """Make a copy of the active vertex group

    """
    pass


def _get_team(request, team_id):
    """Get team for the given team_id"""
    team = request.db.get_team(team_id=team_id)
    return team


@staticmethod
def has_battery() ->bool:
    """Return whether the device has a battery."""
    return False


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

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

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


def add():
    """Add a new time marker

    """
    pass


def directory_new(directory: str='', open: bool=False):
    """Create a new directory

    :param directory: Directory, Name of new directory
    :type directory: str
    :param open: Open, Open new directory
    :type open: bool
    """
    pass


@staticmethod
def _get_numpy_expr(expr):
    """Extracts numpy operations from the overall string representation."""
    if expr[:5] == 'log10':
        return 5, 'log10'
    for idx, char in enumerate(expr):
        if not char.isalpha():
            if char.isnumeric():
                raise ValueError('invalid expression')
            return idx, expr[:idx]


def try_raising(value):
    """Try to raise an exception from option in the first place.
    Raises from classes (e.g. ValueError)
    or exception objects (e.g. ValueError('Incorrect value!'))

    If that fails, returns the value itself.
    """
    if value is TypeError or isinstance(value, TypeError):
        raise value
    try:
        raise value
    except TypeError:
        return value


def generate_units_header_unpack_variables(m, l, t, I, T) ->dict:
    """
    Generates the unit dictionaries with the:

    mass, length, time, current, and temperature

    units respectively.
    """
    units = {'boxsize': l, 'mass_table': m}
    return units


def _gcd(a, b):
    """
    Return greatest common divisor using Euclid's Algorithm.
    """
    if a == 0:
        return b
    if b == 0:
        return a
    while b:
        a, b = b, a % b
    return abs(a)


@classmethod
def register_rule(cls, rule_func):
    """Utility function used by the register_rule decorator to register a
        lambda/function to instantiate a rule."""
    cls._rules_factories.append(rule_func)


def network_status(neutron_status):
    """Translate neutron network status.

    :param neutron_status: neutron status
    """
    if neutron_status == 'ACTIVE':
        return 'active'
    else:
        return 'inactive'


def _pad(word: str, max_len: int) ->bytes:
    """Pad a word out so the byte representation is max_len.

    Args:
        word: The word we are padding out and converting to binary
        max_len: How far to pad the string

    Returns:
        The word as bytes and extended.
    """
    byte_words = word.encode('utf-8')
    return byte_words + b' ' * (max_len - len(byte_words))


@staticmethod
def construct_default_dict():
    """Construct default predicate definition as it would be written in the configuration file."""
    return {'name': 'alwaysTrue'}


def _check_fastq_read(read, read_index):
    """ This is a helper function for validing a single fastq read. It returns
        a list of all errors for this read. It is not intended for external use.
    """
    errors = []
    identifier_line_number = read_index * 4
    sequence_line_number = read_index * 4 + 1
    sequence_len = len(read[1])
    if sequence_len == 0:
        msg = (
            'ERROR on Line {}: Raw Sequence is shorter than the min read length: 0'
            .format(sequence_line_number))
        errors.append(msg)
    plus_line_number = read_index * 4 + 2
    quality_line_number = read_index * 4 + 3
    quality_len = len(read[2])
    if quality_len != sequence_len:
        msg = (
            'ERROR on Line {}: Quality string length ({}) does not equal raw sequence length ({})'
            .format(quality_line_number, quality_len, sequence_len))
        errors.append(msg)
    return errors


def down(f, c):
    """Find the negative values in the series.

    Parameters
    ----------
    f : pandas.DataFrame
        Dataframe containing the column ``c``.
    c : str
        Name of the column in the dataframe ``f``.

    Returns
    -------
    new_column : pandas.Series (bool)
        The array containing the new feature.

    """
    new_column = f[c] < 0
    return new_column


@classmethod
def index(cls, value):
    """Return an index into the Enum given a value."""
    return cls.ALL.index(value)


def req_cycle(req):
    """is this requirement cyclic?"""
    cls = req.__class__
    seen = {req.name}
    while isinstance(req.comes_from, cls):
        req = req.comes_from
        if req.name in seen:
            return True
        else:
            seen.add(req.name)
    return False