def amalgamate_sql(app, model, extra_fields=None, table_name=None,
    view_name=None):
    """This function returns a string, containing SQL to create
    a view exposing given model's content_type_id and object_id,
    with some extra_fields optionally.

    This function does *not* escape or quote its arguments.

    >>> print(utils.amalgamate_sql('tests', 'phone', ['foo', 'x as y']))

            CREATE VIEW tests_phone_view AS
            SELECT
                U0.id::text || '_' || test_phone.id::text AS fake_id,
                U0.id AS content_type_id,
                tests_phone.id AS object_id
                , foo, x as y
            FROM
                tests_phone,
                (SELECT
                    id
                 FROM
                    django_content_type
                 WHERE
                    app_label = 'tests' AND
                    model = 'phone'
                ) U0;
    """
    if extra_fields == None:
        extra_fields = []
    extra_fields = ', '.join(extra_fields)
    if extra_fields:
        extra_fields = ', ' + extra_fields
    if not table_name:
        table_name = '%s_%s' % (app, model)
    if not view_name:
        view_name = '%s_view' % table_name
    return (
        """
            CREATE VIEW %(view_name)s AS
            SELECT
                U0.id::text || '_' || %(table_name)s.id AS fake_id,
                U0.id AS content_type_id,
                %(table_name)s.id AS object_id
                %(extra_fields)s
            FROM
                %(table_name)s,
                (SELECT
                    id
                 FROM
                    django_content_type
                 WHERE
                    app_label = '%(app)s' AND
                    model = '%(model)s'
                ) U0;
    """
         % dict(view_name=view_name, app=app, model=model, table_name=
        table_name, extra_fields=extra_fields))


def pipe(value, *funcs):
    """Pipe a value through a sequence of functions."""
    for func in funcs:
        value = func(value)
    return value


def _translateArgs(**keywords):
    """
    Returns a tuple of inPlace (default False) and debug (default False)
    from a set of keywords:

    >>> braille.translate._translateArgs()
    (False, False)
    >>> braille.translate._translateArgs(debug=True)
    (False, True)
    >>> braille.translate._translateArgs(inPlace=True)
    (True, False)
    >>> braille.translate._translateArgs(inPlace=True, debug=True)
    (True, True)
    """
    inPlace = keywords.get('inPlace', False)
    debug = keywords.get('debug', False)
    return inPlace, debug


def display_init_rulesengine_db(db_root):
    """display function for initializing the rules engine db"""
    print('Created rules engine database at %s' % db_root)


def _apply_default_for_one_key(key, cfg, shared):
    """apply default to a config for a key

    Parameters
    ----------
    key : str
        A config key
    cfg : dict
        A config
    shared : dict
        A dict of shared objects.

    Returns
    -------
    function
        A config with default applied

    """
    ret = {}
    for default_cfg in shared['default_cfg_stack']:
        ret.update(default_cfg.get(key, {}))
    ret.update(cfg)
    return ret


def change(new, old):
    """Return the percent change"""
    return (new - old) / old


@classmethod
def stepOut(cls):
    """Steps out of the function call.
        """
    return cls.build_send_payload('stepOut', {}), None


def countOf(a, b):
    """Return the number of times b occurs in a."""
    count = 0
    for i in a:
        if i == b:
            count += 1
    return count


def mass_gpemgh(GPE, gravity, height):
    """Usage: Find mass from gravitational potential energy, gravity and height"""
    result = GPE / gravity * height
    return result


def get_boundary(content_type):
    """
    Extracts boundary from Content-Type
    """
    if content_type.startswith('multipart/form-data'):
        fields = content_type.split(';')
        for field in fields:
            k, sep, v = field.strip().partition('=')
            if k == 'boundary' and v:
                return v
        else:
            raise ValueError('multipart boundary not found')


def detect_file_format(data):
    """ Determine format of a file

    Parameters
    ----------
    data : string
        string containing file data.

    Returns
    -------
    format : string
        File format. 'excellon' or 'rs274x' or 'unknown'
    """
    lines = data.split('\n')
    for line in lines:
        if 'M48' in line:
            return 'excellon'
        elif '%FS' in line:
            return 'rs274x'
        elif len(line.split()) >= 2 and line.split()[0] == 'P' and line.split(
            )[1] == 'JOB':
            return 'ipc_d_356'
    return 'unknown'


def check_url(url):
    """ Check if the url available """
    ret = 0
    code = 404
    try:
        from urllib2 import urlopen
    except:
        from urllib.request import urlopen
    try:
        resp = urlopen(url)
        code = resp.getcode()
    except:
        pass
    if code != 200:
        ret = 1
    return ret


def weight_set(factor: float=1.0):
    """Set the weight of selected keys

    :param factor: Factor, Interpolation factor between current brush weight, and keys’ weights
    :type factor: float
    """
    pass


def restore_bot_from_backup(backup_filename, *, bot, log):
    """Restores the given bot by executing the 'backup' script.

    The backup file is a python script which manually execute a series of commands on the bot
    to restore it to its previous state.

    :param backup_filename: the full path to the backup script.
    :param bot: the bot instance to restore
    :param log: logger to use during the restoration process
    """
    with open(backup_filename) as f:
        exec(f.read(), {'log': log, 'bot': bot})
    bot.close_storage()


def view_all():
    """Show the entire playable frame range

    """
    pass


def _quadrant_gt(quadrant, x, y, x0, y0):
    """Return whether y is further along the ellipse than coord."""
    if quadrant % 2 == 0:
        if y != y0:
            return y > y0
        else:
            return x < x0
    elif y != y0:
        return y < y0
    else:
        return x > x0


def clean_asn(asn):
    """
    Take something either as 18345, ASn17839 or AS2893
    And returns just the number as a number
    """
    if asn.lower().startswith('asn'):
        return int(asn[3:])
    elif asn.lower().startswith('as'):
        return int(asn[2:])
    else:
        return int(asn)


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

        :param Optional[str] val:
        :rtype: LookupError
        """
    return cls('malformed_path', val)


def graph_delete_curve():
    """Delete track corresponding to the selected curve

    """
    pass


def fill_in_global_parameters(global_params, local_params):
    """
    Update the local parameters with existing global parameters
    without overriding existing ones.
    """
    for key, value in global_params.items():
        for local in local_params.values():
            if key not in local:
                local[key] = value


def parse_genes(gene_file):
    """Select gene to exclude: where sgt column is not 'yes'
    input: csv file with genes
    return: set of genes which should be exluded"""
    to_exlude = set()
    with open(gene_file) as lines:
        next(lines)
        for line in lines:
            gene, _, _, sgt = line.split(',')
            sgt = sgt.strip()
            if sgt.lower() != 'yes':
                to_exlude.add(gene)
    return to_exlude


def provides_facts():
    """
    Returns a dictionary keyed on the facts provided by this module. The value
    of each key is the doc string describing the fact.
    """
    return {'switch_style':
        "A string which indicates the Ethernet switching syntax style supported by the device. Possible values are: 'BRIDGE_DOMAIN', 'VLAN', 'VLAN_L2NG', or 'NONE'."
        }


def de2bin(x):
    """convert decimal to binary
    input: 15
    output: 11110000
    """
    bstr = ''
    x = int(x)
    n = 7
    while n >= 0:
        re = x / 2 ** n
        if re == 1:
            x = x % 2 ** n
        n = n - 1
        bstr = bstr + str(re)
    return bstr


def isoformat(dt):
    """Return iso-formatted timestamp

    Like .isoformat(), but uses Z for UTC instead of +00:00
    """
    return dt.isoformat().replace('+00:00', 'Z')


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

        :param PaperFolderFollowedType val:
        :rtype: EventType
        """
    return cls('paper_folder_followed', val)


def _create_node_matrix_from_full_matrix(specs):
    """Transform parsed data from EDGE_WEIGHT_SECTION into an upper triangular matrix

    'MATRIX' key added to `specs`
    """
    old_matrix = specs['EDGE_WEIGHT_SECTION']
    nodes = specs['DIMENSION']
    specs['MATRIX'] = {}
    for i in range(nodes):
        specs['MATRIX'][i + 1] = {}
        for j in range(nodes):
            if i > j:
                continue
            specs['MATRIX'][i + 1][j + 1] = int(old_matrix[i][j])


def remove_all(apps, schema_editor):
    """
    We can't import the Post model directly as it may be a newer
    version than this migration expects. We use the historical version.
    """
    CoSale = apps.get_model('cosales', 'CoSale')
    CoSale.objects.all().delete()
    CoSaleHistory = apps.get_model('cosales', 'CoSaleHistory')
    CoSaleHistory.objects.all().delete()


def strtobool(val: str) ->bool:
    """Convert a string representation of truth to true or false.

    True values are 'y', 'yes', 't', 'true', 'on', and '1'.
    False values are 'n', 'no', 'f', 'false', 'off', and '0'.
    Raises ValueError if 'val' is anything else.

    Taken from distutils.util and modified to return correct type.
    """
    val = val.lower()
    if val in ('y', 'yes', 't', 'true', 'on', '1'):
        return True
    elif val in ('n', 'no', 'f', 'false', 'off', '0'):
        return False
    else:
        raise ValueError('invalid truth value %r' % (val,))


def processMail():
    """ Process a mail message contained within the adapted request """


def get_register_count(num_blocks, num_threads):
    """
    Returns the number of registers available per block for sm_20

    Parameters
    ----------
    num_blocks : int
        The number of blocks to target per kernel launch
    num_threads : int
        The number of threads to target per kernel launch
    """
    return max(min(32768 / num_blocks / num_threads, 63), 1)


def argsort(a, reverse=False):
    """return index list to get `a` in order, ie
    ``a[argsort(a)[i]] == sorted(a)[i]``, which leads to unexpected
    results with `np.nan` entries, because any comparison with `np.nan`
    is `False`.
    """
    return sorted(range(len(a)), key=a.__getitem__, reverse=reverse)


