def create_campaign(ApplicationId=None, WriteCampaignRequest=None):
    """
    Creates or updates a campaign.

    :example: response = client.create_campaign(
        ApplicationId='string',
        WriteCampaignRequest={
            'AdditionalTreatments': [
                {
                    '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,
                    'TreatmentDescription': 'string',
                    'TreatmentName': 'string'
                },
            ],
            'Description': 'string',
            'HoldoutPercent': 123,
            'IsPaused': True|False,
            '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,
            'TreatmentDescription': 'string',
            'TreatmentName': 'string'
        }
    )

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

    :type WriteCampaignRequest: dict
    :param WriteCampaignRequest: [REQUIRED] Used to create a campaign.
            AdditionalTreatments (list) -- Treatments that are defined in addition to the default treatment.
            (dict) -- Used to create a campaign treatment.
            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.
            TreatmentDescription (string) -- A custom description for the treatment.
            TreatmentName (string) -- The custom name of a variation of the campaign used for A/B testing.

            Description (string) -- A description of the campaign.
            HoldoutPercent (integer) -- The allocated percentage of end users who will not receive messages from this campaign.
            IsPaused (boolean) -- Indicates whether the campaign is paused. A paused campaign does not send messages unless you resume it by setting IsPaused to false.
            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.
            TreatmentDescription (string) -- A custom description for the treatment.
            TreatmentName (string) -- The custom name of a variation of the campaign used for A/B testing.

    :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) -- 201 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 endInteraction():
    """
        End the current interaction.

        Does nothing if there is no interaction.
        """


def add_params(default_params, extra_params):
    """ Add params from extra_params to default_params

    Parameters
    ----------
    default_params : dict
        Original parameters
    extra_params : dict
        Extra parameters to add

    Returns
    ------
    params : dict
        Merged parameters, where extra_params can overwrite default_params

    """
    for k, v in extra_params.items():
        default_params[k] = v
    return default_params


@classmethod
def load_rdkit_mol(cls, mol):
    """
        Create a :class:`MolecularSystem` from :class:`rdkit.Chem.rdchem.Mol`.

        Parameters
        ----------
        mol : :class:`rdkit.Chem.rdchem.Mol`
           An RDKit molecule object.

        Returns
        -------
        :class:`pywindow.molecular.MolecularSystem`
            :class:`MolecularSystem`

        """
    obj = cls()
    obj.system = obj._Input.load_rdkit_mol(mol)
    return obj


def decode_bytes(data, fallback='iso8859-15'):
    """Decode a bytes-like object that is expected to be a valid string

    First utf8 is tried, then the fallback (defaults to iso8859-15).
    The fallback behavior can be disabled by setting the option to None.
    """
    try:
        return data.decode('utf8')
    except UnicodeDecodeError:
        if fallback:
            return data.decode(fallback)
        raise


def build_relabel_dict(x):
    """Relabel the input ids to continuous ids that starts from zero.

    The new id follows the order of the given node id list.

    Parameters
    ----------
    x : list
      The input ids.

    Returns
    -------
    relabel_dict : dict
      Dict from old id to new id.
    """
    relabel_dict = {}
    for i, v in enumerate(x):
        relabel_dict[v] = i
    return relabel_dict


def get_client_ip(request):
    """
    http://stackoverflow.com/questions/4581789/how-do-i-get-user-ip-address-in-django
    :param request:
    """
    x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
    if x_forwarded_for:
        ip = x_forwarded_for.split(',')[0]
    else:
        ip = request.META.get('REMOTE_ADDR')
    return ip


def _get_actor_specs(nodes, nb_gpus_per_node, using_cpu_only,
    nb_cpu_workers, grpc_port):
    """ Returns the list of ip:port for all actor nodes """
    gpu_ips = []
    for node_ip in nodes.values():
        for gpu_ix in range(nb_cpu_workers if using_cpu_only else
            nb_gpus_per_node):
            gpu_ips += ['%s:%d' % (node_ip, grpc_port + 200 + gpu_ix)]
    nb_learners = max(len(gpu_ips) // 8, 1)
    return gpu_ips[:-nb_learners]


@classmethod
def _add_workflow(mcs, field_name, state_field, attrs):
    """Attach the workflow to a set of attributes.

        Constructs the ImplementationWrapper for transitions, and adds them to
        the attributes dict.

        Args:
            field_name (str): name of the attribute where the StateField lives
            state_field (StateField): StateField describing that attribute
            attrs (dict): dictionary of attributes for the class being created
        """
    pass


def read(fieldNode, schema, field):
    """Called once the field in the given <field /> node has been
        read. field is the field instance that was read. schema is the schema
        it is a part of.
        """


@classmethod
def show(cls, context, artifact_id, get_any_artifact=False):
    """Return Artifact from Glare repo

        :param context: user context
        :param artifact_id: id of requested artifact
        :return: requested artifact object
        """
    if cls.get_type_name() != 'all':
        type_name = cls.get_type_name()
    else:
        type_name = None
    af = cls.db_api.get(context, type_name, artifact_id, get_any_artifact)
    return cls.init_artifact(context, af)


def get_owned_replicasets(deployment, replicasets) ->list:
    """Return all replicasets owned by a deployment"""
    owned = []
    for rs in replicasets:
        for owner in rs['metadata'].get('ownerReferences', []):
            if owner['uid'] == deployment['metadata']['uid']:
                owned.append(rs)
    return owned


def _get_hostedzone_id(r53_client, domain):
    """Get the hosted zone id for a Route53 domain.

    Parameters
    ----------
    domain : str
        Name of the domain to locate.

    Returns
    -------
    str or None
        HostedZoneId of the Route53 hosted zone or None if it doesn't exist.
    """
    hosted_zones = r53_client.list_hosted_zones()['HostedZones']
    print('Searching for hosted zone {}'.format(domain))
    for hosted_zone in hosted_zones:
        if hosted_zone['Name'] == domain:
            return hosted_zone['Id']
    return None


def svp_water(t):
    """Saturation vapour pressure over water at given temperature.

    Parameters
    ----------
    t : float
        Air temperature in degree Celsius.

    Returns
    -------
    p_sv : float
        Saturation vapour pressure over water, at the given
        temperature, in Pascal.

    Notes
    -----
    From section A-I of
    http://emtoolbox.nist.gov/Wavelength/Documentation.asp.

    """
    import math
    K1 = 1167.05214528
    K2 = -724213.167032
    K3 = -17.0738469401
    K4 = 12020.8247025
    K5 = -3232555.03223
    K6 = 14.9151086135
    K7 = -4823.26573616
    K8 = 405113.405421
    K9 = -0.238555575678
    K10 = 650.175348448
    T = t + 273.15
    omega = T + K9 / (T - K10)
    A = omega ** 2 + K1 * omega + K2
    B = K3 * omega ** 2 + K4 * omega + K5
    C = K6 * omega ** 2 + K7 * omega + K8
    X = -B + math.sqrt(B ** 2 - 4 * A * C)
    p_sv = 1000000.0 * (2.0 * C / X) ** 4
    return p_sv


def get_offer_video_link(html_parser):
    """
    This method returns a link to a video of the apartment.

    :param html_parser: a BeautifulSoup object
    :rtype: string
    :return: A link to a video of the apartment
    """
    video_raw_data = html_parser.find(class_='section-offer-video')
    video = ''
    if hasattr(video_raw_data, 'iframe'):
        video = html_parser.find(class_='section-offer-video').iframe.attrs[
            'src']
    return video


def get_sounding_direction(bufr_msg):
    """
    Get direction of sounding

    1: upward
    -1: downward
    """
    if str(bufr_msg) == '309052':
        return 1
    elif str(bufr_msg) == '309053':
        return -1
    elif str(bufr_msg) == '309056':
        return -1
    elif str(bufr_msg) == '309057':
        return 1
    else:
        raise NotImplementedError(
            'The bufr message format {} is not implemented'.format(bufr_msg))


def assert_almost_equal(a, b, places=7, msg=None):
    """
    Fail if the two objects are unequal as determined by their
    difference rounded to the given number of decimal places
    and comparing to zero.

    Note that decimal places (from zero) are usually not the same
    as significant digits (measured from the most signficant digit).

    See the builtin round() function for places parameter.
    """
    if msg is None:
        assert round(abs(b - a), places) == 0
    else:
        assert round(abs(b - a), places) == 0, msg


@classmethod
def get_review_policy_exception(cls, exam_id, user_id):
    """
        Helper method to get the policy exception that reviewers should
        follow
        """
    allowance = cls.get_allowance_for_user(exam_id, user_id, cls.
        REVIEW_POLICY_EXCEPTION[0])
    return allowance.value if allowance else None


def molspec(x):
    """
    Parse a string for a lipid or a solvent as given on the command line
    (MOLECULE[=NUMBER|:NUMBER]); where `=NUMBER` sets an absolute number of the
    molecule, and `:NUMBER` sets a relative number of it.
    If both absolute and relative number are set False, then relative count is 1.
    """
    lip = x.split(':')
    abn = lip[0].split('=')
    names = abn[0]
    if len(abn) > 1:
        nrel = 0
        nabs = int(abn[1])
    else:
        nabs = 0
        if len(lip) > 1:
            nrel = float(lip[1])
        else:
            nrel = 1
    return abn[0], nabs, nrel


def slide_marker(offset: float=(0.0, 0.0)):
    """Slide marker areas

    :param offset: Offset, Offset in floating point units, 1.0 is the width and height of the image
    :type offset: float
    """
    pass


def addToolbarActions(toolbar, actions, which):
    """Add actions listed in "which" from dict "actions" to toolbar "toolbar".
    """
    for w in which:
        toolbar.addAction(actions[w])


def add_sequence(automaton, tids, rid, start=0, with_duplicates=False):
    """
    Add the `tids` sequence of token ids for the `rid` Rule id starting at `start`
    position to the an Aho-Corasick `automaton`.

    If `with_duplicates` is True and if `tids` exists in the automaton, append a
    rule pointers to a list of "values" for these `tids`. Otherwise if `tids`
    exists in the automaton, adding a new sequence will overwrite the previous
    entry.
    """
    end = len(tids) - 1
    value = rid, start, start + end
    tokens = tuple(tids)
    if with_duplicates:
        existing = automaton.get(tokens, None)
        if existing:
            existing.append(value)
        else:
            automaton.add_word(tokens, [value])
    else:
        automaton.add_word(tokens, [value])


def pngload(file):
    """
        Returns a read png file.

        Meta information is available as `.info` attribute.

        Can be turned into a numpy array by casting (depends on PIL version)::

            numpy.array(im)

    """
    from PIL import Image
    im = Image.open(file)
    return im


def call_formatter(cmd, input):
    """
    Return the formatted version of the given file.
    """
    from subprocess import Popen, PIPE, CalledProcessError
    import logging
    logging.debug('calling %r', cmd)
    p = Popen(cmd, stdout=PIPE, stdin=PIPE, stderr=PIPE)
    out, err = p.communicate(input)
    if p.returncode:
        raise CalledProcessError(p.returncode, cmd, err)
    return out


def db2dbm(quality):
    """
    Converts the Radio (Received) Signal Strength Indicator (in db) to a dBm
    value.  Please see http://stackoverflow.com/a/15798024/1013960
    """
    dbm = int(quality / 2 - 100)
    return min(max(dbm, -100), -50)


def append_hostname(machine_name, num_list):
    """
    Helper method to append the hostname to node numbers.

    :param machine_name: The name of the cluster.
    :param num_list: The list of nodes to be appended to the cluster name.
    :return: A hostlist string with the hostname and node numbers.
    """
    hostlist = []
    for elem in num_list:
        hostlist.append(machine_name + str(elem))
    return '%s' % ','.join(map(str, hostlist))


def effective_principals(request):
    """ Return a sequence representing the effective principals
        typically including the :term:`userid` and any groups belonged
        to by the current user, always including 'system' groups such
        as ``pyramid.security.Everyone`` and
        ``pyramid.security.Authenticated``.

        """


@staticmethod
def get_vm_info_header():
    """Formatted header for use with cloud_status vm info output."""
    return '%-6s %-25s %-20s %-10s %-12s %-23s\n' % ('ID', 'HOSTNAME',
        'VMTYPE', 'USER', 'STATUS', 'CLUSTER')


def H_donor_count(mol):
    """Hydrogen bond donor count """
    mol.require('Valence')
    return sum(1 for _, a in mol.atoms_iter() if a.H_donor)


@classmethod
def modify_url_for_impersonation(cls, url, impersonate_user, username):
    """
        Modify the SQL Alchemy URL object with the user to impersonate if applicable.
        :param url: SQLAlchemy URL object
        :param impersonate_user: Bool indicating if impersonation is enabled
        :param username: Effective username
        """
    if impersonate_user is not None and username is not None:
        url.username = username


def find_in_list_of_lists(list_of_lists, value):
    """
    Find value in list of lists and return first found index of list.
    :param list_of_lists:
    :param value:
    :return:
    """
    for i, lst in enumerate(list_of_lists):
        if value in lst:
            return i
    return None


def stabilize_2d_add():
    """Add selected tracks to 2D translation stabilization

    """
    pass


def split_path(path, abs_path=True):
    """Splits a URI-encoded path into path segments

    path
        A character string containing the path component of a URI. If
        path is None we treat as for an empty string.

    abs_path
        A flag (defaults to True) indicating whether or not the
        path is relative or absolute.  This flag only affects
        the handling of the empty path.  An empty absolute path
        is treated as if it were '/' and returns a list containing
        a single empty path segment whereas an empty relative
        path returns a list with no path segments, in other words,
        an empty list.

    The return result is always a list of character strings split from
    *path*.  It will only end in an empty path segment if the path ends
    with a slash."""
    if path:
        if abs_path:
            if ord(path[0]) != 47:
                raise ValueError('Abs path must be empty or start with /')
            return path.split('/')[1:]
        else:
            return path.split('/')
    elif not abs_path:
        return ['']
    else:
        return []


def get_frequency_count_bool(values_list, value):
    """Counts frequency for columns containing type boolean

         :param values_list: list
        list of all the values
        :param value: string
            name of the column
        :return:
            dictionary named by the value name and containing all frequencies
            for rows as integer values
        """
    frequency_values_dict = {}
    tmp_dict = {}
    for feature in values_list:
        if feature not in tmp_dict:
            tmp_dict[feature] = 1
        else:
            tmp_dict[feature] = tmp_dict.get(feature) + 1
    frequency_values_dict['{} frequencies'.format(value)] = tmp_dict
    return frequency_values_dict


def seconds_to_str(seconds):
    """Approximate text description of how many seconds

    Parameters
    ----------
    seconds: int
        number of seconds

    Returns
    -------
    str:
        Something like: 30 seconds, or 4 minutes

    """
    minutes = int(seconds / 60)
    if minutes:
        return f'{minutes} min, '
    else:
        return f'{seconds % 60:0.0f} seconds'


def _padtrim(entry, n_bytes):
    """
    Pad or trim an EDF header field entry to n_bytes bytes.
    """
    entry = str(entry)
    n_bytes -= len(entry)
    if n_bytes >= 0:
        entry = entry + ' ' * n_bytes
    else:
        entry = entry[0:n_bytes]
    return entry.encode()


def IB_DESIGNABLE(cls):
    """
    Class decorator for annotating that a class can be used in Interface Builder.

    The decorator doesn't do anything.
    """
    return cls


@staticmethod
def _is_execution_id(text):
    """
        Verify that input is a valid Faaspot execution_id
        """
    return len(text) == 36 and len(text.split('-')) == 5


def sort(canon_dict):
    """Remove the all_variables entry and sort other entries in place."""
    del canon_dict['all_variables']
    canon_dict['selection'].sort()
    for values in canon_dict['restriction'].values():
        values.sort()


@classmethod
def __get_proxy_class__(mcs, real_class):
    """Provide a proxy twin for a real class"""
    try:
        return mcs.__proxy_class_store__[real_class]
    except KeyError:
        proxy_class = mcs.__new_proxy_class__(real_class.__name__,
            real_class.__bases__, real_class.__dict__)
        mcs.register_proxy(real_class=real_class, proxy_class=proxy_class)
        return proxy_class


def get_domain_suggestions(DomainName=None, SuggestionCount=None,
    OnlyAvailable=None):
    """
    The GetDomainSuggestions operation returns a list of suggested domain names given a string, which can either be a domain name or simply a word or phrase (without spaces).
    See also: AWS API Documentation

    :example: response = client.get_domain_suggestions(
        DomainName='string',
        SuggestionCount=123,
        OnlyAvailable=True|False
    )

    :type DomainName: string
    :param DomainName: [REQUIRED]
            A domain name that you want to use as the basis for a list of possible domain names. The domain name must contain a top-level domain (TLD), such as .com, that Amazon Route 53 supports. For a list of TLDs, see Domains that You Can Register with Amazon Route 53 in the Amazon Route 53 Developer Guide .

    :type SuggestionCount: integer
    :param SuggestionCount: [REQUIRED]
            The number of suggested domain names that you want Amazon Route 53 to return.

    :type OnlyAvailable: boolean
    :param OnlyAvailable: [REQUIRED]
            If OnlyAvailable is true , Amazon Route 53 returns only domain names that are available. If OnlyAvailable is false , Amazon Route 53 returns domain names without checking whether they're available to be registered. To determine whether the domain is available, you can call checkDomainAvailability for each suggestion.

    :rtype: dict
    :return: {
        'SuggestionsList': [
            {
                'DomainName': 'string',
                'Availability': 'string'
            },
        ]
    }

    """
    pass


def ifnone(a, b):
    """`b` if `a` is None else `a`"""
    return b if a is None else a


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

    """
    pass


