def send_email(Source=None, Destination=None, Message=None,
    ReplyToAddresses=None, ReturnPath=None, SourceArn=None, ReturnPathArn=
    None, Tags=None, ConfigurationSetName=None):
    """
    Composes an email message based on input data, and then immediately queues the message for sending.
    There are several important points to know about SendEmail :
    See also: AWS API Documentation

    Examples
    The following example sends a formatted email:
    Expected Output:

    :example: response = client.send_email(
        Source='string',
        Destination={
            'ToAddresses': [
                'string',
            ],
            'CcAddresses': [
                'string',
            ],
            'BccAddresses': [
                'string',
            ]
        },
        Message={
            'Subject': {
                'Data': 'string',
                'Charset': 'string'
            },
            'Body': {
                'Text': {
                    'Data': 'string',
                    'Charset': 'string'
                },
                'Html': {
                    'Data': 'string',
                    'Charset': 'string'
                }
            }
        },
        ReplyToAddresses=[
            'string',
        ],
        ReturnPath='string',
        SourceArn='string',
        ReturnPathArn='string',
        Tags=[
            {
                'Name': 'string',
                'Value': 'string'
            },
        ],
        ConfigurationSetName='string'
    )

    :type Source: string
    :param Source: [REQUIRED]
            The email address that is sending the email. This email address must be either individually verified with Amazon SES, or from a domain that has been verified with Amazon SES. For information about verifying identities, see the Amazon SES Developer Guide .
            If you are sending on behalf of another user and have been permitted to do so by a sending authorization policy, then you must also specify the SourceArn parameter. For more information about sending authorization, see the Amazon SES Developer Guide .
            In all cases, the email address must be 7-bit ASCII. If the text must contain any other characters, then you must use MIME encoded-word syntax (RFC 2047) instead of a literal string. MIME encoded-word syntax uses the following form: =?charset?encoding?encoded-text?= . For more information, see RFC 2047 .

    :type Destination: dict
    :param Destination: [REQUIRED]
            The destination for this email, composed of To:, CC:, and BCC: fields.
            ToAddresses (list) --The To: field(s) of the message.
            (string) --
            CcAddresses (list) --The CC: field(s) of the message.
            (string) --
            BccAddresses (list) --The BCC: field(s) of the message.
            (string) --

    :type Message: dict
    :param Message: [REQUIRED]
            The message to be sent.
            Subject (dict) -- [REQUIRED]The subject of the message: A short summary of the content, which will appear in the recipient's inbox.
            Data (string) -- [REQUIRED]The textual data of the content.
            Charset (string) --The character set of the content.
            Body (dict) -- [REQUIRED]The message body.
            Text (dict) --The content of the message, in text format. Use this for text-based email clients, or clients on high-latency networks (such as mobile devices).
            Data (string) -- [REQUIRED]The textual data of the content.
            Charset (string) --The character set of the content.
            Html (dict) --The content of the message, in HTML format. Use this for email clients that can process HTML. You can include clickable links, formatted text, and much more in an HTML message.
            Data (string) -- [REQUIRED]The textual data of the content.
            Charset (string) --The character set of the content.

    :type ReplyToAddresses: list
    :param ReplyToAddresses: The reply-to email address(es) for the message. If the recipient replies to the message, each reply-to address will receive the reply.
            (string) --

    :type ReturnPath: string
    :param ReturnPath: The email address to which bounces and complaints are to be forwarded when feedback forwarding is enabled. If the message cannot be delivered to the recipient, then an error message will be returned from the recipient's ISP; this message will then be forwarded to the email address specified by the ReturnPath parameter. The ReturnPath parameter is never overwritten. This email address must be either individually verified with Amazon SES, or from a domain that has been verified with Amazon SES.

    :type SourceArn: string
    :param SourceArn: This parameter is used only for sending authorization. It is the ARN of the identity that is associated with the sending authorization policy that permits you to send for the email address specified in the Source parameter.
            For example, if the owner of example.com (which has ARN arn:aws:ses:us-east-1:123456789012:identity/example.com ) attaches a policy to it that authorizes you to send from user@example.com , then you would specify the SourceArn to be arn:aws:ses:us-east-1:123456789012:identity/example.com , and the Source to be user@example.com .
            For more information about sending authorization, see the Amazon SES Developer Guide .

    :type ReturnPathArn: string
    :param ReturnPathArn: This parameter is used only for sending authorization. It is the ARN of the identity that is associated with the sending authorization policy that permits you to use the email address specified in the ReturnPath parameter.
            For example, if the owner of example.com (which has ARN arn:aws:ses:us-east-1:123456789012:identity/example.com ) attaches a policy to it that authorizes you to use feedback@example.com , then you would specify the ReturnPathArn to be arn:aws:ses:us-east-1:123456789012:identity/example.com , and the ReturnPath to be feedback@example.com .
            For more information about sending authorization, see the Amazon SES Developer Guide .

    :type Tags: list
    :param Tags: A list of tags, in the form of name/value pairs, to apply to an email that you send using SendEmail . Tags correspond to characteristics of the email that you define, so that you can publish email sending events.
            (dict) --Contains the name and value of a tag that you can provide to SendEmail or SendRawEmail to apply to an email.
            Message tags, which you use with configuration sets, enable you to publish email sending events. For information about using configuration sets, see the Amazon SES Developer Guide .
            Name (string) -- [REQUIRED]The name of the tag. The name must:
            Contain only ASCII letters (a-z, A-Z), numbers (0-9), underscores (_), or dashes (-).
            Contain less than 256 characters.
            Value (string) -- [REQUIRED]The value of the tag. The value must:
            Contain only ASCII letters (a-z, A-Z), numbers (0-9), underscores (_), or dashes (-).
            Contain less than 256 characters.

    :type ConfigurationSetName: string
    :param ConfigurationSetName: The name of the configuration set to use when you send an email using SendEmail .

    :rtype: dict
    :return: {
        'MessageId': 'string'
    }

    :returns:
    Source (string) -- [REQUIRED]
    The email address that is sending the email. This email address must be either individually verified with Amazon SES, or from a domain that has been verified with Amazon SES. For information about verifying identities, see the Amazon SES Developer Guide .
    If you are sending on behalf of another user and have been permitted to do so by a sending authorization policy, then you must also specify the SourceArn parameter. For more information about sending authorization, see the Amazon SES Developer Guide .
    In all cases, the email address must be 7-bit ASCII. If the text must contain any other characters, then you must use MIME encoded-word syntax (RFC 2047) instead of a literal string. MIME encoded-word syntax uses the following form: =?charset?encoding?encoded-text?= . For more information, see RFC 2047 .

    Destination (dict) -- [REQUIRED]
    The destination for this email, composed of To:, CC:, and BCC: fields.

    ToAddresses (list) --The To: field(s) of the message.

    (string) --

    CcAddresses (list) --The CC: field(s) of the message.

    (string) --

    BccAddresses (list) --The BCC: field(s) of the message.

    (string) --

    Message (dict) -- [REQUIRED]
    The message to be sent.

    Subject (dict) -- [REQUIRED]The subject of the message: A short summary of the content, which will appear in the recipient's inbox.

    Data (string) -- [REQUIRED]The textual data of the content.

    Charset (string) --The character set of the content.

    Body (dict) -- [REQUIRED]The message body.

    Text (dict) --The content of the message, in text format. Use this for text-based email clients, or clients on high-latency networks (such as mobile devices).

    Data (string) -- [REQUIRED]The textual data of the content.

    Charset (string) --The character set of the content.

    Html (dict) --The content of the message, in HTML format. Use this for email clients that can process HTML. You can include clickable links, formatted text, and much more in an HTML message.

    Data (string) -- [REQUIRED]The textual data of the content.

    Charset (string) --The character set of the content.

    ReplyToAddresses (list) -- The reply-to email address(es) for the message. If the recipient replies to the message, each reply-to address will receive the reply.

    (string) --

    ReturnPath (string) -- The email address to which bounces and complaints are to be forwarded when feedback forwarding is enabled. If the message cannot be delivered to the recipient, then an error message will be returned from the recipient's ISP; this message will then be forwarded to the email address specified by the ReturnPath parameter. The ReturnPath parameter is never overwritten. This email address must be either individually verified with Amazon SES, or from a domain that has been verified with Amazon SES.
    SourceArn (string) -- This parameter is used only for sending authorization. It is the ARN of the identity that is associated with the sending authorization policy that permits you to send for the email address specified in the Source parameter.
    For example, if the owner of example.com (which has ARN arn:aws:ses:us-east-1:123456789012:identity/example.com ) attaches a policy to it that authorizes you to send from user@example.com , then you would specify the SourceArn to be arn:aws:ses:us-east-1:123456789012:identity/example.com , and the Source to be user@example.com .
    For more information about sending authorization, see the Amazon SES Developer Guide .

    ReturnPathArn (string) -- This parameter is used only for sending authorization. It is the ARN of the identity that is associated with the sending authorization policy that permits you to use the email address specified in the ReturnPath parameter.
    For example, if the owner of example.com (which has ARN arn:aws:ses:us-east-1:123456789012:identity/example.com ) attaches a policy to it that authorizes you to use feedback@example.com , then you would specify the ReturnPathArn to be arn:aws:ses:us-east-1:123456789012:identity/example.com , and the ReturnPath to be feedback@example.com .
    For more information about sending authorization, see the Amazon SES Developer Guide .

    Tags (list) -- A list of tags, in the form of name/value pairs, to apply to an email that you send using SendEmail . Tags correspond to characteristics of the email that you define, so that you can publish email sending events.

    (dict) --Contains the name and value of a tag that you can provide to SendEmail or SendRawEmail to apply to an email.
    Message tags, which you use with configuration sets, enable you to publish email sending events. For information about using configuration sets, see the Amazon SES Developer Guide .

    Name (string) -- [REQUIRED]The name of the tag. The name must:

    Contain only ASCII letters (a-z, A-Z), numbers (0-9), underscores (_), or dashes (-).
    Contain less than 256 characters.

    Value (string) -- [REQUIRED]The value of the tag. The value must:

    Contain only ASCII letters (a-z, A-Z), numbers (0-9), underscores (_), or dashes (-).
    Contain less than 256 characters.

    ConfigurationSetName (string) -- The name of the configuration set to use when you send an email using SendEmail .

    """
    pass


def _disables_array_ufunc(obj):
    """True when __array_ufunc__ is set to None."""
    try:
        return obj.__array_ufunc__ is None
    except AttributeError:
        return False


def smoothstep(a, b, x):
    """ Returns the Hermite interpolation (cubic spline) for x between a and b.
        The return value between 0.0-1.0 eases (slows down) as x nears a or b.
    """
    if x < a:
        return 0.0
    if x >= b:
        return 1.0
    x = float(x - a) / (b - a)
    return x * x * (3 - 2 * x)


