"""
    FD-MobileNet for ImageNet-1K, implemented in TensorFlow.
    Original paper: 'FD-MobileNet: Improved MobileNet with A Fast Downsampling Strategy,'
    http://example.com.
"""

__all__ = ['fdmobilenet_w1', 'fdmobilenet_w3d4', 'fdmobilenet_wd2', 'fdmobilenet_wd4', 'get_fdmobilenet']

import os
import tensorflow as tf
from .mobilenet import MobileNet

def get_fdmobilenet(width_scale,
                    model_name=None,
                    pretrained=False,
                    root=os.path.join("~", ".tensorflow", "models"),
                    **kwargs):
    """
    Create FD-MobileNet model with specific parameters.

    Parameters:
    ----------
    width_scale : float
        Scale factor for width of layers.
    model_name : str or None, default None
        Model name for loading pretrained model.
    pretrained : bool, default False
        Whether to load the pretrained weights for model.
    root : str, default '~/.tensorflow/models'
        Location for keeping the model parameters.
    """
    channels = [[32], [64], [128, 128], [256, 256], [512, 512, 512, 512, 512, 1024]]
    first_stage_stride = True

    if width_scale != 1.0:
        channels = [[int(cij * width_scale) for cij in ci] for ci in channels]

    net = MobileNet(
        channels=channels,
        first_stage_stride=first_stage_stride,
        **kwargs)

    if pretrained:
        if (model_name is None) or (not model_name):
            raise ValueError("Parameter `model_name` should be properly initialized for loading pretrained model.")
        from .model_store import get_model_file
        in_channels = kwargs["in_channels"] if ("in_channels" in kwargs) else 3
        input_shape = (1,) + (in_channels,) + net.in_size if net.data_format == "channels_first" else\
            (1,) + net.in_size + (in_channels,)
        net.build(input_shape=input_shape)
        net.load_weights(
            filepath=get_model_file(
                model_name=model_name,
                local_model_store_dir_path=root))

    return net

def fdmobilenet_w1(**kwargs):
    """
    FD-MobileNet 1.0x model from 'FD-MobileNet: Improved MobileNet with A Fast Downsampling Strategy,'
    https://arxiv.org/abs/1802.03750.

    Parameters:
    ----------
    pretrained : bool, default False
        Whether to load the pretrained weights for model.
    root : str, default '~/.tensorflow/models'
        Location for keeping the model parameters.
    """
    return get_fdmobilenet(width_scale=1.0, model_name="fdmobilenet_w1", **kwargs)

def fdmobilenet_w3d4(**kwargs):
    """
    FD-MobileNet 0.75x model from 'FD-MobileNet: Improved MobileNet with A Fast Downsampling Strategy,'
    https://arxiv.org/abs/1802.03750.

    Parameters:
    ----------
    pretrained : bool, default False
        Whether to load the pretrained weights for model.
    root : str, default '~/.tensorflow/models'
        Location for keeping the model parameters.
    """
    return get_fdmobilenet(width_scale=0.75, model_name="fdmobilenet_w3d4", **kwargs)

def fdmobilenet_wd2(**kwargs):
    """
    FD-MobileNet 0.5x model from 'FD-MobileNet: Improved MobileNet with A Fast Downsampling Strategy,'
    https://arxiv.org/abs/1802.03750.

    Parameters:
    ----------
    pretrained : bool, default False
        Whether to load the pretrained weights for model.
    root : str, default '~/.tensorflow/models'
        Location for keeping the model parameters.
    """
    return get_fdmobilenet(width_scale=0.5, model_name="fdmobilenet_wd2", **kwargs)

def fdmobilenet_wd4(**kwargs):
    """
    FD-MobileNet 0.25x model from 'FD-MobileNet: Improved MobileNet with A Fast Downsampling Strategy,'
    https://arxiv.org/abs/1802.03750.

    Parameters:
    ----------
    pretrained : bool, default False
        Whether to load the pretrained weights for model.
    root : str, default '~/.tensorflow/models'
        Location for keeping the model parameters.
    """
    return get_fdmobilenet(width_scale=0.25, model_name="fdmobilenet_wd4", **kwargs)

import numpy as np
    import tensorflow.keras.backend as K

    pretrained = False

    models = [
        fdmobilenet_w1,
        fdmobilenet_w3d4,
        fdmobilenet_wd2,
        fdmobilenet_wd4,
    ]

    for model in models:

        net = model(pretrained=pretrained)

        batch = 14
        x = tf.random.normal((batch, 224, 224, 3))
        y = net(x)
        assert (tuple(y.shape.as_list()) == (batch, 1000))

        weight_count = sum([np.prod(K.get_value(w).shape) for w in net.trainable_weights])
        print("m={}, {}".format(model.__name__, weight_count))
        assert (model != fdmobilenet_w1 or weight_count == 2901288)
        assert (model != fdmobilenet_w3d4 or weight_count == 1833304)
        assert (model != fdmobilenet_wd2 or weight_count == 993928)
        assert (model != fdmobilenet_wd4 or weight_count == 383160)

if __name__ == "__main__":
    _test()


"""
    FD-MobileNet 0.5x model from 'FD-MobileNet: Improved MobileNet with A Fast Downsampling Strategy,'
    https://arxiv.org/abs/1802.03750.

    Parameters:
    ----------
    pretrained : bool, default False
        Whether to load the pretrained weights for model.
    root : str, default '~/.tensorflow/models'
        Location for keeping the model parameters.
    """
    return get_fdmobilenet(width_scale=0.5, model_name="fdmobilenet_wd2", **kwargs)

"""
    FD-MobileNet for ImageNet-1K, implemented in TensorFlow.
    Original paper: 'FD-MobileNet: Improved MobileNet with A Fast Downsampling Strategy,'
    http://example.com.
"""

__all__ = ['fdmobilenet_w1', 'fdmobilenet_w3d4', 'fdmobilenet_wd2', 'fdmobilenet_wd4', 'get_fdmobilenet']

import os
import tensorflow as tf
from .mobilenet import MobileNet

def get_fdmobilenet(width_scale,
                    model_name=None,
                    pretrained=False,
                    root=os.path.join("~", ".tensorflow", "models"),
                    **kwargs):
    """
    Create FD-MobileNet model with specific parameters.

    Parameters:
    ----------
    width_scale : float
        Scale factor for width of layers.
    model_name : str or None, default None
        Model name for loading pretrained model.
    pretrained : bool, default False
        Whether to load the pretrained weights for model.
    root : str, default '~/.tensorflow/models'
        Location for keeping the model parameters.
    """
    channels = [[32], [64], [128, 128], [256, 256], [512, 512, 512, 512, 512, 1024]]
    first_stage_stride = True

    if width_scale != 1.0:
        channels = [[int(cij * width_scale) for cij in ci] for ci in channels]

    net = MobileNet(
        channels=channels,
        first_stage_stride=first_stage_stride,
        **kwargs)

    if pretrained:
        if (model_name is None) or (not model_name):
            raise ValueError("Parameter `model_name` should be properly initialized for loading pretrained model.")
        from .model_store import get_model_file
        in_channels = kwargs["in_channels"] if ("in_channels" in kwargs) else 3
        input_shape = (1,) + (in_channels,) + net.in_size if net.data_format == "channels_first" else\
            (1,) + net.in_size + (in_channels,)
        net.build(input_shape=input_shape)
        net.load_weights(
            filepath=get_model_file(
                model_name=model_name,
                local_model_store_dir_path=root))

    return net

def fdmobilenet_w1(**kwargs):
    """
    FD-MobileNet 1.0x model from 'FD-MobileNet: Improved MobileNet with A Fast Downsampling Strategy,'
    https://arxiv.org/abs/1802.03750.

    Parameters:
    ----------
    pretrained : bool, default False
        Whether to load the pretrained weights for model.
    root : str, default '~/.tensorflow/models'
        Location for keeping the model parameters.
    """
    return get_fdmobilenet(width_scale=1.0, model_name="fdmobilenet_w1", **kwargs)

def fdmobilenet_w3d4(**kwargs):
    """
    FD-MobileNet 0.75x model from 'FD-MobileNet: Improved MobileNet with A Fast Downsampling Strategy,'
    https://arxiv.org/abs/1802.03750.

    Parameters:
    ----------
    pretrained : bool, default False
        Whether to load the pretrained weights for model.
    root : str, default '~/.tensorflow/models'
        Location for keeping the model parameters.
    """
    return get_fdmobilenet(width_scale=0.75, model_name="fdmobilenet_w3d4", **kwargs)

def fdmobilenet_wd2(**kwargs):

def fdmobilenet_wd4(**kwargs):
    """
    FD-MobileNet 0.25x model from 'FD-MobileNet: Improved MobileNet with A Fast Downsampling Strategy,'
    https://arxiv.org/abs/1802.03750.

    Parameters:
    ----------
    pretrained : bool, default False
        Whether to load the pretrained weights for model.
    root : str, default '~/.tensorflow/models'
        Location for keeping the model parameters.
    """
    return get_fdmobilenet(width_scale=0.25, model_name="fdmobilenet_wd4", **kwargs)

def _test():
    import numpy as np
    import tensorflow.keras.backend as K

    pretrained = False

    models = [
        fdmobilenet_w1,
        fdmobilenet_w3d4,
        fdmobilenet_wd2,
        fdmobilenet_wd4,
    ]

    for model in models:

        net = model(pretrained=pretrained)

        batch = 14
        x = tf.random.normal((batch, 224, 224, 3))
        y = net(x)
        assert (tuple(y.shape.as_list()) == (batch, 1000))

        weight_count = sum([np.prod(K.get_value(w).shape) for w in net.trainable_weights])
        print("m={}, {}".format(model.__name__, weight_count))
        assert (model != fdmobilenet_w1 or weight_count == 2901288)
        assert (model != fdmobilenet_w3d4 or weight_count == 1833304)
        assert (model != fdmobilenet_wd2 or weight_count == 993928)
        assert (model != fdmobilenet_wd4 or weight_count == 383160)

if __name__ == "__main__":
    _test()


"""
    FD-MobileNet for ImageNet-1K, implemented in TensorFlow.
    Original paper: 'FD-MobileNet: Improved MobileNet with A Fast Downsampling Strategy,'
    http://example.com.
"""

__all__ = ['fdmobilenet_w1', 'fdmobilenet_w3d4', 'fdmobilenet_wd2', 'fdmobilenet_wd4', 'get_fdmobilenet']

import os
import tensorflow as tf
from .mobilenet import MobileNet