def request_spot_instances(DryRun=None, SpotPrice=None, ClientToken=None,
    InstanceCount=None, Type=None, ValidFrom=None, ValidUntil=None,
    LaunchGroup=None, AvailabilityZoneGroup=None, BlockDurationMinutes=None,
    LaunchSpecification=None):
    """
    Creates a Spot instance request. Spot instances are instances that Amazon EC2 launches when the bid price that you specify exceeds the current Spot price. Amazon EC2 periodically sets the Spot price based on available Spot Instance capacity and current Spot instance requests. For more information, see Spot Instance Requests in the Amazon Elastic Compute Cloud User Guide .
    See also: AWS API Documentation

    Examples
    This example creates a one-time Spot Instance request for five instances in the specified Availability Zone. If your account supports EC2-VPC only, Amazon EC2 launches the instances in the default subnet of the specified Availability Zone. If your account supports EC2-Classic, Amazon EC2 launches the instances in EC2-Classic in the specified Availability Zone.
    Expected Output:
    This example command creates a one-time Spot Instance request for five instances in the specified subnet. Amazon EC2 launches the instances in the specified subnet. If the VPC is a nondefault VPC, the instances do not receive a public IP address by default.
    Expected Output:

    :example: response = client.request_spot_instances(
        DryRun=True|False,
        SpotPrice='string',
        ClientToken='string',
        InstanceCount=123,
        Type='one-time'|'persistent',
        ValidFrom=datetime(2015, 1, 1),
        ValidUntil=datetime(2015, 1, 1),
        LaunchGroup='string',
        AvailabilityZoneGroup='string',
        BlockDurationMinutes=123,
        LaunchSpecification={
            'ImageId': 'string',
            'KeyName': 'string',
            'SecurityGroups': [
                'string',
            ],
            'UserData': 'string',
            'AddressingType': 'string',
            'InstanceType': 't1.micro'|'t2.nano'|'t2.micro'|'t2.small'|'t2.medium'|'t2.large'|'t2.xlarge'|'t2.2xlarge'|'m1.small'|'m1.medium'|'m1.large'|'m1.xlarge'|'m3.medium'|'m3.large'|'m3.xlarge'|'m3.2xlarge'|'m4.large'|'m4.xlarge'|'m4.2xlarge'|'m4.4xlarge'|'m4.10xlarge'|'m4.16xlarge'|'m2.xlarge'|'m2.2xlarge'|'m2.4xlarge'|'cr1.8xlarge'|'r3.large'|'r3.xlarge'|'r3.2xlarge'|'r3.4xlarge'|'r3.8xlarge'|'r4.large'|'r4.xlarge'|'r4.2xlarge'|'r4.4xlarge'|'r4.8xlarge'|'r4.16xlarge'|'x1.16xlarge'|'x1.32xlarge'|'i2.xlarge'|'i2.2xlarge'|'i2.4xlarge'|'i2.8xlarge'|'i3.large'|'i3.xlarge'|'i3.2xlarge'|'i3.4xlarge'|'i3.8xlarge'|'i3.16xlarge'|'hi1.4xlarge'|'hs1.8xlarge'|'c1.medium'|'c1.xlarge'|'c3.large'|'c3.xlarge'|'c3.2xlarge'|'c3.4xlarge'|'c3.8xlarge'|'c4.large'|'c4.xlarge'|'c4.2xlarge'|'c4.4xlarge'|'c4.8xlarge'|'cc1.4xlarge'|'cc2.8xlarge'|'g2.2xlarge'|'g2.8xlarge'|'cg1.4xlarge'|'p2.xlarge'|'p2.8xlarge'|'p2.16xlarge'|'d2.xlarge'|'d2.2xlarge'|'d2.4xlarge'|'d2.8xlarge'|'f1.2xlarge'|'f1.16xlarge',
            'Placement': {
                'AvailabilityZone': 'string',
                'GroupName': 'string',
                'Tenancy': 'default'|'dedicated'|'host'
            },
            'KernelId': 'string',
            'RamdiskId': 'string',
            'BlockDeviceMappings': [
                {
                    'VirtualName': 'string',
                    'DeviceName': 'string',
                    'Ebs': {
                        'SnapshotId': 'string',
                        'VolumeSize': 123,
                        'DeleteOnTermination': True|False,
                        'VolumeType': 'standard'|'io1'|'gp2'|'sc1'|'st1',
                        'Iops': 123,
                        'Encrypted': True|False
                    },
                    'NoDevice': 'string'
                },
            ],
            'SubnetId': 'string',
            'NetworkInterfaces': [
                {
                    'NetworkInterfaceId': 'string',
                    'DeviceIndex': 123,
                    'SubnetId': 'string',
                    'Description': 'string',
                    'PrivateIpAddress': 'string',
                    'Groups': [
                        'string',
                    ],
                    'DeleteOnTermination': True|False,
                    'PrivateIpAddresses': [
                        {
                            'PrivateIpAddress': 'string',
                            'Primary': True|False
                        },
                    ],
                    'SecondaryPrivateIpAddressCount': 123,
                    'AssociatePublicIpAddress': True|False,
                    'Ipv6Addresses': [
                        {
                            'Ipv6Address': 'string'
                        },
                    ],
                    'Ipv6AddressCount': 123
                },
            ],
            'IamInstanceProfile': {
                'Arn': 'string',
                'Name': 'string'
            },
            'EbsOptimized': True|False,
            'Monitoring': {
                'Enabled': True|False
            },
            'SecurityGroupIds': [
                'string',
            ]
        }
    )

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

    :type SpotPrice: string
    :param SpotPrice: [REQUIRED]
            The maximum hourly price (bid) for any Spot instance launched to fulfill the request.

    :type ClientToken: string
    :param ClientToken: Unique, case-sensitive identifier that you provide to ensure the idempotency of the request. For more information, see How to Ensure Idempotency in the Amazon Elastic Compute Cloud User Guide .

    :type InstanceCount: integer
    :param InstanceCount: The maximum number of Spot instances to launch.
            Default: 1

    :type Type: string
    :param Type: The Spot instance request type.
            Default: one-time

    :type ValidFrom: datetime
    :param ValidFrom: The start date of the request. If this is a one-time request, the request becomes active at this date and time and remains active until all instances launch, the request expires, or the request is canceled. If the request is persistent, the request becomes active at this date and time and remains active until it expires or is canceled.
            Default: The request is effective indefinitely.

    :type ValidUntil: datetime
    :param ValidUntil: The end date of the request. If this is a one-time request, the request remains active until all instances launch, the request is canceled, or this date is reached. If the request is persistent, it remains active until it is canceled or this date and time is reached.
            Default: The request is effective indefinitely.

    :type LaunchGroup: string
    :param LaunchGroup: The instance launch group. Launch groups are Spot instances that launch together and terminate together.
            Default: Instances are launched and terminated individually

    :type AvailabilityZoneGroup: string
    :param AvailabilityZoneGroup: The user-specified name for a logical grouping of bids.
            When you specify an Availability Zone group in a Spot Instance request, all Spot instances in the request are launched in the same Availability Zone. Instance proximity is maintained with this parameter, but the choice of Availability Zone is not. The group applies only to bids for Spot Instances of the same instance type. Any additional Spot instance requests that are specified with the same Availability Zone group name are launched in that same Availability Zone, as long as at least one instance from the group is still active.
            If there is no active instance running in the Availability Zone group that you specify for a new Spot instance request (all instances are terminated, the bid is expired, or the bid falls below current market), then Amazon EC2 launches the instance in any Availability Zone where the constraint can be met. Consequently, the subsequent set of Spot instances could be placed in a different zone from the original request, even if you specified the same Availability Zone group.
            Default: Instances are launched in any available Availability Zone.

    :type BlockDurationMinutes: integer
    :param BlockDurationMinutes: The required duration for the Spot instances (also known as Spot blocks), in minutes. This value must be a multiple of 60 (60, 120, 180, 240, 300, or 360).
            The duration period starts as soon as your Spot instance receives its instance ID. At the end of the duration period, Amazon EC2 marks the Spot instance for termination and provides a Spot instance termination notice, which gives the instance a two-minute warning before it terminates.
            Note that you can't specify an Availability Zone group or a launch group if you specify a duration.

    :type LaunchSpecification: dict
    :param LaunchSpecification: Describes the launch specification for an instance.
            ImageId (string) --The ID of the AMI.
            KeyName (string) --The name of the key pair.
            SecurityGroups (list) --
            (string) --
            UserData (string) --The user data to make available to the instances. If you are using an AWS SDK or command line tool, Base64-encoding is performed for you, and you can load the text from a file. Otherwise, you must provide Base64-encoded text.
            AddressingType (string) --Deprecated.
            InstanceType (string) --The instance type.
            Placement (dict) --The placement information for the instance.
            AvailabilityZone (string) --The Availability Zone.
            [Spot fleet only] To specify multiple Availability Zones, separate them using commas; for example, 'us-west-2a, us-west-2b'.
            GroupName (string) --The name of the placement group (for cluster instances).
            Tenancy (string) --The tenancy of the instance (if the instance is running in a VPC). An instance with a tenancy of dedicated runs on single-tenant hardware. The host tenancy is not supported for Spot instances.
            KernelId (string) --The ID of the kernel.
            RamdiskId (string) --The ID of the RAM disk.
            BlockDeviceMappings (list) --One or more block device mapping entries.
            Although you can specify encrypted EBS volumes in this block device mapping for your Spot Instances, these volumes are not encrypted.
            (dict) --Describes a block device mapping.
            VirtualName (string) --The virtual device name (ephemeral N). Instance store volumes are numbered starting from 0. An instance type with 2 available instance store volumes can specify mappings for ephemeral0 and ephemeral1 .The number of available instance store volumes depends on the instance type. After you connect to the instance, you must mount the volume.
            Constraints: For M3 instances, you must specify instance store volumes in the block device mapping for the instance. When you launch an M3 instance, we ignore any instance store volumes specified in the block device mapping for the AMI.
            DeviceName (string) --The device name exposed to the instance (for example, /dev/sdh or xvdh ).
            Ebs (dict) --Parameters used to automatically set up EBS volumes when the instance is launched.
            SnapshotId (string) --The ID of the snapshot.
            VolumeSize (integer) --The size of the volume, in GiB.
            Constraints: 1-16384 for General Purpose SSD (gp2 ), 4-16384 for Provisioned IOPS SSD (io1 ), 500-16384 for Throughput Optimized HDD (st1 ), 500-16384 for Cold HDD (sc1 ), and 1-1024 for Magnetic (standard ) volumes. If you specify a snapshot, the volume size must be equal to or larger than the snapshot size.
            Default: If you're creating the volume from a snapshot and don't specify a volume size, the default is the snapshot size.
            DeleteOnTermination (boolean) --Indicates whether the EBS volume is deleted on instance termination.
            VolumeType (string) --The volume type: gp2 , io1 , st1 , sc1 , or standard .
            Default: standard
            Iops (integer) --The number of I/O operations per second (IOPS) that the volume supports. For io1 , this represents the number of IOPS that are provisioned for the volume. For gp2 , this represents the baseline performance of the volume and the rate at which the volume accumulates I/O credits for bursting. For more information about General Purpose SSD baseline performance, I/O credits, and bursting, see Amazon EBS Volume Types in the Amazon Elastic Compute Cloud User Guide .
            Constraint: Range is 100-20000 IOPS for io1 volumes and 100-10000 IOPS for gp2 volumes.
            Condition: This parameter is required for requests to create io1 volumes; it is not used in requests to create gp2 , st1 , sc1 , or standard volumes.
            Encrypted (boolean) --Indicates whether the EBS volume is encrypted. Encrypted Amazon EBS volumes may only be attached to instances that support Amazon EBS encryption.
            NoDevice (string) --Suppresses the specified device included in the block device mapping of the AMI.

            SubnetId (string) --The ID of the subnet in which to launch the instance.
            NetworkInterfaces (list) --One or more network interfaces. If you specify a network interface, you must specify subnet IDs and security group IDs using the network interface.
            (dict) --Describes a network interface.
            NetworkInterfaceId (string) --The ID of the network interface.
            DeviceIndex (integer) --The index of the device on the instance for the network interface attachment. If you are specifying a network interface in a RunInstances request, you must provide the device index.
            SubnetId (string) --The ID of the subnet associated with the network string. Applies only if creating a network interface when launching an instance.
            Description (string) --The description of the network interface. Applies only if creating a network interface when launching an instance.
            PrivateIpAddress (string) --The private IPv4 address of the network interface. Applies only if creating a network interface when launching an instance. You cannot specify this option if you're launching more than one instance in a RunInstances request.
            Groups (list) --The IDs of the security groups for the network interface. Applies only if creating a network interface when launching an instance.
            (string) --
            DeleteOnTermination (boolean) --If set to true , the interface is deleted when the instance is terminated. You can specify true only if creating a new network interface when launching an instance.
            PrivateIpAddresses (list) --One or more private IPv4 addresses to assign to the network interface. Only one private IPv4 address can be designated as primary. You cannot specify this option if you're launching more than one instance in a RunInstances request.
            (dict) --Describes a secondary private IPv4 address for a network interface.
            PrivateIpAddress (string) -- [REQUIRED]The private IPv4 addresses.
            Primary (boolean) --Indicates whether the private IPv4 address is the primary private IPv4 address. Only one IPv4 address can be designated as primary.

            SecondaryPrivateIpAddressCount (integer) --The number of secondary private IPv4 addresses. You can't specify this option and specify more than one private IP address using the private IP addresses option. You cannot specify this option if you're launching more than one instance in a RunInstances request.
            AssociatePublicIpAddress (boolean) --Indicates whether to assign a public IPv4 address to an instance you launch in a VPC. The public IP address can only be assigned to a network interface for eth0, and can only be assigned to a new network interface, not an existing one. You cannot specify more than one network interface in the request. If launching into a default subnet, the default value is true .
            Ipv6Addresses (list) --One or more IPv6 addresses to assign to the network interface. You cannot specify this option and the option to assign a number of IPv6 addresses in the same request. You cannot specify this option if you've specified a minimum number of instances to launch.
            (dict) --Describes an IPv6 address.
            Ipv6Address (string) --The IPv6 address.

            Ipv6AddressCount (integer) --A number of IPv6 addresses to assign to the network interface. Amazon EC2 chooses the IPv6 addresses from the range of the subnet. You cannot specify this option and the option to assign specific IPv6 addresses in the same request. You can specify this option if you've specified a minimum number of instances to launch.

            IamInstanceProfile (dict) --The IAM instance profile.
            Arn (string) --The Amazon Resource Name (ARN) of the instance profile.
            Name (string) --The name of the instance profile.
            EbsOptimized (boolean) --Indicates whether the instance is optimized for EBS I/O. This optimization provides dedicated throughput to Amazon EBS and an optimized configuration stack to provide optimal EBS I/O performance. This optimization isn't available with all instance types. Additional usage charges apply when using an EBS Optimized instance.
            Default: false
            Monitoring (dict) --Describes the monitoring of an instance.
            Enabled (boolean) -- [REQUIRED]Indicates whether detailed monitoring is enabled. Otherwise, basic monitoring is enabled.
            SecurityGroupIds (list) --
            (string) --

    :rtype: dict
    :return: {
        'SpotInstanceRequests': [
            {
                'SpotInstanceRequestId': 'string',
                'SpotPrice': 'string',
                'Type': 'one-time'|'persistent',
                'State': 'open'|'active'|'closed'|'cancelled'|'failed',
                'Fault': {
                    'Code': 'string',
                    'Message': 'string'
                },
                'Status': {
                    'Code': 'string',
                    'UpdateTime': datetime(2015, 1, 1),
                    'Message': 'string'
                },
                'ValidFrom': datetime(2015, 1, 1),
                'ValidUntil': datetime(2015, 1, 1),
                'LaunchGroup': 'string',
                'AvailabilityZoneGroup': 'string',
                'LaunchSpecification': {
                    'ImageId': 'string',
                    'KeyName': 'string',
                    'SecurityGroups': [
                        {
                            'GroupName': 'string',
                            'GroupId': 'string'
                        },
                    ],
                    'UserData': 'string',
                    'AddressingType': 'string',
                    'InstanceType': 't1.micro'|'t2.nano'|'t2.micro'|'t2.small'|'t2.medium'|'t2.large'|'t2.xlarge'|'t2.2xlarge'|'m1.small'|'m1.medium'|'m1.large'|'m1.xlarge'|'m3.medium'|'m3.large'|'m3.xlarge'|'m3.2xlarge'|'m4.large'|'m4.xlarge'|'m4.2xlarge'|'m4.4xlarge'|'m4.10xlarge'|'m4.16xlarge'|'m2.xlarge'|'m2.2xlarge'|'m2.4xlarge'|'cr1.8xlarge'|'r3.large'|'r3.xlarge'|'r3.2xlarge'|'r3.4xlarge'|'r3.8xlarge'|'r4.large'|'r4.xlarge'|'r4.2xlarge'|'r4.4xlarge'|'r4.8xlarge'|'r4.16xlarge'|'x1.16xlarge'|'x1.32xlarge'|'i2.xlarge'|'i2.2xlarge'|'i2.4xlarge'|'i2.8xlarge'|'i3.large'|'i3.xlarge'|'i3.2xlarge'|'i3.4xlarge'|'i3.8xlarge'|'i3.16xlarge'|'hi1.4xlarge'|'hs1.8xlarge'|'c1.medium'|'c1.xlarge'|'c3.large'|'c3.xlarge'|'c3.2xlarge'|'c3.4xlarge'|'c3.8xlarge'|'c4.large'|'c4.xlarge'|'c4.2xlarge'|'c4.4xlarge'|'c4.8xlarge'|'cc1.4xlarge'|'cc2.8xlarge'|'g2.2xlarge'|'g2.8xlarge'|'cg1.4xlarge'|'p2.xlarge'|'p2.8xlarge'|'p2.16xlarge'|'d2.xlarge'|'d2.2xlarge'|'d2.4xlarge'|'d2.8xlarge'|'f1.2xlarge'|'f1.16xlarge',
                    'Placement': {
                        'AvailabilityZone': 'string',
                        'GroupName': 'string',
                        'Tenancy': 'default'|'dedicated'|'host'
                    },
                    'KernelId': 'string',
                    'RamdiskId': 'string',
                    'BlockDeviceMappings': [
                        {
                            'VirtualName': 'string',
                            'DeviceName': 'string',
                            'Ebs': {
                                'SnapshotId': 'string',
                                'VolumeSize': 123,
                                'DeleteOnTermination': True|False,
                                'VolumeType': 'standard'|'io1'|'gp2'|'sc1'|'st1',
                                'Iops': 123,
                                'Encrypted': True|False
                            },
                            'NoDevice': 'string'
                        },
                    ],
                    'SubnetId': 'string',
                    'NetworkInterfaces': [
                        {
                            'NetworkInterfaceId': 'string',
                            'DeviceIndex': 123,
                            'SubnetId': 'string',
                            'Description': 'string',
                            'PrivateIpAddress': 'string',
                            'Groups': [
                                'string',
                            ],
                            'DeleteOnTermination': True|False,
                            'PrivateIpAddresses': [
                                {
                                    'PrivateIpAddress': 'string',
                                    'Primary': True|False
                                },
                            ],
                            'SecondaryPrivateIpAddressCount': 123,
                            'AssociatePublicIpAddress': True|False,
                            'Ipv6Addresses': [
                                {
                                    'Ipv6Address': 'string'
                                },
                            ],
                            'Ipv6AddressCount': 123
                        },
                    ],
                    'IamInstanceProfile': {
                        'Arn': 'string',
                        'Name': 'string'
                    },
                    'EbsOptimized': True|False,
                    'Monitoring': {
                        'Enabled': True|False
                    }
                },
                'InstanceId': 'string',
                'CreateTime': datetime(2015, 1, 1),
                'ProductDescription': 'Linux/UNIX'|'Linux/UNIX (Amazon VPC)'|'Windows'|'Windows (Amazon VPC)',
                'BlockDurationMinutes': 123,
                'ActualBlockHourlyPrice': 'string',
                'Tags': [
                    {
                        'Key': 'string',
                        'Value': 'string'
                    },
                ],
                'LaunchedAvailabilityZone': 'string'
            },
        ]
    }

    :returns:
    (string) --

    """
    pass