def remove_leading_zeros(num: str) ->str:
    """
    Strips zeros while handling -, M, and empty strings
    """
    if not num:
        return num
    if num.startswith('M'):
        ret = 'M' + num[1:].lstrip('0')
    elif num.startswith('-'):
        ret = '-' + num[1:].lstrip('0')
    else:
        ret = num.lstrip('0')
    return '0' if ret in ('', 'M', '-') else ret


def is_io_control(controldesc):
    """ Check if the control description is attached to the pipeline
    inputs/outputs.

    A pbox input/output control is specified as '<pbox_control>' while a
    pbox inner box control is specified as '<box_name>.<box_control_name>'.

    Parameters
    ----------
    controldesc: string (mandatory)
        a control description.

    Returns
    -------
    is_pbox_control: bool
        True if a pbox input/output control is detected.
    """
    if '.' not in controldesc:
        return True
    else:
        return False


def prepare():
    """Create the necessary directory structures."""


def size_str(size):
    """
    size: number of bytes
    Return a human-readable string.
    """
    if size is None:
        return None
    for unit in ('', 'k', 'm', 'g', 't'):
        if size < 100 and size != int(size):
            return '%.1f%s' % (size, unit)
        if size < 1024:
            return '%d%s' % (size, unit)
        size /= 1024.0


def column_key(index):
    """将Excel列序号转化成大写字母编号

    :param index: 从0开始的列序号
    :return: 列名, 如"A", "ZB"
    """
    key = chr(index % 26 + 65)
    while index > 25:
        index = index // 26
        key = chr(index % 26 + 64) + key
    return key


def voc_as_image_size(label):
    """Convert a VOC detection label to the image size.

    Args:
        label (dict): an image label in the VOC detection format.

    Returns:
        tuple: width, height of image.
    """
    width = int(label['annotation']['size']['width'])
    height = int(label['annotation']['size']['height'])
    return width, height


@classmethod
def all(cls):
    """Iterate over all registered plugins"""
    return cls.registry[:]


def configure(conf):
    """
	Detects the program gdbus-codegen and sets ``conf.env.GDBUS_CODEGEN``
	"""
    conf.find_program('gdbus-codegen', var='GDBUS_CODEGEN')


def filter_events(events, version_label=None, request_id=None, env_name=None):
    """
    Method filters events by their version_label, request_id, or env_name if supplied,
    or any combination if multiple are specified.

    :param events: A list of `events` returned by the `DescribeEvents` API
    :param version_label: An optional `version_label` of the environment to filter by
    :param request_id: An optional `request_id` of the operation being waited on to filter by
    :param env_name: An optional `environment_name` of the environment that is being waited on
    :return: A new list of events filtered as per the rules above.
    """
    filtered_events = []
    for event in events:
        if (version_label and event.version_label and event.version_label !=
            version_label):
            continue
        if request_id and event.request_id and event.request_id != request_id:
            continue
        if (env_name and event.environment_name and event.environment_name !=
            env_name):
            continue
        filtered_events.append(event)
    return filtered_events


def aggregate_hourly_daily(hourly):
    """Aggregates an hourly timeseries to a daily one."""
    if len(hourly) < 24:
        print('insufficiently short time series')
        return
    daily = []
    for i in range(0, len(hourly) - 23, 24):
        daily.append(sum(hourly[i:i + 24]))
    return daily


def _set_dyn_dist_cutoff(params, name: str, index: int, value: float):
    """Adjust the Parameters.dyn_dist_cutoff parameter"""
    if index is not None:
        raise IndexError('You cannot index the dyn_dist_cutoff parameter')
    params.dyn_dist_cutoff = value


def _truncate(w, needed):
    """Truncate window by 1 sample if needed for DFT-even symmetry"""
    if needed:
        return w[:-1]
    else:
        return w


def load_snapshot(harn, load_path):
    """
        Sets the harness to its state just after an epoch finished

        Args:
            str: path to previously saved snapshot
        """
    harn.info('Loading previous state: {}'.format(load_path))
    snapshot_state = harn.xpu.load(load_path)
    harn.set_snapshot_state(snapshot_state)
    harn.info('Previous snapshot loaded...')


@classmethod
def from_iris(cls, cube: 'iris_Cube') ->'DataArray':
    """Convert a iris.cube.Cube into an xarray.DataArray
        """
    from ..convert import from_iris
    return from_iris(cube)


def add_event_listener(evt, callback):
    """
        Add a listener to an Event object. This may be called multiple
        times for the same event. Every time the event happens, the
        callback method will be called. The callback has one argument
        (a string, the contents of the event, minus the '650' and the
        name of the event)

        FIXME: should have an interface for the callback.
        """


def active_frame_delete():
    """Delete the active frame for the active Grease Pencil Layer

    """
    pass


def ra_clear_horizontal(Bhc, Dhc):
    """
    Computes the clear sky beam irradiance on a horizontal surface

    .. math ::
        G_{hc}=B_{hc}+D_{hc}

    Parameters
    ----------
    Bhc : float
        beam irradiance at a horizontal surface
        :math:`B_{hc}`
        [W/m2]
    Dhc : float
        Diffuse irradiance at a horizontal surface
        :math:`D_{hc}`
        [W/m2]

    Returns
    -------
    ra_hor_clear_i : float
        Total clear-sky irradiance on a horizontal surface
        :math:`G_{hc}`
        [W/m2]

    Examples
    --------
    """
    ra_clear_hor = Bhc + Dhc
    return ra_clear_hor


def shard_delete(transport, request, shard_name):
    """Deletes the shard `shard_name`

    :param transport: Transport instance to use
    :type transport: `transport.base.Transport`
    :param request: Request instance ready to be sent.
    :type request: `transport.request.Request`
    :param shard_name: Shard reference name.
    :type shard_name: `six.text_type`
    """
    request.operation = 'shard_delete'
    request.params['shard_name'] = shard_name
    transport.send(request)


def get_name(cls):
    """Returns the name of the specified class/module"""
    return cls.__name__.split('.')[-1].capitalize()


def set_pass_code():
    """
    Set and validate the password
    :return: string
    """
    pass_code = input('Enter your Oracle Commerce Cloud backend pass-code: ')
    while True:
        if len(pass_code) >= 5:
            return pass_code
        else:
            pass_code = input(
                'Enter your Oracle Commerce Cloud backend pass-code: ')


@staticmethod
def _get_file_id(response):
    """If the telegram response is (for example) an array with different resolutions, here you can return the
        correct entry to the update_cache function
        """
    return response


def segwit_scriptpubkey(witver, witprog):
    """Construct a Segwit scriptPubKey for a given witness program."""
    return bytes([witver + 80 if witver else 0, len(witprog)] + witprog)


def list_queues(QueueNamePrefix=None):
    """
    Returns a list of your queues. The maximum number of queues that can be returned is 1,000. If you specify a value for the optional QueueNamePrefix parameter, only queues with a name that begins with the specified value are returned.
    See also: AWS API Documentation

    :example: response = client.list_queues(
        QueueNamePrefix='string'
    )

    :type QueueNamePrefix: string
    :param QueueNamePrefix: A string to use for filtering the list results. Only those queues whose name begins with the specified string are returned.
            Queue names are case-sensitive.

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

    """
    pass


@classmethod
def fromWindowConfigString(cls, client, winConfig):
    """Construct a new window from a window config string.
		"""
    return cls(client=client)


def view_center_cursor():
    """Center the view so that the cursor is in the middle of the view

    """
    pass


def validate_cram(path):
    """
    Validate CRAM file

    Parameters
    ----------
    path : str
        File to check
    """
    raise NotImplementedError()


def join_extended_lines(lines):
    """Join together any lines which end in an escaped newline.

    This function modifies the given lines object in place.

    lines - List of list of Tagged objects, where each embedded list is a
    separate line in the input program.
    """
    i = 0
    while i < len(lines):
        if lines[i] and lines[i][-1].c == '\\':
            if i + 1 < len(lines):
                del lines[i][-1]
                lines[i] += lines[i + 1]
                del lines[i + 1]
                i -= 1
            else:
                del lines[i][-1]
        i += 1


def _parse_geog_location(geog_location, namespace):
    """returns a dict representation of a geogLocation etree element"""
    return_dict = {'latitude': geog_location.find(namespace + 'latitude').
        text, 'longitude': geog_location.find(namespace + 'longitude').text}
    srs = geog_location.attrib.get('srs')
    if not srs is None:
        return_dict['srs'] = srs
    return return_dict


def return_on_field(wdg_clicked, wdg_autofill):
    """actualizamos auto-fill tras edicion"""
    val = wdg_clicked.get()
    if val.isdigit():
        wdg_autofill['text'] = str(int(val) + 1)
    else:
        wdg_autofill['text'] = str(val)


def get_paginator(operation_name=None):
    """
    Create a paginator for an operation.

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

    :rtype: L{botocore.paginate.Paginator}
    """
    pass


def _fd(f):
    """Get a filedescriptor from something which could be a file or an fd."""
    return f.fileno() if hasattr(f, 'fileno') else f


def get(key, default=None):
    """Attempt to get the value under the given key. If it does not
        exist, return the given default.
        """


def shrink(monolayer, cell, shrink_rate):
    """Divides the equilibrium volume of the cell
    by a factor (1+shrink_rate) and its equilibrium area
    by (1+shrink_rate)^2/3
    """
    factor = 1 + shrink_rate
    monolayer.cell_df.loc[cell, 'prefered_vol'] /= factor
    monolayer.cell_df.loc[cell, 'prefered_area'] /= factor ** (2 / 3)