def widget(func):
    """Decorator to mark :class:`Dialog` methods that provide widgets.

    This allows code to perform automatic operations on these specific
    methods. For instance, one can define a class that behaves similarly
    to :class:`Dialog`, except that after every widget-producing call,
    it spawns a "confirm quit" dialog if the widget returned
    :attr:`Dialog.ESC`, and loops in case the user doesn't actually want
    to quit.

    When it is unclear whether a method should have the decorator or
    not, the return value is used to draw the line. For instance, among
    :meth:`Dialog.gauge_start`, :meth:`Dialog.gauge_update` and
    :meth:`Dialog.gauge_stop`, only the last one has the decorator
    because it returns a :term:`Dialog exit code`, whereas the first two
    don't return anything meaningful.

    Note:

      Some widget-producing methods return the Dialog exit code, but
      other methods return a *sequence*, the first element of which is
      the Dialog exit code; the ``retval_is_code`` attribute, which is
      set by the decorator of the same name, allows to programmatically
      discover the interface a given method conforms to.

    .. versionadded:: 2.14

    """
    func.is_widget = True
    return func


def key():
    """Returns string identifier of ICachedItem attribute that represents unique item entries (e.g. primary key field name)"""


def describe_vpc_endpoint_services(DryRun=None, MaxResults=None, NextToken=None
    ):
    """
    Describes all supported AWS services that can be specified when creating a VPC endpoint.
    See also: AWS API Documentation

    :example: response = client.describe_vpc_endpoint_services(
        DryRun=True|False,
        MaxResults=123,
        NextToken='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 MaxResults: integer
    :param MaxResults: The maximum number of items to return for this request. The request returns a token that you can specify in a subsequent call to get the next set of results.
            Constraint: If the value is greater than 1000, we return only 1000 items.

    :type NextToken: string
    :param NextToken: The token for the next set of items to return. (You received this token from a prior call.)

    :rtype: dict
    :return: {
        'ServiceNames': [
            'string',
        ],
        'NextToken': 'string'
    }

    :returns:
    (string) --

    """
    pass


