from azure.core.exceptions import HttpResponseError
import msrest.serialization

class Resource(msrest.serialization.Model):
    """Common fields that are returned in the response for all Azure Resource Manager resources.

    Variables are only populated by the server, and will be ignored when sending a request.

    :ivar id: Fully qualified resource ID for the resource. Ex -
     /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName}.
    :vartype id: str
    :ivar name: The name of the resource.
    :vartype name: str
    :ivar type: The type of the resource. E.g. "Microsoft.Compute/virtualMachines" or
     "Microsoft.Storage/storageAccounts".
    :vartype type: str
    """

    _validation = {
        'id': {'readonly': True},
        'name': {'readonly': True},
        'type': {'readonly': True},
    }

    _attribute_map = {
        'id': {'key': 'id', 'type': 'str'},
        'name': {'key': 'name', 'type': 'str'},
        'type': {'key': 'type', 'type': 'str'},
    }

    def __init__(
        self,
        **kwargs
    ):
        super(Resource, self).__init__(**kwargs)
        self.id = None
        self.name = None
        self.type = None

class TrackedResource(Resource):
    """The resource model definition for an Azure Resource Manager tracked top level resource which has 'tags' and a 'location'.

    Variables are only populated by the server, and will be ignored when sending a request.

    All required parameters must be populated in order to send to Azure.

    :ivar id: Fully qualified resource ID for the resource. Ex -
     /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName}.
    :vartype id: str
    :ivar name: The name of the resource.
    :vartype name: str
    :ivar type: The type of the resource. E.g. "Microsoft.Compute/virtualMachines" or
     "Microsoft.Storage/storageAccounts".
    :vartype type: str
    :param tags: A set of tags. Resource tags.
    :type tags: dict[str, str]
    :param location: Required. The geo-location where the resource lives.
    :type location: str
    """

    _validation = {
        'id': {'readonly': True},
        'name': {'readonly': True},
        'type': {'readonly': True},
        'location': {'required': True},
    }

    _attribute_map = {
        'id': {'key': 'id', 'type': 'str'},
        'name': {'key': 'name', 'type': 'str'},
        'type': {'key': 'type', 'type': 'str'},
        'tags': {'key': 'tags', 'type': '{str}'},
        'location': {'key': 'location', 'type': 'str'},
    }

    def __init__(
        self,
        **kwargs
    ):
        super(TrackedResource, self).__init__(**kwargs)
        self.tags = kwargs.get('tags', None)
        self.location = kwargs['location']

class Creator(TrackedResource):
    """An Azure resource which represents Maps Creator product and provides ability to manage private location data.

    Variables are only populated by the server, and will be ignored when sending a request.

    All required parameters must be populated in order to send to Azure.

    :ivar id: Fully qualified resource ID for the resource. Ex -
     /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName}.
    :vartype id: str
    :ivar name: The name of the resource.
    :vartype name: str
    :ivar type: The type of the resource. E.g. "Microsoft.Compute/virtualMachines" or
     "Microsoft.Storage/storageAccounts".
    :vartype type: str
    :param tags: A set of tags. Resource tags.
    :type tags: dict[str, str]
    :param location: Required. The geo-location where the resource lives.
    :type location: str
    :param properties: Required. The Creator resource properties.
    :type properties: ~azure.mgmt.maps.models.CreatorProperties
    """

    _validation = {
        'id': {'readonly': True},
        'name': {'readonly': True},
        'type': {'readonly': True},
        'location': {'required': True},
        'properties': {'required': True},
    }

    _attribute_map = {
        'id': {'key': 'id', 'type': 'str'},
        'name': {'key': 'name', 'type': 'str'},
        'type': {'key': 'type', 'type': 'str'},
        'tags': {'key': 'tags', 'type': '{str}'},
        'location': {'key': 'location', 'type': 'str'},
        'properties': {'key': 'properties', 'type': 'CreatorProperties'},
    }

    def __init__(
        self,
        **kwargs
    ):
        super(Creator, self).__init__(**kwargs)
        self.properties = kwargs['properties']

class CreatorList(msrest.serialization.Model):
    """A list of Creator resources.

    Variables are only populated by the server, and will be ignored when sending a request.

    :ivar value: a Creator account.
    :vartype value: list[~azure.mgmt.maps.models.Creator]
    :param next_link: URL client should use to fetch the next page (per server side paging).
     It's null for now, added for future use.
    :type next_link: str
    """

    _validation = {
        'value': {'readonly': True},
    }

    _attribute_map = {
        'value': {'key': 'value', 'type': '[Creator]'},
        'next_link': {'key': 'nextLink', 'type': 'str'},
    }

    def __init__(
        self,
        **kwargs
    ):
        super(CreatorList, self).__init__(**kwargs)
        self.value = None
        self.next_link = kwargs.get('next_link', None)

class CreatorProperties(msrest.serialization.Model):
    """Creator resource properties.

    Variables are only populated by the server, and will be ignored when sending a request.

    All required parameters must be populated in order to send to Azure.

    :ivar provisioning_state: The state of the resource provisioning, terminal states: Succeeded,
     Failed, Canceled.
    :vartype provisioning_state: str
    :param storage_units: Required. The storage units to be allocated. Integer values from 1 to
     100, inclusive.
    :type storage_units: int
    """

    _validation = {
        'provisioning_state': {'readonly': True},
        'storage_units': {'required': True, 'maximum': 100, 'minimum': 1},
    }

    _attribute_map = {
        'provisioning_state': {'key': 'provisioningState', 'type': 'str'},
        'storage_units': {'key': 'storageUnits', 'type': 'int'},
    }

    def __init__(
        self,
        **kwargs
    ):
        super(CreatorProperties, self).__init__(**kwargs)
        self.provisioning_state = None
        self.storage_units = kwargs['storage_units']

class CreatorUpdateParameters(msrest.serialization.Model):
    """Parameters used to update an existing Creator resource.

    Variables are only populated by the server, and will be ignored when sending a request.

    :param tags: A set of tags. Gets or sets a list of key value pairs that describe the resource.
     These tags can be used in viewing and grouping this resource (across resource groups). A
     maximum of 15 tags can be provided for a resource. Each tag must have a key no greater than 128
     characters and value no greater than 256 characters.
    :type tags: dict[str, str]
    :ivar provisioning_state: The state of the resource provisioning, terminal states: Succeeded,
     Failed, Canceled.
    :vartype provisioning_state: str
    :param storage_units: The storage units to be allocated. Integer values from 1 to 100,
     inclusive.
    :type storage_units: int
    """

    _validation = {
        'provisioning_state': {'readonly': True},
        'storage_units': {'maximum': 100, 'minimum': 1},
    }

    _attribute_map = {
        'tags': {'key': 'tags', 'type': '{str}'},
        'provisioning_state': {'key': 'properties.provisioningState', 'type': 'str'},
        'storage_units': {'key': 'properties.storageUnits', 'type': 'int'},
    }

    def __init__(
        self,
        **kwargs
    ):
        super(CreatorUpdateParameters, self).__init__(**kwargs)
        self.tags = kwargs.get('tags', None)
        self.provisioning_state = None
        self.storage_units = kwargs.get('storage_units', None)

class Dimension(msrest.serialization.Model):
    """Dimension of map account, for example API Category, Api Name, Result Type, and Response Code.

    :param name: Display name of dimension.
    :type name: str
    :param display_name: Display name of dimension.
    :type display_name: str
    """

    _attribute_map = {
        'name': {'key': 'name', 'type': 'str'},
        'display_name': {'key': 'displayName', 'type': 'str'},
    }

    def __init__(
        self,
        **kwargs
    ):
        super(Dimension, self).__init__(**kwargs)
        self.name = kwargs.get('name', None)
        self.display_name = kwargs.get('display_name', None)

class ErrorAdditionalInfo(msrest.serialization.Model):
    """The resource management error additional info.

    Variables are only populated by the server, and will be ignored when sending a request.

    :ivar type: The additional info type.
    :vartype type: str
    :ivar info: The additional info.
    :vartype info: str
    """

    _validation = {
        'type': {'readonly': True},
        'info': {'readonly': True},
    }

    _attribute_map = {
        'type': {'key': 'type', 'type': 'str'},
        'info': {'key': 'info', 'type': 'str'},
    }

    def __init__(
        self,
        **kwargs
    ):
        super(ErrorAdditionalInfo, self).__init__(**kwargs)
        self.type = None
        self.info = None

class ErrorDetail(msrest.serialization.Model):
    """The error detail.

    Variables are only populated by the server, and will be ignored when sending a request.

    :ivar code: The error code.
    :vartype code: str
    :ivar message: The error message.
    :vartype message: str
    :ivar target: The error target.
    :vartype target: str
    :ivar details: The error details.
    :vartype details: list[~azure.mgmt.maps.models.ErrorDetail]
    :ivar additional_info: The error additional info.
    :vartype additional_info: list[~azure.mgmt.maps.models.ErrorAdditionalInfo]
    """

    _validation = {
        'code': {'readonly': True},
        'message': {'readonly': True},
        'target': {'readonly': True},
        'details': {'readonly': True},
        'additional_info': {'readonly': True},
    }

    _attribute_map = {
        'code': {'key': 'code', 'type': 'str'},
        'message': {'key': 'message', 'type': 'str'},
        'target': {'key': 'target', 'type': 'str'},
        'details': {'key': 'details', 'type': '[ErrorDetail]'},
        'additional_info': {'key': 'additionalInfo', 'type': '[ErrorAdditionalInfo]'},
    }

    def __init__(
        self,
        **kwargs
    ):
        super(ErrorDetail, self).__init__(**kwargs)
        self.code = None
        self.message = None
        self.target = None
        self.details = None
        self.additional_info = None

class ErrorResponse(msrest.serialization.Model):
    """Common error response for all Azure Resource Manager APIs to return error details for failed operations. (This also follows the OData error response format.).

    :param error: The error object.
    :type error: ~azure.mgmt.maps.models.ErrorDetail
    """

    _attribute_map = {
        'error': {'key': 'error', 'type': 'ErrorDetail'},
    }

    def __init__(
        self,
        **kwargs
    ):
        super(ErrorResponse, self).__init__(**kwargs)
        self.error = kwargs.get('error', None)

class MapsAccount(TrackedResource):
    """An Azure resource which represents access to a suite of Maps REST APIs.

    Variables are only populated by the server, and will be ignored when sending a request.

    All required parameters must be populated in order to send to Azure.

    :ivar id: Fully qualified resource ID for the resource. Ex -
     /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName}.
    :vartype id: str
    :ivar name: The name of the resource.
    :vartype name: str
    :ivar type: The type of the resource. E.g. "Microsoft.Compute/virtualMachines" or
     "Microsoft.Storage/storageAccounts".
    :vartype type: str
    :param tags: A set of tags. Resource tags.
    :type tags: dict[str, str]
    :param location: Required. The geo-location where the resource lives.
    :type location: str
    :param sku: Required. The SKU of this account.
    :type sku: ~azure.mgmt.maps.models.Sku
    :param kind: Get or Set Kind property. Possible values include: "Gen1", "Gen2". Default value:
     "Gen1".
    :type kind: str or ~azure.mgmt.maps.models.Kind
    :ivar system_data: The system meta data relating to this resource.
    :vartype system_data: ~azure.mgmt.maps.models.SystemData
    :param properties: The map account properties.
    :type properties: ~azure.mgmt.maps.models.MapsAccountProperties
    """

    _validation = {
        'id': {'readonly': True},
        'name': {'readonly': True},
        'type': {'readonly': True},
        'location': {'required': True},
        'sku': {'required': True},
        'system_data': {'readonly': True},
    }

    _attribute_map = {
        'id': {'key': 'id', 'type': 'str'},
        'name': {'key': 'name', 'type': 'str'},
        'type': {'key': 'type', 'type': 'str'},
        'tags': {'key': 'tags', 'type': '{str}'},
        'location': {'key': 'location', 'type': 'str'},
        'sku': {'key': 'sku', 'type': 'Sku'},
        'kind': {'key': 'kind', 'type': 'str'},
        'system_data': {'key': 'systemData', 'type': 'SystemData'},
        'properties': {'key': 'properties', 'type': 'MapsAccountProperties'},
    }

    def __init__(
        self,
        **kwargs
    ):
        super(MapsAccount, self).__init__(**kwargs)
        self.sku = kwargs['sku']
        self.kind = kwargs.get('kind', "Gen1")
        self.system_data = None
        self.properties = kwargs.get('properties', None)

