from collections import defaultdict

class IntcodeComputer:
    def __init__(self, intcode, silent=False,
                 feedback_mode=False, ascii_mode=False):
        self.intcode = defaultdict(int, {i: x for i, x in enumerate(intcode)})
        self.original_intcode = self.intcode.copy()
        self.silent = silent
        self.feedback_mode = feedback_mode
        self.ascii_mode = ascii_mode
        self.inputs = None
        self.pointer = 0
        self.relative_base = 0
        self.has_halted = False
        self.is_paused = False
        self.output = None
        self.get_position = (
            self.get_position_in_position_mode,
            self.get_position_in_immediate_mode,
            self.get_position_in_relative_mode
        )
        self.opcode_methods = {
            1: self.add,
            2: self.multiply,
            3: self.read,
            4: self.print_and_or_pause,
            5: self.jump_if_true,
            6: self.jump_if_false,
            7: self.less_than,
            8: self.equals,
            9: self.change_relative_base,
            99: self.halt
        }

    def reset(self):
        self.intcode = self.original_intcode.copy()
        self.pointer = 0
        self.relative_base = 0
        self.has_halted = False
        self.is_paused = False
        self.output = None

    def get_next_instruction(self):
        instruction = str(self.intcode[self.pointer])
        opcode = int(instruction[-2:])
        parameters = [int(i) for i in instruction[-3::-1]]
        return opcode, parameters

    def run(self, inputs=None):
        if inputs is not None:
            if self.ascii_mode:
                inputs = [ord(inp) for inp in inputs]
                ascii_newline = ord("\n")
                if inputs[-1] != ascii_newline:
                    inputs.append(ascii_newline)
            # Reverse input because popping from the end is better.
            self.inputs = list(reversed(inputs))
        self.output = None
        self.is_paused = False
        while not (self.has_halted or self.is_paused):
            opcode, parameters = self.get_next_instruction()
            self.opcode_methods[opcode](parameters)
        if self.ascii_mode and self.output is not None:
            if self.output <= 0x10ffff:  # max value for chr()
                self.output = chr(self.output)
            else:
                self.output = str(self.output)
        return self.output

    def run_ascii(self, instructions=None):
        # Catch all the output into one string.
        # This is a bit hacky with the try...except... but I can't be bothered
        # to figure out where the errors come from.
        # This will also remain a method separate from self.run().
        output = [self.run(instructions)]
        while not self.has_halted:
            try:
                output.append(self.run())
            except (AttributeError, IndexError):
                break
        return "".join(x for x in output if x is not None)

    def get_positions(self, parameters, n):
        parameters += [0] * (n - len(parameters))
        return [self.get_position[param](pos)
                for pos, param in enumerate(parameters)]

    def get_position_in_position_mode(self, position):
        return self.intcode[self.pointer + position + 1]

    def get_position_in_immediate_mode(self, position):
        return self.pointer + position + 1

    def get_position_in_relative_mode(self, position):
        return self.intcode[self.pointer + position + 1] + self.relative_base

    def add(self, parameters):
        a, b, target = self.get_positions(parameters, 3)
        self.intcode[target] = self.intcode[a] + self.intcode[b]
        self.pointer += 4

    def multiply(self, parameters):
        a, b, target = self.get_positions(parameters, 3)
        self.intcode[target] = self.intcode[a] * self.intcode[b]
        self.pointer += 4

    def read(self, parameters):
        position = self.get_positions(parameters, 1)[0]
        self.intcode[position] = self.inputs.pop()
        self.pointer += 2

    def print_and_or_pause(self, parameters):
        position = self.get_positions(parameters, 1)[0]
        self.output = self.intcode[position]
        if not self.silent:
            print(self.output)
        if self.feedback_mode:
            self.is_paused = True
        self.pointer += 2

    def jump_if_true(self, parameters):
        position, target = self.get_positions(parameters, 2)
        if self.intcode[position]:
            self.pointer = self.intcode[target]
        else:
            self.pointer += 3

    def jump_if_false(self, parameters):
        position, target = self.get_positions(parameters, 2)
        if self.intcode[position] == 0:
            self.pointer = self.intcode[target]
        else:
            self.pointer += 3

    def less_than(self, parameters):
        a, b, target = self.get_positions(parameters, 3)
        self.intcode[target] = int(self.intcode[a] < self.intcode[b])
        self.pointer += 4

    def equals(self, parameters):
        a, b, target = self.get_positions(parameters, 3)
        self.intcode[target] = int(self.intcode[a] == self.intcode[b])
        self.pointer += 4

    def change_relative_base(self, parameters):
        position = self.get_positions(parameters, 1)[0]
        self.relative_base += self.intcode[position]
        self.pointer += 2

    def halt(self, parameters):
        self.has_halted = True


"""Nexus Forge access point used by the Nexus access point"""

import getpass
import json
import logging
import pathlib

import jwt
from bluepyentity.state import refresh_token
from kgforge.core import KnowledgeGraphForge
from kgforge.core import Resource
from kgforge.core.commons.strategies import ResolvingStrategy
from kgforge.specializations.resources import Dataset

from bluepyemodel.efeatures_extraction.targets_configuration import TargetsConfiguration
from bluepyemodel.emodel_pipeline.emodel import EModel
from bluepyemodel.emodel_pipeline.emodel_settings import EModelPipelineSettings
from bluepyemodel.emodel_pipeline.emodel_workflow import EModelWorkflow
from bluepyemodel.evaluation.fitness_calculator_configuration import FitnessCalculatorConfiguration
from bluepyemodel.model.distribution_configuration import DistributionConfiguration
from bluepyemodel.model.neuron_model_configuration import NeuronModelConfiguration
from bluepyemodel.tools.utils import yesno

logger = logging.getLogger("__main__")

# pylint: disable=bare-except,consider-iterating-dictionary

CLASS_TO_NEXUS_TYPE = {
    "TargetsConfiguration": "ExtractionTargetsConfiguration",
    "EModelPipelineSettings": "EModelPipelineSettings",
    "FitnessCalculatorConfiguration": "FitnessCalculatorConfiguration",
    "NeuronModelConfiguration": "EModelConfiguration",
    "EModel": "EModel",
    "DistributionConfiguration": "EModelChannelDistribution",
    "EModelWorkflow": "EModelWorkflow",
}

CLASS_TO_RESOURCE_NAME = {
    "TargetsConfiguration": "ETC",
    "EModelPipelineSettings": "EMPS",
    "FitnessCalculatorConfiguration": "FCC",
    "NeuronModelConfiguration": "EMC",
    "EModel": "EM",
    "DistributionConfiguration": "EMCD",
    "EModelWorkflow": "EMW",
}

NEXUS_TYPE_TO_CLASS = {
    "ExtractionTargetsConfiguration": TargetsConfiguration,
    "EModelPipelineSettings": EModelPipelineSettings,
    "FitnessCalculatorConfiguration": FitnessCalculatorConfiguration,
    "EModelConfiguration": NeuronModelConfiguration,
    "EModel": EModel,
    "EModelChannelDistribution": DistributionConfiguration,
    "EModelWorkflow": EModelWorkflow,
}

NEXUS_ENTRIES = [
    "objectOfStudy",
    "contribution",
    "type",
    "id",
    "distribution",
    "@type",
    "annotation",
    "name",
]

class AccessPointException(Exception):
    """For Exceptions related to the NexusForgeAccessPoint"""

