def deregister_image(DryRun=None, ImageId=None):
    """
    Deregisters the specified AMI. After you deregister an AMI, it can't be used to launch new instances.
    This command does not delete the AMI.
    See also: AWS API Documentation

    :example: response = client.deregister_image(
        DryRun=True|False,
        ImageId='string'
    )

    :type DryRun: boolean
    :param DryRun: Checks whether you have the required permissions for the action, without actually making the request, and provides an error response. If you have the required permissions, the error response is DryRunOperation . Otherwise, it is UnauthorizedOperation .

    :type ImageId: string
    :param ImageId: [REQUIRED]
            The ID of the AMI.

    """
    pass


def pretty_req(req):
    """
    return a copy of a pip requirement that is a bit more readable,
    at the expense of removing some of its data
    """
    from copy import copy
    req = copy(req)
    req.link = None
    req.satisfied_by = None
    return req


@classmethod
def from_scaledproto(cls, scaledproto_mesh, pos, vel, euler, euler_vel,
    rotation_vel=(0, 0, 0), component_com_x=None):
    """
        TODO: add documentation
        """
    mesh = cls(**scaledproto_mesh.items())
    mesh._place_in_orbit(pos, vel, euler, euler_vel, rotation_vel,
        component_com_x)
    return mesh


def filter_req(req, extra):
    """Apply an extra using a requirements markers and return True if this requirement is kept"""
    if extra and not req.marker:
        return False
    keep_req = True
    if req.marker:
        if not extra:
            extra = None
        keep_req = req.marker.evaluate({'extra': extra})
    return keep_req


def makeFlatList(nestedList):
    """중첩리스트를 단일리스트로 변환하는 함수"""
    flatList = []
    for sublist in nestedList:
        for item in sublist:
            flatList.append(item)
    return flatList


def Any(arg):
    """
    Any argument is accepted
    Test is for existence of argument
    Can be used to simply test existence of positional or keyword arguments
    """
    return True


def calculate_shape_keeping_aspect_ratio(height: int, width: int, min_size:
    int, max_size: int):
    """
    The function scales spatial sizes of the image keeping aspect ratio to satisfy provided requirements.
    The behavior of this function is equivalent to the output shape calculation of the Preprocessor block of TensorFlow
    Object Detection API models with keep aspect ratio resizer.
    :param height: input height.
    :param width: input width.
    :param min_size: size limit.
    :param max_size: size limit.
    :return: the tuple with scaled image height, width.
    """
    ratio_min = min_size / min(height, width)
    ratio_max = max_size / max(height, width)
    ratio = min(ratio_min, ratio_max)
    return int(round(height * ratio)), int(round(width * ratio))


def try_write(prog, at, data):
    """Tries to write data into member of moderngl program"""
    o = prog.get(at, default=None)
    if o is not None:
        o.write(data)


@classmethod
def _one_argument(cls, data):
    """Parse a single argument from data.

        This always returns exactly two values; if there is no remaining data
        after parsing one argument, the second value will be an empty string.
        If there was no data worth parsing, both values will be empty strings.

        :param str data: The data to get an argument from
        :returns tuple<str,str>: The parsed argument and any remaining data

        """
    data = data.lstrip()
    if not data:
        return '', ''
    if data[0] in cls.delimiters[0]:
        delimiter = cls.delimiters[0].index(data[0])
        delimiter_end = cls.delimiters[1][delimiter]
        closed = False
        try:
            end = data.index(delimiter_end, 1)
            closed = True
        except ValueError:
            end = len(data)
        arg = data[1:end]
        if closed:
            end += 1
        if not arg:
            return cls._one_argument(data[end:])
    else:
        end = 1
        data_end = len(data)
        stop_on = ' \n\r\t' + cls.delimiters[0]
        while end < data_end:
            if data[end] in stop_on:
                break
            end += 1
        arg = data[:end]
    return arg, data[end:]


def get_name(friendly=False):
    """Get name of this resource

    :return: name of this resource
    :rtype: str
    """
    if friendly:
        return 'Events log'
    return 'history'


def sortByMaxima(requestContext, seriesList):
    """
    Takes one metric or a wildcard seriesList.

    Sorts the list of metrics by the maximum value across the time period
    specified.    Useful with the &areaMode=all parameter, to keep the
    lowest value lines visible.

    Example::

        &target=sortByMaxima(server*.instance*.memory.free)

    """
    return list(sorted(seriesList, key=max))


@classmethod
def decode_pkcs8_public(cls, alg_params, key_data):
    """Decode a PKCS#8 format EdDSA public key"""
    return key_data,


@classmethod
def get_session_cls(cls):
    """Return the session class that will be used by the user"""
    raise NotImplemented()


def ynq(prompt):
    """
    Asks a yes or no question, returns True when yes is chosen.
    """
    prompt = f'{prompt} [y/n]'
    x = input(prompt).lower()
    answers = {'y': True, 'n': False, 'yes': True, 'no': False}
    while x not in answers:
        x = input(prompt).lower()
    return answers[x]


@classmethod
def _make(cls, iterable, new=None, len=len):
    """Make a new object from a sequence or iterable"""
    result = cls.__new__(cls, *iterable)
    if len(result) != len(cls._fields):
        raise TypeError('Expected %d arguments, got %d' % (len(cls._fields),
            len(result)))
    return result


def get_file_extension(filepath):
    """Return full file extension from filepath"""
    filename = filepath.split('/')[-1]
    return filename[filename.index('.'):]


def analog_l3_pressed(controller):
    """
    Callback function that is triggered, when the left stick button was pressed

    :param controller:              the controller that triggered the action
    :type controller:               steuer.Controller
    """
    print('ACTION:' + str(controller.number) + ':' + controller.name +
        ':Analog L3 pressed')


def _merge_reserved_keys(key, existing_event, new_event):
    """
    A helper function that merges the reserved keys or raises an exception
    when merge not possible
    :param key: The key to be merged
    :param existing_event: The event that's already in the database
    :param new_event: the new event to be merged
    :return: the dictionary with new attributes to merge with
             the existing event
    """
    if key == 'start_time':
        if new_event.start_time is not None:
            existing_event.start_time = min(new_event.start_time,
                existing_event.start_time)
    elif key == 'end_time':
        if new_event.end_time is not None:
            existing_event.end_time = max(new_event.end_time,
                existing_event.end_time)
    elif key == 'description':
        str1 = existing_event.description.strip()
        str2 = new_event.description.strip()
        if str2 and str2 not in str1:
            existing_event.description = str1 + '\n' + str2
    elif key == 'detail_urls':
        for k in new_event.detail_urls:
            if new_event.detail_urls.get(k) is not None:
                existing_event.detail_urls[k] = new_event.detail_urls[k]
    elif getattr(existing_event, key) != getattr(new_event, key):
        raise ValueError(
            'Merge not possible:reserved keys have clashing values.')


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

        :param SharedFolderMemberError val:
        :rtype: UpdateFolderMemberError
        """
    return cls('member_error', val)


def read_lwostring(raw_name):
    """Parse a zero-padded string."""
    i = raw_name.find(b'\x00')
    name_len = i + 1
    if name_len % 2 == 1:
        name_len += 1
    if i > 0:
        name = raw_name[0:i].decode('utf-8', 'ignore')
    else:
        name = ''
    return name, name_len


def parse_mimetype(mimetype):
    """Parses a MIME type into its components.
    :param str mimetype: MIME type
    :returns: 4 element tuple for MIME type, subtype, suffix and parameters
    :rtype: tuple
    Example:
    >>> parse_mimetype('text/html; charset=utf-8')
    ('text', 'html', '', {'charset': 'utf-8'})
    """
    if not mimetype:
        return '', '', '', {}
    parts = mimetype.split(';')
    params = []
    for item in parts[1:]:
        if not item:
            continue
        key, value = item.split('=', 1) if '=' in item else (item, '')
        params.append((key.lower().strip(), value.strip(' "')))
    params = dict(params)
    fulltype = parts[0].strip().lower()
    if fulltype == '*':
        fulltype = '*/*'
    mtype, stype = fulltype.split('/', 1) if '/' in fulltype else (fulltype, ''
        )
    stype, suffix = stype.split('+', 1) if '+' in stype else (stype, '')
    return mtype, stype, suffix, params


@staticmethod
def _mtr_xy(calc_x, calc_y, mtr_of='e00200p', tax_type='combined'):
    """
        Computes marginal tax rates for Calculator objects calc_x and calc_y
        for specified mtr_of income type and specified tax_type.
        """
    _, iitax_x, combined_x = calc_x.mtr(mtr_of, wrt_full_compensation=True)
    _, iitax_y, combined_y = calc_y.mtr(mtr_of, wrt_full_compensation=True)
    if tax_type == 'combined':
        return combined_x, combined_y
    elif tax_type == 'iitax':
        return iitax_x, iitax_y
    else:
        raise ValueError('tax_type must be "combined" or "iitax"')


def FormatValue(val, maxdigits=None):
    """Format a float to fit in at most ``maxdigits[0]`` spaces with maxdigits[1] after decimal.
    Note that this code has been hacked from FormatSigFigs and may have unused sections.

    :param float val: number to be formatted.

    :param list maxdigits: the number of digits, places after decimal and 'f' or 'g' to be used for display of the
      number (defaults to [10,2,'f']).

    :returns: a string with <= maxdigits characters (usually).
    """
    if 'str' in str(type(val)) and (val == '?' or val == '.'):
        return val
    if maxdigits is None:
        digits = [10, 2, 'f']
    else:
        digits = list(maxdigits)
    if len(digits) == 2:
        digits.append('f')
    if not val:
        digits[2] = 'f'
    fmt = '{:' + str(digits[0]) + '.' + str(digits[1]) + digits[2] + '}'
    string = fmt.format(float(val)).strip()
    if len(string) <= digits[0]:
        if ':' in string:
            string = str(val)
        if digits[1] > 0:
            string = string.rstrip('0')
            if string[-1] == '.':
                string += '0'
        return string
    if val < 0:
        digits[0] -= 1
    decimals = digits[0] - digits[1]
    if abs(val) > 1e+99:
        fmt = '{' + ':{:d}.{:d}g'.format(digits[0], digits[0] - 6) + '}'
    elif abs(val) > 1000000000.0:
        fmt = '{' + ':{:d}.{:d}g'.format(digits[0], digits[0] - 5) + '}'
    elif abs(val) < 10 ** (4 - decimals):
        decimals = min(digits[0] - 5, digits[1])
        fmt = '{' + ':{:d}.{:d}g'.format(digits[0], decimals) + '}'
    elif abs(val) >= 10 ** (decimals - 1):
        decimals = max(0, digits[0] - 5)
        fmt = '{' + ':{:d}.{:d}g'.format(digits[0], decimals) + '}'
    elif abs(val) < 1:
        decimals = min(digits[0] - 3, digits[1])
        fmt = '{' + ':{:d}.{:d}f'.format(digits[0], decimals) + '}'
    else:
        decimals = digits[0] - 6
        fmt = '{' + ':{:d}.{:d}g'.format(digits[0], decimals) + '}'
    try:
        return fmt.format(float(val)).strip()
    except ValueError:
        print('FormatValue Error with val,maxdigits,fmt= %f %d %s' % (val,
            maxdigits, fmt))
        return str(val)


def notwanted(zelf, notwant):
    """ whether an object is not desired. """
    for key, value in notwant.items():
        if key == 'format':
            continue
        if key not in zelf:
            continue
        if value in zelf[key]:
            return True
    return False


def flatten_list(x):
    """Flatten nested lists"""
    if type(x) is not list:
        return x
    x_len = len(x)
    i = 0
    while i < x_len:
        if type(x[i]) is list:
            x_len += len(x[i]) - 1
            x[i:i + 1] = x[i]
        else:
            i += 1
    return x


def add(fileUpload):
    """Add file upload data as chunk"""


@classmethod
def create_floatingip(cls, external_network_id=None, port=None, client=None,
    **kwargs):
    """Creates a floating IP.

        Create a floating IP and schedule it for later deletion.
        If a client is passed, then it is used for deleting the IP too.

        :param external_network_id: network ID where to create
        By default this is 'CONF.network.public_network_id'.

        :param port: port to bind floating IP to
        This is translated to 'port_id=port['id']'
        By default it is None.

        :param client: network client to be used for creating and cleaning up
        the floating IP.

        :param **kwargs: additional creation parameters to be forwarded to
        networking server.
        """
    client = client or cls.client
    external_network_id = external_network_id or cls.external_network_id
    if port:
        port_id = kwargs.setdefault('port_id', port['id'])
        if port_id != port['id']:
            message = 'Port ID specified twice: {!s} != {!s}'.format(port_id,
                port['id'])
            raise ValueError(message)
    fip = client.create_floatingip(external_network_id, **kwargs)['floatingip']
    fip['client'] = client
    cls.floating_ips.append(fip)
    return fip


def is_dict(s):
    """
    Returns True if the given object has dict type or False otherwise
    :param s: object
    :return: bool
    """
    from collections import OrderedDict
    return type(s) in [dict, OrderedDict]


def _check_image_size(ifile):
    """ make sure we don't load humongo images """
    from PIL import Image
    img = Image.open(ifile)
    basewidth = 250
    if img.size[0] > basewidth or img.size[1] > basewidth:
        print('checking image (' + ifile + ') size --> ' + str(img.size))
        wpercent = basewidth / float(img.size[0])
        hsize = int(float(img.size[1]) * float(wpercent))
        img = img.resize((basewidth, hsize), Image.ANTIALIAS)
        img.save(ifile)