def __rsub__(x1, x2):
    """Subtract a NormalDist from a constant or another NormalDist."""
    return -(x1 - x2)


def publishing():
    """Whether the repository is a publishing repository."""


def largura_imagem(img):
    """
    Retorna a largura da imagem
    :param img: Imagem
    :return: Int
    """
    return img.get_width()


def wsgi_path_item(environ, name):
    """Extract the value of a named field in a URL.

    Return None if the name is not present or there are no path items.
    """
    try:
        return environ['wsgiorg.routing_args'][1][name]
    except (KeyError, IndexError):
        return None


def checkisnoseatpro(productlist):
    """
    检测传入的商品列表中是否还存在未占位商品
    add by hexiaoxia 2019/04/16
    :param productlist: 商品列表
    :return:
    """
    for product in productlist:
        for seat in product.productSeatList:
            if seat.seat == False:
                return True
    return False


def each_log(log_iter, action_map):
    """Call a callback for each item in an iterable containing structured
    log entries

    :param log_iter: Iterator returning structured log entries
    :param action_map: Dictionary mapping action name to callback function. Log items
                       with actions not in this dictionary will be skipped.
    """
    for item in log_iter:
        if item['action'] in action_map:
            action_map[item['action']](item)


@classmethod
def _load_jupyter_server_extension(cls, serverapp):
    """Initialize and configure this extension, then add the extension's
        settings and handlers to the server's web application.
        """
    try:
        extension = serverapp._enabled_extensions[cls.extension_name]
    except KeyError:
        extension = cls()
        extension.link_to_serverapp(serverapp)
    extension.initialize()
    return extension


@classmethod
def should_skip_field(cls, field):
    """
        Given a Django model field, return if it should be included in the
        contributed ApiFields.
        """
    if getattr(field, 'rel'):
        return True
    return False


@staticmethod
def empty():
    """
        Constructs an empty Exception.
        """
    return Exception()