class NexusForgeAccessPoint:
    """Access point to Nexus Knowledge Graph using Nexus Forge"""

    def __init__(
        self,
        project="emodel_pipeline",
        organisation="demo",
        endpoint="https://bbp.epfl.ch/nexus/v1",
        forge_path=None,
        limit=5000,
        debug=False,
        cross_bucket=True,
        access_token=None,
        search_endpoint="sparql",
    ):

        self.limit = limit
        self.debug = debug
        self.cross_bucket = cross_bucket
        self.search_endpoint = search_endpoint

        self.access_token = access_token
        if not self.access_token:
            self.access_token = self.get_access_token()

        bucket = organisation + "/" + project
        self.forge = self.connect_forge(bucket, endpoint, self.access_token, forge_path)

        decoded_token = jwt.decode(self.access_token, options={"verify_signature": False})
        self.agent = self.forge.reshape(
            self.forge.from_json(decoded_token), keep=["name", "email", "sub", "preferred_username"]
        )
        self.agent.id = decoded_token["sub"]
        self.agent.type = ["Person", "Agent"]

        self._available_etypes = None
        self._available_mtypes = None
        self._available_ttypes = None

    @property
    def available_etypes(self):
        """List of ids of available etypes in this forge graph"""
        if self._available_etypes is None:
            self._available_etypes = self.get_available_etypes()
        return self._available_etypes

    @property
    def available_mtypes(self):
        """List of ids of available mtypes in this forge graph"""
        if self._available_mtypes is None:
            self._available_mtypes = self.get_available_mtypes()
        return self._available_mtypes

    @property
    def available_ttypes(self):
        """List of ids of available ttypes in this forge graph"""
        if self._available_ttypes is None:
            self._available_ttypes = self.get_available_ttypes()
        return self._available_ttypes

    def get_available_etypes(self):
        """Returns a list of nexus ids of all the etype resources using sparql"""
        query = """
            SELECT ?e_type_id

            WHERE {{
                    ?e_type_id label ?e_type ;
                        subClassOf* EType ;
            }}
        """
        # should we use self.limit here?
        resources = self.forge.sparql(query, limit=self.limit)
        if resources is None:
            return []
        return [r.e_type_id for r in resources]

    def get_available_mtypes(self):
        """Returns a list of nexus ids of all the mtype resources using sparql"""
        query = """
            SELECT ?m_type_id

            WHERE {{
                    ?m_type_id label ?m_type ;
                        subClassOf* MType ;
            }}
        """
        # should we use self.limit here?
        resources = self.forge.sparql(query, limit=self.limit)
        if resources is None:
            return []
        return [r.m_type_id for r in resources]

    def get_available_ttypes(self):
        """Returns a list of nexus ids of all the ttype resources using sparql"""
        query = """
            SELECT ?t_type_id

            WHERE {{
                    ?t_type_id label ?t_type ;
                        subClassOf* BrainCellTranscriptomeType ;
            }}
        """
        # should we use self.limit here?
        resources = self.forge.sparql(query, limit=self.limit)
        if resources is None:
            return []
        return [r.t_type_id for r in resources]

    @staticmethod
    def get_access_token():
        """Define access token either from bbp-workflow or provided by the user"""

        try:
            access_token = refresh_token()
        except:  # noqa: E722
            logger.info("Please get your Nexus access token from https://bbp.epfl.ch/nexus/web/.")
            access_token = getpass.getpass()

        return access_token

    @staticmethod
    def connect_forge(bucket, endpoint, access_token, forge_path=None):
        """Creation of a forge session"""

        if not forge_path:
            forge_path = (
                "https://raw.githubusercontent.com/BlueBrain/nexus-forge/"
                + "master/examples/notebooks/use-cases/prod-forge-nexus.yml"
            )

        forge = KnowledgeGraphForge(
            forge_path, bucket=bucket, endpoint=endpoint, token=access_token
        )

        return forge

    def add_contribution(self, resource):
        """Add the contributing agent to the resource"""

        if self.agent:

            if isinstance(resource, Dataset):
                resource.add_contribution(self.agent, versioned=False)
            elif isinstance(resource, Resource):
                resource.contribution = Resource(type="Contribution", agent=self.agent)

        return resource

    def resolve(self, text, scope="ontology", strategy="all", limit=1):
        """Resolves a string to find the matching ontology"""

        if strategy == "all":
            resolving_strategy = ResolvingStrategy.ALL_MATCHES
        elif strategy == "best":
            resolving_strategy = ResolvingStrategy.BEST_MATCH
        elif strategy == "exact":
            resolving_strategy = ResolvingStrategy.EXACT_MATCH
        else:
            raise Exception(
                f"Resolving strategy {strategy} does not exist. "
                "Strategy should be 'all', 'best' or 'exact'"
            )

        return self.forge.resolve(text, scope=scope, strategy=resolving_strategy, limit=limit)

    def register(
        self,
        resource_description,
        filters_existance=None,
        replace=False,
        distributions=None,
    ):
        """Register a resource from its dictionary description."""

        if "type" not in resource_description:
            raise AccessPointException("The resource description should contain 'type'.")

        previous_resources = None
        if filters_existance:

            previous_resources = self.fetch(filters_existance)

        if filters_existance and previous_resources:

            if replace:
                for resource in previous_resources:
                    rr = self.retrieve(resource.id)
                    self.forge.deprecate(rr)

            else:
                logger.warning(
                    "The resource you are trying to register already exist and will be ignored."
                )
                return

        resource_description["objectOfStudy"] = {
            "@id": "http://bbp.epfl.ch/neurosciencegraph/taxonomies/objectsofstudy/singlecells",
            "@type": "nsg:ObjectOfStudy",
            "label": "Single Cell",
        }

        logger.debug("Registering resources: %s", resource_description)

        resource = self.forge.from_json(resource_description, na="None")
        resource = self.add_contribution(resource)

        if distributions:
            resource = Dataset.from_resource(self.forge, resource)
            for path in distributions:
                resource.add_distribution(path)

        self.forge.register(resource)

    def retrieve(self, id_):
        """Retrieve a resource based on its id"""

        resource = self.forge.retrieve(id=id_, cross_bucket=self.cross_bucket)

        if resource:
            return resource

        logger.debug("Could not retrieve resource of id: %s", id_)

        return None

    def fetch(self, filters):
        """Fetch resources based on filters.

        Args:
            filters (dict): keys and values used for the "WHERE". Should include "type" or "id".

        Returns:
            resources (list): list of resources
        """

        if "type" not in filters and "id" not in filters:
            raise AccessPointException("Search filters should contain either 'type' or 'id'.")

        logger.debug("Searching: %s", filters)

        resources = self.forge.search(
            filters,
            cross_bucket=self.cross_bucket,
            limit=self.limit,
            debug=self.debug,
            search_endpoint=self.search_endpoint,
        )

        if resources:
            return resources

        logger.debug("No resources for filters: %s", filters)

        return None

    def fetch_one(self, filters, strict=True):
        """Fetch one and only one resource based on filters."""

        resources = self.fetch(filters)

        if resources is None:
            if strict:
                raise AccessPointException(f"Could not get resource for filters {filters}")
            return None

        if len(resources) > 1:
            if strict:
                raise AccessPointException(f"More than one resource for filters {filters}")
            return resources[0]

        return resources[0]

    def download(self, resource_id, download_directory="./nexus_temp"):
        """Download datafile from nexus if it doesn't already exist."""

        resource = self.forge.retrieve(resource_id, cross_bucket=True)

        if resource is None:
            raise AccessPointException(f"Could not find resource for id: {resource_id}")

        if hasattr(resource, "distribution"):

            file_paths = []
            if isinstance(resource.distribution, list):
                for dist in resource.distribution:
                    if hasattr(dist, "name"):
                        file_paths.append(pathlib.Path(download_directory) / dist.name)
                    else:
                        raise AttributeError(
                            f"A distribution of the resource {resource.name} does "
                            "not have a file name."
                        )
            else:
                file_paths = [pathlib.Path(download_directory) / resource.distribution.name]

            if any(not fp.is_file() for fp in file_paths):
                self.forge.download(
                    resource, "distribution.contentUrl", download_directory, cross_bucket=True
                )

            return [str(fp) for fp in file_paths]

        return []

    def deprecate(self, filters):
        """Deprecate resources based on filters."""

        tmp_cross_bucket = self.cross_bucket
        self.cross_bucket = False

        resources = self.fetch(filters)

        if resources:
            for resource in resources:
                rr = self.retrieve(resource.id)
                if rr is not None:
                    self.forge.deprecate(rr)

        self.cross_bucket = tmp_cross_bucket

    def deprecate_all(self, metadata):
        """Deprecate all resources used or produced by BluePyModel. Use with extreme caution."""

        if not yesno("Confirm deprecation of all BluePyEmodel resources in Nexus project"):
            return

        for type_ in NEXUS_TYPE_TO_CLASS.keys():

            filters = {"type": type_}
            filters.update(metadata)

            self.deprecate(filters)

    def resource_location(self, resource):
        """Get the path of the files attached to a resource. If the resource is
        not located on gpfs, download it instead"""

        paths = []

        if not hasattr(resource, "distribution"):
            raise AccessPointException(f"Resource {resource} does not have distribution")

        if isinstance(resource.distribution, list):
            distribution_iter = resource.distribution
        else:
            distribution_iter = [resource.distribution]

        for distrib in distribution_iter:

            filepath = None

            if hasattr(distrib, "atLocation"):
                loc = self.forge.as_json(distrib.atLocation)
                if "location" in loc:
                    filepath = loc["location"].replace("file:/", "")

            if filepath is None:
                filepath = self.download(resource.id)[0]

            paths.append(filepath)

        return paths

    @staticmethod
    def resource_name(class_name, metadata):
        """Create a resource name from the class name and the metadata."""
        name_parts = [CLASS_TO_RESOURCE_NAME[class_name]]
        if "iteration" in metadata:
            name_parts.append(metadata["iteration"])
        if "emodel" in metadata:
            name_parts.append(metadata["emodel"])
        if "ttype" in metadata:
            name_parts.append(metadata["ttype"])

        return "__".join(name_parts)

    def object_to_nexus(self, object_, metadata_dict, metadata_str, replace=True):
        """Transform a BPEM object into a dict which gets registered into Nexus as
        the distribution of a Dataset of the matching type. The metadata
        are also attached to the object to be able to retrieve the Resource."""

        type_ = CLASS_TO_NEXUS_TYPE[object_.__class__.__name__]

        base_payload = {
            "type": ["Entity", type_],
            "name": self.resource_name(object_.__class__.__name__, metadata_dict),
        }
        payload_existance = {
            "type": type_,
            "name": self.resource_name(object_.__class__.__name__, metadata_dict),
        }

        base_payload.update(metadata_dict)
        payload_existance.update(metadata_dict)
        json_payload = object_.as_dict()

        path_json = f"{CLASS_TO_RESOURCE_NAME[object_.__class__.__name__]}__{metadata_str}.json"
        path_json = str((pathlib.Path("./nexus_temp") / path_json).resolve())

        distributions = [path_json]
        if "nexus_distributions" in json_payload:
            distributions += json_payload.pop("nexus_distributions")

        with open(path_json, "w") as fp:
            json.dump(json_payload, fp, indent=2)

        payload_existance.pop("annotation", None)

        self.register(
            base_payload,
            filters_existance=payload_existance,
            replace=replace,
            distributions=distributions,
        )

    def resource_to_object(self, type_, resource, metadata):
        """Transform a Resource into a BPEM object of the matching type"""

        file_paths = self.download(resource.id)
        json_path = next((fp for fp in file_paths if pathlib.Path(fp).suffix == ".json"), None)

        if json_path is None:
            # legacy case where the payload is in the Resource
            payload = self.forge.as_json(resource)

            for k in metadata:
                payload.pop(k, None)

            for k in NEXUS_ENTRIES:
                payload.pop(k, None)

        else:
            # Case in which the payload is in a .json distribution
            with open(json_path, "r") as f:
                payload = json.load(f)

        return NEXUS_TYPE_TO_CLASS[type_](**payload)

    def nexus_to_object(self, type_, metadata):
        """Search for a single Resource matching the type_ and metadata and return it
        as a BPEM object of the matching type"""

        filters = {"type": type_}
        filters.update(metadata)

        resource = self.fetch_one(filters)

        return self.resource_to_object(type_, resource, metadata)

    def nexus_to_objects(self, type_, metadata):
        """Search for Resources matching the type_ and metadata and return them
        as BPEM objects of the matching type"""

        filters = {"type": type_}
        filters.update(metadata)

        resources = self.fetch(filters)

        objects_ = []

        if resources:
            for resource in resources:
                objects_.append(self.resource_to_object(type_, resource, metadata))

        return objects_

    def get_nexus_id(self, type_, metadata):
        """Search for a single Resource matching the type_ and metadata and return its id"""
        filters = {"type": type_}
        filters.update(metadata)

        resource = self.fetch_one(filters)

        return resource.id

    @staticmethod
    def brain_region_filter(resources):
        """Filter resources to keep only brain regions

        Arguments:
            resources (list of Resource): resources to be filtered

        Returns:
            list of Resource: the filtered resources
        """
        return [
            r for r in resources if hasattr(r, "subClassOf") and r.subClassOf == "nsg:BrainRegion"
        ]

    def type_filter(self, resources, filter):
        """Filter resources to keep only etypes/mtypes/ttypes

        Arguments:
            resources (list of Resource): resources to be filtered
            filter (str): can be "etype", "mytype" or "ttype"

        Returns:
            list of Resource: the filtered resources
        """
        if filter == "etype":
            available_names = self.available_etypes
        elif filter == "mtype":
            available_names = self.available_mtypes
        elif filter == "ttype":
            available_names = self.available_ttypes
        else:
            raise AccessPointException(
                f'filter is {filter} but should be in ["etype", "mtype", "ttype"]'
            )
        return [r for r in resources if r.id in available_names]

    def filter_resources(self, resources, filter):
        """Filter resources

        Arguments:
            resources (list of Resource): resources to be filtered
            filter (str): which filter to use
                can be "brain_region", "etype", "mtype", "ttype"

        Returns:
            list of Resource: the filtered resources

        Raises:
            AccessPointException if filter not in ["brain_region", "etype", "mtype", "ttype"]
        """
        if filter == "brain_region":
            return self.brain_region_filter(resources)
        if filter in ["etype", "mtype", "ttype"]:
            return self.type_filter(resources, filter)

        filters = ["brain_region", "etype", "mtype", "ttype"]
        raise AccessPointException(
            f"Filter not expected in filter_resources: {filter}"
            f"Please choose among the following filters: {filters}"
        )

def ontology_forge_access_point(access_token=None):
    """Returns an access point targeting the project containing the ontology for the
    species and brain regions"""

    access_point = NexusForgeAccessPoint(
        project="datamodels",
        organisation="neurosciencegraph",
        endpoint="https://bbp.epfl.ch/nexus/v1",
        forge_path=None,
        access_token=access_token,
    )

    return access_point