def mule_id():
    """Returns current mule ID. 0 if not a mule (e.g. worker).

    :rtype: int
    """
    return 0


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

        :param LookupError val:
        :rtype: ExportError
        """
    return cls('path', val)


def view_ghost_border(gesture_mode: int=0, xmin: int=0, xmax: int=0, ymin:
    int=0, ymax: int=0):
    """Set the boundaries of the border used for offset-view

    :param gesture_mode: Gesture Mode
    :type gesture_mode: int
    :param xmin: X Min
    :type xmin: int
    :param xmax: X Max
    :type xmax: int
    :param ymin: Y Min
    :type ymin: int
    :param ymax: Y Max
    :type ymax: int
    """
    pass


def get_box(wcs, radec, w):
    """Get box of width w around source coordinates radec.

    Parameters
    ----------
    radec : tuple
        RA and DEC in degrees.
    w : int
        Width of box.
    wcs : astLib.astWCS.WCS instance
        World Coordinate System.

    Returns
    -------
    box : tuple
        A box centered at radec.

    """
    raPix, decPix = wcs.wcs2pix(*radec)
    raPix = int(raPix)
    decPix = int(decPix)
    box = slice(decPix - int(w / 2), decPix + int(w / 2)), slice(raPix -
        int(w / 2), raPix + int(w / 2))
    return box


def args_order(p):
    """options to order the listing"""
    from .util import args_sort
    g = p.add_argument_group('Ordering')
    args_sort(g)


def format_h_m(string):
    """Converts time string from format HH:MM to HHh MMm"""
    hours, minutes = string.split(':')[0:2]
    return '{0}h {1}m'.format(hours, minutes)


def Dmap(tree):
    """
    Butcher's function D(t).  Represents differentiation.
    Defined by D(t)=0 except for D('T')=1.
    """
    return 1 * (tree == 'T')


def extract_version_from_filename(filename):
    """Extract the version from a filename with the following
    format: `filename_1.1` or `filename_1.1.exe`
    """
    components = filename.replace('.exe', '').split('_')
    if len(components) == 2:
        return components[1]
    else:
        return None


@staticmethod
def _get_minimum(node):
    """Returns the node with the minimum key in the subtree rooted by node"""
    while node.left is not None:
        node = node.left
    return node


@classmethod
def from_points(cls, points, normalize=False):
    """Generator that calculates vectors of subsequent pairs in
        a sequence of coordinate-tuples.

        :param list(tuples) points: The sequence of coordinate points.
        :param bool normalize: Set `True` to normalize resulting
            vector.
        :rtype: `mathutils.Vector`
        """
    for i0 in range(len(points) - 1):
        v = cls.from_two_points(points[i0], points[i0 + 1], normalize)
        yield v


def _guess_main_sequence(madx):
    """Try to guess the 'main' sequence to be viewed."""
    sequence = madx.sequence()
    if sequence:
        return sequence.name
    sequences = madx.sequence
    if not sequences:
        raise ValueError('No sequences defined!')
    if len(sequences) != 1:
        raise ValueError(
            'Multiple sequences defined, none active. Cannot uniquely determine which to use.'
            )
    return next(iter(sequences))


@staticmethod
def ring_list_to_json_bbox(bbox):
    """If a bbox has been returned without all the trimmings, as in the case of
        the cloud func microservices we add some extra structure and return it.
        """
    tmp = [[bbox[0], bbox[1]], [bbox[0], bbox[3]], [bbox[2], bbox[3]], [
        bbox[2], bbox[1]], [bbox[0], bbox[1]]]
    return {'geometry': {'coordinates': tmp, 'type': 'Polygon'}}


def seek_delimiter(file, delimiter, blocksize):
    """ Seek current file to next byte after a delimiter bytestring

    This seeks the file to the next byte following the delimiter.  It does
    not return anything.  Use ``file.tell()`` to see location afterwards.

    Parameters
    ----------
    file: a file
    delimiter: bytes
        a delimiter like ``b'