def get_fdmobilenet(width_scale,
                    model_name=None,
                    pretrained=False,
                    root=os.path.join("~", ".tensorflow", "models"),
                    **kwargs):
    """
    Create FD-MobileNet model with specific parameters.

    Parameters:
    ----------
    width_scale : float
        Scale factor for width of layers.
    model_name : str or None, default None
        Model name for loading pretrained model.
    pretrained : bool, default False
        Whether to load the pretrained weights for model.
    root : str, default '~/.tensorflow/models'
        Location for keeping the model parameters.
    """
    channels = [[32], [64], [128, 128], [256, 256], [512, 512, 512, 512,

    first_stage_stride = True

    if width_scale != 1.0:
        channels = [[int(cij * width_scale) for cij in ci] for ci in channels]

    net = MobileNet(
        channels=channels,
        first_stage_stride=first_stage_stride,
        **kwargs)

    if pretrained:
        if (model_name is None) or (not model_name):
            raise ValueError("Parameter `model_name` should be properly initialized for loading pretrained model.")
        from .model_store import get_model_file
        in_channels = kwargs["in_channels"] if ("in_channels" in kwargs) else 3
        input_shape = (1,) + (in_channels,) + net.in_size if net.data_format == "channels_first" else\
            (1,) + net.in_size + (in_channels,)
        net.build(input_shape=input_shape)
        net.load_weights(
            filepath=get_model_file(
                model_name=model_name,
                local_model_store_dir_path=root))

    return net

def fdmobilenet_w1(**kwargs):
    """
    FD-MobileNet 1.0x model from 'FD-MobileNet: Improved MobileNet with A Fast Downsampling Strategy,'
    https://arxiv.org/abs/1802.03750.

    Parameters:
    ----------
    pretrained : bool, default False
        Whether to load the pretrained weights for model.
    root : str, default '~/.tensorflow/models'
        Location for keeping the model parameters.
    """
    return get_fdmobilenet(width_scale=1.0, model_name="fdmobilenet_w1", **kwargs)

def fdmobilenet_w3d4(**kwargs):
    """
    FD-MobileNet 0.75x model from 'FD-MobileNet: Improved MobileNet with A Fast Downsampling Strategy,'
    https://arxiv.org/abs/1802.03750.

    Parameters:
    ----------
    pretrained : bool, default False
        Whether to load the pretrained weights for model.
    root : str, default '~/.tensorflow/models'
        Location for keeping the model parameters.
    """
    return get_fdmobilenet(width_scale=0.75, model_name="fdmobilenet_w3d4", **kwargs)

def fdmobilenet_wd2(**kwargs):
    """
    FD-MobileNet 0.5x model from 'FD-MobileNet: Improved MobileNet with A Fast Downsampling Strategy,'
    https://arxiv.org/abs/1802.03750.

    Parameters:
    ----------
    pretrained : bool, default False
        Whether to load the pretrained weights for model.
    root : str, default '~/.tensorflow/models'
        Location for keeping the model parameters.
    """
    return get_fdmobilenet(width_scale=0.5, model_name="fdmobilenet_wd2", **kwargs)

def fdmobilenet_wd4(**kwargs):
    """
    FD-MobileNet 0.25x model from 'FD-MobileNet: Improved MobileNet with A Fast Downsampling Strategy,'
    https://arxiv.org/abs/1802.03750.

    Parameters:
    ----------
    pretrained : bool, default False
        Whether to load the pretrained weights for model.
    root : str, default '~/.tensorflow/models'
        Location for keeping the model parameters.
    """
    return get_fdmobilenet(width_scale=0.25, model_name="fdmobilenet_wd4", **kwargs)

def _test():
    import numpy as np
    import tensorflow.keras.backend as K

    pretrained = False

    models = [
        fdmobilenet_w1,
        fdmobilenet_w3d4,
        fdmobilenet_wd2,
        fdmobilenet_wd4,
    ]

    for model in models:

        net = model(pretrained=pretrained)

        batch = 14
        x = tf.random.normal((batch, 224, 224, 3))
        y = net(x)
        assert (tuple(y.shape.as_list()) == (batch, 1000))

        weight_count = sum([np.prod(K.get_value(w).shape) for w in net.trainable_weights])
        print("m={}, {}".format(model.__name__, weight_count))
        assert (model != fdmobilenet_w1 or weight_count == 2901288)
        assert (model != fdmobilenet_w3d4 or weight_count == 1833304)
        assert (model != fdmobilenet_wd2 or weight_count == 993928)
        assert (model != fdmobilenet_wd4 or weight_count == 383160)

if __name__ == "__main__":
    _test()


return get_fdmobilenet(width_scale=0.25, model_name="fdmobilenet_wd4", **kwargs)

"""
    FD-MobileNet for ImageNet-1K, implemented in TensorFlow.
    Original paper: 'FD-MobileNet: Improved MobileNet with A Fast Downsampling Strategy,'
    http://example.com.
"""

__all__ = ['fdmobilenet_w1', 'fdmobilenet_w3d4', 'fdmobilenet_wd2', 'fdmobilenet_wd4', 'get_fdmobilenet']

import os
import tensorflow as tf
from .mobilenet import MobileNet

def get_fdmobilenet(width_scale,
                    model_name=None,
                    pretrained=False,
                    root=os.path.join("~", ".tensorflow", "models"),
                    **kwargs):
    """
    Create FD-MobileNet model with specific parameters.

    Parameters:
    ----------
    width_scale : float
        Scale factor for width of layers.
    model_name : str or None, default None
        Model name for loading pretrained model.
    pretrained : bool, default False
        Whether to load the pretrained weights for model.
    root : str, default '~/.tensorflow/models'
        Location for keeping the model parameters.
    """
    channels = [[32], [64], [128, 128], [256, 256], [512, 512, 512, 512, 512, 1024]]
    first_stage_stride = True

    if width_scale != 1.0:
        channels = [[int(cij * width_scale) for cij in ci] for ci in channels]

    net = MobileNet(
        channels=channels,
        first_stage_stride=first_stage_stride,
        **kwargs)

    if pretrained:
        if (model_name is None) or (not model_name):
            raise ValueError("Parameter `model_name` should be properly initialized for loading pretrained model.")
        from .model_store import get_model_file
        in_channels = kwargs["in_channels"] if ("in_channels" in kwargs) else 3
        input_shape = (1,) + (in_channels,) + net.in_size if net.data_format == "channels_first" else\
            (1,) + net.in_size + (in_channels,)
        net.build(input_shape=input_shape)
        net.load_weights(
            filepath=get_model_file(
                model_name=model_name,
                local_model_store_dir_path=root))

    return net

def fdmobilenet_w1(**kwargs):
    """
    FD-MobileNet 1.0x model from 'FD-MobileNet: Improved MobileNet with A Fast Downsampling Strategy,'
    https://arxiv.org/abs/1802.03750.

    Parameters:
    ----------
    pretrained : bool, default False
        Whether to load the pretrained weights for model.
    root : str, default '~/.tensorflow/models'
        Location for keeping the model parameters.
    """
    return get_fdmobilenet(width_scale=1.0, model_name="fdmobilenet_w1", **kwargs)

def fdmobilenet_w3d4(**kwargs):
    """
    FD-MobileNet 0.75x model from 'FD-MobileNet: Improved MobileNet with A Fast Downsampling Strategy,'
    https://arxiv.org/abs/1802.03750.

    Parameters:
    ----------
    pretrained : bool, default False
        Whether to load the pretrained weights for model.
    root : str, default '~/.tensorflow/models'
        Location for keeping the model parameters.
    """
    return get_fdmobilenet(width_scale=0.75, model_name="fdmobilenet_w3d4", **kwargs)

def fdmobilenet_wd2(**kwargs):
    """
    FD-MobileNet 0.5x model from 'FD-MobileNet: Improved MobileNet with A Fast Downsampling Strategy,'
    https://arxiv.org/abs/1802.03750.

    Parameters:
    ----------
    pretrained : bool, default False
        Whether to load the pretrained weights for model.
    root : str, default '~/.tensorflow/models'
        Location for keeping the model parameters.
    """
    return get_fdmobilenet(width_scale=0.5, model_name="fdmobilenet_wd2", **kwargs)

def fdmobilenet_wd4(**kwargs):
    """
    FD-MobileNet 0.25x model from 'FD-MobileNet: Improved MobileNet with A Fast Downsampling Strategy,'
    https://arxiv.org/abs/1802.03750.

    Parameters:
    ----------
    pretrained : bool, default False
        Whether to load the pretrained weights for model.
    root : str, default '~/.tensorflow/models'
        Location for keeping the model parameters.
    """

def _test():
    import numpy as np
    import tensorflow.keras.backend as K

    pretrained = False

    models = [
        fdmobilenet_w1,
        fdmobilenet_w3d4,
        fdmobilenet_wd2,
        fdmobilenet_wd4,
    ]

    for model in models:

        net = model(pretrained=pretrained)

        batch = 14
        x = tf.random.normal((batch, 224, 224, 3))
        y = net(x)
        assert (tuple(y.shape.as_list()) == (batch, 1000))

        weight_count = sum([np.prod(K.get_value(w).shape) for w in net.trainable_weights])
        print("m={}, {}".format(model.__name__, weight_count))
        assert (model != fdmobilenet_w1 or weight_count == 2901288)
        assert (model != fdmobilenet_w3d4 or weight_count == 1833304)
        assert (model != fdmobilenet_wd2 or weight_count == 993928)
        assert (model != fdmobilenet_wd4 or weight_count == 383160)

if __name__ == "__main__":
    _test()


# Global Imports
import json
from collections import defaultdict

# Metaparser
from genie.metaparser import MetaParser

class SysFixconnectionSchema(MetaParser):

    schema = {}

class SysFixconnection(SysFixconnectionSchema):
    """ To F5 resource for /mgmt/tm/sys/fix-connection
    """

    cli_command = "/mgmt/tm/sys/fix-connection"

response = self.device.get(self.cli_command)

        response_json = response.json()

        if not response_json:
            return {}

        return response_json


response = self.device.get(self.cli_command)

        response_json = response.json()

        if not response_json:
            return {}

        return response_json

# Global Imports
import json
from collections import defaultdict

# Metaparser
from genie.metaparser import MetaParser

class SysFixconnectionSchema(MetaParser):

    schema = {}

class SysFixconnection(SysFixconnectionSchema):
    """ To F5 resource for /mgmt/tm/sys/fix-connection
    """

    cli_command = "/mgmt/tm/sys/fix-connection"

    def rest(self):


# Global Imports
import json
from collections import defaultdict

# Metaparser
from genie.metaparser import MetaParser

class SysFixconnectionSchema(MetaParser):

    schema = {}

class SysFixconnection(SysFixconnectionSchema):
    """ To F5 resource for /mgmt/tm/sys/fix-connection
    """

    cli_command = "/mgmt/tm/sys/fix-connection"

    def rest(self):

        response = se

        response_json = response.json()

        if not response_json:
            return {}

        return response_json


# [GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.34)]
# Embedded file name: type_Result.py
from types import *
import mcl.object.MclTime
RESULT_STATE_INITIAL = 1
RESULT_STATE_STARTED = 2
RESULT_STATE_STOPPED = 3
RESULT_STATE_LIST = 4
RESULT_PROCESS_FLAG_64_BIT = 1
RESULT_PROCESS_FLAG_32_BIT = 2

class Result:

    def __init__(self):
        self.__dict__['state'] = 0
        self.__dict__['processId'] = 0
        self.__dict__['parentProcessId'] = 0
        self.__dict__['flags'] = 0
        self.__dict__['createTime'] = mcl.object.MclTime.MclTime()
        self.__dict__['processorTime'] = mcl.object.MclTime.MclTime()
        self.__dict__['user'] = ''
        self.__dict__['displayLocation'] = ''
        self.__dict__['name'] = ''
        self.__dict__['executablePath'] = ''
        self.__dict__['description'] = ''

    def __getattr__(self, name):
        if name == 'state':
            return self.__dict__['state']
        if name == 'processId':
            return self.__dict__['processId']
        if name == 'parentProcessId':
            return self.__dict__['parentProcessId']
        if name == 'flags':
            return self.__dict__['flags']
        if name == 'createTime':
            return self.__dict__['createTime']
        if name == 'processorTime':
            return self.__dict__['processorTime']
        if name == 'user':
            return self.__dict__['user']
        if name == 'displayLocation':
            return self.__dict__['displayLocation']
        if name == 'name':
            return self.__dict__['name']
        if name == 'executablePath':
            return self.__dict__['executablePath']
        if name == 'description':
            return self.__dict__['description']
        raise AttributeError("Attribute '%s' not found" % name)

    def __setattr__(self, name, value):
        if name == 'state':
            self.__dict__['state'] = value
        elif name == 'processId':
            self.__dict__['processId'] = value
        elif name == 'parentProcessId':
            self.__dict__['parentProcessId'] = value
        elif name == 'flags':
            self.__dict__['flags'] = value
        elif name == 'createTime':
            self.__dict__['createTime'] = value
        elif name == 'processorTime':
            self.__dict__['processorTime'] = value
        elif name == 'user':
            self.__dict__['user'] = value
        elif name == 'displayLocation':
            self.__dict__['displayLocation'] = value
        elif name == 'name':
            self.__dict__['name'] = value
        elif name == 'executablePath':
            self.__dict__['executablePath'] = value
        elif name == 'description':
            self.__dict__['description'] = value
        else:
            raise AttributeError("Attribute '%s' not found" % name)

from mcl.object.Message import MarshalMessage
        submsg = MarshalMessage()
        submsg.AddU8(MSG_KEY_RESULT_STATE, self.__dict__['state'])
        submsg.AddU32(MSG_KEY_RESULT_PROCESS_ID, self.__dict__['processId'])
        submsg.AddU32(MSG_KEY_RESULT_PARENT_PROCESS_ID, self.__dict__['parentProcessId'])
        submsg.AddU32(MSG_KEY_RESULT_FLAGS, self.__dict__['flags'])
        submsg.AddTime(MSG_KEY_RESULT_CREATE_TIME, self.__dict__['createTime'])
        submsg.AddTime(MSG_KEY_RESULT_PROCESSOR_TIME, self.__dict__['processorTime'])
        submsg.AddStringUtf8(MSG_KEY_RESULT_USER, self.__dict__['user'])
        submsg.AddStringUtf8(MSG_KEY_RESULT_DISPLAY_LOCATION, self.__dict__['displayLocation'])
        submsg.AddStringUtf8(MSG_KEY_RESULT_NAME, self.__dict__['name'])
        submsg.AddStringUtf8(MSG_KEY_RESULT_EXECUTABLE_PATH, self.__dict__['executablePath'])
        submsg.AddStringUtf8(MSG_KEY_RESULT_DESCRIPTION, self.__dict__['description'])
        mmsg.AddMessage(MSG_KEY_RESULT, submsg)

    def Demarshal(self, dmsg, instance=-1):
        import mcl.object.Message
        msgData = dmsg.FindData(MSG_KEY_RESULT, mcl.object.Message.MSG_TYPE_MSG, instance)
        submsg = mcl.object.Message.DemarshalMessage(msgData)
        self.__dict__['state'] = submsg.FindU8(MSG_KEY_RESULT_STATE)
        self.__dict__['processId'] = submsg.FindU32(MSG_KEY_RESULT_PROCESS_ID)
        self.__dict__['parentProcessId'] = submsg.FindU32(MSG_KEY_RESULT_PARENT_PROCESS_ID)
        self.__dict__['flags'] = submsg.FindU32(MSG_KEY_RESULT_FLAGS)
        self.__dict__['createTime'] = submsg.FindTime(MSG_KEY_RESULT_CREATE_TIME)
        self.__dict__['processorTime'] = submsg.FindTime(MSG_KEY_RESULT_PROCESSOR_TIME)
        self.__dict__['user'] = submsg.FindString(MSG_KEY_RESULT_USER)
        self.__dict__['displayLocation'] = submsg.FindString(MSG_KEY_RESULT_DISPLAY_LOCATION)
        self.__dict__['name'] = submsg.FindString(MSG_KEY_RESULT_NAME)
        self.__dict__['executablePath'] = submsg.FindString(MSG_KEY_RESULT_EXECUTABLE_PATH)
        self.__dict__['description'] = submsg.FindString(MSG_KEY_RESULT_DESCRIPTION)


self.__dict__['state'] = 0
        self.__dict__['processId'] = 0
        self.__dict__['parentProcessId'] = 0
        self.__dict__['flags'] = 0
        self.__dict__['createTime'] = mcl.object.MclTime.MclTime()
        self.__dict__['processorTime'] = mcl.object.MclTime.MclTime()
        self.__dict__['user'] = ''
        self.__dict__['displayLocation'] = ''
        self.__dict__['name'] = ''
        self.__dict__['executablePath'] = ''
        self.__dict__['description'] = ''

# [GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.34)]
# Embedded file name: type_Result.py
from types import *
import mcl.object.MclTime
RESULT_STATE_INITIAL = 1
RESULT_STATE_STARTED = 2
RESULT_STATE_STOPPED = 3
RESULT_STATE_LIST = 4
RESULT_PROCESS_FLAG_64_BIT = 1
RESULT_PROCESS_FLAG_32_BIT = 2

class Result:

    def __init__(self):

    def __getattr__(self, name):
        if name == 'state':
            return self.__dict__['state']
        if name == 'processId':
            return self.__dict__['processId']
        if name == 'parentProcessId':
            return self.__dict__['parentProcessId']
        if name == 'flags':
            return self.__dict__['flags']
        if name == 'createTime':
            return self.__dict__['createTime']
        if name == 'processorTime':
            return self.__dict__['processorTime']
        if name == 'user':
            return self.__dict__['user']
        if name == 'displayLocation':
            return self.__dict__['displayLocation']
        if name == 'name':
            return self.__dict__['name']
        if name == 'executablePath':
            return self.__dict__['executablePath']
        if name == 'description':
            return self.__dict__['description']
        raise AttributeError("Attribute '%s' not found" % name)

    def __setattr__(self, name, value):
        if name == 'state':
            self.__dict__['state'] = value
        elif name == 'processId':
            self.__dict__['processId'] = value
        elif name == 'parentProcessId':
            self.__dict__['parentProcessId'] = value
        elif name == 'flags':
            self.__dict__['flags'] = value
        elif name == 'createTime':
            self.__dict__['createTime'] = value
        elif name == 'processorTime':
            self.__dict__['processorTime'] = value
        elif name == 'user':
            self.__dict__['user'] = value
        elif name == 'displayLocation':
            self.__dict__['displayLocation'] = value
        elif name == 'name':
            self.__dict__['name'] = value
        elif name == 'executablePath':
            self.__dict__['executablePath'] = value
        elif name == 'description':
            self.__dict__['description'] = value
        else:
            raise AttributeError("Attribute '%s' not found" % name)

    def Marshal(self, mmsg):
        from mcl.object.Message import MarshalMessage
        submsg = MarshalMessage()
        submsg.AddU8(MSG_KEY_RESULT_STATE, self.__dict__['state'])
        submsg.AddU32(MSG_KEY_RESULT_PROCESS_ID, self.__dict__['processId'])
        submsg.AddU32(MSG_KEY_RESULT_PARENT_PROCESS_ID, self.__dict__['parentProcessId'])
        submsg.AddU32(MSG_KEY_RESULT_FLAGS, self.__dict__['flags'])
        submsg.AddTime(MSG_KEY_RESULT_CREATE_TIME, self.__dict__['createTime'])
        submsg.AddTime(MSG_KEY_RESULT_PROCESSOR_TIME, self.__dict__['processorTime'])
        submsg.AddStringUtf8(MSG_KEY_RESULT_USER, self.__dict__['user'])
        submsg.AddStringUtf8(MSG_KEY_RESULT_DISPLAY_LOCATION, self.__dict__['displayLocation'])
        submsg.AddStringUtf8(MSG_KEY_RESULT_NAME, self.__dict__['name'])
        submsg.AddStringUtf8(MSG_KEY_RESULT_EXECUTABLE_PATH, self.__dict__['executablePath'])
        submsg.AddStringUtf8(MSG_KEY_RESULT_DESCRIPTION, self.__dict__['description'])
        mmsg.AddMessage(MSG_KEY_RESULT, submsg)

    def Demarshal(self, dmsg, instance=-1):
        import mcl.object.Message
        msgData = dmsg.FindData(MSG_KEY_RESULT, mcl.object.Message.MSG_TYPE_MSG, instance)
        submsg = mcl.object.Message.DemarshalMessage(msgData)
        self.__dict__['state'] = submsg.FindU8(MSG_KEY_RESULT_STATE)
        self.__dict__['processId'] = submsg.FindU32(MSG_KEY_RESULT_PROCESS_ID)
        self.__dict__['parentProcessId'] = submsg.FindU32(MSG_KEY_RESULT_PARENT_PROCESS_ID)
        self.__dict__['flags'] = submsg.FindU32(MSG_KEY_RESULT_FLAGS)
        self.__dict__['createTime'] = submsg.FindTime(MSG_KEY_RESULT_CREATE_TIME)
        self.__dict__['processorTime'] = submsg.FindTime(MSG_KEY_RESULT_PROCESSOR_TIME)
        self.__dict__['user'] = submsg.FindString(MSG_KEY_RESULT_USER)
        self.__dict__['displayLocation'] = submsg.FindString(MSG_KEY_RESULT_DISPLAY_LOCATION)
        self.__dict__['name'] = submsg.FindString(MSG_KEY_RESULT_NAME)
        self.__dict__['executablePath'] = submsg.FindString(MSG_KEY_RESULT_EXECUTABLE_PATH)
        self.__dict__['description'] = submsg.FindString(MSG_KEY_RESULT_DESCRIPTION)


# [GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.34)]
# Embedded file name: type_Result.py
from types import *
import mcl.object.MclTime
RESULT_STATE_INITIAL = 1
RESULT_STATE_STARTED = 2
RESULT_STATE_STOPPED = 3
RESULT_STATE_LIST = 4
RESULT_PROCESS_FLAG_64_BIT = 1
RESULT_PROCESS_FLAG_32_BIT = 2

class Result:

    def __init__(self):
        self.__dict__['state'] = 0
        self.__dict__['processId'] = 0
        self.__dict__['parentProcessId'] = 0
        self.__dict__['flags'] = 0
        self.__dict__['createTime'] = mcl.object.MclTime.MclTime()
        self.__dict__['processorTime'] = mcl.object.MclTime.MclTime()
        self.__dict__['user'] = ''
        self.__dict__['displayLocation'] = ''
        self.__dict__['name'] = ''
        self.__dict__['executablePath'] = ''
        self.__dict__['description'] = ''

    def __getattr__(self, name):
        if name == 'state':
            return self.__dict__['state']
        if name == 'processId':
            return self.__dict__['processId']
        if name == 'parentProcessId':
            return self.__dict__['parentProcessId']
        if name == 'flags':
            return self.__dict__['flags']
        if name == 'createTime':
            return self.__dict__['createTime']
        if name == 'processorTime':
            return self.__dict__['processorTime']
        if name == 'user':
            return self.__dict__['user']
        if name == 'displayLocation':
            return self.__dict__['displayLocation']
        if name == 'name':
            return self.__dict__['name']
        if name == 'executablePath':
            return self.__dict__['executablePath']
        if name == 'description':
            return self.__dict__['description']
        raise AttributeError(

    def __setattr__(self, name, value):
        if name == 'state':
            self.__dict__['state'] = value
        elif name == 'processId':
            self.__dict__['processId'] = value
        elif name == 'parentProcessId':
            self.__dict__['parentProcessId'] = value
        elif name == 'flags':
            self.__dict__['flags'] = value
        elif name == 'createTime':
            self.__dict__['createTime'] = value
        elif name == 'processorTime':
            self.__dict__['processorTime'] = value
        elif name == 'user':
            self.__dict__['user'] = value
        elif name == 'displayLocation':
            self.__dict__['displayLocation'] = value
        elif name == 'name':
            self.__dict__['name'] = value
        elif name == 'executablePath':
            self.__dict__['executablePath'] = value
        elif name == 'description':
            self.__dict__['description'] = value
        else:
            raise AttributeError("Attribute '%s' not found" % name)

    def Marshal(self, mmsg):
        from mcl.object.Message import MarshalMessage
        submsg = MarshalMessage()
        submsg.AddU8(MSG_KEY_RESULT_STATE, self.__dict__['state'])
        submsg.AddU32(MSG_KEY_RESULT_PROCESS_ID, self.__dict__['processId'])
        submsg.AddU32(MSG_KEY_RESULT_PARENT_PROCESS_ID, self.__dict__['parentProcessId'])
        submsg.AddU32(MSG_KEY_RESULT_FLAGS, self.__dict__['flags'])
        submsg.AddTime(MSG_KEY_RESULT_CREATE_TIME, self.__dict__['createTime'])
        submsg.AddTime(MSG_KEY_RESULT_PROCESSOR_TIME, self.__dict__['processorTime'])
        submsg.AddStringUtf8(MSG_KEY_RESULT_USER, self.__dict__['user'])
        submsg.AddStringUtf8(MSG_KEY_RESULT_DISPLAY_LOCATION, self.__dict__['displayLocation'])
        submsg.AddStringUtf8(MSG_KEY_RESULT_NAME, self.__dict__['name'])
        submsg.AddStringUtf8(MSG_KEY_RESULT_EXECUTABLE_PATH, self.__dict__['executablePath'])
        submsg.AddStringUtf8(MSG_KEY_RESULT_DESCRIPTION, self.__dict__['description'])
        mmsg.AddMessage(MSG_KEY_RESULT, submsg)

    def Demarshal(self, dmsg, instance=-1):
        import mcl.object.Message
        msgData = dmsg.FindData(MSG_KEY_RESULT, mcl.object.Message.MSG_TYPE_MSG, instance)
        submsg = mcl.object.Message.DemarshalMessage(msgData)
        self.__dict__['state'] = submsg.FindU8(MSG_KEY_RESULT_STATE)
        self.__dict__['processId'] = submsg.FindU32(MSG_KEY_RESULT_PROCESS_ID)
        self.__dict__['parentProcessId'] = submsg.FindU32(MSG_KEY_RESULT_PARENT_PROCESS_ID)
        self.__dict__['flags'] = submsg.FindU32(MSG_KEY_RESULT_FLAGS)
        self.__dict__['createTime'] = submsg.FindTime(MSG_KEY_RESULT_CREATE_TIME)
        self.__dict__['processorTime'] = submsg.FindTime(MSG_KEY_RESULT_PROCESSOR_TIME)
        self.__dict__['user'] = submsg.FindString(MSG_KEY_RESULT_USER)
        self.__dict__['displayLocation'] = submsg.FindString(MSG_KEY_RESULT_DISPLAY_LOCATION)
        self.__dict__['name'] = submsg.FindString(MSG_KEY_RESULT_NAME)
        self.__dict__['executablePath'] = submsg.FindString(MSG_KEY_RESULT_EXECUTABLE_PATH)
        self.__dict__['description'] = submsg.FindString(MSG_KEY_RESULT_DESCRIPTION)


from argparse import ArgumentParser

def build_opts(transformers=None):
    opts = ArgumentParser()
    opts.add_argument(dest='filename', help='Filename or release name to guess', nargs='*')

    naming_opts = opts.add_argument_group("Naming")
    naming_opts.add_argument('-t', '--type', dest='type', default=None,
                             help='The suggested file type: movie, episode. If undefined, type will be guessed.')
    naming_opts.add_argument('-n', '--name-only', dest='name_only', action='store_true', default=False,
                             help='Parse files as name only. Disable folder parsing, extension parsing, and file content analysis.')
    naming_opts.add_argument('-c', '--split-camel', dest='split_camel', action='store_true', default=False,
                             help='Split camel case part of filename.')

    naming_opts.add_argument('-X', '--disabled-transformer', action='append', dest='disabled_transformers',
                             help='Transformer to disable (can be used multiple time)')

    output_opts = opts.add_argument_group("Output")
    output_opts.add_argument('-v', '--verbose', action='store_true', dest='verbose', default=False,
                             help='Display debug output')
    output_opts.add_argument('-P', '--show-property', dest='show_property', default=None,
                             help='Display the value of a single property (title, series, videoCodec, year, type ...)'),
    output_opts.add_argument('-u', '--unidentified', dest='unidentified', action='store_true', default=False,
                             help='Display the unidentified parts.'),
    output_opts.add_argument('-a', '--advanced', dest='advanced', action='store_true', default=False,
                             help='Display advanced information for filename guesses, as json output')
    output_opts.add_argument('-y', '--yaml', dest='yaml', action='store_true', default=False,
                             help='Display information for filename guesses as yaml output (like unit-test)')
    output_opts.add_argument('-f', '--input-file', dest='input_file', default=False,
                             help='Read filenames from an input file.')
    output_opts.add_argument('-d', '--demo', action='store_true', dest='demo', default=False,
                             help='Run a few builtin tests instead of analyzing a file')

    information_opts = opts.add_argument_group("Information")
    information_opts.add_argument('-p', '--properties', dest='properties', action='store_true', default=False,
                                  help='Display properties that can be guessed.')
    information_opts.add_argument('-V', '--values', dest='values', action='store_true', default=False,
                                  help='Display property values that can be guessed.')
    information_opts.add_argument('-s', '--transformers', dest='transformers', action='store_true', default=False,
                                  help='Display transformers that can be used.')
    information_opts.add_argument('--version', dest='version', action='store_true', default=False,
                                  help='Display the guessit version.')

    webservice_opts = opts.add_argument_group("guessit.io")
    webservice_opts.add_argument('-b', '--bug', action='store_true', dest='submit_bug', default=False,
                                 help='Submit a wrong detection to the guessit.io service')

    other_opts = opts.add_argument_group("Other features")
    other_opts.add_argument('-i', '--info', dest='info', default='filename',
                            help='The desired information type: filename, video, hash_mpc or a hash from python\'s '
                            'hashlib module, such as hash_md5, hash_sha1, ...; or a list of any of '
                            'them, comma-separated')

    if transformers:
        for transformer in transformers:
            transformer.register_arguments(opts, naming_opts, output_opts, information_opts, webservice_opts, other_opts)

    return opts, naming_opts, output_opts, information_opts, webservice_opts, other_opts
_opts, _naming_opts, _output_opts, _information_opts, _webservice_opts, _other_opts = None, None, None, None, None, None

global _opts, _naming_opts, _output_opts, _information_opts, _webservice_opts, _other_opts
    _opts, _naming_opts, _output_opts, _information_opts, _webservice_opts, _other_opts = build_opts(transformers)

def get_opts():
    return _opts


from argparse import ArgumentParser

def build_opts(transformers=None):
    opts = ArgumentParser()
    opts.add_argument(dest='filename', help='Filename or release name to guess', nargs='*')

    naming_opts = opts.add_argument_group("Naming")
    naming_opts.add_argument('-t', '--type', dest='type', default=None,
                             help='The suggested file type: movie, episode. If undefined, type will be guessed.')
    naming_opts.add_argument('-n', '--name-only', dest='name_only', action='store_true', default=False,
                             help='Parse files as name only. Disable folder parsing, extension parsing, and file content analysis.')
    naming_opts.add_argument('-c', '--split-camel', dest='split_camel', action='store_true', default=False,
                             help='Split camel case part of filename.')

    naming_opts.add_argument('-X', '--disabled-transformer', action='append', dest='disabled_transformers',
                             help='Transformer to disable (can be used multiple time)')

    output_opts = opts.add_argument_group("Output")
    output_opts.add_argument('-v', '--verbose', action='store_true', dest='verbose', default=False,
                             help='Display debug output')
    output_opts.add_argument('-P', '--show-property', dest='show_property', default=None,
                             help='Display the value of a single property (title, series, videoCodec, year, type ...)'),
    output_opts.add_argument('-u', '--unidentified', dest='unidentified', action='store_true', default=False,
                             help='Display the unidentified parts.'),
    output_opts.add_argument('-a', '--advanced', dest='advanced', action='store_true', default=False,
                             help='Display advanced information for filename guesses, as json output')
    output_opts.add_argument('-y', '--yaml', dest='yaml', action='store_true', default=False,
                             help='Display information for filename guesses as yaml output (like unit-test)')
    output_opts.add_argument('-f', '--input-file', dest='input_file', default=False,
                             help='Read filenames from an input file.')
    output_opts.add_argument('-d', '--demo', action='store_true', dest='demo', default=False,
                             help='Run a few builtin tests instead of analyzing a file')

    information_opts = opts.add_argument_group("Information")
    information_opts.add_argument('-p', '--properties', dest='properties', action='store_true', default=False,
                                  help='Display properties that can be guessed.')
    information_opts.add_argument('-V', '--values', dest='values', action='store_true', default=False,
                                  help='Display property values that can be guessed.')
    information_opts.add_argument('-s', '--transformers', dest='transformers', action='store_true', default=False,
                                  help='Display transformers that can be used.')
    information_opts.add_argument('--version', dest='version', action='store_true', default=False,
                                  help='Display the guessit version.')

    webservice_opts = opts.add_argument_group("guessit.io")
    webservice_opts.add_argument('-b', '--bug', action='store_true', dest='submit_bug', default=False,
                                 help='Submit a wrong detection to the guessit.io service')

    other_opts = opts.add_argument_group("Other features")
    other_opts.add_argument('-i', '--info', dest='info', default='filename',
                            help='The desired information type: filename, video, hash_mpc or a hash from python\'s '
                            'hashlib module, such as hash_md5, hash_sha1, ...; or a list of any of '
                            'them, comma-separated')

    if transformers:
        for transformer in transformers:
            transformer.register_arguments(opts, naming_opts, output_opts, information_opts, webservice_opts, other_opts)

    return opts, naming_opts, output_opts, information_opts, webservice_opts, other_opts
_opts, _naming_opts, _output_opts, _information_opts, _webservice_opts, _other_opts = None, None, None, None, None, None

def reload(transformers=None):
    global _opts, _naming_opts, _output_opts, _information_opts, _webservice_opts, _other_opts
    _opts, _naming_opts, _output_opts, _information_opts, _webservice_opts, _other_opts = build_opts(transformers)

def get_opts():


from argparse import ArgumentParser

def build_opts(transformers=None):
    opts = ArgumentParser()
    opts.add_argument(dest='filename', help='Filename or release name to guess', nargs='*')

    naming_opts = opts.add_argument_group("Naming")
    naming_opts.add_argument('-t', '--type', dest='type', default=None,
                             help='The suggested file type: movie, episode. If undefined, type will be guessed.')
    naming_opts.add_argument('-n', '--name-only', dest='name_only', action='store_true', default=False,
                             help='Parse files as name only. Disable folder parsing, extension parsing, and file content analysis.')
    naming_opts.add_argument('-c', '--split-camel', dest='split_camel', action='store_true', default=False,
                             help='Split camel case part of filename.')

    naming_opts.add_argument('-X', '--disabled-transformer', action='append', dest='disabled_transformers',
                             help='Transformer to disable (can be used multiple time)')

    output_opts = opts.add_argument_group("Output")
    output_opts.add_argument('-v', '--verbose', action='store_true', dest='verbose', default=False,
                             help='Display debug output')
    output_opts.add_argument('-P', '--show-property', dest='show_property', default=None,
                             help='Display the value of a single property (title, series, videoCodec, year, type ...)'),
    output_opts.add_argument('-u', '--unidentified', dest='unidentified', action='store_true', default=False,
                             help='Display the unidentified parts.'),
    output_opts.add_argument('-a', '--advanced', dest='advanced', action='store_true', default=False,
                             help='Display advanced information for filename guesses, as json output')
    output_opts.add_argument('-y', '--yaml', dest='yaml', action='store_true', default=False,
                             help='Display information for filename guesses as yaml output (like unit-test)')
    output_opts.add_argument('-f', '--input-file', dest='input_file', default=False,
                             help='Read filenames from an input file.')
    output_opts.add_argument('-d', '--demo', action='store_true', dest='demo', default=False,
                             help='Run a few builtin tests instead of analyzing a file')

    information_opts = opts.add_argument_group("Information")
    information_opts.add_argument('-p', '--properties', dest='properties', action='store_true', default=False,
                                  help='Display properties that can be guessed.')
    information_opts.add_argument('-V', '--values', dest='values', action='store_true', default=False,
                                  help='Display property values that can be guessed.')
    information_opts.add_argument('-s', '--transformers', dest='transformers', action='store_true', default=False,
                                  help='Display transformers that can be used.')
    information_opts.add_argument('--version', dest='version', action='store_true', default=False,
                                  help='Display the guessit version.')

    webservice_opts = opts.add_argument_group("guessit.io")
    webservice_opts.add_argument('-b', '--bug', action='store_true', dest='submit_bug', default=False,
                                 help='Submit a wrong detection to the guessit.io service')

    other_opts = opts.add_argument_group("Other features")
    other_opts.add_argument('-i', '--info', dest='info', default='filename',
                            help='The desired information type: filename, video, hash_mpc or a hash from python\'s '
                            'hashlib module, such as hash_md5, hash_sha1, ...; or a list of any of '
                            'them, comma-separated')

    if transformers:
        for transformer in transformers:
            transformer.register_arguments(opts, naming_opts, output_opts, information_opts, webservice_opts, other_opts)

    return opts, naming_opts, output_opts, information_opts, webservice_opts, other_opts
_opts, _naming_opts, _output_opts, _information_opts, _webservice_opts, _other_opts = None, None, None, None, None, None

def reload(transformers=None):
    global _op

    _opts, _naming_opts, _output_opts, _information_opts, _webservice_opts, _other_opts = build_opts(transformers)

def get_opts():
    return _opts


import numpy as np
import torch
from pytorch_lightning import Trainer
from torch import Tensor

from pl_bolts.models.rl.ppo_model import PPO

def test_discount_rewards():
    """Test calculation of discounted rewards."""
    model = PPO(env="CartPole-v0", batch_size=16, gamma=0.99)

    rewards = np.ones(4)
    gt_qvals = [3.9403989999999998, 2.9701, 1.99, 1.0]

    qvals = model.discount_rewards(rewards, discount=0.99)

    assert gt_qvals == qvals

"""Test the critic loss function."""

    model = PPO(env="CartPole-v0", batch_size=16, gamma=0.99)
    obs_dim = model.env.observation_space.shape[0]

    batch_states = torch.rand(8, obs_dim)
    batch_qvals = torch.rand(8)

    loss = model.critic_loss(batch_states, batch_qvals)

    assert isinstance(loss, Tensor)

def test_actor_loss_categorical():
    """Test the actor loss function on categorical action-space environment."""

    model = PPO(env="CartPole-v0", batch_size=16, gamma=0.99)
    obs_dim = model.env.observation_space.shape[0]

    batch_states = torch.rand(8, obs_dim)
    batch_actions = torch.rand(8).long()
    batch_logp_old = torch.rand(8)
    batch_adv = torch.rand(8)

    loss = model.actor_loss(batch_states, batch_actions, batch_logp_old, batch_adv)

    assert isinstance(loss, Tensor)

def test_actor_loss_continuous():
    """Test the actor loss function on continuous action-space environment."""

    model = PPO(env="MountainCarContinuous-v0", batch_size=16, gamma=0.99)
    obs_dim = model.env.observation_space.shape[0]
    action_dim = model.env.action_space.shape[0]

    batch_states = torch.rand(8, obs_dim)
    batch_actions = torch.rand(8, action_dim)
    batch_logp_old = torch.rand(8)
    batch_adv = torch.rand(8)

    loss = model.actor_loss(batch_states, batch_actions, batch_logp_old, batch_adv)

    assert isinstance(loss, Tensor)

def test_generate_trajectory_samples():
    model = PPO("CartPole-v0", batch_size=16)

    obs_dim = model.env.observation_space.shape[0]

    sample_gen = model.generate_trajectory_samples()
    state, action, logp_old, qval, adv = next(sample_gen)

    assert state.shape[0] == obs_dim
    assert action
    assert logp_old
    assert qval
    assert adv

def test_training_categorical():
    model = PPO("CartPole-v0", batch_size=16)
    trainer = Trainer(max_epochs=1)
    trainer.fit(model)

def test_training_continous():
    model = PPO("MountainCarContinuous-v0", batch_size=16)
    trainer = Trainer(max_epochs=1)
    trainer.fit(model)


"""Test the critic loss function."""

    model = PPO(env="CartPole-v0", batch_size=16, gamma=0.99)
    obs_dim = model.env.observation_space.shape[0]

    batch_states = torch.rand(8, obs_dim)
    batch_qvals = torch.rand(8)

    loss = model.critic_loss(batch_states, batch_qvals)

    assert isinstance(loss, Tensor)

import numpy as np
import torch
from pytorch_lightning import Trainer
from torch import Tensor

from pl_bolts.models.rl.ppo_model import PPO

def test_discount_rewards():
    """Test calculation of discounted rewards."""
    model = PPO(env="CartPole-v0", batch_size=16, gamma=0.99)

    rewards = np.ones(4)
    gt_qvals = [3.9403989999999998, 2.9701, 1.99, 1.0]

    qvals = model.discount_rewards(rewards, discount=0.99)

    assert gt_qvals == qvals

def test_critic_loss():

def test_actor_loss_categorical():
    """Test the actor loss function on categorical action-space environment."""

    model = PPO(env="CartPole-v0", batch_size=16, gamma=0.99)
    obs_dim = model.env.observation_space.shape[0]

    batch_states = torch.rand(8, obs_dim)
    batch_actions = torch.rand(8).long()
    batch_logp_old = torch.rand(8)
    batch_adv = torch.rand(8)

    loss = model.actor_loss(batch_states, batch_actions, batch_logp_old, batch_adv)

    assert isinstance(loss, Tensor)

def test_actor_loss_continuous():
    """Test the actor loss function on continuous action-space environment."""

    model = PPO(env="MountainCarContinuous-v0", batch_size=16, gamma=0.99)
    obs_dim = model.env.observation_space.shape[0]
    action_dim = model.env.action_space.shape[0]

    batch_states = torch.rand(8, obs_dim)
    batch_actions = torch.rand(8, action_dim)
    batch_logp_old = torch.rand(8)
    batch_adv = torch.rand(8)

    loss = model.actor_loss(batch_states, batch_actions, batch_logp_old, batch_adv)

    assert isinstance(loss, Tensor)

def test_generate_trajectory_samples():
    model = PPO("CartPole-v0", batch_size=16)

    obs_dim = model.env.observation_space.shape[0]

    sample_gen = model.generate_trajectory_samples()
    state, action, logp_old, qval, adv = next(sample_gen)

    assert state.shape[0] == obs_dim
    assert action
    assert logp_old
    assert qval
    assert adv

def test_training_categorical():
    model = PPO("CartPole-v0", batch_size=16)
    trainer = Trainer(max_epochs=1)
    trainer.fit(model)

def test_training_continous():
    model = PPO("MountainCarContinuous-v0", batch_size=16)
    trainer = Trainer(max_epochs=1)
    trainer.fit(model)


import numpy as np
import torch
from pytorch_lightning import Trainer
from torch import Tensor

from pl_bolts.models.rl.ppo_model import PPO

def test_discount_rewards():
    """Test calculation of discounted rewards."""
    model = PPO(env="CartPole-v0", batch_size=16, gamma=0.99)

    rewards = np.ones(4)
    gt_qvals = [3.9403989999999998, 2.9701, 1.99, 1.0]

    qvals = model.discount_rewards(rewards, discount=0.99)

    assert gt_qvals == qvals

def test_critic_loss():
    """Test the critic loss function."""

    model = PPO(env="CartPole-v0", batch_size=16, gamma=0.99)
    obs_dim = model.env.observation_space.shape[0]

    batch_states = torch.rand(8, obs_dim)
    batch_qvals = torch.rand(8)

    loss = model.critic

    assert isinstance(loss, Tensor)

def test_actor_loss_categorical():
    """Test the actor loss function on categorical action-space environment."""

    model = PPO(env="CartPole-v0", batch_size=16, gamma=0.99)
    obs_dim = model.env.observation_space.shape[0]

    batch_states = torch.rand(8, obs_dim)
    batch_actions = torch.rand(8).long()
    batch_logp_old = torch.rand(8)
    batch_adv = torch.rand(8)

    loss = model.actor_loss(batch_states, batch_actions, batch_logp_old, batch_adv)

    assert isinstance(loss, Tensor)

def test_actor_loss_continuous():
    """Test the actor loss function on continuous action-space environment."""

    model = PPO(env="MountainCarContinuous-v0", batch_size=16, gamma=0.99)
    obs_dim = model.env.observation_space.shape[0]
    action_dim = model.env.action_space.shape[0]

    batch_states = torch.rand(8, obs_dim)
    batch_actions = torch.rand(8, action_dim)
    batch_logp_old = torch.rand(8)
    batch_adv = torch.rand(8)

    loss = model.actor_loss(batch_states, batch_actions, batch_logp_old, batch_adv)

    assert isinstance(loss, Tensor)

def test_generate_trajectory_samples():
    model = PPO("CartPole-v0", batch_size=16)

    obs_dim = model.env.observation_space.shape[0]

    sample_gen = model.generate_trajectory_samples()
    state, action, logp_old, qval, adv = next(sample_gen)

    assert state.shape[0] == obs_dim
    assert action
    assert logp_old
    assert qval
    assert adv

def test_training_categorical():
    model = PPO("CartPole-v0", batch_size=16)
    trainer = Trainer(max_epochs=1)
    trainer.fit(model)

def test_training_continous():
    model = PPO("MountainCarContinuous-v0", batch_size=16)
    trainer = Trainer(max_epochs=1)
    trainer.fit(model)


    model = PPO(env="CartPole-v0", batch_size=16, gamma=0.99)

    rewards = np.ones(4)
    gt_qvals = [3.9403989999999998, 2.9701, 1.99, 1.0]

    qvals = model.discount_rewards(rewards, discount=0.99)

    assert gt_qvals == qvals

import numpy as np
import torch
from pytorch_lightning import Trainer
from torch import Tensor

from pl_bolts.models.rl.ppo_model import PPO

def test_discount_rewards():
    """Test calculation of discounted rewards."""

def test_critic_loss():
    """Test the critic loss function."""

    model = PPO(env="CartPole-v0", batch_size=16, gamma=0.99)
    obs_dim = model.env.observation_space.shape[0]

    batch_states = torch.rand(8, obs_dim)
    batch_qvals = torch.rand(8)

    loss = model.critic_loss(batch_states, batch_qvals)

    assert isinstance(loss, Tensor)

def test_actor_loss_categorical():
    """Test the actor loss function on categorical action-space environment."""

    model = PPO(env="CartPole-v0", batch_size=16, gamma=0.99)
    obs_dim = model.env.observation_space.shape[0]

    batch_states = torch.rand(8, obs_dim)
    batch_actions = torch.rand(8).long()
    batch_logp_old = torch.rand(8)
    batch_adv = torch.rand(8)

    loss = model.actor_loss(batch_states, batch_actions, batch_logp_old, batch_adv)

    assert isinstance(loss, Tensor)

def test_actor_loss_continuous():
    """Test the actor loss function on continuous action-space environment."""

    model = PPO(env="MountainCarContinuous-v0", batch_size=16, gamma=0.99)
    obs_dim = model.env.observation_space.shape[0]
    action_dim = model.env.action_space.shape[0]

    batch_states = torch.rand(8, obs_dim)
    batch_actions = torch.rand(8, action_dim)
    batch_logp_old = torch.rand(8)
    batch_adv = torch.rand(8)

    loss = model.actor_loss(batch_states, batch_actions, batch_logp_old, batch_adv)

    assert isinstance(loss, Tensor)

def test_generate_trajectory_samples():
    model = PPO("CartPole-v0", batch_size=16)

    obs_dim = model.env.observation_space.shape[0]

    sample_gen = model.generate_trajectory_samples()
    state, action, logp_old, qval, adv = next(sample_gen)

    assert state.shape[0] == obs_dim
    assert action
    assert logp_old
    assert qval
    assert adv

def test_training_categorical():
    model = PPO("CartPole-v0", batch_size=16)
    trainer = Trainer(max_epochs=1)
    trainer.fit(model)

def test_training_continous():
    model = PPO("MountainCarContinuous-v0", batch_size=16)
    trainer = Trainer(max_epochs=1)
    trainer.fit(model)


import django
from django.db import models
from south.db import db

from flother.apps.contact.models import *

class Migration:

"""Add model ``Message``."""
        db.create_table('contact_message', (
            ('body', orm['contact.Message:body']),
            ('sender_name', orm['contact.Message:sender_name']),
            ('created_at', orm['contact.Message:created_at']),
            ('updated_at', orm['contact.Message:updated_at']),
            ('sender_email', orm['contact.Message:sender_email']),
            ('id', orm['contact.Message:id']),
            ('is_spam', orm['contact.Message:is_spam']),
        ))
        db.send_create_signal('contact', ['Message'])

    def backwards(self, orm):
        """Delete model ``Message``."""
        db.delete_table('contact_message')

    models = {
        'contact.message': {
            'body': ('django.db.models.fields.TextField', [], {}),
            'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True', 'blank': 'True'}),
            'is_spam': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
            'sender_email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}),
            'sender_name': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
            'updated_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'})
        }
    }

    complete_apps = ['contact']