def raise_not_found_exception(base_text, label, access_point, filter, limit=30):
    """Raise an exception mentioning the possible appropriate resource names available on nexus

    Arguments:
        base_text (str): text to display in the Exception
        label (str): name of the resource to search for
        access_point (NexusForgeAccessPoint)
        filter (str): which filter to use
            can be "brain_region", "etype", "mtype", or "ttype"
        limit (int): maximum number of resources to fetch when looking up
            for resource name suggestions
    """
    if not base_text.endswith("."):
        base_text = f"{base_text}."

    resources = access_point.resolve(label, strategy="all", limit=limit)
    if resources is None:
        raise AccessPointException(base_text)

    # make sure that resources is iterable
    if not isinstance(resources, list):
        resources = [resources]
    filtered_names = "\n".join(
        set(r.label for r in access_point.filter_resources(resources, filter))
    )
    if filtered_names:
        raise AccessPointException(f"{base_text} Maybe you meant one of those:\n{filtered_names}")

    raise AccessPointException(base_text)

def check_resource(label, category, access_point=None, access_token=None):
    """Checks that resource is present on nexus and is part of the provided category

    Arguments:
        label (str): name of the resource to search for
        category (str): can be "etype", "mtype" or "ttype"
        access_point (str):  ontology_forge_access_point(access_token)
    """
    allowed_categories = ["etype", "mtype", "ttype"]
    if category not in allowed_categories:
        raise AccessPointException(f"Category is {category}, but should be in {allowed_categories}")

    if access_point is None:
        access_point = ontology_forge_access_point(access_token)

    resource = access_point.resolve(label, strategy="exact")
    # raise Exception if resource was not found
    if resource is None:
        base_text = f"Could not find {category} with name {label}"
        raise_not_found_exception(base_text, label, access_point, category)

    # if resource found but not of the appropriate category, also raise Exception
    available_names = []
    if category == "etype":
        available_names = access_point.available_etypes
    elif category == "mtype":
        available_names = access_point.available_mtypes
    elif category == "ttype":
        available_names = access_point.available_ttypes
    if resource.id not in available_names:
        base_text = f"Resource {label} is not a {category}"
        raise_not_found_exception(base_text, label, access_point, category)

def get_brain_region(brain_region, access_token=None):
    """Returns a dict with id and label of the resource corresponding to the brain region

    If the brain region name is not present in nexus,
    raise an exception mentioning the possible brain region names available on nexus

    Arguments:
        brain_region (str): name of the brain region to search for
        access_token (str): nexus connection token

    Returns:
        dict: the id and label of the nexus resource of the brain region
    """

    filter = "brain_region"
    access_point = ontology_forge_access_point(access_token)

    if brain_region in ["SSCX", "sscx"]:
        brain_region = "somatosensory areas"

    resource = access_point.resolve(brain_region, strategy="exact")
    # try with capital 1st letter, or every letter lowercase
    if resource is None:
        # do not use capitalize, because it also make every other letter lowercase
        if len(brain_region) > 1:
            brain_region = f"{brain_region[0].upper()}{brain_region[1:]}"
        elif len(brain_region) == 1:
            brain_region = brain_region.upper()
        resource = access_point.resolve(brain_region, strategy="exact")

        if resource is None:
            resource = access_point.resolve(brain_region.lower(), strategy="exact")

    # raise Exception if resource was not found
    if resource is None:
        base_text = f"Could not find any brain region with name {brain_region}"
        raise_not_found_exception(base_text, brain_region, access_point, filter)

    # if resource found but not a brain region, also raise Exception
    if not hasattr(resource, "subClassOf") or resource.subClassOf != "nsg:BrainRegion":
        base_text = f"Resource {brain_region} is not a brain region"
        raise_not_found_exception(base_text, brain_region, access_point, filter)

    # if no exception was raised, filter to get id and label and return them
    brain_region_dict = access_point.forge.as_json(resource)
    return {
        "id": brain_region_dict["id"],
        "label": brain_region_dict["label"],
    }

def get_all_species(access_token=None):

    access_point = ontology_forge_access_point(access_token)

    resources = access_point.forge.search({"subClassOf": "nsg:Species"}, limit=100)

    return sorted(set(r.label for r in resources))


from collections import OrderedDict

from cppbind import default_config
from cppbind.common.error import Error
from cppbind.common.yaml_process import to_value
from cppbind.context_manager.var_eval import VariableEvaluator
from cppbind.ir.ast import (
    Node,
    RootNode,
    ROOT_KIND_NAME,
    DIR_KIND_NAME,
    FILE_KIND_NAME
)
from cppbind.parser.cppbind_api_parser import APIParser
from cppbind.utils import init_jinja_env

ALL_PLATFORMS = sorted(list(default_config.platforms))

class ContextManager:
    """
    A class for evaluating current context variables
    using current context to assign the result to the current node.
    """

    def __init__(self, ctx_desc, platform, language):
        self.ctx_desc = ctx_desc
        self.platform = platform
        self.language = language
        jinja_env = init_jinja_env(language)
        self.cppbind_api_parser = APIParser(ctx_desc, jinja_env, platform, language)
        self.var_evaluator = VariableEvaluator(jinja_env)

    def eval_root_attrs(self, ctx, var_values, location=None):
        """Eval context variables for root node"""
        args = None
        api = Node.API_NONE

        # update context with var values to use them during evaluation
        ctx.update(var_values)

        parsed_api = self.cppbind_api_parser.parse_yaml_api(RootNode.ROOT_KEY, ctx)
        if parsed_api:
            api, args = parsed_api

        args = args or {}
        # overwrite parsed variables with command line values (it has higher priority)
        args.update(var_values)

        return api, self.__process_attrs(ROOT_KIND_NAME, args, location, ctx)

    def eval_dir_attrs(self, name, ctx, location=None):
        """Eval context variables for dir node"""
        api = args = None
        parsed_api = self.cppbind_api_parser.parse_yaml_api(name, ctx)
        if parsed_api:
            api, args = parsed_api
        return api, self.__process_attrs(DIR_KIND_NAME, args, location, ctx)

    def eval_file_attrs(self, name, ctx, location=None):
        """Eval context variables for file node"""
        parsed_api = self.cppbind_api_parser.parse_yaml_api(name, ctx)
        if parsed_api:
            api, args = parsed_api
            if api:
                return api, self.__process_attrs(FILE_KIND_NAME, args, location, ctx)
        return None

    def eval_clang_attrs(self, name, kind, api_section, ctx, location):
        """Eval context variables for clang node"""
        parsed_api = self.cppbind_api_parser.parse_api(name, api_section, location, ctx)
        if parsed_api:
            api, args = parsed_api
            if api:
                return api, self.__process_attrs(kind, args, location, ctx)
        return None

    def __process_attrs(self, kind, args, location, ctx=None):
        """
        Evaluate/calculate current context variables values by its' kind and current context.
        """
        ctx = ctx or OrderedDict()
        args = args or OrderedDict()
        res = OrderedDict()

        # dummy object for identifying undefined and null value defined variables
        undefined = object()

        # add all missing attributes
        for att_name, properties in self.ctx_desc.get_var_def().items():
            new_att_val = args.get(att_name, undefined)

            allowed = kind in properties["allowed_on"]
            if new_att_val is undefined:
                # check mandatory attribute existence
                if kind in properties["required_on"]:
                    Error.error(f"Attribute '{att_name}' is mandatory attribute on {kind}.",
                                location.file_name if location else None,
                                location.line_number if location else None)
                    break

                # inherit from parent or add default value
                if properties.get('inheritable'):
                    # directory based nodes may not have parent
                    if ctx:
                        new_att_val = ctx.get(att_name, undefined)

                if allowed:
                    if new_att_val is undefined:
                        # use default value
                        new_att_val = ContextManager.get_attr_default_value(
                            properties, self.platform, self.language, undefined)

                        if new_att_val is not undefined:
                            new_att_val = self.var_evaluator.eval_var_value(properties,
                                                                            new_att_val,
                                                                            ctx,
                                                                            att_name,
                                                                            location)
            else:
                # attribute is set check weather or not it is allowed.
                if not allowed:
                    Error.error(f"Attribute {att_name} is not allowed on {kind}.",
                                location.file_name if location else None,
                                location.line_number if location else None)
                    break

                new_att_val = self.var_evaluator.eval_var_value(properties,
                                                                new_att_val,
                                                                ctx,
                                                                att_name,
                                                                location)

            # validate variable values
            if new_att_val not in (None, undefined):
                self.cppbind_api_parser.validate_attr(att_name, new_att_val)

            options = to_value(ContextManager.get_var_property_value(properties, self.platform, self.language, 'options'))

            if new_att_val not in (None, undefined) and options is not None:
                if new_att_val not in options:
                    Error.error(f"Value mismatch for '{att_name}' variable: "
                                f"value {new_att_val} is not in list of allowed options",
                                location.file_name if location else None,
                                location.line_number if location else None)

            if new_att_val is not undefined:
                # add attr to current node context so that it can be used for coming attributes
                ctx[att_name] = new_att_val
                res[att_name] = new_att_val

        return res

    @staticmethod
    def get_attr_default_value(props, plat, lang, default=None):
        return ContextManager.get_var_property_value(props, plat, lang, 'default', default)

    @staticmethod
    def get_var_property_value(props, plat, lang, prop, default=None):
        """
        Retrieve language/platform specific default value for current variable.
        """

        # detect illegal specification of plat/lang option
        if plat + f'.{prop}' in props and lang + f'.{prop}' in props:
            Error.critical(
                f"Conflict of attributes in attributes definition file: {plat}.default and {lang}.default: "
                f"only one of them must be defined separately, or they must be both specified")

        # if plat/lang specific key is preset, return corresponding section
        # we search for specific key by descending order of priority
        for key in (plat + '.' + lang + f'.{prop}', plat + f'.{prop}', lang + f'.{prop}', prop):
            if key in props:
                return props[key]

        return default

    def filter_by_plat_lang(self, var_values):
        """
        Filter current platform/language specific values from initial context provided via command line arguments
        """
        res = {}

        if var_values is None:
            return res

        # convert argparse.Namespace into dict be able to lookup and iterate over it
        var_values = var_values.__dict__

        # pick those variable names which are present in variable definitions
        var_def = self.ctx_desc.get_var_def()
        var_names = set(name.split('.')[-1] for name in var_values if name in var_def)

        for name in var_names:
            prop = var_def[name]
            if 'cmd_line' not in prop['allowed_on']:
                continue

            plat_lang_opt = f"{self.platform}.{self.language}.{name}"
            plat_opt = f"{self.platform}.{name}"
            lang_opt = f"{self.language}.{name}"

            # search for value from highest to lowest priority (plat+lang+name, plat+name, lang+name, name)
            for opt in (plat_lang_opt, plat_opt, lang_opt, name):
                if opt in var_values and var_values[opt] is not None:
                    res[name] = var_values[opt]
                    # no need for later searching since we already found an option with the highest possible priority
                    break

        return res


import cv2
from time import time
import numpy as np

from lib.capture import RotMGCapture
from lib.vision import Vision
from lib.conductor import Conductor

capture = RotMGCapture()
vision = Vision("static/stats.png", debug=True)
conductor = Conductor("r", "f", "v")

loop_time = time()
while(True):
    screenshot = capture.get_screenshot()
    #cv2.imshow('result', vision.process_screenshot(screenshot))
    data = vision.process_screenshot(screenshot)
    if data:
        conductor.conductor(data)

    print('FPS {}'.format(1 / (time() - loop_time)))
    loop_time = time()

    if cv2.waitKey(1) == ord('q'):
        cv2.destroyAllWindows()
        break