def remove_cookie_by_name(cookiejar, name, domain=None, path=None):
    """Unsets a cookie by name, by default over all domains and paths.

    Wraps CookieJar.clear(), is O(n).
    """
    clearables = []
    for cookie in cookiejar:
        if cookie.name == name:
            if domain is None or domain == cookie.domain:
                if path is None or path == cookie.path:
                    clearables.append((cookie.domain, cookie.path, cookie.name)
                        )
    for domain, path, name in clearables:
        cookiejar.clear(domain, path, name)


def _norm_angle(a):
    """Return the given angle normalized to -180 < *a* <= 180 degrees."""
    a = (a + 360) % 360
    if a > 180:
        a = a - 360
    return a


def job_dir(this, value):
    """Try to create job dir when access it"""
    ret = this.proc.workdir.joinpath(str(this.index + 1)).resolve()
    if not ret.is_dir():
        ret.mkdir(exist_ok=True)
    return ret


def _item_from(container, index):
    """Attempts to fetch a index/key from a given container."""
    if index is None:
        return container
    return container[index]


def addCookie(k, v, expires=None, domain=None, path=None, max_age=None,
    comment=None, secure=None):
    """
        Set an outgoing HTTP cookie.

        In general, you should consider using sessions instead of cookies, see
        L{twisted.web.server.Request.getSession} and the
        L{twisted.web.server.Session} class for details.
        """