@classmethod
def unmarshal(cls, raw: bytes):
    """Returns a new FactoidBlock object, unmarshalling given bytes according to:
        https://github.com/FactomProject/FactomDocs/blob/master/factomDataStructureDetails.md#factoid-block

        Useful for working with a single fblock out of context, pulled directly from a factomd database for instance.

        FactoidBlock created will not include contextual metadata, such as timestamp or the pointer to the
        next factoid block.
        """
    block, data = cls.unmarshal_with_remainder(raw)
    assert len(data) == 0, 'Extra bytes remaining!'
    return block


def convert_list(in_list):
    """Converts a list of strings to a printable list of object names"""
    return ''.join(('[', ','.join(in_list), ']'))


def removewhitespace(text):
    """
    Remove the whitespace in the string

    :param text: string
    :return: string with no whitespace
    """
    return ''.join(text.strip().split())


@staticmethod
def is_main_name(name):
    """Check if name comes from a block on the main path

        :param name: block_id
        :rtype: bool
        """
    if 'alt' not in name:
        return True
    if name.count('chr') > 1:
        return True
    return False


def test_dns_answer(HostedZoneId=None, RecordName=None, RecordType=None,
    ResolverIP=None, EDNS0ClientSubnetIP=None, EDNS0ClientSubnetMask=None):
    """
    Gets the value that Amazon Route 53 returns in response to a DNS request for a specified record name and type. You can optionally specify the IP address of a DNS resolver, an EDNS0 client subnet IP address, and a subnet mask.
    See also: AWS API Documentation

    :example: response = client.test_dns_answer(
        HostedZoneId='string',
        RecordName='string',
        RecordType='SOA'|'A'|'TXT'|'NS'|'CNAME'|'MX'|'NAPTR'|'PTR'|'SRV'|'SPF'|'AAAA',
        ResolverIP='string',
        EDNS0ClientSubnetIP='string',
        EDNS0ClientSubnetMask='string'
    )

    :type HostedZoneId: string
    :param HostedZoneId: [REQUIRED]
            The ID of the hosted zone that you want Amazon Route 53 to simulate a query for.

    :type RecordName: string
    :param RecordName: [REQUIRED]
            The name of the resource record set that you want Amazon Route 53 to simulate a query for.

    :type RecordType: string
    :param RecordType: [REQUIRED]
            The type of the resource record set.

    :type ResolverIP: string
    :param ResolverIP: If you want to simulate a request from a specific DNS resolver, specify the IP address for that resolver. If you omit this value, TestDnsAnswer uses the IP address of a DNS resolver in the AWS US East (N. Virginia) Region (us-east-1 ).

    :type EDNS0ClientSubnetIP: string
    :param EDNS0ClientSubnetIP: If the resolver that you specified for resolverip supports EDNS0, specify the IPv4 or IPv6 address of a client in the applicable location, for example, 192.0.2.44 or 2001:db8:85a3::8a2e:370:7334 .

    :type EDNS0ClientSubnetMask: string
    :param EDNS0ClientSubnetMask: If you specify an IP address for edns0clientsubnetip , you can optionally specify the number of bits of the IP address that you want the checking tool to include in the DNS query. For example, if you specify 192.0.2.44 for edns0clientsubnetip and 24 for edns0clientsubnetmask , the checking tool will simulate a request from 192.0.2.0/24. The default value is 24 bits for IPv4 addresses and 64 bits for IPv6 addresses.

    :rtype: dict
    :return: {
        'Nameserver': 'string',
        'RecordName': 'string',
        'RecordType': 'SOA'|'A'|'TXT'|'NS'|'CNAME'|'MX'|'NAPTR'|'PTR'|'SRV'|'SPF'|'AAAA',
        'RecordData': [
            'string',
        ],
        'ResponseCode': 'string',
        'Protocol': 'string'
    }

    :returns:
    For non-alias resource record sets, a RecordDataEntry element contains one value in the resource record set. If the resource record set contains multiple values, the response includes one RecordDataEntry element for each value.
    For multiple resource record sets that have the same name and type, which includes weighted, latency, geolocation, and failover, a RecordDataEntry element contains the value from the appropriate resource record set based on the request.
    For alias resource record sets that refer to AWS resources other than another resource record set, the RecordDataEntry element contains an IP address or a domain name for the AWS resource, depending on the type of resource.
    For alias resource record sets that refer to other resource record sets, a RecordDataEntry element contains one value from the referenced resource record set. If the referenced resource record set contains multiple values, the response includes one RecordDataEntry element for each value.

    """
    pass


@classmethod
def name(cls):
    """
        Should be used as standard Interface for class name.
        """
    return cls.__name__.replace('Element', '')


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


def check_altsw(altcheck=False):
    """
    Ask for and return alternate software release, if needed.

    :param altcheck: If we're using an alternate software release.
    :type altcheck: bool
    """
    if altcheck:
        altsw = input('RADIO SOFTWARE RELEASE (PRESS ENTER TO GUESS): ')
        if not altsw:
            altsw = 'checkme'
    else:
        altsw = None
    return altsw


def tio_is_attribute(tree_item):
    """
    Returns 'True' if the tree item object is an attribute of the parent
    opposed to e.g. a list element.
    """
    if tree_item.is_attribute is None:
        return ''
    else:
        return str(tree_item.is_attribute)


def the_same_repository(repo_1_info, repo_2_info, check_revision=True):
    """
    Given two dicts containing info about repositories, determine if they are the same
    repository.
    Each of the dicts must have the following keys: `changeset_revisions`( if check revisions is true), `name`, `owner`, and
    (either `tool_shed` or `tool_shed_url`).
    """
    if not check_revision or repo_1_info.get('changeset_revision'
        ) == repo_2_info.get('changeset_revision'):
        if repo_1_info.get('name') == repo_2_info.get('name'):
            if repo_1_info.get('owner') == repo_2_info.get('owner'):
                t1ts = repo_1_info.get('tool_shed', repo_1_info.get(
                    'tool_shed_url', None))
                t2ts = repo_2_info.get('tool_shed', repo_2_info.get(
                    'tool_shed_url', None))
                if t1ts in t2ts or t2ts in t1ts:
                    return True
    return False


def sinh(data=None, name=None, attr=None, out=None, **kwargs):
    """Returns the hyperbolic sine of the input array, computed element-wise.

    .. math::
       sinh(x) = 0.5\\times(exp(x) - exp(-x))

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

       - sinh(default) = default
       - sinh(row_sparse) = row_sparse
       - sinh(csr) = csr

    Defined in src/operator/tensor/elemwise_unary_op_trig.cc:L313

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

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

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


def t_KEY_ID(t):
    """(key|KEY)_(1[0-5]|[0-9])"""
    t.value = int(t.value.split('_')[1])
    return t


def PolsSickHosp(t):
    """Number of policies: Sickness Hospitalization"""
    return 0


def average_word_length(text):
    """
    :type text: Text
    :param text: The text to be analysed
    :rtype float
    :returns Average number of chars per word
    """
    return len(text.text) / len(text.tokens)


def formatErrorMsg(funcname, exc):
    """Formatter for error messages.

    Args:
        funcname: str the function name where the error occurred
        exc: Exception

    Returns:
        str:
    """
    ename = type(exc).__name__
    return f'Error in {funcname}: {ename}: {exc}\n'


def dict_from_string(dispstr):
    """
    Converts a string which contains a Content-Disposition
    header's contents into a dict.
    :param dispstr: String with Content-Disposition value
    :return: Dictionary of Content-Disposition values.
    """
    disp_parts = dispstr.split(';')
    disp_dict = {}
    for d_part in disp_parts:
        if len(d_part.split('=', 1)) > 1:
            disp_param_cleaned = list(map(str.strip, d_part.split('=', 1)))
            disp_dict[disp_param_cleaned[0]] = disp_param_cleaned[1]
        else:
            disp_dict[d_part.strip().lower()] = None
    return disp_dict


def MotorAmpP2P(RPM=1200, CF=None, W=139, Wu=20, e=4):
    """Calculates the motor amplitude Peak to Peak
    RPM = Rotations Per Minute
    CF = Centifugal Force (lbs)
    k= spring constant (lbs/in)
    W = weight on springs (lbs)
    Wu=unbalanced weigth (lbs)
    e=eccentric distance from ctr mass to ctr rotation (inches)

    example:
    MotorAmpP2P(RPM=1200,CF=1621,W=139)#out=0.570
    MotorAmpP2P(W=139,Wu=19.8125,e=4)#out=.570

    Derivation using Centrifugal Force
    this comes from standard spring-mass damper formula
    X=(F0/k)*(1/sqrt((1-r**2)**2+(2*gamma*r)*2))
    r=radial freq / natural freq
    F0=centrifugal force, k=spring const,gamma=damping ratio
    assuming negligible damping, gamma=0, X simplifies to
    X=(F0/k)*(1/abs(1-W*(pi*RPM)**2/(g*k*900)))
    for high RPM, the W*(pi*RPM)**2/(g*k*900) term is much larger than 1.
    therefore we can simplify further:
    X=(F0*g*900)/(W*(RPM*pi)**2)

    Derivation using eccentrics/weight plates
    start with equation where gamma=0 (no damping)
    X=(F0/k)*(1/abs(1-W*(pi*RPM)**2/(g*k*900)))
    F0=Wu*e*(pi*RPM)**2/(g*900)
    combining and simplifying we get:
    X=Wu*e/W

    """
    from math import pi
    if not CF:
        P2P = Wu * e / W
        return P2P
    P2P = 2 * CF * 900 * 386.04 / (W * (pi * RPM) ** 2)
    return P2P


def editmode_toggle():
    """Enter/Exit edit mode for Grease Pencil strokes

    """
    pass


def key_of(msg, group_by, depth):
    """ get the msg's attribute to be used as key for grouping """
    if group_by == 'path':
        key = msg.path if depth == 0 else msg.parent_path(depth)
    elif group_by == 'type':
        key = msg.name
    elif group_by == 'client':
        key = msg.client
    else:
        raise ValueError('Unknown group: %s' % group_by)
    return key


@staticmethod
def check_unknow_params(params: dict, payload: dict):
    """
			Vérifie que les paramètres soient présents dans la définition.
			Lance une erreur spécifique le cas contraire.
		"""
    for par in payload:
        if par not in params:
            raise ValueError('Unknow parameter : ' + par)


def __iter__():
    """Return an iterator for the keys of the mapping object.
        """


def cdriver2filetype(driver):
    """Convert a connection driver to a file type.

    Args:
        driver (str): The name of the connection driver.

    Returns:
        str: The corresponding file type for the driver.

    """
    _legacy = {'FileInputDriver': 'binary', 'FileOutputDriver': 'binary',
        'AsciiMapInputDriver': 'map', 'AsciiMapOutputDriver': 'map',
        'AsciiFileInputDriver': 'ascii', 'AsciiFileOutputDriver': 'ascii',
        'AsciiTableInputDriver': 'table', 'AsciiTableOutputDriver': 'table',
        'PandasFileInputDriver': 'pandas', 'PandasFileOutputDriver':
        'pandas', 'PickleFileInputDriver': 'pickle',
        'PickleFileOutputDriver': 'pickle', 'PlyFileInputDriver': 'ply',
        'PlyFileOutputDriver': 'ply', 'ObjFileInputDriver': 'obj',
        'ObjFileOutputDriver': 'obj', 'MatInputDriver': 'mat',
        'MatOutputDriver': 'mat'}
    if driver in _legacy:
        return _legacy[driver]
    raise ValueError('%s is not a registered connection driver.' % driver)