'''

Difficulty: Medium
https://www.youtube.com/watch?v=Vn2v6ajA7U0

Given an integer array nums that may contain duplicates, return all possible subsets (the power set).

The solution set must not contain duplicate subsets. Return the solution in any order.

'''
from typing import List

class Solution:
    def subsetsWithDup(self, nums: List[int]) -> List[List[int]]:
        res = []
        nums.sort()

        def backtrack(i, subset):
            if i == len(nums):
                res.append(subset[::])
                return

            subset.append(nums[i])
            backtrack(i + 1, subset)
            subset.pop()

            while i + 1 < len(nums) and nums[i] == nums[i + 1]:
                i += 1

            backtrack(i + 1, subset)

        backtrack(0, [])
        return res


import pandas as pd
import matplotlib.pyplot as plt

dfs = pd.read_excel("../11/PT100-tx-tn-prec.xlsx", sheet_name=None)
years = ['year','Annual']

tmins = dfs['tmin']
tmins = tmins[years].copy()
tmins.dropna(inplace=True)

tmaxs = dfs['tmax']
tmaxs = tmaxs[years].copy()
tmaxs.dropna(inplace=True)
#print(tmins,tmaxs)

temps = pd.merge(tmins,tmaxs,on='year',suffixes=('_tmin','_tmax'))
#print(temps.info())
temps['year'] = temps['year'].astype('uint16')
temps.set_index('year',inplace=True)
print(temps)
# para sobrepor as duas temperaturas
temps['Annual_tmax'] = temps['Annual_tmax'] - temps['Annual_tmin']
temps.plot(kind='area',alpha=0.3,stacked=True,legend=False,ylabel='Temp (ºC)')

#plt.show()
plt.savefig('plot.png')


import collections

Node = collections.namedtuple('Node', ['left', 'right', 'value'])

def contains(root, value):
    if root is None:
        return False
    if root.value == value:
        return True

    if root.left is None and root.right is None:
        return False

    if root.value > value:
        return contains(root.left, value)
    else:
        return contains(root.right, value)
import collections

n1 = Node(value=1, left=None, right=None)
n3 = Node(value=3, left=None, right=None)
n2 = Node(value=2, left=n1, right=n3)

print(contains(n2, 3))


### Code from https://github.com/patrickloeber/python-fun/tree/master/snake-pygame

import pygame
import random
from enum import Enum
from collections import namedtuple
from config import *
from Snake import Snake
import numpy as np

pygame.init()

font = pygame.font.SysFont('arial', 25)

class Direction(Enum):
    RIGHT = 1
    LEFT = 2
    UP = 3
    DOWN = 4

Point = namedtuple('Point', 'x, y')

# rgb colors
WHITE = (255, 255, 255)
BLUE = (0, 0, 200)
BLUE1 = (0, 0, 255)
BLUE2 = (0, 100, 255)
GREEN = (0, 200, 0)
GREEN1 = (0, 255, 0)
GREEN2 = (100, 255, 0)
BLACK = (0,0,0)

class SnakeGameAI:
    """
    game should be in the following shape:
    type game = {
        height: number,
        width: number,
        gameMoves: {
                snakeBody: Point[]
                food: Point
            }[]
    }
    These are the basics variables needed
    """
    def __init__(self, game, s=SPEED):
        if len(game['gameMoves']) == 0:
            raise Exception("No game moves given")
        try:
            self.w = game['width']
            self.h = game['height']
            self.currMove = 0
            firstMove = game['gameMoves'][0]
            self.snake = firstMove['snakeBody']
            self.food = firstMove['food']

            self.display = pygame.display.set_mode((self.w, self.h), pygame.NOFRAME)
            pygame.display.set_caption('Snake')
            self.clock = pygame.time.Clock()
        except:
            raise Exception("Missing game data")

    def updateUi(self):
        self.display.fill(BLACK)

        for pt in self.snake:
            pygame.draw.rect(self.display, BLUE1, pygame.Rect(pt.x, pt.y, BLOCK_SIZE, BLOCK_SIZE))
            pygame.draw.rect(self.display, BLUE2, pygame.Rect(pt.x+4, pt.y+4, 12, 12))

            food = self.food
            pygame.draw.rect(self.display, BLUE, pygame.Rect(food.x, food.y, BLOCK_SIZE, BLOCK_SIZE))

        pygame.display.flip()
        self.clock.tick(self.s)


# notes
'''
This file is for housing the main dash application.
This is where we define the various css items to fetch as well as the layout of our application.
'''

# package imports
import dash
from dash import html
import dash_bootstrap_components as dbc
from flask import Flask
import os

# local imports
from utils.settings import APP_HOST, APP_PORT, APP_DEBUG, DEV_TOOLS_PROPS_CHECK

from components import navbar, footer

server = Flask(__name__)
app = dash.Dash(
    __name__,
    server=server,
    use_pages=True,    # turn on Dash pages
    external_stylesheets=[
        dbc.themes.BOOTSTRAP,
        dbc.icons.FONT_AWESOME
    ],  # fetch the proper css items we want
    meta_tags=[
        {   # check if device is a mobile device. This is a must if you do any mobile styling
            'name': 'viewport',
            'content': 'width=device-width, initial-scale=1'
        }
    ],
    suppress_callback_exceptions=True,
    title='Dash app structure'
)

server.config.update(SECRET_KEY=os.getenv('SECRET_KEY'))

def serve_layout():
    '''Define the layout of the application'''
    return html.Div(
        [
            navbar,
            dbc.Container(
                dash.page_container,
                class_name='my-2'
            ),
            footer
        ]
    )

app.layout = serve_layout   # set the layout to the serve_layout function
server = app.server         # the server is needed to deploy the application

if __name__ == "__main__":
    app.run_server(
        host=APP_HOST,
        port=APP_PORT,
        debug=APP_DEBUG,
        dev_tools_props_check=DEV_TOOLS_PROPS_CHECK
    )


# -*- coding: utf-8 -*-
"""Tests for pyneric.meta"""

import inspect
from unittest import TestCase

from future.utils import with_metaclass

import pyneric

class MetadataBehaviourTestCase(TestCase):

    def test_invalid_metadata_attr(self):
        self.assertRaises(TypeError, pyneric.MetadataBehaviour,
                          metadata_attr=object())

    def test_invalid_propagate_attr(self):
        self.assertRaises(TypeError, pyneric.MetadataBehaviour,
                          propagate_attr=object())

    def test_invalid_base_override_attr(self):
        self.assertRaises(TypeError, pyneric.MetadataBehaviour,
                          base_override_attr=object())

    def test_invalid_storage_attr(self):
        self.assertRaises(TypeError, pyneric.MetadataBehaviour,
                          storage_attr=object())

    def test_invalid_storage_class(self):
        self.assertRaises(TypeError, pyneric.MetadataBehaviour,
                          storage_class=object())

class MetaclassTestCase(TestCase):

    def test_basic(self):
        a_value = object()
        class M(pyneric.Metaclass):
            __metadata__ = dict(a=a_value)
        class C(with_metaclass(M, object)):
            pass
        self.assertTrue(inspect.isdatadescriptor(M.a))
        expected = dict(a=a_value, __propagate__=set(), __base_overrides__={})
        self.assertEqual(expected, M._get_metadata())
        self.assertEqual(expected, C._get_metadata())
        self.assertEqual(a_value, C.a)
        obj = C()
        self.assertRaises(AttributeError, getattr, obj, 'a')
        new_value = object()
        self.assertRaises(AttributeError, setattr, C, 'a', new_value)
        # Test that a non-propagated metadata attribute is not affected by an
        # object's own attribute of the same name.
        obj.a = new_value
        self.assertEqual(new_value, obj.a)
        self.assertEqual(a_value, C.a)

    def test_basic_metadata_iterable(self):
        a_value = object()
        class M(pyneric.Metaclass):
            __metadata__ = ('a',)
            a = a_value
        class C(with_metaclass(M, object)):
            pass
        self.assertTrue(inspect.isdatadescriptor(M.a))
        expected = dict(a=a_value, __propagate__=set(), __base_overrides__={})
        self.assertEqual(expected, M._get_metadata())
        self.assertEqual(expected, C._get_metadata())
        self.assertEqual(a_value, C.a)
        obj = C()
        self.assertRaises(AttributeError, getattr, obj, 'a')
        new_value = object()
        self.assertRaises(AttributeError, setattr, C, 'a', new_value)
        # Test that a non-propagated metadata attribute is not affected by an
        # object's own attribute of the same name.
        obj.a = new_value
        self.assertEqual(new_value, obj.a)
        self.assertEqual(a_value, C.a)

    def test_validation(self):
        a_value = dict()
        class CustomException(Exception):
            """Exception for validation test"""
        class M(pyneric.Metaclass):
            __metadata__ = dict(a=a_value)
            @staticmethod
            def validate_a(value):
                if not isinstance(value, dict):
                    raise CustomException("must be a dict")
        class C(with_metaclass(M, object)):
            a = {'valid': 'dict'}
        self.assertRaises(CustomException, type, 'C',
                          (with_metaclass(M, object),),
                          dict(a={'invalid', 'set', 'not', 'a', 'dict'}))
        self.assertRaises(CustomException, type, 'C1', (C,),
                          dict(a={'invalid', 'set', 'not', 'a', 'dict'}))

    def test_validate_not_callable(self):
        a_value = dict()
        v_value = object()
        class M(pyneric.Metaclass):
            __metadata__ = dict(a=a_value)
            # The "validate_a" attribute is not a function, so "a" metadata is
            # not validated.
            validate_a = v_value
        class C(with_metaclass(M, object)):
            a = {'valid': 'dict'}
        # The value of "a" is not being validated, so it can be a set.
        class C1(with_metaclass(M, object)):
            a = {'set', 'not', 'a', 'dict'}
        class C2(C):
            a = {'set', 'not', 'a', 'dict'}

    def test_valid(self):
        a_value = object()
        b_value = object()
        c_value = object()
        d_value = object()
        class M(pyneric.Metaclass):
            __metadata__ = dict(a=None, b=None, c=c_value)
            __propagate__ = ('a', 'c')
            @property
            def c(cls):
                if hasattr(cls, 'x'):
                    return "different value"
                return cls._get_metadata('c')
        class C(with_metaclass(M, object)):
            a = a_value
            d = d_value
        self.assertTrue(inspect.isdatadescriptor(M.a))
        self.assertTrue(inspect.isdatadescriptor(M.b))
        self.assertTrue(inspect.isdatadescriptor(M.c))
        self.assertRaises(AttributeError, getattr, M, 'd')
        expected = dict(a=None, b=None, c=c_value, __propagate__={'a', 'c'},
                        __base_overrides__={})
        self.assertEqual(expected, M._get_metadata())
        expected.update(a=a_value)
        self.assertEqual(expected, C._get_metadata())
        self.assertEqual(a_value, C.a)
        self.assertIsNone(C.b)
        self.assertEqual(c_value, C.c)
        self.assertEqual(d_value, C.d)
        obj = C()
        self.assertEqual(a_value, obj.a)
        self.assertRaises(AttributeError, getattr, obj, 'b')
        self.assertEqual(c_value, obj.c)
        self.assertEqual(d_value, obj.d)
        obj.b = b_value
        new_value = object()
        self.assertRaises(AttributeError, setattr, C, 'a', new_value)
        self.assertRaises(AttributeError, setattr, C, 'b', new_value)
        self.assertRaises(AttributeError, setattr, C, 'c', new_value)
        C.d = new_value
        self.assertEqual(new_value, C.d)
        self.assertEqual(a_value, obj.a)
        self.assertEqual(b_value, obj.b)
        self.assertEqual(c_value, obj.c)
        self.assertEqual(new_value, obj.d)
        self.assertRaises(AttributeError, setattr, obj, 'a', new_value)
        obj.b = new_value
        self.assertRaises(AttributeError, setattr, obj, 'c', new_value)
        newer_value = object()
        obj.d = newer_value
        self.assertEqual(new_value, obj.b)
        self.assertEqual(newer_value, obj.d)
        self.assertEqual(c_value, C.c)
        C.x = None
        self.assertEqual('different value', C.c)

    def test_invalid_metadata_attribute(self):
        class M(pyneric.Metaclass):
            pass
        self.assertRaises(AttributeError, M._get_metadata, 'x')

    def test_invalid_metadata(self):
        self.assertRaises(TypeError, type, 'M', (pyneric.Metaclass,),
                          dict(__metadata__=object()))