"""Delete model ``Message``."""
        db.delete_table('contact_message')

import django
from django.db import models
from south.db import db

from flother.apps.contact.models import *

class Migration:
    def forwards(self, orm):
        """Add model ``Message``."""
        db.create_table('contact_message', (
            ('body', orm['contact.Message:body']),
            ('sender_name', orm['contact.Message:sender_name']),
            ('created_at', orm['contact.Message:created_at']),
            ('updated_at', orm['contact.Message:updated_at']),
            ('sender_email', orm['contact.Message:sender_email']),
            ('id', orm['contact.Message:id']),
            ('is_spam', orm['contact.Message:is_spam']),
        ))
        db.send_create_signal('contact', ['Message'])

    def backwards(self, orm):

    models = {
        'contact.message': {
            'body': ('django.db.models.fields.TextField', [], {}),
            'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True', 'blank': 'True'}),
            'is_spam': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
            'sender_email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}),
            'sender_name': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
            'updated_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'})
        }
    }

    complete_apps = ['contact']


import django
from django.db import models
from south.db import db

from flother.apps.contact.models import *

class Migration:
    def forwards(self, orm):
        """Add model ``Message``."""
        db.create_table('contact_message', (
            ('body', orm['contact.Message:body']),
            ('sender_name', orm['contact.Message:sender_name']),
            ('created_at', orm['contact.Message:created_at']),
            ('updated_at', orm['contact.Message:updated_at']),
            ('sender_email', orm['contact.Message:sender_email']),
            ('id', orm['contact.Message:id']),
            ('is_spam', orm['contact.Message:is_spam']),
        ))
        db.send_create_signal('contact', [

    def backwards(self, orm):
        """Delete model ``Message``."""
        db.delete_table('contact_message')

    models = {
        'contact.message': {
            'body': ('django.db.models.fields.TextField', [], {}),
            'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True', 'blank': 'True'}),
            'is_spam': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
            'sender_email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}),
            'sender_name': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
            'updated_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'})
        }
    }

    complete_apps = ['contact']