@classmethod
def room_quick_veto(cls, temperature: float, duration: int):
    """
        Payload to set a quick veto for a *Room*.
        Duration is mandatory (Duration is in minutes, max 1440 =24 hours)
        """
    return {'temperatureSetpoint': temperature, 'duration': duration}


def guess_contains_xerces(lines):
    """Tries to determine if a file includes xerces
    """
    for line in lines:
        if 'xerces-c-src_' in line:
            return 1
    return 0


@staticmethod
def flow_suffix():
    """Returns the flow file suffix."""
    return 'syx'


def _prepare_ticket_fields(fields):
    """
        Makes sure each key value pair in the fields dictionary is in the correct form.
        :param fields: Ticket fields.
        :return: fields: Ticket fields in the correct form for the ticketing tool.
        """
    for key, value in fields.items():
        if key in ['cc', 'admincc']:
            if isinstance(value, list):
                fields[key] = ', '.join(value)
    return fields


def dispatchDate(date):
    """ Dispatch a ee.Date """
    info = date.format().getInfo()
    return info


def set_session_key(request, key, value):
    """
    Sets django sessions request key
    :param request:
    :param key:
    :param value:
    :return:
    """
    setattr(request, key, value)


@staticmethod
def replaceRule(oldRule, newRule):
    """
        Replace instance of Rule with another one.
        :param oldRule: Instance in the tree.
        :param newRule: Instance to replace with.
        :return: New instance attached to the tree.
        """
    for par in oldRule.from_symbols:
        par._set_to_rule(newRule)
        newRule._from_symbols.append(par)
    for ch in oldRule.to_symbols:
        ch._set_from_rule(newRule)
        newRule._to_symbols.append(ch)
    return newRule


@staticmethod
def interleaveblastresults(query, subject):
    """
        Creates an interleaved string that resembles BLAST sequence comparisons
        :param query: Query sequence
        :param subject: Subject sequence
        :return: Properly formatted BLAST-like sequence comparison
        """
    matchstring = str()
    blaststring = str()
    for i, bp in enumerate(query):
        if bp == subject[i]:
            matchstring += '|'
        else:
            matchstring += ' '
    prev = 0
    for j in range(0, len(query), 60):
        """
            0000 OLC ATGAAGAAGATATTTGTAGCGGCTTTATTTGCTTTTGTTTCTGTTAATGCAATGGCAGCT
                     ||||||||||| ||| | |||| ||||||||| || ||||||||||||||||||||||||
                 ref ATGAAGAAGATGTTTATGGCGGTTTTATTTGCATTAGTTTCTGTTAATGCAATGGCAGCT
            0060 OLC GATTGTGCAAAAGGTAAAATTGAGTTCTCTAAGTATAATGAGAATGATACATTCACAGTA
                     ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
                 ref GATTGTGCAAAAGGTAAAATTGAGTTCTCTAAGTATAATGAGAATGATACATTCACAGTA
            """
        blaststring += '{} OLC {}\n         {}\n     ref {}\n'.format('{:04d}'
            .format(j), query[prev:j + 60], matchstring[prev:j + 60],
            subject[prev:j + 60])
        prev = j + 60
    return blaststring


def doc_handle_n_get(event):
    """Documentation for handlers bound to ``evt.EVT_N_GET``.

    User implementation of this event handler is required if one or more
    services that use N-GET are to be supported. If a handler is
    not implemented and bound to ``evt.EVT_N_GET`` then the N_GET request
    will be responded to using a  *Status* value of ``0x0110`` - Processing
    Failure.

    **Event**

    ``evt.EVT_N_GET``

    **Supported Service Classes**

    * *Display System Management Service Class*
    * *Modality Performed Procedure Step Management*

    **Status**

    Success
      | ``0x0000`` - Success

    Failure
      | ``0x0107`` - Attribute list error
      | ``0x0110`` - Processing failure
      | ``0x0112`` - No such SOP Instance
      | ``0x0117`` - Invalid object Instance
      | ``0x0118`` - No such SOP Class
      | ``0x0119`` - Class-Instance conflict
      | ``0x0124`` - Not authorised
      | ``0x0210`` - Duplicate invocation
      | ``0x0211`` - Unrecognised operation
      | ``0x0212`` - Mistyped argument
      | ``0x0213`` - Resource limitation
      | ``0xC112`` - Applicable Machine Verification Instance not found
      | ``0xC307`` - Specified SOP Instance UID doesn't exist or is not
        a UPS Instance managed by this SCP

    Warning
      | ``0x0001`` - Requested optional Attributes are not supported
      | ``0x0107`` - Attribute list error

    Parameters
    ----------
    event : events.Event
        The event representing a service class receiving an N-GET
        request message. ``Event`` attributes are:

        * ``assoc`` : the
          :py:class:`association <pynetdicom.association.Association>`
          that is running the service that received the N-GET request.
        * ``context`` : the presentation context the request was sent under
          as a ``presentation.PresentationContextTuple``.
        * ``event`` : the event that occurred as ``namedtuple``.
        * ``request`` : the received
          :py:class:`N-GET request <pynetdicom.dimse_primitives.N_GET>`
        * ``timestamp`` : the
          `date and time <https://docs.python.org/3/library/datetime.html#datetime-objects>`_
          that the N-GET request was processed by the service.

        ``Event`` properties are:

        * ``attribute_identifiers`` : a list of attribute
          :py:class:`Tags <pydicom.tag.BaseTag>` contained within the
          N-GET request's *Attribute Identifier List* parameter.

    Returns
    -------
    status : pydicom.dataset.Dataset or int
        The status returned to the peer AE in the N-GET response. Must be a
        valid N-GET status value for the applicable Service Class as either
        an ``int`` or a ``Dataset`` object containing (at a minimum) a
        (0000,0900) *Status* element. If returning a ``Dataset`` object then
        it may also contain optional elements related to the *Status* (as in
        DICOM Standard Part 7, Annex C).
    dataset : pydicom.dataset.Dataset or None
        If the status category is 'Success' or 'Warning' then a ``Dataset``
        containing elements matching the request's *Attribute List*
        conformant to the specifications in the corresponding Service
        Class.

        If the status category is not 'Success' or 'Warning' then ``None``.

    See Also
    --------
    :py:meth:`send_n_get()<pynetdicom.association.Association.send_n_get>`
    :py:class:`N_GET<pynetdicom.dimse_primitives.N_GET>`
    :py:class:`DisplaySystemManagementServiceClass<pynetdicom.service_class_n.DisplaySystemManagementServiceClass>`
    :py:class:`ProcedureStepServiceClass<pynetdicom.service_class_n.ProcedureStepServiceClass>`

    References
    ----------

    * DICOM Standart Part 4, `Annex F <http://dicom.nema.org/medical/dicom/current/output/html/part04.html#chapter_F>`_
    * DICOM Standart Part 4, `Annex H <http://dicom.nema.org/medical/dicom/current/output/html/part04.html#chapter_H>`_
    * DICOM Standard Part 4, `Annex S <http://dicom.nema.org/medical/dicom/current/output/html/part04.html#chapter_S>`_
    * DICOM Standard Part 4, `Annex CC <http://dicom.nema.org/medical/dicom/current/output/html/part04.html#chapter_CC>`_
    * DICOM Standard Part 4, `Annex DD <http://dicom.nema.org/medical/dicom/current/output/html/part04.html#chapter_DD>`_
    * DICOM Standard Part 4, `Annex EE <http://dicom.nema.org/medical/dicom/current/output/html/part04.html#chapter_EE>`_
    """
    pass


@classmethod
def items(cls):
    """
        This mimics the `dict` API, which is required for
        `numba` support.

        When passing an object to the `jitclass` decorator in
        `numba`, `numba` does `OrderedDict(my_obj)` to get the
        attribute and type specifications, which requires us to
        have this implemented.

        >>> from privates import NamedStruct
        >>> class Test(NamedStruct):
        ...     a: int
        ...     b: int
        >>> t = Test(1, 2)
        >>> t.items()
        dict_items([('a', <class 'int'>), ('b', <class 'int'>)])
        """
    return cls._fields().items()


def __new__(cls, *args, **kwargs):
    """Save original class so decode() returns an instance of it."""
    original_class = kwargs.pop('original_class')
    combined_args = [cls] + list(args)
    instance = bytes.__new__(*combined_args, **kwargs)
    instance.original_class = original_class
    return instance


def handle_ends(index1, s, index2, t):
    """Updates intersection parameters if it is on the end of an edge.

    .. note::

       This is a helper used only by :meth:`.Triangle.intersect`.

    Does nothing if the intersection happens in the middle of two
    edges.

    If the intersection occurs at the end of the first curve,
    moves it to the beginning of the next edge. Similar for the
    second curve.

    This function is used as a pre-processing step before passing
    an intersection to :func:`classify_intersection`. There, only
    corners that **begin** an edge are considered, since that
    function is trying to determine which edge to **move forward** on.

    Args:
        index1 (int): The index (among 0, 1, 2) of the first edge in the
            intersection.
        s (float): The parameter along the first curve of the intersection.
        index2 (int): The index (among 0, 1, 2) of the second edge in the
            intersection.
        t (float): The parameter along the second curve of the intersection.

    Returns:
        Tuple[bool, bool, Tuple[int, float, int, float]]: A triple of:

        * flag indicating if the intersection is at the end of an edge
        * flag indicating if the intersection is a "corner"
        * 4-tuple of the "updated" values ``(index1, s, index2, t)``
    """
    edge_end = False
    if s == 1.0:
        s = 0.0
        index1 = (index1 + 1) % 3
        edge_end = True
    if t == 1.0:
        t = 0.0
        index2 = (index2 + 1) % 3
        edge_end = True
    is_corner = s == 0.0 or t == 0.0
    return edge_end, is_corner, (index1, s, index2, t)