class MetaclassCustomBehaviourTestCase(TestCase):

    def test_no_propagate_attr(self):
        behaviour = pyneric.MetadataBehaviour(propagate_attr=None)
        a_value = object()
        b_value = dict(a=None)
        p_value = {'a'}
        class M(pyneric.Metaclass):
            __metadata_behaviour__ = behaviour
            __metadata__ = dict(a=a_value)
            # Prove that __propagate__ is not part of metadata behaviour.
            __propagate__ = p_value
            # Prove that base overrides are not affected.
            __base_overrides__ = b_value
        class C(with_metaclass(M, object)):
            pass
        self.assertTrue(inspect.isdatadescriptor(M.a))
        # Note that there is no "__propagate__" attribute in the metadata.
        expected = dict(a=a_value, __base_overrides__=b_value)
        self.assertEqual(expected, M._get_metadata())
        expected.update(a=None)
        self.assertEqual(expected, C._get_metadata())
        # Prove that __propagate__ is not part of metadata behaviour.
        self.assertEqual(p_value, M.__propagate__)
        self.assertEqual(p_value, C.__propagate__)
        # Prove that base overrides are not affected.
        self.assertEqual(None, C.a)
        # Prove that propagation of "a" does not occur.
        self.assertRaises(AttributeError, getattr, C(), 'a')

    def test_no_base_override_attr(self):
        behaviour = pyneric.MetadataBehaviour(base_override_attr=None)
        a_value = object()
        b_value = dict(a=None)
        p_value = {'a'}
        class M(pyneric.Metaclass):
            __metadata_behaviour__ = behaviour
            __metadata__ = dict(a=a_value)
            # Prove that propagation is not affected.
            __propagate__ = p_value
            # Prove that __base_overrides__ is not part of metadata behaviour.
            __base_overrides__ = b_value
        class C(with_metaclass(M, object)):
            pass
        self.assertTrue(inspect.isdatadescriptor(M.a))
        # Note that there is no "__base_overrides__" attribute in the metadata.
        expected = dict(a=a_value, __propagate__=p_value)
        self.assertEqual(expected, M._get_metadata())
        self.assertEqual(expected, C._get_metadata())
        # Prove that __base_overrides__ is not part of metadata behaviour.
        self.assertEqual(b_value, M.__base_overrides__)
        self.assertEqual(b_value, C.__base_overrides__)
        # Prove that "a" was not overridden.
        self.assertEqual(a_value, C.a)
        # Prove that propagation is not affected.
        self.assertEqual(a_value, C().a)

    def test_validation_disabled(self):
        behaviour = pyneric.MetadataBehaviour(validate_prefix=None)
        a_value = dict()
        class M(pyneric.Metaclass):
            __metadata_behaviour__ = behaviour
            __metadata__ = dict(a=a_value)
            @staticmethod
            def validate_a(value):
                if not isinstance(value, dict):
                    raise TypeError("must be a dict")
        class C(with_metaclass(M, object)):
            a = {'valid': 'dict'}
        # The value of "a" is not being validated, so it can be a set.
        class C1(with_metaclass(M, object)):
            a = {'set', 'not', 'a', 'dict'}
        class C2(C):
            a = {'set', 'not', 'a', 'dict'}

    def test_validation_with_transformation(self):
        behaviour = pyneric.MetadataBehaviour(validate_transforms=True)
        a_value = dict()
        class CustomException(Exception):
            """Exception for validation test"""
        class M(pyneric.Metaclass):
            __metadata_behaviour__ = behaviour
            __metadata__ = dict(a=a_value)
            @staticmethod
            def validate_a(value):
                if not isinstance(value, dict):
                    raise CustomException("must be a dict")
                return list(value)
        class C(with_metaclass(M, object)):
            a = {'valid': 'dict'}
        self.assertEqual(['valid'], C.a)
        # still also raises exception when appropriate
        self.assertRaises(CustomException, type, 'C',
                          (with_metaclass(M, object),),
                          dict(a={'invalid', 'set', 'not', 'a', 'dict'}))
        self.assertRaises(CustomException, type, 'C1', (C,),
                          dict(a={'invalid', 'set', 'not', 'a', 'dict'}))
        class C1(C):
            a = {'another': 4, 'one': 1, 'transformed': 0}
        self.assertIsInstance(C1.a, list)
        self.assertEqual({'another', 'one', 'transformed'}, set(C1.a))

    def test_metadata_behaviour_similar_to_django_model(self):
        class CustomMetadataBehaviour(pyneric.MetadataBehaviour):
            def __init__(self, storage_class, metadata_attr='Meta',
                         storage_attr='_meta', propagate_attr=None):
                super(CustomMetadataBehaviour, self).__init__(
                    metadata_attr=metadata_attr,
                    propagate_attr=propagate_attr,
                    storage_attr=storage_attr,
                    storage_class=storage_class)
            def _get_local_metadata(self, dict, base_attrs=()):
                """Django-like metadata retrieval function."""
                try:
                    meta_class = dict[self.metadata_attr]
                except KeyError:
                    return {}
                # Django does not currently test that it is a class.
                if not inspect.isclass(meta_class):
                    raise TypeError(
                        "The '{}' attribute must be a class."
                        .format(self.metadata_attr))
                result = {}
                for k, v in meta_class.__dict__.items():
                    if (k.startswith('_') and
                        k not in (self.propagate_attr,
                                  self.base_override_attr)):
                        continue
                    result[k] = v
                return result
        class MetadataStorage(object):
            def __init__(self, **kwargs):
                for attr, value in kwargs.items():
                    setattr(self, attr, value)
        class M(pyneric.Metaclass):
            __metadata_behaviour__ = CustomMetadataBehaviour(MetadataStorage)
            class Meta:
                app_label = None
                db_table = None
                abstract = False
                __base_overrides__ = dict(abstract=False)
        class C(with_metaclass(M, object)):
            class Meta:
                db_table = 'tbl'
                abstract = True
        class C1(C):
            class Meta:
                db_table = 'tbl1'
        self.assertEqual('tbl', C.db_table)
        self.assertEqual(True, C.abstract)
        self.assertEqual('tbl1', C1.db_table)
        self.assertEqual(False, C1.abstract)


import time
import pickle
import datetime

import matplotlib.pyplot as plt
import numpy as np

from sacred import Experiment
from sacred.observers import FileStorageObserver, RunObserver

from constrained_bai.driver import get_driver
from constrained_bai.driver_bandit import DriverBandit

# changes the run _id and thereby the path that the FileStorageObserver
# writes the results
# cf. https://github.com/IDSIA/sacred/issues/174
class SetID(RunObserver):
    priority = 50  # very high priority to set id

    def started_event(
        self, ex_info, command, host_info, start_time, config, meta_info, _id
    ):
        timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S_%f")
        custom_id = "{}".format(timestamp)
        return custom_id  # started_event returns the _run._id

ex = Experiment("driver_solve_with_restarts")
ex.observers = [SetID(), FileStorageObserver("results")]

@ex.config
def cfg():
    problem = {"cars_trajectory": "blocked", "goal": "target_velocity"}
    penalty_lambda = 1
    n_restarts = 10
    constraint = None
    experiment_label = None

@ex.automain
def run(_run, seed, problem, penalty_lambda, n_restarts, constraint, experiment_label):
    env = get_driver(
        problem["cars_trajectory"],
        problem["goal"],
        penalty_lambda=penalty_lambda,
        constraint=constraint,
    )
    env_eval = get_driver(
        problem["cars_trajectory"],
        problem["goal"],
        penalty_lambda=penalty_lambda,
        constraint="default",
    )

    max_rew = -float("inf")
    max_features = None

    for _ in range(n_restarts):
        policy, policy_features, _ = env.get_optimal_policy()
        reward = np.dot(policy_features, env.reward_w)
        if env.constraint_w is not None:
            constraint = np.dot(policy_features, env.constraint_w)
        else:
            constraint = None
        print("reward", reward, "constraint", constraint)
        if (constraint is None or constraint < env.threshold) and reward > max_rew:
            print("updating solution")
            max_rew = reward
            max_features = policy_features

    reward = np.dot(max_features, env_eval.reward_w)
    constraint = np.dot(max_features, env_eval.constraint_w)

    print("Found solution with")
    print("reward", reward)
    print("constraint", constraint)

    return {"reward": reward, "constraint": constraint}


import ipaddress
from typing import Dict, List, AsyncGenerator

# --- Ping --- #

from mcstatus import JavaServer
from typing import Dict

class Ping:
    def __init__(self):
        ...

    async def ping(
        self, ip_address, port: int
    ) -> dict[str, str | int | Dict[str, str | int | list]] | Exception:
        """Fully and asynchronously pings a minecraft server.

        Args:
            ip_address (str): The server's IP Address.
            port (int): The port to ping on.

        Returns:
            dict[str, str | int | Dict[str, str | int | list]] | Exception: The server's response data.

            {
                "version": {
                    "name": "1.8.7",
                    "protocol": 47
                },
                "players": {
                    "max": 100,
                    "online": 5,
                    "sample": [
                        {
                            "name": "thinkofdeath",
                            "id": "4566e69f-c907-48ee-8d71-d7ba5aa00d20"
                        }
                    ]
                },
                "description": {
                    "text": "Hello world"
                },
                "favicon": "data:image/png;base64,<data>"
            }

            version: Dict[str, str | int]
            players: Dict[str, str | int | List[Dict[str, str]]]
            description: Dict[str, str]
            favicon: str
        """
        try:
            data = JavaServer(host=ip_address, port=port)
            data = await data.async_status()
            data = data.raw
        except Exception as exc:
            data = exc
        return data

# --- Syn --- #

"""Contains functions for checking if a port is open using syn packets and a generator wrapper around it.

To be frank, I wasn't sure how to tackle this, so I started by doing some research on how masscan worked, and how I could send syn packets through python. I considered using python-masscan but that simply didn't have what I wanted, I want something nice, asynchronous, and customizable, which is only possible when you do something in house.

Resources -
- https://inc0x0.com/tcp-ip-packets-introduction/tcp-ip-packets-4-creating-a-syn-port-scanner/
For actual syn code in py, most of the function is based off of it.

- https://www.thepythoncode.com/article/syn-flooding-attack-using-scapy-in-python
To understand how a normal TCP connection works and how this is different.
"""