@classmethod
def check_strike(cls, strike):
    """
        Check if ``strike`` is in range ``[0, 360)``
        and raise ``ValueError`` otherwise.
        """
    if not 0 <= strike < 360:
        raise ValueError('strike %g is out of range [0, 360)' % strike)


@classmethod
def _to_str(cls, value):
    """Represents values either as string or None values as empty string.

        Args:
            value: a value

        """
    if value is None:
        return ''
    else:
        return str(value)


def update_package_data(distribution):
    """update build_py options to get package_data changes"""
    build_py = distribution.get_command_obj('build_py')
    build_py.finalize_options()


def get_all(isamAppliance, check_mode=False, force=False):
    """
    Retrieving the list of federated directories
    """
    return isamAppliance.invoke_get(
        'Retrieving the list of federated directories',
        '/isam/runtime_components/federated_directories/v1')


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

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


def detect_conflict(cursor):
    """
        Find all conflicts in the data about to be committed (as stored
        by :meth:`store_temps`)

        Returns a sequence of
        ``(oid, committed_tid, attempted_committed_tid, committed_state)`` where
        each entry refers to a conflicting object. The *committed_state* **must** be
        returned.

        This method should be called during the ``tpc_vote`` phase of a transaction,
        with :meth:`ILocker.lock_current_objects` held.
        """


def view_on_a_map(filename, **kwargs):
    """
    Plots a feeder file on a map
    :param filename:
    :param kwargs:
    :return:
    """
    if kwargs is not None:
        for key, value in kwargs.iteritems():
            if key == 'location':
                location = value
            elif key == 'location_latlong':
                location_latlong = value
            elif key == 'radius':
                radius = value
            elif key == 'basemap':
                basemap = value


def abort():
    """Abort sending the message for asynchronous subclasses."""


def getwrapperchain(container, funcname):
    """get a chain of wrappers of a function

    Return a list of functions: [newest wrapper, ..., oldest wrapper, origfunc]

    The wrapper functions are the ones passed to wrapfunction, whose first
    argument is origfunc.
    """
    result = []
    fn = getattr(container, funcname)
    while fn:
        assert callable(fn)
        result.append(getattr(fn, '_unboundwrapper', fn))
        fn = getattr(fn, '_origfunc', None)
    return result


def tabunescape(escaped):
    """ Unescape a string using the specific Dovecot tabescape
    See: https://github.com/dovecot/core/blob/master/src/lib/strescape.c
    """
    return escaped.replace(b'\x01r', b'\r').replace(b'\x01n', b'\n').replace(
        b'\x01t', b'\t').replace(b'\x010', b'\x00').replace(b'\x011', b'\x01')


def expandCesiumColor(colorString):
    """
    Returns None or Cesium.Color.COLORNAME
    """
    if colorString is None:
        return None
    colorString.replace(' ', '')
    if '.' in colorString:
        parts = colorString.split('.')
        if len(parts) == 3:
            return '{}.{}.{}'.format(parts[0].capitalize(), parts[1].
                capitalize(), parts[2].upper())
        else:
            return colorString
    else:
        return 'Cesium.Color.{}'.format(colorString.upper())