import django
from django.db import models
from south.db import db

from flother.apps.contact.models import *

class Migration:
    def forwards(self, orm):
        """Add model ``Message``."""
        db.create_table('contact_message', (
            ('body', orm['contact.Message:body']),
            ('sender_name', orm['contact.Message:sender_name']),
            ('created_at', orm['contact.Message:created_at']),
            ('updated_at', orm['contact.Message:updated_at']),
            ('sender_email', orm['contact.Message:sender_email']),
            ('id', orm['contact.Message:id']),
            ('is_spam', orm['contact.Message:is_spam']),
        ))
        db.send_create_signal('contact', ['Message'])

    def backwards(self, orm):
        """Delete model ``Message``."""


self.offset = 0
        self.data = []
    def add(self, s):
        if s is None:
            return 0
        pos = self.offset
        byte_data = s.encode('utf-16le')
        self.offset += len(byte_data) + 2
        self.data.append(byte_data)
        return pos
    def add_list(self, env):
        if not env:
            return 0
        pos = self.offset
        for k, v in env:
            self.add(k)
            self.add(v)
        # Terminator
        self.add('')
        self.add('')
        return pos
    def stringdata(self):
        self.data.append(b'')
        return b'\0\0'.join(self.data)

class Shim:
    def __init__(self, exe):
        self.exe_type = 0
        self.exe = exe
        self.exe_base = None
        self.cwd = None
        self.env = []
    def serialize(self):
        buf = StringBuffer()
        fmt = '4s5L'
        hdrlen = struct.calcsize(fmt)
        exe_offset = buf.add(self.exe)
        exe_base_offset = buf.add(self.exe_base)
        cwd_offset = buf.add(self.cwd)
        env_offset = buf.add_list(self.env)
        hdr = struct.pack(fmt, b'SHIM', self.exe_type, exe_offset,
                          exe_base_offset, cwd_offset, env_offset)
        hdr += buf.stringdata()
        footer = struct.pack('L', len(hdr) + struct.calcsize('L'))
        return hdr + footer