import socket
from awaits.awaitable import awaitable

class Syn:
    def __init__(self):
        ...

    @awaitable
    def ping(self, host: str, port: int, timeout: int = 3) -> bool:
        """Pings an IP Address using sync packets, sourced from https://github.com/pdrb/synping/blob/master/synping/synping.py

        Args:
            host (str): The IP Address to ping.
            port (int): The port to ping on.
            timeout (int, optional): How long the socket should wait before timing out. Defaults to 3 seconds.

        Returns:
            bool: Whether or not the port is open, as well as if the host is alive.
        """
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.settimeout(timeout)
        try:
            s.connect((host, port))
            s.close()
            return True
        except ConnectionRefusedError:
            return False
        except TimeoutError:
            return False
        except Exception as exc:
            return False

# --- Scanning --- #

syn = Syn()
ping = Ping()

async def scan(ip_range: ipaddress.IPv4Network, ports: List[int]) -> AsyncGenerator:
    """Meant for scanning an IP Block for minecraft servers."""

    for ip_address in ip_range:
        ip_address = str(ip_address)
        for port in ports:
            ip = f"{str(ip_address)}:{port}"
            if not await syn.ping(ip_address, port):
                yield False, ip, "syn", None
                continue
            data = await ping.ping(ip_address, port)
            if isinstance(data, Exception):
                yield False, ip, "err", data
                continue
            yield True, data.raw, "suc", None


# -*- coding: utf-8 -*-
import nltk
from ABSAli1 import preProcessing
from ABSAli1 import entity
import logging
from gensim.models.word2vec import Word2Vec
from sklearn.cluster import KMeans
import pickle
import pandas

logging.basicConfig(format='%(asctime)s:%(levelname)s:%(message)s',level=logging.INFO)

#词嵌入，并将两种词向量作为位置特征字典
#训练词向量
def trainingForWords(texts,fnum,filepath,sg,hs):
    #设定词向量参数

    sentences=[str(text).split(' ') for text in texts]  #.lower()
    # print(sentences)
    print('分词完成，开始训练')

    num_features=fnum #词向量的维度
    min_word_count=3 #词频数最低阈值
    num_workers=8 #线程数,想要随机种子生效的话，设为1
    context=10 #上下文窗口大小
    downsampling=1e-3 #与自适应学习率有关
    num_iter=15 #没有加额外数据时，设置为100最佳(添加额外数据后30最佳)
    hs=hs
    sg=sg#是否使用skip-gram模型

    model_path=filepath
    model=Word2Vec(sentences,workers=num_workers,hs=hs,
                   size=num_features,min_count=min_word_count,seed=77,iter=num_iter,
                   window=context,sample=downsampling,sg=sg)
    model.init_sims(replace=True)#锁定训练好的word2vec,之后不能对其进行更新
    model.save(model_path)#讲训练好的模型保存到文件中
    print('训练完成')
    return model

#加载word2vec模型
def loadForWord(filepath):
    model=Word2Vec.load(filepath)
    print('word2vec模型读取完毕')
    return model

def trainingEmbedding(vector_len=150,d_type='re',add_extra=False):
    if d_type=='re':
        d_name='Restaurants'
        extraFile='data/extra/yelp/Restaurants_Raw.csv'
    else:
        d_name='LapTops'
        extraFile='data/extra/amzon/LapTops_Raw.csv'

    print('------训练%s数据的Word2Vec------'%d_name)
    train_corpus=preProcessing.loadXML('data/origin/%s_Train_v2.xml'%d_name)                #判断训练集合法
    test_corpus=preProcessing.loadXML('data/origin/%s_Test_Data_PhaseA.xml'%d_name)         #判断测试集合法
    print('数据集合并完成')

    corpus=train_corpus.corpus
    corpus=train_corpus.corpus+test_corpus.corpus

    del train_corpus
    del test_corpus

    bio_entity=entity.BIO_Entity(corpus,d_type)
    texts=bio_entity.texts

    #向SemEval-2014文件中的'Restaurants'和'LapTops'添加额外的数据
    if add_extra==True:
        print('添加额外语料:%s'%extraFile)
        extra_csv=pandas.read_csv(extraFile)  #,encoding='gbk'
        extra_texts=list(extra_csv['text'])
        texts=texts+extra_texts
        del extra_csv
        del extra_texts
        print('额外语料加载完成')

    print('创建WordEmbedding')
    trainingForWords(texts,vector_len,'model/%s.w2v'%d_name,1,0)        #Word2Vec中采用Skipgram
    print('创建WordEmbedding_CBOW')
    trainingForWords(texts,vector_len,'model/%s.w2v_cbow'%d_name,0,0)  #Word2Vec中采用CBOW
#采用skipgram模型和cbow模型，之所以训练两组是为了丰富后面的特征。

#为什么采用Keman处理
#在后面要进行特征抽取任务中，我们当然不能直接把单词的词向量丢到CRF里去学习（这可不是LSTM这种NN模型，要CRF学习词向量的每一维的转换关系，消耗上是不能接受的，且没有意义），
#这里合理做法是我之前提到的TOP选手的做法，将全体单词词向量做Kmeans聚类，每一个单词都会得到一个聚类类别，反映了其大体语义，我们将单词的类别作为CRF的位置特征。

def kmeansClusterForW2V(filepath,outpath,cluster_num):
    W2Vmodel=loadForWord(filepath)
    vocab=list(W2Vmodel.wv.vocab.keys())
    vectors=[W2Vmodel[vocab[i]] for i in (range(len(vocab)))]
    print('开始聚类')
    clf=KMeans(n_clusters=cluster_num,random_state=77)
    clf.fit(vectors)
    print('聚类完成，开始讲词典转化为类别字典')
    dict_re={vocab[i]:clf.labels_[i] for i in range(len(vocab))}
    print('保存字典。。。。')
    with open(outpath,'wb') as f:
        pickle.dump(dict_re,f)
    return dict_re

def loadDict(dictpath):
    print('载入字典：%s'%dictpath)
    with open(dictpath,'rb') as f:
        dict_re=pickle.load(f)
    return dict_re

#对词向量进行聚类处理，    位置特征字典序列  簇的类别为10
def createCluster(cluster_num=10,d_type='re'):
    if d_type=='re':
        d_name='Restaurants'
    else:
        d_name='LapTops'

    print('创建W2V聚类')
    kmeansClusterForW2V('model/%s.w2v'%d_name,'cluster/%s_w2v.pkl'%d_type,cluster_num)
    print('W2V聚类群创建完毕！')
    print('创建W2V_CBOW聚类')
    kmeansClusterForW2V('model/%s.w2v_cbow'%d_name,'cluster/%s_w2v_c.pkl'%d_type,cluster_num)
    print('W2V聚类群创建完毕！')

if __name__=='__main__':
     print('word2vecProcessing')
     # trainingEmbedding(300,'re')
     # createCluster(100,'re',  True,True,True)

     # trainingEmbedding(300,'lp',True,   True,True,True)
     # createCluster(200,'lp',  True,True,True)

     # W2V=loadForWord('embeddingModels/Laptops.w2v')


from django.http import HttpResponse
from django.template import Template, Context
from django.template.loader import get_template
from django.shortcuts import render
from django.http import JsonResponse
from sklearn.preprocessing import MinMaxScaler, OneHotEncoder
from joblib import load
from django.core.files import File
import os
import numpy as np
import json
from django.core.serializers.json import DjangoJSONEncoder
from django.utils.safestring import mark_safe
from django.template import Library
import sys
import boto3
from django.conf import settings

# 'fuelType', 'km', 'make', 'model', 'price', 'transmissionType', 'year',
#        'cubicCapacity', 'doors', 'hp'

def inicio(request):
    # ----------------------lectura de json para los select ---------------------------
    marcas_id = open(
        os.path.dirname(os.path.realpath(__file__)) + "/json/marcas_id.json",
        "rb",
    )

    marca_model_id = open(
        os.path.dirname(os.path.realpath(__file__)) +
        "/json/marca_model_id.json",
        "rb",
    )

    with marcas_id as file:
        data = json.load(file)
        data_json = json.dumps(data)

    with marca_model_id as file2:
        data2 = json.load(file2)
        data_json2 = json.dumps(data2)

    # ----------------------lectura de json para los select ---------------------------

    aws_access_key_ID = settings.AWS_ACCESS_KEY_ID
    aws_secret_access_KEY = settings.AWS_SECRET_ACCESS_KEY
    aws_session_TOKEN = settings.AWS_SESSION_TOKEN
    endpPoint = settings.ENDPOINT
    bucket = settings.BUCKET
    region_NAME = settings.REGION_NAME

    if request.POST:
        # 'fuelType', 'km', 'make', 'model','transmissionType', 'year','cubicCapacity', 'doors', 'hp'
        fuelType = request.POST['fuelType']
        km = request.POST['km']
        make = request.POST['make']
        model = request.POST['model']
        transmissionType = request.POST['transmissionType']
        year = request.POST['year']
        cubicCapacity = request.POST['cubicCapacity']
        doors = request.POST['doors']
        hp = request.POST['hp']

        data_usuario = f"{fuelType},{km},{make},{model},{transmissionType},{year},{cubicCapacity},{doors},{hp}"
        # print(data_usuario)

        client = boto3.Session(
            aws_access_key_id=aws_access_key_ID,
            aws_secret_access_key=aws_secret_access_KEY,
            aws_session_token=aws_session_TOKEN,
            region_name=region_NAME).client('sagemaker-runtime')

        response = client.invoke_endpoint(
            EndpointName=endpPoint, ContentType='text/csv', Accept='text/csv', Body=data_usuario)
        response = response['Body'].read().decode('utf-8')

        return render(request, "resultado.html", {"predict": response})

    return render(request, "inicio.html", {"marcas_id": data_json, "marca_model_id": data_json2})


import sys
import pathlib
import logging
from exceptions import ArgvException, NotTextFile, CrypterBaseException
from crypter import Caesar, Shift

def get_file_text(path):
    """Get the file from a text file"""
    with open(path) as fin:
        content = fin.read()
    return content

ROOT = pathlib.Path(__file__).parent
LOGS_DIR = ROOT / "logs"

try:
    LOGS_DIR.mkdir(exist_ok=True)
except OSError:
    logs_file_name = None
else:
    logs_file_name = LOGS_DIR / "log.log"

logging.basicConfig(level=logging.DEBUG,
                    format="%(asctime)s %(levelname)s line:  %(lineno)d %(message)s",
                    filename=logs_file_name)

def get_path_from_argv(idx):
    """Get path from CLI using sys module and is taking 1 argument which is the index"""
    if len(sys.argv) == 1:
        raise ArgvException("Error: Argumentul Path nu a fost gasit")

    path = pathlib.Path(sys.argv[idx])
    if not path.is_file():
        raise NotTextFile(f"Error: Nu am gasit fisierul {sys.argv[idx]}")
    return path

def crypt(msg, cypher):
    """Returns a string with the encrypted message and takes 2 arguments"""
    return str(cypher.crypt(msg))

def write_crypt_msg(path, msg, cipher):
    """Writes the encrypted message in a file text and takes 3 arguments"""
    with open(path, "w") as f:
        crypt_mes = f.write(crypt(msg, cipher))
    return crypt_mes