class MapsAccountKeys(msrest.serialization.Model):
    """The set of keys which can be used to access the Maps REST APIs. Two keys are provided for key rotation without interruption.

    Variables are only populated by the server, and will be ignored when sending a request.

    :ivar primary_key_last_updated: The last updated date and time of the primary key.
    :vartype primary_key_last_updated: str
    :ivar primary_key: The primary key for accessing the Maps REST APIs.
    :vartype primary_key: str
    :ivar secondary_key: The secondary key for accessing the Maps REST APIs.
    :vartype secondary_key: str
    :ivar secondary_key_last_updated: The last updated date and time of the secondary key.
    :vartype secondary_key_last_updated: str
    """

    _validation = {
        'primary_key_last_updated': {'readonly': True},
        'primary_key': {'readonly': True},
        'secondary_key': {'readonly': True},
        'secondary_key_last_updated': {'readonly': True},
    }

    _attribute_map = {
        'primary_key_last_updated': {'key': 'primaryKeyLastUpdated', 'type': 'str'},
        'primary_key': {'key': 'primaryKey', 'type': 'str'},
        'secondary_key': {'key': 'secondaryKey', 'type': 'str'},
        'secondary_key_last_updated': {'key': 'secondaryKeyLastUpdated', 'type': 'str'},
    }

    def __init__(
        self,
        **kwargs
    ):
        super(MapsAccountKeys, self).__init__(**kwargs)
        self.primary_key_last_updated = None
        self.primary_key = None
        self.secondary_key = None
        self.secondary_key_last_updated = None

class MapsAccountProperties(msrest.serialization.Model):
    """Additional Map account properties.

    Variables are only populated by the server, and will be ignored when sending a request.

    :ivar unique_id: A unique identifier for the maps account.
    :vartype unique_id: str
    :param disable_local_auth: Allows toggle functionality on Azure Policy to disable Azure Maps
     local authentication support. This will disable Shared Keys authentication from any usage.
    :type disable_local_auth: bool
    :ivar provisioning_state: the state of the provisioning.
    :vartype provisioning_state: str
    """

    _validation = {
        'unique_id': {'readonly': True},
        'provisioning_state': {'readonly': True},
    }

    _attribute_map = {
        'unique_id': {'key': 'uniqueId', 'type': 'str'},
        'disable_local_auth': {'key': 'disableLocalAuth', 'type': 'bool'},
        'provisioning_state': {'key': 'provisioningState', 'type': 'str'},
    }

    def __init__(
        self,
        **kwargs
    ):
        super(MapsAccountProperties, self).__init__(**kwargs)
        self.unique_id = None
        self.disable_local_auth = kwargs.get('disable_local_auth', False)
        self.provisioning_state = None

class MapsAccounts(msrest.serialization.Model):
    """A list of Maps Accounts.

    Variables are only populated by the server, and will be ignored when sending a request.

    :ivar value: a Maps Account.
    :vartype value: list[~azure.mgmt.maps.models.MapsAccount]
    :param next_link: URL client should use to fetch the next page (per server side paging).
     It's null for now, added for future use.
    :type next_link: str
    """

    _validation = {
        'value': {'readonly': True},
    }

    _attribute_map = {
        'value': {'key': 'value', 'type': '[MapsAccount]'},
        'next_link': {'key': 'nextLink', 'type': 'str'},
    }

    def __init__(
        self,
        **kwargs
    ):
        super(MapsAccounts, self).__init__(**kwargs)
        self.value = None
        self.next_link = kwargs.get('next_link', None)

class MapsAccountUpdateParameters(msrest.serialization.Model):
    """Parameters used to update an existing Maps Account.

    Variables are only populated by the server, and will be ignored when sending a request.

    :param tags: A set of tags. Gets or sets a list of key value pairs that describe the resource.
     These tags can be used in viewing and grouping this resource (across resource groups). A
     maximum of 15 tags can be provided for a resource. Each tag must have a key no greater than 128
     characters and value no greater than 256 characters.
    :type tags: dict[str, str]
    :param kind: Get or Set Kind property. Possible values include: "Gen1", "Gen2". Default value:
     "Gen1".
    :type kind: str or ~azure.mgmt.maps.models.Kind
    :param sku: The SKU of this account.
    :type sku: ~azure.mgmt.maps.models.Sku
    :ivar unique_id: A unique identifier for the maps account.
    :vartype unique_id: str
    :param disable_local_auth: Allows toggle functionality on Azure Policy to disable Azure Maps
     local authentication support. This will disable Shared Keys authentication from any usage.
    :type disable_local_auth: bool
    :ivar provisioning_state: the state of the provisioning.
    :vartype provisioning_state: str
    """

    _validation = {
        'unique_id': {'readonly': True},
        'provisioning_state': {'readonly': True},
    }

    _attribute_map = {
        'tags': {'key': 'tags', 'type': '{str}'},
        'kind': {'key': 'kind', 'type': 'str'},
        'sku': {'key': 'sku', 'type': 'Sku'},
        'unique_id': {'key': 'properties.uniqueId', 'type': 'str'},
        'disable_local_auth': {'key': 'properties.disableLocalAuth', 'type': 'bool'},
        'provisioning_state': {'key': 'properties.provisioningState', 'type': 'str'},
    }

    def __init__(
        self,
        **kwargs
    ):
        super(MapsAccountUpdateParameters, self).__init__(**kwargs)
        self.tags = kwargs.get('tags', None)
        self.kind = kwargs.get('kind', "Gen1")
        self.sku = kwargs.get('sku', None)
        self.unique_id = None
        self.disable_local_auth = kwargs.get('disable_local_auth', False)
        self.provisioning_state = None

class MapsKeySpecification(msrest.serialization.Model):
    """Whether the operation refers to the primary or secondary key.

    All required parameters must be populated in order to send to Azure.

    :param key_type: Required. Whether the operation refers to the primary or secondary key.
     Possible values include: "primary", "secondary".
    :type key_type: str or ~azure.mgmt.maps.models.KeyType
    """

    _validation = {
        'key_type': {'required': True},
    }

    _attribute_map = {
        'key_type': {'key': 'keyType', 'type': 'str'},
    }

    def __init__(
        self,
        **kwargs
    ):
        super(MapsKeySpecification, self).__init__(**kwargs)
        self.key_type = kwargs['key_type']

class MapsOperations(msrest.serialization.Model):
    """The set of operations available for Maps.

    Variables are only populated by the server, and will be ignored when sending a request.

    :ivar value: An operation available for Maps.
    :vartype value: list[~azure.mgmt.maps.models.OperationDetail]
    :param next_link: URL client should use to fetch the next page (per server side paging).
     It's null for now, added for future use.
    :type next_link: str
    """

    _validation = {
        'value': {'readonly': True},
    }

    _attribute_map = {
        'value': {'key': 'value', 'type': '[OperationDetail]'},
        'next_link': {'key': 'nextLink', 'type': 'str'},
    }

    def __init__(
        self,
        **kwargs
    ):
        super(MapsOperations, self).__init__(**kwargs)
        self.value = None
        self.next_link = kwargs.get('next_link', None)

class MetricSpecification(msrest.serialization.Model):
    """Metric specification of operation.

    :param name: Name of metric specification.
    :type name: str
    :param display_name: Display name of metric specification.
    :type display_name: str
    :param display_description: Display description of metric specification.
    :type display_description: str
    :param unit: Unit could be Count.
    :type unit: str
    :param dimensions: Dimensions of map account.
    :type dimensions: list[~azure.mgmt.maps.models.Dimension]
    :param aggregation_type: Aggregation type could be Average.
    :type aggregation_type: str
    :param fill_gap_with_zero: The property to decide fill gap with zero or not.
    :type fill_gap_with_zero: bool
    :param category: The category this metric specification belong to, could be Capacity.
    :type category: str
    :param resource_id_dimension_name_override: Account Resource Id.
    :type resource_id_dimension_name_override: str
    """

    _attribute_map = {
        'name': {'key': 'name', 'type': 'str'},
        'display_name': {'key': 'displayName', 'type': 'str'},
        'display_description': {'key': 'displayDescription', 'type': 'str'},
        'unit': {'key': 'unit', 'type': 'str'},
        'dimensions': {'key': 'dimensions', 'type': '[Dimension]'},
        'aggregation_type': {'key': 'aggregationType', 'type': 'str'},
        'fill_gap_with_zero': {'key': 'fillGapWithZero', 'type': 'bool'},
        'category': {'key': 'category', 'type': 'str'},
        'resource_id_dimension_name_override': {'key': 'resourceIdDimensionNameOverride', 'type': 'str'},
    }

    def __init__(
        self,
        **kwargs
    ):
        super(MetricSpecification, self).__init__(**kwargs)
        self.name = kwargs.get('name', None)
        self.display_name = kwargs.get('display_name', None)
        self.display_description = kwargs.get('display_description', None)
        self.unit = kwargs.get('unit', None)
        self.dimensions = kwargs.get('dimensions', None)
        self.aggregation_type = kwargs.get('aggregation_type', None)
        self.fill_gap_with_zero = kwargs.get('fill_gap_with_zero', None)
        self.category = kwargs.get('category', None)
        self.resource_id_dimension_name_override = kwargs.get('resource_id_dimension_name_override', None)

class OperationDetail(msrest.serialization.Model):
    """Operation detail payload.

    :param name: Name of the operation.
    :type name: str
    :param is_data_action: Indicates whether the operation is a data action.
    :type is_data_action: bool
    :param display: Display of the operation.
    :type display: ~azure.mgmt.maps.models.OperationDisplay
    :param origin: Origin of the operation.
    :type origin: str
    :param service_specification: One property of operation, include metric specifications.
    :type service_specification: ~azure.mgmt.maps.models.ServiceSpecification
    """

    _attribute_map = {
        'name': {'key': 'name', 'type': 'str'},
        'is_data_action': {'key': 'isDataAction', 'type': 'bool'},
        'display': {'key': 'display', 'type': 'OperationDisplay'},
        'origin': {'key': 'origin', 'type': 'str'},
        'service_specification': {'key': 'properties.serviceSpecification', 'type': 'ServiceSpecification'},
    }

    def __init__(
        self,
        **kwargs
    ):
        super(OperationDetail, self).__init__(**kwargs)
        self.name = kwargs.get('name', None)
        self.is_data_action = kwargs.get('is_data_action', None)
        self.display = kwargs.get('display', None)
        self.origin = kwargs.get('origin', None)
        self.service_specification = kwargs.get('service_specification', None)

class OperationDisplay(msrest.serialization.Model):
    """Operation display payload.

    :param provider: Resource provider of the operation.
    :type provider: str
    :param resource: Resource of the operation.
    :type resource: str
    :param operation: Localized friendly name for the operation.
    :type operation: str
    :param description: Localized friendly description for the operation.
    :type description: str
    """

    _attribute_map = {
        'provider': {'key': 'provider', 'type': 'str'},
        'resource': {'key': 'resource', 'type': 'str'},
        'operation': {'key': 'operation', 'type': 'str'},
        'description': {'key': 'description', 'type': 'str'},
    }

    def __init__(
        self,
        **kwargs
    ):
        super(OperationDisplay, self).__init__(**kwargs)
        self.provider = kwargs.get('provider', None)
        self.resource = kwargs.get('resource', None)
        self.operation = kwargs.get('operation', None)
        self.description = kwargs.get('description', None)

class ServiceSpecification(msrest.serialization.Model):
    """One property of operation, include metric specifications.

    :param metric_specifications: Metric specifications of operation.
    :type metric_specifications: list[~azure.mgmt.maps.models.MetricSpecification]
    """

    _attribute_map = {
        'metric_specifications': {'key': 'metricSpecifications', 'type': '[MetricSpecification]'},
    }

    def __init__(
        self,
        **kwargs
    ):
        super(ServiceSpecification, self).__init__(**kwargs)
        self.metric_specifications = kwargs.get('metric_specifications', None)