if not env:
            return 0
        pos = self.offset
        for k, v in env:
            self.add(k)
            self.add(v)
        # Terminator
        self.add('')
        self.add('')
        return pos

import struct

class StringBuffer:
    def __init__(self):
        self.offset = 0
        self.data = []
    def add(self, s):
        if s is None:
            return 0
        pos = self.offset
        byte_data = s.encode('utf-16le')
        self.offset += len(byte_data) + 2
        self.data.append(byte_data)
        return pos
    def add_list(self, env):

    def stringdata(self):
        self.data.append(b'')
        return b'\0\0'.join(self.data)

class Shim:
    def __init__(self, exe):
        self.exe_type = 0
        self.exe = exe
        self.exe_base = None
        self.cwd = None
        self.env = []
    def serialize(self):
        buf = StringBuffer()
        fmt = '4s5L'
        hdrlen = struct.calcsize(fmt)
        exe_offset = buf.add(self.exe)
        exe_base_offset = buf.add(self.exe_base)
        cwd_offset = buf.add(self.cwd)
        env_offset = buf.add_list(self.env)
        hdr = struct.pack(fmt, b'SHIM', self.exe_type, exe_offset,
                          exe_base_offset, cwd_offset, env_offset)
        hdr += buf.stringdata()
        footer = struct.pack('L', len(hdr) + struct.calcsize('L'))
        return hdr + footer