def get_eventid(event):
    """Event id from event"""
    return str(event.resource_id).split('/')[-1]


def _missingExtraCheck(given, required, extraException, missingException):
    """
    If the L{sets<set>} C{required} and C{given} do not contain the same
    elements raise an exception describing how they are different.

    @param given: The L{set} of elements that was actually given.
    @param required: The L{set} of elements that must be given.

    @param extraException: An exception to raise if there are elements in
        C{given} that are not in C{required}.
    @param missingException: An exception to raise if there are elements in
        C{required} that are not in C{given}.

    @return: C{None}
    """
    extra = given - required
    if extra:
        raise extraException(extra)
    missing = required - given
    if missing:
        raise missingException(missing)


def parse_args():
    """Parse input arguments."""
    import argparse
    parser = argparse.ArgumentParser(description='Get a shape mesh (t-pose)')
    parser.add_argument('--model_dir', type=str, help='model dir', required
        =True)
    parser.add_argument('--batch_size', type=int, help='batch size',
        required=30)
    parser.add_argument('--input', type=str, help='Input dir of images',
        required=True)
    parser.add_argument('--output', type=str, help='Output dir of clusters',
        required=True)
    args = parser.parse_args()
    return args


def weighted_median(y, w):
    """
    Compute weighted median of `y` with weights `w`.
    """
    items = sorted(zip(y, w))
    midpoint = sum(w) / 2
    yvals = []
    wsum = 0
    for yy, ww in items:
        wsum += ww
        if wsum > midpoint:
            yvals.append(yy)
            break
        elif wsum == midpoint:
            yvals.append(yy)
    else:
        yvals = y
    return sum(yvals) / len(yvals)


@staticmethod
def set_fold_trigger(block, val):
    """
        Set the block fold trigger flag (True means the block is a fold
        trigger).

        :param block: block to set
        :param val: value to set
        """
    if block is None:
        return
    state = block.userState()
    if state == -1:
        state = 0
    state &= 2080374783
    state |= int(val) << 26
    block.setUserState(state)


def has(cls):
    """
    Check whether *cls* is a class with ``attrs`` attributes.

    :param type cls: Class to introspect.
    :raise TypeError: If *cls* is not a class.

    :rtype: bool
    """
    return getattr(cls, '__attrs_attrs__', None) is not None


def one(resolve=True):
    """ Return the element in the resultset, asserting that there is only
        one result.  If the resultset has more than one element, raise an
        :exc:`hypatia.exc.MultipleResults` exception.  If the resultset has no
        elements, raise an :exc:`hypatia.exc.NoResults` exception. `If
        ``resolve`` is True, and the result set has a valid resolver, return
        the resolved document, otherwise return the document id of the
        document."""


def get_fontext_synonyms(fontext):
    """
    Return a list of file extensions extensions that are synonyms for
    the given file extension *fileext*.
    """
    return {'afm': ['afm'], 'otf': ['otf', 'ttc', 'ttf'], 'ttc': ['otf',
        'ttc', 'ttf'], 'ttf': ['otf', 'ttc', 'ttf']}[fontext]


@staticmethod
def _migration_file_name(migration_version):
    """Create migration file name based on migration version."""
    return str(migration_version) + '.json'


def _get_object_for_value(results, value):
    """Get vm reference value from vm object."""
    for object in results:
        if object.propSet[0].val == value:
            return object.obj


def __getattr__(cls, item):
    """Special warning for attribute errors.

        Its likely that user may have wanted to use a model interface
        instead of the Base class.
        """
    raise AttributeError("'{}' has no attribute '{}'".format(cls.__name__,
        item))


def check_bucket_valid(bucket):
    """
    Check bucket name whether is legal.

    :type bucket: string
    :param bucket: None
    =======================
    :return:
        **Boolean**
    """
    alphabet = 'abcdefghijklmnopqrstuvwxyz0123456789-'
    if len(bucket) < 3 or len(bucket) > 63:
        return False
    if bucket[-1] == '-' or bucket[-1] == '_':
        return False
    if not ('a' <= bucket[0] <= 'z' or '0' <= bucket[0] <= '9'):
        return False
    for i in bucket:
        if not i in alphabet:
            return False
    return True


def strip_blank_lines(l):
    """Remove leading and trailing blank lines from a list of lines"""
    while l and not l[0].strip():
        del l[0]
    while l and not l[-1].strip():
        del l[-1]
    return l


def _parse_memory(s):
    """
    Parse a memory string in the format supported by Java (e.g. 1g, 200m) and
    return the value in MB

    >>> _parse_memory("256m")
    256
    >>> _parse_memory("2g")
    2048
    """
    units = {'g': 1024, 'm': 1, 't': 1 << 20, 'k': 1.0 / 1024}
    if s[-1].lower() not in units:
        raise ValueError('invalid format: ' + s)
    return int(float(s[:-1]) * units[s[-1].lower()])


def dsmr_transform(value):
    """Transform DSMR version value to right format."""
    if value.isdigit():
        return float(value) / 10
    return value


def _split_members(members):
    """Splits the members list into 3 sublists:
        -One containing functions (or other callable objects).
        -One containing properties which have a setter
        -The last containing properties which don´t have a setter
    Anything not falling in one of those categories gets discarded."""
    callables, settable_properties, not_settable_properties = [], [], []
    for element in members:
        element_value = element[1]
        if callable(element_value):
            callables.append(element)
        elif isinstance(element_value, property):
            if element_value.fset is None:
                not_settable_properties.append(element)
            else:
                settable_properties.append(element)
    return callables, settable_properties, not_settable_properties


@classmethod
def dump_forest(cls, root_node, token_dicts=None):
    """ Return a string with a multi-line text representation of the parse tree """
    dumper = cls(token_dicts)
    dumper.go(root_node)
    dumper._result.append('Q0')
    return '\n'.join(dumper._result)


def is_power_2(value):
    """
    Check if passed value is a power of 2
    """
    return value != 0 and value & value - 1 == 0


def file_extensions_valid(ext_list):
    """Checks if file list contains only valid files

    Notes:
        Assumes all file extensions are equal! Only checks first file

    Args:
        ext_list (list): file extensions, eg ['.csv','.csv']

    Returns:
        bool: first element in list is one of ['.csv','.txt','.xls','.xlsx']?
    """
    ext_list_valid = ['.csv', '.txt', '.xls', '.xlsx']
    return ext_list[0] in ext_list_valid


def write_rep_radius(rep_radius, genomes, out_file):
    """Write out ANI radius for each representative genomes."""
    fout = open(out_file, 'w')
    fout.write(
        """Representative	GTDB species	NCBI species	ANI	AF	Closest species	Closest representative
"""
        )
    for gid in rep_radius:
        ani, af, neighbour_gid = rep_radius[gid]
        if not af:
            af = 0
        if not neighbour_gid or neighbour_gid == 'N/A':
            neighbour_gid = 'N/A'
            neighbour_sp = 'N/A'
        else:
            neighbour_sp = genomes[neighbour_gid].gtdb_taxa.species
        fout.write('%s\t%s\t%s\t%.2f\t%.2f\t%s\t%s\n' % (gid, genomes[gid].
            gtdb_taxa.species, genomes[gid].ncbi_taxa.species, ani, af,
            neighbour_sp, neighbour_gid))
    fout.close()


def get_shared_prefix(word1: str, word2: str) ->str:
    """
    Get the substring in the beginning of word1 and word2 which both share.

    Parameters
    ----------
    word1 : str
    word2 : str

    Returns
    -------
    shared_prefix : str

    Examples
    --------
    >>> get_shared_prefix("foo", "bar")
    ''
    >>> get_shared_prefix("foobar", "bar")
    ''
    >>> get_shared_prefix("foobar", "foo")
    'foo'
    >>> get_shared_prefix("steamship", "steampowered")
    'steam'
    """
    shared_prefix = ''
    for char1, char2 in zip(word1, word2):
        if char1 == char2:
            shared_prefix += char1
        else:
            break
    return shared_prefix


def scale(val, src, dst):
    """
    Scale the given value from the scale of src to the scale of dst.
    """
    return int((val - src[0]) / float(src[1] - src[0]) * (dst[1] - dst[0]) +
        dst[0])


def is_classifier(estimator):
    """Returns True if the given estimator is (probably) a classifier.

    Parameters
    ----------
    estimator : object
        Estimator object to test.

    Returns
    -------
    out : bool
        True if estimator is a classifier and False otherwise.
    """
    return getattr(estimator, '_estimator_type', None) == 'classifier'


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 '+'


@staticmethod
def storageFormat(data):
    """ convert data from format returned by get, to raw database format """
    if isinstance(data, str):
        data.replace(', ', ',')
        return data.split(',')
    return data


def isfinite(f):
    """Check if f is finite"""
    return float('-inf') < float(f) < float('inf')


def dir_dict(obj, raise_exc=False):
    """Return a dictionary of attribute names to values for a given
    object. Unlike ``obj.__dict__``, this function returns all
    attributes on the object, including ones on parent classes.
    """
    ret = {}
    for k in dir(obj):
        try:
            ret[k] = getattr(obj, k)
        except Exception:
            if raise_exc:
                raise
    return ret