class Sku(msrest.serialization.Model):
    """The SKU of the Maps Account.

    Variables are only populated by the server, and will be ignored when sending a request.

    All required parameters must be populated in order to send to Azure.

    :param name: Required. The name of the SKU, in standard format (such as S0). Possible values
     include: "S0", "S1", "G2".
    :type name: str or ~azure.mgmt.maps.models.Name
    :ivar tier: Gets the sku tier. This is based on the SKU name.
    :vartype tier: str
    """

    _validation = {
        'name': {'required': True},
        'tier': {'readonly': True},
    }

    _attribute_map = {
        'name': {'key': 'name', 'type': 'str'},
        'tier': {'key': 'tier', 'type': 'str'},
    }

    def __init__(
        self,
        **kwargs
    ):
        super(Sku, self).__init__(**kwargs)
        self.name = kwargs['name']
        self.tier = None

class SystemData(msrest.serialization.Model):
    """Metadata pertaining to creation and last modification of the resource.

    :param created_by: The identity that created the resource.
    :type created_by: str
    :param created_by_type: The type of identity that created the resource. Possible values
     include: "User", "Application", "ManagedIdentity", "Key".
    :type created_by_type: str or ~azure.mgmt.maps.models.CreatedByType
    :param created_at: The timestamp of resource creation (UTC).
    :type created_at: ~datetime.datetime
    :param last_modified_by: The identity that last modified the resource.
    :type last_modified_by: str
    :param last_modified_by_type: The type of identity that last modified the resource. Possible
     values include: "User", "Application", "ManagedIdentity", "Key".
    :type last_modified_by_type: str or ~azure.mgmt.maps.models.CreatedByType
    :param last_modified_at: The timestamp of resource last modification (UTC).
    :type last_modified_at: ~datetime.datetime
    """

    _attribute_map = {
        'created_by': {'key': 'createdBy', 'type': 'str'},
        'created_by_type': {'key': 'createdByType', 'type': 'str'},
        'created_at': {'key': 'createdAt', 'type': 'iso-8601'},
        'last_modified_by': {'key': 'lastModifiedBy', 'type': 'str'},
        'last_modified_by_type': {'key': 'lastModifiedByType', 'type': 'str'},
        'last_modified_at': {'key': 'lastModifiedAt', 'type': 'iso-8601'},
    }

    def __init__(
        self,
        **kwargs
    ):
        super(SystemData, self).__init__(**kwargs)
        self.created_by = kwargs.get('created_by', None)
        self.created_by_type = kwargs.get('created_by_type', None)
        self.created_at = kwargs.get('created_at', None)
        self.last_modified_by = kwargs.get('last_modified_by', None)
        self.last_modified_by_type = kwargs.get('last_modified_by_type', None)
        self.last_modified_at = kwargs.get('last_modified_at', None)


import os
import openai
import pandas as pd
from concurrent.futures import ThreadPoolExecutor
from google.cloud import bigquery
# from dotenv import load_dotenv
from datetime import datetime
from fetch_query import prepare_notam_row, check_existing_notams_keys, fetch_notam_by_ids

# load_dotenv()
GPT_MODEL = "gpt-4-0613"
GPT_MODEL_BRIEFING = "gpt-4"
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
os.environ['OPENAI_API_KEY'] = OPENAI_API_KEY

function_descriptions = [
    {
        "name": "extract_info_from_notam",
        "description": "extract and interprate key info from an NOTAM (Notice to Airman), such as short description, category, impacted role (ATC,Flight Dispatcher, etc).",
        "parameters": {
            "type": "object",
            "properties": {
                "notamShortDescription": {
                    "type": "string",
                    "description": "The most important informations of the NOTAM summarized to one or two setences"
                },
                "notamDescription": {
                    "type": "string",
                    "description": "Interpretation of the NOTAM"
                },
                "category": {
                    "type": "string",
                    "description": "Try to categorise this NOTAM into categories like those: 1. Opening Hours; 2. Airport maintenance; 3. Airspace closure; 4. Obstacle; etc."
                },
                "impactedRole":{
                    "type": "string",
                    "description": "Try to categorise which role should be informed about this NOTAM. Return value as string for roles after comma. (Pilot, Flight Dispatcher, ATC)."
                },
            },
            "required": ["notamShortDescription", "notamDescription", "category", "impactedRole"]
        }
    }
]

def interpret_notam_with_gpt(notam_message):
    # Call the OpenAI Chat Completions API to interpret the NOTAM
    prompt = f"Please extract key information from this NOTAM: {notam_message} "
    message = [{"role": "user", "content": prompt}]
    response = openai.ChatCompletion.create(
        model=GPT_MODEL,
        api_key=OPENAI_API_KEY,
        messages=message,
        functions = function_descriptions,
        function_call="auto"
    )
    arguments = response.choices[0]["message"]["function_call"]["arguments"]
    short_interpretation = eval(arguments).get("notamShortDescription")
    interpretation= eval(arguments).get("notamDescription")
    category= eval(arguments).get("category")
    roles= eval(arguments).get("impactedRole")

    return short_interpretation, interpretation, category, roles

def prepare_gpt_interpretation_row(notam, short_interpretation, interpretation, category, roles):
    return {
        'notam_id': notam['notam_id'],
        'notam_content': notam['message'] if notam['message'] else notam['all'],
        'gpt_model': GPT_MODEL,
        'gpt_short_interpretation': short_interpretation,
        'gpt_interpretation': interpretation,
        'gpt_category': category,
        'gpt_interpretation_role': roles,
        'processed_at': datetime.now().isoformat()
    }

def insert_gpt_interpretation_into_bigquery(rows_to_insert):
    client = bigquery.Client()
    table_ref = client.dataset('model').table('notam_gpt_interpretation')
    dataframe = pd.DataFrame(rows_to_insert)
    job = client.load_table_from_dataframe(dataframe, table_ref)
    job.result()

def check_interpretation_exists(notam_id, model=GPT_MODEL):
    client = bigquery.Client()
    query = f"""
    SELECT notam_id FROM UNNEST({notam_id}) notam_id
    EXCEPT DISTINCT
    SELECT notam_id FROM notamify.model.notam_gpt_interpretation WHERE notam_id IN UNNEST({notam_id}) AND gpt_model = '{model}'
    """
    query_job = client.query(query)
    notam_ids = [row['notam_id'] for row in query_job.result()]
    return notam_ids

def fetch_interpret_and_insert_notams(notams, notam_ids):
    if notams is None:
        print("NOTAMs not found. Skipping interpretation.")
        return

    notam_ids_to_interpret = check_interpretation_exists(notam_ids)

    if not notam_ids_to_interpret:
        return

    interpretations_to_insert = []

    def process_notam(notam):
        if notam['notam_id'] in notam_ids_to_interpret:
            message = notam['message'] if notam['message'] else notam['all']
            short_interpretation, interpretation, category, roles = interpret_notam_with_gpt(message)
            interpretation_row = prepare_gpt_interpretation_row(notam, short_interpretation, interpretation, category, roles)
            return interpretation_row

    # Parallelize NOTAM processing
    with ThreadPoolExecutor() as executor:
        interpretations_to_insert = list(executor.map(process_notam, notams))

    # Remove None values (if any)
    interpretations_to_insert = [x for x in interpretations_to_insert if x is not None]

    # Insert into BigQuery in one go
    if interpretations_to_insert:
        insert_gpt_interpretation_into_bigquery(interpretations_to_insert)

    return None

# Briefing

def fetch_interpretations_from_bigquery(notam_ids):
    client = bigquery.Client()
    query = f"""
    SELECT icao, gpt_short_interpretation, gpt_category, gpt_interpretation_role
    FROM notamify.model.notam_gpt_interpretation
    INNER JOIN
    (SELECT notam_id, icao FROM notamify.raw.notams_icao_api QUALIFY ROW_NUMBER() OVER(PARTITION BY notam_id ORDER BY processed_at DESC) = 1) USING (notam_id)
    WHERE notam_id IN UNNEST ({notam_ids})
    ORDER BY icao, gpt_interpretation_role
    """
    query_job = client.query(query)
    return list(query_job.result())

def generate_briefing(notam_ids, role):
    # Fetch the interpretations from BigQuery
    interpretations = fetch_interpretations_from_bigquery(notam_ids)

    # Format the interpretations into a briefing
    notams = ";\n".join([f"Airport: {interp['icao']}. NOTAM: {interp['gpt_short_interpretation']}\n" for interp in interpretations])

    # Use the GPT model to generate a summary of the briefing
    prompt = f"You are tasked with providing a briefing for a {role} based solely on the provided NOTAMs. Your goal is to extract and present only the information that is directly relevant to the responsibilities of a {role}. Please prioritize the most critical information and keep the briefing concise and to the point. Do not include any information that is not directly related to the role of a {role}. Begin the briefing with the phrase 'Here is your briefing' and format the briefing in Markdown. Use the following NOTAMs as your source of information:\n{notams}."
    message = [{"role": "user", "content": prompt}]
    response = openai.ChatCompletion.create(
        model=GPT_MODEL_BRIEFING,
        api_key=OPENAI_API_KEY,
        messages=message
    )

    # Extract the summary from the response
    summary = response.choices[0].message.content.strip()

    return summary


import numpy as np
import pandas as pd
import random
import tqdm
import torch
import torch.nn.functional as F
from torch.utils.data import Dataset, DataLoader
import os

# 全局参数，随机种子，图像尺寸
seed = 114514
np.random.seed(seed)
random.seed(seed)
BATCH_SIZE = 512

hidden_dim = 16
epochs = 1
device = torch.device('cuda:0') if torch.cuda.is_available() else torch.device('cpu')
print(device)

df = pd.read_csv('train_dataset.csv')
print('共{}个用户，{}本图书，{}条记录'.format(max(df['user_id']) + 1, max(df['item_id']) + 1, len(df)))

class Goodbooks(Dataset):
    def __init__(self, df, mode='training', negs=99):
        super().__init__()

        self.df = df
        self.mode = mode

        self.book_nums = max(df['item_id']) + 1
        self.user_nums = max(df['user_id']) + 1

        self._init_dataset()

    def _init_dataset(self):
        self.Xs = []

        self.user_book_map = {}
        for i in range(self.user_nums):
            self.user_book_map[i] = []

        for index, row in self.df.iterrows():
            user_id, book_id = row
            self.user_book_map[user_id].append(book_id)

        if self.mode == 'training':
            for user, items in tqdm.tqdm(self.user_book_map.items()):
                for item in items[:-1]:
                    self.Xs.append((user, item, 1))
                    for _ in range(3):
                        while True:
                            neg_sample = random.randint(0, self.book_nums - 1)
                            if neg_sample not in self.user_book_map[user]:
                                self.Xs.append((user, neg_sample, 0))
                                break

        elif self.mode == 'validation':
            for user, items in tqdm.tqdm(self.user_book_map.items()):
                if len(items) == 0:
                    continue
                self.Xs.append((user, items[-1]))

    def __getitem__(self, index):

        if self.mode == 'training':
            user_id, book_id, label = self.Xs[index]
            return user_id, book_id, label
        elif self.mode == 'validation':
            user_id, book_id = self.Xs[index]

            negs = list(random.sample(
                list(set(range(self.book_nums)) - set(self.user_book_map[user_id])),
                k=99
            ))
            return user_id, book_id, torch.LongTensor(negs)

    def __len__(self):
        return len(self.Xs)

# 建立训练和验证dataloader
traindataset = Goodbooks(df, 'training')
validdataset = Goodbooks(df, 'validation')

trainloader = DataLoader(traindataset, batch_size=BATCH_SIZE, shuffle=True, drop_last=False, num_workers=0)
validloader = DataLoader(validdataset, batch_size=BATCH_SIZE, shuffle=True, drop_last=False, num_workers=0)