def __new__(cls, *args, **kwargs):
    """Caches arguments for Player cloning."""
    obj = super().__new__(cls)
    obj.init_kwargs = cls.init_params(*args, **kwargs)
    return obj


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

        :param MemberSendInvitePolicyChangedType val:
        :rtype: EventType
        """
    return cls('member_send_invite_policy_changed', val)


def update_byte_match_set(ByteMatchSetId=None, ChangeToken=None, Updates=None):
    """
    Inserts or deletes  ByteMatchTuple objects (filters) in a  ByteMatchSet . For each ByteMatchTuple object, you specify the following values:
    For example, you can add a ByteMatchSetUpdate object that matches web requests in which User-Agent headers contain the string BadBot . You can then configure AWS WAF to block those requests.
    To create and configure a ByteMatchSet , perform the following steps:
    For more information about how to use the AWS WAF API to allow or block HTTP requests, see the AWS WAF Developer Guide .
    See also: AWS API Documentation

    Examples
    The following example deletes a ByteMatchTuple object (filters) in an byte match set with the ID exampleIDs3t-46da-4fdb-b8d5-abc321j569j5.
    Expected Output:

    :example: response = client.update_byte_match_set(
        ByteMatchSetId='string',
        ChangeToken='string',
        Updates=[
            {
                'Action': 'INSERT'|'DELETE',
                'ByteMatchTuple': {
                    'FieldToMatch': {
                        'Type': 'URI'|'QUERY_STRING'|'HEADER'|'METHOD'|'BODY',
                        'Data': 'string'
                    },
                    'TargetString': b'bytes',
                    'TextTransformation': 'NONE'|'COMPRESS_WHITE_SPACE'|'HTML_ENTITY_DECODE'|'LOWERCASE'|'CMD_LINE'|'URL_DECODE',
                    'PositionalConstraint': 'EXACTLY'|'STARTS_WITH'|'ENDS_WITH'|'CONTAINS'|'CONTAINS_WORD'
                }
            },
        ]
    )

    :type ByteMatchSetId: string
    :param ByteMatchSetId: [REQUIRED]
            The ByteMatchSetId of the ByteMatchSet that you want to update. ByteMatchSetId is returned by CreateByteMatchSet and by ListByteMatchSets .

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

    :type Updates: list
    :param Updates: [REQUIRED]
            An array of ByteMatchSetUpdate objects that you want to insert into or delete from a ByteMatchSet . For more information, see the applicable data types:
            ByteMatchSetUpdate : Contains Action and ByteMatchTuple
            ByteMatchTuple : Contains FieldToMatch , PositionalConstraint , TargetString , and TextTransformation
            FieldToMatch : Contains Data and Type
            (dict) --In an UpdateByteMatchSet request, ByteMatchSetUpdate specifies whether to insert or delete a ByteMatchTuple and includes the settings for the ByteMatchTuple .
            Action (string) -- [REQUIRED]Specifies whether to insert or delete a ByteMatchTuple .
            ByteMatchTuple (dict) -- [REQUIRED]Information about the part of a web request that you want AWS WAF to inspect and the value that you want AWS WAF to search for. If you specify DELETE for the value of Action , the ByteMatchTuple values must exactly match the values in the ByteMatchTuple that you want to delete from the ByteMatchSet .
            FieldToMatch (dict) -- [REQUIRED]The part of a web request that you want AWS WAF to search, such as a specified header or a query string. For more information, see FieldToMatch .
            Type (string) -- [REQUIRED]The part of the web request that you want AWS WAF to search for a specified string. Parts of a request that you can search include the following:
            HEADER : A specified request header, for example, the value of the User-Agent or Referer header. If you choose HEADER for the type, specify the name of the header in Data .
            METHOD : The HTTP method, which indicated the type of operation that the request is asking the origin to perform. Amazon CloudFront supports the following methods: DELETE , GET , HEAD , OPTIONS , PATCH , POST , and PUT .
            QUERY_STRING : A query string, which is the part of a URL that appears after a ? character, if any.
            URI : The part of a web request that identifies a resource, for example, /images/daily-ad.jpg .
            BODY : The part of a request that contains any additional data that you want to send to your web server as the HTTP request body, such as data from a form. The request body immediately follows the request headers. Note that only the first 8192 bytes of the request body are forwarded to AWS WAF for inspection. To allow or block requests based on the length of the body, you can create a size constraint set. For more information, see CreateSizeConstraintSet .
            Data (string) --When the value of Type is HEADER , enter the name of the header that you want AWS WAF to search, for example, User-Agent or Referer . If the value of Type is any other value, omit Data .
            The name of the header is not case sensitive.
            TargetString (bytes) -- [REQUIRED]The value that you want AWS WAF to search for. AWS WAF searches for the specified string in the part of web requests that you specified in FieldToMatch . The maximum length of the value is 50 bytes.
            Valid values depend on the values that you specified for FieldToMatch :
            HEADER : The value that you want AWS WAF to search for in the request header that you specified in FieldToMatch , for example, the value of the User-Agent or Referer header.
            METHOD : The HTTP method, which indicates the type of operation specified in the request. CloudFront supports the following methods: DELETE , GET , HEAD , OPTIONS , PATCH , POST , and PUT .
            QUERY_STRING : The value that you want AWS WAF to search for in the query string, which is the part of a URL that appears after a ? character.
            URI : The value that you want AWS WAF to search for in the part of a URL that identifies a resource, for example, /images/daily-ad.jpg .
            BODY : The part of a request that contains any additional data that you want to send to your web server as the HTTP request body, such as data from a form. The request body immediately follows the request headers. Note that only the first 8192 bytes of the request body are forwarded to AWS WAF for inspection. To allow or block requests based on the length of the body, you can create a size constraint set. For more information, see CreateSizeConstraintSet .
            If TargetString includes alphabetic characters A-Z and a-z, note that the value is case sensitive.
            If you're using the AWS WAF API
            Specify a base64-encoded version of the value. The maximum length of the value before you base64-encode it is 50 bytes.
            For example, suppose the value of Type is HEADER and the value of Data is User-Agent . If you want to search the User-Agent header for the value BadBot , you base64-encode BadBot using MIME base64 encoding and include the resulting value, QmFkQm90 , in the value of TargetString .
            If you're using the AWS CLI or one of the AWS SDKs
            The value that you want AWS WAF to search for. The SDK automatically base64 encodes the value.
            TextTransformation (string) -- [REQUIRED]Text transformations eliminate some of the unusual formatting that attackers use in web requests in an effort to bypass AWS WAF. If you specify a transformation, AWS WAF performs the transformation on TargetString before inspecting a request for a match.
            CMD_LINE
            When you're concerned that attackers are injecting an operating system commandline command and using unusual formatting to disguise some or all of the command, use this option to perform the following transformations:
            Delete the following characters: ' ' ^
            Delete spaces before the following characters: / (
            Replace the following characters with a space: , ;
            Replace multiple spaces with one space
            Convert uppercase letters (A-Z) to lowercase (a-z)
            COMPRESS_WHITE_SPACE
            Use this option to replace the following characters with a space character (decimal 32):
            f, formfeed, decimal 12
            t, tab, decimal 9
            n, newline, decimal 10
            r, carriage return, decimal 13
            v, vertical tab, decimal 11
            non-breaking space, decimal 160
            COMPRESS_WHITE_SPACE also replaces multiple spaces with one space.HTML_ENTITY_DECODE
            Use this option to replace HTML-encoded characters with unencoded characters. HTML_ENTITY_DECODE performs the following operations:
            Replaces (ampersand)quot; with '
            Replaces (ampersand)nbsp; with a non-breaking space, decimal 160
            Replaces (ampersand)lt; with a 'less than' symbol
            Replaces (ampersand)gt; with ````
            Replaces characters that are represented in hexadecimal format, (ampersand)#xhhhh; , with the corresponding characters
            Replaces characters that are represented in decimal format, (ampersand)#nnnn; , with the corresponding characters
            LOWERCASE
            Use this option to convert uppercase letters (A-Z) to lowercase (a-z).
            URL_DECODE
            Use this option to decode a URL-encoded value.
            NONE
            Specify NONE if you don't want to perform any text transformations.
            PositionalConstraint (string) -- [REQUIRED]Within the portion of a web request that you want to search (for example, in the query string, if any), specify where you want AWS WAF to search. Valid values include the following:
            CONTAINS
            The specified part of the web request must include the value of TargetString , but the location doesn't matter.
            CONTAINS_WORD
            The specified part of the web request must include the value of TargetString , and TargetString must contain only alphanumeric characters or underscore (A-Z, a-z, 0-9, or _). In addition, TargetString must be a word, which means one of the following:
            TargetString exactly matches the value of the specified part of the web request, such as the value of a header.
            TargetString is at the beginning of the specified part of the web request and is followed by a character other than an alphanumeric character or underscore (_), for example, BadBot; .
            TargetString is at the end of the specified part of the web request and is preceded by a character other than an alphanumeric character or underscore (_), for example, ;BadBot .
            TargetString is in the middle of the specified part of the web request and is preceded and followed by characters other than alphanumeric characters or underscore (_), for example, -BadBot; .
            EXACTLY
            The value of the specified part of the web request must exactly match the value of TargetString .
            STARTS_WITH
            The value of TargetString must appear at the beginning of the specified part of the web request.
            ENDS_WITH
            The value of TargetString must appear at the end of the specified part of the web request.

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

    :returns:
    Create a ByteMatchSet. For more information, see  CreateByteMatchSet .
    Use  GetChangeToken to get the change token that you provide in the ChangeToken parameter of an UpdateByteMatchSet request.
    Submit an UpdateByteMatchSet request to specify the part of the request that you want AWS WAF to inspect (for example, the header or the URI) and the value that you want AWS WAF to watch for.

    """
    pass


def defaultPage(portal, objectId):
    """ Define or packages catalog as default page"""
    portal.manage_changeProperties(default_page=objectId)


def get_fmt_results(results, limit=5, sep='::', fmt=None):
    """
    Return a list of formatted strings representation on a result dictionary.
    The elements of the key are divided by a separator string. The result is
    appended after the key between parentheses. Apply a format transformation
    to odd elements of the key if a fmt parameter is passed.
    """
    result_list = []
    for key in sorted(results, key=lambda x: results[x], reverse=True):
        if len(result_list) >= limit and results[key] <= 1:
            break
        if fmt is not None:
            fmtkey = []
            for i in range(len(key)):
                if i % 2 == 1:
                    fmtkey.append(fmt.format(key[i]))
                else:
                    fmtkey.append(key[i])
            result_list.append(u'{0}({1})'.format(sep.join(fmtkey), results
                [key]))
        else:
            result_list.append(u'{0}({1})'.format(sep.join(key), results[key]))
    else:
        return result_list
    if fmt is not None:
        result_list.append(fmt.format(u'[%d more skipped]' % (len(results) -
            len(result_list))))
    else:
        result_list.append(u'[%d more skipped]' % (len(results) - len(
            result_list)))
    return result_list


def clamp(x, a, b):
    """
    Clamps a value x between a minimum a and a maximum b
    :param x: The value to clamp
    :param a: The minimum
    :param b: The maximum
    :return: The clamped value
    """
    return max(a, min(x, b))


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

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

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


def __instancecheck__(cls, instance=None):
    """ Make elements of super classes to be instances of this class.
        """
    icls = type(instance)
    return cls in icls.__mro__ or icls in cls.__mro__


def noop(val, *args, **kwargs):
    """A function does nothing.

    >>> noop(1)
    1
    """
    return val


def get_state(id):
    """ Returns the specified :py:class:`IState`
        """


def remove(header, pattern):
    """Remove the given rule from this mailing list's header match list.

        :param header: The email header part of the rule to be removed.
        :type header: string
        :param pattern: The regular expression part of the rule to be removed.
        :type pattern: string
        :raises ValueError: if the header does not exist in the list of
            header matches.
        """


@classmethod
def literally_compare(cls, local, upstream):
    """
        Compares the given versions, literally.

        :param str local:
            The local version converted
            by :py:func:`~PyFunceble.abstracts.package.split_versions`.

        :param str upstream:
            The upstream version converted
            by :py:func:`~PyFunceble.abstracts.package.split_versions`.

        :return:
            - :code:`True`: local == upstream
            - :code:`False`: local != upstream
        :rtype: bool
        """
    return local == upstream


def get_supported_libraries():
    """
    Get list of supported libraries for the parser.

    :rtype: list
    """
    return ['oled', 'lcd', 'led_matrix', 'emulator']


def insert_offset():
    """Automatically offset nodes on insertion

    """
    pass


def remove_bold(s):
    """
    Unescape HTML characters

    """
    s = s.replace('<b', '<b')
    return s


def celsius_to_fahrenheit(celsius: float, interval: bool=False) ->float:
    """Convert a temperature in Celsius to Fahrenheit."""
    if interval:
        return celsius * 1.8
    return celsius * 1.8 + 32.0


@staticmethod
def _get_data_multiplier(solution, dmu_code, category):
    """ Helper method that is used for writing weighted data
            to a given output.

            Args:
                solution (Solution): solution.
                dmu_code (str): DMU code.
                category (str): category name.

            Returns:
                int: a scale value to scale weights.
        """
    return solution._input_data.coefficients[dmu_code, category]


def explode(df, column, sep='|', keep=False):
    """
    Split the values of a column and expand so the new DataFrame has one value per row.
    Filters rows where the column is missing.

    :param df: pandas.DataFrame - dataframe with a column to split and expand
    :param column: str - the column to split and expand
    :param sep: str - the string used to split the column's values
    :param keep: bool -whether to retain the presplit value as it's own row
    :return: pandas.DataFrame - dataframe with the same columns as `df`.
    """
    indexes = list()
    new_values = list()
    df = df.dropna(subset=[column])
    for i, presplit in enumerate(df[column].astype(str)):
        values = presplit.split(sep)
        if keep and len(values) > 1:
            indexes.append(i)
            new_values.append(presplit)
        for value in values:
            indexes.append(i)
            new_values.append(value)
    new_df = df.iloc[(indexes), :].copy()
    new_df[column] = new_values
    return new_df


def provider_parser(subparser):
    """Specify arguments for AWS Route 53 Lexicon Provider."""
    subparser.add_argument('--auth-access-key', help=
        'specify ACCESS_KEY for authentication')
    subparser.add_argument('--auth-access-secret', help=
        'specify ACCESS_SECRET for authentication')
    subparser.add_argument('--private-zone', help=
        'indicates what kind of hosted zone to use. If true, use only private zones. If false, use only public zones'
        )
    subparser.add_argument('--auth-username', help=
        'alternative way to specify the ACCESS_KEY for authentication')
    subparser.add_argument('--auth-token', help=
        'alternative way to specify the ACCESS_SECRET for authentication')


def psi_Ca_CO3_Cl_HMW84(T, P):
    """c-a-a': calcium carbonate chloride [HMW84]."""
    psi = 0.0
    valid = T == 298.15
    return psi, valid


@classmethod
def _add_positional_arguments(cls, parser):
    """
        Add positional arguments for the apply method to parser.
        """
    pass


def extract_prime_power(a, p):
    """
    Return s, t such that  a = p**s * t,  t % p = 0
    """
    s = 0
    if p > 2:
        while a and a % p == 0:
            s += 1
            a //= p
    elif p == 2:
        while a and a & 1 == 0:
            s += 1
            a >>= 1
    else:
        raise ValueError('Number %d is not a prime (is smaller than 2)' % p)
    return s, a


@classmethod
def is_activity_type(cls, assignment_name):
    """Given the name of an activity, determines
        whether it is an instance of this unit type"""
    return cls.regex.search(assignment_name.strip().lower())


def iter_length(iter):
    """
	>>> iter_length(iter([1,2,3]))
	3
	>>> iter_length(iter([]))
	0
	"""
    n = 0
    try:
        while True:
            next(iter)
            n += 1
    except StopIteration:
        return n


def isSuccess(status):
    """
    Checks if the status provided is a success status.

    @param status: integer
        The status code to check if is for a successful operation.
    @return: boolean
        True if the status is a success status, False otherwise.
    """
    assert isinstance(status, int), 'Invalid status %s' % status
    return status / 100 == 2


def to_timestamp(value):
    """
    Convert datetime to a timestamp string MediaWiki would understand.
    :type value: datetime
    :rtype str
    """
    if value.tzinfo is not None and value.tzinfo.utcoffset(value):
        raise ValueError('datetime value has a non-UTC timezone')
    return value.strftime('%Y-%m-%dT%H:%M:%SZ')


def __call__(cls, *args, **kwds):
    """Instantiate cls after preprocessing its token definitions."""
    if '_tokens' not in cls.__dict__:
        cls._all_tokens = {}
        cls._tmpname = 0
        if hasattr(cls, 'token_variants') and cls.token_variants:
            pass
        else:
            cls._tokens = cls.process_tokendef('', cls.get_tokendefs())
    return type.__call__(cls, *args, **kwds)


@staticmethod
def protected_attr(attr):
    """Primitive, but check to see if it startswith _"""
    return attr.startswith('_')


def get_species_match_details(matches, refseq_species_info):
    """
    use pandas to merge best matches  with ref species info and return the merged data frame
    """
    best_match_species_df = matches.merge(refseq_species_info, on=['filename'])
    return best_match_species_df


def ether_to_gwei(ether):
    """
    Convert ether to Gwei
    """
    return int(ether * 10 ** 9)


def confusion_matrix(classify=lambda document: False, documents=[(None, False)]
    ):
    """ Returns the performance of a binary classification task (i.e., predicts True or False)
        as a tuple of (TP, TN, FP, FN):
        - TP: true positives  = correct hits,
        - TN: true negatives  = correct rejections,
        - FP: false positives = false alarm (= type I error),
        - FN: false negatives = misses (= type II error).
        The given classify() function returns True or False for a document.
        The list of documents contains (document, bool)-tuples for testing,
        where True means a document that should be identified as True by classify().
    """
    TN = TP = FN = FP = 0
    for document, b1 in documents:
        b2 = classify(document)
        if b1 and b2:
            TP += 1
        elif not b1 and not b2:
            TN += 1
        elif not b1 and b2:
            FP += 1
        elif b1 and not b2:
            FN += 1
    return TP, TN, FP, FN


def identity(a):
    """Get the same output as the input."""
    return a


def _call_with_frames_removed(func, *args, **kwds):
    """
    remove_importlib_frames in import.c will always remove sequences
    of importlib frames that end with a call to this function
    Use it instead of a normal call in places where including the importlib
    frames introduces unwanted noise into the traceback (e.g. when executing
    module code)
    """
    return func(*args, **kwds)


def getDelayedCalls():
    """
        Retrieve all currently scheduled delayed calls.

        @return: A tuple of all L{IDelayedCall} providers representing all
                 currently scheduled calls. This is everything that has been
                 returned by C{callLater} but not yet called or canceled.
        """


def readb(path):
    """Read a binary file.

    Args:
        path (str): Full path to file

    Returns:
        File bytes
    """
    with open(path, 'rb') as handle:
        return handle.read()


def parse_proxy(proxy_str):
    """Parses proxy address user:pass@host:port into a dict suitable for httplib2"""
    proxy_dict = {}
    if proxy_str is None:
        return
    if '@' in proxy_str:
        user_pass, host_port = proxy_str.split('@')
    else:
        user_pass, host_port = '', proxy_str
    if ':' in host_port:
        host, port = host_port.split(':')
        proxy_dict['proxy_host'], proxy_dict['proxy_port'] = host, int(port)
    if ':' in user_pass:
        proxy_dict['proxy_user'], proxy_dict['proxy_pass'] = user_pass.split(
            ':')
    return proxy_dict


def indent(lines, amount=2, char=' '):
    """Indent a string.

    Prepends whitespace to every line in the passed string. (Lines are
    separated by newline characters.)

    Args:
        lines (str): The string to indent.

    Keyword Args:
        amount (int): The number of columns to indent by.
        char (str): The character to to use as the indentation.

    Returns:
        str: The indented string.

    Example:
        >>> print(indent('line1\\nline2', char='*'))
        **line1
        **line2
    """
    lines = str(lines)
    padding = amount * char
    return padding + ('\n' + padding).join(lines.split('\n'))


def Test(sentence='Default sentence'):
    """ Print sentence to screen - Test module activation

	Parameters
	----------
	sentence :	str
		input sentence

	Returns
	-------
	None

	Returns
	-------
	None

	Reference
	---------
	None

	Examples
	--------
	>>> import magnelPy.ML as ML
	>>> ML.regression.Test()
	Default sentence
 	>>> ML.regression.Test("Another test")
 	Another test
	"""
    print(sentence)


def validar_id(valor):
    """ VALIDACIÓN DE CAMPO ID.

    Retorna True o False dependiendo si el campo enviado como parámetro es el
    id, esto se realiza para no mostrar en el reporte el id o clave primaria.

    Parámetros:
    valor -- nombre de campo a evaluar.

    """
    if valor is not 'id':
        return True
    return False


def do_slice(value, slices, fill_with=None):
    """Slice an iterator and return a list of lists containing
    those items. Useful if you want to create a div containing
    three ul tags that represent columns:

    .. sourcecode:: html+jinja

          {%- for column in items|slice(3) %}

            {%- for item in column %}

{{ item }}

            {%- endfor %}

          {%- endfor %}

    If you pass it a second argument it's used to fill missing
    values on the last iteration.
    """
    seq = list(value)
    length = len(seq)
    items_per_slice = length // slices
    slices_with_extra = length % slices
    offset = 0
    for slice_number in range(slices):
        start = offset + slice_number * items_per_slice
        if slice_number < slices_with_extra:
            offset += 1
        end = offset + (slice_number + 1) * items_per_slice
        tmp = seq[start:end]
        if fill_with is not None and slice_number >= slices_with_extra:
            tmp.append(fill_with)
        yield tmp


def _factors_count(idadf, columnlist, valuelist=None):
    """
    Count non-missing values for all columns in a list (valuelist) over the
    IdaDataFrame grouped by a list of columns(columnlist).

    Parameters
    ----------
    columnlist : list
        List of column names that exist in self.
    valuelist : list
        List of column names that exist in self.

     Notes
     -----
     The function assumes the following:

        * The columns given as parameter exists in the IdaDataframe
        * The parameter columnlist is a optional and is a list
        * Columns are referenced by their own name (character string)

    Returns
    -------
        DataFrame
    """
    column_string = '"' + '", "'.join(columnlist) + '"'
    name = idadf.internal_state.current_state
    if valuelist is None:
        query = (
            'SELECT %s, COUNT(*) as COUNT FROM %s GROUP BY %s ORDER BY %s, COUNT ASC'
             % (column_string, name, column_string, column_string))
    else:
        agg_list = []
        for value in valuelist:
            query = 'COUNT("%s") as "%s"' % (value, value)
            agg_list.append(query)
        agg_string = ', '.join(agg_list)
        value_string = '"' + '", "'.join(valuelist) + '"'
        query = 'SELECT %s,%s FROM %s GROUP BY %s ORDER BY %s,%s ASC' % (
            column_string, agg_string, name, column_string, column_string,
            value_string)
    return idadf.ida_query(query)


def _pullbundle2extraprepare(pullop, kwargs):
    """hook function so that extensions can extend the getbundle call"""


def master_params(optimizer):
    """
    Generator expression that iterates over the params owned by ``optimizer``.
    Args:
        optimizer: An optimizer previously returned from ``amp.initialize``.
    """
    for group in optimizer.param_groups:
        for p in group['params']:
            yield p


@staticmethod
def read_serial_numbers_from_file(file='serial_numbers.txt') ->list:
    """ Get the list of all Tello serials numbers from the given file.
        Blank lines and lines that start with "#" will be skipped, so you can add labels/notes about which drone is which

        :param file: The file containing the list of serial numbers; default: 'serial_numbers.txt'
        """
    serials = list()
    with open(file, 'r') as serial_numbers:
        for serial_number in serial_numbers:
            serial_number = ''.join(serial_number.split())
            if serial_number == '' or serial_number[0] == '#':
                continue
            serials.append(serial_number)
    return serials


def position_is_escaped(string, position=None):
    """
    Checks whether a char at a specific position of the string is preceded by
    an odd number of backslashes.

    :param string:   Arbitrary string
    :param position: Position of character in string that should be checked
    :return:         True if the character is escaped, False otherwise
    """
    escapes_uneven = False
    for i in range(len(string[:position]) - 1, -1, -1):
        if string[i] == '\\':
            escapes_uneven = not escapes_uneven
        else:
            break
    return escapes_uneven


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

        :param str val:
        :rtype: MembersGetInfoItem
        """
    return cls('id_not_found', val)


def get_attribs(args):
    """ Get a list of attributes to set on a client when adding/updating it """
    attr_d = {}
    for i in args[2:]:
        attr, val = i.split('=', 1)
        if attr not in ['profile', 'uuid', 'password', 'floating', 'secure',
            'address', 'auth']:
            print('Attribute %s unknown' % attr)
            raise SystemExit(1)
        attr_d[attr] = val
    return attr_d


def banners():
    """
        Get contained banners
        """


def centimeters(pin):
    """Return distance in cm from sensor

    Parameters:
      pin (int):     Analog pin to read from (e.g. 1 for A1)

    Returns:         Calculated distance in cm
    """
    from . import arduino
    reading = float(arduino().analogRead(pin + 1 + 14))
    distance = 27.726 * (reading * 5 / 1024) ** -1.2045
    return distance


def name_default_projector(apps, schema_editor):
    """
    Set the name of the default projector to 'Defaultprojector'
    """
    Projector = apps.get_model('core', 'Projector')
    Projector.objects.filter(pk=1).update(name='Default projector')


def dist_to_conc(dist, r_min, r_max, rule='trapezoid'):
    """ Converts a swath of a size distribution function to an actual number
    concentration.

    Aerosol size distributions are typically reported by normalizing the
    number density by the size of the aerosol. However, it's sometimes more
    convenient to simply have a histogram of representing several aerosol
    size ranges (bins) and the actual number concentration one should expect
    in those bins. To accomplish this, one only needs to integrate the size
    distribution function over the range spanned by the bin.

    Parameters
    ----------
    dist : object implementing a ``pdf()`` method
        the representation of the size distribution
    r_min, r_max : float
        the lower and upper bounds of the size bin, in the native units of ``dist``
    rule : {'trapezoid', 'simpson', 'other'} (default='trapezoid')
        rule used to integrate the size distribution

    Returns
    -------
    float
        The number concentration of aerosol particles the given bin.

    Examples
    --------

    >>> dist = Lognorm(mu=0.015, sigma=1.6, N=850.0)
    >>> r_min, r_max = 0.00326456461236 0.00335634401598
    >>> dist_to_conc(dist, r_min, r_max)
    0.114256210943

    """
    pdf = dist.pdf
    width = r_max - r_min
    if rule == 'trapezoid':
        return width * 0.5 * (pdf(r_max) + pdf(r_min))
    elif rule == 'simpson':
        return width / 6.0 * (pdf(r_max) + pdf(r_min) + 4.0 * pdf(0.5 * (
            r_max + r_min)))
    else:
        return width * pdf(0.5 * (r_max + r_min))


@staticmethod
def calculate_flag(sfw: bool=True, nsfp: bool=False, nsfw: bool=False, nsfl:
    bool=False) ->int:
    """
        Used to calculate flags for the post requests

        sfw = 1
        nsfw = 2
        sfw + nsfw = 3
        nsfl = 4
        nsfw + nsfl = 6
        sfw + nsfw + nsfl = 7
        nsfp = 8
        sfw + nsfp = 9
        sfw + nsfp + nsfw = 11
        sfw + nsfp + nsfw + nsfl = 15

        Parameters
        ----------
        :param sfw: bool
        :param nsfp: bool
        :param nsfw: bool
        :param nsfl: bool
        :return: Calculated flag for requests
        """
    flag = 0
    flag += 1 if sfw else 0
    flag += 2 if nsfw else 0
    flag += 4 if nsfl else 0
    flag += 8 if nsfp and sfw else 0
    return flag


def instance_name(instance):
    """Shortcut to get instance name."""
    return getattr(instance, 'OS-EXT-SRV-ATTR:instance_name', None)


def get_p2p_scatter_2praw(model):
    """
    Get ratio of variability (sum of squared differences of consecutive
    values) of folded and unfolded models.
    """
    return model['scatter_2praw']


def theta_Cl_OH_HMW84(T, P):
    """a-a': chloride hydroxide [HMW84]."""
    theta = -0.05
    valid = T == 298.15
    return theta, valid


def factory(container, name, factory):
    """Test whether objects provided by the factory are acceptable

        Return a boolean value.
        """


@classmethod
def _from_et(cls, root, parent):
    """
        Create a :class:`Gate` from a :code:`gate` element.

        :param root: The element tree tree to parse.
        :param parent: :class:`EagleFilePart` that should hold the resulting :class:`EagleFilePart`
        :rtype: :class:`Gate`
        """
    n = cls()
    n._init_from_et(root, parent)
    return n


def calculate_precision_recall_F_metrics(algorithm_number, real_number,
    correct_number):
    """
    Result: (precision, recall, F)
    """
    if algorithm_number == 0:
        precision = 0
    else:
        precision = float(correct_number) / algorithm_number
    if real_number == correct_number:
        recall = 1
    else:
        recall = float(correct_number) / real_number
    return precision, recall, 2 * float(correct_number) / (real_number +
        algorithm_number)


def path2Extension(path):
    """Answers the file extension of path.

    >>> path2Extension('/xxx/yyy/zzz/Agency_FB-Compressed.ufo')
    'ufo'
    >>> path2Extension('/xxx/yyy/zzz/Agency_FB-Compressed.TTF')
    'ttf'
    """
    return path.split('.')[-1].lower()


@classmethod
def search_count(cls, domain):
    """
        Return the number of records that match the domain.
        """
    res = cls.search(domain, order=[], count=True)
    if isinstance(res, list):
        return len(res)
    return res


def set_db_application_prefix(prefix, sep=None):
    """Set the global app prefix and separator."""
    global _APPLICATION_PREFIX, _APPLICATION_SEP
    _APPLICATION_PREFIX = prefix
    if sep is not None:
        _APPLICATION_SEP = sep


def list_notebook_param(args, library_db, current_scene_db):
    """list all parameters in the current notebook"""
    from src.praxxis.sqlite import sqlite_parameter
    from src.praxxis.notebook import notebook
    from src.praxxis.display import display_param
    name = args.notebook
    notebook_data = notebook.get_notebook(current_scene_db, library_db, name)
    sqlite_parameter.get_all_param(current_scene_db)
    parameters = sqlite_parameter.list_notebook_param(library_db,
        notebook_data[1], notebook_data[2])
    display_param.display_view_param(parameters, sqlite_parameter.
        get_all_param(current_scene_db))
    return parameters


def _get_type(s):
    """Reads a string to see if it can be converted into int or float.

    Parameters
    ----------
    s : str
        A string to be parsed.

    Returns
    -------
    str, int or float
        The parsed value.
    """
    try:
        float(s)
        if '.' not in s:
            return 'i'
        else:
            return 'f'
    except ValueError:
        return 's'


def get_input_params(radl):
    """
    Search for input parameters, ask the user for the values and replace them in the RADL
    """
    pos = 0
    while pos != -1:
        pos = radl.find('@input.', pos)
        if pos != -1:
            pos = pos + 7
            pos_fin = radl.find('@', pos)
            param_name = radl[pos:pos_fin]
            valor = input('Specify parameter ' + param_name + ': ')
            radl = radl.replace('@input.' + param_name + '@', valor)
    return radl