'`` or message sentinel
    blocksize: int
        Number of bytes to read from the file at once.
    """
    if file.tell() == 0:
        return
    last = b''
    while True:
        current = file.read(blocksize)
        if not current:
            return
        full = last + current
        try:
            i = full.index(delimiter)
            file.seek(file.tell() - (len(full) - i) + len(delimiter))
            return
        except ValueError:
            pass
        last = full[-len(delimiter):]


@classmethod
def parse(cls, definitions, xmlelement, operation, type, nsmap):
    """Parse a wsdl:binding/wsdl:operation/wsdl:operation for the SOAP
        implementation.

        Each wsdl:operation can contain three child nodes:
         - input
         - output
         - fault

        Definition for input/output::

          <input>
            <soap:body parts="nmtokens"? use="literal|encoded"
                       encodingStyle="uri-list"? namespace="uri"?>

            <soap:header message="qname" part="nmtoken" use="literal|encoded"
                         encodingStyle="uri-list"? namespace="uri"?>*
              <soap:headerfault message="qname" part="nmtoken"
                                use="literal|encoded"
                                encodingStyle="uri-list"? namespace="uri"?/>*
            </soap:header>
          </input>

        And the definition for fault::

           <soap:fault name="nmtoken" use="literal|encoded"
                       encodingStyle="uri-list"? namespace="uri"?>

        """
    name = xmlelement.get('name')
    obj = cls(definitions.wsdl, name, operation, nsmap=nsmap, type=type)
    body_data = None
    header_data = None
    body = xmlelement.find('soap:body', namespaces=operation.binding.nsmap)
    if body is not None:
        body_data = cls._parse_body(body)
    elements = xmlelement.findall('soap:header', namespaces=operation.
        binding.nsmap)
    header_data = cls._parse_header(elements, definitions.target_namespace,
        operation)
    obj._resolve_info = {'body': body_data, 'header': header_data}
    return obj


def _vv(vec1, vec2):
    """
    Computes the inner product ``< vec1 | vec 2 >``.
    """
    return vec1.unsqueeze(-2).matmul(vec2.unsqueeze(-1)).squeeze(-1).squeeze(-1
        )


def move_to_front(lst, *items):
    """
    Move the specified items to the front of the given list. If an item is not
    in the list, it is ignored.

    Mutates the list. Does not return anything.
    """
    for item in reversed(items):
        if item in lst:
            lst.remove(item)
            lst.insert(0, item)


@staticmethod
def _unzigzag(number: int) ->int:
    """ ZigZag encoding uses LSB for sign storage,
        the value of the signed integer is shifted left by one bit,
        and bitwise negated in case of negative integers.
        """
    if number % 2:
        number = ~number
    number >>= 1
    return number


def KK_RC72_fit(params, w, t_values):
    """
    Kramers-Kronig Function: -RC-

    Kristian B. Knudsen (kknu@berkeley.edu / kristianbknudsen@gmail.com)
    """
    Rs = params['Rs']
    R1 = params['R1']
    R2 = params['R2']
    R3 = params['R3']
    R4 = params['R4']
    R5 = params['R5']
    R6 = params['R6']
    R7 = params['R7']
    R8 = params['R8']
    R9 = params['R9']
    R10 = params['R10']
    R11 = params['R11']
    R12 = params['R12']
    R13 = params['R13']
    R14 = params['R14']
    R15 = params['R15']
    R16 = params['R16']
    R17 = params['R17']
    R18 = params['R18']
    R19 = params['R19']
    R20 = params['R20']
    R21 = params['R21']
    R22 = params['R22']
    R23 = params['R23']
    R24 = params['R24']
    R25 = params['R25']
    R26 = params['R26']
    R27 = params['R27']
    R28 = params['R28']
    R29 = params['R29']
    R30 = params['R30']
    R31 = params['R31']
    R32 = params['R32']
    R33 = params['R33']
    R34 = params['R34']
    R35 = params['R35']
    R36 = params['R36']
    R37 = params['R37']
    R38 = params['R38']
    R39 = params['R39']
    R40 = params['R40']
    R41 = params['R41']
    R42 = params['R42']
    R43 = params['R43']
    R44 = params['R44']
    R45 = params['R45']
    R46 = params['R46']
    R47 = params['R47']
    R48 = params['R48']
    R49 = params['R49']
    R50 = params['R50']
    R51 = params['R51']
    R52 = params['R52']
    R53 = params['R53']
    R54 = params['R54']
    R55 = params['R55']
    R56 = params['R56']
    R57 = params['R57']
    R58 = params['R58']
    R59 = params['R59']
    R60 = params['R60']
    R61 = params['R61']
    R62 = params['R62']
    R63 = params['R63']
    R64 = params['R64']
    R65 = params['R65']
    R66 = params['R66']
    R67 = params['R67']
    R68 = params['R68']
    R69 = params['R69']
    R70 = params['R70']
    R71 = params['R71']
    R72 = params['R72']
    return Rs + R1 / (1 + w * 1.0j * t_values[0]) + R2 / (1 + w * 1.0j *
        t_values[1]) + R3 / (1 + w * 1.0j * t_values[2]) + R4 / (1 + w *
        1.0j * t_values[3]) + R5 / (1 + w * 1.0j * t_values[4]) + R6 / (1 +
        w * 1.0j * t_values[5]) + R7 / (1 + w * 1.0j * t_values[6]) + R8 / (
        1 + w * 1.0j * t_values[7]) + R9 / (1 + w * 1.0j * t_values[8]
        ) + R10 / (1 + w * 1.0j * t_values[9]) + R11 / (1 + w * 1.0j *
        t_values[10]) + R12 / (1 + w * 1.0j * t_values[11]) + R13 / (1 + w *
        1.0j * t_values[12]) + R14 / (1 + w * 1.0j * t_values[13]) + R15 / (
        1 + w * 1.0j * t_values[14]) + R16 / (1 + w * 1.0j * t_values[15]
        ) + R17 / (1 + w * 1.0j * t_values[16]) + R18 / (1 + w * 1.0j *
        t_values[17]) + R19 / (1 + w * 1.0j * t_values[18]) + R20 / (1 + w *
        1.0j * t_values[19]) + R21 / (1 + w * 1.0j * t_values[20]) + R22 / (
        1 + w * 1.0j * t_values[21]) + R23 / (1 + w * 1.0j * t_values[22]
        ) + R24 / (1 + w * 1.0j * t_values[23]) + R25 / (1 + w * 1.0j *
        t_values[24]) + R26 / (1 + w * 1.0j * t_values[25]) + R27 / (1 + w *
        1.0j * t_values[26]) + R28 / (1 + w * 1.0j * t_values[27]) + R29 / (
        1 + w * 1.0j * t_values[28]) + R30 / (1 + w * 1.0j * t_values[29]
        ) + R31 / (1 + w * 1.0j * t_values[30]) + R32 / (1 + w * 1.0j *
        t_values[31]) + R33 / (1 + w * 1.0j * t_values[32]) + R34 / (1 + w *
        1.0j * t_values[33]) + R35 / (1 + w * 1.0j * t_values[34]) + R36 / (
        1 + w * 1.0j * t_values[35]) + R37 / (1 + w * 1.0j * t_values[36]
        ) + R38 / (1 + w * 1.0j * t_values[37]) + R39 / (1 + w * 1.0j *
        t_values[38]) + R40 / (1 + w * 1.0j * t_values[39]) + R41 / (1 + w *
        1.0j * t_values[40]) + R42 / (1 + w * 1.0j * t_values[41]) + R43 / (
        1 + w * 1.0j * t_values[42]) + R44 / (1 + w * 1.0j * t_values[43]
        ) + R45 / (1 + w * 1.0j * t_values[44]) + R46 / (1 + w * 1.0j *
        t_values[45]) + R47 / (1 + w * 1.0j * t_values[46]) + R48 / (1 + w *
        1.0j * t_values[47]) + R49 / (1 + w * 1.0j * t_values[48]) + R50 / (
        1 + w * 1.0j * t_values[49]) + R51 / (1 + w * 1.0j * t_values[50]
        ) + R52 / (1 + w * 1.0j * t_values[51]) + R53 / (1 + w * 1.0j *
        t_values[52]) + R54 / (1 + w * 1.0j * t_values[53]) + R55 / (1 + w *
        1.0j * t_values[54]) + R56 / (1 + w * 1.0j * t_values[55]) + R57 / (
        1 + w * 1.0j * t_values[56]) + R58 / (1 + w * 1.0j * t_values[57]
        ) + R59 / (1 + w * 1.0j * t_values[58]) + R60 / (1 + w * 1.0j *
        t_values[59]) + R61 / (1 + w * 1.0j * t_values[60]) + R62 / (1 + w *
        1.0j * t_values[61]) + R63 / (1 + w * 1.0j * t_values[62]) + R64 / (
        1 + w * 1.0j * t_values[63]) + R65 / (1 + w * 1.0j * t_values[64]
        ) + R66 / (1 + w * 1.0j * t_values[65]) + R67 / (1 + w * 1.0j *
        t_values[66]) + R68 / (1 + w * 1.0j * t_values[67]) + R69 / (1 + w *
        1.0j * t_values[68]) + R70 / (1 + w * 1.0j * t_values[69]) + R71 / (
        1 + w * 1.0j * t_values[70]) + R72 / (1 + w * 1.0j * t_values[71])


@staticmethod
def _directive_set_attribute(directive_body):
    """Directive for :py:meth:`set_attribute`"""
    instance, attribute_name, new_value = directive_body
    return setattr(instance, attribute_name, new_value)


def scatter_row_inplace(data, row_index, value):
    """Write the value into the data tensor using the row index inplace.

    This is an inplace write so it will break the autograd.

    Parameters
    ----------
    data : Tensor
        The data tensor to be updated.
    row_index : Tensor
        A 1-D integer tensor containing which rows to be updated.
    value : Tensor
        The new value.
    """
    pass


def get_esconde_data():
    """Retorna o valor da configuração esconde_data."""


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

    The ".dev0" means dirty.

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


def write_doxyfile(config, doxyfile):
    """ Write a doxyfile """
    with open(doxyfile, 'w') as fp:
        for key, value in config.items():
            fp.write('%s = %s\n' % (key, value))


@staticmethod
def extensions():
    """Return accepted extension for this loader"""
    return 'gif',


def get_numpy_include_path():
    """
    Gets the path to the numpy headers.
    """
    import builtins
    if hasattr(builtins, '__NUMPY_SETUP__'):
        del builtins.__NUMPY_SETUP__
    import imp
    import numpy
    imp.reload(numpy)
    try:
        numpy_include = numpy.get_include()
    except AttributeError:
        numpy_include = numpy.get_numpy_include()
    return numpy_include


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 name(schemaName, tree):
    """Return the schema name to use
        """


def check_pandas_columns(df, column_names):
    """check_pandas_columns
    will check that a list of columns is in a data frame
    """
    for column_name in column_names:
        if column_name not in df.columns:
            raise ValueError(
                'column %s is missing from relationship table.' % column_name)


def delete_web_acl(WebACLId=None, ChangeToken=None):
    """
    Permanently deletes a  WebACL . You can't delete a WebACL if it still contains any Rules .
    To delete a WebACL , perform the following steps:
    See also: AWS API Documentation

    Examples
    The following example deletes a web ACL with the ID example-46da-4444-5555-example.
    Expected Output:

    :example: response = client.delete_web_acl(
        WebACLId='string',
        ChangeToken='string'
    )

    :type WebACLId: string
    :param WebACLId: [REQUIRED]
            The WebACLId of the WebACL that you want to delete. WebACLId is returned by CreateWebACL and by ListWebACLs .

    :type ChangeToken: string
    :param ChangeToken: [REQUIRED]
            The value returned by the most recent call to GetChangeToken .

    :rtype: dict
    :return: {
        'ChangeToken': 'string'
    }

    :returns:
    WebACLId (string) -- [REQUIRED]
    The WebACLId of the  WebACL that you want to delete. WebACLId is returned by  CreateWebACL and by  ListWebACLs .

    ChangeToken (string) -- [REQUIRED]
    The value returned by the most recent call to  GetChangeToken .

    """
    pass


def _distill_params(multiparams, params):
    """Given arguments from the calling form *multiparams, **params,
    return a list of bind parameter structures, usually a list of
    dictionaries.

    In the case of 'raw' execution which accepts positional parameters,
    it may be a list of tuples or lists.

    """
    if not multiparams:
        if params:
            return [params]
        else:
            return []
    elif len(multiparams) == 1:
        zero = multiparams[0]
        if isinstance(zero, (list, tuple)):
            if not zero or hasattr(zero[0], '__iter__') and not hasattr(zero
                [0], 'strip'):
                return zero
            else:
                return [zero]
        elif hasattr(zero, 'keys'):
            return [zero]
        else:
            return [[zero]]
    elif hasattr(multiparams[0], '__iter__') and not hasattr(multiparams[0],
        'strip'):
        return multiparams
    else:
        return [multiparams]


def is_private(address):
    """
    Checks if an address is private and if so returns True.  Otherwise returns
    False.
    Args:
        address: Address to check. Can be list or string
    Returns:
        True or False
    """
    if '.' in address:
        pairs = address.split('.')
    elif ':' in address:
        pairs = address.split(':')
    else:
        pairs = []
    private = False
    if pairs:
        if pairs[0] == '10':
            private = True
        elif pairs[0] == '192' and pairs[1] == '168':
            private = True
        elif pairs[0] == '172' and 16 <= int(pairs[1]) <= 31:
            private = True
        elif pairs[0] == 'fe80':
            private = True
        elif pairs[0].startswith('fd'):
            private = True
    return private


def calculate_final_drive_torque_losses_v1(n_wheel_drive,
    final_drive_torques_out, final_drive_ratio_vector, final_drive_efficiency):
    """
    Calculates final drive torque losses [N*m].

    :param n_wheel_drive:
        Number of wheel drive [-].
    :type n_wheel_drive: int

    :param final_drive_torques_out:
        Torque at the wheels [N*m].
    :type final_drive_torques_out: numpy.array | float

    :param final_drive_ratio_vector:
        Final drive ratio vector [-].
    :type final_drive_ratio_vector: numpy.array | float

    :param final_drive_efficiency:
        Final drive efficiency [-].
    :type final_drive_efficiency: float

    :return:
        Final drive torque losses [N*m].
    :rtype: numpy.array | float
    """
    eff_fd = final_drive_efficiency - (n_wheel_drive - 2) / 100
    to = final_drive_torques_out
    return (1 - eff_fd) / (eff_fd * final_drive_ratio_vector) * to


def guess_type(url, supported):
    """Guess the mime type of the file link.
    If the mimetype is not recognized, default to the first supported value.

    Parameters
    ----------
    url : str
      Path or URL to file.
    supported : list, tuple
      Supported mimetypes.

    Returns
    -------
    mimetype, encoding
    """
    import mimetypes
    try:
        mime, enc = mimetypes.guess_type(url, strict=False)
    except TypeError:
        mime, enc = None, None
    if (mime == 'application/x-netcdf' and 'dodsC' in url and
        'application/x-ogc-dods' in supported):
        mime = 'application/x-ogc-dods'
    zips = ['application/zip', 'application/x-zipped-shp']
    if mime not in supported:
        if mime in zips and set(zips).intersection(supported):
            mime = set(zips).intersection(supported).pop()
    if mime is None:
        mime = supported[0]
    elif mime not in supported:
        raise ValueError(
            f'mimetype {mime} not in supported mimetypes {supported}.')
    return mime, enc


def is_null(key):
    """Detect null keys like super key."""
    if isinstance(key, str) and len(key) == 1:
        return ord(key) == 0
    return key == ''


def _async_request_completed(payload):
    """Looks into an async response payload to see if the requested job has finished."""
    if payload['status'] == 'COMPLETED':
        return True
    if payload['status'] == 'ERROR':
        return True
    return False


@classmethod
def from_dict(cls, dict_obj):
    """ Creates a yalchemy CheckConstraint from a dictionary.

        The dictionary has the following specification::

            {
                # The check is the string of the check we want to
                # have on the constraint. It should be verbatium
                # what the check would be in SQL
                'name': str(required),
                'check': str(required),
            }
        """
    return cls(name=dict_obj['name'], check=dict_obj['check'])


def calculate_cubic_bezier(points, t):
    """
    Points is a list of four points, P0, P1, P2 and P3, in that order
    """
    P0, P1, P2, P3 = points
    Bt = (1 - t) ** 3 * P0 + 3 * (1 - t) ** 2 * t * P1 + 3 * (1 - t
        ) * t ** 2 * P2 + t ** 3 * P3
    return Bt


def calculate_floating_non_replaced_width(node, context):
    """Implements S10.3.5"""
    raise NotImplementedError('Section 10.3.5')


def no_prefix(name):
    """does the given constant have a ZMQ_ prefix?"""
    return name.startswith('E') and not name.startswith('EVENT')


@task
def get_tasks():
    """Get all paver-defined tasks."""
    from paver.tasks import environment
    for task in environment.get_tasks():
        print(task.shortname)


def get_manager(addr):
    """Get assumed environment manager's address for a given agent address.
    """
    return addr.rsplit('/', 1)[0] + '/0'


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

        :param FileEditCommentType val:
        :rtype: EventType
        """
    return cls('file_edit_comment', val)


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

        :param PaperDocEditDetails val:
        :rtype: EventDetails
        """
    return cls('paper_doc_edit_details', val)


def _pandas_sort_pre_017(df, by, *args, **kwargs):
    """Use sort() to sort a DataFrame"""
    return df.sort(*args, columns=by, **kwargs)


@staticmethod
def spinner_states(cc=False):
    """Get spinner-style animation states

        Example::

            lh = Spinner(Spinner.spinner_states())

        :param bool cc: True to rotate counter-clockwise (default: False)
        :returns: spinner states
        :rtype: [str]
        """
    return '|\\-/' if cc else '|/-\\'


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


@staticmethod
def p_value_table_description_list_optional(p):
    """value_table_description_list_optional : empty
                                                 | value_table_description_list"""
    p[0] = p[1]


def ParseBool(text):
    """Parse a boolean value.

  Args:
    text: Text to parse.

  Returns:
    Boolean values parsed

  Raises:
    ValueError: If text is not a valid boolean.
  """
    if text in ('true', 't', '1', 'True'):
        return True
    elif text in ('false', 'f', '0', 'False'):
        return False
    else:
        raise ValueError('Expected "true" or "false".')


def _logsubexp(a, b):
    """Evaluate `log(exp(a) - exp(b))` preserving accuracy.

  Subtract log-domain numbers and return in the log-domain.
  Wraps `scipy.special.logsumexp`.
  """
    from scipy.special import logsumexp
    return logsumexp([a, b], b=[1, -1])


def uint_to_list_of_uints(uint, size, width):
    """
    Convert an unsigned integer into a list of unsigned integers.

    Args:
        `uint`: the input unsigned integer
        `width`: The width of each individual unsigned integer.
        `size`: The number of items in the produced list.

    >>> uint_to_list_of_uints(5, size=4, width=1)
    [1, 0, 1, 0]
    >>> uint_to_list_of_uints(27, size=3, width=2)
    [3, 2, 1]
    """
    if uint is None:
        output = [None] * size
    else:
        assert uint >= 0
        residual = uint
        f = pow(2, width)
        output = []
        for i in range(size):
            output.append(residual % f)
            residual = residual >> width
        assert residual == 0
    return output


def try_argcomplete(parser):
    """Make sure to use argcomplete if it is installed.

    :param parser: the parser to add autocomplete
    """
    try:
        import argcomplete
    except ImportError:
        pass
    else:
        argcomplete.autocomplete(parser)


def calculate_capacities(volume, temp_h, temp_c, heat_capacity=4195.52,
    density=971.803):
    """
    Calculates the nominal storage capacity, minimum
    and maximum storage level of a stratified thermal storage.

    .. calculate_capacities-equations:

    :math:`Q_N = V \\cdot c \\cdot \\rho \\cdot \\left( T_{H} - T_{C} \\right)`

    Parameters
    ----------
    volume :numeric
        Volume of the storage [m3]

    temp_h : numeric
        Temperature of hot storage medium [deg C]

    temp_c : numeric
        Temperature of cold storage medium [deg C]

    heat_capacity: numeric
        Average specific heat capacity of storage medium [J/(kg*K)]
        Default values calculated with CoolProp for a temperature of 80 °C
        as a simplifying assumption

    density : numeric
        Average density of storage medium [kg/m3]
        Default values calculated with CoolProp for a temperature of 80 °C
        as a simplifying assumption

    Returns
    -------
    nominal_storage_capacity : numeric
        Maximum amount of stored thermal energy [MWh]

    """
    nominal_storage_capacity = volume * heat_capacity * density * (temp_h -
        temp_c)
    nominal_storage_capacity *= 1 / 3600
    nominal_storage_capacity *= 1e-06
    return nominal_storage_capacity


def filter_fields(d: dict, nt):
    """Excludes fields not found in the schema/namedtuple"""
    res = {}
    for k, v in d.items():
        if k in nt._fields:
            res.update({k: v})
    return res


def get_nth(li, i):
    """if i < len(l) returns l[i] else l[-1]"""
    try:
        return li[min(i, len(li) - 1)]
    except Exception:
        return li


def _single_test(args):
    """Run a model on a subset of training data with a fixed test set.

    Return the output of a function specified by the last argument.

    Parameters
    ----------
    args : tuple
        Parameters and data to be passed to model.

        args[0] : int
            Increment.
        args[1] : int
            Step size. args[1] * args[0] training examples will be passed
            to the regression model.
        args[2] : array
            An n, d array of training examples.
        args[3] : list
            A list of the target values.
        args[4] : array
            An n, d array of test data.
        args[5] : list
            A list of the test target values.
        args[6] : object
            custom function for testing a predictive model.
            Must accept 4 parameters, which are args[2:5].
    """
    x = args[0]
    n = x * args[1]
    train_features = args[2]
    test = args[3]
    train_targets = args[4]
    test_targets = args[5]
    model = args[6]
    train = train_features[-n:, :]
    targets = train_targets[-n:]
    result = model(train, targets, test, test_targets)
    return result


def merge(df1, df2, monthly=False):
    """
    Merge two dataframes

    :param df1: (pd.DataFrame) - dataframe to merge
    :param df2: (pd.DataFrame) - another dataframe to merge
    :param monthly: (boolean) - whether to groupby month first
    :return merged_df: (pd.DataFrame) - combined df1 and df2
    """
    if monthly:
        df1 = df1.groupby('1M').mean()
        df2 = df2.groupby('1M').mean()
    return df1.merge(df2, how='outer', left_index=True, right_index=True)


def superset():
    """incoming things that are supersets of incoming things"""


def areaBetween(requestContext, *seriesLists):
    """
    Draws the vertical area in between the two series in seriesList. Useful for
    visualizing a range such as the minimum and maximum latency for a service.

    areaBetween expects **exactly one argument** that results in exactly two
    series (see example below). The order of the lower and higher values
    series does not matter. The visualization only works when used in
    conjunction with ``areaMode=stacked``.

    Most likely use case is to provide a band within which another metric
    should move. In such case applying an ``alpha()``, as in the second
    example, gives best visual results.

    Example::

      &target=areaBetween(service.latency.{min,max})&areaMode=stacked

      &target=alpha(areaBetween(service.latency.{min,max}),0.3)&areaMode=stacked

    If for instance, you need to build a seriesList, you should use the
    ``group`` function, like so::

      &target=areaBetween(group(minSeries(a.*.min),maxSeries(a.*.max)))
    """
    if len(seriesLists) == 1:
        [seriesLists] = seriesLists
    assert len(seriesLists
        ) == 2, 'areaBetween series argument must reference *exactly* 2 series'
    lower, upper = seriesLists
    if len(lower) == 1:
        [lower] = lower
    if len(upper) == 1:
        [upper] = upper
    lower.options['stacked'] = True
    lower.options['invisible'] = True
    upper.options['stacked'] = True
    lower.name = upper.name = 'areaBetween(%s)' % upper.pathExpression
    return [lower, upper]


def __new__(cls, arg, ignore_nonimports=False, ignore_shadowed=False):
    """
        Return as an `ImportSet`.

        :param ignore_nonimports:
          If ``False``, complain about non-imports.  If ``True``, ignore
          non-imports.
        :param ignore_shadowed:
          Whether to ignore shadowed imports.  If ``False``, then keep all
          unique imports, even if they shadow each other.  Note that an
          ``ImportSet`` is unordered; an ``ImportSet`` with conflicts will only
          be useful for very specific cases (e.g. set of imports to forget
          from known-imports database), and not useful for outputting as code.
          If ``ignore_shadowed`` is ``True``, then earlier shadowed imports are
          ignored.
        :rtype:
          `ImportSet`
        """
    if isinstance(arg, cls):
        if ignore_shadowed:
            return cls._from_imports(arg._importset, ignore_shadowed=True)
        else:
            return arg
    return cls._from_args(arg, ignore_nonimports=ignore_nonimports,
        ignore_shadowed=ignore_shadowed)


def get_delay_in_minutes(delay=0):
    """Get the delay in minutes from a delay in seconds."""
    return round(int(delay) / 60)


def real(x):
    """Returns the real part of a complex tensor.

    :param x: The complex tensor
    :type x: torch.Tensor

    :returns: The real part of `x`; will have one less dimension than `x`.
    :rtype: torch.Tensor
    """
    return x[0, ...]


@classmethod
def _parse_value(cls, stream_rdr, offset, value_count, value_offset):
    """
        Return the value of this field parsed from *stream_rdr* at *offset*.
        Intended to be overridden by subclasses.
        """
    return 'UNIMPLEMENTED FIELD TYPE'


def delete(key):
    """
        Deletes a key/value from the cache.

        :param key: The key in the cache to delete.
        :returns: True if the key is successfully deleted, False otherwise.
        :rtype: ``boolean``

        """


def _improve_answer_span(doc_tokens, input_start, input_end, tokenizer,
    orig_answer_text):
    """Returns tokenized answer spans that better match the annotated answer."""
    tok_answer_text = ' '.join(tokenizer.tokenize(orig_answer_text))
    for new_start in range(input_start, input_end + 1):
        for new_end in range(input_end, new_start - 1, -1):
            text_span = ' '.join(doc_tokens[new_start:new_end + 1])
            if text_span == tok_answer_text:
                return new_start, new_end
    return input_start, input_end


@classmethod
def _from_dict(cls, _dict):
    """Initialize a MemoryUsage object from a json dictionary."""
    args = {}
    if 'used_bytes' in _dict:
        args['used_bytes'] = _dict.get('used_bytes')
    if 'total_bytes' in _dict:
        args['total_bytes'] = _dict.get('total_bytes')
    if 'used' in _dict:
        args['used'] = _dict.get('used')
    if 'total' in _dict:
        args['total'] = _dict.get('total')
    if 'percent_used' in _dict:
        args['percent_used'] = _dict.get('percent_used')
    return cls(**args)


def get_charstring(option, section_items, language, language_alternate=None):
    """convenience function to return unilingual or multilingual value(s)"""
    section_items = dict(section_items)
    option_value1 = None
    option_value2 = None
    if 'language_alternate' is None:
        option_tmp = '{}_{}'.format(option, language)
        if option_tmp in section_items:
            option_value1 = section_items[option_tmp]
        else:
            try:
                option_value1 = section_items[option]
            except KeyError:
                pass
    else:
        option_tmp = '{}_{}'.format(option, language)
        if option_tmp in section_items:
            option_value1 = section_items[option_tmp]
        else:
            try:
                option_value1 = section_items[option]
            except KeyError:
                pass
        option_tmp2 = '{}_{}'.format(option, language_alternate)
        if option_tmp2 in section_items:
            option_value2 = section_items[option_tmp2]
    return [option_value1, option_value2]


def intensity_localization_fv(data3dr, voxelsize_mm, seeds=None, unique_cls
    =None):
    """
    Use organ_localizator features plus intensity features

    :param data3dr:
    :param voxelsize_mm:
    :param seeds:
    :param unique_cls:
    :return:
    """
    import scipy
    import numpy as np
    import os.path as op
    try:
        from lisa import organ_localizator
    except:
        import organ_localizator
    f0 = scipy.ndimage.filters.gaussian_filter(data3dr, sigma=0.5).reshape(
        -1, 1)
    f1 = scipy.ndimage.filters.gaussian_filter(data3dr, sigma=3).reshape(-1, 1)
    import organ_localizator
    fvall = organ_localizator.localization_fv(data3dr, voxelsize_mm)
    fv = np.concatenate([f0, f1, fvall], 1)
    if seeds is not None:
        sd = seeds.reshape(-1, 1)
        selection = np.in1d(sd, unique_cls)
        fv = fv[selection]
        sd = sd[selection]
        return fv, sd
    return fv


def use_cdecimal():
    """ Do a hack-in replacement of `decimal` with `cdecimal`.
    Should be done before importing other modules.

    Also see
    http://adamj.eu/tech/2015/06/06/swapping-decimal-for-cdecimal-on-python-2/
    for a possibly more reliable way.
    """
    import sys
    import decimal
    import cdecimal
    sys.modules['decimal'] = cdecimal


def markLocation(stream):
    """Creates text file showing current location in context."""
    RADIUS = 5000
    stream.seek(-RADIUS, 1)
    outputDoc = open('PyPDF2_pdfLocation.txt', 'w')
    outputDoc.write(stream.read(RADIUS))
    outputDoc.write('HERE')
    outputDoc.write(stream.read(RADIUS))
    outputDoc.close()
    stream.seek(-RADIUS, 1)


@staticmethod
def randperm(tensor_size):
    """
        Generate `tensor_size[:-1]` random ArithmeticSharedTensor permutations of
        the first `tensor_size[-1]` whole numbers
        """
    raise NotImplementedError('HomomorphicProvider not implemented')


@staticmethod
def getJavaPackage():
    """ Returns package name String. """
    return 'com.microsoft.ml.spark.featurize.Featurize'


def p_method_or_not(p):
    """method_or_not : LPAREN function_call_parameter_list RPAREN
                     | empty"""
    if len(p) == 4:
        p[0] = p[2]


def find_cutoff(cutplot, n_cls=None):
    """
    Finds the weight cutoff based on the longest run in cutplot.
    If n_cls is provided, finds the cutoff point where n_cls
    clusters are formed."""
    from itertools import groupby
    if n_cls != None:
        for c in cutplot:
            if c[1] == n_cls:
                return c[0]
    group = groupby(cutplot[:, (1)])
    val = max(group, key=lambda k: len(list(k[1])))[0]
    for c in cutplot:
        if c[1] == val:
            return c[0] + 0.01


@classmethod
def _login_event_handler(cls, user=None):
    """This method is triggered when a login event occurs.

        When a user logs in, all items in his guest cart should be added to his
        logged in or registered cart. If there is no such cart, it should be
        created.
        """
    guest_cart = cls.find_cart(None)
    if not guest_cart:
        return
    if guest_cart.sale and guest_cart.sale.lines:
        to_cart = cls.open_cart(True)
        for from_line in guest_cart.sale.lines:
            sale_line = from_line.add_to(to_cart.sale)
            sale_line.save()
    guest_cart._clear_cart()


def rect(x0, y0, x1, y1):
    """
    Allow drawing a rectangle.

    Args:
        x0 int: x starting point of the rectangle.
        y0 int: y starting point of the rectangle.
        x1 int: x ending point of the rectangle.
        y1 int: y ending point of the rectangle.

    Returns:
        list of tuples. Each tuple is a x,y pair representing points where the
            color should be changed.
    """
    dx = abs(x1 - x0) + 1
    dy = abs(y1 - y0) + 1
    rectComplete = []
    if x0 < x1:
        ix = 1
    else:
        ix = -1
    if y0 < y1:
        iy = 1
    else:
        iy = -1
    x = x0
    for i in range(dx):
        y = y0
        for j in range(dy):
            rectComplete.append([x, y])
            y += iy
        x += ix
    return rectComplete


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


def unique(iterable):
    """
    Yields all elements once, preserving order. Remember all elements ever seen.
    >>> list(unique('AAAABBBCCDAABBB'))
    ['A', 'B', 'C', 'D']
    """
    seen = set()
    seen_add = seen.add
    for element in iterable:
        if element not in seen:
            seen_add(element)
            yield element


def true_param(p):
    """Check if ``p`` is a parameter name, not a limit/error/fix attributes."""
    return not p.startswith('limit_') and not p.startswith('error_'
        ) and not p.startswith('fix_')


def build_event_set(event):
    """
    Turn an EventStream event into a set of event types that ORES
    uses internally.
    """
    event_set = set()
    if event['meta']['stream'] == 'mediawiki.revision-create':
        event_set.add('edit')
        if event.get('page_namespace') == 0:
            event_set.add('main_edit')
        user_groups = event.get('performer', {}).get('user_groups', [])
        if 'bot' in user_groups:
            event_set.add('bot_edit')
        else:
            event_set.add('nonbot_edit')
        if not event.get('rev_parent_id'):
            event_set.add('page_creation')
            if event.get('page_namespace') == 0:
                event_set.add('main_creation')
            if 'bot' in user_groups:
                event_set.add('bot_page_creation')
            else:
                event_set.add('nonbot_page_creation')
    return event_set


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


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 subset(df, lb=None, ub=None, param='capacity_fraction', sum_param='length'
    ):
    """
    subset a Dataframe between the provided lowerbound and upperbound (lb, ub)
    along the given parameter. optionally return a scalar sum of data within the
    sum_param
    """
    if lb is not None:
        df = df.loc[df[param] >= lb]
    if ub is not None:
        df = df.loc[df[param] < ub]
    if sum_param is not None:
        return df[sum_param].sum()
    else:
        return df


@classmethod
def get_url_name(cls):
    """ This name will be used by generic relationships to membership model for URL creation """
    return '{}-{}'.format(cls._meta.app_label, cls.__name__.lower())


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

    The ".dev0" means dirty.

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


def list_size_constraint_sets(NextMarker=None, Limit=None):
    """
    Returns an array of  SizeConstraintSetSummary objects.
    See also: AWS API Documentation

    Examples
    The following example returns an array of up to 100 size contraint match sets.
    Expected Output:

    :example: response = client.list_size_constraint_sets(
        NextMarker='string',
        Limit=123
    )

    :type NextMarker: string
    :param NextMarker: If you specify a value for Limit and you have more SizeConstraintSets than the value of Limit , AWS WAF returns a NextMarker value in the response that allows you to list another group of SizeConstraintSets . For the second and subsequent ListSizeConstraintSets requests, specify the value of NextMarker from the previous response to get information about another batch of SizeConstraintSets .

    :type Limit: integer
    :param Limit: Specifies the number of SizeConstraintSet objects that you want AWS WAF to return for this request. If you have more SizeConstraintSets objects than the number you specify for Limit , the response includes a NextMarker value that you can use to get another batch of SizeConstraintSet objects.

    :rtype: dict
    :return: {
        'NextMarker': 'string',
        'SizeConstraintSets': [
            {
                'SizeConstraintSetId': 'string',
                'Name': 'string'
            },
        ]
    }

    """
    pass


def getfilename(path):
    """This function extracts the file name without file path or extension

    Args:
        path (file):
            full path and file (including extension of file)

    Returns:
        name of file as string
    """
    return path.split('\\').pop().split('/').pop().rsplit('.', 1)[0]


def generate(context, param={}, dataSource=None, seed=None):
    """Generate sample data of this plugin.

        This method assumes the sample data this plugin depends on has
        been created.
        """


def child_isinstance(block, child_id, block_class_or_mixin):
    """
    Efficiently check if a child of an XBlock is an instance of the given class.

    Arguments:
    block -- the parent (or ancestor) of the child block in question
    child_id -- the usage key of the child block we are wondering about
    block_class_or_mixin -- We return true if block's child indentified by child_id is an
    instance of this.

    This method is equivalent to

        isinstance(block.runtime.get_block(child_id), block_class_or_mixin)

    but is far more efficient, as it avoids the need to instantiate the child.
    """
    def_id = block.runtime.id_reader.get_definition_id(child_id)
    type_name = block.runtime.id_reader.get_block_type(def_id)
    child_class = block.runtime.load_block_type(type_name)
    return issubclass(child_class, block_class_or_mixin)


@classmethod
def _validate_status(cls, status):
    """Return True if 'status' is a valid state."""
    return True


def join(items):
    """
    Shortcut to join collection of strings.
    """
    return b''.join(items)


def _get_real_user(user, anon_user=None):
    """
    Given a "user" that could be:

    * a real user object
    * a function that returns a real user object
    * a LocalProxy to a real user object (like Flask-Login's ``current_user``)

    This function returns the real user object, regardless of which we have.
    """
    if hasattr(user, '_get_current_object'):
        user = user._get_current_object()
    if callable(user):
        user = user()
    if anon_user and isinstance(user, anon_user):
        return None
    return user


def get_xsteps(size, min_x, plot_cores, xtick_step):
    """Return the step size needed for a reasonable xtick spacing.

    Default step size is 1. If benchmarks>=18 are plotted, the step size is
    increased to 2. If we are plotting the number of cores, we increase the
    step size to 3, if the number of benchmarks>10 or the number of
    cores/node>=100.

    The user setting `xtick_step` overrides all previous settings.
    """
    step = 1
    if size >= 18:
        step = 2
    if plot_cores and (size > 10 or min_x >= 100):
        step = 3
    if xtick_step:
        step = xtick_step
    return step


@classmethod
def from_list(cls, assoclist, assoctype, resource, sortkey=None):
    """Create AssociationsMap from assoclist."""
    if assoclist is None:
        return None
    assocs = cls(assoctype, resource, sortkey=sortkey)
    for assoc_d in assoclist:
        assoc = assocs.assoc_class.from_dict(assoc_d)
        assocs[assoc.key] = assoc.value
    return assocs


def set_text(node, text):
    """Set the text of a parent"""
    node.text = text


def wrapUser(user):
    """Returns an IMember instance for the given user object.

        o Permission:  Private (Python-only)
        """


def cursor_set(location: float=(0.0, 0.0)):
    """Set 2D cursor location

    :param location: Location, Cursor location in normalized (0.0-1.0) coordinates
    :type location: float
    """
    pass


def padded_data(data: bytes, start: int, stop: int) ->bytes:
    """Return the data between the start and stop index.

    The data is treated as padded with an infinite amount of null bytes before index 0.
    """
    assert start <= stop
    if start <= stop <= 0:
        return b'\x00' * (stop - start)
    if 0 <= start <= stop:
        return data[start:stop]
    return b'\x00' * (0 - start) + data[0:stop]


@classmethod
def maptag(cls, tag, fn):
    """
        Map (override) tag => I{class} mapping.

        @param tag: An XSD tag name.
        @type tag: str
        @param fn: A function or class.
        @type fn: fn|class.

        """
    cls.tags[tag] = fn


def undo_patch(revised, patch):
    """
    Undo the changes specified in the given patch

    :param revised: the changed text
    :param patch: the patch to undo the changes in
    :exception PatchFailedException: if unable to undo the changes
    :return: the original text
    """
    if isinstance(revised, str):
        revised = revised.splitlines()
    patch.restore(revised)


def _hemi(lat):
    """Return the hemisphere letter.

       @arg lat: Latitude (C{degrees} or C{radians}).

       @return: C{'N'|'S'} for north-/southern hemisphere.
    """
    return 'S' if lat < 0 else 'N'


def linear_to_long_mag(lateral_mag):
    """Compute the longitudinal (along optical axis) magnification from the lateral mag.

    Parameters
    ----------
    lateral_mag : `float`
        linear magnification, from thin lens formulas

    Returns
    -------
    `float`
        longitudinal magnification

    """
    return lateral_mag ** 2


@classmethod
def clear(cls):
    """Clear the cached instances"""
    try:
        del cls._cache
    except AttributeError:
        pass


def contains_filter(value, item):
    """
    Checks whether the provided value contains the item.

    Internally, this uses the Python 'in' check.

    Args:
        value: the value
        item: the contained item

    Returns: True if the item is found in the value

    """
    return item in value


def diskcache_expand(d):
    """return  list of strings described by d, where
        d is dict with keys
    {"directory", "frame_type", "site", "dur", "ext", "segmentlist"}
    """
    for dc_seg in d['segmentlist']:
        for gps in range(dc_seg[0], dc_seg[1], d['dur']):
            lfn = '-'.join([d['site'], d['frame_type'], str(gps), str(d[
                'dur'])]) + d['ext']
            yield '/'.join([d['directory'], lfn])


def select_from_key(key, d):
    """
    Return element of the dict to do the insertion on. If it is foo.1.bar, it
    will return d["foo"][1]. If it is only foo, it will return d directly.
    """
    path = key.split('.')[:-1]
    tmp_d = d
    for p in path:
        if isinstance(tmp_d, (list, tuple)):
            tmp_d = tmp_d[int(p)]
        else:
            tmp_d = tmp_d[p]
    return tmp_d


def isRegistered(history_id):
    """Returns True if the object is already registered.

        A registered object has a history.
        """


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

        :param ShowcaseChangeDownloadPolicyType val:
        :rtype: EventType
        """
    return cls('showcase_change_download_policy', val)


@classmethod
def get_pks(cls, id):
    """
            Convert the id string to a pk dict
        """
    values = str(id).split(cls.delimiter)
    result = dict()
    for pk_col, val in zip(cls.columns, values):
        if not val:
            if pk_col.type.python_type == int:
                val = 0
        try:
            col_name = str(pk_col.name)
            result[col_name] = pk_col.type.python_type(val)
        except (ValueError, TypeError):
            if pk_col.default:
                result[col_name] = pk_col.default
            else:
                result[col_name] = ''
        except:
            result[col_name] = ''
    return result


def is_float(string):
    """    Check whether string is float.

    See also
    --------
    http://stackoverflow.com/questions/736043/checking-if-a-string-can-be-converted-to-float-in-python
    """
    try:
        float(string)
        return True
    except ValueError:
        return False


@staticmethod
def print_data_to_file(dtype, data, file):
    """
        Print data type and data to a file (these can be passed in externally for convenience).
        args:
            dtype: data type
            data: data to be printed
            file: file object
        """
    file.write('dtype :' + dtype + '\n\n')
    if len(data) == 0:
        file.write('Structure is not defined\n')


def word_len(word):
    """Returns the word length, minus any color codes."""
    if word[0] == '\x1b':
        return len(word) - 11
    return len(word)


def str_is_pos_int(numeric_string):
    """Returns true if the string is a positive integer

    Arguments
    ---------
    string : str
        String representing a number

    Returns
    -------
    bool
        True if the string is a positive integer
    """
    is_int = False
    if numeric_string:
        if numeric_string.isdigit():
            is_int = True
    return is_int


def call_with_context(ctx, func, *args, _context_callable=False, **kwargs):
    """
    Returns the value of func(*args, **kwargs) within the context
    Set '_context_callable=True' if your contextmanager needs to be called first
    """
    if _context_callable:
        ctx = ctx()
    with ctx:
        return func(*args, **kwargs)


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


def diluted_eps(adj_net_income, shares_outstanding):
    """Computes diluted earnings per share.

    @params
    -------
    adj_net_income: adjusted income available for ordinary shares, reflecting conversion of dilutive securities
    shares_outstanding: weighted average number of ordinary and potential ordinary shares outstanding

    returns
    -------
    Diluted earnings per share, int or float

    explanation
    -----------

    """
    return adj_net_income / shares_outstanding


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


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

        :param WriteError val:
        :rtype: SaveCopyReferenceError
        """
    return cls('path', val)


def filter_cds_utr_ncrna(df_in):
    """Filter regions CDS, UTR5, UTR3 and ncRNA by size and trim."""
    utr5 = df_in.region == 'UTR5'
    cds = df_in.region == 'CDS'
    utr3 = df_in.region == 'UTR3'
    ncrna = df_in.region == 'ncRNA'
    size = df_in.end - df_in.start >= 100
    df_out = df_in[utr5 & size | cds & size | utr3 & size | ncrna].copy()
    df_out.loc[df_out['region'] == 'CDS', ['start']] = df_out.start + 30
    df_out.loc[df_out['region'] == 'CDS', ['end']] = df_out.end - 30
    return df_out


def func_name_is_class_init(name):
    """Return True if |name| is that of a class' __init__ method."""
    return name == '__init__' or name.endswith('.__init__')


def get_tot_pop(dwellings):
    """Get total population of all dwellings

    Return
    ------
    tot_pop : float or bool
        If population is not provided, return `None`,
        otherwise summed population of all dwellings
    """
    tot_pop = 0
    for dwelling in dwellings:
        if dwelling.population is None:
            return None
        else:
            tot_pop += dwelling.population
    return tot_pop


def linear(x, weights):
    """A linear interaction.

    :param x:
        shape ``(batch_size, in_features)``
    :param weights:
        shape ``(n_factors, in_features, out_features)``
    """
    return x @ weights


def peek_char(fd, num_chars=1):
    """
        Read a char and seek the point back
    """
    peek_c = fd.peek(num_chars)[:num_chars]
    return bytes.decode(peek_c)


def parse_exported_playlist_data(filename):
    """
    Example how to load playlist information text file exported
    from iTunes (applies to iOS device backups as well).

    This can be used to figure out which songs there were on a iOS device
    playlist, which the silly thing can't do itself. What you need to do
    is to:
    - connect the iOS device
    - select playlist from the iOS device
    - use File -> Library -> Export Playlist to export playlist info to text file
    - repeat for every playlist on iOS

    To import the playlist directly back to iTunes, just use 'Import Playlist' from
    menu and import the text file ... silly buggers!

    When you have the .txt files, you can use this function to reconstruct the
    playlist contents, to for example export the information to a normal .m3u
    playlist of tracks in your library.
    """
    from csv import reader
    tracks = []
    with open(filename, 'r', encoding='utf-16') as fd:
        rows = reader(fd, delimiter='\t')
        fields = next(rows)
        for row in rows:
            track = {}
            for i, field in enumerate(fields):
                track[field] = row[i]
            tracks.append(track)
    return tracks


def _default_globals():
    """Return a mapping of default and precomputed expressions.
    These default expressions are convenience defaults available when eveluating
    section headers expressions.
    NB: this is wrapped in a function so that the computing of these expressions
    is lazy and done only if needed (ie if there is at least one section with
    an expression) because the computing of some of these expressions can be
    expensive.
    """
    import sys
    import os
    import platform
    import re
    globals_defs = {'sys': sys, 'os': os, 'platform': platform, 're': re}
    major_python_versions = tuple(map(str, platform.python_version_tuple()))
    globals_defs.update({'python2': major_python_versions[0] == '2',
        'python3': major_python_versions[0] == '3'})
    minor_python_versions = ('24', '25', '26', '27', '30', '31', '32', '33',
        '34', '35', '36')
    for v in minor_python_versions:
        globals_defs['python' + v] = ''.join(major_python_versions[:2]) == v
    sys_version = sys.version.lower()
    pypy = 'pypy' in sys_version
    jython = 'java' in sys_version
    ironpython = 'iron' in sys_version
    cpython = not any((pypy, jython, ironpython))
    globals_defs.update({'cpython': cpython, 'pypy': pypy, 'jython': jython,
        'ironpython': ironpython})
    sys_platform = str(sys.platform).lower()
    globals_defs.update({'linux': 'linux' in sys_platform, 'windows':
        'win32' in sys_platform, 'cygwin': 'cygwin' in sys_platform,
        'solaris': 'sunos' in sys_platform, 'macosx': 'darwin' in
        sys_platform, 'posix': 'posix' in os.name.lower()})
    import struct
    void_ptr_size = struct.calcsize('P') * 8
    globals_defs.update({'bits32': void_ptr_size == 32, 'bits64':
        void_ptr_size == 64, 'little_endian': sys.byteorder == 'little',
        'big_endian': sys.byteorder == 'big'})
    return globals_defs


def disable_domain_auto_renew(DomainName=None):
    """
    This operation disables automatic renewal of domain registration for the specified domain.
    See also: AWS API Documentation

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

    :type DomainName: string
    :param DomainName: [REQUIRED]
            The name of the domain that you want to disable automatic renewal for.

    :rtype: dict
    :return: {}

    """
    pass


def _glibc_version_string_ctypes():
    """
    Fallback implementation of glibc_version_string using ctypes.
    """
    try:
        import ctypes
    except ImportError:
        return None
    process_namespace = ctypes.CDLL(None)
    try:
        gnu_get_libc_version = process_namespace.gnu_get_libc_version
    except AttributeError:
        return None
    gnu_get_libc_version.restype = ctypes.c_char_p
    version_str = gnu_get_libc_version()
    if not isinstance(version_str, str):
        version_str = version_str.decode('ascii')
    return version_str


@classmethod
def coerce_type(cls, obj, typedef=None, **kwargs):
    """Coerce objects of specific types to match the data type.

        Args:
            obj (object): Object to be coerced.
            typedef (dict, optional): Type defintion that object should be
                coerced to. Defaults to None.
            **kwargs: Additional keyword arguments are metadata entries that may
                aid in coercing the type.

        Returns:
            object: Coerced object.

        """
    return obj


@staticmethod
def _transaction_begin(transaction_id, **kwargs):
    """Start a new transaction.
        :param transaction_id: ID for this transaction in the transport layer.
        :param **kwargs: Further parameters for the transport layer.
        """
    raise NotImplementedError('Transport interface not implemented')


def identity(x):
    """Returns its argument. Useful for certain things in the
    environment.
    """
    return x


def get_code_type(code):
    """
    判断代码是属于那种类型，目前仅支持 ['fund', 'stock']
    :return str 返回code类型, fund 基金 stock 股票
    """
    if code.startswith(('00', '30', '60')):
        return 'stock'
    return 'fund'


def _computer_test_no_unexpected_output(transport, scheduler, authinfo):
    """Test that there is no unexpected output from the connection.

    This can happen if e.g. there is some spurious command in the
    .bashrc or .bash_profile that is not guarded in case of non-interactive
    shells.

    :param transport: an open transport
    :param scheduler: the corresponding scheduler class
    :param authinfo: the AuthInfo object (from which one can get computer and aiidauser)
    :return: tuple of boolean indicating success or failure and an optional string message
    """
    retval, stdout, stderr = transport.exec_command_wait('echo -n')
    if retval != 0:
        return (False,
            'The command `echo -n` returned a non-zero return code ({})'.
            format(retval))
    if stdout:
        return (False,
            u"""
There is some spurious output in the standard output,
that we report below between the === signs:
=========================================================
{}
=========================================================
Please check that you don't have code producing output in
your ~/.bash_profile (or ~/.bashrc). If you don't want to
remove the code, but just to disable it for non-interactive
shells, see comments in issue #1980 on GitHub:
https://github.com/aiidateam/aiida-core/issues/1890
(and in the AiiDA documentation, linked from that issue)
"""
            .format(stdout))
    if stderr:
        return u"""
There is some spurious output in the stderr,
that we report below between the === signs:
=========================================================
{}
=========================================================
Please check that you don't have code producing output in
your ~/.bash_profile (or ~/.bashrc). If you don't want to
remove the code, but just to disable it for non-interactive
shells, see comments in issue #1980 on GitHub:
https://github.com/aiidateam/aiida-core/issues/1890
(and in the AiiDA documentation, linked from that issue)
"""
    return True, None


def alphatrans(plaintext, alpha1, alpha2):
    """
    Function for translation from a plaintext alphabet to a
    codetext alphabet.

    Args:
    plaintext -- plaintext to be coded.
    alpha1 -- plaintext alphabet.
    alpha2 -- codetext alphabet.

    Returns:
    Coded text string.
    """
    alpha1 = alpha1.lower()
    alpha2 = alpha2.lower()
    plaintext = plaintext.lower()
    codetext = ''
    for char in plaintext:
        try:
            index = alpha1.index(char)
            codetext += alpha2[index].upper()
        except:
            codetext += char
    return codetext


def _get_out_class(objs):
    """
    From a list of input objects ``objs`` get merged output object class.

    This is just taken as the deepest subclass. This doesn't handle complicated
    inheritance schemes.
    """
    out_class = objs[0].__class__
    for obj in objs[1:]:
        if issubclass(obj.__class__, out_class):
            out_class = obj.__class__
    if any(not issubclass(out_class, obj.__class__) for obj in objs):
        raise ValueError('unmergeable object classes {}'.format([obj.
            __class__.__name__ for obj in objs]))
    return out_class


def cp_sub_into_main_rr(rr_main, rr_sub, ys=None, ye=None):
    """
    Copies subset of results recorder into main results recorder

    :param rr_main:
    :type rr_main:
    :param rr_sub:
    :type rr_sub:
    :param ys:
    :type ys:
    :param ye:
    :type ye:
    """
    rr_main.error_alpha[ys:ye, :] = rr_sub.error_alpha
    rr_main.error_alpha_f[ys:ye, :] = rr_sub.error_alpha_f
    rr_main.error_f[ys:ye, :] = rr_sub.error_f
    rr_main.error_lsq[ys:ye, :] = rr_sub.error_lsq
    rr_main.chl[ys:ye, :] = rr_sub.chl
    rr_main.cdom[ys:ye, :] = rr_sub.cdom
    rr_main.nap[ys:ye, :] = rr_sub.nap
    rr_main.depth[ys:ye, :] = rr_sub.depth
    rr_main.sub1_frac[ys:ye, :] = rr_sub.sub1_frac
    rr_main.sub2_frac[ys:ye, :] = rr_sub.sub2_frac
    rr_main.sub3_frac[ys:ye, :] = rr_sub.sub3_frac
    rr_main.closed_rrs[ys:ye, :, :] = rr_sub.closed_rrs
    rr_main.nit[ys:ye, :] = rr_sub.nit
    rr_main.success[ys:ye, :] = rr_sub.success
    rr_main.kd[ys:ye, :] = rr_sub.kd
    rr_main.sdi[ys:ye, :] = rr_sub.sdi
    return


def getTLDs():
    """
        Return a dictionary of known ccTLDs and their languages.
        """


@classmethod
def fromWaves(cls, waves, unk02=0):
    """
        Create a SWAR from a list of SWAVs.
        """
    obj = cls(unk02=unk02)
    obj.waves = waves
    return obj


def script(js_file):
    """
    Returns a route to the JS folder. Renders the JS file in the js folder
    Error 404 is seen in the server log if not found
    :param js_file:
    :return:
    """
    if 'http' in js_file:
        return '<script type="text/javascript" src="' + js_file + '"></script>'
    return ('<script type="text/javascript" src="/script/' + js_file +
        '"></script>')


def path_reference(filepath: str, base_src: str, base_dst: str, mode: str=
    'AUTO', copy_subdir: str='', copy_set: set=None, library:
    'bpy.types.Library'=None) ->str:
    """Return a filepath relative to a destination directory, for use with exporters.

    :param filepath: the file path to return, supporting blenders relative ‘//’ prefix.
    :type filepath: str
    :param base_src: the directory the filepath is relative too (normally the blend file).
    :type base_src: str
    :param base_dst: the directory the filepath will be referenced from (normally the export path).
    :type base_dst: str
    :param mode: the method used get the path in [‘AUTO’, ‘ABSOLUTE’, ‘RELATIVE’, ‘MATCH’, ‘STRIP’, ‘COPY’]
    :type mode: str
    :param copy_subdir: the subdirectory of base_dst to use when mode=’COPY’.
    :type copy_subdir: str
    :param copy_set: collect from/to pairs when mode=’COPY’, pass to path_reference_copy when exporting is done.
    :type copy_set: set
    :param library: The library this path is relative to.
    :type library: 'bpy.types.Library'
    :return:  the new filepath.
    """
    pass


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 check_external_parameter_name(name):
    """
    Checks that a user-supplied parameter name meets the special criteria.
    Basically, we do not want such names start with underscores
    to prevent them from conflicting with internal names.
    """
    if name.startswith('_'):
        raise ValueError(
            'External parameter name cannot start with the underscore.')


@staticmethod
def filterContactsByName(contacts, nameA, nameB, mapindex):
    """Returns contacts, when their key is included in nameA and nameB."""
    filtered = []
    for c in contacts:
        add = False
        try:
            prop1 = c.key1[mapindex]
            prop2 = c.key2[mapindex]
        except IndexError:
            filtered.append(c)
            continue
        if nameA.lower() != u'all' and nameB.lower() != u'all':
            splitA = nameA.split(u',')
            splitB = nameB.split(u',')
            if prop1 in splitA and prop2 in splitB:
                add = True
        elif nameA.lower() != u'all' and nameB.lower() == u'all':
            splitA = nameA.split(u',')
            if prop1 in splitA:
                add = True
        elif nameA.lower() == u'all' and nameB.lower() != u'all':
            splitB = nameB.split(u',')
            if prop2 in splitB:
                add = True
        else:
            add = True
        if add:
            filtered.append(c)
    return filtered


def print_failure(message):
    """
    Given a message string, print as a failure in red.

    Parameters:
      - message: the message to print in red (indicating failure).
    """
    print('\x1b[31m' + message + '\x1b[0m')


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


def generate(userid, output_stream):
    """Generates a default avatar image for a user with the passed
        ``userid`` and writes to the ``output_stream``, which is expected
        to be a file-like object.
        """


def ignore(obj):
    """
    Decorator to specify that a task should be ignored.

    @type obj: function or Task, depending on order @ignore and @task used
    """
    obj.ignorable = True
    return obj


def two_port_matrix_to_complex_form(matrix_form_data):
    """two_port_matrix_to_complex_form takes a list of [[frequency,np.matrix([[S11,S12],[S21,S22]])]..]
    and returns a list in the
    form [[frequency,S11,S21,S12,S22],..] , it is meant to undo two_port_complex_to_matrix_form"""
    out_list = []
    for row in matrix_form_data:
        frequency = row[0]
        m = row[1]
        [S11, S21, S12, S22] = [m[0, 0], m[1, 0], m[0, 1], m[1, 1]]
        out_list.append([frequency, S11, S12, S21, S22])
    return out_list


def findRelations(query=(), maxDepth=None, filter=None, targetQuery=None,
    targetFilter=None, queryFactory=None, ignoreSearchIndex=False):
    """Given a single dictionary of {indexName: token}, return an iterable
        of relations that match the query"""


def has_colours(stream):
    """
    check the console can display color
    :param stream:
    """
    if not hasattr(stream, 'isatty'):
        return False
    if not stream.isatty():
        return False
    try:
        import curses
        curses.setupterm()
        return curses.tigetnum('colors') > 2
    except:
        return False


def same_shape(t1: tuple, t2: tuple) ->bool:
    """
    Returns True if t1 and t2 are the same shape.
    False, otherwise."""
    if t1 and t2:
        return len(t1) == len(t2)
    return False


def npoly_val(params, exponents, x_vals):
    """ Returns the value of an n-variable polynomial at the point given by
        x_vals
    """
    try:
        sum_of_terms = 0
        for i, param in enumerate(params):
            term = param
            for j, x in enumerate(x_vals):
                term = term * pow(x, exponents[i][j])
            sum_of_terms += term
        return sum_of_terms
    except:
        raise ValueError('exponents: {}; i = {}; j = {}; xdata = {}'.format
            (exponents, i, j, x_vals))


def merge_shards(shard_data, existing):
    """
    Compares ``shard_data`` with ``existing`` and updates ``shard_data`` with
    any items of ``existing`` that take precedence over the corresponding item
    in ``shard_data``.

    :param shard_data: a dict representation of shard range that may be
        modified by this method.
    :param existing: a dict representation of shard range.
    :returns: True if ``shard data`` has any item(s) that are considered to
        take precedence over the corresponding item in ``existing``
    """
    if not existing:
        return True
    if existing['timestamp'] < shard_data['timestamp']:
        return True
    elif existing['timestamp'] > shard_data['timestamp']:
        return False
    new_content = False
    for k in ('lower', 'upper', 'deleted'):
        shard_data[k] = existing[k]
    if existing['meta_timestamp'] >= shard_data['meta_timestamp']:
        for k in ('object_count', 'bytes_used', 'meta_timestamp'):
            shard_data[k] = existing[k]
    else:
        new_content = True
    if existing['state_timestamp'] == shard_data['state_timestamp'
        ] and shard_data['state'] > existing['state']:
        new_content = True
    elif existing['state_timestamp'] >= shard_data['state_timestamp']:
        for k in ('state', 'state_timestamp', 'epoch'):
            shard_data[k] = existing[k]
    else:
        new_content = True
    return new_content


@classmethod
def get_dict(cls):
    """
        Returns the class dictionary.
        """
    return cls.CLASS_DICT


def pack_padded_tensor(input, lengths):
    """Packs a tensor containing padded sequence of variable length.

    Parameters
    ----------
    input : Tensor
        The input tensor with shape :math:`(B, L, *)`, where :math:`B` is
        the batch size and :math:`L` is the maximum length of the batch.
    lengths : list or tensor
        The array of tensor lengths (of the first dimension) :math:`L`.
        :math:`\\max_i(L_i)` should equal :math:`L`.

    Returns
    -------
    Tensor
        The obtained tensor with shape :math:`(N, *)` where
        :math:`N = \\sum_{i=1}^{B}L_i`
    """
    pass


def get(isamAppliance, uuid, check_mode=False, force=False):
    """
    Retrieving a single interface
    """
    return isamAppliance.invoke_get('Retrieving a single interface',
        '/net/ifaces/' + uuid)


def _real_dollar(s, m):
    """$ Matches the end of the string or just before the newline at the end of the string"""
    if m:
        length_1 = s.__len__()
        length_2 = m.group(0).__len__()
        if length_1 == length_2:
            return True
        else:
            return False
    else:
        return False


def create_or_update(model, *, defaults=None, save=True, **kwargs):
    """
    Create or update a django model instance.

    :param model:
    :param defaults:
    :param kwargs:
    :return: object, created, updated

    """
    obj, created = model._default_manager.get_or_create(defaults=defaults,
        **kwargs)
    updated = False
    if not created:
        if defaults:
            for k, v in defaults.items():
                if getattr(obj, k) != v:
                    setattr(obj, k, v)
                    updated = True
        if updated and save:
            obj.save()
    return obj, created, updated