def select_sign(pathways, sign):
    """Selects all pathways depending on the overall sign """
    selected = []
    pos = False
    if sign > 0.0:
        pos = True
    for pway in pathways:
        if pos:
            if pway.sign > 0.0:
                selected.append(pway)
        elif pway.sign < 0.0:
            selected.append(pway)
    return selected


def apply_pending_maintenance_action(ResourceIdentifier=None, ApplyAction=
    None, OptInType=None):
    """
    Applies a pending maintenance action to a resource (for example, to a DB instance).
    See also: AWS API Documentation

    Examples
    This example immediately applies a pending system update to a DB instance.
    Expected Output:

    :example: response = client.apply_pending_maintenance_action(
        ResourceIdentifier='string',
        ApplyAction='string',
        OptInType='string'
    )

    :type ResourceIdentifier: string
    :param ResourceIdentifier: [REQUIRED]
            The RDS Amazon Resource Name (ARN) of the resource that the pending maintenance action applies to. For information about creating an ARN, see Constructing an RDS Amazon Resource Name (ARN) .

    :type ApplyAction: string
    :param ApplyAction: [REQUIRED]
            The pending maintenance action to apply to this resource.
            Valid values: system-update , db-upgrade

    :type OptInType: string
    :param OptInType: [REQUIRED]
            A value that specifies the type of opt-in request, or undoes an opt-in request. An opt-in request of type immediate cannot be undone.
            Valid values:
            immediate - Apply the maintenance action immediately.
            next-maintenance - Apply the maintenance action during the next maintenance window for the resource.
            undo-opt-in - Cancel any existing next-maintenance opt-in requests.

    :rtype: dict
    :return: {
        'ResourcePendingMaintenanceActions': {
            'ResourceIdentifier': 'string',
            'PendingMaintenanceActionDetails': [
                {
                    'Action': 'string',
                    'AutoAppliedAfterDate': datetime(2015, 1, 1),
                    'ForcedApplyDate': datetime(2015, 1, 1),
                    'OptInStatus': 'string',
                    'CurrentApplyDate': datetime(2015, 1, 1),
                    'Description': 'string'
                },
            ]
        }
    }

    """
    pass


def triangle_coordinates(i, j, k):
    """
    Computes coordinates of the constituent triangles of a triangulation for the
    simplex. These triangules are parallel to the lower axis on the lower side.

    Parameters
    ----------
    i,j,k: enumeration of the desired triangle

    Returns
    -------
    A numpy array of coordinates of the hexagon (unprojected)
    """
    return [(i, j, k), (i + 1, j, k - 1), (i, j + 1, k - 1)]


def getSVTYPE(chr1, chr2, extend1, extend2):
    """Get SVTYPE from extend right"""
    if chr1 != chr2:
        return 'TRA'
    eventmap = {(True): {(True): 'INV', (False): 'DUP'}, (False): {(True):
        'DEL', (False): 'INV'}}
    return eventmap[extend1][extend2]


def add_meta(req, content, http_equiv=None, name=None, scheme=None, lang=None):
    """Add a `<meta>` tag into the `<head>` of the generated HTML."""
    meta = {'content': content, 'http-equiv': http_equiv, 'name': name,
        'scheme': scheme, 'lang': lang, 'xml:lang': lang}
    req.chrome.setdefault('metas', []).append(meta)


def Nu_vertical_cylinder_Hanesian_Kalish_Morgan(Pr, Gr):
    """Calculates Nusselt number for natural convection around a vertical
    isothermal cylinder according to the results of [1]_ correlated by
    [2]_, also as presented in [3]_ and [4]_.

    .. math::
        Nu_H = 0.48 Ra_H^{0.23},\\; 10^{6} < Ra < 10^{8}

    Parameters
    ----------
    Pr : float
        Prandtl number [-]
    Gr : float
        Grashof number [-]

    Returns
    -------
    Nu : float
        Nusselt number, [-]

    Notes
    -----
    For air and fluoro-carbons. If outside of range, no warning is given.
    Laminar range only!

    Examples
    --------
    >>> Nu_vertical_cylinder_Hanesian_Kalish_Morgan(.7, 1E7)
    18.014150492696604

    References
    ----------
    .. [1] Hanesian, D. and Kalish, R. "Heat Transfer by Natural Convection
       with Fluorocarbon Gases." IEEE Transactions on Parts, Materials and
       Packaging 6, no. 4 (December 1970): 147-148.
       doi:10.1109/TPMP.1970.1136270.
    .. [2] Morgan, V.T., The Overall Convective Heat Transfer from Smooth
       Circular Cylinders, in Advances in Heat Transfer, eds. T.F. Irvin and
       J.P. Hartnett, V 11, 199-264, 1975.
    .. [3] Popiel, Czeslaw O. "Free Convection Heat Transfer from Vertical
       Slender Cylinders: A Review." Heat Transfer Engineering 29, no. 6
       (June 1, 2008): 521-36. doi:10.1080/01457630801891557.
    .. [4] Boetcher, Sandra K. S. "Natural Convection Heat Transfer From
       Vertical Cylinders." In Natural Convection from Circular Cylinders,
       23-42. Springer, 2014.
    """
    Ra = Pr * Gr
    return 0.48 * Ra ** 0.23


def deny_request(session, request_id, return_type=None, **kwargs):
    """
    Deny VPSAOS account requests.

    :type session: zadarapy.session.Session
    :param session: A valid zadarapy.session.Session object.  Required.

    :type request_id: str
    :param request_id: Request ID. Required.

    :type return_type: str
    :param return_type: If this is set to the string 'json', this function
        will return a JSON string.  Otherwise, it will return a Python
        dictionary.  Optional (will return a Python dictionary by default).

    :rtype: dict, str
    :returns: A dictionary or JSON data set as a string depending on
        return_type parameter.
    """
    path = '/api/requests/{0}/deny.json'.format(request_id)
    return session.post_api(path=path, return_type=return_type, **kwargs)


def lambd_H3PO4_H3PO4_PS76(T, P):
    """n-n: phosphoric-acid phosphoric-acid [PS76]."""
    lambd = 0.05031
    valid = T == 298.15
    return lambd, valid


def enable_evaluation():
    """
    Enable Add, Mul and Pow contractions
    """
    global _evaluate
    _evaluate = True


def date_to_iso8601(date):
    """Returns an ISO8601 string from a date"""
    datetimestr = date.strftime('%Y-%m-%dT%H:%M:%S')
    timezone_sign = date.strftime('%z')[0:1]
    timezone_str = '%s:%s' % (date.strftime('%z')[1:3], date.strftime('%z')
        [3:5])
    return '{datetimestr}{tzsign}{timezone}'.format(datetimestr=datetimestr,
        tzsign=timezone_sign, timezone=timezone_str).replace(':', '%3A'
        ).replace('+', '%2B')


def triage(parser, main=None, validate_args=None):
    """Triage the command-line presented.

    :param parser:
    :param main:
    :param validate_args:
    :return:
    """
    options, args = parser.parse_args()
    if options.doctest or not main:
        import doctest
    if validate_args:
        validate_args(parser, options, args)
        doctest.testmod(verbose=options.verbose)
    elif main:
        main()
    return options, args


def html5_field(name, base):
    """
    Takes a Django form field class and returns a subclass of
    it with the given name as its input type.
    """
    return type(str(''), (base,), {'input_type': name})


@classmethod
def install(kls, *types):
    """Create many types at the same time! and put them onto the Type class"""
    for name, size, fmt, conversion in types:
        if size is not None:
            setattr(kls, name, kls.t(name, fmt, conversion)(size))
        else:
            setattr(kls, name, kls.t(name, fmt, conversion))


def GetOpticalPowerSlopeAndOffset(*args, **kwargs):
    """ Stub Anduin function."""
    print('GetOpticalPowerSlopeAndOffset', args, kwargs)


def getInfFromSeqDesc(seq_desc):
    """
    Return sequencer id, run id, flowcell id and position of the sequence on the sequencer flowcell.

    :param sequence: The ID of the sequence provided by the sequencer.
    :type sequence: str
    :return: The sequencer id, run id, flowcell id and position of the sequence on the sequencer flowcell.
    :rtype: dict
    """
    reads_phases, kept_status, control_bits, barcode = seq_desc.split(':')
    return {'reads_phases': int(reads_phases), 'is_kept': kept_status ==
        'N', 'control_bits': None if control_bits == '0' else int(
        control_bits), 'barcode': None if barcode == '' else barcode}


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 getSchedulers():
    """Return a list of ISchedulerStatus objects for all
        currently-registered Schedulers."""


def foname(tag):
    """Append the fo: namespace to the tag.
    If the tag already have a namespace return the tag unmodified.
    """
    if not ':' in tag:
        return 'fo:%s' % tag
    else:
        return tag


@classmethod
def has_resuming(cls):
    """Returns whether it supports to resume the fetch process.

        :returns: this backend supports items resuming
        """
    return True


def show_doc_byline():
    """ Returns whether the document byline should be shown or not."""


def generate_branches(scales=None, angles=None, shift_angle=0):
    """Generates branches with alternative system.

    Args:
        scales (tuple/array): Indicating how the branch/es length/es develop/s from age to age.
        angles (tuple/array): Holding the branch and shift angle in radians.
        shift_angle (float): Holding the rotation angle for all branches.

    Returns:
        branches (2d-array): A array constits of arrays holding scale and angle for every branch.
    """
    branches = []
    for pos, scale in enumerate(scales):
        angle = -sum(angles) / 2 + sum(angles[:pos]) + shift_angle
        branches.append([scale, angle])
    return branches


def geodesic_euclid(A, B, alpha=0.5):
    """Return the matrix at the position alpha on the euclidean geodesic between A and B  :

    .. math::
            \\mathbf{C} = (1-\\alpha) \\mathbf{A} + \\alpha \\mathbf{B}

    C is equal to A if alpha = 0 and B if alpha = 1

    :param A: the first coavriance matrix
    :param B: the second coavriance matrix
    :param alpha: the position on the geodesic
    :returns: the covariance matrix

    """
    return (1 - alpha) * A + alpha * B


def check_buffer(coords, length, buffer):
    """
    check to see how much of the buffer is being used
    """
    s = min(coords[0], buffer)
    e = min(length - coords[1], buffer)
    return [s, e]


@classmethod
def current(cls):
    """Get the latest started `Coverage` instance, if any.

        Returns: a `Coverage` instance, or None.

        .. versionadded:: 5.0

        """
    if cls._instances:
        return cls._instances[-1]
    else:
        return None