# 构建模型
class NCFModel(torch.nn.Module):
    def __init__(self, hidden_dim, user_num, item_num, mlp_layer_num=4, weight_decay=1e-5, dropout=0.5):
        super().__init__()
        self.hidden_dim = hidden_dim
        self.user_num = user_num
        self.item_num = item_num
        self.mlp_layer_num = mlp_layer_num
        self.weight_decay = weight_decay
        self.dropout = dropout

        self.mlp_user_embedding = torch.nn.Embedding(user_num, hidden_dim * (2 ** (self.mlp_layer_num - 1)))
        self.mlp_item_embedding = torch.nn.Embedding(item_num, hidden_dim * (2 ** (self.mlp_layer_num - 1)))

        self.gmf_user_embedding = torch.nn.Embedding(user_num, hidden_dim)
        self.gmf_item_embedding = torch.nn.Embedding(item_num, hidden_dim)

        mlp_Layers = []
        input_size = int(hidden_dim * (2 ** (self.mlp_layer_num)))
        for i in range(self.mlp_layer_num):
            mlp_Layers.append(torch.nn.Linear(int(input_size), int(input_size / 2)))
            mlp_Layers.append(torch.nn.Dropout(self.dropout))
            mlp_Layers.append(torch.nn.ReLU())
            input_size /= 2
        self.mlp_layers = torch.nn.Sequential(*mlp_Layers)

        self.output_layer = torch.nn.Linear(2 * self.hidden_dim, 1)

    def forward(self, user, item):
        user_gmf_embedding = self.gmf_user_embedding(user)
        item_gmf_embedding = self.gmf_item_embedding(item)

        user_mlp_embedding = self.mlp_user_embedding(user)
        item_mlp_embedding = self.mlp_item_embedding(item)

        gmf_output = user_gmf_embedding * item_gmf_embedding

        mlp_input = torch.cat([user_mlp_embedding, item_mlp_embedding], dim=-1)
        mlp_output = self.mlp_layers(mlp_input)

        output = torch.sigmoid(self.output_layer(torch.cat([gmf_output, mlp_output], dim=-1))).squeeze(-1)

        # return -r_pos_neg + reg
        return output

    def predict(self, user, item):
        self.eval()
        with torch.no_grad():
            user_gmf_embedding = self.gmf_user_embedding(user)
            item_gmf_embedding = self.gmf_item_embedding(item)

            user_mlp_embedding = self.mlp_user_embedding(user)
            item_mlp_embedding = self.mlp_item_embedding(item)

            gmf_output = user_gmf_embedding.unsqueeze(1) * item_gmf_embedding

            user_mlp_embedding = user_mlp_embedding.unsqueeze(1).expand(-1, item_mlp_embedding.shape[1], -1)
            mlp_input = torch.cat([user_mlp_embedding, item_mlp_embedding], dim=-1)
            mlp_output = self.mlp_layers(mlp_input)

        output = torch.sigmoid(self.output_layer(torch.cat([gmf_output, mlp_output], dim=-1))).squeeze(-1)
        return output

model = NCFModel(hidden_dim, traindataset.user_nums, traindataset.book_nums).to(device)
optimizer = torch.optim.Adam(model.parameters(), lr=1e-3)
crit = torch.nn.BCELoss()

loss_for_plot = []
hits_for_plot = []

for epoch in range(epochs):

    losses = []
    for index, data in enumerate(trainloader):
        user, item, label = data
        user, item, label = user.to(device), item.to(device), label.to(device).float()
        y_ = model(user, item).squeeze()

        loss = crit(y_, label)
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

        losses.append(loss.detach().cpu().item())

    hits = []
    for index, data in enumerate(validloader):
        user, pos, neg = data
        pos = pos.unsqueeze(1)
        all_data = torch.cat([pos, neg], dim=-1)
        output = model.predict(user.to(device), all_data.to(device)).detach().cpu()

        for batch in output:
            if 0 not in (-batch).argsort()[:10]:
                hits.append(0)
            else:
                hits.append(1)
    print('Epoch {} finished, average loss {}, hits@20 {}'.format(epoch, sum(losses) / len(losses),
                                                                  sum(hits) / len(hits)))
    loss_for_plot.append(sum(losses) / len(losses))
    hits_for_plot.append(sum(hits) / len(hits))

# 模型保存
torch.save(model.state_dict(), 'model.h5')

import matplotlib.pyplot as plt

x = list(range(1, len(hits_for_plot) + 1))
plt.subplot(1, 2, 1)
plt.xlabel('epochs')
plt.ylabel('loss')
plt.plot(x, loss_for_plot, 'r')

plt.subplot(1, 2, 2)
plt.xlabel('epochs')
plt.ylabel('acc')
plt.plot(x, hits_for_plot, 'r')

plt.show()

df = pd.read_csv('test_dataset.csv')
user_for_test = df['user_id'].tolist()

predict_item_id = []

def chunks(l, n):
    for i in range(0, len(l), n):
        yield l[i, i + n]

f = open('submission.csv', 'w', encoding='utf-8')

for user in user_for_test:
    # 将用户已经交互过的物品排除
    user_visited_items = traindataset.user_book_map[user]
    items_for_predict = list(set(range(traindataset.book_nums)) - set(user_visited_items))

    results = []
    user = torch.Tensor([user]).to(device)

    for batch in chunks(items_for_predict, 64):
        batch = torch.Tensor(batch).unsqueeze(0).to(device)

        result = model(user, batch).view(-1).detach().cpu()
        results.append(result)

    results = torch.cat(results, dim=-1)
    predict_item_id = (-results).argsort()[:10]
    list(map(lambda x: f.write('{},{}\n'.format(user.cpu().item(), x)), predict_item_id))

f.flush()
f.close()


from collections import defaultdict, deque

transistable = lambda a,b: sum((1 if x!=y else 0) for x,y in zip(a,b)) == 1

def solution(begin, target, words):
    graph = defaultdict(list)
    graph[begin] = set(filter(lambda x: transistable(begin, x), words))
    for word in words:
        graph[word] = set(filter(lambda x: transistable(word, x), words))
    # print(graph)

    q = deque([(begin, 0)])

    if target not in words:
        return 0

    while q:
        node, level = q.popleft()
        for word in graph[node]:
            if word == target:
                return level+1
            else:
                q.append((word, level+1))
    return 0

# def solution(begin, target, words):
#     def wordcmp(w1, w2):
#         cnt = 0
#         for ch in w1:
#             if ch in w2:
#                 cnt += 1
#         if cnt < len(w1)-1:
#             return 0
#         elif cnt == len(w1)-1:
#             return 1

#     ans = 0
#     visited = OrderedDict()
#     cursor = begin

#     if target not in words:
#         print(ans)
#         return ans

#     for word in words:
#         if len(visited) == len(words) or cursor == target:
#             print(ans, visited)
#             break
#         if wordcmp(cursor, word) == 1:
#             visited[word] = True
#             cursor = word
#             ans += 1
#             print(cursor)
#     return ans

def test(begin, target, words, ans):
    try:
        assert begin != target
        assert len(words) >= 3 and len(words) <= 50
        assert [word for word in words if len(word)>=3 and len(word)<=10]
        assert(solution(begin, target, words) == ans)
        print('정답입니다 :)')
    except AssertionError as err:
        print('틀렸습니다 :(')

if __name__ == '__main__':
    test('hit', 'cog', ['hot', 'dot', 'dog', 'lot', 'log', 'cog'], 4)
    test("hit", "cog", ["hot", "dot", "dog", "lot", "log"], 0)
    test('hit', 'hhh', ['hhh', 'hot', 'hht'], 2)


#module
import phonenumbers
from phonenumbers import timezone,geocoder,carrier
#userinput
user = (input('Masukan nomer telepon ex: +62 : '))
#data
phonenumber = phonenumbers.parse(user)
timeZone = timezone.time_zones_for_number(phonenumber)
Carrier = carrier.name_for_number(phonenumber,'id')
Region = geocoder.description_for_number(phonenumber,'id')
#output
print(phonenumber)
print('Asal Nomer = ', timeZone)
print('Provider = ', Carrier)
print('Negara = ', Region)


# 완주하지 못한 선수 (hash)

# 문제설명 : https://programmers.co.kr/learn/courses/30/lessons/42576

# 예상풀이
# Hash를 사용하지 않은 풀이다. (성공하지 못한풀이(결과x))

# 문제풀이(1)
# def solution(participant, completion):

#     participant.sorted()
#     completion.sorted()

#     for i in range(len(participant)):
#         for j in range(len(completion)):
#             if participant[i] == completion[j]:
#                 participant[i].remove()

#     return participant

#Hash를 사용하지 않은 풀이다. (성공하지 못한풀이(결과x))

# 문제풀이(2)
# def solution(participant, completion):
#     answer = ''
#     participant.sort()
#     completion.sort()

#     for i in range(len(completion)):
#         if participant[i] != completion[i]:
#             answer = participant[i]
#         else:
#             answer = participant[-1]

#     return answer

# 테스트 케이스는 통과했지만, 제출은 성공하지 못했다

# 문제풀이(3)
def solution(participant, completion):

    participant.sort()
    completion.sort()

    for i, j in zip(participant, completion):
        if i != j :
            return i
    return participant[-1]

# 처음에 participant와 completion 배열을 정렬을 해준다.
# zip 함수를 사용하여 participant와 completion 배열을 묶어준 뒤
# i와 j의 값이 같지 않다면 i를 return해주고
# 아니라면 participant배열의 마지막 값을 return 해준다.

# 다른 사람의 풀이(1)
import collections

def solution(participant, completion):
    answer = collections.Counter(participant) - collections.Counter(completion)
    return list(answer.keys())[0]

# collections 모듈을 사용한 풀이다.

print(solution(["leo", "kiki", "eden"], ["eden", "kiki"]))      # "leo"
print(solution(["marina", "josipa", "nikola", "vinko", "filipa"], ["josipa", "filipa", "marina", "nikola"]))        # "leo"
print(solution(["mislav", "stanko", "mislav", "ana"], ["stanko", "ana", "mislav"]))     # "mislav"


from bs4 import BeautifulSoup
import requests

def parse():
    url = 'https://omsk.shop.megafon.ru/mobile/apple'
    page = requests.get(url)
    soup = BeautifulSoup(page.text, "html.parser")

    block = soup.findAll('span', class_='b-price-good-list__actual b-price-good-list__actual_one b-price__actual')
    prices = []
    for data in block:
        if data.find('span', class_="b-price-good-list__value b-price__value"):
            price = float(data.text.strip().replace("\n", "").replace("Рублей", "").replace(" ", ""))
            prices.append(price)
    avg_price = sum(prices) / len(prices)
    min_price = min(prices)
    max_price = max(prices)
    print("Список всех цен: ")
    print(*prices, sep = ' рублей, ')
    print(f"Средняя цена: {avg_price:.2f} рублей")
    print(f"Минимальная цена: {min_price:.2f} рублей")
    print(f"Максимальная цена: {max_price:.2f} рублей")


# -*- coding: utf-8 -*-

import os
from setuptools import find_packages, setup

with open(os.path.join(os.path.dirname(__file__), 'README.md')) as readme:
    README = readme.read()

# allow setup.py to be run from any path
os.chdir(os.path.normpath(os.path.join(os.path.abspath(__file__), os.pardir)))

with open("botshot/version.py") as fp:
    version_dict = {}
    exec(fp.read(), version_dict)
    __version__ = version_dict['__version__']