def delete_campaign(ApplicationId=None, CampaignId=None):
    """
    Deletes a campaign.

    :example: response = client.delete_campaign(
        ApplicationId='string',
        CampaignId='string'
    )

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

    :type CampaignId: string
    :param CampaignId: [REQUIRED]

    :rtype: dict
    :return: {
        'CampaignResponse': {
            'AdditionalTreatments': [
                {
                    'Id': 'string',
                    'MessageConfiguration': {
                        'APNSMessage': {
                            'Action': 'OPEN_APP'|'DEEP_LINK'|'URL',
                            'Body': 'string',
                            'ImageIconUrl': 'string',
                            'ImageUrl': 'string',
                            'JsonBody': 'string',
                            'MediaUrl': 'string',
                            'SilentPush': True|False,
                            'Title': 'string',
                            'Url': 'string'
                        },
                        'DefaultMessage': {
                            'Action': 'OPEN_APP'|'DEEP_LINK'|'URL',
                            'Body': 'string',
                            'ImageIconUrl': 'string',
                            'ImageUrl': 'string',
                            'JsonBody': 'string',
                            'MediaUrl': 'string',
                            'SilentPush': True|False,
                            'Title': 'string',
                            'Url': 'string'
                        },
                        'GCMMessage': {
                            'Action': 'OPEN_APP'|'DEEP_LINK'|'URL',
                            'Body': 'string',
                            'ImageIconUrl': 'string',
                            'ImageUrl': 'string',
                            'JsonBody': 'string',
                            'MediaUrl': 'string',
                            'SilentPush': True|False,
                            'Title': 'string',
                            'Url': 'string'
                        }
                    },
                    'Schedule': {
                        'EndTime': 'string',
                        'Frequency': 'ONCE'|'HOURLY'|'DAILY'|'WEEKLY'|'MONTHLY',
                        'IsLocalTime': True|False,
                        'QuietTime': {
                            'End': 'string',
                            'Start': 'string'
                        },
                        'StartTime': 'string',
                        'Timezone': 'string'
                    },
                    'SizePercent': 123,
                    'State': {
                        'CampaignStatus': 'SCHEDULED'|'EXECUTING'|'PENDING_NEXT_RUN'|'COMPLETED'|'PAUSED'
                    },
                    'TreatmentDescription': 'string',
                    'TreatmentName': 'string'
                },
            ],
            'ApplicationId': 'string',
            'CreationDate': 'string',
            'DefaultState': {
                'CampaignStatus': 'SCHEDULED'|'EXECUTING'|'PENDING_NEXT_RUN'|'COMPLETED'|'PAUSED'
            },
            'Description': 'string',
            'HoldoutPercent': 123,
            'Id': 'string',
            'IsPaused': True|False,
            'LastModifiedDate': 'string',
            'Limits': {
                'Daily': 123,
                'Total': 123
            },
            'MessageConfiguration': {
                'APNSMessage': {
                    'Action': 'OPEN_APP'|'DEEP_LINK'|'URL',
                    'Body': 'string',
                    'ImageIconUrl': 'string',
                    'ImageUrl': 'string',
                    'JsonBody': 'string',
                    'MediaUrl': 'string',
                    'SilentPush': True|False,
                    'Title': 'string',
                    'Url': 'string'
                },
                'DefaultMessage': {
                    'Action': 'OPEN_APP'|'DEEP_LINK'|'URL',
                    'Body': 'string',
                    'ImageIconUrl': 'string',
                    'ImageUrl': 'string',
                    'JsonBody': 'string',
                    'MediaUrl': 'string',
                    'SilentPush': True|False,
                    'Title': 'string',
                    'Url': 'string'
                },
                'GCMMessage': {
                    'Action': 'OPEN_APP'|'DEEP_LINK'|'URL',
                    'Body': 'string',
                    'ImageIconUrl': 'string',
                    'ImageUrl': 'string',
                    'JsonBody': 'string',
                    'MediaUrl': 'string',
                    'SilentPush': True|False,
                    'Title': 'string',
                    'Url': 'string'
                }
            },
            'Name': 'string',
            'Schedule': {
                'EndTime': 'string',
                'Frequency': 'ONCE'|'HOURLY'|'DAILY'|'WEEKLY'|'MONTHLY',
                'IsLocalTime': True|False,
                'QuietTime': {
                    'End': 'string',
                    'Start': 'string'
                },
                'StartTime': 'string',
                'Timezone': 'string'
            },
            'SegmentId': 'string',
            'SegmentVersion': 123,
            'State': {
                'CampaignStatus': 'SCHEDULED'|'EXECUTING'|'PENDING_NEXT_RUN'|'COMPLETED'|'PAUSED'
            },
            'TreatmentDescription': 'string',
            'TreatmentName': 'string',
            'Version': 123
        }
    }

    :returns:
    (dict) -- 200 response
    CampaignResponse (dict) -- Campaign definition
    AdditionalTreatments (list) -- Treatments that are defined in addition to the default treatment.
    (dict) -- Treatment resource
    Id (string) -- The unique treatment ID.
    MessageConfiguration (dict) -- The message configuration settings.
    APNSMessage (dict) -- The message that the campaign delivers to APNS channels. Overrides the default message.
    Action (string) -- The action that occurs if the user taps a push notification delivered by the campaign: OPEN_APP  Your app launches, or it becomes the foreground app if it has been sent to the background. This is the default action. DEEP_LINK  Uses deep linking features in iOS and Android to open your app and display a designated user interface within the app. URL  The default mobile browser on the user's device launches and opens a web page at the URL you specify.
    Body (string) -- The message body. Can include up to 140 characters.
    ImageIconUrl (string) -- The URL that points to the icon image for the push notification icon, for example, the app icon.
    ImageUrl (string) -- The URL that points to an image used in the push notification.
    JsonBody (string) -- The JSON payload used for a silent push.
    MediaUrl (string) -- The URL that points to the media resource, for example a .mp4 or .gif file.
    SilentPush (boolean) -- Indicates if the message should display on the users device. Silent pushes can be used for Remote Configuration and Phone Home use cases.
    Title (string) -- The message title that displays above the message on the user's device.
    Url (string) -- The URL to open in the user's mobile browser. Used if the value for Action is URL.

    DefaultMessage (dict) -- The default message for all channels.
    Action (string) -- The action that occurs if the user taps a push notification delivered by the campaign: OPEN_APP  Your app launches, or it becomes the foreground app if it has been sent to the background. This is the default action. DEEP_LINK  Uses deep linking features in iOS and Android to open your app and display a designated user interface within the app. URL  The default mobile browser on the user's device launches and opens a web page at the URL you specify.
    Body (string) -- The message body. Can include up to 140 characters.
    ImageIconUrl (string) -- The URL that points to the icon image for the push notification icon, for example, the app icon.
    ImageUrl (string) -- The URL that points to an image used in the push notification.
    JsonBody (string) -- The JSON payload used for a silent push.
    MediaUrl (string) -- The URL that points to the media resource, for example a .mp4 or .gif file.
    SilentPush (boolean) -- Indicates if the message should display on the users device. Silent pushes can be used for Remote Configuration and Phone Home use cases.
    Title (string) -- The message title that displays above the message on the user's device.
    Url (string) -- The URL to open in the user's mobile browser. Used if the value for Action is URL.

    GCMMessage (dict) -- The message that the campaign delivers to GCM channels. Overrides the default message.
    Action (string) -- The action that occurs if the user taps a push notification delivered by the campaign: OPEN_APP  Your app launches, or it becomes the foreground app if it has been sent to the background. This is the default action. DEEP_LINK  Uses deep linking features in iOS and Android to open your app and display a designated user interface within the app. URL  The default mobile browser on the user's device launches and opens a web page at the URL you specify.
    Body (string) -- The message body. Can include up to 140 characters.
    ImageIconUrl (string) -- The URL that points to the icon image for the push notification icon, for example, the app icon.
    ImageUrl (string) -- The URL that points to an image used in the push notification.
    JsonBody (string) -- The JSON payload used for a silent push.
    MediaUrl (string) -- The URL that points to the media resource, for example a .mp4 or .gif file.
    SilentPush (boolean) -- Indicates if the message should display on the users device. Silent pushes can be used for Remote Configuration and Phone Home use cases.
    Title (string) -- The message title that displays above the message on the user's device.
    Url (string) -- The URL to open in the user's mobile browser. Used if the value for Action is URL.

    Schedule (dict) -- The campaign schedule.
    EndTime (string) -- The scheduled time that the campaign ends in ISO 8601 format.
    Frequency (string) -- How often the campaign delivers messages. Valid values: ONCE, HOURLY, DAILY, WEEKLY, MONTHLY
    IsLocalTime (boolean) -- Indicates whether the campaign schedule takes effect according to each user's local time.
    QuietTime (dict) -- The time during which the campaign sends no messages.
    End (string) -- The default end time for quiet time in ISO 8601 format.
    Start (string) -- The default start time for quiet time in ISO 8601 format.

    StartTime (string) -- The scheduled time that the campaign begins in ISO 8601 format.
    Timezone (string) -- The starting UTC offset for the schedule if the value for isLocalTime is true Valid values: UTC UTC+01 UTC+02 UTC+03 UTC+03:30 UTC+04 UTC+04:30 UTC+05 UTC+05:30 UTC+05:45 UTC+06 UTC+06:30 UTC+07 UTC+08 UTC+09 UTC+09:30 UTC+10 UTC+10:30 UTC+11 UTC+12 UTC+13 UTC-02 UTC-03 UTC-04 UTC-05 UTC-06 UTC-07 UTC-08 UTC-09 UTC-10 UTC-11

    SizePercent (integer) -- The allocated percentage of users for this treatment.
    State (dict) -- The treatment status.
    CampaignStatus (string) -- The status of the campaign, or the status of a treatment that belongs to an A/B test campaign. Valid values: SCHEDULED, EXECUTING, PENDING_NEXT_RUN, COMPLETED, PAUSED

    TreatmentDescription (string) -- A custom description for the treatment.
    TreatmentName (string) -- The custom name of a variation of the campaign used for A/B testing.

    ApplicationId (string) -- The ID of the application to which the campaign applies.
    CreationDate (string) -- The date the campaign was created in ISO 8601 format.
    DefaultState (dict) -- The status of the campaign's default treatment. Only present for A/B test campaigns.
    CampaignStatus (string) -- The status of the campaign, or the status of a treatment that belongs to an A/B test campaign. Valid values: SCHEDULED, EXECUTING, PENDING_NEXT_RUN, COMPLETED, PAUSED

    Description (string) -- A description of the campaign.
    HoldoutPercent (integer) -- The allocated percentage of end users who will not receive messages from this campaign.
    Id (string) -- The unique campaign ID.
    IsPaused (boolean) -- Indicates whether the campaign is paused. A paused campaign does not send messages unless you resume it by setting IsPaused to false.
    LastModifiedDate (string) -- The date the campaign was last updated in ISO 8601 format.
    Limits (dict) -- The campaign limits settings.
    Daily (integer) -- The maximum number of messages that the campaign can send daily.
    Total (integer) -- The maximum total number of messages that the campaign can send.

    MessageConfiguration (dict) -- The message configuration settings.
    APNSMessage (dict) -- The message that the campaign delivers to APNS channels. Overrides the default message.
    Action (string) -- The action that occurs if the user taps a push notification delivered by the campaign: OPEN_APP  Your app launches, or it becomes the foreground app if it has been sent to the background. This is the default action. DEEP_LINK  Uses deep linking features in iOS and Android to open your app and display a designated user interface within the app. URL  The default mobile browser on the user's device launches and opens a web page at the URL you specify.
    Body (string) -- The message body. Can include up to 140 characters.
    ImageIconUrl (string) -- The URL that points to the icon image for the push notification icon, for example, the app icon.
    ImageUrl (string) -- The URL that points to an image used in the push notification.
    JsonBody (string) -- The JSON payload used for a silent push.
    MediaUrl (string) -- The URL that points to the media resource, for example a .mp4 or .gif file.
    SilentPush (boolean) -- Indicates if the message should display on the users device. Silent pushes can be used for Remote Configuration and Phone Home use cases.
    Title (string) -- The message title that displays above the message on the user's device.
    Url (string) -- The URL to open in the user's mobile browser. Used if the value for Action is URL.

    DefaultMessage (dict) -- The default message for all channels.
    Action (string) -- The action that occurs if the user taps a push notification delivered by the campaign: OPEN_APP  Your app launches, or it becomes the foreground app if it has been sent to the background. This is the default action. DEEP_LINK  Uses deep linking features in iOS and Android to open your app and display a designated user interface within the app. URL  The default mobile browser on the user's device launches and opens a web page at the URL you specify.
    Body (string) -- The message body. Can include up to 140 characters.
    ImageIconUrl (string) -- The URL that points to the icon image for the push notification icon, for example, the app icon.
    ImageUrl (string) -- The URL that points to an image used in the push notification.
    JsonBody (string) -- The JSON payload used for a silent push.
    MediaUrl (string) -- The URL that points to the media resource, for example a .mp4 or .gif file.
    SilentPush (boolean) -- Indicates if the message should display on the users device. Silent pushes can be used for Remote Configuration and Phone Home use cases.
    Title (string) -- The message title that displays above the message on the user's device.
    Url (string) -- The URL to open in the user's mobile browser. Used if the value for Action is URL.

    GCMMessage (dict) -- The message that the campaign delivers to GCM channels. Overrides the default message.
    Action (string) -- The action that occurs if the user taps a push notification delivered by the campaign: OPEN_APP  Your app launches, or it becomes the foreground app if it has been sent to the background. This is the default action. DEEP_LINK  Uses deep linking features in iOS and Android to open your app and display a designated user interface within the app. URL  The default mobile browser on the user's device launches and opens a web page at the URL you specify.
    Body (string) -- The message body. Can include up to 140 characters.
    ImageIconUrl (string) -- The URL that points to the icon image for the push notification icon, for example, the app icon.
    ImageUrl (string) -- The URL that points to an image used in the push notification.
    JsonBody (string) -- The JSON payload used for a silent push.
    MediaUrl (string) -- The URL that points to the media resource, for example a .mp4 or .gif file.
    SilentPush (boolean) -- Indicates if the message should display on the users device. Silent pushes can be used for Remote Configuration and Phone Home use cases.
    Title (string) -- The message title that displays above the message on the user's device.
    Url (string) -- The URL to open in the user's mobile browser. Used if the value for Action is URL.

    Name (string) -- The custom name of the campaign.
    Schedule (dict) -- The campaign schedule.
    EndTime (string) -- The scheduled time that the campaign ends in ISO 8601 format.
    Frequency (string) -- How often the campaign delivers messages. Valid values: ONCE, HOURLY, DAILY, WEEKLY, MONTHLY
    IsLocalTime (boolean) -- Indicates whether the campaign schedule takes effect according to each user's local time.
    QuietTime (dict) -- The time during which the campaign sends no messages.
    End (string) -- The default end time for quiet time in ISO 8601 format.
    Start (string) -- The default start time for quiet time in ISO 8601 format.

    StartTime (string) -- The scheduled time that the campaign begins in ISO 8601 format.
    Timezone (string) -- The starting UTC offset for the schedule if the value for isLocalTime is true Valid values: UTC UTC+01 UTC+02 UTC+03 UTC+03:30 UTC+04 UTC+04:30 UTC+05 UTC+05:30 UTC+05:45 UTC+06 UTC+06:30 UTC+07 UTC+08 UTC+09 UTC+09:30 UTC+10 UTC+10:30 UTC+11 UTC+12 UTC+13 UTC-02 UTC-03 UTC-04 UTC-05 UTC-06 UTC-07 UTC-08 UTC-09 UTC-10 UTC-11

    SegmentId (string) -- The ID of the segment to which the campaign sends messages.
    SegmentVersion (integer) -- The version of the segment to which the campaign sends messages.
    State (dict) -- The campaign status. An A/B test campaign will have a status of COMPLETED only when all treatments have a status of COMPLETED.
    CampaignStatus (string) -- The status of the campaign, or the status of a treatment that belongs to an A/B test campaign. Valid values: SCHEDULED, EXECUTING, PENDING_NEXT_RUN, COMPLETED, PAUSED

    TreatmentDescription (string) -- A custom description for the treatment.
    TreatmentName (string) -- The custom name of a variation of the campaign used for A/B testing.
    Version (integer) -- The campaign version number.

    """
    pass