def power_amplifier(s, thresh, pwr=2):
    """ Amplify elements of a positive-valued signal. Rescale the signal
        so that elements above thresh are equal to or greater than 1,
        and elements below thresh are less than one. Then take a power
        of the signal, which will supress values less than 1, and amplify
        values that are greater than one.
    """
    s /= s.max()
    s += 1.0 - thresh
    s = s ** pwr
    s -= (1.0 - thresh) ** pwr
    s /= s.max()
    return s


@staticmethod
def p_songbrackets(symbols):
    """songbrackets : SONG_LOPTIONS separator dictionary separator SONG_ROPTIONS
                        | empty
        """
    if len(symbols) == 6:
        symbols[0] = symbols[3]
    else:
        symbols[0] = {}


def _label(label):
    """
    Returns a query item matching a label.

    Args:
        label (str): The label the message must have applied.

    Returns:
        The query string.

    """
    return f'label:{label}'


def add_cache_buster(config, spec, cache_buster):
    """ Add a new cache buster to a particular set of assets """


def ghost_curves_create():
    """Create snapshot (Ghosts) of selected F-Curves as background aid for active Graph Editor

    """
    pass


def check_iotune(expected_param, result_param):
    """check block iotune configuration
    """
    for k in list(expected_param.keys()):
        if expected_param[k] != result_param[k]:
            return 1
    return 0


def getIgnored():
    """Return the list of ignored terms.

        Return the list of terms that were ignored by the most recent
        call to parseQuery() because they were stopwords.

        If parseQuery() was never called this returns None.
        """


def get_mobilenetv2_filename(key):
    """Rename tensor name to the corresponding Keras layer weight name.
    # Arguments
        key: tensor name in TF (determined by tf.variable_scope)
    """
    filename = str(key)
    filename = filename.replace('/', '_')
    filename = filename.replace('MobilenetV2_', '')
    filename = filename.replace('BatchNorm', 'BN')
    if 'Momentum' in filename:
        return None
    filename = filename.replace('_weights', '_kernel')
    filename = filename.replace('_biases', '_bias')
    return filename + '.npy'


@classmethod
def parse(cls, name, data_size, reader, parsers):
    """given a 4 byte name, data_size int, BitstreamReader
        and dict of {"atom":handler} sub-parsers,
        returns an atom of this class"""
    assert name == b'free'
    reader.skip_bytes(data_size)
    return cls(data_size)


@staticmethod
def _build_default_doc(record):
    """
        If a document does not have an `elastic_search_json` method, this
        method tries to build one in lieu.
        """
    return {'rec_name': record.rec_name}


def browserDefault(request):
    """The default step is our browserDefault traversal setp."""


def p_listmaker(p):
    """listmaker : expression listmaker2  """
    p[0] = [p[1]] + p[2]


@classmethod
def set_base_url(cls, base_url):
    """Load the base url and its derived urls."""
    cls.base_url = base_url
    cls.base_url_protocol = base_url.split(':')[0]
    cls.base_url_domain = cls.domain(base_url)


def archive_model(model, instance, **mapping):
    """
    Archives the instance to the given history model
    optionally maps field names from the instance model to the history model
    """
    archive = model()
    mapping['created'] = mapping['modified'] = None
    for field in instance._meta.get_fields():
        to_name = mapping.get(field.name, field.name)
        if to_name is not None:
            setattr(archive, to_name, getattr(instance, field.name, None))
    archive.save()
    return archive


def dict_override(a, b):
    """Overriding dictionary values.

    Values in second dictionary override the values in the first one (except
    when relevant value in second dictionary is None).

    >>> dict_override({'a': 1,'b': 2}, {'a': 3,'b': None}) == {'a': 3,'b': 2}
    True

    >>> dict_override({'a': 3,'b': None}, {'a': 1,'b': 2}) == {'a': 1,'b': 2}
    True

    >>> dict_override({'a': 6,'b': None}, {'b': 7}) == {'a': 6,'b': 7}
    True
    """
    res = {}
    for key in (set(a.keys()) | set(b.keys())):
        if key in b and b[key] != None:
            res[key] = b[key]
        else:
            res[key] = a[key]
    return res


def unblockable(function):
    """Decorate a function to exempt it from the ignore/blocks system.

    For example, this can be used to ensure that important events such as
    ``JOIN`` are always recorded::

        from sopel import module

        @module.event('JOIN')
        @module.unblockable
        def on_join_callable(bot, trigger):
            # do something when a user JOIN a channel
            # a blocked nickname or hostname *will* trigger this
            pass

    .. seealso::

        Sopel's :meth:`~sopel.bot.Sopel.dispatch` and
        :meth:`~sopel.bot.Sopel.get_triggered_callables` methods.

    """
    function.unblockable = True
    return function


def add_oval_filled(pic, x, y, w, h, col):
    """Draw a filled oval of Color col, width w, and height h on Picture pic.
    The upper left corner of the oval is at (x, y)."""
    pic.add_oval_filled(col, x, y, w, h)


def inheritdoc(method):
    """Set __doc__ of *method* to __doc__ of *method* in its parent class.

    Since this is used on :class:`.SmartList`, the "parent class" used is
    ``list``. This function can be used as a decorator.
    """
    method.__doc__ = getattr(list, method.__name__).__doc__
    return method


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 Mobility(Te, mu0, T0):
    """
    Temperature dependent mobility.

    See page 4 of Reference 1.

    35, 37, 38

    References
    ----------

    [1] Shiue et al. 2019
        URL: http://www.nature.com/articles/s41467-018-08047-3

    [2] Dorgan et al. 2013.
        URL: https://doi.org/10.1021/nl400197w

    [3] Bae et al. 2010
        URL: https://doi.org/10.1021/nl1011596
    """
    mu = mu0 * (Te / T0) ** 2.3
    return mu


def add_simple_uvs():
    """Add cube map uvs on mesh

    """
    pass


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 find_mixed_type_cols(df, fix=True):
    """For a given dataframe, find the columns that are of mixed type.

    Tool to help with the performance warning when trying to save a pandas DataFrame as a HDF.
    When a column changes datatype somewhere, pickling occurs, slowing down the reading process of the HDF file.

    Parameters
    ----------
    df : pandas.DataFrame
        Dataframe to be searched for mixed data-types
    fix : bool
        Switch to control if NaN values in these problem columns should be replaced by the string 'UNKNOWN'
    Returns
    -------
    List of column names that have data type changes within themselves.
    """
    result = []
    for col in df.columns:
        weird = (df[[col]].applymap(type) != df[[col]].iloc[0].apply(type)
            ).any(axis=1)
        if len(df[weird]) > 0:
            print(col)
            result.append(col)
    if fix is True:
        for col in result:
            df[col].fillna('UNKNOWN', inplace=True)
    return result


def distributed_fault_patches_to_config(patches):
    """
    Input: List of PsCmpRectangularSource(s)
    """
    srows = []
    for i, patch in enumerate(patches):
        srows.append('%i %s' % (i + 1, patch.string_for_config()))
    return '\n'.join(srows), len(srows)


@classmethod
def add_field(cls, rname, label, model, table, ftype):
    """ Insert a field definition

        :param rname: name of the field
        :param label: label of the field
        :param model: namespace of the model
        :param table: name of the table of the model
        :param ftype: type of the AnyBlok Field
        """
    cls.insert(code=table + '.' + rname, model=model, name=rname, label=
        label, ftype=ftype)


def check_user_password(username, password):
    """ Boolean return when username and password match user record. """
    from x84.bbs import find_user, get_user
    handle = find_user(username)
    if handle is None:
        return False
    user = get_user(handle)
    if user is None:
        return False
    return password and user.auth(password)


def newcol_mapped(orig_df, orig_col, new_col, mapping):
    """
    map a new column from an old column and a mapping dictionary
    """
    new_vals = orig_df[orig_col].map(mapping).values
    return orig_df.assign(**{new_col: new_vals})


def _command_name_to_metavar(command_name):
    """Transforms a command name to a better metaname (used for -h)."""
    return command_name.replace('set_', '').upper()


def temp_both(p_temp, h_temp):
    """
    Use this function as :attr:`~SenseEnviron.temp_source` if you wish
    to return both the pressure and humidity sensor's temperature readings as a
    tuple from the :attr:`~SenseEnviron.temperature` attribute.
    """
    return p_temp, h_temp


def normalize_ir_text(text):
    """
    Normalize the given string to latin1 compatible encoding that is
    suitable for use in LLVM IR.
    """
    return text.encode('utf8').decode('latin1')


def is_odd(num):
    """
  Determines whether a number is odd.

  :param num:
      Integer
  :returns:
      ``True`` if odd; ``False`` otherwise.
  """
    return bool(num & 1)


@staticmethod
def set_string_field(is_analyzed=True):
    """
        sets string mapping values
        :param bool is_analyzed: Analyzed status
        :return dictionary:
        """
    if is_analyzed:
        f_type = 'text'
    else:
        f_type = 'keyword'
    return {'type': f_type}


def make_closure_cell(x):
    """
  Creates a new Python cell object that can usually be found in a functions
  `__closure__` tuple. The values in a `__closure__` must match the free
  variables defined in the function's code object's `co_freevars` member.

  x (any): The cell contents.
  return (cell): A function closure cell object containing *x*.
  """
    return (lambda : x).__closure__[0]


def short_color(color):
    """ format a color to its short size """
    if len(color) > 6:
        return color[2:]
    return color


def task_type(inputs, include_calc_type=True):
    """
    Determines the task_type

    Args:
        inputs (dict): inputs dict with an incar, kpoints, potcar, and poscar dictionaries
        include_calc_type (bool): whether to include calculation type
            in task_type such as HSE, GGA, SCAN, etc.
    """
    calc_type = ''
    incar = inputs.get('incar', {})
    if include_calc_type:
        if incar.get('LHFCALC', False):
            calc_type += 'HSE '
        elif incar.get('METAGGA', '') == 'SCAN':
            calc_type += 'SCAN '
        elif incar.get('LDAU', False):
            calc_type += 'GGA+U '
        else:
            calc_type += 'GGA '
    if incar.get('ICHARG', 0) > 10:
        if len(list(filter(None, inputs.get('kpoints', {}).get('labels', [])))
            ) > 0:
            return calc_type + 'NSCF Line'
        else:
            return calc_type + 'NSCF Uniform'
    elif incar.get('LEPSILON', False):
        return calc_type + 'Static Dielectric'
    elif incar.get('LCHIMAG', False):
        return calc_type + 'NMR Chemical Shielding'
    elif incar.get('LEFG', False):
        return calc_type + 'NMR Electric Field Gradient'
    elif incar.get('NSW', 1) == 0:
        return calc_type + 'Static'
    elif incar.get('ISIF', 2) == 3 and incar.get('IBRION', 0) > 0:
        return calc_type + 'Structure Optimization'
    elif incar.get('ISIF', 3) == 2 and incar.get('IBRION', 0) > 0:
        return calc_type + 'Deformation'
    return ''


def avg(values):
    """
    Returns the average of a sequence of numbers.
    """
    if not values:
        return 0
    else:
        return sum(values) / len(values)


def _make_package(x):
    """Get the package name and drop the last '.' """
    package = ''
    for p in x:
        package += p[0] + p[1]
    if package and package[-1] == '.':
        package = package[:-1]
    return package


def _inverse(x):
    """Just a simple inverse for use in the InverseVariance"""
    return 1 / x


