def calc_hit_ratio_start_time_cache_size_subprocess(order,
    break_points_share_array, reuse_dist_share_array, q, **kwargs):
    """
    the child process for calculating hit rate of different cache size with different starting time, but fixed end time,
    and each child process will calculate for a column with a given starting time
    :param q:
    :param reuse_dist_share_array:
    :param break_points_share_array:
    :param order: the order of column the child is working on
    :return: a list of result in the form of (x, y, hit_ratio) with x as fixed value(starting time), y as cache size
    """
    max_rd = kwargs['max_rd']
    bin_size = kwargs['bin_size']
    result_list = []
    rd_distribution = [0] * int(max_rd // bin_size + 1)
    for i in range(break_points_share_array[order],
        break_points_share_array[-1]):
        rd_distribution[reuse_dist_share_array[i] // bin_size] += 1
    num_of_total_request = break_points_share_array[-1
        ] - break_points_share_array[order]
    accum = 0
    for i in range(len(rd_distribution)):
        accum += rd_distribution[i]
        result_list.append((order, i, accum / num_of_total_request))
    q.put(result_list)


def copyfile(source, destination, CHUNK_SIZE=4096):
    """Copies from one file object to another.
    """
    while True:
        chunk = source.read(CHUNK_SIZE)
        if chunk:
            destination.write(chunk)
        if len(chunk) != CHUNK_SIZE:
            break


def removeReader(reader):
    """
        Removes an object previously added with L{addReader}.

        @return: L{None}.
        """


@classmethod
def _convert_postmark_to_native(cls, message):
    """Converts Postmark message API field names to their corresponding
        :class:`Message` attribute names.

        :param message: Postmark message data, with API fields using Postmark
            API names.
        :type message: `dict`
        """
    d = {}
    for dest, src in cls._fields.items():
        if src in message:
            d[dest] = message[src]
    return d


@staticmethod
def list_url(mlist):
    """See `IArchiver`."""
    return None


def _get(isamAppliance, id):
    """
    Internal function to get data using "id" - used to avoid extra calls

    :param isamAppliance:
    :param id:
    :return:
    """
    return isamAppliance.invoke_get('Retrieve a specific mapping rule',
        '/iam/access/v8/mapping-rules/{0}'.format(id))


def lower_camel_case_from_underscores(string):
    """Generate a lower-cased camelCase string from an underscore_string"""
    components = string.split('_')
    string = components[0].lower()
    for component in components[1:]:
        string += component[0].upper() + component[1:].lower()
    return string


def replace_spaces(m):
    """ this functions is workaround for python sre exception "unmatched groups"
  """
    out = ''
    for g in m.groups():
        if g:
            out += g
    return out


def copy(CopySource=None, Bucket=None, Key=None, ExtraArgs=None, Callback=
    None, SourceClient=None, Config=None):
    """
    Copy an object from one S3 location to another.
    This is a managed transfer which will perform a multipart copy in
    multiple threads if necessary.
    :

    :example: import boto3
    s3 = boto3.resource('s3')
    copy_source = {
        'Bucket': 'mybucket',
        'Key': 'mykey'
    }
    s3.meta.client.copy(copy_source, 'otherbucket', 'otherkey')

    :type CopySource: dict
    :param CopySource: The name of the source bucket, key name of the
            source object, and optional version ID of the source object. The
            dictionary format is:
            {'Bucket': 'bucket', 'Key': 'key', 'VersionId': 'id'}. Note
            that the VersionId key is optional and may be omitted.

    :type Bucket: str
    :param Bucket: The name of the bucket to copy to

    :type Key: str
    :param Key: The name of the key to copy to

    :type ExtraArgs: dict
    :param ExtraArgs: Extra arguments that may be passed to the
            client operation

    :type Callback: method
    :param Callback: A method which takes a number of bytes transferred to
            be periodically called during the copy.

    :type SourceClient: botocore or boto3 Client
    :param SourceClient: The client to be used for operation that
            may happen at the source object. For example, this client is
            used for the head_object that determines the size of the copy.
            If no client is provided, the current client is used as the client
            for the source object.

    :type Config: boto3.s3.transfer.TransferConfig
    :param Config: The transfer configuration to be used when performing the
            copy.

    """
    pass


@classmethod
def generate_from_tuple(cls, t):
    """
            Same as generate, but takes all parameters as one tuple
        """
    cls.generate(*t)


def flatten_list(sth):
    """Convert the argument in a list, being an empty list if none"""
    if sth is not None:
        if not isinstance(sth, (list, tuple)):
            sth = [sth]
    else:
        sth = []
    return sth


def interpolate_context(command, context):
    """
    Given a single hook command and a dict of context names/values, interpolate the values by
    "{name}" into the command and return the result.
    """
    for name, value in context.items():
        command = command.replace('{%s}' % name, str(value))
    return command


def make_markdown_table(array: list, title=None):
    """把数组转为markdown格式的字符串
    :array: [['title', 'value'], ['asd', '1']]
    """
    if title:
        array.insert(0, title)
    markdown = '\n' + str('| ')
    for e in array[0]:
        to_add = ' ' + str(e) + str(' |')
        markdown += to_add
    markdown += '\n'
    markdown += '|'
    for i in range(len(array[0])):
        markdown += str('-------------- | ')
    markdown += '\n'
    for entry in array[1:]:
        markdown += str('| ')
        for e in entry:
            to_add = str(e) + str(' | ')
            markdown += to_add
        markdown += '\n'
    return markdown + '\n'


def previewrange_set(xmin: int=0, xmax: int=0, ymin: int=0, ymax: int=0,
    wait_for_input: bool=True):
    """Interactively define frame range used for playback

    :param xmin: X Min
    :type xmin: int
    :param xmax: X Max
    :type xmax: int
    :param ymin: Y Min
    :type ymin: int
    :param ymax: Y Max
    :type ymax: int
    :param wait_for_input: Wait for Input
    :type wait_for_input: bool
    """
    pass


def get_id(sensorid, feedtag, feedname, feedid, feeduserid):
    """Return unique identifier for feed / sensor."""
    return f'emoncms{sensorid}_{feedtag}_{feedname}_{feedid}_{feeduserid}'


def tune(scale, acc_rate):
    """
    Tunes the scaling parameter for the proposal distribution
    according to the acceptance rate over the last tune_interval:

    Rate    Variance adaptation
    ----    -------------------
    <0.001        x 0.1
    <0.05         x 0.5
    <0.2          x 0.9
    >0.5          x 1.1
    >0.75         x 2
    >0.95         x 10

    """
    if acc_rate < 0.001:
        scale *= 0.1
    elif acc_rate < 0.05:
        scale *= 0.5
    elif acc_rate < 0.2:
        scale *= 0.9
    elif acc_rate > 0.95:
        scale *= 10.0
    elif acc_rate > 0.75:
        scale *= 2.0
    elif acc_rate > 0.5:
        scale *= 1.1
    return scale


def size(data):
    """Return the size of the dataset `data`."""
    return data[0].get_value(borrow=True).shape[0]


def first_line(text):
    """
    Returns just the first line in a docstring.
    """
    return text.splitlines()[0].strip()


def delta(v, d):
    """
    Limits of v +/- d for array v and d.
    """
    return zip(v - d, v + d)


def rstrip(iterable, pred):
    """Yield the items from *iterable*, but strip any from the end
    for which *pred* returns ``True``.

    For example, to remove a set of items from the end of an iterable:

        >>> iterable = (None, False, None, 1, 2, None, 3, False, None)
        >>> pred = lambda x: x in {None, False, ''}
        >>> list(rstrip(iterable, pred))
        [None, False, None, 1, 2, None, 3]

    This function is analogous to :func:`str.rstrip`.

    """
    cache = []
    cache_append = cache.append
    for x in iterable:
        if pred(x):
            cache_append(x)
        else:
            for y in cache:
                yield y
            del cache[:]
            yield x


def _pj_after_store_hook(conn):
    """Custom store hook.

        This method is called after the object has been stored in the
        database. The ``conn`` attribute is a connection to the database.

        You should not manage the connection within this method, ie. abort or
        commit the transaction.
        """


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


@classmethod
def delete(cls, *args, **kwargs):
    """ Shortcut for creating a DELETE update """
    return cls(cls.DELETE, *args, **kwargs)


@staticmethod
def _validate_error_behavior(error_behavior: str) ->None:
    """Validate that a specified error behavior is supported."""
    if error_behavior not in {'raise', 'warn'}:
        raise ValueError("error_behavior must be 'raise' or 'warn'.")


def asplain2asdot(asplain):
    """
    This returns an ASDOT+ formatted ASN given an ASPLAIN format, unless given a 16-bit ASN
    :param asplain: ASPLAIN formatted AS number
    :return: ASDOT+ formatted AS number
    """
    begin = int(asplain)
    current = begin
    new = current
    counter = 0
    while current > 65535:
        new = current - 65536
        counter = counter + 1
        current = new
    if counter == 0:
        ret = str(new)
    else:
        ret = str(counter) + '.' + str(new)
    return ret


def evalUnits(unitStr):
    """
    Evaluate a unit string into ([numerators,...], [denominators,...])
    Examples:
        N m/s^2   =>  ([N, m], [s, s])
        A*s / V   =>  ([A, s], [V,])
    """
    pass


def get_child_qdiscid(classid):
    """
    Return the id to handle for a child qdisc. By convention, it will take its
    parent class id

    :param classid: parent class id
    """
    return classid[classid.find(':') + 1:]


def expand_indent(line):
    """Return the amount of indentation.

    Tabs are expanded to the next multiple of 8.

    >>> expand_indent('    ')
    4
    >>> expand_indent('\\t')
    8
    >>> expand_indent('       \\t')
    8
    >>> expand_indent('        \\t')
    16
    """
    if '\t' not in line:
        return len(line) - len(line.lstrip())
    result = 0
    for char in line:
        if char == '\t':
            result = result // 8 * 8 + 8
        elif char == ' ':
            result += 1
        else:
            break
    return result


def index_iterator(shape):
    """Iterates over the indexes of a multi-dimensional array of a specified shape.

    The last index changes most rapidly.
    :param shape: sequence of array dimensions
    :return: yields tuples of array indexes
    """
    dim = len(shape)
    idx = [0] * dim
    num_iterations = 1
    for j in range(0, dim):
        num_iterations *= shape[j]
    for iterations in range(num_iterations):
        yield tuple(idx)
        for j in range(dim - 1, -1, -1):
            idx[j] += 1
            if idx[j] < shape[j]:
                break
            idx[j] = 0


def get_all_headers(message, key):
    """
	Given an HTTPMessage, return all headers matching a given key.
	"""
    return message.get_all(key)


def mod9710(iban):
    """
    Calculates the MOD 97 10 of the passed IBAN as specified in ISO7064.

    @method mod9710
    @param {String} iban
    @returns {Number}
    """
    remainder = iban
    block = None
    while len(remainder) > 2:
        block = remainder[:9]
        remainder = str(int(block) % 97) + remainder[len(block):]
    return int(remainder) % 97


def get_markings(obj):
    """
    Get all object level markings from the given SDO or SRO object.

    Args:
        obj: A SDO or SRO object.

    Returns:
        list: Marking identifiers contained in the SDO or SRO. Empty list if no
            markings are present in `object_marking_refs`.

    """
    return obj.get('object_marking_refs', [])


def sampleIdKey(id_):
    """
    Get a sort key for a sample id.

    @param id_: The C{str} id of a sample. This will normally take the form
        of DA222 (letters followed by some digits), but may also have trailing
        non-digits, as in VK211-G.
    @raise ValueError: If id_ contains a digit that is not followed by
        characters that are all also digits.
    @return: A 3-C{tuple} containing the initial C{str} part of id_ then
        the C{int} suffix, if any (else C{0}), then the trailing C{str}, if
        any.
    """
    prefix = ''
    value = 0
    trailing = ''
    state = 'PREFIX'
    for offset, c in enumerate(id_):
        if state == 'PREFIX':
            if c.isdigit():
                state = 'VALUE'
                value = 10 * value + int(c)
            else:
                prefix += c
        elif state == 'VALUE':
            if c.isdigit():
                value = 10 * value + int(c)
            else:
                state = 'TRAILING'
                trailing += c
        else:
            trailing += c
    return prefix, value, trailing


@classmethod
def _get_apic_classes(cls):
    """
        Get the APIC classes used by this acitoolkit class.

        :returns: list of strings containing APIC class names
        """
    resp = ['lldpIf']
    return resp


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


def connect_hair(all: bool=False):
    """Connect hair to the emitter mesh

    :param all: All hair, Connect all hair systems to the emitter mesh
    :type all: bool
    """
    pass


def is_sigma_algebra__brute(F, X=None):
    """Returns True if F is a sigma algebra on X.

    Parameters
    ----------
    F : set of frozensets
        The candidate sigma algebra.
    X : frozenset, None
        The universal set. If None, then X is taken to be the union of the
        sets in F.

    Returns
    -------
    issa : bool
        True if F is a sigma algebra and False if not.

    Notes
    -----
    This is a brute force check against the definition of a sigma algebra
    on a finite set. Its time complexity is O( len(F)**2 ).

    """
    if X is None:
        X = frozenset().union(*F)
    else:
        X = frozenset(X)
    for subset1 in F:
        if X.difference(subset1) not in F:
            return False
        for subset2 in F:
            if subset1.union(subset2) not in F:
                return False
    else:
        return True


def convert_by_vocab(vocab, items):
    """Converts a sequence of [tokens|ids] using the vocab."""
    output = []
    for item in items:
        output.append(vocab[item])
    return output


def _one_weight(n_one, n_zero, a, alpha):
    """Get the weight of the ones."""
    weight = a * (n_one / n_zero) ** -alpha
    return weight


def _convert_floor(builder, node, graph, err):
    """
    convert to CoreML Floor Layer:
    https://github.com/apple/coremltools/blob/655b3be5cc0d42c3c4fa49f0f0e4a93a26b3e492/mlmodel/format/NeuralNetwork.proto#L5040
    """
    builder.add_floor(name=node.name, input_name=node.inputs[0],
        output_name=node.outputs[0])


def set_image_size_mode(s):
    """Set the quality of the images to be downloaded
    This set the global variable `image_size_mode`

    :param s: quality level, 1 is original size, 12 is smallest
    :type s: str
    """
    global image_size_mode
    image_size_mode = s


@classmethod
def bold(cls, s):
    """Wrap text in bold."""
    return cls._wrap_colour(s, cls.BOLD)


@staticmethod
def all_nodes_between(graph, begin, end):
    """Finds all nodes between begin and end. Returns None if there is any
           path starting at begin that does not reach end."""
    to_visit = [begin]
    seen = set()
    while len(to_visit) > 0:
        n = to_visit.pop()
        if n == end:
            continue
        if n in seen:
            continue
        seen.add(n)
        node_out_edges = graph.out_edges(n)
        if len(node_out_edges) == 0:
            return None
        for e in node_out_edges:
            next_node = e.dst
            if next_node != end and next_node not in seen:
                to_visit.append(next_node)
    return seen


def get_date():
    """Return the current modification date.
        """


@classmethod
def from_keys(cls, iterable, value=None):
    """T.from_keys(S[,v]) -> New tree with keys from S and values equal to v."""
    tree = cls()
    for key in iterable:
        tree.insert(key, value)
    return tree


def parse_roster(roster, email=False):
    """Extract desired information from a string representation of a roster
    file.

    Args:
        roster: string representation of a roster file
        email: whether email should be parsed as well as username

    Returns:
        A list of student usernames, or a list of dictionaries containing
        student emails and usernames if email param is specified.
    """
    if not email:
        students = []
        for line in roster:
            if not line.strip():
                continue
            line = line.strip()
            line = line.split('|')
            students.append(line[0])
        return students
    else:
        students = []
        for line in roster:
            if not line.strip():
                continue
            student = {}
            line = line.strip()
            line = line.split('|')
            print(line)
            student['username'] = line[0]
            student['email'] = line[16]
            students.append(student)
        return students


def getId():
    """Return a string containing a unique id within a tree
        """


@staticmethod
def one_of(_registry, _effective_name, objct):
    """Assign one of the possible options.

        When given as a collection strategy to :code:`collect`,
        will assign one of the options to a name in case more
        than one item is registered to the same name.

        This is the default.
        """
    return objct


def p_str_value(p):
    """ str_value : STRING
                  | STRING_ENCLOSED_DOUBLE_QUOTE
    """
    p[0] = p[1]


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

        :param OutdatedLinkViewReportFailedDetails val:
        :rtype: EventDetails
        """
    return cls('outdated_link_view_report_failed_details', val)


def hsv2rgb(hue, saturation, value):
    """Transform a HSV color to a RGB color."""
    c = value * saturation
    x = c * (1 - abs(hue / 60 % 2 - 1))
    m = value - c
    if 0 <= hue < 60:
        return c + m, x + m, m
    elif 60 <= hue < 120:
        return x + m, c + m, m
    elif 120 <= hue < 180:
        return m, c + m, x + m
    elif 180 <= hue < 240:
        return m, x + m, c + m
    elif 240 <= hue < 300:
        return x + m, m, c + m
    elif 300 <= hue < 360:
        return c + m, m, x + m


def genWorld(pos, dimension, seed, queue):
    """
    Generate the small area of the world
    """
    preGenPos = pos
    print('genning world')
    tileMap = dimension.chunkProvider.generate(preGenPos, seed)
    queue.put(tileMap)
    print('world gen done')
    queue.put(preGenPos)
    queue.put('end')


def formatarg_line(v, i=None, idx=None):
    """reduce output of long lists subroutine"""
    if len(v) > 2 and len('{}'.format(v)) > 80:
        sv = ''
        k = 0
        while len(sv) <= 30 and k < 10:
            sv += '{}, '.format(v[k])
            k += 1
        a = 'list of length: {} [ {}... , {} ]'.format(len(v), sv, v[-1])
    else:
        a = '{}'.format(v)
    if i is not None:
        if idx is not None:
            i = '{}_{:03d}'.format(i, idx)
        a = '{0:.<15}{1}'.format(i, a)
    return a


def command_raw(util, args):
    """ Handler for command raw """
    return util.raw(args.json)


def id():
    """This object's id.
        """


def position_graph_nodes(g, mesh):
    """
    Label the triangle that contains terminal layers.

    Parameters
    ----------
    g : NetworkX graph object
        Graph nodes are updated with labels
    n : int
        Node id in the graph
    label : gdspy object
        Label objec from the gdspy library that contains the label text and position.
    poly : list
        Points of the triangle polygon.

    Returns
    -------
    g : NetworkX graph object
        Updated graph with labels are returned.
    """
    for n, tri in enumerate(mesh['cells']['triangle']):
        pp = mesh['points']
        n1, n2, n3 = pp[tri[0]], pp[tri[1]], pp[tri[2]]
        sum_x = 100000000.0 * (n1[0] + n2[0] + n3[0]) / 3.0
        sum_y = 100000000.0 * (n1[1] + n2[1] + n3[1]) / 3.0
        g.nodes[n]['vertex'] = tri
        g.nodes[n]['pos'] = [sum_x, sum_y]
    return g


def update_states(res, registers) ->None:
    """Update Registers state."""
    for key, value in res.items():
        for reg in registers:
            if key == reg.addr:
                reg.state = value


def silent_progress(iterable, *args, **kwargs):
    """No progress output: ignores all options, and just gives the iterator

    Parameters
    ----------
    iterable : iterable
        thing to iterate over
    """
    return iter(iterable)


def get_video_info(filename):
    """
    returns information about video file in a dictionary format

    Parameters
    ----------
    filename :: (string)
        full filename including root

    Returns
    -------
    video_info :: (dictionary)

    Examples
    --------
    >>> video_info = get_video_info(filename)
    """
    import cv2
    dic = {}
    vidcap = cv2.VideoCapture(filename)
    dic['filename'] = filename
    dic['width'] = int(vidcap.get(cv2.CAP_PROP_FRAME_WIDTH))
    dic['height'] = int(vidcap.get(cv2.CAP_PROP_FRAME_HEIGHT))
    dic['gain'] = vidcap.get(cv2.CAP_PROP_GAIN)
    dic['iso'] = vidcap.get(cv2.CAP_PROP_ISO_SPEED)
    dic['frame_count'] = int(vidcap.get(cv2.CAP_PROP_FRAME_COUNT))
    dic['format'] = vidcap.get(cv2.CAP_PROP_FORMAT)
    dic['fps'] = round(vidcap.get(cv2.CAP_PROP_FPS), 0)
    return dic


@staticmethod
def delay_as_int(delay):
    """ By convention, None means no delay """
    return 0 if delay is None else int(delay)


def dosegrid_extents_positions(extents, dd):
    """Determine dose grid extents in patient coordinate indices.

    Parameters
    ----------
    extents : list
        Dose grid extents in pixel coordintes: [xmin, ymin, xmax, ymax].
    dd : dict
        Dose data from dicomparser.GetDoseData.

    Returns
    -------
    list
        Dose grid extents in patient coordintes: [xmin, ymin, xmax, ymax].
    """
    return [dd['lut'][0][extents[0]], dd['lut'][1][extents[1]], dd['lut'][0
        ][extents[2]], dd['lut'][1][extents[3]]]


def function_for(mod, command, ending='_command'):
    """
    Return a reference to the function for a given command.
    """
    return mod.__dict__[command + ending]


def addon_disable(module: str=''):
    """Disable an add-on

    :param module: Module, Module name of the add-on to disable
    :type module: str
    """
    pass


def add_url_rules(bp, cls, decorator=None, decorator_args=[]):
    """
    add url rules to bp for class cls

    cls may define the following class attribute
        url_rules   dict {endpoint: options, ...}
            endpoint    the endpoint for the registered URL rule
            options     tuple (url_rule[, methods[, defaults]])
                url_rule    the URL rule as string
                methods     tuple of supported methods, e.g. 'GET', 'POST'
                defaults    optional dict with defaults for other rules with the same endpoint
                            see http://werkzeug.pocoo.org/docs/0.14/routing/#werkzeug.routing.Rule
    """
    for endpoint, options in cls.url_rules.items():
        url_rule = options
        methods = 'GET',
        defaults = {}
        if len(options) == 2:
            url_rule, methods = options
        elif len(options) == 3:
            url_rule, methods, defaults = options
        if not decorator:
            view_func = cls.as_view(endpoint)
        else:
            view_func = decorator(*decorator_args)(cls.as_view(endpoint))
        bp.add_url_rule(url_rule, endpoint=endpoint, methods=methods,
            defaults=defaults, view_func=view_func)


@staticmethod
def map_sf_to_greek(sf):
    """Render scale factors in Greek alphabet if appropriate.

        Pass this dictionary to *map_sf* preference if you prefer µ rather than u.

        Example::

            >>> with Quantity.prefs(map_sf=Quantity.map_sf_to_greek):
            ...     print(Quantity('mu0').render(show_label='f'))
            µ₀ = 1.2566 µH/m -- permeability of free space

        """
    return {'u': 'µ'}.get(sf, sf)


def decode_params(encoded_data: str) ->str:
    """ Decode Parameter data from Spreader Interop """
    return encoded_data.replace('|', '|').replace('
', '\r\n')


def send_process_will_be_substituted():
    """Sends a message that a new process is going to be created.
    When `PyDB` works in server mode this method also waits for the
    response from IDE to be sure that IDE received this message.
    """
    from _pydevd_bundle.pydevd_comm import get_global_debugger
    debugger = get_global_debugger()
    if debugger is not None:
        debugger.send_process_will_be_substituted()


def donottrack(request):
    """
    Adds ``donottrack`` to the context, which is ``True`` if the ``HTTP_DNT``
    header is ``'1'``, ``False`` otherwise.

    This context processor requires installtion of the
    ``donottrack.middleware.DoNotTrackMiddleware``.

    Note that use of this context processor is not strictly necessary. (Though
    it is quite convenient.) If you are using the
    ``django.core.context_processors.request`` context processor, you have
    access to ``{{ request.donottrack }}``.

    """
    try:
        return {'donottrack': request.donottrack}
    except AttributeError:
        raise AttributeError(
            "'WSGIRequest' object has no attribute 'donottrack' - 'donottrack.middleware.DoNotTrackMiddleware' must be in your MIDDLEWARE_CLASSES"
            )


@classmethod
def init_and_get_iter(cls, mirror_rp, inc_rp, compare_time):
    """Return rorp iter at given compare time"""
    cls.set_mirror_and_rest_times(compare_time)
    cls.initialize_rf_cache(mirror_rp, inc_rp)
    return cls.subtract_indices(cls.mirror_base.index, cls.
        get_mirror_rorp_iter())


def generate_presigned_url(ClientMethod=None, Params=None, ExpiresIn=None,
    HttpMethod=None):
    """
    Generate a presigned url given a client, its method, and arguments

    :type ClientMethod: string
    :param ClientMethod: The client method to presign for

    :type Params: dict
    :param Params: The parameters normally passed to
            ClientMethod.

    :type ExpiresIn: int
    :param ExpiresIn: The number of seconds the presigned url is valid
            for. By default it expires in an hour (3600 seconds)

    :type HttpMethod: string
    :param HttpMethod: The http method to use on the generated url. By
            default, the http method is whatever is used in the method's model.

    """
    pass


def get_null_keywords_es(es, size):
    """
    Get from ElasticSearch the news entries which don't contain keywords.

    :param es: ElasticSearch connection
    :param size: limit of news which are retrieved
    :return: list of news without keywords
    """
    result = es.search(index='sitemaps', q='-news\\:keywords:*',
        _source_includes='news:keywords', size=size)
    return result['hits']['hits']


def timestamp_branch_name(fields):
    """Return the first field not being 'igitt'"""
    for i in fields:
        if i != '' and i != 'igitt':
            return i + '-timestamps'
    return 'igitt-timestamps'


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

        :param MemberChangeNameType val:
        :rtype: EventType
        """
    return cls('member_change_name', val)


def chiffre_barre_carre(s, r, i, j):
    """
    Look into every number in sub square *i, j*,
    if a number in it ``s[i][k]`` is not null,

    @param      s       current state of the sudoku
    @param      r       array ``r[n] == 0`` means number *n+1* is already taken on this sub square
    @param      i       sub square are indexed by :math:`(i, j) \\in \\{0, 1, 2\\}^2` (0 based)
    @param      j       see parameter *i*
    """
    a = i // 3 * 3
    b = j // 3 * 3
    for k in range(a, a + 3):
        for l in range(b, b + 3):
            if s[k][l] > 0:
                r[s[k][l] - 1] = 0


def migrationTarget_get(targerVM):
    """Service Layer to get Migration Target details"""
    return targerVM.get_Migration_Target()


def getfunction(func):
    """
    Return the function associated with a class method.
    """
    return func


def dic_cmp(dic1, dic2):
    """Compare dictionaries"""
    d1_keys_ = set(dic1.keys())
    d2_keys_ = set(dic2.keys())
    intersect_keys_ = d1_keys_.intersection(d2_keys_)
    added_ = d1_keys_ - d2_keys_
    removed_ = d2_keys_ - d1_keys_
    modified_ = []
    same_ = []
    for k_ in intersect_keys_:
        if dic1[k_] == dic2[k_]:
            same_.append(k_)
        else:
            modified_.append({k_: (dic1[k_], dic2[k_])})
    return added_, removed_, modified_, same_


def make_indentation(indent_size, part=u' '):
    """Creates an indentation prefix string of the given size."""
    return indent_size * part


@classmethod
def from_existing_session(cls, session: object, options: str=None
    ) ->'RsCmwGprfGen':
    """Creates a new RsCmwBluetoothSig object with the entered 'session' reused.

		:param session: can be an another driver or a direct pyvisa session.
		:param options: string tokens alternating the driver settings."""
    return cls(None, False, False, options, session)


def __init__(cls, *args, **kwargs):
    """
        Initializes the class with an empty dictionary of instances.

        Arguments are `name`, `bases`, and `attributes`, as usual.
        """
    super().__init__(*args, **kwargs)
    cls._instances = {}


def get_dim(y):
    """Return the number of dimensions of a torch tensor or numpy
    array-like object.

    """
    try:
        return y.ndim
    except AttributeError:
        return y.dim()


def as_int(n):
    """
    Convert the argument to a builtin integer.

    The return value is guaranteed to be equal to the input. ValueError is
    raised if the input has a non-integral value.

    Examples
    ========

    >>> from sympy.core.compatibility import as_int
    >>> from sympy import sqrt
    >>> 3.0
    3.0
    >>> as_int(3.0) # convert to int and test for equality
    3
    >>> int(sqrt(10))
    3
    >>> as_int(sqrt(10))
    Traceback (most recent call last):
    ...
    ValueError: ... is not an integer

    """
    try:
        result = int(n)
        if result != n:
            raise TypeError
    except TypeError:
        raise ValueError('%s is not an integer' % n)
    return result


@classmethod
def current_date_as_knx(cls):
    """Return current local date as KNX bytes."""
    return cls.to_knx(cls._current_date())


def __call__(context, request, *args, **kw):
    """
        Return a unicode string representing HTML for a section on a larger
        page.
        """


def dget_tkey(dictionary, tuple_key, default=None, ignore_case=True,
    raise_if_missing=False):
    """
    Dictionary helper function to retrieve values from dictionaries with tuple keys.
    Yields the first value found corresponding to a tuple_key found within that key.
    :param dictionary:
    :param tuple_key:
    :param default:
    :param ignore_case:
    :param raise_if_missing:
    :return:
    """
    if ignore_case:
        if isinstance(tuple_key, str):
            tuple_key = tuple_key.lower()
        else:
            ignore_case = False
    for keys, value in dictionary.iteritems():
        for key in keys:
            if ignore_case and isinstance(key, str):
                key = key.lower()
            if tuple_key != key:
                continue
            return value
    if raise_if_missing:
        raise KeyError(tuple_key)
    return default


def s_to_ms(time_seconds: float) ->int:
    """
    Converts seconds to milliseconds.
    """
    return int(time_seconds * 1000)


def get_all(isamAppliance, check_mode=False, force=False):
    """
    Retrieving all Password Strength
    """
    return isamAppliance.invoke_get('Retrieving all Password Strength',
        '/wga/pwd_strength')


def _split_list(s, predicate):
    """Split sequence s via predicate, and return pair ([true], [false]).

    The return value is a 2-tuple of lists,
        ([x for x in s if predicate(x)],
         [x for x in s if not predicate(x)])
    """
    yes = []
    no = []
    for x in s:
        if predicate(x):
            yes.append(x)
        else:
            no.append(x)
    return yes, no


@classmethod
def valueRepr(cls, line):
    """return the representation of the given content line value"""
    return line.value


def connect_nfldb():
    """Connect to the nfldb database.

    Rather than using the builtin method we make our own,
    since we're going to use SQLAlchemy as the engine. However,
    we can still make use of the information in the nfldb config
    file to get information like username and password, which
    means this function doesn't need any arguments.

    Parameters
    ----------
    None

    Returns
    -------
    SQLAlchemy engine object
        A connected engine, ready to be used to query the DB.

    Raises
    ------
    IOError
        If it can't find the config file.
    """
    import nfldb
    import sqlalchemy as sql
    db_config, paths_tried = nfldb.db.config()
    if db_config is None:
        raise IOError(
            'get_play_data: could not find database config! Looked in these places: {0}'
            .format(paths_tried))
    db_config['drivername'] = 'postgres'
    db_config['username'] = db_config['user']
    del db_config['user']
    del db_config['timezone']
    engine = sql.create_engine(sql.engine.url.URL(**db_config))
    return engine


@classmethod
def supports_physical_network(cls):
    """Return whether the physical_network field is supported.

        :returns: Whether the physical_network field is supported
        :raises: ovo_exception.IncompatibleObjectVersion
        """
    return cls.supports_version((1, 7))


def draw_box(image, box, color):
    """Draw 3-pixel width bounding boxes on the given image array.
    color: list of 3 int values for RGB.
    """
    y1, x1, y2, x2 = box
    image[y1:y1 + 2, x1:x2] = color
    image[y2:y2 + 2, x1:x2] = color
    image[y1:y2, x1:x1 + 2] = color
    image[y1:y2, x2:x2 + 2] = color
    return image


def has_level_label(label_flags, vmin):
    """
    Returns true if the ``label_flags`` indicate there is at least one label
    for this level.

    if the minimum view limit is not an exact integer, then the first tick
    label won't be shown, so we must adjust for that.
    """
    if label_flags.size == 0 or label_flags.size == 1 and label_flags[0
        ] == 0 and vmin % 1 > 0.0:
        return False
    else:
        return True


def iodp_sample_names(df):
    """
    Convert expedition, hole, section, type, interval to sample name in format:
    exp-hole-type-sect-interval

    Parameters
    ___________
    df : Pandas DataFrame
         dataframe read in from .csv file downloaded from LIMS online database

    Returns
    --------------

    holes : list
           IODP Holes name in format U999A

    specimens : pandas Series
            series with sample names, e.g. 999-U999A-1H-1-W-1

    """
    if 'Top offset (cm)' in df.columns:
        offset_key = 'Top offset (cm)'
    elif 'Offset (cm)' in df.columns:
        offset_key = 'Offset (cm)'
    else:
        print('No offset key found')
        return False, []
    interval = df[offset_key].astype('float').astype('str')
    holes = df['Site'].astype('str') + df['Hole']
    specimens = df['Exp'].astype('str') + '-' + holes + '-' + df['Core'
        ].astype('str') + df['Type'].astype('str') + '-' + df['Sect'].astype(
        'str') + '-' + df['A/W'] + '-' + interval
    return holes, specimens


def get_supported_browsers_suggestions():
    """Return a list of supported browsers by default."""
    supported_browsers = ['chrome', 'chrome-remote', 'chrome-headless',
        'chrome-remote-headless', 'edge', 'edge-remote', 'firefox',
        'firefox-headless', 'firefox-remote', 'firefox-remote-headless',
        'ie', 'ie-remote', 'opera', 'opera-remote']
    return supported_browsers


def interval_to_freq(time_interval: str) ->str:
    """
    Convert the natural language-based time period into freq char in order to
    standardize user input.

    Parameters
    ----------
    time_interval : Natural lanaguage time period.

    Returns
    -------
    freq : Appropriate frequency char, see: https://pandas.pydata.org/pandas-docs/stable/user_guide/timeseries.html#offset-aliases

    """
    time_interval = time_interval.strip().lower()
    freq = ''
    if time_interval in ['seconds', 'second', 'sec', 's']:
        freq = 'S'
    elif time_interval in ['minutes', 'minute', 'min', 't']:
        freq = 'T'
    elif time_interval in ['hours', 'hour', 'hourly', 'hr', 'h']:
        freq = 'H'
    elif time_interval in ['days', 'day', 'daily', 'd']:
        freq = 'D'
    elif time_interval in ['weeks', 'week', 'weekly', 'w']:
        freq = 'W'
    elif time_interval in ['months', 'month', 'mth', 'm']:
        freq = 'M'
    elif time_interval in ['qtr', 'quarter', 'quar', 'q']:
        freq = 'Q'
    elif time_interval in ['years', 'year', 'annual', 'y', 'a']:
        freq = 'Y'
    else:
        raise ValueError('Parameter time_interval not recognized.')
        return None
    return freq


def remove_atom_from_res(res, at_id, verbose=False):
    """
    Removes atoms from given residue
    """
    if verbose:
        print('  Deleting atom ' + at_id)
    res.detach_child(at_id)


def updateTimezones(db):
    """
    Update UTC offses in 'timezones' with values in 'pg_timezone_names'

    The UTC offsets in 'pg_timezone_names' are DST adjusted (for the timezones
    we care about) so we need to copy the values regularly to keep the cached
    values in 'timezones' up-to-date.
    """
    import base
    if base.configuration()['database.driver'] == 'postgresql':
        with db.updating_cursor('timezones') as cursor:
            cursor.execute(
                """UPDATE timezones
                                 SET utc_offset=pg_timezone_names.utc_offset
                                FROM pg_timezone_names
                               WHERE pg_timezone_names.name=timezones.name"""
                )


def findCommonParentGoIds(terms, go):
    """This function finds the common ancestors in the GO
    tree of the list of terms in the input.

    :arg terms: a list of GO terms
    :type terms: tuple, list, :class:`~numpy.ndarray`

    :arg go: object containing a gene ontology (GO) directed acyclic graph (DAG)
    :type go: `~goatools.obo_parser.GODag`
    """
    rec = go[terms[0]]
    candidates = rec.get_all_parents()
    candidates.update({terms[0]})
    for term in terms[1:]:
        rec = go[term]
        parents = rec.get_all_parents()
        parents.update({term})
        candidates.intersection_update(parents)
    return candidates


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

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


def keras_clip(optimizer):
    """ Convenience function for creating kwargs for setting Keras gradient
		clipping.
	"""
    if optimizer.clip_type is None:
        return {}
    elif optimizer.clip_type == 'norm':
        return {'clipnorm': optimizer.clip_value}
    elif optimizer.clip_type == 'abs':
        return {'clipvalue': optimizer.clip_value}
    else:
        raise ValueError('Unhandled clip type: {}. This is a bug.'.format(
            optimizer.clip_type))


def getChange(number):
    """Return an IChange object."""


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

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

        """
    return cls._member_map_.copy()


@classmethod
def copy(cls, ami, name):
    """ copy ami to your account
        :param ami: any public ami
        :param name: name for saved ami
        """
    from . import Spot, Volume
    instance = Spot(ami)
    instance.start(persistent=True)
    volume = Volume(ami)
    instance.terminate()
    volume.name = name
    snapshot = volume.create_snapshot()
    snapshot.register_image()
    volume.delete()


def duplicate_move(NODE_OT_duplicate=None, NODE_OT_translate_attach=None):
    """Duplicate selected nodes and move them

    :param NODE_OT_duplicate: Duplicate Nodes, Duplicate selected nodes
    :param NODE_OT_translate_attach: Move and Attach, Move nodes and attach to frame
    """
    pass


def component(rdef):
    """ Return the `component` part of a composite relation  """
    if rdef.composite is None:
        return None
    return rdef.object if rdef.composite == 'subject' else rdef.subject


def is_point_in_polygon(x, y, polygon_point_list):
    """
    Use ray-tracing to see if point is inside a polygon

    Args:
        x:
        y:
        polygon_point_list:

    Returns: bool

    """
    n = len(polygon_point_list)
    inside = False
    p1x, p1y = polygon_point_list[0]
    for i in range(n + 1):
        p2x, p2y = polygon_point_list[i % n]
        if y > min(p1y, p2y):
            if y <= max(p1y, p2y):
                if x <= max(p1x, p2x):
                    if p1y != p2y:
                        xints = (y - p1y) * (p2x - p1x) / (p2y - p1y) + p1x
                    if p1x == p2x or x <= xints:
                        inside = not inside
        p1x, p1y = p2x, p2y
    return inside


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 generate_config(api_addr: str='::1', api_port: int=1118) ->str:
    """ Generate basic V2ray configuration file with gRPC api enabled"""
    return (
        """{
  "inbounds": [{
      "port": %(port)d,
      "listen": "%(addr)s",
      "protocol": "dokodemo-door",
      "settings": {
        "address": "127.0.0.1"
      },
      "tag": "api"
    }
  ],
  "outbounds": [
    {
      // Protocol name of the outbound proxy.
      "protocol": "freedom",
      // Settings of the protocol. Varies based on protocol.
      "settings": {},
      // Tag of the outbound. May be used for routing.
      "tag": "direct"
    }
  ],
  "policy": {
    "levels": {
      "0": {
        "statsUserUplink": true,
        "statsUserDownlink": true
      }
    },
    "system": {
      "statsInboundUplink": true,
      "statsInboundDownlink": true
    }
  },
  "stats": {},
  "api": {
    "tag": "api",
    "services": [
      "HandlerService",
      "StatsService"
    ]
  },
  "routing": {
    "settings": {
      "rules": [
        {
          "inboundTag": [
            "api"
          ],
          "outboundTag": "api",
          "type": "field"
        }
      ]
    },
    "strategy": "rules"
  }
}
"""
         % {'port': api_port, 'addr': api_addr})


def datetime_to_json(date):
    """
    Convert datetime in a dictionary
    :param date: Date in datetime format [Datetime]
    :return: Dictionary with all components of the date: year, month, day, hour, minute, second [Dictionary]
    """
    year = str(date.year)
    month = str(date.month).zfill(2)
    day = str(date.day).zfill(2)
    hour = str(date.hour).zfill(2)
    minute = str(date.minute).zfill(2)
    second = str(date.second).zfill(2)
    json_date = {'year': year, 'month': month, 'day': day, 'hour': hour,
        'minute': minute, 'second': second}
    return json_date


@classmethod
def setTableType(cls, tableType):
    """
        Sets the table type for this widget to the inputed type.

        :param      tableType | <subclass of orb.Table>
        """
    cls._tableType = tableType


def set_options(pool_or_cursor, row_instance):
    """for connection-level options that need to be set on Row instances"""
    for option in ('JSON_READ',):
        setattr(row_instance, option, getattr(pool_or_cursor, option, None))
    return row_instance


def sanit_arg_count(input_array, number_lo, number_hi):
    """
        Returns True, if length of input array is in <number_lo, number_hi>.
    """
    if len(input_array) <= number_hi and len(input_array) >= number_lo:
        return True
    return False


def update_apns_channel(APNSChannelRequest=None, ApplicationId=None):
    """
    Use to update the APNs channel for an app.

    :example: response = client.update_apns_channel(
        APNSChannelRequest={
            'Certificate': 'string',
            'PrivateKey': 'string'
        },
        ApplicationId='string'
    )

    :type APNSChannelRequest: dict
    :param APNSChannelRequest: [REQUIRED] Apple Push Notification Service channel definition.
            Certificate (string) -- The distribution certificate from Apple.
            PrivateKey (string) -- The certificate private key.

    :type ApplicationId: string
    :param ApplicationId: [REQUIRED]

    :rtype: dict
    :return: {
        'APNSChannelResponse': {
            'ApplicationId': 'string',
            'CreationDate': 'string',
            'Id': 'string',
            'IsArchived': True|False,
            'LastModifiedBy': 'string',
            'LastModifiedDate': 'string',
            'Platform': 'string',
            'Version': 123
        }
    }

    :returns:
    (dict) -- 200 response
    APNSChannelResponse (dict) -- Apple Distribution Push Notification Service channel definition.
    ApplicationId (string) -- The ID of the application to which the channel applies.
    CreationDate (string) -- When was this segment created
    Id (string) -- The unique channel ID.
    IsArchived (boolean) -- Is this channel archived
    LastModifiedBy (string) -- Who last updated this entry
    LastModifiedDate (string) -- Last date this was updated
    Platform (string) -- The platform type. Will be APNS.
    Version (integer) -- Version of channel

    """
    pass


@staticmethod
def get_s3_bucket_locations(buckets, self_log=False):
    """return (bucket_name, prefix) for all s3 logging targets"""
    for b in buckets:
        if b.get('Logging'):
            if self_log:
                if b['Name'] != b['Logging']['TargetBucket']:
                    continue
            yield b['Logging']['TargetBucket'], b['Logging']['TargetPrefix']
        if not self_log and b['Name'].startswith('cf-templates-'):
            yield b['Name'], ''


def search4letters(phrase: str, letters: str='aeiou') ->set:
    """Return a set of the 'letters' found in 'phrease'."""
    return set(letters).intersection(set(phrase))


def get_system_name(allowed_model, name) ->str:
    """Gets the system name of the Custom Field """
    if allowed_model is None:
        allowed_model = 'all'
    else:
        allowed_model = str(allowed_model.model).replace(' ', '')
    name = name.replace(' ', '').lower()
    system_name = '{namespace}:{name}'.format(namespace=allowed_model, name
        =name)
    return system_name


def async_(func):
    """No-op decorator, used to visually distinguish async_ functions"""
    return func


def create_zip(archive, compression, cmd, verbosity, interactive, filenames):
    """Create a ZIP archive."""
    cmdlist = [cmd, 'a']
    if not interactive:
        cmdlist.append('-y')
    cmdlist.extend(['-tzip', '-mx=9', '--', archive])
    cmdlist.extend(filenames)
    return cmdlist


@classmethod
def from_ini(cls, *args, **kwargs):
    """Define a new `SummaryPlot` from a an INI-format `ConfigParser`
        section.
        """
    raise NotImplementedError('Sub-classes should provide this method.')


def merge_dicts(*dict_args):
    """
    Given any number of dicts, shallow copy and merge into a new dict,
    precedence goes to key value pairs in latter dicts.
    """
    result = {}
    for dictionary in dict_args:
        result.update(dictionary)
    return result


def midpnt(df, price, midpnt, n):
    """
    The Midpoint calculation is similar to the Midprice, except the highest and
    lowest values are returned from the same input field. The default indicator
    calculates the highest close and lowest close within the look back period
    and averages the two values.

    Parameters:
        df (pd.DataFrame): DataFrame which contain the asset information.
        price (string): the column name for the price of the asset.
        midpnt (string): the column name for the calculated midpoint values.
        n (int): the total number of periods.

    Returns:
        df (pd.DataFrame): Dataframe with the midpoint calculated.

    """
    midpnt_max = df[price].rolling(window=n).max()
    midpnt_min = df[price].rolling(window=n).min()
    df[midpnt] = (midpnt_max + midpnt_min) / 2
    df = df.dropna().reset_index(drop=True)
    return df


@staticmethod
def control_relays(states):
    """Generate a command to control relays.

        :param     RelayStateModifier    states:    The 8 modifiers for the
                                                    relay states as a list
        :return:   The PCK command (without address header) as text
        :rtype:    str
        """
    if len(states) != 8:
        raise ValueError('Invalid states length.')
    ret = 'R8'
    for state in states:
        ret += state.value
    return ret


def merge_to_length(a, b, length):
    """Merge 2 lists into a specific length.

    This method will merge 2 lists into a short list, replacing the last few
    items of the first list if necessary.

    For example, a = [1,2,3], b = [4,5,6,7], and length = 6. The result will
    be [1,2,4,5,6,7]. If length = 5, the result will be [1,4,5,6,7]. If length
    is greater or equal to 7, the result will be [1,2,3,4,5,6,7].

    Parameters
    ----------
    a : list
        A list of elements.
    b : list
        Another list of elements.
    length : int
        The length of the result list.

    Returns
    -------
    list
        A merged list of the specified length.

    """
    temp = b[:]
    for index, item in enumerate(a):
        if len(temp) < length:
            temp.insert(index, item)
        else:
            break
    return temp


def synchronized_order(img, target_img, axes=True, reference=True):
    """ Reorder reference and axes of `img` to match target_img.

    Parameters
    ----------
    img : Image
    target_img : Image
    axes : bool, optional
        If True, synchronize the order of the axes.
    reference : bool, optional
        If True, synchronize the order of the reference coordinates.

    Returns
    -------
    newimg : Image
        An Image satisfying newimg.axes == target.axes (if axes == True),
        newimg.reference == target.reference (if reference == True).

    Examples
    --------
    >>> data = np.random.standard_normal((3,4,7,5))
    >>> im = Image(data, AffineTransform.from_params('ijkl', 'xyzt', np.diag([1,2,3,4,1])))
    >>> im_scrambled = im.reordered_axes('iljk').reordered_reference('txyz')
    >>> im == im_scrambled
    False
    >>> im_unscrambled = synchronized_order(im_scrambled, im)
    >>> im == im_unscrambled
    True

    The images don't have to be the same shape

    >>> data2 = np.random.standard_normal((3,11,9,4))
    >>> im2 = Image(data, AffineTransform.from_params('ijkl', 'xyzt', np.diag([1,2,3,4,1])))
    >>> im_scrambled2 = im2.reordered_axes('iljk').reordered_reference('xtyz')
    >>> im_unscrambled2 = synchronized_order(im_scrambled2, im)
    >>> im_unscrambled2.coordmap == im.coordmap
    True

    or have the same coordmap

    >>> data3 = np.random.standard_normal((3,11,9,4))
    >>> im3 = Image(data3, AffineTransform.from_params('ijkl', 'xyzt', np.diag([1,9,3,-2,1])))
    >>> im_scrambled3 = im3.reordered_axes('iljk').reordered_reference('xtyz')
    >>> im_unscrambled3 = synchronized_order(im_scrambled3, im)
    >>> im_unscrambled3.axes == im.axes
    True
    >>> im_unscrambled3.reference == im.reference
    True
    >>> im_unscrambled4 = synchronized_order(im_scrambled3, im, axes=False)
    >>> im_unscrambled4.axes == im.axes
    False
    >>> im_unscrambled4.axes == im_scrambled3.axes
    True
    >>> im_unscrambled4.reference == im.reference
    True
    """
    target_axes = target_img.axes
    target_reference = target_img.coordmap.function_range
    if axes:
        img = img.reordered_axes(target_axes.coord_names)
    if reference:
        img = img.reordered_reference(target_reference.coord_names)
    return img


def _api_group_for_type(cls):
    """
    Determine which Kubernetes API group a particular PClass is likely to
    belong with.

    This is basically nonsense.  The question being asked is wrong.  An
    abstraction has failed somewhere.  Fixing that will get rid of the need
    for this.
    """
    _groups = {(u'v1beta1', u'Deployment'): u'extensions', (u'v1beta1',
        u'DeploymentList'): u'extensions', (u'v1beta1', u'ReplicaSet'):
        u'extensions', (u'v1beta1', u'ReplicaSetList'): u'extensions'}
    key = cls.apiVersion, cls.__name__.rsplit(u'.')[-1]
    group = _groups.get(key, None)
    return group


def _cat(pth):
    """Return the contents of a given path."""
    return pth.open().read()


def lookup_by_name(name, nsdicts):
    """
    Look up an object by name from a sequence of namespace dictionaries.
    Returns a tuple of (nsdict, obj_name, attrs); nsdict is the namespace
    dictionary the name was found in, obj_name is the name of the base object
    the name is bound to, and the attrs list is the chain of attributes
    of the object that completes the name.

        >>> import os
        >>> nsdict, obj_name, attrs = lookup_by_name("os.path.isdir",
        ...     (locals(),))
        >>> obj_name, attrs
        ('os', ['path', 'isdir'])
        >>> getattr(getattr(nsdict[obj_name], attrs[0]), attrs[1])  # doctest: +ELLIPSIS
        <function isdir at ...>
        >>> lookup_by_name("os.monkey", (locals(),))
        Traceback (most recent call last):
          ...
        NameError: name 'os.monkey' is not defined

    """
    for nsdict in nsdicts:
        attrs = name.split('.')
        names = []
        while attrs:
            names.append(attrs.pop(0))
            obj_name = '.'.join(names)
            if obj_name in nsdict:
                attr_copy = attrs[:]
                tmp = nsdict[obj_name]
                try:
                    while attr_copy:
                        tmp = getattr(tmp, attr_copy.pop(0))
                except AttributeError:
                    pass
                else:
                    return nsdict, obj_name, attrs
    raise NameError("name '%s' is not defined" % name)


def interspace(btn_h, btn_count, scr_h):
    """
    Given the height of a button, the number of buttons to be displayed, and
    the height of the curses window the buttons will be displayed within,
    returns the number of lines to be given between each button for maximum
    vertical spacing.
    """
    return (scr_h - btn_h * btn_count) // (btn_count - 1)


def strip_suffix(run: dict) ->dict:
    """
    Certain attributes such as SeriesDescriptions (but not ProtocolName!?) may get a suffix like '_SBRef' from the vendor,
    try to strip it off from the BIDS labels

    :param run: The run with potentially added suffixes that are the same as the BIDS suffixes
    :return:    The run with these suffixes removed
    """
    if 'suffix' in run['bids'] and run['bids']['suffix']:
        suffix = run['bids']['suffix'].lower()
    else:
        return run
    for key in run['bids']:
        if key == 'suffix':
            continue
        if isinstance(run['bids'][key], str) and run['bids'][key].lower(
            ).endswith(suffix):
            run['bids'][key] = run['bids'][key][0:-len(suffix)]
    return run


@classmethod
def from_dict(cls, exp_dict):
    """Create an _Experiment object from given `exp_dict`."""
    experiment = cls(exp_dict.pop('name'), exp_dict.pop('duration'),
        exp_dict.pop('reservation'))
    experiment.type = exp_dict.pop('type')
    experiment.nodes = exp_dict.pop('nodes')
    if 'profiles' in exp_dict.keys():
        experiment.profiles = exp_dict.pop('profiles')
    if 'mobilities' in exp_dict.keys():
        experiment.mobilities = exp_dict.pop('mobilities')
    experiment._load_assocs(**exp_dict)
    return experiment


def list_versions_by_function(FunctionName=None, Marker=None, MaxItems=None):
    """
    List all versions of a function. For information about the versioning feature, see AWS Lambda Function Versioning and Aliases .
    See also: AWS API Documentation

    Examples
    This operation retrieves a Lambda function versions
    Expected Output:

    :example: response = client.list_versions_by_function(
        FunctionName='string',
        Marker='string',
        MaxItems=123
    )

    :type FunctionName: string
    :param FunctionName: [REQUIRED]
            Function name whose versions to list. You can specify a function name (for example, Thumbnail ) or you can specify Amazon Resource Name (ARN) of the function (for example, arn:aws:lambda:us-west-2:account-id:function:ThumbNail ). AWS Lambda also allows you to specify a partial ARN (for example, account-id:Thumbnail ). Note that the length constraint applies only to the ARN. If you specify only the function name, it is limited to 64 characters in length.

    :type Marker: string
    :param Marker: Optional string. An opaque pagination token returned from a previous ListVersionsByFunction operation. If present, indicates where to continue the listing.

    :type MaxItems: integer
    :param MaxItems: Optional integer. Specifies the maximum number of AWS Lambda function versions to return in response. This parameter value must be greater than 0.

    :rtype: dict
    :return: {
        'NextMarker': 'string',
        'Versions': [
            {
                'FunctionName': 'string',
                'FunctionArn': 'string',
                'Runtime': 'nodejs'|'nodejs4.3'|'nodejs6.10'|'java8'|'python2.7'|'python3.6'|'dotnetcore1.0'|'nodejs4.3-edge',
                'Role': 'string',
                'Handler': 'string',
                'CodeSize': 123,
                'Description': 'string',
                'Timeout': 123,
                'MemorySize': 123,
                'LastModified': 'string',
                'CodeSha256': 'string',
                'Version': 'string',
                'VpcConfig': {
                    'SubnetIds': [
                        'string',
                    ],
                    'SecurityGroupIds': [
                        'string',
                    ],
                    'VpcId': 'string'
                },
                'DeadLetterConfig': {
                    'TargetArn': 'string'
                },
                'Environment': {
                    'Variables': {
                        'string': 'string'
                    },
                    'Error': {
                        'ErrorCode': 'string',
                        'Message': 'string'
                    }
                },
                'KMSKeyArn': 'string',
                'TracingConfig': {
                    'Mode': 'Active'|'PassThrough'
                }
            },
        ]
    }

    :returns:
    (string) --

    """
    pass


def split_clspath(clspath):
    """Split clspath into module and class names.

    Note: This is a really simplistic implementation.

    """
    return clspath.rsplit('.', 1)


def build_where_query(tables, columns, join_columns, where_conditions):
    """Return a SQL query from input arguments using WHERE."""
    query = 'SELECT '
    query += ', '.join(columns)
    query += ' FROM '
    query += ', '.join(tables)
    if join_columns or where_conditions:
        query += ' WHERE '
    joins = []
    if join_columns:
        for ind in range(1, len(join_columns), 2):
            joins.append(join_columns[ind - 1] + '=' + join_columns[ind])
        query += ' AND '.join(joins)
    if where_conditions:
        if join_columns:
            query += ' AND '
        query += ' AND '.join(where_conditions)
    return query


def i2le(number: int) ->bytes:
    """
    Convert int to little endian (LE) bytes

    Args:
        number: int value to convert to bytes in LE format
    Returns:
        LE-encoded number
    """
    if number == 0:
        return b'\x00'
    return number.to_bytes((number.bit_length() + 7) // 8, 'little')


def color_rgb_to_int(red: int, green: int, blue: int) ->int:
    """Return a RGB color as an integer."""
    return red * 256 * 256 + green * 256 + blue


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


def unicode_is_ascii(u_string):
    """Determine if unicode string only contains ASCII characters.

    :param str u_string: unicode string to check. Must be unicode
        and not Python 2 `str`.
    :rtype: bool
    """
    assert isinstance(u_string, str)
    try:
        u_string.encode('ascii')
        return True
    except UnicodeEncodeError:
        return False


def group_sequence(lst):
    """
    Break a sequence of integers into continuous groups
    [1,2,3,5,7,8] -> [[1,2,3],[5],[7,8]]
    :param lst: list of ints
    :return: list of lists
    """
    if not lst:
        return []
    grouped = [[lst[0]]]
    for i in range(1, len(lst)):
        if lst[i - 1] + 1 == lst[i]:
            grouped[-1].append(lst[i])
        else:
            grouped.append([lst[i]])
    return grouped


def open(file_handle):
    """Create a new file reader and use `file_handle` to read from.

        This method is a class method!

        """


@classmethod
def _intersection(cls, values):
    """
        Returns the lowest state in `states`.

        This represents the case where multiple keys represent one action.
        (you have to press every key)
        """
    return min(values)


def slow_parent_set():
    """Set the object’s slow parent

    """
    pass


def right_now():
    """Return Y:M:D H:M:S"""
    import datetime
    right_now = str(datetime.datetime.now()).replace(':', '-').split('.')[0]
    return right_now


def add_vertex_slide(MASK_OT_add_vertex=None, MASK_OT_slide_point=None):
    """Add new vertex and slide it

    :param MASK_OT_add_vertex: Add Vertex, Add vertex to active spline
    :param MASK_OT_slide_point: Slide Point, Slide control points
    """
    pass


def get_write_target_stats_options(**kwargs):
    """
    Get optional arguments for write_target_stats function.

    Retrieves the keywords supplied to the WRITE_TARGET_STATS
    function (**KWARGS), and returns the values in a OPTION dictionary.
    Default values are assigned to selected optional arguments. The
    function will terminate with an error if an unrecognized optional
    argument is supplied.

    INPUTS:
    **kwargs : keyword argument list

    OUTPUTS:
    option : data structure containing option values.
    option['title']     : title descriptor for data set.
    option['overwrite'] : boolean to overwrite Excel file.

    LIST OF OPTIONS:
      A title description for each dataset TITLE can be optionally
    provided as well as an overwrite option if the file name currently
    exists.

    label = label : label for each data point in target diagram, e.g.
                    'OC445 (CB)'
    overwrite = boolean : true/false flag to overwrite Excel file
    title = title : title descriptor for each data set in data, e.g.
                   'Expt. 01.0'

    Author: Peter A. Rochford
    Acorn Science & Innovation
    prochford@acornsi.com

    Created on Dec 10, 2016

    @author: rochfordp
    """
    from skill_metrics import check_on_off
    nargin = len(kwargs)
    option = {}
    option['overwrite'] = False
    option['label'] = []
    option['title'] = ''
    if nargin == 0:
        return option
    for optname, optvalue in kwargs.items():
        optname = optname.lower()
        if not optname in option:
            raise ValueError('Unrecognized option: ' + optname)
        else:
            option[optname] = optvalue
            if optname == 'overwrite':
                option['overwrite'] = check_on_off(option['overwrite'])
    return option


@staticmethod
def call_callback_functions(functions, message):
    """Call callback functions."""
    for func in functions:
        func(message)


def merkle_pair(hashes, hash_f):
    """Take a list of hashes, and return the parent row in the tree of merkle hashes."""
    if len(hashes) % 2 == 1:
        hashes = list(hashes)
        hashes.append(hashes[-1])
    items = []
    for i in range(0, len(hashes), 2):
        items.append(hash_f(hashes[i] + hashes[i + 1]))
    return items


def isolate_one_only(func):
    """
    When using role isolation, and several hosts are available, run on only
    one role.  Useful for instance, for a database client. it does not make
    sense to run the interactive client on every host which has database
    access.
    """
    func.isolate_one_only = True
    return func


def postInstall(context):
    """Called as at the end of the setup process. """
    site = context.getSite()


def invisible_axes(ax):
    """
    Make axes invisible.

    Parameters
    ----------
    ax :
        Matplotlib ax object.
    """
    ax.axis('off')


def get_simple_partition(dataframe, case_id_key, no_partitions):
    """
    Get a simple partitioning of a CSV

    Parameters
    --------------
    dataframe
        Dataframe
    case_id_key
        Column that is the case ID
    no_partitions
        Number of partitions

    Returns
    --------------
    dataframe
        Dataframe with a partitioning (@@partition) column
    """
    dataf = dataframe.copy()
    dataf['@@partition'] = dataf[case_id_key].rank(method='dense',
        ascending=False).astype(int) % no_partitions
    return dataf


def find_in_map(value):
    """If the value is a ^map macro, replace it with a Cloud Formation
    Formation ``Fn::FindInMap`` function, splitting up the period delimited
    reference. For example if a value is ``^map Foo.Bar.Baz`` it will be
    returned as ``dict({'Fn::FindInMap': ['Foo', 'Bar', Baz'})``.

    :param str value: The value to check for the map macro
    :rtype: str|dict
    :raises: ValueError

    """
    if value.startswith('^map '):
        ref = value[5:].split('.')
        if len(ref) != 3:
            raise ValueError('Invalid map reference: {}'.format(value[5:]))
        return {'Fn::FindInMap': ref}
    return value


def SizeReserveUernPremEnd(t):
    """Unearned reserve per policy: End of period"""
    return 0


def boxes_and_offsets_must_have_same_len():
    """ Disconnected diagram error. """
    return 'Boxes and offsets must have the same length.'


def _safe_str(cmd):
    """Transform bytes into string without risk of conversion error"""
    if isinstance(cmd, str):
        return cmd
    else:
        return str(cmd, errors='replace')


def locked():
    """True if the object is locked with any lock.
        """


def coalesce(*args):
    """
    Return the first non-None argument

    >>> coalesce()

    >>> coalesce(0, 1)
    0
    >>> coalesce(None, 0)
    0
    """
    for arg in args:
        if arg is not None:
            return arg


@staticmethod
def run(prog):
    """Run the given program."""
    for exe in prog.execs:
        exe.run()


def tile_url(image, viz_params=None):
    """Create a target url for tiles from an EE image asset.
    e.g.
    im = ee.Image("LE7_TOA_1YEAR/" + year).select("B3","B2","B1")
    viz = {'opacity': 1, 'gain':3.5, 'bias':4, 'gamma':1.5}
    url = tile_url(image=im),viz_params=viz)
    """
    if viz_params:
        d = image.getMapId(viz_params)
    else:
        d = image.getMapId()
    base_url = 'https://earthengine.googleapis.com'
    url = (
        f"https://earthengine.googleapis.com/v1alpha/{d['mapid']}/tiles/{{z}}/{{x}}/{{y}}"
        )
    return url


def forInterface(interface, check=True, omit=(), prefix=None):
    """Get an IRecordsProxy for the given interface. If `check` is True,
        an error will be raised if one or more fields in the interface does
        not have an equivalent setting.
        """


def _project_data(proj_axes, data):
    """
        Helper function to project data onto the the axes defined in proj_axes.

        :param proj_axes:   str that holds the axes that are projected to as number, e.g. '01' for projection onto xy
                            or '02' for projection onto xz.
        :param data:
    """
    p_a = proj_axes
    dim = len(proj_axes)
    if dim == 2:
        indices = '012'
        for ix in range(len(p_a)):
            indices = indices.replace(p_a[ix], '')
        deleted_axis = int(indices)
        ax = [0, 1, 2]
        ax.remove(deleted_axis)
        result = data[:, (ax)]
    elif dim == 1:
        ax = int(p_a)
        result = data[:, (ax)]
    else:
        result = data
    return result


def number_field_choices(field):
    """
        Given a field, returns the number of choices.
    """
    try:
        return len(field.get_flat_choices())
    except AttributeError:
        return 0


def _print_integrate_lp(integrate_lp_stats):
    """Print the contents of the integrate.lp dictionary."""
    images = sorted(integrate_lp_stats.keys())
    for i in images:
        data = integrate_lp_stats[i]
        print('%4d %5.3f %5d %5d %5d %4.2f %6.2f %5.2f' % (i, data['scale'],
            data['strong'], data['overloads'], data['rejected'], data.get(
            'mosaic', 0.0), data['distance'], data['resolution']))


@staticmethod
def formatfundbjson(fundbjson):
    """格式化集思录返回的json数据,以字典形式保存"""
    result = {}
    for row in fundbjson['rows']:
        cell = row['cell']
        fundb_id = cell['fundb_id']
        result[fundb_id] = cell
    return result


def deploy_dashboard(db_json_url, wf_url, api_token):
    """Deploy a dashboard in wavefront."""
    print('Deploying Dashboard with %s, %s, %s' % (db_json_url, wf_url,
        api_token))
    return True


def shift_string_fields(fields, n):
    """
    Process n string fields and convert to None if they're empty
    """
    for _ in range(n):
        s = next(fields)
        yield None if s == '-' else s


def top_arrow_path(x, y, offset):
    """ x,y is the final point
    """
    d = [('m', x, y + 2 * offset), (0, -offset), (-offset, 0), (offset, -
        offset), (offset, offset), (-offset, 0), 'z']
    return d


@classmethod
def deserialize(cls, serialized):
    """
        Deserializes the provided JSON entity

        :params serialized: a Python dict or JSON text, assumed to be the
            serialization of a *Proof* object
        :type: dict or str
        :rtype: Proof
        """
    kwargs = {}
    if isinstance(serialized, dict):
        kwargs.update({'from_dict': serialized})
    elif isinstance(serialized, str):
        kwargs.update({'from_json': serialized})
    return cls(**kwargs)


def lines(s):
    """
    lines :: str -> [str]
    lines breaks a string up into a list of strings at newline characters. The resulting strings do not contain newlines.
    """
    return s.split('\n')


def moving_avg(xyw, avg_len):
    """
    Calculate a moving average for a given averaging length
    :param xyw: output from collapse_into_single_dates
    :type xyw: dict
    :param avg_len: average of these number of points, i.e., look-back window
    :type avg_len: int
    :return: list of x values, list of y values
    :rtype: tuple
    """
    cumsum, moving_aves, x_final = [0], [], []
    for i, y in enumerate(xyw['y'], 1):
        cumsum.append(cumsum[i - 1] + y / xyw['w'][i - 1])
        if i >= avg_len:
            moving_ave = (cumsum[i] - cumsum[i - avg_len]) / avg_len
            moving_aves.append(moving_ave)
    x_final = [xyw['x'][i] for i in range(avg_len - 1, len(xyw['x']))]
    return x_final, moving_aves


def n_decimals(number):
    """Number of meaningful decimals in ``number``, at least 1"""
    s = str(number)
    if '.' in s:
        return s[::-1].index('.')
    else:
        return 1


def format_throughput(available, used=None):
    """ Format the read/write throughput for display """
    if used is None:
        return str(available)
    percent = float(used) / available
    return '{0:.0f}/{1:.0f} ({2:.0%})'.format(used, available, percent)


def evalcontextfilter(f):
    """Decorator for marking eval-context dependent filters.  An eval
    context object is passed as first argument.  For more information
    about the eval context, see :ref:`eval-context`.

    .. versionadded:: 2.4
    """
    f.evalcontextfilter = True
    return f


@classmethod
def create_service_profile(cls, description, metainfo, driver):
    """Wrapper utility that returns a test service profile."""
    body = cls.admin_client.create_service_profile(driver=driver, metainfo=
        metainfo, description=description)
    service_profile = body['service_profile']
    cls.service_profiles.append(service_profile)
    return service_profile


def normalize_url(url):
    """Return a normalized url with trailing and without leading slash.

     >>> normalize_url(None)
     '/'
     >>> normalize_url('/')
     '/'
     >>> normalize_url('/foo/bar')
     '/foo/bar'
     >>> normalize_url('foo/bar')
     '/foo/bar'
     >>> normalize_url('/foo/bar/')
     '/foo/bar'
    """
    if not url or len(url) == 0:
        return '/'
    if not url.startswith('/'):
        url = '/' + url
    if len(url) > 1 and url.endswith('/'):
        url = url[0:len(url) - 1]
    return url


def sort_by_server(row1, row2):
    """Sorts the rows alphabetically by their network name."""
    if row1.room.network.name < row2.room.network.name:
        return -1
    else:
        return 1


def string_to_num(s):
    """Converts a string to an int/float

    Returns ``None`` if it can't be converted

    >>> string_to_num('5')
    5
    >>> string_to_num('5.2')
    5.2
    >>> string_to_num(10)
    10
    >>> string_to_num(10.1)
    10.1
    >>> string_to_num('this is not a string') is None
    True
    """
    if isinstance(s, (int, float)):
        return s
    if s.isdigit():
        return int(s)
    try:
        return float(s)
    except ValueError:
        return None


def print_results(results):
    """Print `results` (the results of validation) to stdout.

    Args:
        results: A list of FileValidationResults or ObjectValidationResults
                 instances.

    """
    if not isinstance(results, list):
        results = [results]
    for r in results:
        try:
            r.log()
        except AttributeError:
            raise ValueError(
                'Argument to print_results() must be a list of FileValidationResults or ObjectValidationResults.'
                )


def label_sort_key(label):
    """
    A sort key that encourages more useful labels to come first, when we don't
    have a more solid basis to decide.

    * Prefer words starting with digits over words starting with letters:
      '101' is better than 'ci' or 'one hundred one'.
    * Prefer words ending with letters over words ending with digits:
      'hassium' is better than 'atomic number 108'.
    * Prefer lowercase words over capitalized ones: 'huge' is better than
      'Brobdingnagian'.
    * Prefer longer labels over shorter ones, as they're probably more
      specific: 'Paul Newman' is better than 'Newman'.
    * All else being equal, prefer the first label in alphabetical order.

    This is, fortunately, not the only way to choose labels. If a WordNet
    synset has a "sameAs" link pointing to a named synset in WordNet 2.0, we
    use that name, letting us use the label "United Kingdom" instead of
    "United Kingdom of Great Britain and Northern Ireland".

    However, we disregard the synset names for people, as they tend to be just
    the person's last name, and therefore are highly ambiguous in a way that
    won't be disambiguated by adding the category "person". For people, we
    apply this rule no matter what, choosing their longest name.
    """
    return not label[0].isdigit(), label[-1].isdigit(), not label.islower(
        ), -len(label), label


@staticmethod
def translate(flag) ->str:
    """Converts acceptable python strings to command line args"""
    return flag.replace('_', '-')


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 abortNetworkConfig(update):
    """
    Release resources claimed by chute network configuration.
    """
    pass


def step_error(request, feature, scenario, step, step_func, step_func_args,
    exception):
    """Finalize the step report as failed."""
    request.node.__scenario_report__.fail()


@classmethod
def start(cls, ctx, question_list, settings):
    """Create and start a trivia session.

        This allows the session to manage the running and cancellation of its
        own tasks.

        Parameters
        ----------
        ctx : `commands.Context`
            Same as `TriviaSession.ctx`
        question_list : `dict`
            Same as `TriviaSession.question_list`
        settings : `dict`
            Same as `TriviaSession.settings`

        Returns
        -------
        TriviaSession
            The new trivia session being run.

        """
    session = cls(ctx, question_list, settings)
    loop = ctx.bot.loop
    session._task = loop.create_task(session.run())
    session._task.add_done_callback(session._error_handler)
    return session


def __adjust_rad_for_skip(diam, skip):
    """

    If necessary, increase the crop circle diameter (radius) for the chosen
    skip value. This is required because the diameter must be divisible by
    skip without rest.

    Parameters
    ----------
    diam: int
        Initial diameter of crop circle (in pixels).
    skip: int
        The numbers of pixels to skip when evaluating film thickness
        information.

    Returns
    -------
    diam: int
        Diameter of circle that is divisible by skip without rest.

    """
    while diam % skip != 0:
        diam += 1
    return diam


def remove_trailing_string(content, trailing):
    """
    Strip trailing component `trailing` from `content` if it exists.
    Used when generating names from view classes.
    """
    if content.endswith(trailing) and content != trailing:
        return content[:-len(trailing)]
    return content


def add_top_padding(box, extra_padding):
    """Increase the top padding of a box. This also translates the children.
    """
    box.padding_top += extra_padding
    for child in box.children:
        child.translate(dy=extra_padding)


def _rels_part_for(part_name: str) ->str:
    """ Get the name of the XML part with the relationships of `part_name` according to the OPC spec """
    name_parts = part_name.split('/')
    return '/'.join(name_parts[:-1] + ['_rels', name_parts[-1]]) + '.rels'


def word_wrap(text, linelen=80, indent=0, joinstr='\n'):
    """Return string, word wrapped at linelen."""
    if len(text) < linelen:
        return text
    result = []
    line = []
    llen = -indent
    for word in text.split():
        llen += len(word) + 1
        if llen < linelen:
            line.append(word)
        else:
            result.append(' '.join(line))
            line = [word]
            llen = len(word)
    if line:
        result.append(' '.join(line))
    return joinstr.join(result)


def canonical_species_name(species_name):
    """Get canonical species name from GTDB or NCBI species name."""
    if species_name == 's__':
        return species_name
    species_name = species_name.replace('Candidatus ', '')
    prefix = species_name[0:3]
    full_name = species_name[3:]
    genus, species = full_name.split(' ')[0:2]
    underscore_pos = genus.rfind('_')
    if underscore_pos != -1:
        genus = genus[0:underscore_pos]
    underscore_pos = species.rfind('_')
    if underscore_pos != -1:
        species = species[0:underscore_pos]
    genus = genus.replace('[', '').replace(']', '')
    species = species.replace('[', '').replace(']', '')
    return prefix + genus + ' ' + species


def _get_plotting_function(ax, plot_function_str, valid):
    """Get the plotting function to utilize.

    Warnings
    --------
    This method is intended for internal use only.

    """
    plotting_functions_dict = {'plot': ax.plot, 'semilogx': ax.semilogx,
        'semilogy': ax.semilogy, 'loglog': ax.loglog}
    if (plot_function_str not in plotting_functions_dict or
        plot_function_str not in valid):
        raise ValueError(
            "'{0}' not a valid plotting option. Must be one of the following options: '{1}'."
            .format(plot_function_str, valid))
    return plotting_functions_dict[plot_function_str]


def find_union_coords(cases):
    """Take a list of cases and find the union of coordinates
    with which to index all cases. Sort the coords if possible.
    """
    for x in zip(*cases):
        try:
            yield sorted(set(x))
        except TypeError:
            yield list(set(x))


def layer_prev():
    """Switch to editing action in animation layer below the current action in the NLA Stack

    """
    pass


def network_is_xy(network):
    """Verify that a network lies in the XY plane.

    Parameters
    ----------
    network : Network
        A network object.

    Returns
    -------
    bool
        True if the Z coordinate of all vertices is zero.
        False otherwise.

    """
    z = None
    for key in network.nodes():
        if z is None:
            z = network.node_attribute(key, 'z') or 0.0
        elif z != network.node_attribute(key, 'z') or 0.0:
            return False
    return True


def read_mantid_MDHisto(filename):
    """Read the saved MDHisto from from Mantid and returns an xarray.DataArray object"""
    import h5py
    import numpy as np
    import xarray as xr
    from javelin.unitcell import UnitCell
    with h5py.File(filename, 'r') as f:
        if 'SaveMDVersion' not in f['MDHistoWorkspace'].attrs or f[
            'MDHistoWorkspace'].attrs['SaveMDVersion'] < 2:
            raise RuntimeError('Cannot open ' + filename +
                ', must be saved by SaveMD Version 2')
        path = 'MDHistoWorkspace/data/'
        if path + 'signal' not in f:
            raise RuntimeError('Cannot open ' + path + 'signal in ' + filename)
        signal = f[path + 'signal']
        data = np.array(signal)
        if 'axes' not in signal.attrs:
            print("Can't find axes")
            return xr.DataArray(data)
        axes = signal.attrs['axes'].decode().split(':')
        dims_list = []
        coords_list = []
        for a in axes:
            dims_list.append(a)
            axis = np.array(f[path + a])
            axis = (axis + np.roll(axis, -1))[:-1] / 2
            coords_list.append(np.array(axis))
        data_set = xr.DataArray(data, dims=dims_list, coords=coords_list)
        oriented_lattice = (
            'MDHistoWorkspace/experiment0/sample/oriented_lattice')
        if oriented_lattice in f:
            lattice = f[oriented_lattice]
            data_set.attrs['unit_cell'] = UnitCell(lattice['unit_cell_a'][0
                ], lattice['unit_cell_b'][0], lattice['unit_cell_c'][0],
                lattice['unit_cell_alpha'][0], lattice['unit_cell_beta'][0],
                lattice['unit_cell_gamma'][0])
        W_MATRIX = 'MDHistoWorkspace/experiment0/logs/W_MATRIX/value'
        if W_MATRIX in f:
            data_set.attrs['projection_matrix'] = np.array(f[W_MATRIX]
                ).reshape(3, 3)
    return data_set


def exhaustible(iterable):
    """Returns True if *iterable* is an exhaustible iterator."""
    return iter(iterable) is iter(iterable)


def chunks(l, n):
    """Yield successive n-sized chunks from l."""
    for i in range(0, len(l), n):
        yield l[i:i + n]


def toolbar():
    """Toggles tool shelf display

    """
    pass


def _calculate_atr(atr_length, highs, lows, closes):
    """Calculate the average true range
    atr_length : time period to calculate over
    all_highs : list of highs
    all_lows : list of lows
    all_closes : list of closes
    """
    if atr_length < 1:
        raise ValueError('Specified atr_length may not be less than 1')
    elif atr_length >= len(closes):
        raise ValueError(
            'Specified atr_length is larger than the length of the dataset: ' +
            str(len(closes)))
    atr = 0
    for i in range(len(highs) - atr_length, len(highs)):
        high = highs[i]
        low = lows[i]
        close_prev = closes[i - 1]
        tr = max(abs(high - low), abs(high - close_prev), abs(low - close_prev)
            )
        atr += tr
    return atr / atr_length


def batch_get_projects(names=None):
    """
    Gets information about build projects.
    See also: AWS API Documentation

    :example: response = client.batch_get_projects(
        names=[
            'string',
        ]
    )

    :type names: list
    :param names: [REQUIRED]
            The names of the build projects.
            (string) --

    :rtype: dict
    :return: {
        'projects': [
            {
                'name': 'string',
                'arn': 'string',
                'description': 'string',
                'source': {
                    'type': 'CODECOMMIT'|'CODEPIPELINE'|'GITHUB'|'S3',
                    'location': 'string',
                    'buildspec': 'string',
                    'auth': {
                        'type': 'OAUTH',
                        'resource': 'string'
                    }
                },
                'artifacts': {
                    'type': 'CODEPIPELINE'|'S3'|'NO_ARTIFACTS',
                    'location': 'string',
                    'path': 'string',
                    'namespaceType': 'NONE'|'BUILD_ID',
                    'name': 'string',
                    'packaging': 'NONE'|'ZIP'
                },
                'environment': {
                    'type': 'LINUX_CONTAINER',
                    'image': 'string',
                    'computeType': 'BUILD_GENERAL1_SMALL'|'BUILD_GENERAL1_MEDIUM'|'BUILD_GENERAL1_LARGE',
                    'environmentVariables': [
                        {
                            'name': 'string',
                            'value': 'string'
                        },
                    ]
                },
                'serviceRole': 'string',
                'timeoutInMinutes': 123,
                'encryptionKey': 'string',
                'tags': [
                    {
                        'key': 'string',
                        'value': 'string'
                    },
                ],
                'created': datetime(2015, 1, 1),
                'lastModified': datetime(2015, 1, 1)
            },
        ],
        'projectsNotFound': [
            'string',
        ]
    }

    :returns:
    CODECOMMIT : The source code is in an AWS CodeCommit repository.
    CODEPIPELINE : The source code settings are specified in the source action of a pipeline in AWS CodePipeline.
    GITHUB : The source code is in a GitHub repository.
    S3 : The source code is in an Amazon Simple Storage Service (Amazon S3) input bucket.

    """
    pass


def removecomment(astr, cphrase):
    """
    the comment is similar to that in python.
    any charachter after the # is treated as a comment
    until the end of the line
    astr is the string to be de-commented
    cphrase is the comment phrase"""
    alist = astr.splitlines()
    for i in range(len(alist)):
        alist1 = alist[i].split(cphrase)
        alist[i] = alist1[0]
    return '\n'.join(alist)


def __getitem__(id):
    """ Returns the subscriber having the id specified
        """


def main(project_name, dataset_name, remote_filepath):
    """
    Copy annotations between items
    :return:
    """
    import dtlpy as dl
    project = dl.projects.get(project_name=project_name)
    dataset = project.datasets.get(dataset_name=dataset_name)
    item = dataset.items.get(filepath=remote_filepath)
    annotations = item.annotations.list()
    ann = annotations[0]
    ann.delete()
    annotations = item.annotations.list()
    annotations.delete()


def energy_pet(power, time):
    """Usage: energy_pet(power,time)"""
    return power * time


def currency_code_average(days):
    """Returns code and average rate of days."""


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

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


def crash():
    """
        Stop the main loop *immediately*, without firing any system events.

        This is named as it is because this is an extremely "rude" thing to do;
        it is possible to lose data and put your system in an inconsistent
        state by calling this.  However, it is necessary, as sometimes a system
        can become wedged in a pre-shutdown call.
        """


def findAll(haystack, needle):
    """returns a list of all occurances of needle in haystack"""
    h = haystack
    res = []
    f = haystack.find(needle)
    offset = 0
    while f >= 0:
        res.append(f + offset)
        offset += f + len(needle)
        h = h[f + len(needle):]
        f = h.find(needle)
    return res


def create_option_group(OptionGroupName=None, EngineName=None,
    MajorEngineVersion=None, OptionGroupDescription=None, Tags=None):
    """
    Creates a new option group. You can create up to 20 option groups.
    See also: AWS API Documentation

    Examples
    This example creates an option group.
    Expected Output:

    :example: response = client.create_option_group(
        OptionGroupName='string',
        EngineName='string',
        MajorEngineVersion='string',
        OptionGroupDescription='string',
        Tags=[
            {
                'Key': 'string',
                'Value': 'string'
            },
        ]
    )

    :type OptionGroupName: string
    :param OptionGroupName: [REQUIRED]
            Specifies the name of the option group to be created.
            Constraints:
            Must be 1 to 255 alphanumeric characters or hyphens
            First character must be a letter
            Cannot end with a hyphen or contain two consecutive hyphens
            Example: myoptiongroup

    :type EngineName: string
    :param EngineName: [REQUIRED]
            Specifies the name of the engine that this option group should be associated with.

    :type MajorEngineVersion: string
    :param MajorEngineVersion: [REQUIRED]
            Specifies the major version of the engine that this option group should be associated with.

    :type OptionGroupDescription: string
    :param OptionGroupDescription: [REQUIRED]
            The description of the option group.

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

    :rtype: dict
    :return: {
        'OptionGroup': {
            'OptionGroupName': 'string',
            'OptionGroupDescription': 'string',
            'EngineName': 'string',
            'MajorEngineVersion': 'string',
            'Options': [
                {
                    'OptionName': 'string',
                    'OptionDescription': 'string',
                    'Persistent': True|False,
                    'Permanent': True|False,
                    'Port': 123,
                    'OptionVersion': 'string',
                    'OptionSettings': [
                        {
                            'Name': 'string',
                            'Value': 'string',
                            'DefaultValue': 'string',
                            'Description': 'string',
                            'ApplyType': 'string',
                            'DataType': 'string',
                            'AllowedValues': 'string',
                            'IsModifiable': True|False,
                            'IsCollection': True|False
                        },
                    ],
                    'DBSecurityGroupMemberships': [
                        {
                            'DBSecurityGroupName': 'string',
                            'Status': 'string'
                        },
                    ],
                    'VpcSecurityGroupMemberships': [
                        {
                            'VpcSecurityGroupId': 'string',
                            'Status': 'string'
                        },
                    ]
                },
            ],
            'AllowsVpcAndNonVpcInstanceMemberships': True|False,
            'VpcId': 'string',
            'OptionGroupArn': 'string'
        }
    }

    :returns:
    ModifyDBInstance
    RebootDBInstance
    RestoreDBInstanceFromDBSnapshot
    RestoreDBInstanceToPointInTime

    """
    pass


def wrap_nodes_between(first, last, new_parent):
    """An helper function to move all nodes between two nodes to a new node
    and add that new node to their former parent. The boundary nodes are
    removed in the process.
    """
    old_parent = first.getparent()
    if first.tail:
        new_parent.text = first.tail
    for node in first.itersiblings():
        if node is last:
            break
        new_parent.append(node)
    old_parent.replace(first, new_parent)
    new_parent.tail = last.tail
    old_parent.remove(last)


def edit(enabled=None, condition=None):
    """Modifies an existing conditional TALES modifier.

        'condition' is a TALES expression.

        None values leave the respective parameter unchanged.
        """


def calculate_checksum(bytes_):
    """
    Calculates the checksum for bytes_.

    :param bytes_: A string of bytes representing the raw header and body of a FIX message.
    :return: The checksum value calculated over bytes_.
    """
    return sum(bytes_) % 256


@classmethod
def supports_from_pcm(cls):
    """returns True if all necessary components are available
        to support the .from_pcm() classmethod"""
    try:
        from audiotools.encoders import encode_alac
        return True
    except ImportError:
        return False


@classmethod
def is_capable(cls, df_type):
    """
        @param::df_type: the type of input dataframe in string
        return boolean value indicates whether or not the conversion is supported
        """
    raise NotImplementedError(
        '> Dataframe.JointerBase is_capable(): method is not implemented. ')


@staticmethod
def t_beginsong_RBRACE1(token):
    """}(?![ \\t\\r\\n]*\\[)"""
    token.lexer.open_braces -= 1
    token.type = 'RBRACE'
    if token.lexer.open_braces == 0:
        token.lexer.pop_state()
        token.type = 'SONG_RTITLE'
    return token


def list_identity_policies(Identity=None):
    """
    Returns a list of sending authorization policies that are attached to the given identity (an email address or a domain). This API returns only a list. If you want the actual policy content, you can use GetIdentityPolicies .
    Sending authorization is a feature that enables an identity owner to authorize other senders to use its identities. For information about using sending authorization, see the Amazon SES Developer Guide .
    This action is throttled at one request per second.
    See also: AWS API Documentation

    Examples
    The following example returns a list of sending authorization policies that are attached to an identity:
    Expected Output:

    :example: response = client.list_identity_policies(
        Identity='string'
    )

    :type Identity: string
    :param Identity: [REQUIRED]
            The identity that is associated with the policy for which the policies will be listed. You can specify an identity by using its name or by using its Amazon Resource Name (ARN). Examples: user@example.com , example.com , arn:aws:ses:us-east-1:123456789012:identity/example.com .
            To successfully call this API, you must own the identity.

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

    """
    pass


def move_spines(ax, sides, dists):
    """
    Move the entire spine relative to the figure.

    Parameters:
      ax: axes to operate on
      sides: list of sides to move. Sides: top, left, bottom, right
      dists: list of float distances to move. Should match sides in length.

    Example:
    move_spines(ax, sides=['left', 'bottom'], dists=[-0.02, 0.1])
    """
    for side, dist in zip(sides, dists):
        ax.spines[side].set_position(('axes', dist))
    return ax