setup(
    name='botshot',
    version=__version__,
    packages=find_packages(),
    include_package_data=True,
    license='GPL',
    description='A framework for creating stateful chatbots on Django.',
    long_description=README,
    long_description_content_type='text/markdown',
    url='https://github.com/prihoda/botshot',
    author='David Příhoda, Matúš Žilinec, Jakub Drdák',
    author_email='david.prihoda@gmail.com, zilinec.m@gmail.com',
    entry_points={
          'console_scripts': [
              'bots = botshot.bots:main'
          ]
      },
    classifiers=[
        'Development Status :: 4 - Beta',
        'Environment :: Web Environment',
        'Framework :: Django',
        'Intended Audience :: Developers',
        'License :: OSI Approved :: GNU General Public License v3 (GPLv3)',
        'Operating System :: OS Independent',
        'Programming Language :: Python',
        'Programming Language :: Python :: 3',
        'Programming Language :: Python :: 3.5',
        'Programming Language :: Python :: 3.6',
        # 'Programming Language :: Python :: 3.7',  Not compatible yet, waiting for Celery 4.3 !
        'Topic :: Internet :: WWW/HTTP',
        'Topic :: Internet :: WWW/HTTP :: Dynamic Content',
        'Topic :: Communications :: Chat',
    ],
    install_requires=['django>=2.1.5', 'networkx', 'requests', 'six', 'sqlparse', 'wit==4.3.0', 'wheel', 'redis', 'Pillow', 'jsonfield',
                      'pytz', 'unidecode', 'emoji', 'elasticsearch', 'celery>=4.1.1', 'python-dateutil', 'pyyaml', 'djangorestframework',
                      'pytest', 'pytest-django', 'mock'],
)


import asyncio
import aiohttp
from data.config import CLIENT_ID, CLIENT_SECRET, YOUTUBE_API
from pytube import YouTube

async def get_spotify_access_token():
    data = {
        'grant_type': 'client_credentials',
        'client_id': CLIENT_ID,
        'client_secret': CLIENT_SECRET,
    }

    async with aiohttp.ClientSession() as session:
        async with session.post('https://accounts.spotify.com/api/token', data=data) as response:
            response_json = await response.json()
            return response_json['access_token']

async def get_spotify_track_info(access_token, track_id):
    headers = {
        'Authorization': f'Bearer {access_token}',
    }

    async with aiohttp.ClientSession() as session:
        async with session.get(f'https://api.spotify.com/v1/tracks/{track_id}', headers=headers) as response:
            response_json = await response.json()
            return response_json

async def download_cover_image(image_url, path):
    async with aiohttp.ClientSession() as session:
        async with session.get(image_url) as response:
            image_data = await response.read()
            with open(f'temp/{path}/image_{path}.jpg', 'wb') as file:
                file.write(image_data)

async def search_youtube_video(track_title):
    params = {
        'part': 'snippet',
        'q': track_title,
        'maxResults': 1,
        'key': YOUTUBE_API,
    }
    async with aiohttp.ClientSession() as session:
        async with session.get('https://www.googleapis.com/youtube/v3/search', params=params) as response:
            response_json = await response.json()
            video_id = response_json['items'][0]['id']['videoId']
            return video_id

async def download_audio(video_id, path):
    youtube_url = f'https://youtu.be/{video_id}'
    yt = YouTube(youtube_url)
    audio = yt.streams.get_audio_only()
    audio_file = f"temp/{path}/audio_{path}.mp3"
    audio.download(filename=audio_file)


#ecoding: utf-8
import kivy
kivy.require('1.9.1')

# Testing github with pycharm

from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.core.window import Window
from kivy.uix.label import Label
from kivy.uix.behaviors.button import ButtonBehavior
from kivy.graphics import Color, Ellipse, Rectangle
from kivy.properties import ListProperty
from kivy.uix.popup import Popup
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.image import Image
from kivy.animation import Animation

class Gerenciador(ScreenManager):
    pass

class Menu(Screen):

    def on_pre_enter(self): #Éssa função é para mostrar o Popup quando apertardo o botão ESQ
        Window.bind(on_request_close=self.confirmar)

    def confirmar(self,*args,**kwargs):

        box = BoxLayout(orientation='vertical', padding=10, spacing=10)
        botoes = BoxLayout(spacing=10)
        pop = Popup(title='Deseja realmente sair?', content=box, size_hint=(None,None),
                    size=(180,180))
        imag = Image(source='icones/atencao.png')
        bt_sim = Botao(text='Sim',on_release=App.get_running_app().stop)
        bt_nao = Botao(text='Não', on_release=pop.dismiss)

        box.add_widget(imag)
        botoes.add_widget(bt_sim)
        botoes.add_widget(bt_nao)

        box.add_widget(botoes)

        anim_pop = Animation(size=(300,180), duration=.2, t="out_back")
        anim_pop.start(pop)

        anim_bt_sim = Animation(color=(0,0,0,1)) + Animation(color=(1,1,1,1))
        anim_bt_sim.start(bt_sim)
        anim_bt_sim.repeat = True

        pop.open()
        return True

class Competitivo(Screen):
    pass

class Botao(ButtonBehavior,Label):
    cor = ListProperty([.3,.3,.3,1])
    cor2 = ListProperty([0,0,0,1])

    def __init__(self,**kwargs):
        super(Botao,self).__init__(**kwargs)
        self.atualizar()

    def on_size(self,*kwargs):
        self.atualizar()
    def on_pos(self,*kwargs):
        self.atualizar()

    def on_cor(self,*args):
        self.atualizar()

    def on_press(self,*args):
        self.cor,self.cor2 = self.cor2,self.cor

    def on_release(self,*args):
        self.cor,self.cor2 = self.cor2,self.cor

    def atualizar(self):
        self.canvas.before.clear()
        with self.canvas.before:
            # Color(rgba=(.3,.3,.3,1))
            Color(rgba=self.cor)
            Ellipse(size=(self.height,self.height),
                    pos=(self.x,self.y))
            Ellipse(size=(self.height,self.height),
                    pos=(self.x+self.width-self.height,self.y))
            Rectangle(size=(self.width-self.height,self.height),
                      pos=(self.x+self.height/2.0, self.y))

class Game(Screen):
    lista_nome1 = list()
    lista_nome2 = list()
    lb_posicao = 1
    step = list()
    valida = 0
    pos2 = 0
    cont = 0
    retroceder_uma_vez = 0

    def __init__(self, **kwargs):
        super(Game,self).__init__(**kwargs)
        self.l_nome1 = Game.lista_nome1
        self.l_nome2 = Game.lista_nome2
        self.l_step = Game.step
        self.valida = Game.valida   # Para validar o botão "VS"
        self.pos2 = Game.pos2
        self.cont = Game.cont
        self.voltar_uma = Game.retroceder_uma_vez
        self.lb_posicao  = Game.lb_posicao
        self.step_cont = Game.cont

    def add_lista(self):
        """
        Adicionando os nomes na lista e apagando o nomes que foram escritos caixa de entrada "write_nome"
        :return:
        """
        if self.ids.entrada.text.capitalize().strip() in self.l_nome2 or self.ids.entrada.text.capitalize().strip() in self.l_nome1:
            self.ids.lb_entrada.text = str(self.ids.entrada.text.capitalize().strip() + ' já extende a lista de oponentes')
        elif self.ids.entrada.text != '':
            self.l_nome2.append(self.ids.entrada.text.capitalize().strip())
            self.ids.lb_entrada.text = 'Digite os nome dos jogadores'
            if len(self.l_nome1) > 0:
                self.ids.lb_entrada.text = self.ids.entrada.text.capitalize().strip() + ' Adicionado a fila'
        if len(self.ids.entrada.text) <= 0:
            self.ids.lb_entrada.text = 'Não foi digitado nenhum nome'
        if self.valida > 0:
            self.ids.quant_jogador.text = str(len(self.l_nome2) + 1)
            # self.lb_nome3["text"] = self.l_nome2[self.lb_posicao]
        else:
            self.ids.quant_jogador.text = str(len(self.l_nome2))
        self.ids.entrada.text = ''

    def destribui_nome(self):
        """
        Colocando os nomes nos botões de celeção
        :return:
        """
        if self.valida < 1:  # Aqui valida o botão "VS" para ser usado somente no começo da destribuição dos jogadore
            if len(self.l_nome2) > 2:
                self.l_nome1 = self.l_nome2[0]      #lista_nome1 recebendo a primeira posição da lista_nome2
                del(self.l_nome2[0])                #deletando o nome da lista_nome2 que foi passado pára para a lista_nome1
                self.ids.nome1.text = str(self.l_nome1)
                self.ids.nome2.text = str(self.l_nome2[0])
                self.ids.lb_nome3.text = self.l_nome2[1] # Mostrando o proximo jogador
                self.ids.quant_jogador.text = str(len(self.l_nome2)+1)
                self.valida +=1
            else:
                self.ids.lb_entrada.text = 'Digite pelomenos 3 nomes'

    # Logicá do programa de entradas de nomes
    def passando_nome1(self):
        # if self.step_cont == 1:
        #     self.cont = self.step_cont
        # else:
        #     self.step_cont = self.cont  # STEP_CONT RECEBE O CONTADOR DE VITÓRIA PARA REPOSICIONAR O ULTIMO RESULTADO DA VITORIA
        if self.ids.nome1.text != "Primeiro nome":
            self.pos2 += 1
            self.ids.lb_cont.text = str(self.cont)
            if self.ids.check_vitoria.active:  # celetor para ativar ou desativar o contador de vitórias
                self.cont += 1
                self.ids.lb_vitoria.text = 'Vitoria Ligada'
            else:
                self.ids.lb_vitoria.text = 'Vitoria pausada'
            if self.pos2 >= len(self.l_nome2):
                self.pos2 = 0
            self.lb_posicao = self.pos2
            self.ids.lb_cont.text = str(self.cont)
            self.lb_posicao += 1
            if self.lb_posicao >= len(self.l_nome2):
                self.lb_posicao = 0
            self.ids.nome2.text = str(self.l_nome2[self.pos2])
            self.ids.lb_nome3.text = self.l_nome2[self.lb_posicao]
        else:
            self.ids.lb_entrada.text = 'Caixa primeiro nome vázio!'
        self.step = ''
        self.voltar_uma = 0
        self.step_cont = self.cont  # STEP_CONT RECEBE O CONTADOR DE VITÓRIA PARA REPOSICIONAR O ULTIMO RESULTADO DA VITORIA

    def passando_nome2(self):
        if self.ids.nome2.text != "Segundo nome":
            self.step = self.l_nome2[self.pos2]
            self.l_nome2[self.pos2] = self.l_nome1
            self.l_nome1 = self.step
            self.pos2 += 1
            self.lb_posicao +=1

            self.cont = 1
            if self.ids.check_vitoria.active:
                self.cont = 1
                self.ids.lb_vitoria.text = 'Vitoria Ligada'
            else:
                self.ids.lb_vitoria.text = 'Vitoria Pausada'
            if self.pos2 >= len(self.l_nome2):
                self.pos2 = 0
            if self.lb_posicao >= len(self.l_nome2):
                self.lb_posicao = 0
            self.ids.lb_nome3.text = str(self.l_nome2[self.lb_posicao])
            self.ids.lb_cont.text = str(self.cont)
            self.ids.nome1.text = str(self.l_nome1)
            self.ids.nome2.text = str(self.l_nome2[self.pos2])
        else:
            self.ids.lb_entrada.text = 'Caixa segundo nome vázio!'
        self.voltar_uma = 0

    def retroceder(self):
        if len(self.l_nome2) > 0:
            if self.voltar_uma == 0:
                self.voltar_uma += 1
                if self.pos2 == 0:  # se a pos2 voltar para o zero ele ira receber o ultimo numero da lista que era oque esta
                    self.pos2 = len(self.l_nome2)-1
                else:
                    self.pos2 -= 1
                if self.lb_posicao == 0:
                    self.lb_posicao = len(self.l_nome2)-1
                else:
                    self.lb_posicao -= 1

                if len(self.step) > 0:
                    self.l_nome1 = self.l_nome2[self.pos2]
                    self.l_nome2[self.pos2] = self.step
                    self.step = ''
                    self.cont = self.step_cont
                    self.cont += 1
                    self.ids.nome1.text = str(self.l_nome1)
                    self.ids.nome2.text = str(self.l_nome2[self.pos2])
                    self.ids.lb_nome3.text = str(self.l_nome2[self.lb_posicao])
                else:
                    self.ids.nome2.text = str(self.l_nome2[self.pos2])
                    self.ids.lb_nome3.text = str(self.l_nome2[self.lb_posicao])
                self.cont -= 1
                self.ids.lb_cont.text = str(self.cont)
        else:
            self.ids.lb_entrada.text = 'Sem nome na lista'

    def deleta(self):
        if self.ids.entrada.text != '':
            if self.ids.entrada.text.capitalize() not in self.l_nome2:
                self.ids.lb_entrada.text = str(self.ids.entrada.text.capitalize() +' nome não estende a lista de jogadore')
            posicao = self.l_nome2.index(self.ids.entrada.text.capitalize())
            del (self.l_nome2[posicao])
            self.ids.lb_entrada.text = str(self.ids.entrada.text.capitalize() + ' Removido da lista')
            self.ids.entrada.text = ''
            self.ids.quant_jogador.text = str(len(self.l_nome2) + 1)
            if self.lb_posicao >= len(self.l_nome2):
                self.lb_posicao = 0
            self.ids.lb_nome3.text = self.l_nome2[self.lb_posicao]

    def lb_check(self):
        if self.ids.check_vitoria.active:
            self.ids.lb_vitoria.text = 'Vitoria Ligada'
        else:
            self.ids.lb_vitoria.text = 'Vitoria Pausada'
    #=========== Eventos de teclado ===========================
    def on_pre_enter(self):
        Window.bind(on_keyboard=self.salvar)

    def salvar(self,window,key,*args):
        if key == 13:
            self.add_lista()
        if key == 27:
            App.get_running_app().root.current = 'Menu'
            return True

    def on_pre_leave(self):
        Window.unbind(on_keyboard=self.salvar)

    def sair(self):
        Menu().confirmar()