def _const_compare_digest_backport(a, b):
    """
    Compare two digests of equal length in constant time.

    The digests must be of type str/bytes.
    Returns True if the digests match, and False otherwise.
    """
    result = abs(len(a) - len(b))
    for l, r in zip(bytearray(a), bytearray(b)):
        result |= l ^ r
    return result == 0


def is_number(s):
    """Check if a string is a number or not."""
    try:
        float(s)
        return True
    except ValueError:
        return False


def make_list(value, sep=','):
    """Split strings around `sep` or return as is.

    Examples:
        >>> make_list('foo,bar')
        ['foo', 'bar']
        >>> make_list('foo,bar', sep='.')
        ['foo,bar']
        >>> make_list(3)
        3

    """
    return value.split(sep) if isinstance(value, str) else value


def datetimetostr(dt):
    """Return a RFC3339 date-time string corresponding to the given
    datetime object."""
    if dt.utcoffset() is not None:
        return dt.isoformat()
    else:
        return '%sZ' % dt.isoformat()


def serial_escape(value):
    """Escape string values that are elements of a list, for serialization."""
    return value.replace('\\', '\\\\').replace(' ', '\\ ')


def delete_listdict_keys(listOfDicts: list, toDelete: list) ->list:
    """ Deletes the given list of keys from a list dicts
    """
    new_data = []
    for row in listOfDicts:
        for delete in toDelete:
            if delete in row:
                del row[delete]
        new_data.append(row)
    return new_data


def write_list(data_list, save_path):
    """
    将list写入文本中,一个元素一行
    :return:
    """
    with open(save_path, 'w') as w:
        if data_list is None or len(data_list) == 0:
            return
        for data in data_list:
            w.write(str(data))
            w.write('\n')


def _len_guards(M):
    """Handle small or incorrect window lengths"""
    if int(M) != M or M < 0:
        raise ValueError('Window length M must be a non-negative integer')
    return M <= 1


def _string_dict(string):
    """splits a OCAD-string and returns a dict"""
    split_string = string.split('\t')
    i = 0
    string_dict = {}
    for codevalue in split_string:
        if i == 0:
            code = 'First'
            value = codevalue
        else:
            code = codevalue[0:1]
            value = codevalue[1:]
        string_dict[code] = value
        i += 1
    return string_dict


def _match_suffix(suffix, ffilter):
    """Return file type (textual description) for a given suffix.

    Parameters
    ----------
    suffix : str
        File extension to check (must include the leading dot).
    ffilter : dict
        ffilter : dict
        Known file types. The keys contain descriptions (names), whereas the
        values contain the corresponding file extension(s).

    Returns
    -------
    ftype : str | None
        File type (None if unknown file type).
    """
    for ftype, ext in ffilter.items():
        if suffix in ext:
            return ftype