"""----------------------------------------------------------------------------------------------------------------"""

def decrypt(msg, cypher):
    """Returns a string with the decrypted message and takes 2 arguments"""
    return str(cypher.decrypt(msg))

def write_decrypt_msg(path, msg, cipher):
    """Writes the decrypted message in a file text and takes 3 arguments"""
    with open(path, "w") as f:
        decrypt_mes = f.write(decrypt(msg, cipher))
    return decrypt_mes

main_msg = get_file_text("my_text.txt")
my_cypher = Caesar(3)
my_cypher2 = Shift(5)
crypt_msg = get_file_text("encrypted.txt")

if sys.argv[1] == "c":
    try:
        logging.info(f"The file {get_path_from_argv(2)} will be encrypted")
        encrypted_msg = "encrypted.txt"
    except OSError:
        encrypted_msg = None
    except CrypterBaseException as err:
        logging.error(err)
    else:
        write_crypt_msg(encrypted_msg, main_msg, my_cypher2)
        logging.info(f"In {encrypted_msg} file you will find the encrypted message")

elif sys.argv[1] == "d":
    try:
        logging.info(f"The file {get_path_from_argv(2)} will be decrypted")
        decrypted_msg = "decrypted.txt"
    except OSError:
        decrypted_msg = None
    except CrypterBaseException as err:
        logging.error(err)
    else:
        if crypt_msg.split()[0] == 'Shift':
            write_decrypt_msg(decrypted_msg, crypt_msg, my_cypher2)
            logging.info(f"In {decrypted_msg} file you will find the decrypted message")
        elif crypt_msg.split()[0] == 'Caesar':
            write_decrypt_msg(decrypted_msg, crypt_msg, my_cypher)
            logging.info(f"In {decrypted_msg} file you will find the decrypted message")
        else:
            logging.info("Message cannot be decrypted")
else:
    raise NotTextFile("Command dose not exist")


import unittest, logging, sys
sys.path.insert(0, '../')
from models.poems.limerick import limerick
from models.poems.parseLines import parse, parse_all
from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy
from models.poems.poem import Tweet, Poem, engine
from sqlalchemy.sql import text

class TestLimerick(unittest.TestCase):
    def setUp(self):
      try:
        app = Flask(__name__)
        app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://localhost/test'
        db = SQLAlchemy(app)
        db.drop_all()
        db.create_all()
        db.session.add(Tweet('The limerick packs laughs anatomical', 'url1', 'limerick_test1', 10, 'AO1F', 'anatomical'))
        db.session.add(Tweet('Into space that is quite economical', 'url2', 'limerick_test1', 10, 'AO1F', 'economical'))
        db.session.add(Tweet("But the good ones I've seen", 'url3', 'limerick_test1', 6, 'IY1N', 'seen'))
        db.session.add(Tweet("So seldom are clean", 'url4', 'limerick_test1', 6, 'IY1N', 'clean'))
        db.session.add(Tweet("And the clean ones so seldom are comical", 'url5', 'limerick_test1', 10, 'AO1F', 'comical'))

        db.session.commit()
      except Exception as e:
        db.session.rollback()

    def test_valid(self):
        ''' Test a valid amount of tweets '''
        poem = limerick('limerick_test1')
        poem = [t.text for t in poem.tweets]
        self.assertTrue(poem[0] == "The limerick packs laughs anatomical")
        self.assertTrue(poem[1] == "Into space that is quite economical")
        self.assertTrue(poem[2] == "But the good ones I've seen")
        self.assertTrue(poem[3] == "So seldom are clean")
        self.assertTrue(poem[4] == "And the clean ones so seldom are comical")

    def test_invalid(self):
        ''' Tests insufficient amount of appropriate tweets '''
        self.assertRaises(Exception, limerick, 'limerick_test2')

    def test_invalid_duplicates(self):
        ''' Test no duplicates '''
        self.assertRaises(Exception, limerick, 'limerick_test3')

    def test_invalid_nonenglish(self):
        ''' Test no non-english lines '''
        self.assertRaises(Exception, limerick, 'limerick_test4')

    def test_valid_variance(self):
        ''' Limerick should choose lines that have similar syllable counts '''
        poem = limerick('limerick_test1')
        poem = [t.text for t in poem.tweets]
        self.assertTrue(poem[0] == "The limerick packs laughs anatomical")
        self.assertTrue(poem[1] == "Into space that is quite economical")
        self.assertTrue(poem[2] == "But the good ones I've seen")
        self.assertTrue(poem[3] == "So seldom are clean")
        self.assertTrue(poem[4] == "And the clean ones so seldom are comical")

    def test_urls(self):
        ''' Ensure the poems have the correct urls attached '''
        poem = limerick('limerick_test1')
        poem = [t.url for t in poem.tweets]
        self.assertTrue(poem[0] == 'url1')
        self.assertTrue(poem[1] == 'url2')
        self.assertTrue(poem[2] == 'url3')
        self.assertTrue(poem[3] == 'url4')
        self.assertTrue(poem[4] == 'url5')

if __name__ == '__main__':
    logging.basicConfig(stream=sys.stderr, level=logging.INFO)
    unittest.main()


import requests
import tkinter as tk
from tkinter import ttk, Frame

def report(d):
    district = d.get()

    lf3 = ttk.LabelFrame(gui, text = "District Data: " + district, style = "Red.TLabelframe")
    lf3.place(x=690, y=350)
    Frame(lf3, width=670, height=380, background = 'Light Blue').pack()

    try:
        dist_pop = data[state_code]["districts"][district]["meta"]["population"]
        dist_v1 = data[state_code]["districts"][district]["total"]["vaccinated1"]
        dist_v2 = data[state_code]["districts"][district]["total"]["vaccinated2"]
        dist_v1_p = (dist_v1/dist_pop)*100
        dist_v2_p = (dist_v2/dist_pop)*100
    except:
        pass

    yy = 430

    try:
        for key, value in data[state_code]["districts"][district]["delta"].items():
             tk.Label(gui, text="Today's Report: " + date1, font=('Calibri Bold', 16), fg="dark blue", bg="Light Blue").place(x=700, y=380)
             p1 = key.replace('{', " ")
             p1 = p1.replace('}', " ")
             tk.Label(gui, text=p1, font=('Calibri Bold', 14), fg="Black", bg="Light Blue").place(x=700, y=yy)
             tk.Label(gui, text=value, font=('Calibri', 14), fg="Black", bg="Light Blue").place(x=900, y=yy)
             yy = yy+30
    except:
        tk.Label(gui, text="Today's Data Upload is in Progress\nPlease Try After Sometime", font=('Calibri Bold', 15), fg="red", bg="Light Blue").place(x=700, y=450)
    cnf, dead, rec = 0, 0, 0
    yy = 430
    for key, value in data[state_code]["districts"][district]["total"].items():
         tk.Label(gui, text="Cumulative Till Date", font=('Calibri Bold', 16), fg="dark blue", bg="Light Blue").place(x=1050, y=380)

         p1 = key.replace('{', " ")
         p1 = p1.replace('}', " ")

         if p1 == "confirmed":
             cnf = value
         if p1 == "deceased":
             dead = value
         if p1 == "recovered":
             rec = value

         tk.Label(gui, text=p1, font=('Calibri Bold', 14), fg="Black", bg="Light Blue").place(x=1050, y=yy)
         tk.Label(gui, text=value, font=('Calibri', 14), fg="Black", bg="Light Blue").place(x=1250, y=yy)
         yy = yy+30
    try:
        active = cnf-dead-rec
        rec_rate = (rec/cnf)*100
    except:
        tk.Label(gui, text="District wise break up is not available", font=('Calibri Bold', 20), fg="Red", bg="Light Blue").place(x=700, y=650)
        return()
    tk.Label(gui, text="Active Caseload: " + str(active), font=('Calibri Bold', 20), fg="Red", bg="Light Blue").place(x=700, y=660)
    tk.Label(gui, text="Recovery Rate  : " + str(round(rec_rate,1)) + " %", font=('Calibri Bold', 20), fg="Dark Green", bg="Light Blue").place(x=700, y=700)
    tk.Label(gui, text="Population: " + str(dist_pop), font=('Calibri Bold', 20), fg="brown", bg="Light Blue").place(x=1020, y=660)
    tk.Label(gui, text="Vaccination: ", font=('Calibri Bold', 20), fg="Dark Green", bg="Light Blue").place(x=1020, y=700)
    tk.Label(gui, text="Dose 1: " + str(round(dist_v1_p,1)) + " %" + "\nDose 2:   " + str(round(dist_v2_p,1)) + " %", font=('Calibri Bold', 14), fg="Dark Green", bg="Light Blue").place(x=1180, y=695)