class MkApp(App):
    def build(self):
        return Gerenciador()

MkApp().run()


import json
import urllib2

import ipaddress
from django.conf import settings
from django.http import HttpResponse

from app.services.models import Event

def initialize_webhook_addresses():
    """
    Adds the webhook addresses to the settings variable.
    """
    if not hasattr(settings, 'GITHUB_IP_ADDRESSES'):
        blocks = get_api_data('https://api.github.com/meta')
        blocks = blocks['hooks']
        addresses = []
        for block in blocks:
            addresses += map(lambda ip: str(ip), list(ipaddress.ip_network(block).hosts()))
        setattr(settings, 'GITHUB_IP_ADDRESSES', addresses)

    return None

def get_client_ip(request):
    """
    Gets the client's ip address from a request object.
    """
    forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR', None)
    real_ip = request.META.get('HTTP_X_REAL_IP', None)
    if forwarded_for:
        return forwarded_for.split(',')[0]
    elif real_ip:
        return real_ip
    return request.META.get('REMOTE_ADDR')

def get_api_data(url, headers=None):
    """
    Makes a request to the specified API for data, defaults to getting
    json data.

    @param url: String, the url to make the request to
    @param headers: Dictionary of headers
    @return: dict
    """
    if headers is None:
        headers = {"Content-type": "application/json"}

    try:
        req = urllib2.urlopen(url)
        return json.loads(req.read())
    except (urllib2.HTTPError, urllib2.URLError):
        pass
    return None

def get_contributors():
    """
    Gets a list of the contributors to the Github project.

    @return: list
    """
    if hasattr(settings, "PROJECT_CONTRIBUTORS"):
        return settings.PROJECT_CONTRIBUTORS

    contributors_list = get_api_data(settings.CONTRIBUTORS_URL)
    contributors_list = [] if contributors_list is None else contributors_list
    contributors = []

    for contributor in contributors_list:
        contributor = get_api_data(contributor['url'])
        if contributor is not None:
            contributors.append(contributor)

    setattr(settings, "PROJECT_CONTRIBUTORS", contributors)
    return contributors

def json_response(data, success=True):
    """
    Creates a HttpResponse for returning json data.

    @param data: Object
    @return: HttpResponse
    """
    return HttpResponse(json.dumps({
            'response': data,
            'success': success
        }, separators=(',', ':'), indent=4),
        content_type="application/json", status=200)


"""
Email backends.
"""

from django.core.mail.backends.base import BaseEmailBackend

from django_yubin import queue_email_message

class QueuedEmailBackend(BaseEmailBackend):
    """
    A wrapper that manages a queued SMTP system.
    """

    def send_messages(self, email_messages):
        """
        Add new messages to the email queue.

        The ``email_messages`` argument should be one or more instances
        of Django's core mail ``EmailMessage`` class.
        """
        num_sent = 0
        for email_message in email_messages:
            num_sent += queue_email_message(email_message)
        return num_sent


import abc
import enum
import types

import dbus

from into_dbus_python import xformers

_IDENTITY = lambda x: x # pragma: no cover

def _option_to_tuple(value, default):
    """
    Converts a Python "option" type, None or a value, to a tuple.

    :param object value: any value
    :param object default: a valid default to use if value is None
    :returns: a tuple encoding the meaning of value
    :rtypes: bool * object
    """
    return (False, default) if value is None else (True, value)

def _info_to_xformer(specs):
    """
    Function that yields a xformer function.

    :param specs: specifications for this function
    :type names: iterable of triples, name, inxform function, sig
    :return: a transformation function
    :rtype: (list of object) -> (list of object)
    """
    inxforms = [y for (_, y, _) in specs]
    outxforms = [f for (f, _) in xformers("".join(z for (_, _, z) in specs))]
    expected_length = len(specs)

    def xformer(objects):
        """
        Transforms a list of objects to dbus-python types.

        :param objects: list of objects
        :type objects: list of object
        :returns: a transformed list of objects
        :rtype: list of object
        """
        if len(objects) != expected_length:
            raise ValueError("wrong number of objects")

        return \
           [x for (x, _) in (f(g(a)) for \
           ((f, g), a) in zip(zip(outxforms, inxforms), objects))]

    return xformer

def _xformers(key_to_sig):
    """
    Get a map from keys to functions from a map of names to signatures.

    :param key_to_sig: a map from keys to signatures
    :type key_to_sig: dict of object * str
    :returns: a map from keys to functions
    :rtype: dict of object * xformation function
    """
    return dict(
       (method, ([n for (n, _, _) in specs], _info_to_xformer(specs))) for \
       (method, specs) in key_to_sig.items())

class InterfaceSpec(abc.ABC):
    """
    Parent class for an interface hierarchy.
    """
    # pylint: disable=too-few-public-methods

    INTERFACE_NAME = abc.abstractproperty(doc="interface name")
    INPUT_SIGS = \
       abc.abstractproperty(doc="map from method name to input signatures")
    OUTPUT_SIGS = \
       abc.abstractproperty(doc="map from method name to output signatures")
    XFORMERS = abc.abstractproperty(doc="map from method name to xformer")
    PROPERTY_SIGS = abc.abstractproperty(doc="map from property names to sigs")

class ObjectManagerSpec(InterfaceSpec):
    """
    org.freedesktop.DBus.ObjectManager interface
    """
    # pylint: disable=too-few-public-methods

    class MethodNames(enum.Enum):
        """
        Method names.
        """
        GetManagedObjects = "GetManagedObjects"

    class PropertyNames(enum.Enum):
        """
        Property names.
        """
        pass

    INTERFACE_NAME = "org.freedesktop.DBus.ObjectManager"

    INPUT_SIGS = {
       MethodNames.GetManagedObjects: (),
    }

    OUTPUT_SIGS = {
       MethodNames.GetManagedObjects: "a{oa{sa{sv}}}"
    }
    XFORMERS = _xformers(INPUT_SIGS)

    PROPERTY_SIGS = {}

class FilesystemSpec(InterfaceSpec):
    """
    Filesystem interface.
    """
    # pylint: disable=too-few-public-methods

    class MethodNames(enum.Enum):
        """
        Names of the methods of the Filesystem class.
        """
        SetName = "SetName"

    class PropertyNames(enum.Enum):
        """
        Names of the properties of the Filesystem interface.
        """
        Name = "Name"
        Pool = "Pool"
        Uuid = "Uuid"

    INTERFACE_NAME = 'org.storage.stratis1.filesystem'

    INPUT_SIGS = {
       MethodNames.SetName: (("name", _IDENTITY, "s"),),
    }
    OUTPUT_SIGS = {
       MethodNames.SetName: "bqs",
    }
    XFORMERS = _xformers(INPUT_SIGS)

    PROPERTY_SIGS = {
       PropertyNames.Name: "s",
       PropertyNames.Pool: "o",
       PropertyNames.Uuid: "s",
    }

class ManagerSpec(InterfaceSpec):
    """
    Manager interface.
    """
    # pylint: disable=too-few-public-methods

    class MethodNames(enum.Enum):
        """
        The method names of the manager interface.
        """
        ConfigureSimulator = "ConfigureSimulator"
        CreatePool = "CreatePool"
        DestroyPool = "DestroyPool"

    class PropertyNames(enum.Enum):
        """
        Names of the properties of the manager interface.
        """
        ErrorValues = "ErrorValues"
        RedundancyValues = "RedundancyValues"
        Version = "Version"

    INTERFACE_NAME = 'org.storage.stratis1.Manager'

    INPUT_SIGS = { # pragma: no cover
        MethodNames.ConfigureSimulator : (("denominator", _IDENTITY, "u"),),
        MethodNames.CreatePool :
           (
              ("name", _IDENTITY, "s"),
              ("redundancy", (lambda x: _option_to_tuple(x, 0)), "(bq)"),
              ("force", _IDENTITY, "b"),
              ("devices", _IDENTITY, "as"),
           ),
        MethodNames.DestroyPool : (("pool", _IDENTITY, "o"),),
    }
    OUTPUT_SIGS = {
        MethodNames.ConfigureSimulator : "qs",
        MethodNames.CreatePool : "(oas)qs",
        MethodNames.DestroyPool : "bqs",
    }
    XFORMERS = _xformers(INPUT_SIGS)

    PROPERTY_SIGS = {
       PropertyNames.ErrorValues: "a(sq)",
       PropertyNames.RedundancyValues: "a(sq)",
       PropertyNames.Version: "s"
    }

class PoolSpec(InterfaceSpec):
    """
    Pool interface.
    """
    # pylint: disable=too-few-public-methods

    class MethodNames(enum.Enum):
        """
        Names of the methods of the Pool class.
        """
        AddDevs = "AddDevs"
        CreateFilesystems = "CreateFilesystems"
        DestroyFilesystems = "DestroyFilesystems"
        SetName = "SetName"

    class PropertyNames(enum.Enum):
        """
        Names of the properties of the manager interface.
        """
        Name = "Name"
        Uuid = "Uuid"

    INTERFACE_NAME = 'org.storage.stratis1.pool'

    INPUT_SIGS = { # pragma: no cover
       MethodNames.AddDevs:
          (("force", _IDENTITY, "b"), ("devices", _IDENTITY, "as"),),
       MethodNames.CreateFilesystems: (("specs", _IDENTITY, "as"),),
       MethodNames.DestroyFilesystems: (("filesystems", _IDENTITY, "ao"),),
       MethodNames.SetName: (("name", _IDENTITY, "s"),)
    }
    OUTPUT_SIGS = {
       MethodNames.AddDevs: "asqs",
       MethodNames.CreateFilesystems: "a(os)qs",
       MethodNames.DestroyFilesystems: "asqs",
       MethodNames.SetName: "bqs"
    }
    XFORMERS = _xformers(INPUT_SIGS)

    PROPERTY_SIGS = {
       PropertyNames.Name: "s",
       PropertyNames.Uuid: "s",
    }

def _prop_builder(spec):
    """
    Returns a function that builds a property interface based on 'spec'.

    :param spec: the interface specification
    :type spec: type, a subtype of InterfaceSpec
    """

    def builder(namespace):
        """
        The property class's namespace.

        :param namespace: the class's namespace
        """

        def build_property(prop): # pragma: no cover
            """
            Build a single property getter for this class.

            :param prop: the property
            """

            def dbus_func(proxy_object): # pragma: no cover
                """
                The property getter.
                """
                return proxy_object.Get(
                   spec.INTERFACE_NAME,
                   prop.name,
                   dbus_interface=dbus.PROPERTIES_IFACE
                )

            return dbus_func

        for prop in spec.PropertyNames:
            namespace[prop.name] = staticmethod(build_property(prop)) # pragma: no cover

    return builder