import struct

class StringBuffer:
    def __init__(self):
        self.offset = 0
        self.data = []
    def add(self, s):
        if s is None:
            return 0
        pos = self.offset
        byte_data = s.encode('utf-16le')
        self.offset += len(byte_data) + 2
        self.data.append(byte_data)
        return pos
    def add_list(self, env):
        if not env:
            return 0
        pos = self.offset
        for k, v in env:
            self.add(k)
            self.add(v)
        # Terminator
        self.add('')
        self.add('')
        return pos
    def stringdata(self):
        self.data.append(b'')
        return b'\0\0'.join(self.data)

class Shim:
    def __init__(self, exe):
        self.exe_type = 0
        self.exe = exe
        self.exe_base = None
        self.cwd = None
        self.env = []
    def serialize(self):
        buf = StringBuffer()
        fmt = '4s5L'
        hdrlen = struct.calcsize(fmt)
        exe_offset = buf.add(self.exe)
        exe_base_offset = buf.add(self.exe_base)
        cwd_offset = buf.add(self.cwd)
        env_offset = buf.add_list(self.env)
        hdr = struct.pack(fmt, b'SHIM', self.exe_type, exe_offset,
                          exe_base_offset, cwd_offset, env_offset)
        hdr += buf.stringdata()
        footer = struct.pac


"""Pibooth view management.
"""

import os
import time
import contextlib
import pygame
from pygame import gfxdraw
from PIL import Image
from pibooth import pictures, fonts
from pibooth.view import background
from pibooth.utils import LOGGER
from pibooth.pictures import sizing

class PiWindow(object):

    """Class to handle the window.
    The following attributes are available for use in plugins:

    :attr surface: surface on which sprites are displayed
    :type surface: :py:class:`pygame.Surface`
    :attr is_fullscreen: set to True if the window is display in full screen
    :type is_fullscreen: bool
    :attr display_size: tuple (width, height) represneting the size of the screen
    :type display_size: tuple
    """

    CENTER = 'center'
    RIGHT = 'right'
    LEFT = 'left'
    FULLSCREEN = 'fullscreen'

    def __init__(self, title,
                 size=(800, 480),
                 color=(0, 0, 0),
                 text_color=(255, 255, 255),
                 arrow_location=background.ARROW_BOTTOM,
                 arrow_offset=0,
                 debug=False):
        self.__size = size
        self.debug = debug
        self.bg_color = color
        self.text_color = text_color
        self.arrow_location = arrow_location
        self.arrow_offset = arrow_offset

        # Prepare the pygame module for use
        os.environ['SDL_VIDEO_CENTERED'] = '1'
        pygame.init()

        # Save the desktop mode, shall be done before `setmode` (SDL 1.2.10, and pygame 1.8.0)
        info = pygame.display.Info()

        pygame.display.set_caption(title)
        self.is_fullscreen = False
        self.display_size = (info.current_w, info.current_h)
        self.surface = pygame.display.set_mode(self.__size, pygame.RESIZABLE)

        self._buffered_images = {}
        self._current_background = None
        self._current_foreground = None
        self._print_number = 0
        self._print_failure = False
        self._capture_number = (0, 4)  # (current, max)

        self._pos_map = {self.CENTER: self._center_pos,
                         self.RIGHT: self._right_pos,
                         self.LEFT: self._left_pos,
                         self.FULLSCREEN: self._center_pos}

        # Don't use pygame.mouse.get_cursor() because will be removed in pygame2
        self._cursor = ((16, 16), (0, 0),
                        (0, 0, 64, 0, 96, 0, 112, 0, 120, 0, 124, 0, 126, 0, 127, 0,
                         127, 128, 124, 0, 108, 0, 70, 0, 6, 0, 3, 0, 3, 0, 0, 0),
                        (192, 0, 224, 0, 240, 0, 248, 0, 252, 0, 254, 0, 255, 0, 255,
                         128, 255, 192, 255, 224, 254, 0, 239, 0, 207, 0, 135, 128, 7, 128, 3, 0))

    def _update_foreground(self, pil_image, pos=CENTER, resize=True):
        """Show a PIL image on the foreground.
        Only one is bufferized to avoid memory leak.
        """
        image_name = id(pil_image)

        if pos == self.FULLSCREEN:
            image_size_max = (self.surface.get_size()[0] * 0.9, self.surface.get_size()[1] * 0.9)
        else:
            image_size_max = (self.surface.get_size()[0] * 0.48, self.surface.get_size()[1])

        buff_size, buff_image = self._buffered_images.get(image_name, (None, None))
        if buff_image and image_size_max == buff_size:
            image = buff_image
        else:
            if resize:
                image = pil_image.resize(sizing.new_size_keep_aspect_ratio(
                    pil_image.size, image_size_max), Image.ANTIALIAS)
            else:
                image = pil_image
            image = pygame.image.frombuffer(image.tobytes(), image.size, image.mode)
            if self._current_foreground:
                self._buffered_images.pop(id(self._current_foreground[0]), None)
            LOGGER.debug("Add to buffer the image '%s'", image_name)
            self._buffered_images[image_name] = (image_size_max, image)

        self._current_foreground = (pil_image, pos, resize)

        if self.debug and resize:
            # Build rectangle around picture area for debuging purpose
            outlines = pygame.Surface(image_size_max, pygame.SRCALPHA, 32)
            pygame.draw.rect(outlines, pygame.Color(255, 0, 0), outlines.get_rect(), 2)
            self.surface.blit(outlines, self._pos_map[pos](outlines))

        return self.surface.blit(image, self._pos_map[pos](image))