def select_district(s):
    state = s.get()
    global key, data, gui, state_code, date1

    lf2 = ttk.LabelFrame(gui, text = "State Data: " + state, style = "Red.TLabelframe")
    lf2.place(x=10, y=350)
    Frame(lf2, width=670, height=380, background = 'Light Blue').pack()

    lf3 = ttk.LabelFrame(gui, text = "District Data", style = "Red.TLabelframe")
    lf3.place(x=690, y=350)
    Frame(lf3, width=670, height=380, background = 'Light Blue').pack()

    if   state == "Andaman & Nicobar Islands":          state_code = "AN"
    elif state == "Andhra Pradesh":                     state_code = "AP"
    elif state == "Arunachal Pradesh":                  state_code = "AR"
    elif state == "Assam":                              state_code = "AS"
    elif state == "Bihar":                              state_code = "BR"
    elif state == "Chandigarh":                         state_code = "CH"
    elif state == "Chattisgarh":                        state_code = "CT"
    elif state == "Dadra & Nagar Haveli \ Daman & Diu": state_code = "DN"
    elif state == "Delhi":                              state_code = "DL"
    elif state == "Goa":                                state_code = "GA"
    elif state == "Gujarat":                            state_code = "GJ"
    elif state == "Haryana":                            state_code = "HR"
    elif state == "Himachal Pradesh":                   state_code = "HP"
    elif state == "Jammu & Kashmir":                    state_code = "JK"
    elif state == "Jharkhand":                          state_code = "JH"
    elif state == "Karnataka":                          state_code = "KA"
    elif state == "Kerala":                             state_code = "KL"
    elif state == "Ladakh":                             state_code = "LA"
    elif state == "Lakshadweep":                        state_code = "LD"
    elif state == "Madhya Pradesh":                     state_code = "MP"
    elif state == "Maharashtra":                        state_code = "MH"
    elif state == "Manipur":                            state_code = "MN"
    elif state == "Meghalaya":                          state_code = "ML"
    elif state == "Mizoram":                            state_code = "MZ"
    elif state == "Nagaland":                           state_code = "NL"
    elif state == "Odisha":                             state_code = "OR"
    elif state == "Puducherry":                         state_code = "PY"
    elif state == "Punjab":                             state_code = "PB"
    elif state == "Rajasthan":                          state_code = "RJ"
    elif state == "Sikkim":                             state_code = "SK"
    elif state == "Tamil Nadu":                         state_code = "TN"
    elif state == "Telangana":                          state_code = "TG"
    elif state == "Tripura":                            state_code = "TR"
    elif state == "Uttar Pradesh":                      state_code = "UP"
    elif state == "Uttarakhand":                        state_code = "UT"
    elif state == "West Bengal":                        state_code = "WB"

    p1 = []
    dist = data[state_code]['districts']
    dist = list(dist.keys())

    selected_dist = tk.StringVar(gui)
    tk.Label(gui, text="Select District: ", font=('Calibri Bold', 16), fg="Black", bg="Light Blue").place(x=380, y=190)
    cb1 = ttk.Combobox(gui, textvariable=selected_dist, width=35, height=20, values=dist, font=('Halvetica', 12))
    cb1.place(x=550, y=195)
    cb1.current(0)
    tk.Button(gui, text = "Submit", command = lambda: report(selected_dist), font=('Calibri Bold', 12), fg="white", bg="Dark Blue", width = 10).place(x=950, y=190)

    cnf, dead, rec = 0, 0, 0
    yy = 430
    try:
        state_pop = data[state_code]["meta"]["population"]
        state_v1 = data[state_code]["total"]["vaccinated1"]
        state_v2 = data[state_code]["total"]["vaccinated2"]
        state_v1_p = (state_v1/state_pop)*100
        state_v2_p = (state_v2/state_pop)*100
    except:
        pass
    try:
        for key, value in data[state_code]['delta'].items():
             date1 = data[state_code]["meta"]["date"]
             tk.Label(gui, text="Today's Report: " + date1, font=('Calibri Bold', 16), fg="dark blue", bg="Light Blue").place(x=20, y=380)

             p1 = key.replace('{', " ")
             p1 = p1.replace('}', " ")

             tk.Label(gui, text=p1, font=('Calibri Bold', 14), fg="Black", bg="Light Blue").place(x=20, y=yy)
             tk.Label(gui, text=value, font=('Calibri', 14), fg="Black", bg="Light Blue").place(x=220, y=yy)
             yy = yy+30
    except:
        tk.Label(gui, text="Today's Data Upload is in Progress\nPlease Try After Sometime", font=('Calibri Bold', 15), fg="red", bg="Light Blue").place(x=20, y=450)

    yy = 430
    for key, value in data[state_code]['total'].items():
         tk.Label(gui, text="Cumulative Till Date", font=('Calibri Bold', 16), fg="dark blue", bg="Light Blue").place(x=350, y=380)

         p1 = key.replace('{', " ")
         p1 = p1.replace('}', " ")

         if p1 == "confirmed":
             cnf = value
         if p1 == "deceased":
             dead = value
         if p1 == "recovered":
             rec = value

         tk.Label(gui, text=p1, font=('Calibri Bold', 14), fg="Black", bg="Light Blue").place(x=350, y=yy)
         tk.Label(gui, text=value, font=('Calibri', 14), fg="Black", bg="Light Blue").place(x=550, y=yy)
         yy = yy+30

    active = cnf-dead-rec
    rec_rate = (rec/cnf)*100
    tk.Label(gui, text="Active Caseload: " + str(active), font=('Calibri Bold', 20), fg="Red", bg="Light Blue").place(x=20, y=660)
    tk.Label(gui, text="Recovery Rate  : " + str(round(rec_rate,1)) + " %", font=('Calibri Bold', 20), fg="Dark Green", bg="Light Blue").place(x=20, y=700)
    tk.Label(gui, text="Population: " + str(state_pop), font=('Calibri Bold', 20), fg="brown", bg="Light Blue").place(x=350, y=660)
    tk.Label(gui, text="Vaccination: ", font=('Calibri Bold', 20), fg="Dark Green", bg="Light Blue").place(x=350, y=700)
    tk.Label(gui, text="Dose 1: " + str(round(state_v1_p,1)) + " %" + "\nDose 2:   " + str(round(state_v2_p,1)) + " %", font=('Calibri Bold', 14), fg="Dark Green", bg="Light Blue").place(x=520, y=695)

def home():

    global data
    response = requests.get("https://api.covid19india.org/v4/min/data.min.json", verify=False)
    data = response.json()
    # key1 = list(data.keys())
    # key1.remove('TT')

    india_cnf = data['TT']["total"]["confirmed"]
    india_rec = data['TT']["total"]["recovered"]
    india_dead = data['TT']["total"]["deceased"]
    india_oth = data['TT']["total"]["other"]
    india_active = india_cnf-india_rec-india_dead-india_oth
    v1 = data['TT']["total"]["vaccinated1"]
    v2 = data['TT']["total"]["vaccinated2"]
    dat = data['TT']["meta"]["date"]
    pop = data['TT']["meta"]["population"]

    pv1 = (v1/pop)*100
    pv2 = (v2/pop)*100

    try:
        india_cnf_today = data['TT']["delta"]["confirmed"]
        india_dead_today = data['TT']["delta"]["deceased"]
        india_rec_today = data['TT']["delta"]["recovered"]
        india_active_today = india_cnf_today-india_dead_today-india_rec_today
    except:
        india_cnf_today = 0
        india_dead_today = 0
        india_rec_today = 0
        india_active_today = 0

    global s
    s = ttk.Style()
    s.configure('Red.TLabelframe.Label', font=('Arial Bold', 16), foreground ='Dark Blue')

    lf1 = ttk.LabelFrame(gui, text = "Choose State and District", style = "Red.TLabelframe")
    lf1.place(x=10, y=100)
    Frame(lf1, width=1346, height=210, background = 'Light Blue').pack()

    lf2 = ttk.LabelFrame(gui, text = "State Data", style = "Red.TLabelframe")
    lf2.place(x=10, y=350)
    Frame(lf2, width=670, height=380, background = 'Light Blue').pack()

    lf3 = ttk.LabelFrame(gui, text = "District Data", style = "Red.TLabelframe")
    lf3.place(x=690, y=350)
    Frame(lf3, width=670, height=380, background = 'Light Blue').pack()

    tk.Label(gui, text="Select State: ", font=('Calibri Bold', 16), fg="Black", bg="Light Blue").place(x=380, y=150)

    states_list = ["Andaman & Nicobar Islands", "Andhra Pradesh", "Arunachal Pradesh", "Assam", "Bihar", "Chandigarh", "Chattisgarh", "Dadra & Nagar Haveli \ Daman & Diu",
              "Delhi", "Goa", "Gujarat", "Haryana", "Himachal Pradesh", "Jammu & Kashmir", "Jharkhand", "Karnataka", "Kerala", "Ladakh", "Lakshadweep", "Madhya Pradesh",
              "Maharashtra", "Manipur", "Meghalaya", "Mizoram", "Nagaland", "Odisha", "Puducherry", "Punjab", "Rajasthan", "Sikkim",
              "Tamil Nadu", "Telangana", "Tripura", "Uttar Pradesh", "Uttarakhand", "West Bengal"]

    selected_state = tk.StringVar(gui)

    cb1 = ttk.Combobox(gui, textvariable=selected_state, width=35, height=20, values=states_list, font=('Halvetica', 12))
    cb1.place(x=550, y=155)
    cb1.current(0)

    tk.Label(gui, text="Last Updated:\n" + str(dat), font=('Calibri Bold', 16), fg="brown", bg="Light Blue").place(x=150, y=150)
    tk.Label(gui, text="Population:\n" + str(pop), font=('Calibri Bold', 16), fg="brown", bg="Light Blue").place(x=1140, y=150)

    tk.Label(gui, text="Confirmed: " + str(india_cnf), font=('Calibri Bold', 16), fg="brown", bg="Light Blue").place(x=20, y=250)
    tk.Label(gui, text="Active   : " + str(india_active), font=('Calibri Bold', 16), fg="dark blue", bg="Light Blue").place(x=300, y=250)
    tk.Label(gui, text="Recovery: " + str(india_rec), font=('Calibri Bold', 16), fg="dark green", bg="Light Blue").place(x=550, y=250)
    tk.Label(gui, text="Deceased : " + str(india_dead), font=('Calibri Bold', 16), fg="red", bg="Light Blue").place(x=820, y=250)
    tk.Label(gui, text="Vaccine  : " + str(v1+v2), font=('Calibri Bold', 16), fg="green", bg="Light Blue").place(x=1070, y=250)

    tk.Label(gui, text=str(india_cnf_today), font=('Calibri Bold', 12), fg="brown", bg="Light Blue").place(x=100, y=280)
    tk.Label(gui, text=str(india_active_today), font=('Calibri Bold', 12), fg="dark blue", bg="Light Blue").place(x=350, y=280)
    tk.Label(gui, text=str(india_rec_today), font=('Calibri Bold', 12), fg="dark green", bg="Light Blue").place(x=620, y=280)
    tk.Label(gui, text=str(india_dead_today), font=('Calibri Bold', 12), fg="red", bg="Light Blue").place(x=900, y=280)
    tk.Label(gui, text="Dose 1: " + str(v1) + " (" + str(round(pv1, 1)) + " %)", font=('Calibri Bold', 12), fg="green", bg="Light Blue").place(x=1070, y=280)
    tk.Label(gui, text="Dose 2: " + str(v2) + " (" + str(round(pv2, 1)) + " %)", font=('Calibri Bold', 12), fg="green", bg="Light Blue").place(x=1070, y=305)

    tk.Button(gui, text = "Submit", command = lambda: select_district(selected_state), font=('Calibri Bold', 12), fg="white", bg="Dark Blue", width = 10).place(x=950, y=150)
    tk.Button(gui, text = "Refresh", command = lambda: home(), font=('Calibri Bold', 12), fg="white", bg="Dark Blue").place(x=1250, y=50)
    response.close()

global gui
gui = tk.Tk()
gui.title("COVID-19 INDIA")
gui.geometry("1366x768")
gui.resizable(0,0)
gui.configure(background='Light Blue')
tk.Label(gui, text="COVID-19 DASHBOARD", font=('Arial Bold', 54), fg="dark blue", bg="Light Blue").place(x=300, y=1)
home()
gui.mainloop()


"""
Modified from https://github.com/AndrewCarterUK/pascal-voc-writer
"""
import os

from jinja2 import Environment, PackageLoader

class PascalVOCWriter:
    def __init__(
        self,
        path: str,
        width: int,
        height: int,
        depth: int = 3,
        database: str = "Unknown",
        segmented: int = 0,
    ) -> None:
        environment = Environment(
            loader=PackageLoader("ml_dronebase_utils", "templates"),
            keep_trailing_newline=True,
        )
        self.annotation_template = environment.get_template("annotation.xml")
        abspath = os.path.abspath(path)
        if "s3" in path:
            file_path = path
        else:
            file_path = abspath
        self.template_parameters = {
            "path": file_path,
            "filename": os.path.basename(abspath),
            "folder": os.path.basename(os.path.dirname(abspath)),
            "width": width,
            "height": height,
            "depth": depth,
            "database": database,
            "segmented": segmented,
            "objects": [],
        }

    def addObject(
        self,
        name: str,
        xmin: int,
        ymin: int,
        xmax: int,
        ymax: int,
        angle: str = "Unspecified",
        pose: str = "Unspecified",
        truncated: int = 0,
        difficult: int = 0,
    ) -> None:
        self.template_parameters["objects"].append(
            {
                "name": name,
                "xmin": xmin,
                "ymin": ymin,
                "xmax": xmax,
                "ymax": ymax,
                "angle": angle,
                "pose": pose,
                "truncated": truncated,
                "difficult": difficult,
            }
        )

    def save(self, annotation_path: str) -> None:
        with open(annotation_path, "w") as file:
            content = self.annotation_template.render(**self.template_parameters)
            file.write(content)