def _iface_builder(spec):
    """
    Returns a function that builds a method interface based on 'spec'.

    :param spec: the interface specification
    :type spec: type, a subtype of InterfaceSpec
    """

    def builder(namespace):
        """
        Builds the class.

        :param namespace: the class's namespace
        """

        def build_method(method):
            """
            Build a single method for this class.

            :param method: the method
            """
            (names, func) = spec.XFORMERS[method]

            def dbus_func(proxy_object, **kwargs): # pragma: no cover
                """
                The function method spec.
                """
                if frozenset(names) != frozenset(kwargs.keys()):
                    raise ValueError("Bad keys")
                args = \
                   [v for (k, v) in \
                   sorted(kwargs.items(), key=lambda x: names.index(x[0]))]
                xformed_args = func(args)
                dbus_method = getattr(proxy_object, method.name)
                return dbus_method(
                   *xformed_args,
                   dbus_interface=spec.INTERFACE_NAME
                )

            return dbus_func

        for method in spec.MethodNames:
            namespace[method.name] = staticmethod(build_method(method))

        namespace['Properties'] = \
           types.new_class(
              "Properties",
              bases=(object,),
              exec_body=_prop_builder(spec)
           )

    return builder

ObjectManager = types.new_class(
   "ObjectManager",
   bases=(object,),
   exec_body=_iface_builder(ObjectManagerSpec)
)
Filesystem = types.new_class(
   "Filesystem",
   bases=(object,),
   exec_body=_iface_builder(FilesystemSpec)
)
Manager = types.new_class(
   "Manager",
   bases=(object,),
   exec_body=_iface_builder(ManagerSpec)
)
Pool = \
   types.new_class("Pool", bases=(object,), exec_body=_iface_builder(PoolSpec))


import numpy as np
import numpy.random as npr
import random
import matplotlib.pyplot as plt
import sys
import os
os.environ['KMP_DUPLICATE_LIB_OK']='True'

from SwingyMonkey import SwingyMonkey

import torch
import torch.nn as nn

# implement neural net using pytorch
class Neural_Network(nn.Module):
  def __init__(self):
    super(Neural_Network, self).__init__()
    self.input_dim = 4
    self.hidden_dim = 16
    self.output_dim = 2

    self.fc1 = nn.Linear(self.input_dim, self.hidden_dim)
    self.fc2 = nn.Linear(self.hidden_dim, self.output_dim, bias=None) # initialize simple NN structure

  def forward(self, X):
    X = torch.relu(self.fc1(X)) # pass through first layer
    X = self.fc2(X) # pass through second layer
    return X

class Learner:
  '''Class type to play the game'''

  def __init__(self, alpha, gamma, batch_size, mem_size):
    self.last_state  = None
    self.last_action = None
    self.last_reward = None
    self.alpha = alpha
    self.gamma = gamma
    self.batch_size = batch_size
    self.mem_size = mem_size
    self.tick = 0
    self.transition_hist = torch.ones(size=(self.mem_size, 2, 4))
    self.action_hist = np.ones(self.mem_size, dtype=int)
    self.reward_hist = np.ones(self.mem_size)
    self.pred_NN = Neural_Network()
    self.target_NN = Neural_Network()
    self.optimizer = torch.optim.Adam(self.pred_NN.parameters(), lr=alpha)
    self.criterion = nn.MSELoss()
    self.score = 0
    self.max_score = 0
    self.count = 0
    self.current = 0
    self.loss_val = []

  def reset(self):
    self.last_state  = None
    self.last_action = None
    self.last_reward = None
    self.score = 0

  def action_callback(self, state):

    self.score = state['score'] # update score
    new_state = self.state_parser(state) # parse new state for input

    if self.count < self.batch_size:
      if self.last_reward is not None:
        self.update_history(new_state)
      new_action = (0 if npr.rand() < 0.1 else 1)
    else:
      self.tick += 1 # track iterations
      if self.last_reward is not None:
        self.update_history(new_state)

      prev_states, prev_actions, prev_rewards = self.mem_replay()
      # prev_states = torch.tensor(prev_states)

      self.optimizer.zero_grad()

      for i in range(self.batch_size):
        # pred_Q = self.pred_NN(prev_states[i,0,:])[prev_actions[i]]

        # ns = prev_states[i,1,:]
        # best_action = self.pred_NN(ns).argmax()
        # q_val = self.target_NN(ns)[best_action]
        # target_Q = prev_rewards[i] + self.gamma*q_val

        # self.optimizer.zero_grad() # zero gradient buffer (order s.t. gradient step only based on prediction)

        # loss = self.loss(pred_Q, target_Q)
        loss = self.loss(s=prev_states[i,0,:],
                         a=prev_actions[i],
                         r=prev_rewards[i],
                         ns=prev_states[i,1,:])

        self.loss_val.append(loss)
        # print(loss.item())
        loss.backward() # set up gradients in buffer
        # print(self.pred_NN.fc1.bias.grad)
        # self.optimizer.step() # perform update

      self.optimizer.step()

      self.tick += 1 # track iterations

      # take action based on epsilon-greedy
      if npr.rand() < max(1/self.tick, 0.1):
        new_action = (0 if npr.rand() < 0.5 else 1)
      else:
        # print(self.pred_NN(torch.tensor(new_state)))
        new_action = self.pred_NN(torch.tensor(new_state)).argmax() # new action

    # update second neural network as needed
    if self.tick % 200 == 0:
      torch.save(self.pred_NN, 'NN')
      self.target_NN = torch.load('NN')
      self.target_NN.eval()

    self.last_action = int(new_action) # update state and action
    self.last_state = new_state

    return self.last_action

  def reward_callback(self, reward):
    '''This gets called so you can see what reward you get.'''

    self.last_reward = reward

  def state_parser(self, state):
    s = [state['tree']['dist'],
        # state['tree']['top'],
        state['tree']['bot'],
        state['monkey']['vel'],
        # state['monkey']['top'],
        state['monkey']['bot']]
    return s

  def update_history(self, new_state):
    self.transition_hist[self.current, ...] = torch.tensor([self.last_state, new_state])
    self.action_hist[self.current] = self.last_action
    self.reward_hist[self.current] = self.last_reward

    self.count = max(self.count, self.current+1)
    self.current = (self.current + 1) % self.mem_size

  def mem_replay(self):
    idx = []
    for _ in range(self.batch_size):
      idx.append(npr.randint(0, self.count))
    return self.transition_hist[idx, :], self.action_hist[idx], self.reward_hist[idx]

  # def loss(self, pred_Q, target_Q):
  #   return (target_Q - pred_Q)**2

  def loss(self, s, a, r, ns):
    pred_Q = self.pred_NN(s)[a]

    best_action = self.pred_NN(ns).argmax()
    q_val = self.target_NN(ns)[best_action]
    target_Q = r + self.gamma*q_val

    return (target_Q - pred_Q)**2

iters = 200
learner = Learner(alpha = 0.1, gamma = 0.7, batch_size=10, mem_size=10000)
scores = []

for ii in range(iters):

  # Make a new monkey object.
  swing = SwingyMonkey(sound=False,            # Don't play sounds.
                       text="Epoch %d" % (ii), # Display the epoch on screen.
                       tick_length=1,          # Make game ticks super fast.
                       action_callback=learner.action_callback,
                       reward_callback=learner.reward_callback)

  # Loop until you hit something.
  while swing.game_loop():
    pass

  # Reset the state of the learner.
  scores.append(learner.score)
  learner.reset()

fig = plt.figure(figsize=(18,6))
plt.plot(np.arange(0,len(scores)), scores)
plt.xlabel('Iteration')
plt.ylabel('Score')

fig = plt.figure(figsize=(18,6))
plt.plot(np.arange(0,len(learner.loss_val)), learner.loss_val)
plt.xlabel('Iteration')
plt.ylabel('Loss')
plt.show()


#!/usr/bin/python

import sys
import time
import os
import fnmatch
from argparse import ArgumentParser
from argparse import RawTextHelpFormatter
from datetime import datetime
from datetime import timedelta
from glob import glob
import pygsf
import shapefile

def main():
	parser = ArgumentParser(description='Read GSF file and create an ESRI shape file of the trackplot.',
			epilog='Example: \n To convert a single file use -i c:/temp/myfile.gsf \n to convert GSF files in a folder use -i c:/temp/*.gsf\n To convert all .GSF files recursively in a folder, use -r -i c:/temp \n To convert all files recursively from the current folder, use -r -i ./ \n', formatter_class=RawTextHelpFormatter)
	parser.add_argument('-i', dest='inputFile', action='store', help='-i <filename.gsf> : input filename to process. It can also be a wildcard, e.g. *.gsf')
	parser.add_argument('-o', dest='outputFile', action='store', default='track.shp', help='-o <SHPfilename.shp> : output filename to create. e.g. trackplot.shp [Default: track.shp]')
	parser.add_argument('-s', dest='step', action='store', default='1', help='step size in seconds.  Useful to reduce the complexity of the feature, which keeps ArcMap fastt. [Default: 1]')
	parser.add_argument('-r', action='store_true', default=False, dest='recursive', help='-r : search recursively.  [Default: False]')
	if len(sys.argv)==1:
		parser.print_help()
		sys.exit(1)

	args = parser.parse_args()
	# we need to remember the previous record so we only create uniq values, not duplicates
	fileOut = args.outputFile
	stepSize = float(args.step)
	if not fileOut.lower().endswith('.shp'):
		fileOut += '.shp'

	fileCounter=0
	matches = []
	lastTimeStamp = 0
	trackRecordCount = 0

	if args.recursive:
		for root, dirnames, filenames in os.walk(os.path.dirname(args.inputFile)):
			for f in fnmatch.filter(filenames, '*.GSF'):
				matches.append(os.path.join(root, f))
				print (matches[-1])
	else:
		for filename in glob(args.inputFile):
			matches.append(filename)
		print (matches)
	if len(matches) == 0:
		print ("Nothing found to convert, quitting")
		exit()

	if os.path.isfile(fileOut):
		try:
			# Create a shapefile reader
			r = shapefile.Reader(fileOut)
			# Create a shapefile writer
			# using the same shape type
			# as our reader
			w = shapefile.Writer(r.shapeType)
			# Copy over the existing dbf fields
			w.fields = list(r.fields)
			# Copy over the existing dbf records
			w.records.extend(r.records())
			# Copy over the existing polygons
			w._shapes.extend(r.shapes())
		except shapefile.error:
			print ("Problem opening existing shape file, aborting!")
			exit()
	else:
		# w = shapefile.Writer(shapefile.POINTZ)
		w = shapefile.Writer(shapefile.POLYLINE)
		w.autoBalance = 1
		w.field("LineName", "C")
		# w.field("WaterDepth", "N")
		w.field("UNIXTime", "N")
		w.field("SurveyDate", "D")

	for filename in matches:
		# print ("processing file: %s" % filename)
		line_parts = []
		line = []

		r = pygsf.GSFREADER(filename)
		start_time = time.time() # time  the process
		navigation = r.loadnavigation()
		for update in navigation:
			if update[0] - lastTimeStamp > stepSize:
				line.append([float(update[1]),float(update[2])])
				trackRecordCount += 1
				lastTimeStamp = update[0]
		# now add the very last update
		line.append([float(navigation[-1][1]),float(navigation[-1][2])])

		line_parts.append(line)
		w.line(parts=line_parts)
		# now add to the shape file.
		recTimeStamp = from_timestamp(navigation[0][0]).strftime("%Y/%m/%d %H:%M:%S")
		recDate = from_timestamp(navigation[0][0]).strftime("%Y%m%d")
		# depth = 1111.123
		w.record(os.path.basename(filename), int(navigation[0][0]), recDate)
		# w.record(os.path.basename(filename), depth, navigation[0][0], recDate)

		update_progress("Processed: %s (%d/%d)" % (filename, fileCounter, len(matches)), (fileCounter/len(matches)))
		lastTimeStamp = update[0]
		fileCounter +=1
		r.close()

	update_progress("Process Complete: ", (fileCounter/len(matches)))
	print ("Saving shapefile: %s position updates added %d" % (fileOut, trackRecordCount))
	w.save(fileOut)

	# now write out a prj file so the data has a spatial Reference
	f = open(fileOut.replace('.shp','.prj'), 'w')
	f.write('GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]') # python will convert \n to os.linesep
	f.close() # you can omit in most cases as the destructor will call it
	print("Duration %.3fs" % (time.time() - start_time )) # time the process