"""Show image on the background.
        """
        self._current_background = self._buffered_images.setdefault(str(bkgd), bkgd)
        self._current_background.set_color(self.bg_color)
        self._current_background.set_outlines(self.debug)
        self._current_background.set_text_color(self.text_color)
        self._current_background.resize(self.surface)
        self._current_background.paint(self.surface)
        self._update_capture_number()
        self._update_print_number()

    def _update_capture_number(self):
        """Update the captures counter displayed.
        """
        if not self._capture_number[0]:
            return  # Dont show counter: no picture taken

        center = self.surface.get_rect().center
        radius = 10
        border = 20
        x = center[0] - (2 * radius * self._capture_number[1] + border * (self._capture_number[1] - 1)) // 2
        y = self.surface.get_size()[1] - radius - border
        for nbr in range(self._capture_number[1]):
            gfxdraw.aacircle(self.surface, x, y, radius, self.text_color)
            if self._capture_number[0] > nbr:
                # Because anti-aliased filled circle doesn't exist
                gfxdraw.aacircle(self.surface, x, y, radius - 3, self.text_color)
                gfxdraw.filled_circle(self.surface, x, y, radius - 3, self.text_color)
            x += (2 * radius + border)

    def _update_print_number(self):
        """Update the number of files in the printer queue.
        """
        if not self._print_number and not self._print_failure:
            return  # Dont show counter: no file in queue, no failure

        smaller = self.surface.get_size()[1] if self.surface.get_size(
        )[1] < self.surface.get_size()[0] else self.surface.get_size()[0]
        side = int(smaller * 0.05)  # 5% of the window

        if side > 0:
            if self._print_failure:
                image = pictures.get_pygame_image('printer_failure.png', (side, side), color=self.text_color)
            else:
                image = pictures.get_pygame_image('printer.png', (side, side), color=self.text_color)
            y = self.surface.get_rect().height - image.get_rect().height - 10
            self.surface.blit(image, (10, y))
            font = pygame.font.Font(fonts.CURRENT, side)
            label = font.render(str(self._print_number), True, self.text_color)
            self.surface.blit(label, (side + 20, y))

    def _center_pos(self, image):
        """
        Return the position of the given image to be centered on window.
        """
        pos = self.surface.get_rect().center
        return image.get_rect(center=pos) if image else pos

    def _left_pos(self, image):
        """
        Return the position of the given image to be put on the left of the screen
        """
        pos = (self.surface.get_rect().centerx // 2, self.surface.get_rect().centery)
        return image.get_rect(center=pos) if image else pos

    def _right_pos(self, image):
        """
        Return the position of the given image to be put on the right of the screen
        """
        pos = (self.surface.get_rect().centerx + self.surface.get_rect().centerx // 2, self.surface.get_rect().centery)
        return image.get_rect(center=pos) if image else pos

    def get_rect(self, absolute=False):
        """Return a Rect object (as defined in pygame) for this window.

        :param absolute: absolute position considering the window centered on screen
        :type absolute: bool
        """
        if absolute:
            return self.surface.get_rect(center=(self.display_size[0] / 2, self.display_size[1] / 2))
        return self.surface.get_rect()

    def get_image(self):
        """Return the currently displayed foreground image.
        """
        if self._current_foreground:
            return self._current_foreground[0]
        return None

    def resize(self, size):
        """Resize the window keeping aspect ratio.
        """
        if not self.is_fullscreen:
            self.__size = size  # Manual resizing
            self.surface = pygame.display.set_mode(self.__size, pygame.RESIZABLE)
        self.update()

    def update(self):
        """Repaint the window with currently displayed images.
        """
        if self._current_background:
            self._update_background(self._current_background)
        else:
            self._update_capture_number()
            self._update_print_number()
        if self._current_foreground:
            self._update_foreground(*self._current_foreground)

    def show_oops(self):
        """Show failure view in case of exception.
        """
        self._capture_number = (0, self._capture_number[1])
        self._update_background(background.OopsBackground())

    def show_intro(self, pil_image=None, with_print=True):
        """Show introduction view.
        """
        self._capture_number = (0, self._capture_number[1])
        if with_print and pil_image:
            self._update_background(background.IntroWithPrintBackground(self.arrow_location, self.arrow_offset))
        else:
            self._update_background(background.IntroBackground(self.arrow_location, self.arrow_offset))

        if pil_image:
            self._update_foreground(pil_image, self.RIGHT)
        elif self._current_foreground:
            self._buffered_images.pop(id(self._current_foreground[0]), None)
            self._current_foreground = None

    def show_choice(self, choices, selected=None):
        """Show the choice view.
        """
        self._capture_number = (0, self._capture_number[1])
        if not selected:
            self._update_background(background.ChooseBackground(choices, self.arrow_location, self.arrow_offset))
        else:
            self._update_background(background.ChosenBackground(choices, selected))

    def show_image(self, pil_image=None, pos=CENTER):
        """Show PIL image as it (no resize).
        """
        if not pil_image:
            # Clear the currently displayed image
            if self._current_foreground:
                _, image = self._buffered_images.pop(id(self._current_foreground[0]))
                _, pos, _ = self._current_foreground
                self._current_foreground = None
                image.fill((0, 0, 0))
                return self.surface.blit(image, self._pos_map[pos](image))
        else:
            return self._update_foreground(pil_image, pos, False)

    def show_work_in_progress(self):
        """Show wait view.
        """
        self._capture_number = (0, self._capture_number[1])
        self._update_background(background.ProcessingBackground())

    def show_print(self, pil_image=None):
        """Show print view (image resized on the left).
        """
        self._capture_number = (0, self._capture_number[1])
        self._update_background(background.PrintBackground(self.arrow_location,
                                                           self.arrow_offset))
        if pil_image:
            self._update_foreground(pil_image, self.LEFT)

    def show_finished(self, pil_image=None):
        """Show finished view (image resized fullscreen).
        """
        self._capture_number = (0, self._capture_number[1])
        if pil_image:
            bg = background.FinishedWithImageBackground(pil_image.size)
            if self._buffered_images.get(str(bg), bg).foreground_size != pil_image.size:
                self._buffered_images.pop(str(bg))  # Drop cache, foreground size ratio has changed
            self._update_background(background.FinishedWithImageBackground(pil_image.size))
            self._update_foreground(pil_image, self.FULLSCREEN)
        else:
            self._update_background(background.FinishedBackground())

    @contextlib.contextmanager
    def flash(self, count):
        """Flash the window content.
        """
        if count < 1:
            raise ValueError("The flash counter shall be greater than 0")

        for i in range(count):
            self.surface.fill((255, 255, 255))
            if self._current_foreground:
                # Flash only the background, keep foreground at the top
                self._update_foreground(*self._current_foreground)
            pygame.event.pump()
            pygame.display.update()
            time.sleep(0.02)
            if i == count - 1:
                yield  # Let's do actions before end of flash
                self.update()
                pygame.event.pump()
                pygame.display.update()
            else:
                self.update()
                pygame.event.pump()
                pygame.display.update()
                time.sleep(0.02)

    def set_capture_number(self, current_nbr, total_nbr):
        """Set the current number of captures taken.
        """
        if total_nbr < 1:
            raise ValueError("Total number of captures shall be greater than 0")

        self._capture_number = (current_nbr, total_nbr)
        self._update_background(background.CaptureBackground())
        if self._current_foreground:
            self._update_foreground(*self._current_foreground)
        pygame.display.update()

    def set_print_number(self, current_nbr=None, failure=None):
        """Set the current number of tasks in the printer queue.
        """
        update = False

        if current_nbr is not None and self._print_number != current_nbr:
            self._print_number = current_nbr
            update = True

        if failure is not None and self._print_failure != failure:
            self._print_failure = failure
            update = True

        if update:
            self._update_background(self._current_background)
            if self._current_foreground:
                self._update_foreground(*self._current_foreground)
            pygame.display.update()

    def toggle_fullscreen(self):
        """Set window to full screen or initial size.
        """
        if self.is_fullscreen:
            self.is_fullscreen = False  # Set before resize
            pygame.mouse.set_cursor(*self._cursor)
            self.surface = pygame.display.set_mode(self.__size, pygame.RESIZABLE)
        else:
            self.is_fullscreen = True  # Set before resize
            # Make an invisible cursor (don't use pygame.mouse.set_visible(False) because
            # the mouse event will always return the window bottom-right coordinate)
            pygame.mouse.set_cursor((8, 8), (0, 0), (0, 0, 0, 0, 0, 0, 0, 0), (0, 0, 0, 0, 0, 0, 0, 0))
            self.surface = pygame.display.set_mode(self.display_size, pygame.FULLSCREEN)

        self.update()

    def drop_cache(self):
        """Drop all cached background and foreground to force
        refreshing the view.
        """
        self._current_background = None
        self._current_foreground = None
        self._buffered_images = {}


"""Return the currently displayed foreground image.
        """
        if self._current_foreground:
            return self._current_foreground[0]
        return None

"""Pibooth view management.
"""

import os
import time
import contextlib
import pygame
from pygame import gfxdraw
from PIL import Image
from pibooth import pictures, fonts
from pibooth.view import background
from pibooth.utils import LOGGER
from pibooth.pictures import sizing

class PiWindow(object):

    """Class to handle the window.
    The following attributes are available for use in plugins:

    :attr surface: surface on which sprites are displayed
    :type surface: :py:class:`pygame.Surface`
    :attr is_fullscreen: set to True if the window is display in full screen
    :type is_fullscreen: bool
    :attr display_size: tuple (width, height) represneting the size of the screen
    :type display_size: tuple
    """

    CENTER = 'center'
    RIGHT = 'right'
    LEFT = 'left'
    FULLSCREEN = 'fullscreen'

    def __init__(self, title,
                 size=(800, 480),
                 color=(0, 0, 0),
                 text_color=(255, 255, 255),
                 arrow_location=background.ARROW_BOTTOM,
                 arrow_offset=0,
                 debug=False):
        self.__size = size
        self.debug = debug
        self.bg_color = color
        self.text_color = text_color
        self.arrow_location = arrow_location
        self.arrow_offset = arrow_offset

        # Prepare the pygame module for use
        os.environ['SDL_VIDEO_CENTERED'] = '1'
        pygame.init()

        # Save the desktop mode, shall be done before `setmode` (SDL 1.2.10, and pygame 1.8.0)
        info = pygame.display.Info()

        pygame.display.set_caption(title)
        self.is_fullscreen = False
        self.display_size = (info.current_w, info.current_h)
        self.surface = pygame.display.set_mode(self.__size, pygame.RESIZABLE)

        self._buffered_images = {}
        self._current_background = None
        self._current_foreground = None
        self._print_number = 0
        self._print_failure = False
        self._capture_number = (0, 4)  # (current, max)

        self._pos_map = {self.CENTER: self._center_pos,
                         self.RIGHT: self._right_pos,
                         self.LEFT: self._left_pos,
                         self.FULLSCREEN: self._center_pos}

        # Don't use pygame.mouse.get_cursor() because will be removed in pygame2
        self._cursor = ((16, 16), (0, 0),
                        (0, 0, 64, 0, 96, 0, 112, 0, 120, 0, 124, 0, 126, 0, 127, 0,
                         127, 128, 124, 0, 108, 0, 70, 0, 6, 0, 3, 0, 3, 0, 0, 0),
                        (192, 0, 224, 0, 240, 0, 248, 0, 252, 0, 254, 0, 255, 0, 255,
                         128, 255, 192, 255, 224, 254, 0, 239, 0, 207, 0, 135, 128, 7, 128, 3, 0))

    def _update_foreground(self, pil_image, pos=CENTER, resize=True):
        """Show a PIL image on the foreground.
        Only one is bufferized to avoid memory leak.
        """
        image_name = id(pil_image)

        if pos == self.FULLSCREEN:
            image_size_max = (self.surface.get_size()[0] * 0.9, self.surface.get_size()[1] * 0.9)
        else:
            image_size_max = (self.surface.get_size()[0] * 0.48, self.surface.get_size()[1])

        buff_size, buff_image = self._buffered_images.get(image_name, (None, None))
        if buff_image and image_size_max == buff_size:
            image = buff_image
        else:
            if resize:
                image = pil_image.resize(sizing.new_size_keep_aspect_ratio(
                    pil_image.size, image_size_max), Image.ANTIALIAS)
            else:
                image = pil_image
            image = pygame.image.frombuffer(image.tobytes(), image.size, image.mode)
            if self._current_foreground:
                self._buffered_images.pop(id(self._current_foreground[0]), None)
            LOGGER.debug("Add to buffer the image '%s'", image_name)
            self._buffered_images[image_name] = (image_size_max, image)

        self._current_foreground = (pil_image, pos, resize)

        if self.debug and resize:
            # Build rectangle around picture area for debuging purpose
            outlines = pygame.Surface(image_size_max, pygame.SRCALPHA, 32)
            pygame.draw.rect(outlines, pygame.Color(255, 0, 0), outlines.get_rect(), 2)
            self.surface.blit(outlines, self._pos_map[pos](outlines))

        return self.surface.blit(image, self._pos_map[pos](image))

    def _update_background(self, bkgd):
        """Show image on the background.
        """
        self._current_background = self._buffered_images.setdefault(str(bkgd), bkgd)
        self._current_background.set_color(self.bg_color)
        self._current_background.set_outlines(self.debug)
        self._current_background.set_text_color(self.text_color)
        self._current_background.resize(self.surface)
        self._current_background.paint(self.surface)
        self._update_capture_number()
        self._update_print_number()

    def _update_capture_number(self):
        """Update the captures counter displayed.
        """
        if not self._capture_number[0]:
            return  # Dont show counter: no picture taken

        center = self.surface.get_rect().center
        radius = 10
        border = 20
        x = center[0] - (2 * radius * self._capture_number[1] + border * (self._capture_number[1] - 1)) // 2
        y = self.surface.get_size()[1] - radius - border
        for nbr in range(self._capture_number[1]):
            gfxdraw.aacircle(self.surface, x, y, radius, self.text_color)
            if self._capture_number[0] > nbr:
                # Because anti-aliased filled circle doesn't exist
                gfxdraw.aacircle(self.surface, x, y, radius - 3, self.text_color)
                gfxdraw.filled_circle(self.surface, x, y, radius - 3, self.text_color)
            x += (2 * radius + border)

    def _update_print_number(self):
        """Update the number of files in the printer queue.
        """
        if not self._print_number and not self._print_failure:
            return  # Dont show counter: no file in queue, no failure

        smaller = self.surface.get_size()[1] if self.surface.get_size(
        )[1] < self.surface.get_size()[0] else self.surface.get_size()[0]
        side = int(smaller * 0.05)  # 5% of the window

        if side > 0:
            if self._print_failure:
                image = pictures.get_pygame_image('printer_failure.png', (side, side), color=self.text_color)
            else:
                image = pictures.get_pygame_image('printer.png', (side, side), color=self.text_color)
            y = self.surface.get_rect().height - image.get_rect().height - 10
            self.surface.blit(image, (10, y))
            font = pygame.font.Font(fonts.CURRENT, side)
            label = font.render(str(self._print_number), True, self.text_color)
            self.surface.blit(label, (side + 20, y))

    def _center_pos(self, image):
        """
        Return the position of the given image to be centered on window.
        """
        pos = self.surface.get_rect().center
        return image.get_rect(center=pos) if image else pos

    def _left_pos(self, image):
        """
        Return the position of the given image to be put on the left of the screen
        """
        pos = (self.surface.get_rect().centerx // 2, self.surface.get_rect().centery)
        return image.get_rect(center=pos) if image else pos

    def _right_pos(self, image):
        """
        Return the position of the given image to be put on the right of the screen
        """
        pos = (self.surface.get_rect().centerx + self.surface.get_rect().centerx // 2, self.surface.get_rect().centery)
        return image.get_rect(center=pos) if image else pos

    def get_rect(self, absolute=False):
        """Return a Rect object (as defined in pygame) for this window.

        :param absolute: absolute position considering the window centered on screen
        :type absolute: bool
        """
        if absolute:
            return self.surface.get_rect(center=(self.display_size[0] / 2, self.display_size[1] / 2))
        return self.surface.get_rect()

    def get_image(self):

    def resize(self, size):
        """Resize the window keeping aspect ratio.
        """
        if not self.is_fullscreen:
            self.__size = size  # Manual resizing
            self.surface = pygame.display.set_mode(self.__size, pygame.RESIZABLE)
        self.update()

    def update(self):
        """Repaint the window with currently displayed images.
        """
        if self._current_background:
            self._update_background(self._current_background)
        else:
            self._update_capture_number()
            self._update_print_number()
        if self._current_foreground:
            self._update_foreground(*self._current_foreground)

    def show_oops(self):
        """Show failure view in case of exception.
        """
        self._capture_number = (0, self._capture_number[1])
        self._update_background(background.OopsBackground())

    def show_intro(self, pil_image=None, with_print=True):
        """Show introduction view.
        """
        self._capture_number = (0, self._capture_number[1])
        if with_print and pil_image:
            self._update_background(background.IntroWithPrintBackground(self.arrow_location, self.arrow_offset))
        else:
            self._update_background(background.IntroBackground(self.arrow_location, self.arrow_offset))

        if pil_image:
            self._update_foreground(pil_image, self.RIGHT)
        elif self._current_foreground:
            self._buffered_images.pop(id(self._current_foreground[0]), None)
            self._current_foreground = None

    def show_choice(self, choices, selected=None):
        """Show the choice view.
        """
        self._capture_number = (0, self._capture_number[1])
        if not selected:
            self._update_background(background.ChooseBackground(choices, self.arrow_location, self.arrow_offset))
        else:
            self._update_background(background.ChosenBackground(choices, selected))

    def show_image(self, pil_image=None, pos=CENTER):
        """Show PIL image as it (no resize).
        """
        if not pil_image:
            # Clear the currently displayed image
            if self._current_foreground:
                _, image = self._buffered_images.pop(id(self._current_foreground[0]))
                _, pos, _ = self._current_foreground
                self._current_foreground = None
                image.fill((0, 0, 0))
                return self.surface.blit(image, self._pos_map[pos](image))
        else:
            return self._update_foreground(pil_image, pos, False)

    def show_work_in_progress(self):
        """Show wait view.
        """
        self._capture_number = (0, self._capture_number[1])
        self._update_background(background.ProcessingBackground())

    def show_print(self, pil_image=None):
        """Show print view (image resized on the left).
        """
        self._capture_number = (0, self._capture_number[1])
        self._update_background(background.PrintBackground(self.arrow_location,
                                                           self.arrow_offset))
        if pil_image:
            self._update_foreground(pil_image, self.LEFT)

    def show_finished(self, pil_image=None):
        """Show finished view (image resized fullscreen).
        """
        self._capture_number = (0, self._capture_number[1])
        if pil_image:
            bg = background.FinishedWithImageBackground(pil_image.size)
            if self._buffered_images.get(str(bg), bg).foreground_size != pil_image.size:
                self._buffered_images.pop(str(bg))  # Drop cache, foreground size ratio has changed
            self._update_background(background.FinishedWithImageBackground(pil_image.size))
            self._update_foreground(pil_image, self.FULLSCREEN)
        else:
            self._update_background(background.FinishedBackground())

    @contextlib.contextmanager
    def flash(self, count):
        """Flash the window content.
        """
        if count < 1:
            raise ValueError("The flash counter shall be greater than 0")

        for i in range(count):
            self.surface.fill((255, 255, 255))
            if self._current_foreground:
                # Flash only the background, keep foreground at the top
                self._update_foreground(*self._current_foreground)
            pygame.event.pump()
            pygame.display.update()
            time.sleep(0.02)
            if i == count - 1:
                yield  # Let's do actions before end of flash
                self.update()
                pygame.event.pump()
                pygame.display.update()
            else:
                self.update()
                pygame.event.pump()
                pygame.display.update()
                time.sleep(0.02)

    def set_capture_number(self, current_nbr, total_nbr):
        """Set the current number of captures taken.
        """
        if total_nbr < 1:
            raise ValueError("Total number of captures shall be greater than 0")

        self._capture_number = (current_nbr, total_nbr)
        self._update_background(background.CaptureBackground())
        if self._current_foreground:
            self._update_foreground(*self._current_foreground)
        pygame.display.update()

    def set_print_number(self, current_nbr=None, failure=None):
        """Set the current number of tasks in the printer queue.
        """
        update = False

        if current_nbr is not None and self._print_number != current_nbr:
            self._print_number = current_nbr
            update = True

        if failure is not None and self._print_failure != failure:
            self._print_failure = failure
            update = True

        if update:
            self._update_background(self._current_background)
            if self._current_foreground:
                self._update_foreground(*self._current_foreground)
            pygame.display.update()

    def toggle_fullscreen(self):
        """Set window to full screen or initial size.
        """
        if self.is_fullscreen:
            self.is_fullscreen = False  # Set before resize
            pygame.mouse.set_cursor(*self._cursor)
            self.surface = pygame.display.set_mode(self.__size, pygame.RESIZABLE)
        else:
            self.is_fullscreen = True  # Set before resize
            # Make an invisible cursor (don't use pygame.mouse.set_visible(False) because
            # the mouse event will always return the window bottom-right coordinate)
            pygame.mouse.set_cursor((8, 8), (0, 0), (0, 0, 0, 0, 0, 0, 0, 0), (0, 0, 0, 0, 0, 0, 0, 0))
            self.surface = pygame.display.set_mode(self.display_size, pygame.FULLSCREEN)

        self.update()

    def drop_cache(self):
        """Drop all cached background and foreground to force
        refreshing the view.
        """
        self._current_background = None
        self._current_foreground = None
        self._buffered_images = {}