def human_time(seconds):
    """
    Returns a human-friendly time string that is always exactly 6
    characters long.

    Depending on the number of seconds given, can be one of::

        1w 3d
        2d 4h
        1h 5m
        1m 4s
          15s

    Will be in color if console coloring is turned on.

    Parameters
    ----------
    seconds : int
        The number of seconds to represent

    Returns
    -------
    time : str
        A human-friendly representation of the given number of seconds
        that is always exactly 6 characters.
    """
    units = [('y', 60 * 60 * 24 * 7 * 52), ('w', 60 * 60 * 24 * 7), ('d',
        60 * 60 * 24), ('h', 60 * 60), ('m', 60), ('s', 1)]
    seconds = int(seconds)
    if seconds < 60:
        return '   {0:2d}s'.format(seconds)
    for i in range(len(units) - 1):
        unit1, limit1 = units[i]
        unit2, limit2 = units[i + 1]
        if seconds >= limit1:
            return '{0:2d}{1}{2:2d}{3}'.format(seconds // limit1, unit1,
                seconds % limit1 // limit2, unit2)
    return '  ~inf'


def _truncate_seq_pair(tokens_a, tokens_b, max_length):
    """Truncates a sequence pair in place to the maximum length."""
    while True:
        total_length = len(tokens_a) + len(tokens_b)
        if total_length <= max_length:
            break
        if len(tokens_a) > len(tokens_b):
            tokens_a.pop()
        else:
            tokens_b.pop()


def simple_crossing(a, b, c, d):
    """see :cpp:func:`S2EdgeUtil::SimpleCrossing`"""
    ab = a.cross_prod(b)
    acb = -ab.dot_prod(c)
    bda = ab.dot_prod(d)
    if acb * bda <= 0:
        return False
    cd = c.cross_prod(d)
    cbd = -cd.dot_prod(b)
    dac = cd.dot_prod(a)
    return acb * cbd > 0 and acb * dac > 0


def encode(sequence, converter):
    """convert a sequence to numbers using a given converter list"""
    newSeq = []
    for filename in sequence:
        if filename not in converter:
            newSeq.append(1)
        else:
            newSeq.append(converter.index(filename))
    return newSeq


def get_target(target_fqn):
    """
    This function returns the target object, module object, and the module's fully qualified name based on the provided fully qualified target name.
    """
    module_fqn = target_fqn.split('.')
    while True:
        try:
            module = __import__('.'.join(module_fqn))
            break
        except ImportError:
            module_fqn.pop()
            if len(module_fqn) == 0:
                raise Exception('Could not resolve target: %s' % repr(
                    target_fqn))
    pieces = target_fqn.split('.')
    obj = module
    for item in pieces[1:]:
        obj = getattr(obj, item)
    return obj, module, '.'.join(module_fqn)


def __str__():
    """Return the layout as a str value"""


def write_file(url):
    """ Writes file to cache """
    raise NotImplementedError


def merge_configs(base_config, new_config):
    """
    Merge static configurations.
    Used internally. Removes "family" key from the result, which is set explicitly by ExtractManager.push_config

    :param base_config: Base configuration
    :param new_config: Changes to apply
    :return: Merged configuration
    """
    config = dict(base_config)
    for k, v in new_config.items():
        if k == 'family':
            continue
        if k not in config:
            config[k] = v
        elif config[k] == v:
            continue
        elif isinstance(config[k], list):
            for el in v:
                if el not in config[k]:
                    config[k] = config[k] + [el]
        else:
            raise RuntimeError(
                "Extractor tries to override '{old_value}' value of '{key}' with '{new_value}'"
                .format(key=k, old_value=config[k], new_value=v))
    return config


def sRGB2RGB(img):
    """ this function converts a sRGB img to  linear RGB values.

        :param img: image to analyze, in sRGB
        :type img: numpy.ndarray
        :return: image to analyze, in RGB
        :rtyipe: numpy.ndarray
    """
    newimg = []
    for row in img:
        thisrow = []
        for pixel in row:
            thispixel = []
            for value in pixel:
                if value / 255 <= 0.04045:
                    thispixel.append(value / (255 * 12.92))
                else:
                    thispixel.append(((value / 255 + 0.055) / 1.055) ** 2.4)
            thisrow.append(thispixel)
        newimg.append(thisrow)
    return newimg


def probability_peak_exceeds_value(times, peakval):
    """This calculates the probability that periodogram values exceed the given
    peak value.

    This is from page 3 of Zechmeister and Kurster (2009)::

        Prob(p > p_best) = (1 − p_best)**((N−3)/2)

    where::

        p_best is the peak value in consideration
        N is the number of times

    Note that this is for the default normalization of the periodogram,
    e.g. P_normalized = P(omega), such that P represents the sample variance
    (see Table 1).

    Parameters
    ----------

    lspvals : np.array
        The periodogram power value array.

    peakval : float
        A single peak value to calculate the probability for.

    Returns
    -------

    prob: float
        The probability value.

    """
    return (1.0 - peakval) ** ((times.size - 3.0) / 2.0)


def checkbox(theWhere, theX, theY, theLabel, theState, theColor=13553358):
    """
	Display a checkbox. You can use the state parameter to monitor if the
	checkbox is checked or not.

	Parameters
	----------
	theWhere: np.ndarray
		image/frame where the component should be rendered.
	theX: int
		position X where the component should be placed.
	theY: int
		position Y where the component should be placed.
	theLabel: str
		text displayed besides the clickable checkbox square.
	theState: [bool]
		array or list of booleans whose first position, i.e. theState[0], will be used to store the current state of the checkbox: `True` means the checkbox is checked.
	theColor: uint
		color of the label in the format `0xRRGGBB`, e.g. `0xff0000` for red.

	Returns
	----------
	a boolean value that indicates the current state of the checkbox, `true` if it is checked.
	"""
    print('This is wrapper function to help code autocompletion.')


def update(monitor, epoch, _raw_metrics, lr=None):
    """
        Informs the monitor about quality measurements for a particular epoch.

        Args:
            epoch (int):
                Current epoch number

            _raw_metrics (Dict[str, float]):
                Scalar values for each quality metric that was measured on this
                epoch.

        Returns:
            bool: improved:
                True if the model has quality of the validation metrics have
                improved.

        Example:
            >>> from netharn.monitor import *  # NOQA
            >>> import netharn as nh
            >>> rng = np.random.RandomState(0)
            >>> monitor = Monitor(minimize=['loss'], min_lr=1e-5)
            >>> for epoch in range(200):
            >>>     _raw_metrics = {'loss': rng.rand(), 'miou': rng.rand()}
            >>>     lr = 1.0 / (10 ** max(1, epoch))
            >>>     monitor.update(epoch, _raw_metrics, lr)
            >>>     term_reason = monitor.is_done()
            >>>     if term_reason:
            >>>         print('MONITOR IS DONE. BREAK')
            >>>         break
            >>> print(monitor.is_done())
            >>> assert monitor._current_lr <= monitor.min_lr
            >>> print('monitor = {!r}'.format(monitor))
        """
    monitor._epochs.append(epoch)
    monitor._raw_metrics.append(_raw_metrics)
    monitor._ewma.update(_raw_metrics)
    if epoch is not None:
        monitor._current_epoch = epoch
    if lr is not None:
        monitor._current_lr = lr
    _smooth_metrics = monitor._ewma.average()
    monitor._smooth_metrics.append(_smooth_metrics.copy())
    improved_keys = monitor._improved(_smooth_metrics, monitor.
        _best_smooth_metrics)
    if improved_keys:
        if monitor._best_smooth_metrics is None:
            monitor._best_smooth_metrics = _smooth_metrics.copy()
            monitor._best_raw_metrics = _raw_metrics.copy()
        else:
            for key in improved_keys:
                monitor._best_smooth_metrics[key] = _smooth_metrics[key]
                monitor._best_raw_metrics[key] = _raw_metrics[key]
        monitor._best_epoch = epoch
        monitor._n_bad_epochs = 0
    else:
        monitor._n_bad_epochs += 1
    improved = len(improved_keys) > 0
    monitor._is_good.append(improved)
    return improved


def isochone_ratio(e, rd, r_hyp):
    """
    Get the isochone ratio as described in Spudich et al. (2013) PEER
    report, page 88.

    :param e:
        a float defining the E-path length, which is the distance from
        Pd(direction) point to hypocentre. In km.
    :param rd:
        float, distance from the site to the direct point.
    :param r_hyp:
        float, the hypocentre distance.
    :returns:
        c_prime, a float defining the isochone ratio
    """
    if e == 0.0:
        c_prime = 0.8
    elif e > 0.0:
        c_prime = 1.0 / (1.0 / 0.8 - (r_hyp - rd) / e)
    return c_prime


def _normalize_units(units):
    """
    Convert units to normalized form.

    Converts to lower case and if necessary applies one of the following
    transforms:

        millim[.]* -> mm
        centim[.]* -> cm
        inch[.]*   -> inches

    """
    normed = units.lower()
    if normed.startswith('inch'):
        normed = 'inches'
    elif normed.startswith('millim'):
        normed = 'mm'
    elif normed.startswith('centim'):
        normed = 'cm'
    return normed


def undo_all(changes):
    """Undo all the changes in CHANGES."""
    if changes is None:
        return
    for change in changes:
        if change.unifier is not None:
            change.unifier.delete(change.var)


def ibarlett(x):
    """
    Barlett inverse VST, more numerically stable than the inverse Anscombe VST
    """
    return x ** 2 / 4.0 - 3.0 / 8


@staticmethod
def serialize(val, protocol_version):
    """
        Given a value appropriate for this class, serialize it according to the
        protocol for this type and return the corresponding bytestring.
        """
    return val


def _unique_parnames(names):
    """
    Given a list of parnames, including possible duplicates, returns a new list
    of parnames with duplicates prepended by one or more underscores to make
    them unique.  This is also case insensitive.
    """
    upper_names = set()
    unique_names = []
    for name in names:
        name_upper = name.upper()
        while name_upper in upper_names:
            name = '_' + name
            name_upper = '_' + name_upper
        unique_names.append(name)
        upper_names.add(name_upper)
    return unique_names


def face_join(faces: 'bmesh.types.BMFace', remove: bool=True
    ) ->'bmesh.types.BMFace':
    """Joins a sequence of faces.

    :param faces: Sequence of faces.
    :type faces: 'bmesh.types.BMFace'
    :param remove: Remove the edges and vertices between the faces.
    :type remove: bool
    :return:  The newly created face or None on failure.
    """
    pass


def _par_indices(names):
    """
    Given a list of objects, returns a mapping of objects in that list to the
    index or indices at which that object was found in the list.
    """
    unique = {}
    for idx, name in enumerate(names):
        name = name.upper()
        if name in unique:
            unique[name].append(idx)
        else:
            unique[name] = [idx]
    return unique


def stars_and_pull_requests(repo_info):
    """Return total stars and pull requests"""
    try:
        data = repo_info.select('a.muted-link')
        try:
            stars = data[0].text.strip()
        except IndexError:
            stars = None
        try:
            pull_requests = data[1].text.strip()
        except IndexError:
            pull_requests = None
        return stars, pull_requests
    except AttributeError:
        return


@classmethod
def from_set(cls, database, key, data, clear=False):
    """
        Create and populate a Set object from a data set.
        """
    s = cls(database, key)
    if clear:
        s.clear()
    s.add(*data)
    return s


def write(data):
    """Writes the given chunk to the output buffer. To actually write the
        output to the network, use the flush() method below.

        ``data``,
            byte-string of data to buffer for writing to socket.
        """


def annotate_routes(router, prefix):
    """
    Annotate klein routes for compatibility with autoflask generator.
    """
    router.static_path = ''
    router.view_functions = router.endpoints
    for rule in router.url_map.iter_rules():
        rule.doc_prefix = prefix


@classmethod
def make_cmd(cls, argv=None, **kwargs):
    """
        Instanciate, initialize and return application.

        :param argv:
            Like :meth:`initialize()`, if undefined, replaced with ``sys.argv[1:]``.

        - Tip: Apply :func:`pump_cmd()` on return values to process
          generators of :meth:`run()`.
        - This functions is the 1st half of :meth:`launch_instance()` which
          invokes and discards :meth:`start()` results.
        """
    cmd = cls.instance(**kwargs)
    cmd.initialize(argv)
    return cmd


@staticmethod
def _fields_opts():
    """Returns command options in a form that can be handled by the
        command parser."""
    opts = {'-h': {'type': bool, 'default': False}, '-c': {'type': bool,
        'default': False}}
    return opts


def simple_digest(s):
    """
    Create a sum of the ordinal values of the characters passed in from s.

    .. code-block: javascript
        // The original javascript code.
        function simpleDigest(mystr) {
            var res = 0;
            for (var i = 0; i < mystr.length; i++) {
                res += mystr.charCodeAt(i);
            }
            return res;
        }

    :param s: The string to calculate the digest from.
    :return: Sum of ordinal values converted to a string.
    """
    res = 0
    for ch in s:
        res += ord(ch)
    return str(res)


@classmethod
def list_available_perspectives(cls) ->list:
    """List available strategy for multi-perspective matching."""
    return ['full', 'max-pooling', 'attentive', 'max-attentive']


def estimate_job_time(task):
    """Placeholder for alignment calculation time estimate.

    :param task:
    :return:
    """
    if task == 'alignment':
        return 10
    elif task == 'tree':
        return 60


def upper(series):
    """Transform all text to uppercase."""
    return series.str.upper()


def task_count(backend):
    """
    A task to allow getting the backend's task count. Should be supported.
    """
    return str(backend.task_count)


def normalize_path(path):
    """Resolve given path from relative into absolute form."""
    if './' not in path:
        return path
    atoms = []
    for atom in path.split('/'):
        if atom == '.':
            pass
        elif atom == '..':
            if atoms:
                atoms.pop()
        elif atom:
            atoms.append(atom)
    newpath = '/'.join(atoms)
    if path.startswith('/'):
        newpath = '/' + newpath
    return newpath


def unsubscribe(id):
    """ Unsubscribes the subscriber
        """


def Concat(*data, **kwargs):
    """Joins input arrays along a given axis.

    .. note:: `Concat` is deprecated. Use `concat` instead.

    The dimensions of the input arrays should be the same except the axis along
    which they will be concatenated.
    The dimension of the output array along the concatenated axis will be equal
    to the sum of the corresponding dimensions of the input arrays.

    The storage type of ``concat`` output depends on storage types of inputs

    - concat(csr, csr, ..., csr, dim=0) = csr
    - otherwise, ``concat`` generates output with default storage

    Example::

       x = [[1,1],[2,2]]
       y = [[3,3],[4,4],[5,5]]
       z = [[6,6], [7,7],[8,8]]

       concat(x,y,z,dim=0) = [[ 1.,  1.],
                              [ 2.,  2.],
                              [ 3.,  3.],
                              [ 4.,  4.],
                              [ 5.,  5.],
                              [ 6.,  6.],
                              [ 7.,  7.],
                              [ 8.,  8.]]

       Note that you cannot concat x,y,z along dimension 1 since dimension
       0 is not the same for all the input arrays.

       concat(y,z,dim=1) = [[ 3.,  3.,  6.,  6.],
                             [ 4.,  4.,  7.,  7.],
                             [ 5.,  5.,  8.,  8.]]

    Defined in src/operator/nn/concat.cc:L383
    This function support variable length of positional input.

    Parameters
    ----------
    data : Symbol[]
        List of arrays to concatenate
    dim : int, optional, default='1'
        the dimension to be concated.

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

    Returns
    -------
    Symbol
        The result symbol.

    Examples
    --------
    Concat two (or more) inputs along a specific dimension:

    >>> a = Variable('a')
    >>> b = Variable('b')
    >>> c = Concat(a, b, dim=1, name='my-concat')
    >>> c
    <Symbol my-concat>
    >>> SymbolDoc.get_output_shape(c, a=(128, 10, 3, 3), b=(128, 15, 3, 3))
    {'my-concat_output': (128L, 25L, 3L, 3L)}

    Note the shape should be the same except on the dimension that is being
    concatenated.
    """
    return 0,


def apply_delta_data(src_buf, src_buf_size, delta_buf, delta_buf_size, write):
    """
    Apply data from a delta buffer using a source buffer to the target file

    :param src_buf: random access data from which the delta was created
    :param src_buf_size: size of the source buffer in bytes
    :param delta_buf_size: size fo the delta buffer in bytes
    :param delta_buf: random access delta data
    :param write: write method taking a chunk of bytes

    **Note:** transcribed to python from the similar routine in patch-delta.c"""
    i = 0
    db = delta_buf
    while i < delta_buf_size:
        c = db[i]
        i += 1
        if c & 128:
            cp_off, cp_size = 0, 0
            if c & 1:
                cp_off = db[i]
                i += 1
            if c & 2:
                cp_off |= db[i] << 8
                i += 1
            if c & 4:
                cp_off |= db[i] << 16
                i += 1
            if c & 8:
                cp_off |= db[i] << 24
                i += 1
            if c & 16:
                cp_size = db[i]
                i += 1
            if c & 32:
                cp_size |= db[i] << 8
                i += 1
            if c & 64:
                cp_size |= db[i] << 16
                i += 1
            if not cp_size:
                cp_size = 65536
            rbound = cp_off + cp_size
            if rbound < cp_size or rbound > src_buf_size:
                break
            write(src_buf[cp_off:cp_off + cp_size])
        elif c:
            write(db[i:i + c])
            i += c
        else:
            raise ValueError('unexpected delta opcode 0')
    assert i == delta_buf_size, 'delta replay has gone wild'


def is_valid_mask(mask):
    """
    Validates a UNIX style permissions mask.  Mask must be octal.

    :type mask: str
    :param mask: The octal mask to be validated.  For example: '0755'.

    :rtype: bool
    :return: True or False depending on whether mask passes validation.
    """
    if mask is None:
        return False
    if not mask.isdigit():
        return False
    if len(mask) != 4:
        return False
    mask_values = ['0', '1', '2', '4', '5', '6', '7']
    if mask[0] != '0':
        return False
    for value in mask[1:]:
        if value not in mask_values:
            return False
    return True


def event_env_merge_info(app, env, _, other):
    """Called by Sphinx during phase 3 (resolving).

    * Combine child process' modified env with this one. Only changes should be new Imgur IDs since cache update is done
      in event_env_updated() after everything is merged and we're back to one process.

    :param sphinx.application.Sphinx app: Sphinx application object.
    :param sphinx.environment.BuildEnvironment env: Sphinx build environment.
    :param _: Not used.
    :param sphinx.environment.BuildEnvironment other: Sphinx build environment from child process.
    """
    other_album_cache = getattr(other, 'imgur_album_cache', None)
    other_image_cache = getattr(other, 'imgur_image_cache', None)
    if not other_album_cache and not other_image_cache:
        return
    album_cache = app.builder.env.imgur_album_cache
    image_cache = app.builder.env.imgur_image_cache
    assert env
    album_cache.update(other_album_cache)
    image_cache.update(other_image_cache)


def _a_encode_none(value, mapping):
    """
    None --> ['0', 'n']
    """
    return [b'0n']


def objects(*interfaces):
    """ Iterator of the latest objects modified by the current user optionally
            filtered by interfaces
        """


@classmethod
def _get_xsd_enum_values(cls, xsd_schemas, xml_field):
    """Get the distinct enum values from XSD schemas for a given XML field.

        Depending of the 'xsd_type' of the XML field, retrieve the distinct
        enum values and definitions from the XSD schemas.

        Parameters
        ----------
        xsd_schemas : list of etree.ElementTree
            List of parsed XSD schemas.
        xml_field : dict
            Dictionary describing the XML field, including a 'xsd_type' key
            linking the type to the enum type in (one of) the XSD schemas.

        Returns
        -------
        values : dict
            Dictionary containing the enum values as keys (in the datatype
            of the XML field) and the definitions as values.

        """
    values = None
    if xml_field.get('xsd_type', None):
        values = {}
        for schema in xsd_schemas:
            tree_values = schema.findall(
                './/{{http://www.w3.org/2001/XMLSchema}}simpleType[@name="{}"]/{{http://www.w3.org/2001/XMLSchema}}restriction/{{http://www.w3.org/2001/XMLSchema}}enumeration'
                .format(xml_field.get('xsd_type')))
            for e in tree_values:
                value = cls._typeconvert(e.get('value'), xml_field.get('type'))
                values[value] = e.findtext(
                    './{http://www.w3.org/2001/XMLSchema}annotation/{http://www.w3.org/2001/XMLSchema}documentation'
                    )
    return values


def get_tables():
    """Returns a C{list} of domain classes

        This should return a C{list} of tuples, each one containing the
        domain path as the first item, and a list of classes as
        the second. e.g. A 'from a.b import C, D' should be
        translated into the C{tuple} ('a.b', ['C', 'D']).
        @note: this information is used for database synchronization

        :returns: a C{list} of C{tuple} containing domain info
        """
    pass


@classmethod
def create_relocate_package(cls, package_name, shade_prefix=None, recursive
    =True):
    """Convenience constructor for a package relocation rule.

        Essentially equivalent to just using ``shading_relocate('package_name.**')``.

        :param string package_name: Package name to shade (eg, ``org.pantsbuild.example``).
        :param string shade_prefix: Optional prefix to apply to the package. Defaults to
          ``__shaded_by_pants__.``.
        :param bool recursive: Whether to rename everything under any subpackage of ``package_name``,
          or just direct children of the package. (Defaults to True).
        """
    return cls.create_relocate(from_pattern=cls._format_package_glob(
        package_name, recursive), shade_prefix=shade_prefix)


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 debian_package_install(packages, clean_package_cache=True):
    """Jinja utility method for building debian-based package install command.

    apt-get is not capable of installing .deb files from a URL and the
    template logic to construct a series of steps to install regular packages
    from apt repos as well as .deb files that need to be downloaded, manually
    installed, and cleaned up is complicated. This method will construct the
    proper string required to install all packages in a way that's a bit
    easier to follow.

    :param packages: a list of strings that are either packages to install
    from an apt repo, or URLs to .deb files
    :type packages: list

    :returns: string suitable to provide to RUN command in a Dockerfile that
    will install the given packages
    :rtype: string
    """
    cmds = []
    reg_packages, url_packages = [], []
    for package in packages:
        if package.startswith('http'):
            url_packages.append(package)
        else:
            reg_packages.append(package)
    if reg_packages:
        cmds.append('apt-get update')
        cmds.append('apt-get -y install --no-install-recommends {}'.format(
            ' '.join(reg_packages)))
        if clean_package_cache:
            cmds.append('apt-get clean')
            cmds.append('rm -rf /var/lib/apt/lists/*')
    for url in url_packages:
        name = url[url.rfind('/') + 1:]
        cmds.extend(['curl --location {} -o {}'.format(url, name),
            'dpkg -i {}'.format(name), 'rm -rf {}'.format(name)])
    return ' && '.join(cmds)


@staticmethod
def _wrap_unpack(bytestream, unpacker):
    """Return the first value when `unpacker` is run on `bytestream`.

        Parameters
        ----------
        bytestream : bytes
            The encoded data to unpack.
        unpacker : callable
            A callable function to use to unpack the data in `bytestream`. The
            `unpacker` should return a tuple containing unpacked values.
            Example: struct.Struct('>I').unpack.
        """
    return unpacker(bytestream)[0]


def renumerate(sequence):
    """
    Reverse emumerate - starts at the highest index (last item in the iterator) and counts down. This generator yields
    a tuple containing the index and item, starting with the last item in the iterator.

    Don't use reversed(list(enumerate(sequence))) as it's not efficient (it has to iterate through the whole sequence first.)

    :param sequence:
    :return:
    """
    for i in range(len(sequence) - 1, -1, -1):
        yield i, sequence[i]


def armature_apply():
    """Apply the current pose as the new rest pose

    """
    pass


def build_models(payment_class):
    """
    Here you can dynamically build a Model class that needs to have ForeignKey to Payment model
    """
    return []


@classmethod
def _field_model_ready(cls, model, field):
    """Called when a model is ready, for each field..

        May be used by a subclass to handle indexes related but not directly tied to this field

        Parameters
        ----------
        field : RedisField
            The field for which the indexes are ready

        """
    pass


def setQualifiedRights(qualified_rights):
    """Set the qualified Rights elements.

        The argument must be a sequence of Rights `IDublinCoreElementItem`.
        """


def get_resource_filename(manager, resource_name):
    """Return a true filesystem path for `resource_name`

        `manager` must be an ``IResourceManager``"""


def prep_sr_lookup(osver):
    """
    Prepare software lookup XML.

    :param osver: OS version to lookup, 10.x.y.zzzz.
    :type osver: str
    """
    query = (
        '<?xml version="1.0" encoding="UTF-8"?><srVersionLookupRequest version="2.0.0" authEchoTS="1366644680359"><clientProperties><hardware><pin>0x2FFFFFB3</pin><bsn>1140011878</bsn><imei>004402242176786</imei><id>0x8D00240A</id><isBootROMSecure>true</isBootROMSecure></hardware><network><vendorId>0x0</vendorId><homeNPC>0x60</homeNPC><currentNPC>0x60</currentNPC><ecid>0x1</ecid></network><software><currentLocale>en_US</currentLocale><legalLocale>en_US</legalLocale><osVersion>{0}</osVersion><omadmEnabled>false</omadmEnabled></software></clientProperties></srVersionLookupRequest>'
        .format(osver))
    return query


@staticmethod
def __rounded_time_shift(time_shift):
    """
        Return the given time shift in seconds, but rounded to
        full hours. The argument is also assumed to be given in
        seconds.
        """
    minute = 60.0
    hour = 60.0 * minute
    if time_shift == 0:
        return 0.0
    absolute_time_shift = abs(time_shift)
    signum = time_shift / absolute_time_shift
    absolute_rounded_time_shift = int((absolute_time_shift + 7.5 * minute) /
        (15.0 * minute)) * (15.0 * minute)
    return signum * absolute_rounded_time_shift


def _filter_by_attr(list_in, attr_name, attr_val, match_substring=False):
    """
    Filter input list by the value of its elements' attributes.
    """
    list_out = []
    for val in list_in:
        if match_substring:
            if attr_val in getattr(val, attr_name):
                list_out.append(val)
        elif getattr(val, attr_name) == attr_val:
            list_out.append(val)
    return list_out


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

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

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


def rosenbrock_2D_d(x1, x2):
    """ Return the value of the Rosenbrock function's derivative. """
    return 100 * (-4 * x2 * x1 + 4 * x1 ** 3) + (-2 * x1 + 2 * x1
        ), 2 * x2 - 2 * x1 ** 2


def fill_with_dflts(d, dflt_dict=None):
    """
    Fed up with multiline handling of dict arguments?
    Fed up of repeating the if d is None: d = {} lines ad nauseam (because defaults can't be dicts as a default
    because dicts are mutable blah blah, and the python kings don't seem to think a mutable dict is useful enough)?
    Well, my favorite solution would be a built-in handling of the problem of complex/smart defaults,
    that is visible in the code and in the docs. But for now, here's one of the tricks I use.

    Main use is to handle defaults of function arguments. Say you have a function `func(d=None)` and you want
    `d` to be a dict that has at least the keys `foo` and `bar` with default values 7 and 42 respectively.
    Then, in the beginning of your function code you'll say:

        d = fill_with_dflts(d, {'a': 7, 'b': 42})

    See examples to know how to use it.

    ATTENTION: A shallow copy of the dict is made. Know how that affects you (or not).
    ATTENTION: This is not recursive: It won't be filling any nested fields with defaults.

    Args:
        d: The dict you want to "fill"
        dflt_dict: What to fill it with (a {k: v, ...} dict where if k is missing in d, you'll get a new field k, with
            value v.

    Returns:
        a dict with the new key:val entries (if the key was missing in d).

    >>> fill_with_dflts(None)
    {}
    >>> fill_with_dflts(None, {'a': 7, 'b': 42})
    {'a': 7, 'b': 42}
    >>> fill_with_dflts({}, {'a': 7, 'b': 42})
    {'a': 7, 'b': 42}
    >>> fill_with_dflts({'b': 1000}, {'a': 7, 'b': 42})
    {'a': 7, 'b': 1000}
    """
    if d is None:
        d = {}
    if dflt_dict is None:
        dflt_dict = {}
    return dict(dflt_dict, **d)


def int2uint32(value):
    """
    Convert a signed 32 bits integer into an unsigned 32 bits integer.

    >>> print(int2uint32(1))
    1
    >>> print(int2uint32(2**32 + 1))  # ignore bits larger than 32 bits
    1
    >>> print(int2uint32(-1))
    4294967295
    """
    return value & 4294967295


def process_row(row_tag):
    """
    return row_tag as a list of HTML-tag-stripped strings

    row_tag: a <tr> bs4 Tag, where each column contains exactly one string
    """
    res = []
    for tag in row_tag.children:
        if not tag.string or tag.string.isspace():
            res.append(None)
        else:
            res.append(tag.string)
    return res


def second_bashforth(state, tendencies_list, timestep):
    """Return the new state using second-order Adams-Bashforth. tendencies_list
    should be a list of dictionaries whose values are tendencies in
    units/second (from oldest to newest), and timestep should be a timedelta
    object. The dictionaries in tendencies_list should all have the same keys.
    """
    return_state = {}
    for key in tendencies_list[0].keys():
        return_state[key] = state[key] + timestep.total_seconds() * (1.5 *
            tendencies_list[-1][key] - 0.5 * tendencies_list[-2][key])
    return return_state


def p_fully_qualified_class_name(p):
    """fully_qualified_class_name : namespace_name
                                  | NS_SEPARATOR namespace_name
                                  | NAMESPACE NS_SEPARATOR namespace_name"""
    if len(p) == 2:
        p[0] = p[1]
    elif len(p) == 3:
        p[0] = p[1] + p[2]
    else:
        p[0] = p[1] + p[2] + p[3]


def __call__(source):
    """Set ``self.anchor`` refering to given source.

        @param source: ``ISource`` implementation.
        """


def _fk_colspec(fk, metadata_schema):
    """Implement a 'safe' version of ForeignKey._get_colspec() that
    never tries to resolve the remote table.

    """
    if metadata_schema is None:
        return fk._get_colspec()
    else:
        tokens = fk._colspec.split('.')
        if len(tokens) == 2:
            return '%s.%s' % (metadata_schema, fk._colspec)
        else:
            return fk._colspec


@classmethod
def store_obj(cls, intf, obj):
    """Stores the topo object. """
    cls.topo_intf_obj_dict[intf] = obj


def pig_step_properties(script, arguments=None, input=None, output=None):
    """
    Create pig step properties

    :param script: the script path of step
    :type script: string

    :param arguments: arguments for the step
    :type arguments: string

    :param input: the input path of step
    :type input: string

    :param output: the output path of step
    :type output: string

    :return:
    :rtype map
    """
    pig_step = {'script': script}
    if arguments is not None:
        pig_step['arguments'] = arguments
    if input is not None:
        pig_step['input'] = input
    if output is not None:
        pig_step['output'] = output
    return pig_step


def make_rpc_name(name):
    """
    Convert python compatible name to Transmission RPC name.
    """
    return name.replace('_', '-')


def sortKey():
    """Sort key used to order distributed transactions

        When a transaction involved multiple storages, 2-phase commit
        operations are applied in sort-key order.  This must be unique
        among storages used in a transaction. Obviously, the storage
        can't assure this, but it should construct the sort key so it
        has a reasonable chance of being unique.

        The result must be a string.
        """


def freestyle_linestyle_new():
    """Create a new line style, reusable by multiple line sets

    """
    pass


def str_rea_metabolites(rea_metbolites):
    """
    convert reaction.metabolites to str

    :param rea_metbolites: reaction.metabolites a special dictionary
    :return: a str of rea_metbolites
    eval(str_rea_metabolites(rea_metbolites)) could be a normal dictionary
    """
    temp_dic = {}
    for k, v in rea_metbolites.items():
        temp_dic[k.id] = v
    str_mets = str(temp_dic)
    return str_mets


def channels_expand(all: bool=True):
    """Expand (i.e. open) all selected expandable animation channels

    :param all: All, Expand all channels (not just selected ones)
    :type all: bool
    """
    pass


@classmethod
def set_controller(cls, controller):
    """Sets which :class:`rasblite.engine.Controller` to use by the RequestHandler

        :param rasblite.engine.Controller controller: controller to use
        """
    cls.controller = controller


def filter_lambda(Input_Dict):
    """
    Filter lambda parameter.

    :param Input_Dict: input parameters dictionary
    :type Input_Dict : dict
    :return: modified dictionary
    """
    try:
        if Input_Dict['lambda'] > 23:
            Input_Dict['lambda'] = 23
            print(
                '[Warning] Opem Automatically Set Lambda To Maximum Value (23) '
                )
        elif Input_Dict['lambda'] < 14:
            Input_Dict['lambda'] = 23
            print(
                '[Warning] Opem Automatically Set Lambda To Minimum Value (14) '
                )
        return Input_Dict
    except Exception:
        return Input_Dict


@classmethod
def load(cls, activity, course, save=True, **kwargs):
    """
        Handles loading data for a non-quiz unit
        :param activity:
        :param course:
        :param kwargs:
        :return: DataFrame
        """


def get_plain_text(values, strip=True):
    """Get the first value in a list of values that we expect to be plain-text.
    If it is a dict, then return the value of "value".

    :param list values: a list of values
    :param boolean strip: true if we should strip the plaintext value
    :return: a string or None
    """
    if values:
        v = values[0]
        if isinstance(v, dict):
            v = v.get('value', '')
        if strip:
            v = v.strip()
        return v


def _represent_numpy_float(dumper, npfloat: 'numpy.float_') ->str:
    """
    Convert the passed Numpy float into a YAML-formatted string.

    Specifically, this function returns a stringified YAML float equivalent to
    the passed float.

    Parameters
    ----------
    dumper: yaml.Dumper
        Object converting arbitrary Python objects to YAML-formatted strings.
    npfloat: numpy.ndarray
        Numpy float to be converted into a YAML-formatted string.

    Returns
    ----------
    str
        YAML-formatted string representing this Numpy float.
    """
    return dumper.represent_float(float(npfloat))


def pad(b, block_size):
    """
    padding to blocksize according to PKCS #7
    """
    padsize = block_size - len(b) % block_size
    return b + padsize * bytes(bytearray([padsize]))


def viz_b(body):
    """Create HTML b for graphviz"""
    return '<B>{}</B>'.format(body)


@classmethod
def is_valid_status(cls, status):
    """
        Makes sure that passed in status string is valid
        """
    return cls.is_completed_status(status) or cls.is_incomplete_status(status)


@staticmethod
def get_mac_wrapped_library_file(target_configuration):
    """ Return the full pathname of the file that implements the library
        being wrapped by the module as it would be called on OS/X so that the
        module will reference it explicitly without DYLD_LIBRARY_PATH being
        set.  If it is None or an empty string then the default is used.
        target_configuration is the target configuration.
        """
    return None


def list_percelen_adapter(obj, request):
    """
    Adapter for rendering a list of
    :class:`crabpy.gateway.crab.Perceel` to json.
    """
    return {'id': obj.id}


def within_range(df, items=None):
    """
    Assert that a DataFrame is within a range.

    Parameters
    ==========
    df : DataFame
    items : dict
        mapping of columns (k) to a (low, high) tuple (v)
        that ``df[k]`` is expected to be between.
    """
    for k, (lower, upper) in items.items():
        if (lower > df[k]).any() or (upper < df[k]).any():
            raise AssertionError
    return df


def _int_or_none(s):
    """
    Parse a string into an integer, returning None if the string was empty.

    Raises ValueError otherwise.
    """
    return int(s) if s else None


def findFEATImage(overlayList, overlay):
    """Searches the given :class:`.OverlayList` to see if there is a
    :class:`.FEATImage` associated with the given ``overlay``. Returns the
    ``FEATImage`` if found, otherwise returns ``None``.
    """
    import fsl.data.featanalysis as featanalysis
    import fsl.data.featimage as featimage
    if isinstance(overlay, featimage.FEATImage):
        return overlay
    if overlay is None:
        return None
    if overlay.dataSource is None:
        return None
    featPath = featanalysis.getAnalysisDir(overlay.dataSource)
    if featPath is None:
        return None
    dataPath = featanalysis.getDataFile(featPath)
    featImage = overlayList.find(dataPath)
    return featImage


def which_argument(arguments, options):
    """Return which of the given constant options was specified in the given
    argument source parsed by docopt."""
    for check in options:
        if arguments[check]:
            return check


def _migrate_dataset_schema(data, client):
    """Migrate from old dataset formats."""
    if 'authors' not in data:
        return
    data['@context']['creator'] = data['@context'].pop('authors', {
        '@container': 'list'})
    data['creator'] = data.pop('authors', {})
    files = data.get('files', [])
    if isinstance(files, dict):
        files = files.values()
    for file_ in files:
        file_['creator'] = file_.pop('authors', {})
    return data


def add_template(endpoint_template):
    """
        Add a new template for the external API.

        :param six.text_type endpoint_template: a :obj:`IEndpointTemplate` to add to the
            :obj:`IExternalAPIMock` instance
        :raises: ValueError if the endpoint template has already been added
        :raises: TypeError if the endpoint template does not implement
            the expected interface (IEndpointTempalte)
        """


def union(f, g):
    """Return the union of two FSTs"""
    res = f.copy()
    res.disjunct(g)
    res.minimize()
    return res


def note_off_event(current_track, tick, channel, pitch):
    """appends a note off event"""
    current_track.append([128, 2, tick, channel, 0, pitch, 0])


def check_palette(palette):
    """Check a palette argument (to the :class:`Writer` class)
    for validity.  Returns the palette as a list if okay; raises an
    exception otherwise.
    """
    if palette is None:
        return None
    p = list(palette)
    if not 0 < len(p) <= 256:
        raise ValueError('a palette must have between 1 and 256 entries')
    seen_triple = False
    for i, t in enumerate(p):
        if len(t) not in (3, 4):
            raise ValueError(
                'palette entry %d: entries must be 3- or 4-tuples.' % i)
        if len(t) == 3:
            seen_triple = True
        if seen_triple and len(t) == 4:
            raise ValueError(
                'palette entry %d: all 4-tuples must precede all 3-tuples' % i)
        for x in t:
            if int(x) != x or not 0 <= x <= 255:
                raise ValueError(
                    'palette entry %d: values must be integer: 0 <= x <= 255' %
                    i)
    return p


def _get_wind_direction(wind_direction_degree: float) ->str:
    """Convert wind direction degree to named direction."""
    if 11.25 <= wind_direction_degree < 33.75:
        return 'NNE'
    if 33.75 <= wind_direction_degree < 56.25:
        return 'NE'
    if 56.25 <= wind_direction_degree < 78.75:
        return 'ENE'
    if 78.75 <= wind_direction_degree < 101.25:
        return 'E'
    if 101.25 <= wind_direction_degree < 123.75:
        return 'ESE'
    if 123.75 <= wind_direction_degree < 146.25:
        return 'SE'
    if 146.25 <= wind_direction_degree < 168.75:
        return 'SSE'
    if 168.75 <= wind_direction_degree < 191.25:
        return 'S'
    if 191.25 <= wind_direction_degree < 213.75:
        return 'SSW'
    if 213.75 <= wind_direction_degree < 236.25:
        return 'SW'
    if 236.25 <= wind_direction_degree < 258.75:
        return 'WSW'
    if 258.75 <= wind_direction_degree < 281.25:
        return 'W'
    if 281.25 <= wind_direction_degree < 303.75:
        return 'WNW'
    if 303.75 <= wind_direction_degree < 326.25:
        return 'NW'
    if 326.25 <= wind_direction_degree < 348.75:
        return 'NNW'
    return 'N'


def validate_project_element_name(name):
    """"Validate name for a test, page or suite.
    `name` must be a relative dot path from the base element folder.
    """
    errors = []
    parts = name.split('.')
    last_part = parts.pop()
    for part in parts:
        if len(part) == 0:
            errors.append('Directory name cannot be empty')
            break
    if len(last_part) == 0:
        errors.append('File name cannot be empty')
    for c in name:
        if not c.isalnum() and c not in ['_', '.']:
            errors.append('Only letters, numbers and underscores are allowed')
            break
    return errors


@staticmethod
def object_exists_stmt(schema_name: str, child_name='', table: bool=False,
    view: bool=False):
    """ Returns statement that, when executed, returns TRUE when the current object (of specified type) exists
        """
    if table or view:
        if table:
            sql_runner = 'tables'
        elif view:
            sql_runner = 'views'
        join = (
            f"JOIN sys.{sql_runner} o ON o.schema_id = s.schema_id AND o.name='{child_name}'"
            )
    else:
        join = ''
    return (
        f"EXISTS (SELECT 1 FROM sys.schemas s {join} WHERE s.name='{schema_name}')"
        )


@staticmethod
def template_context(record):
    """Generate the tempalte context

        This is mainly to assist in the inheritance pattern
        """
    return {'record': record}


def parse_object(response, infotype):
    """
    Parse the results of an OBJECT command
    """
    if infotype in ('idletime', 'refcount'):
        return int(response)
    return response


@classmethod
def get(cls, id):
    """ Get transfer details """
    d = cls.client.request('/transfers/%i' % id, method='GET')
    t = d['transfer']
    return cls(t)


def escape_table_cell_value(text: str) ->str:
    """
    Escape pipe characters `|` in a table cell's value. Since the pipe characters
    are used to separate cells in a row, we need to replace them by `\\|`.
    """
    return text.replace('|', '\\|')


def pprint_dist_dict(int_dict, indent=4, descending=False):
    """Prints the given dict, representing a normalized distribution, nicely.

    Parameters
    ----------
    int_dict : list
        A dict object mapping each key to an int value between 0 and 1, and all
        values sum to 1.
    """
    sorted_tup = sorted(int_dict.items(), key=lambda x: x[1])
    if descending:
        sorted_tup.reverse()
    print('{')
    for tup in sorted_tup:
        print('{}{}: {:.2f} %'.format(' ' * indent, tup[0], tup[1] * 100))
    print('}')


@classmethod
def get(cls, definition, ctx=None):
    """Get a ``Counter``."""
    return cls.query.get(definition.format(**ctx or {}))