def from_timestamp(unixtime):
	return datetime(1970, 1 ,1) + timedelta(seconds=unixtime)

def update_progress(job_title, progress):
	length = 20 # modify this to change the length
	block = int(round(length*progress))
	msg = "\r{0}: [{1}] {2}%".format(job_title, "#"*block + "-"*(length-block), round(progress*100, 2))
	if progress >= 1: msg += " DONE\r\n"
	sys.stdout.write(msg)
	sys.stdout.flush()

if __name__ == "__main__":
	main()


from __future__ import absolute_import

'''Resnet for cifar dataset.
Ported form
https://github.com/facebook/fb.resnet.torch
and
https://github.com/pytorch/vision/blob/master/torchvision/models/resnet.py
(c) YANG, Wei
'''
import torch.nn as nn
import math

__all__ = ['resnet']

def conv3x3(in_planes, out_planes, stride=1):
    "3x3 convolution with padding"
    return nn.Conv2d(in_planes, out_planes, kernel_size=3, stride=stride,
                     padding=1, bias=False)

class BasicBlock(nn.Module):
    expansion = 1
    # Basicblock for cifar10 / cifar100
    def __init__(self, inplanes, planes, stride=1, downsample=None):
        super(BasicBlock, self).__init__()
        self.conv1 = conv3x3(inplanes, planes, stride)
        self.bn1 = nn.BatchNorm2d(planes)
        self.relu = nn.ReLU(inplace=True)
        self.conv2 = conv3x3(planes, planes)
        self.bn2 = nn.BatchNorm2d(planes)
        self.downsample = downsample
        self.stride = stride

    def forward(self, x):
        residual = x

        out = self.conv1(x)
        out = self.bn1(out)
        out = self.relu(out)

        out = self.conv2(out)
        out = self.bn2(out)

        if self.downsample is not None:
            residual = self.downsample(x)

        out += residual
        out = self.relu(out)

        return out

class Bottleneck(nn.Module):
    expansion = 4

    def __init__(self, inplanes, planes, stride=1, downsample=None):
        super(Bottleneck, self).__init__()
        self.conv1 = nn.Conv2d(inplanes, planes, kernel_size=1, bias=False)
        self.bn1 = nn.BatchNorm2d(planes)
        self.conv2 = nn.Conv2d(planes, planes, kernel_size=3, stride=stride,
                               padding=1, bias=False)
        self.bn2 = nn.BatchNorm2d(planes)
        self.conv3 = nn.Conv2d(planes, planes * 4, kernel_size=1, bias=False)
        self.bn3 = nn.BatchNorm2d(planes * 4)
        self.relu = nn.ReLU(inplace=True)
        self.downsample = downsample
        self.stride = stride

    def forward(self, x):
        residual = x

        out = self.conv1(x)
        out = self.bn1(out)
        out = self.relu(out)

        out = self.conv2(out)
        out = self.bn2(out)
        out = self.relu(out)

        out = self.conv3(out)
        out = self.bn3(out)

        if self.downsample is not None:
            residual = self.downsample(x)

        out += residual
        out = self.relu(out)

        return out

class ResNet(nn.Module):
   # Basicblock for cifar10 / cifar100
    def __init__(self, depth, num_classes=1000, block_name='BasicBlock'):
        super(ResNet, self).__init__()
        # Model type specifies number of layers for CIFAR-10 model    以110层为例
        if block_name.lower() == 'basicblock':
            assert (depth - 2) % 6 == 0, 'When use basicblock, depth should be 6n+2, e.g. 20, 32, 44, 56, 110, 1202'
            n = (depth - 2) // 6   # 18
            block = BasicBlock
        elif block_name.lower() == 'bottleneck':                                                    #     12
            assert (depth - 2) % 9 == 0, 'When use bottleneck, depth should be 9n+2, e.g. 20, 29, 47, 56, 110, 1199'
            n = (depth - 2) // 9   # 12
            block = Bottleneck
        else:
            raise ValueError('block_name shoule be Basicblock or Bottleneck')

        self.inplanes = 16
        self.conv1 = nn.Conv2d(3, 16, kernel_size=3, padding=1, bias=False)  # 3*3 通道 3 --> 16
        self.bn1 = nn.BatchNorm2d(16)                                            # 通道 16 --> 16
        self.relu = nn.ReLU(inplace=True)                                        # 通道 16 --> 16

        self.layer1 = self._make_layer(block, 16, n)                             # 通道 16 --> 16
        self.layer2 = self._make_layer(block, 32, n, stride=2)                   # 通道 16 --> 32
        self.layer3 = self._make_layer(block, 64, n, stride=2)                   # 通道 32 --> 64

        self.avgpool = nn.AvgPool2d(8)  # 池化窗口 大小为8*8
        self.fc = nn.Linear(64 * block.expansion, num_classes)                  # 64 --> 100

        # self.convShare = nn.Conv2d(3, 16, kernel_size=3, padding=1, bias=False)  # 共享投影层
        for m in self.modules():
            if isinstance(m, nn.Conv2d):
                n = m.kernel_size[0] * m.kernel_size[1] * m.out_channels
                m.weight.data.normal_(0, math.sqrt(2. / n))
            elif isinstance(m, nn.BatchNorm2d):
                m.weight.data.fill_(1)
                m.bias.data.zero_()
                    #     什么块  输出通道 多少块    步长
    def _make_layer(self, block, planes, blocks, stride=1):   # 通用块
        downsample = None

        #     步幅 不为1      上一个层级输出通道  不等于 这一层级输出通道
        if stride != 1 or self.inplanes != planes * block.expansion:
            downsample = nn.Sequential(
                nn.Conv2d(self.inplanes, planes * block.expansion,
                          kernel_size=1, stride=stride, bias=False),
                nn.BatchNorm2d(planes * block.expansion),
            )

        layers = []
        #               输入通道 = 上一级大Blocks块的输出通道
        #                       输入通道   输出通道
        layers.append(block(self.inplanes, planes, stride, downsample))  # 只有刚进该大块的时候 把图片尺寸卷成了一半
        self.inplanes = planes * block.expansion    # 输入通道等于第一个小Block块的输出通道
        for i in range(1, blocks):  # 每个大块 各有18个 BasicBlock  填入剩下的17个小Block块
                            #     输入通道        输出通道
            layers.append(block(self.inplanes, planes))

        return nn.Sequential(*layers)

    def forward(self, x):
        x = self.conv1(x)
        x = self.bn1(x)
        x = self.relu(x)    # 32x32

        x = self.layer1(x)  # 32x32
        x = self.layer2(x)  # 16x16
        x = self.layer3(x)  # 8x8

        x = self.avgpool(x)
        x = x.view(x.size(0), -1)
        x = self.fc(x)

        return x

def resnet(**kwargs):
    """
    Constructs a ResNet model.
    """
    return ResNet(**kwargs)


from django.shortcuts import render,redirect, get_object_or_404
from .models import Video, Comment_Model, ReplyModel, Rating
from .forms import VideoUpload, CommentForm, ReplyCommentForm, RatingForm
from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import User
from django.http import HttpResponseRedirect

# Create your views here.

@login_required(login_url='login')
def file_upload(request):
    form = VideoUpload()
    user_id = User.objects.get(id=request.user.id)
    if request.method == 'POST':
        form = VideoUpload(request.POST or None, request.FILES or None)
        if form.is_valid():
            form_obj = form.save(commit=False)
            form_obj.user = user_id
            form_obj.save()
            return redirect('profile')
    return render(request, 'app/upload.html', {'form': form})

def show_video(request): # Show Video List in UI
    videos= Video.objects.filter(make_privet=False).order_by('-created_on')
    if videos is not None:
        return render(request, 'app/index.html', {'video': videos})

@login_required(login_url='login')
def add_ratting(request, video_id):
    url = request.META.get('HTTP_REFERER')

    if request.method == 'POST':
        try:
            ratings = Rating.objects.get(video_id=video_id, user=request.user)
            ratings.delete()
        except:
            ratings = None
        rating = request.POST.get('rating')
        rating_obj = Rating(user=request.user, video_id=video_id, rating=rating)
        rating_obj.save()
        return HttpResponseRedirect(url)

    return HttpResponseRedirect(url)

def play_video(request, id): # Show clicked Video with list into UI
    url = request.META.get('HTTP_REFERER')
    video = Video.objects.get(pk=id)
    list = Video.objects.all().order_by('-created_on')
    comments = Comment_Model.objects.filter(is_aproved=True, comment_video=video)
    ratings = Rating.objects.filter(video=video)

    if request.method =='POST':
        url = request.META.get('HTTP_REFERER')
        user_id = User.objects.get(id=request.user.id)
        comment_form = CommentForm(request.POST)

        # comment section
        if comment_form.is_valid():
            comment_obj = comment_form.save(commit=False)
            comment_obj.comment_video = video
            comment_obj.comment_user=user_id
            comment_obj.save()
            return HttpResponseRedirect(url)

    total_rating =0
    avg_rating = 0
    no_rating = len(ratings)
    if ratings is not None:
        for rating in ratings:
            total_rating += rating.rating
            avg_rating = total_rating / no_rating;
            avg_rating= round(avg_rating, 1)

    rating_form = RatingForm()
    comment_form = CommentForm()
    context={'video': video,
             'list': list,
             'comments': comments,
             'comment_form': comment_form,
             'rating_form':rating_form,
             'no_rating':no_rating,
             'avg_rating': avg_rating, }
    return render(request, 'app/play.html', context)

@login_required(login_url='login')
def comment_reply(request, id):
    url = request.META.get('HTTP_REFERER')
    parent_comment = Comment_Model.objects.get(pk=id)
    child_comment = ReplyModel.objects.filter(comment=id)
    comment_form = ReplyCommentForm()
    if request.method == 'POST':
        comment_form = ReplyCommentForm(request.POST)
        if comment_form.is_valid():
            reply_obj = comment_form.save(commit=False)
            reply_obj.comment = parent_comment
            reply_obj.comment_user = request.user
            reply_obj.save()
            return HttpResponseRedirect(url)

    context= {
        'comment': parent_comment,
        'replys': child_comment,
        'form': comment_form

    }
    return render(request, 'app/reply.html', context)

@login_required(login_url='login')
def delete_view(request, id):
    url = request.META.get('HTTP_REFERER')
    video = Video.objects.get(pk=id)
    video.delete()
    return HttpResponseRedirect(url)

@login_required(login_url='login')
def delete_comment(request, id):
    url = request.META.get('HTTP_REFERER')
    comment = Comment_Model.objects.get(pk=id)
    comment.delete()
    return HttpResponseRedirect(url)

@login_required(login_url='login')
def delete_reply(request, comment, reply):
    url = request.META.get('HTTP_REFERER')
    reply_comment = ReplyModel.objects.get(pk=reply)
    reply_comment.delete()
    return HttpResponseRedirect(url)


"""
    This is Example of Python Mixin,
"""
import json

class Jsonizable(object):

    @classmethod
    def from_json(cls, data):
        kwargs = json.loads(data)
        return cls(**kwargs)

    def to_json(self):
        return json.dumps(self.__dict__)

class DeserializeObj(Jsonizable):

    def __init__(self, **kwargs):
        self.created_at = kwargs.pop("created_at", None)
        self.tags = kwargs.pop("tags", None)

if __name__ == "__main__":
    meta = DeserializeObj()
    meta.created_at = 1234567
    meta.tags = ["Node",]

    meta_str = meta.to_json()
    print(meta_str)

    meta2 = DeserializeObj.from_json(meta_str)
    print(meta2.created_at)
    print(meta2.tags)
    print(meta2.to_json())