def _wider_test_jpeg(data):
    """Test for a jpeg file following the UNIX file implementation which
    uses the magic bytes rather than just looking for the bytes that
    represent 'JFIF' or 'EXIF' at a fixed position.
    """
    if data[:2] == b'\xff\xd8':
        return 'jpeg'


def subscribe(TopicArn=None, Protocol=None, Endpoint=None):
    """
    Prepares to subscribe an endpoint by sending the endpoint a confirmation message. To actually create a subscription, the endpoint owner must call the ConfirmSubscription action with the token from the confirmation message. Confirmation tokens are valid for three days.
    See also: AWS API Documentation

    :example: response = client.subscribe(
        TopicArn='string',
        Protocol='string',
        Endpoint='string'
    )

    :type TopicArn: string
    :param TopicArn: [REQUIRED]
            The ARN of the topic you want to subscribe to.

    :type Protocol: string
    :param Protocol: [REQUIRED]
            The protocol you want to use. Supported protocols include:
            http -- delivery of JSON-encoded message via HTTP POST
            https -- delivery of JSON-encoded message via HTTPS POST
            email -- delivery of message via SMTP
            email-json -- delivery of JSON-encoded message via SMTP
            sms -- delivery of message via SMS
            sqs -- delivery of JSON-encoded message to an Amazon SQS queue
            application -- delivery of JSON-encoded message to an EndpointArn for a mobile app and device.
            lambda -- delivery of JSON-encoded message to an AWS Lambda function.

    :type Endpoint: string
    :param Endpoint: The endpoint that you want to receive notifications. Endpoints vary by protocol:
            For the http protocol, the endpoint is an URL beginning with 'http://'
            For the https protocol, the endpoint is a URL beginning with 'https://'
            For the email protocol, the endpoint is an email address
            For the email-json protocol, the endpoint is an email address
            For the sms protocol, the endpoint is a phone number of an SMS-enabled device
            For the sqs protocol, the endpoint is the ARN of an Amazon SQS queue
            For the application protocol, the endpoint is the EndpointArn of a mobile app and device.
            For the lambda protocol, the endpoint is the ARN of an AWS Lambda function.

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

    """
    pass


def delta_t(soil_type):
    """ Displacement at Tu
    """
    delta_ts = {'dense sand': 0.003, 'loose sand': 0.005, 'stiff clay':
        0.008, 'soft clay': 0.01}
    return delta_ts.get(soil_type, ValueError('Unknown soil type.'))


def get_wsgi_string(string, encoding='utf-8'):
    """
    Returns wsgi-compatible string
    """
    return string.encode(encoding).decode('iso-8859-1')


def generic_find_fk_constraint_names(table, columns, referenced, insp):
    """Utility to find foreign-key constraint names in alembic migrations"""
    names = set()
    for fk in insp.get_foreign_keys(table):
        if fk['referred_table'] == referenced and set(fk['referred_columns']
            ) == columns:
            names.add(fk['name'])
    return names


def dbh_sdt_viewer(path, contenttype, extension, roottag, nsurl):
    """ Responds To SDT Files """
    if extension == 'sdt':
        return 'db_sdt_viewer'
    else:
        return False


def provision_product(AcceptLanguage=None, ProductId=None,
    ProvisioningArtifactId=None, PathId=None, ProvisionedProductName=None,
    ProvisioningParameters=None, Tags=None, NotificationArns=None,
    ProvisionToken=None):
    """
    Requests a Provision of a specified product. A ProvisionedProduct is a resourced instance for a product. For example, provisioning a CloudFormation-template-backed product results in launching a CloudFormation stack and all the underlying resources that come with it.
    You can check the status of this request using the  DescribeRecord operation.
    See also: AWS API Documentation

    :example: response = client.provision_product(
        AcceptLanguage='string',
        ProductId='string',
        ProvisioningArtifactId='string',
        PathId='string',
        ProvisionedProductName='string',
        ProvisioningParameters=[
            {
                'Key': 'string',
                'Value': 'string'
            },
        ],
        Tags=[
            {
                'Key': 'string',
                'Value': 'string'
            },
        ],
        NotificationArns=[
            'string',
        ],
        ProvisionToken='string'
    )

    :type AcceptLanguage: string
    :param AcceptLanguage: The language code to use for this operation. Supported language codes are as follows:
            'en' (English)
            'jp' (Japanese)
            'zh' (Chinese)
            If no code is specified, 'en' is used as the default.

    :type ProductId: string
    :param ProductId: [REQUIRED]
            The product identifier.

    :type ProvisioningArtifactId: string
    :param ProvisioningArtifactId: [REQUIRED]
            The provisioning artifact identifier for this product.

    :type PathId: string
    :param PathId: The identifier of the path for this product's provisioning. This value is optional if the product has a default path, and is required if there is more than one path for the specified product.

    :type ProvisionedProductName: string
    :param ProvisionedProductName: [REQUIRED]
            A user-friendly name to identify the ProvisionedProduct object. This value must be unique for the AWS account and cannot be updated after the product is provisioned.

    :type ProvisioningParameters: list
    :param ProvisioningParameters: Parameters specified by the administrator that are required for provisioning the product.
            (dict) --The arameter key/value pairs used to provision a product.
            Key (string) --The ProvisioningArtifactParameter.ParameterKey parameter from DescribeProvisioningParameters .
            Value (string) --The value to use for provisioning. Any constraints on this value can be found in ProvisioningArtifactParameter for Key .

    :type Tags: list
    :param Tags: A list of tags to use as provisioning options.
            (dict) --Key/value pairs to associate with this provisioning. These tags are entirely discretionary and are propagated to the resources created in the provisioning.
            Key (string) -- [REQUIRED]The ProvisioningArtifactParameter.TagKey parameter from DescribeProvisioningParameters .
            Value (string) -- [REQUIRED]The esired value for this key.

    :type NotificationArns: list
    :param NotificationArns: Passed to CloudFormation. The SNS topic ARNs to which to publish stack-related events.
            (string) --

    :type ProvisionToken: string
    :param ProvisionToken: [REQUIRED]
            An idempotency token that uniquely identifies the provisioning request.
            This field is autopopulated if not provided.

    :rtype: dict
    :return: {
        'RecordDetail': {
            'RecordId': 'string',
            'ProvisionedProductName': 'string',
            'Status': 'IN_PROGRESS'|'SUCCEEDED'|'ERROR',
            'CreatedTime': datetime(2015, 1, 1),
            'UpdatedTime': datetime(2015, 1, 1),
            'ProvisionedProductType': 'string',
            'RecordType': 'string',
            'ProvisionedProductId': 'string',
            'ProductId': 'string',
            'ProvisioningArtifactId': 'string',
            'PathId': 'string',
            'RecordErrors': [
                {
                    'Code': 'string',
                    'Description': 'string'
                },
            ],
            'RecordTags': [
                {
                    'Key': 'string',
                    'Value': 'string'
                },
            ]
        }
    }

    """
    pass


def transform_entity_synonyms(synonyms, known_synonyms=None):
    """Transforms the entity synonyms into a text->value dictionary"""
    entity_synonyms = known_synonyms if known_synonyms else {}
    for s in synonyms:
        if 'value' in s and 'synonyms' in s:
            for synonym in s['synonyms']:
                entity_synonyms[synonym] = s['value']
    return entity_synonyms


def rnd(float, places='default'):
    """ places: number of decimal places to round.
                set to 'default': defaults to 1 decimal place if float < 100, otherwise defaults to 0 places
    """
    if places == 'default':
        if float < 1:
            places = 2
        elif float < 100:
            places = 1
        else:
            places = 0
    rounded = round(float, places)
    if rounded != int(rounded):
        return rounded
    else:
        return int(rounded)


@classmethod
def from_path(cls, path):
    """Load YAML data from a file"""
    with open(path) as f:
        obj = cls(f)
    return obj


def get_ip_port(socket_str):
    """
    Returns ip and port
    :param socket_str: ipv4/6:port
    :return:
    address, port
    """
    splitter_index = socket_str.rindex(':')
    address = socket_str[0:splitter_index]
    port = socket_str[splitter_index + 1:]
    return address, port


def is_lock(lock):
    """
    Tests if the given lock is an instance of a lock class
    """
    if lock is None:
        return False
    for attr in ('acquire', 'release', '__enter__', '__exit__'):
        if not hasattr(lock, attr):
            return False
    return True


def strencode(string):
    """
    This function converts unicode strings to ASCII, using python's
    :func:`str.encode`, replacing any unicode characters present in the
    string. Unicode characters which Tendril expects to see in web content
    related to it are specifically replaced first with ASCII characters
    or character sequences which reasonably reproduce the original meanings.

    :param string: unicode string to be encoded.
    :return: ASCII version of the string.

    .. warning::
        This function is marked for deprecation by the general (but gradual)
        move towards ``unicode`` across tendril.

    """
    nstring = ''
    for char in string:
        if char == u'µ':
            char = 'u'
        if char == u'±':
            char = '+/-'
        nstring += char
    return nstring.encode('ascii', 'replace')


def replace_node(ptr, value):
    """Replaces a node. ptr is of the form used on the access path stack
    (parent, attrname, listidx|None)
    """
    parent, attrname, listidx = ptr
    if listidx is None:
        setattr(parent, attrname, value)
    else:
        getattr(parent, attrname)[listidx] = value


def createNode(service, nodeIdentifier=None):
    """
        Create a new publish subscribe node.

        @param service: The publish-subscribe service entity.
        @type service: L{JID<twisted.words.protocols.jabber.jid.JID>}
        @param nodeIdentifier: Optional suggestion for the new node's
                               identifier. If omitted, the creation of an
                               instant node will be attempted.
        @type nodeIdentifier: C{unicode}
        @return: a deferred that fires with the identifier of the newly created
                 node. Note that this can differ from the suggested identifier
                 if the publish subscribe service chooses to modify or ignore
                 the suggested identifier.
        @rtype: L{Deferred<twisted.internet.defer.Deferred>}
        """


def async_sleep(seconds):
    """Suspends handling the current request and passes control to the next async core.

    * http://uwsgi.readthedocs.io/en/latest/Async.html

    :param seconds: Sleep time, in seconds.

    :rtype None:
    """


def make_plural(count, word):
    """Makes world plural if more than one item.

    Args:
        count (int): count of items.
        word (str): Word.

    Returns: Modified word.
    """
    if count > 1:
        return word + 's'
    return word


def remove_variables(data, exclude_variables=None):
    """
    Removes variables from the data set.

    If passed a list of variable names to exclude, remove_variables
    will drop those variables from the dataset.

    :param data: A pandas.DataFrame.
    :param exclude_variables: A list of strings.
    :return: A pandas.DataFrame.
    """
    if exclude_variables is not None:
        data = data.drop(exclude_variables, axis=1)
    return data


def limitedSubs(data, max_interp=3, func=lambda x: abs(x) > abs(x.std() * 4.0)
    ):
    """
    Substitute elements for NaNs if a certain conditions given by fund is met at
    a maximum of max_interp times in a row.
    If there are more than that number in a row, then they are not substituted.

    Parameters
    -----------
    data: pandas.dataframe
        data to be interpolated
    max_interp: int
        number of maximum NaNs in a row to interpolate
    func: function
        function of x only that determines the which elements become NaNs. Should return
        only True or False.

    Returns
    --------
    df: pandas.dataframe
        dataframe with the elements substituted
    """
    import numpy as np
    df = data.copy()
    cond = func(df)
    for c in df.columns:
        grouper = (cond[c] != cond[c].shift(1)).cumsum() * cond[c]
        fill = df.groupby(grouper)[c].transform(lambda x: x.size) <= max_interp
        df.loc[fill & cond[c], c] = np.nan
    return df


def change_linesep(sep):
    """change line separator, this is here just for tests.
    """
    global LINESEP, LINESEP_LEN
    LINESEP = sep
    LINESEP_LEN = len(sep)


def get_fqn(the_type):
    """Get module.type_name for a given type."""
    module = the_type.__module__
    name = the_type.__qualname__
    return '%s.%s' % (module, name)


def match_kv(condition):
    """Take a list of key value pairs and generate an EQL expression.

    :param dict condition: The source text query
    :rtype: ast.Expression
    """
    from . import ast
    from .parser import parse_field
    if not isinstance(condition, dict):
        raise TypeError('unsupported type {} to match_kv. Expected {}'.
            format(type(condition), ast.EqlNode))
    and_node = ast.Boolean(True)
    for field_text, field_match in sorted(condition.items()):
        if not isinstance(field_match, (list, tuple)):
            field_match = [field_match]
        field_node = parse_field(field_text)
        exact = []
        wildcards = []
        for term in field_match:
            literal = ast.Literal.from_python(term)
            if isinstance(literal, ast.String) and '*' in literal.value:
                wildcards.append(literal)
            else:
                exact.append(literal)
        match_node = ast.InSet(field_node, exact).optimize()
        if wildcards:
            match_node |= ast.FunctionCall('wildcard', [field_node] + wildcards
                )
        and_node &= match_node
    return and_node


def padNextPower2(size: int) ->int:
    """Calculate the amount of padding to next power of 2

    Parameters
    ----------
    size : float
        Size of array to be padded

    Returns
    -------
    padSize : int
        Amout of extra padding required to increase to next power of 2
    """
    import math
    next2Power = math.ceil(math.log(size, 2))
    next2Size = math.pow(2, int(next2Power))
    return int(next2Size) - size


@staticmethod
def _line(line, comment='', termination=';', comment_char='//', new_lines=1):
    """
        To format a line

        Args:
            new_lines (int): Number of new lines to be added after the line
            termination (str): Termination character for the code line
            comment_char (str): Comment tag
            comment (str): Comment for the line if any
            line (str): The code line to be added
        """
    comment_line = ''
    main_line = line
    main_line = main_line + termination if main_line else main_line
    if comment:
        if main_line:
            comment_line = '    {}{}'.format(comment_char, comment)
        else:
            comment_line = '{}{}'.format(comment_char, comment)
    main_line += comment_line
    return main_line + '\n' * new_lines


def _get_role_ids(identity_client, parsed_args):
    """Return prior and implied role id(s)

    If prior and implied role id(s) are retrievable from identity
    client, return tuple containing them.
    """
    role_id = None
    implied_role_id = None
    roles = identity_client.roles.list()
    for role in roles:
        role_id_or_name = role.name, role.id
        if parsed_args.role in role_id_or_name:
            role_id = role.id
        elif parsed_args.implied_role in role_id_or_name:
            implied_role_id = role.id
    return role_id, implied_role_id


def merge_kwargs(local_kwarg, default_kwarg):
    """Merges kwarg dictionaries.

    If a local key in the dictionary is set to None, it will be removed.
    """
    if default_kwarg is None:
        return local_kwarg
    if isinstance(local_kwarg, str):
        return local_kwarg
    if local_kwarg is None:
        return default_kwarg
    if not hasattr(default_kwarg, 'items'):
        return local_kwarg
    kwargs = default_kwarg.copy()
    kwargs.update(local_kwarg)
    for k, v in list(local_kwarg.items()):
        if v is None:
            del kwargs[k]
    return kwargs


@classmethod
def _expr_big_minus(cls, x, n):
    """An expression for F(exp_polar(2*I*pi*n + pi*I)*x), |x| > 1."""
    raise NotImplementedError


def branchmap():
    """Obtain heads in named branches.

        Returns a dict mapping branch name to an iterable of nodes that are
        heads on that branch.
        """


def read_file(path):
    """Reads a given file, returns str(file_content)"""
    with open(path, 'a+') as f:
        f.seek(0, 0)
        return '\n'.join(f.readlines())


@staticmethod
def _define_module_argument_spec():
    """
        Define the argument spec for the ansible module
        :return: argument spec dictionary
        """
    argument_spec = dict(id=dict(required=False), location=dict(required=True))
    return argument_spec


@staticmethod
def _resolve_param_duplicates(values, param_defn, _in):
    """ Resolve cases where query parameters are provided multiple times.
            The default behavior is to use the first-defined value.
            For example, if the query string is '?a=1,2,3&a=4,5,6' the value of
            `a` would be "4,5,6".
            However, if 'collectionFormat' is 'multi' then the duplicate values
            are concatenated together and `a` would be "1,2,3,4,5,6".
        """
    if param_defn.get('collectionFormat') == 'multi':
        return ','.join(values)
    return values[-1]


def str_check(value, default=''):
    """value must be a string or default."""
    if value is None:
        return default
    else:
        return str(value)


def get_theme_names():
    """Return an iterable of names."""


def hide_fields_in_newer_versions(obj):
    """This method hides fields that were added in newer API versions.

    Certain node fields were introduced at certain API versions.
    These fields are only made available when the request's API version
    matches or exceeds the versions when these fields were introduced.
    """
    pass


def write_to_file(html, file):
    """
    write html to file
    """
    with open(file, 'w') as f:
        f.write(html)


def load_ipython_extension(ip):
    """Load the extension in IPython."""
    from ipython_magic import GHDiffMagics
    ip.register_magics(GHDiffMagics)