from typing import Optional
from xml.etree.ElementTree import Element, Comment

from api.mvc.model.data.content_model import ContentModel
from api.mvc.model.data.data_model import DataModel
from api.mvc.model.data.data_type import DataType
from api_core.exception.api_exception import ApiException
from api_core.helper.file_folder_helper import FileFolderHelper
from api_core.helper.string_helper import StringHelper
from api_core.mvc.service.file.xml_file_service import XmlFileService

class ContentModelFileService(XmlFileService):
    """
    Class used to manage content-model XML files.
    """

    def __init__(self):
        """
        Initialize a new instance of 'ContentModelService' class.
        """
        super().__init__(True, {"xmlns": "http://www.alfresco.org/model/dictionary/1.0"})

    def extract_content_model_prefix(self, content_model_file_path: str) -> str:
        """
        Extracts the content model prefix.
        :param content_model_file_path: The path to the content model file.
        :return: The content model prefix.
        """
        root: Element = self._get_root(content_model_file_path)
        filename: str = FileFolderHelper.extract_filename_from_path(content_model_file_path)

        # Verification that the attribute exists.
        if not ("name" in root.attrib):
            raise ApiException("Content model file '{0}' does not have the necessary 'namespace' node."
                               .format(filename))
        # Verification that the attribute has a value.
        if StringHelper.is_empty(root.attrib["name"]):
            raise ApiException("The 'name' attribute of the content model file '{0}' is not entered. The latter is "
                               "mandatory.".format(filename))
        # Data recovery.
        try:
            return root.attrib["name"].rsplit(":", 1)[0]
        except IndexError:
            raise ApiException("The value of the 'name' attribute of the source node is invalid. This must be composed "
                               "as follows: prefix:name")

    def extract_content_model_name(self, content_model_file_path: str) -> str:
        """
        Extracts the content model name.
        :param content_model_file_path: The path to the content model file.
        :return: The content model name.
        """
        root: Element = self._get_root(content_model_file_path)
        filename: str = FileFolderHelper.extract_filename_from_path(content_model_file_path)

        # Verification that the attribute exists.
        if not ("name" in root.attrib):
            raise ApiException("Content model file '{0}' does not have the necessary 'namespace' node."
                               .format(filename))
        # Verification that the attribute has a value.
        if StringHelper.is_empty(root.attrib["name"]):
            raise ApiException("The 'name' attribute of the content model file '{0}' is not entered. The latter is "
                               "mandatory.".format(filename))
        # Data recovery.
        try:
            return root.attrib["name"].rsplit(":", 1)[1]
        except IndexError:
            raise ApiException("The value of the 'name' attribute of the source node is invalid. This must be composed "
                               "as follows: prefix:name")

    def create_content_model(self, content_model_file_path: str, prefix: str, name: str, description: Optional[str],
                             author: Optional[str]):
        model: Element = Element("model")
        model.set("name", "{0}:{1}".format(prefix, name))

        # Set xml namespace.
        if self.namespaces is not None:
            for item in self.namespaces:
                model.set(item[0], item[1])

        model.append(Comment(" Optional meta-data about the model "))

        # Set the description
        description_node: Element = Element("description")
        description_node.text = description if description is not None else "SET THE PROJECT DESCRIPTION"
        model.append(description_node)

        # Set the author
        author_node: Element = Element("author")
        author_node.text = author if author is not None else "Alfresco Helper Script 1.0.0"
        model.append(author_node)

        # Set the version
        version_node: Element = Element("version")
        version_node.text = "1.0.0"
        model.append(version_node)

        # Set the imports
        imports_node: Element = Element("imports")
        imports_node.append(Comment(" Import Alfresco Dictionary Definitions "))
        # First import
        import1: Element = Element("import")
        import1.set("uri", "http://www.alfresco.org/model/dictionary/1.0")
        import1.set("prefix", "d")
        imports_node.append(import1)

        # Second import
        import2: Element = Element("import")
        import2.set("uri", "http://www.alfresco.org/model/content/1.0")
        import2.set("prefix", "cm")
        imports_node.append(import2)

        # Set the namespaces.
        namespaces_node: Element = Element("namespaces")
        # Set a namespace
        namespace_node: Element = Element("namespace")
        namespace_node.set("uri", "http://www.{0}.org/model/content/1.0".format(name.lower()))
        namespace_node.set("prefix", prefix)
        namespaces_node.append(namespace_node)

        # Add the import to the model.
        model.append(imports_node)
        # Add the import to the model.
        model.append(Comment(" Custom namespace for the '{0}:{1}' model ".format(prefix, name)))
        model.append(namespaces_node)

        types: Element = Element("types")
        aspects: Element = Element("aspects")

        model.append(types)
        model.append(aspects)

        # Write the XML file.
        self._write(model, content_model_file_path)

    def find_data(self, content_model: ContentModel, typology: str, data: str) -> Optional[Element]:
        """
        Finds data's node in its content model.
        :param content_model: A data model of a content-model.
        :param typology: The data typology.
        :param data: The name of the data.
        :return: The data node, otherwise None.
        """
        return self._get_root(content_model.path).find(".//{0}{3}s/{0}{3}[@name='{1}:{2}']".format(
            self.get_namespace("xmlns"), content_model.prefix, data, typology))

    def find_aspect(self, content_model: ContentModel, aspect: str) -> Optional[Element]:
        """
        Finds an aspect's node in its content model.
        :param content_model: A data model of a content-model.
        :param aspect: The name of the aspect.
        :return: The aspect node, otherwise None.
        """
        return self._get_root(content_model.path).find(".//{0}aspects/{0}aspect[@name='{1}:{2}']".format(
            self.get_namespace("xmlns"), content_model.prefix, aspect))

    def get_aspects_name(self, content_model: ContentModel) -> list[str]:
        """
        Finds an all aspects name in its content model.
        :param content_model: A data model of a content-model.
        :return: The list of aspects name.
        """
        aspects: list[str] = []
        filename: str = FileFolderHelper.extract_filename_from_path(content_model.path)
        for aspect in self._get_root(content_model.path).findall(".//{0}aspects/{0}aspect".format(
                self.get_namespace("xmlns"))):
            aspects.append(self.__extract_aspect_name(aspect, filename))
        return aspects

    def get_data_names(self, content_model: ContentModel, typology: str) -> list[str]:
        """
        Finds an all aspects name in its content model.
        :param typology: The type of the data to get.
        :param content_model: A data model of a content-model.
        :return: The list of aspects name.
        """
        data_names: list[str] = []
        filename: str = FileFolderHelper.extract_filename_from_path(content_model.path)
        for data in self._get_root(content_model.path).findall(".//{0}{1}s/{0}{1}".format(
                self.get_namespace("xmlns"), typology)):
            data_names.append(self.__extract_data_name(data, typology, filename))
        return data_names

    def find_type(self, content_model: ContentModel, type_name: str) -> Optional[Element]:
        return self._get_root(content_model.path).find(".//{0}types/{0}type[@name='{1}:{2}']".format(
            self.get_namespace("xmlns"), content_model.prefix, type_name))

    def add_aspect(self, content_model: ContentModel, name: str, title: str, description: str):
        root: Element = self._get_root(content_model.path)

        aspect: Element = Element("aspect")
        aspect.set("name", "{0}:{1}".format(content_model.prefix, name))

        if not StringHelper.is_empty(title):
            title_node: Element = Element("title")
            title_node.text = title
            aspect.append(title_node)

        if not StringHelper.is_empty(description):
            description_node: Element = Element("description")
            description_node.text = description
            aspect.append(description_node)

        properties: Element = Element("properties")
        aspect.append(properties)

        add_to_root: bool = False
        aspects: Element = root.find(".//{0}aspects".format(self.get_namespace("xmlns"), content_model.prefix, aspect))
        if aspects is None:
            aspects = Element("aspects")
            add_to_root = True

        aspects.append(Comment(" Definition of aspect '{0}'. ".format(name)))
        aspects.append(aspect)

        if add_to_root:
            root.append(aspects)

        self._write(root, content_model.path)

    def add_type(self, content_model: ContentModel, name: str, title: str, description: str):
        root: Element = self._get_root(content_model.path)

        type_node: Element = Element("type")
        type_node.set("name", "{0}:{1}".format(content_model.prefix, name))

        if not StringHelper.is_empty(title):
            title_node: Element = Element("title")
            title_node.text = title
            type_node.append(title_node)

        if not StringHelper.is_empty(description):
            description_node: Element = Element("description")
            description_node.text = description
            type_node.append(description_node)

        properties: Element = Element("properties")
        type_node.append(properties)

        add_to_root: bool = False
        types: Element = root.find(".//{0}types".format(self.get_namespace("xmlns"), content_model.prefix, type_node))
        if types is None:
            types = Element("types")
            add_to_root = True

        types.append(Comment(" Definition of type '{0}'. ".format(name)))
        types.append(type_node)

        self._write(root, content_model.path)

    def add_property(self, content_model: ContentModel, data: DataModel, name: str, title: Optional[str],
                     description: Optional[str], typology: str, mandatory: bool):
        root: Element = self._get_root(content_model.path)
        # Create the property
        prop: Element = Element("property")
        prop.set("name", "{0}:{1}".format(content_model.prefix, name))

        # Set the property's title.
        if not StringHelper.is_empty(title):
            title_node: Element = Element("title")
            title_node.text = title
            prop.append(title_node)

        # Set the property's description.
        if not StringHelper.is_empty(description):
            description_node: Element = Element("description")
            description_node.text = description
            prop.append(description_node)

        # Set the property's type.
        type_node: Element = Element("type")
        type_node.text = "d:{0}".format(typology)
        prop.append(type_node)

        # Set the property's mandatory.
        mandatory_node: Element = Element("mandatory")
        mandatory_node.text = "true" if mandatory else "false"
        prop.append(mandatory_node)

        data_node: Optional[Element] = root.find(".//{0}{3}s/{0}{3}[@name='{1}:{2}']"
                                                 .format(self.get_namespace("xmlns"), content_model.prefix, data.name,
                                                         data.typology))

        add_to_data: bool = False
        properties_node: Element = data_node.find(".//{0}properties".format(self.get_namespace("xmlns")))
        if properties_node is None:
            properties_node = Element("properties")
            add_to_data = True

        properties_node.append(prop)
        if add_to_data:
            data_node.append(properties_node)

        self._write(root, content_model.path)

    def add_extension(self, content_model: ContentModel, source: DataModel, parent: DataModel):
        namespace: str = self.get_namespace("xmlns")
        root: Element = self._get_root(content_model.path)

        source_node: Element = root.find(".//{0}{1}s/{0}{1}[@name='{2}:{3}']"
                                         .format(namespace, source.typology, content_model.prefix, source.name))
        parent_node: Optional[Element] = source_node.find("./{0}parent".format(namespace))

        add_parent: bool = True if parent_node is None else False
        if add_parent:
            parent_node = Element("parent")

        parent_node.text = "{0}".format(parent.complete_name)

        if add_parent:
            source_node.insert(self.__get_properties_node_index(source_node), parent_node)

        self._write(root, content_model.path)

    def add_mandatory(self, content_model: ContentModel, source: DataModel, mandatory: DataModel):
        namespace: str = self.get_namespace("xmlns")
        root: Element = self._get_root(content_model.path)

        source_node: Element = root.find(".//{0}{1}s/{0}{1}[@name='{2}:{3}']"
                                         .format(namespace, source.typology, content_model.prefix, source.name))
        mandatory_node: Optional[Element] = source_node.find("./{0}mandatory-aspects".format(namespace))

        aspect: Element = Element("aspect")
        aspect.text = "{0}:{1}".format(content_model.prefix, mandatory.name)

        add_mandatory_node: bool = True if mandatory_node is None else False
        if add_mandatory_node:
            mandatory_node = Element("mandatory-aspects")
        mandatory_node.append(aspect)
        if add_mandatory_node:
            source_node.append(mandatory_node)

        self._write(root, content_model.path)

    def get_aspect_description(self, content_model: ContentModel, name: str) -> Optional[str]:
        """
        Retrieve the value of the description node of an aspect node.
        :param content_model: A data model of a content-model.
        :param name: The name of the aspect node.
        :return: The value of the aspect's description node.
        """
        return self.__get_data_description(content_model, DataType.ASPECT.name, name)

    def get_type_description(self, content_model: ContentModel, name: str) -> Optional[str]:
        """
        Retrieve the value of the description node of a type node.
        :param content_model: A data model of a content-model.
        :param name: The name of the type node.
        :return: The value of the type's description node.
        """
        return self.__get_data_description(content_model, DataType.TYPE.name, name)

    def get_aspect_title(self, content_model: ContentModel, name: str) -> Optional[str]:
        """
        Retrieve the value of the title node of an aspect node.
        :param content_model: A data model of a content-model.
        :param name: The name of the aspect node.
        :return: The value of the aspect's title node.
        """
        return self.__get_data_title(content_model, DataType.ASPECT.value, name)

    def get_aspect_parent(self, content_model: ContentModel, name: str) -> Optional[str]:
        """
        Retrieve the value of the parent node of an aspect node.
        :param content_model: A data model of a content-model.
        :param name: The name of the aspect node.
        :return: The value of the aspect's parent node.
        """
        return self.get_data_parent(content_model, DataType.ASPECT.value, name)

    def get_aspect_mandatory_aspects(self, content_model: ContentModel, name: str) -> list[str]:
        return self.__get_data_mandatory_aspects(content_model, DataType.ASPECT.value, name)

    def get_type_title(self, content_model: ContentModel, name: str) -> Optional[str]:
        """
        Retrieve the value of the title node of a type node.
        :param content_model: A data model of a content-model.
        :param name: The name of the type node.
        :return: The value of the type's title node.
        """
        return self.__get_data_title(content_model, DataType.TYPE.name, name)

    def get_type_parent(self, content_model: ContentModel, name: str) -> Optional[str]:
        """
        Retrieve the value of the title node of a type node.
        :param content_model: A data model of a content-model.
        :param name: The name of the type node.
        :return: The value of the type's title node.
        """
        return self.__get_data_title(content_model, DataType.TYPE.name, name)

    def __extract_aspect_name(self, aspect: Element, filename: str) -> str:
        """
        Extracts the aspect node name.
        :param aspect: The aspect node.
        :return: The aspect name.
        """
        return self.__extract_data_name(aspect, DataType.ASPECT.name, filename)

    def get_type_mandatory_aspects(self, content_model: ContentModel, name: str) -> list[str]:
        return self.__get_data_mandatory_aspects(content_model, DataType.TYPE.value, name)

    def __extract_type_name(self, type_node: Element, filename: str) -> str:
        """
        Extracts the aspect node name.
        :param type_node: The type node.
        :return: The type name.
        """
        return self.__extract_data_name(type_node, DataType.TYPE.value, filename)

    @staticmethod
    def __extract_data_name(data: Element, typology: str, filename: str) -> str:
        """
        Extracts the aspect node name.
        :param data: The aspect model.
        :return: The aspect name.
        """
        # Verification that the attribute exists.
        if not ("name" in data.attrib):
            raise ApiException("There is {1} in file '{0}' that has not been defined correctly. It lacks the "
                               "'name' attribute."
                               .format(filename, "an aspect" if typology.__eq__("aspect") else "a type"))

        # Verification that the attribute has a value.
        if StringHelper.is_empty(data.attrib["name"]):
            raise ApiException("There is {1} in file '{0}' that has not been defined correctly. The 'name' "
                               "attribute is null or empty."
                               .format(filename, "an aspect" if typology.__eq__("aspect") else "a type"))

        # Data recovery.
        try:
            return data.attrib["name"].rsplit(":", 1)[1]
        except IndexError:
            raise ApiException("There is {1} in file '{0}' whose name attribute was not set correctly. The "
                               "attribute value must be composed as follows: prefix:name"
                               .format(filename, "an aspect" if typology.__eq__("aspect") else "a type"))

    @staticmethod
    def __extract_property_name(prop: Element, filename: str) -> str:
        """
        Extracts the aspect node name.
        :param prop: The property node.
        :return: The aspect name.
        """
        # Verification that the attribute exists.
        if not ("name" in prop.attrib):
            raise ApiException("There is a property in file '{0}' that has not been defined correctly. It lacks the "
                               "'name' attribute."
                               .format(filename))

        # Verification that the attribute has a value.
        if StringHelper.is_empty(prop.attrib["name"]):
            raise ApiException("There is a property in file '{0}' that has not been defined correctly. The 'name' "
                               "attribute is null or empty."
                               .format(filename))

        # Data recovery.
        try:
            return prop.attrib["name"].rsplit(":", 1)[1]
        except IndexError:
            raise ApiException("There is a property in file '{0}' whose name attribute was not set correctly. The "
                               "attribute value must be composed as follows: prefix:name"
                               .format(filename))

    def __get_data_description(self, content_model: ContentModel, typology: str, name: str) -> Optional[str]:
        """
        Retrieve the value of the description node of a data node (aspect or type).
        :param content_model: A data model of a content-model.
        :param typology: The type of the node (aspect or type).
        :param name: The name of the data node.
        :return: The value of the data node description node.
        """
        description: Element = self._get_root(content_model.path) \
            .find(".//{0}{1}s/{0}{1}[@name='{2}:{3}']/{0}description"
                  .format(self.get_namespace("xmlns"), typology, content_model.prefix, name))
        return None if description is None else description.text

    def __get_data_title(self, content_model: ContentModel, typology: str, name: str) -> Optional[str]:
        """
        Retrieve the value of the title node of a data node (aspect or type).
        :param content_model: A data model of a content-model.
        :param typology: The type of the node (aspect or type).
        :param name: The name of the data node.
        :return: The value of the data node title node.
        """
        title: Element = self._get_root(content_model.path) \
            .find(".//{0}{1}s/{0}{1}[@name='{2}:{3}']/{0}title"
                  .format(self.get_namespace("xmlns"), typology, content_model.prefix, name))
        return None if title is None else title.text

    def get_data_parent(self, content_model: ContentModel, typology: str, name: str) -> Optional[str]:
        """
        Retrieve the value of the parent node of a data node (aspect or type).
        :param content_model: A data model of a content-model.
        :param typology: The type of the node (aspect or type).
        :param name: The name of the data node.
        :return: The value of the data node title node.
        """
        parent: Element = self._get_root(content_model.path) \
            .find(".//{0}{1}s/{0}{1}[@name='{2}:{3}']/{0}parent"
                  .format(self.get_namespace("xmlns"), typology, content_model.prefix, name))
        return None if parent is None else parent.text

    def __get_data_mandatory_aspects(self, content_model: ContentModel, typology: str, name: str) -> list[str]:
        result: list[str] = []
        root: Element = self._get_root(content_model.path)
        mandatory_aspects: list[Element] = root.findall(".//{0}{1}s/{0}{1}[@name='{2}:{3}']/{0}mandatory-aspects"
                                                        "/{0}aspect".format(self.get_namespace("xmlns"), typology,
                                                                            content_model.prefix, name))
        for mandatory_aspect in mandatory_aspects:
            result.append(mandatory_aspect.text)

        return result

    def __get_properties_node_index(self, data_node: Element) -> int:
        namespace: str = self.get_namespace("xmlns")
        children: list[Element] = data_node.findall(".//{0}*".format(namespace))
        maximum: int = len(children)
        index: int = 0

        while index.__lt__(maximum) and children[index].tag.__ne__("{0}properties".format(namespace)):
            index += 1

        return index if index.__lt__(maximum) else (index - 1)

    def get_property(self, content_model: ContentModel, data: DataModel, property_name: str) \
            -> tuple[str, str, str, str, bool]:
        namespace: str = self.get_namespace("xmlns")
        root: Element = self._get_root(content_model.path)
        filename: str = FileFolderHelper.extract_filename_from_path(content_model.path)

        node: Element = root.find(".//{0}{1}s/{0}{1}[@name='{2}:{3}']/{0}properties/{0}property[@name='{2}:{4}']"
                                  .format(namespace, data.typology, content_model.prefix, data.name, property_name))
        if node is None:
            ApiException("There is no property named '{0}' in {1} '{2}' in content model '{3}' in file '{4}'."
                         .format(property_name, data.typology, data.name, content_model.complete_name, filename))

        title_node: Element = node.find("./{0}title".format(namespace))
        title: Optional[str] = None if title_node is None else title_node.text

        description_node: Element = node.find("./{0}description".format(namespace))
        description: Optional[str] = None if description_node is None else description_node.text

        type_node: Element = node.find("./{0}type".format(namespace))
        typology: Optional[str] = None
        if type_node is not None:
            if StringHelper.is_empty(type_node.text):
                raise ApiException("The type of the {0} property from the content-model '{1}' of file '{2}' is invalid."
                                   " It cannot be empty or None."
                                   .format(data.typology, content_model.complete_name,
                                           FileFolderHelper.extract_filename_from_path(content_model.path)))
            elif StringHelper.has_space(type_node.text):
                raise ApiException("The type of the {0} property from the content-model '{1}' of file '{2}' is invalid."
                                   " There can be no space in it."
                                   .format(data.typology, content_model.complete_name,
                                           FileFolderHelper.extract_filename_from_path(content_model.path)))
            try:
                typology = type_node.text.rsplit(":", 1)[1]
                if (typology.__ne__("text") and typology.__ne__("int") and typology.__ne__("long")
                        and typology.__ne__("float") and typology.__ne__("double") and typology.__ne__("date")
                        and typology.__ne__("datetime") and typology.__ne__("boolean") and typology.__ne__("encrypted")
                        and typology.__ne__("noderef")):
                    raise ApiException(
                        "The type of the {0} property from the content-model '{1}' of file '{2}' is invalid. Its value"
                        " must be: text, int, long, float, double, date, datetime, boolean, encrypted or noderef."
                        .format(data.typology, content_model.complete_name,
                                FileFolderHelper.extract_filename_from_path(content_model.path)))

            except IndexError:
                raise ApiException("The value of property type '{0}' of {1} '{2}' of content model '{3}' of file '{4}'"
                                   " is invalid. It should be formed like this: d:[type]"
                                   .format(property_name, data.typology, data.name, content_model.complete_name,
                                           filename))

        mandatory_node: Element = node.find("./{0}mandatory".format(namespace))
        mandatory: bool = False
        if mandatory_node is not None:

            if StringHelper.is_empty(mandatory_node.text):
                raise ApiException("The value of property 'mandatory' '{0}' of {1} {2} of content model {3} of file "
                                   "{4} is invalid. A value must be set ('true' or 'false').")

            elif mandatory_node.text.__eq__("true"):
                mandatory = True

            elif mandatory_node.text.__eq__("false"):
                mandatory = False
            else:
                raise ApiException("The value of property 'mandatory' '{0}' of {1} {2} of content model {3} of file "
                                   "{4} is invalid. The value can only be 'true' or 'false'."
                                   .format(property_name, data.typology, data.name, content_model.complete_name,
                                           filename))

        return property_name, title, description, typology, mandatory

    def get_properties(self, content_model: ContentModel) -> list[str]:
        result: list[str] = []
        filename: str = FileFolderHelper.extract_filename_from_path(content_model.path)
        root: Element = self._get_root(content_model.path)
        for prop in root.findall(".//{0}aspects/{0}aspect/{0}properties/{0}property".format(
                self.get_namespace("xmlns"))):
            result.append(self.__extract_property_name(prop, filename))
        for prop in root.findall(".//{0}types/{0}type/{0}properties/{0}property".format(
                self.get_namespace("xmlns"))):
            result.append(self.__extract_property_name(prop, filename))
        return result

    def get_data_property_names(self, content_model: ContentModel, data: DataModel) -> list[str]:
        """
        Retrieve a list of property names from a data model.
        :param content_model: A data model of a content-model.
        :param data:
        :return:
        """
        # Result initialization.
        result: list[str] = []
        # Retrieving model properties.
        namespace: str = self.get_namespace("xmlns")
        root: Element = self._get_root(content_model.path)
        filename: str = FileFolderHelper.extract_filename_from_path(content_model.path)
        properties: list[Element] = root.findall(".//{0}{1}s/{0}{1}[@name='{2}:{3}']/{0}properties/{0}property"
                                                 .format(namespace, data.typology, content_model.prefix, data.name))
        # Extract property names.
        for prop in properties:
            result.append(self.__extract_property_name(prop, filename))
        # Return of the result.
        return result


from flask_restx import Namespace, Resource, reqparse
from main.model.ORM import *

search_ns = Namespace('searching', description='search recipes by either recipe\'s name or ingredients list')

search_name_rep = reqparse.RequestParser()
search_name_rep.add_argument('name', type=str)
search_name_rep.add_argument('email', type=str)

@search_ns.route('/by_name')
class Searching_by_Name(Resource):
    @search_ns.expect(search_name_rep)
    def post(self):
        args = search_name_rep.parse_args()
        name = args['name']

        recipe = RecipeDB.query.filter_by(name=name).first()

        if not recipe:
            return {'error': 'recipe does not exist'}
        else:
            # update user explore history
            user = UserDB.query.filter_by(email=args['email']).first()
            explore_list = eval(user.explore_list)

            if recipe.id not in explore_list:
                if len(explore_list) == 10:
                    del explore_list[0]
                explore_list.append(recipe.id)
                user.explore_list = str(explore_list)
                db.session.commit()
            ##

            contributor = UserDB.query.filter_by(id=recipe.contributed_by).first()

            return {
                'recipe_name': recipe.name,
                'rate': recipe.average_rate,
                'external_link': recipe.external_link,
                'contributor': {'email': contributor.email,
                                'name': contributor.name,
                                'is_followed': contributor.id in eval(user.follow_list),
                                },
                'category': recipe.category,
                'ingredients': [IngredientDB.query.filter_by(id=id).first().name for id in
                                recipe.ingredients_list.split(',')],
                'comments': [i.text for i in recipe.comments_id],
                'is_favourite': recipe.id in eval(user.favourite_list)

            }

search_list_rep = reqparse.RequestParser()
search_list_rep.add_argument('ingredients_list', type=str)  # , location='args')

@search_ns.route('/by_list')
# 名字 分数 图片 食材有几种
class Searching_by_list(Resource):

    # 先返回所有匹配上的菜谱的简略信息，用户点开具体某一个之后前端再向后端请求具体信息
    @search_ns.expect(search_list_rep)
    def post(self):
        ingredients_str = search_list_rep.parse_args()['ingredients_list']
        have_id_list = [IngredientDB.query.filter_by(name=name).first().id for name in ingredients_str.split(',')]

        has_fully_covered = 0
        return_format = []
        for i in db.session.query(RecipeDB.name, RecipeDB.ingredients_list, RecipeDB.average_rate,
                                  RecipeDB.category).order_by(
                RecipeDB.average_rate.desc()).all():

            need_id_list = i.ingredients_list.split(',')
            miss_id_list = [int(j) for j in need_id_list if int(j) not in have_id_list]

            # 如果缺少大于1 或者 食谱只需要一个食材还缺少
            if len(miss_id_list) > 1 or (miss_id_list and len(need_id_list) == 1):
                continue

            if not miss_id_list:
                has_fully_covered = 1

            return_format.append({'name': i.name,
                                  'rate': i.average_rate,
                                  'category': i.category,
                                  'n_ingredients': len(need_id_list),
                                  'missing': IngredientDB.query.filter_by(id=miss_id_list[0]).first().name if len(
                                      miss_id_list) else None})

        if not has_fully_covered:
            self._update_SearchDB(have_id_list)

        return return_format

    def _update_SearchDB(self, id_list):
        searched_id_str = ','.join('%s' % n for n in sorted(id_list))
        searched_list = IngredientSearchDB.query.filter_by(ingredients_list=searched_id_str).first()
        if searched_list:
            searched_list.times += 1
        else:
            new_searched_list = IngredientSearchDB(
                ingredients_list=searched_id_str,
            )
            db.session.add(new_searched_list)

        db.session.commit()
        return


# Opus/UrbanSim urban simulation software.
# Copyright (C) 2010-2011 University of California, Berkeley, 2005-2009 University of Washington
# See opus_core/LICENSE

from opus_core.variables.variable import Variable, ln
from variable_functions import my_attribute_label

class county_id(Variable):
    """county id of household"""

    def dependencies(self):
        return [my_attribute_label("grid_id"),
                "urbansim.gridcell.county_id"
                ]

    def compute(self, dataset_pool):
        gridcells = dataset_pool.get_dataset('gridcell')
        return self.get_dataset().get_join_data(gridcells, "county_id")

from opus_core.tests import opus_unittest
from urbansim.variable_test_toolbox import VariableTestToolbox
from numpy import array
from numpy import ma
class Tests(opus_unittest.OpusTestCase):
    variable_name = "psrc.household.county_id"

    def test_my_inputs( self ):

        values = VariableTestToolbox().compute_variable( self.variable_name, \
            {"household":{ \
                "grid_id":array([1, 1, 2, 3, 4]),
                },
             "gridcell":{
                 "grid_id":array([1, 2, 3, 4]),
                 "county_id":array([33, 31, 21, 33])
                         }
             }, \
            dataset = "household" )
        should_be = array( [33, 33, 31, 21, 33] )

        self.assertEqual( ma.allclose( values, should_be, rtol=1e-7 ), \
                          True, msg = "Error in " + self.variable_name )

if __name__=='__main__':
    opus_unittest.main()


from sets import Set
from collections import defaultdict
class MagicDictionary(object):

    def __init__(self):
        """
        Initialize your data structure here.
        """

    def buildDict(self, dict):
        """
        Build a dictionary through a list of words
        :type dict: List[str]
        :rtype: void
        """
        self.data = defaultdict(int)
        self.original = Set(dict)
        for w in dict:
            for i in xrange(len(w)):
                can = w[:i]+"_"+w[i+1:]
                self.data[can] += 1
                # print can
        # print self.data

    def search(self, word):
        """
        Returns if there is any word in the trie that equals to the given word after modifying exactly one character
        :type word: str
        :rtype: bool
        """
        double = False
        if word in self.original:
            double = True
        for i in xrange(len(word)):
            can = word[:i]+"_"+word[i+1:]

            if double:
                if can in self.data and self.data[can] >= 2:
                    return True
            else:
                if can in self.data:
                    return True

        return False

# Your MagicDictionary object will be instantiated and called as such:
# obj = MagicDictionary()
# obj.buildDict(dict)
# param_2 = obj.search(word)
#Implement Magic Dictionary


# PopGen 1.1 is A Synthetic Population Generator for Advanced
# Microsimulation Models of Travel Demand
# Copyright (C) 2009, Arizona State University
# See PopGen/License

DEFAULT_PERSON_PUMS2000_QUERIES = [ "alter table person_pums add column agep bigint",
                                "alter table person_pums add column gender bigint",
                                "alter table person_pums add column race bigint",
                                "alter table person_pums add column employment bigint",
                                "update person_pums set agep = 1 where age < 5",
                                "update person_pums set agep = 2 where age >= 5 and age < 15",
                                "update person_pums set agep = 3 where age >= 15 and age < 25",
                                "update person_pums set agep = 4 where age >= 25 and age < 35",
                                "update person_pums set agep = 5 where age >= 35 and age < 45",
                                "update person_pums set agep = 6 where age >= 45 and age < 55",
                                "update person_pums set agep = 7 where age >= 55 and age < 65",
                                "update person_pums set agep = 8 where age >= 65 and age < 75",
                                "update person_pums set agep = 9 where age >= 75 and age < 85",
                                "update person_pums set agep = 10 where age >= 85",
                                "update person_pums set gender = sex",
                                "update person_pums set race = 1 where race1 = 1",
                                "update person_pums set race = 2 where race1 = 2",
                                "update person_pums set race = 3 where race1 >=3 and race1 <= 5",
                                "update person_pums set race = 4 where race1 = 6",
                                "update person_pums set race = 5 where race1 = 7",
                                "update person_pums set race = 6 where race1 = 8",
                                "update person_pums set race = 7 where race1 = 9",
                                "update person_pums set employment = 1 where esr = 0",
                                "update person_pums set employment = 2 where esr = 1 or esr = 2 or esr = 4 or esr = 5",
                                "update person_pums set employment = 3 where esr = 3",
                                "update person_pums set employment = 4 where esr = 6",
                                "drop table person_sample",
                                "create table person_sample select state, pumano, hhid, serialno, pnum, agep, gender, race, employment, relate from person_pums",
                                "alter table person_sample add index(serialno, pnum)",
                                "drop table hhld_sample_temp",
                                "alter table hhld_sample drop column hhldrage",
                                "alter table hhld_sample rename to hhld_sample_temp",
                                "drop table hhld_sample",
                                "create table hhld_sample select hhld_sample_temp.*, agep as hhldrage from hhld_sample_temp left join person_sample using(serialno) where relate = 1",
                                "alter table hhld_sample add index(serialno)",
                                "update hhld_sample set hhldrage = 1 where hhldrage <=7 ",
                                "update hhld_sample set hhldrage = 2 where hhldrage >7"]

DEFAULT_PERSON_PUMSACS_QUERIES = ["alter table person_pums change agep age bigint",
                                  "alter table person_pums change puma pumano bigint",
                                  "alter table person_pums change rac1p race1 bigint",
                                  "alter table person_pums change st state bigint",
                                  "alter table person_pums change sporder pnum bigint",
                                  "alter table person_pums change rel relate bigint",

                                  "alter table person_pums add column agep bigint",
                                  "alter table person_pums add column gender bigint",
                                  "alter table person_pums add column race bigint",
                                  "alter table person_pums add column employment bigint",
                                  "update person_pums set agep = 1 where age < 5",
                                  "update person_pums set agep = 2 where age >= 5 and age < 15",
                                  "update person_pums set agep = 3 where age >= 15 and age < 25",
                                  "update person_pums set agep = 4 where age >= 25 and age < 35",
                                  "update person_pums set agep = 5 where age >= 35 and age < 45",
                                  "update person_pums set agep = 6 where age >= 45 and age < 55",
                                  "update person_pums set agep = 7 where age >= 55 and age < 65",
                                  "update person_pums set agep = 8 where age >= 65 and age < 75",
                                  "update person_pums set agep = 9 where age >= 75 and age < 85",
                                  "update person_pums set agep = 10 where age >= 85",
                                  "update person_pums set gender = sex",
                                  "update person_pums set race = 1 where race1 = 1",
                                  "update person_pums set race = 2 where race1 = 2",
                                  "update person_pums set race = 3 where race1 >=3 and race1 <= 5",
                                  "update person_pums set race = 4 where race1 = 6",
                                  "update person_pums set race = 5 where race1 = 7",
                                  "update person_pums set race = 6 where race1 = 8",
                                  "update person_pums set race = 7 where race1 = 9",
                                  "update person_pums set employment = 1 where esr = 0",
                                  "update person_pums set employment = 2 where esr = 1 or esr = 2 or esr = 4 or esr = 5",
                                  "update person_pums set employment = 3 where esr = 3",
                                  "update person_pums set employment = 4 where esr = 6",

                                  "alter table person_pums add index(serialno)",

                                   "create table person_pums1 select person_pums.*, hhid from person_pums left join serialcorr using(serialno)",
                                  "update person_pums1 set serialno = hhid",

                                  "drop table person_sample",

                                  "create table person_sample select state, pumano, hhid, serialno, pnum, agep, gender, race, employment, relate from person_pums1",
                                  "alter table person_sample add index(serialno, pnum)",

                                  "drop table hhld_sample_temp",
                                  "alter table hhld_sample drop column hhldrage",
                                  "alter table hhld_sample rename to hhld_sample_temp",
                                  "drop table hhld_sample",
                                  "create table hhld_sample select hhld_sample_temp.*, agep as hhldrage from hhld_sample_temp left join person_sample using(serialno) where relate = 0",
                                  "alter table hhld_sample add index(serialno)",
                                  "update hhld_sample set hhldrage = 1 where hhldrage <=7 ",
                                  "update hhld_sample set hhldrage = 2 where hhldrage >7",
                                  "drop table hhld_sample_temp",
                                  "drop table person_pums1"]

DEFAULT_HOUSING_PUMS2000_QUERIES = ["alter table housing_pums add index(serialno)",
                                "alter table housing_pums add column hhtype bigint",
                                "alter table housing_pums add column hhldtype bigint",
                                "alter table housing_pums add column hhldinc bigint",
                                "alter table housing_pums add column hhldtenure bigint",
                                "alter table housing_pums add column hhldsize bigint",
                                "alter table housing_pums add column childpresence bigint",
                                "alter table housing_pums add column groupquarter bigint",
                                "alter table housing_pums add column hhldfam bigint",

                                "update housing_pums set hhtype = 1 where unittype = 0",
                                "update housing_pums set hhtype = 2 where unittype = 1 or unittype = 2",
                                "update housing_pums set hhldtype = 1 where hht = 1",
                                "update housing_pums set hhldtype = 2 where hht = 2",
                                "update housing_pums set hhldtype = 3 where hht = 3",
                                "update housing_pums set hhldtype = 4 where hht = 4 or hht = 5",
                                "update housing_pums set hhldtype = 5 where hht = 6 or hht = 7",
                                "update housing_pums set hhldtype = -99 where hht = 0",
                                "update housing_pums set hhldinc = 1 where hinc <15000",
                                "update housing_pums set hhldinc = 2 where hinc >= 15000 and hinc < 25000",
                                "update housing_pums set hhldinc = 3 where hinc >= 25000 and hinc < 35000",
                                "update housing_pums set hhldinc = 4 where hinc >= 35000 and hinc < 45000",
                                "update housing_pums set hhldinc = 5 where hinc >= 45000 and hinc < 60000",
                                "update housing_pums set hhldinc = 6 where hinc >= 60000 and hinc < 100000",
                                "update housing_pums set hhldinc = 7 where hinc >= 100000 and hinc < 150000",
                                "update housing_pums set hhldinc = 8 where hinc >= 150000",
                                "update housing_pums set hhldinc = -99 where hht = 0",
                                #"update housing_pums set hhldtenure = 1 where tenure = 1 or tenure = 2",
                                #"update housing_pums set hhldtenure = 2 where tenure = 3 or tenure = 4",
                                #"update housing_pums set hhldtenure = -99 where tenure = 0",
                                "update housing_pums set hhldsize = persons where persons < 7",
                                "update housing_pums set hhldsize = 7 where persons >= 7",
                                "update housing_pums set hhldsize = -99 where hht = 0",
                                "update housing_pums set childpresence = 1 where noc > 0",
                                "update housing_pums set childpresence = 2 where noc = 0",
                                "update housing_pums set childpresence = -99 where hht = 0",
                                "update housing_pums set groupquarter = unittype where unittype >0",
                                "update housing_pums set groupquarter = -99 where unittype =0",

                                "update housing_pums set hhldfam = 1 where hhldtype <=3",
                                "update housing_pums set hhldfam = 2 where hhldtype > 3",

                                "delete from housing_pums where persons = 0",
                                "drop table hhld_sample",
                                "drop table gq_sample",
                                "create table hhld_sample select state, pumano, hhid, serialno, hhtype, hhldtype, hhldinc, hhldsize, childpresence, hhldfam from housing_pums where hhtype = 1",
                                "create table gq_sample select state, pumano, hhid, serialno, hhtype, groupquarter from housing_pums where hhtype = 2",
                                "alter table hhld_sample add index(serialno)",
                                "alter table gq_sample add index(serialno)"]

DEFAULT_HOUSING_PUMSACS_QUERIES = ["alter table housing_pums add index(serialno)",
                                   "alter table housing_pums change hincp hinc bigint",
                                   "alter table housing_pums change np persons bigint",
                                   "alter table housing_pums change hupaoc noc bigint",
                                   "alter table housing_pums change type unittype bigint",
                                   "alter table housing_pums change st state bigint",
                                   "alter table housing_pums change puma pumano bigint",

                                   "alter table housing_pums add column hhtype bigint",
                                   "alter table housing_pums add column hhldtype bigint",
                                   "alter table housing_pums add column hhldinc bigint",
                                   "alter table housing_pums add column hhldtenure bigint",
                                   "alter table housing_pums add column hhldsize bigint",
                                   "alter table housing_pums add column childpresence bigint",
                                   "alter table housing_pums add column groupquarter bigint",
                                   "alter table housing_pums add column hhldfam bigint",

                                   "update housing_pums set hhtype = 1 where unittype = 1",
                                   "update housing_pums set hhtype = 2 where unittype = 2 or unittype = 3",
                                   "update housing_pums set hhldtype = 1 where hht = 1",
                                   "update housing_pums set hhldtype = 2 where hht = 2",
                                   "update housing_pums set hhldtype = 3 where hht = 3",
                                   "update housing_pums set hhldtype = 4 where hht = 4 or hht = 6",
                                   "update housing_pums set hhldtype = 5 where hht = 5 or hht = 7",
                                   "update housing_pums set hhldtype = -99 where hht = 0",
                                   "update housing_pums set hhldinc = 1 where hinc <15000",
                                   "update housing_pums set hhldinc = 2 where hinc >= 15000 and hinc < 25000",
                                   "update housing_pums set hhldinc = 3 where hinc >= 25000 and hinc < 35000",
                                   "update housing_pums set hhldinc = 4 where hinc >= 35000 and hinc < 45000",
                                   "update housing_pums set hhldinc = 5 where hinc >= 45000 and hinc < 60000",
                                   "update housing_pums set hhldinc = 6 where hinc >= 60000 and hinc < 100000",
                                   "update housing_pums set hhldinc = 7 where hinc >= 100000 and hinc < 150000",
                                   "update housing_pums set hhldinc = 8 where hinc >= 150000",
                                   "update housing_pums set hhldinc = -99 where hht = 0",
                                   #"update housing_pums set hhldtenure = 1 where tenure = 1 or tenure = 2",
                                   #"update housing_pums set hhldtenure = 2 where tenure = 3 or tenure = 4",
                                   #"update housing_pums set hhldtenure = -99 where tenure = 0",
                                   "update housing_pums set hhldsize = persons where persons < 7",
                                   "update housing_pums set hhldsize = 7 where persons >= 7",
                                   "update housing_pums set hhldsize = -99 where hht = 0",
                                   "update housing_pums set childpresence = 1 where noc =1 or noc = 2 or noc = 3",
                                   "update housing_pums set childpresence = 2 where noc = 4",
                                   "update housing_pums set childpresence = -99 where hht = 0",
                                   "update housing_pums set groupquarter = 1 where unittype >1",
                                   "update housing_pums set groupquarter = -99 where unittype =1",

                                   "update housing_pums set hhldfam = 1 where hhldtype <=3",
                                   "update housing_pums set hhldfam = 2 where hhldtype > 3",

                                   "delete from housing_pums where persons = 0",
                                   "drop table serialcorr",
                                   "create table serialcorr select state, pumano, serialno from housing_pums group by serialno",
                                   "alter table serialcorr add column hhid bigint primary key auto_increment not null",
                                   "alter table serialcorr add index(serialno)",

                                   "drop table hhld_sample",
                                   "drop table gq_sample",

                                   "alter table housing_pums add index(serialno)",

                                   "create table housing_pums1 select housing_pums.*, hhid from housing_pums left join serialcorr using(serialno)",
                                   "update housing_pums1 set serialno = hhid",

                                   "create table hhld_sample select state, pumano, hhid, serialno, hhtype, hhldtype, hhldinc, hhldsize, childpresence, hhldfam from housing_pums1 where hhtype = 1",
                                   "create table gq_sample select state, pumano, hhid, serialno, hhtype, groupquarter from housing_pums1 where hhtype = 2",

                                   "alter table hhld_sample add index(serialno)",
                                   "alter table gq_sample add index(serialno)",
                                   "drop table housing_pums1"]

DEFAULT_SF2000_QUERIES = ["alter table %s add column agep1 bigint",
                          "alter table %s add column agep2 bigint",
                          "alter table %s add column agep3 bigint",
                          "alter table %s add column agep4 bigint",
                          "alter table %s add column agep5 bigint",
                          "alter table %s add column agep6 bigint",
                          "alter table %s add column agep7 bigint",
                          "alter table %s add column agep8 bigint",
                          "alter table %s add column agep9 bigint",
                          "alter table %s add column agep10 bigint",
                          "alter table %s add column gender1 bigint",
                          "alter table %s add column gender2 bigint",
                          "alter table %s add column race1 bigint",
                          "alter table %s add column race2 bigint",
                          "alter table %s add column race3 bigint",
                          "alter table %s add column race4 bigint",
                          "alter table %s add column race5 bigint",
                          "alter table %s add column race6 bigint",
                          "alter table %s add column race7 bigint",
                          "alter table %s add column employment1 bigint",
                          "alter table %s add column employment2 bigint",
                          "alter table %s add column employment3 bigint",
                          "alter table %s add column employment4 bigint",
                          "alter table %s add column childpresence1 bigint",
                          "alter table %s add column childpresence2 bigint",
                          "alter table %s add column groupquarter1 bigint",
                          "alter table %s add column groupquarter2 bigint",
                          "alter table %s add column hhldinc1 bigint",
                          "alter table %s add column hhldinc2 bigint",
                          "alter table %s add column hhldinc3 bigint",
                          "alter table %s add column hhldinc4 bigint",
                          "alter table %s add column hhldinc5 bigint",
                          "alter table %s add column hhldinc6 bigint",
                          "alter table %s add column hhldinc7 bigint",
                          "alter table %s add column hhldinc8 bigint",
                          "alter table %s add column hhldsize1 bigint",
                          "alter table %s add column hhldsize2 bigint",
                          "alter table %s add column hhldsize3 bigint",
                          "alter table %s add column hhldsize4 bigint",
                          "alter table %s add column hhldsize5 bigint",
                          "alter table %s add column hhldsize6 bigint",
                          "alter table %s add column hhldsize7 bigint",
                          "alter table %s add column hhldtype1 bigint",
                          "alter table %s add column hhldtype2 bigint",
                          "alter table %s add column hhldtype3 bigint",
                          "alter table %s add column hhldtype4 bigint",
                          "alter table %s add column hhldtype5 bigint",
                          "alter table %s add column hhldrage1 bigint",
                          "alter table %s add column hhldrage2 bigint",
                          "alter table %s add column hhldfam1 bigint",
                          "alter table %s add column hhldfam2 bigint",

                          "update %s set agep1 = (P008003+P008004+P008005+P008006+P008007) + (P008042+P008043+P008044+P008045+P008046)",
                          "update %s set agep2 = (P008008+P008009+P008010+P008011+P008012+P008013+P008014+P008015+P008016+P008017 ) + (P008047+P008048+P008049+P008050+P008051+P008052+P008053+P008054+P008055+P008056)",
                          "update %s set agep3 = (P008018+P008019+P008020+P008021+P008022+P008023+P008024+P008025 ) + (P008057+P008058+P008059+P008060+P008061+P008062+P008063+P008064)",
                          "update %s set agep4 = (P008026+P008027) + (P008065+P008066)",
                          "update %s set agep5 = (P008028+P008029) + (P008067+P008068)",
                          "update %s set agep6 = (P008030+P008031) + (P008069+P008070)",
                          "update %s set agep7 = (P008032+P008033+P008034) + (P008071+P008072+P008073)",
                          "update %s set agep8 = (P008035+P008036+P008037) + (P008074+P008075+P008076)",
                          "update %s set agep9 = (P008038+P008039) + (P008077+P008078)",
                          "update %s set agep10 = (P008040) + (P008079)",
                          "update %s set gender1 = P008002",
                          "update %s set gender2 = P008041",
                          "update %s set race1 = P006002",
                          "update %s set race2 = P006003",
                          "update %s set race3 = P006004",
                          "update %s set race4 = P006005",
                          "update %s set race5 = P006006",
                          "update %s set race6 = P006007",
                          "update %s set race7 = P006008",
                          "update %s set employment1 = agep1+agep2+P008018+P008057",
                          "update %s set employment2 = P043004+P043006+P043011+P043013",
                          "update %s set employment3 = P043007+P043014",
                          "update %s set employment4 = P043008+P043015",
                          "update %s set childpresence1 = P010008 + P010012 + P010015",
                          "update %s set childpresence2 = P010009 + P010013 + P010016 + P010017 + P010002",
                          "update %s set groupquarter1 = P009026",
                          "update %s set groupquarter2 = P009027",
                          "update %s set hhldinc1 = P052002 + P052003",
                          "update %s set hhldinc2 = P052004 + P052005",
                          "update %s set hhldinc3 = P052006 + P052007",
                          "update %s set hhldinc4 = P052008 + P052009",
                          "update %s set hhldinc5 = P052010 + P052011",
                          "update %s set hhldinc6 = P052012 + P052013",
                          "update %s set hhldinc7 = P052014 + P052015",
                          "update %s set hhldinc8 = P052016 + P052017",
                          "update %s set hhldsize1 = P014010 ",
                          "update %s set hhldsize2 = P014003+P014011 ",
                          "update %s set hhldsize3 = P014004+P014012 ",
                          "update %s set hhldsize4 = P014005+P014013 ",
                          "update %s set hhldsize5 = P014006+P014014 ",
                          "update %s set hhldsize6 = P014007+P014015 ",
                          "update %s set hhldsize7 = P014008+P014016 ",
                          "update %s set hhldtype1 = P010007",
                          "update %s set hhldtype2 = P010011 ",
                          "update %s set hhldtype3 = P010014",
                          "update %s set hhldtype4 = P010002",
                          "update %s set hhldtype5 = P010017",
                          "update %s set hhldrage1 = P012002",
                          "update %s set hhldrage2 = P012017",
                          "update %s set hhldfam1 = hhldtype1 + hhldtype2 + hhldtype3",
                          "update %s set hhldfam2 = hhldtype4 + hhldtype5",

                          "drop table hhld_marginals",
                          "drop table gq_marginals",
                          "drop table person_marginals",
                          """create table hhld_marginals select state, county, tract, bg, hhldinc1, hhldinc2, hhldinc3, hhldinc4, hhldinc5, hhldinc6, hhldinc7, hhldinc8,"""
                          """hhldsize1, hhldsize2, hhldsize3, hhldsize4, hhldsize5, hhldsize6, hhldsize7, hhldtype1, hhldtype2, hhldtype3, hhldtype4, hhldtype5,"""
                          """childpresence1, childpresence2, hhldrage1, hhldrage2, hhldfam1, hhldfam2 from %s""",
                          "create table gq_marginals select state, county, tract, bg, groupquarter1, groupquarter2 from %s",
                          """create table person_marginals select state, county, tract, bg, agep1, agep2, agep3, agep4, agep5, agep6, agep7, agep8, agep9, agep10,"""
                          """gender1, gender2, race1, race2, race3, race4, race5, race6, race7, employment1, employment2, employment3, employment4 from"""
                          """ %s"""]

DEFAULT_SFACS_QUERIES = ["alter table %s add column agep1 bigint",
                         "alter table %s add column agep2 bigint",
                         "alter table %s add column agep3 bigint",
                         "alter table %s add column agep4 bigint",
                         "alter table %s add column agep5 bigint",
                         "alter table %s add column agep6 bigint",
                         "alter table %s add column agep7 bigint",
                         "alter table %s add column agep8 bigint",
                         "alter table %s add column agep9 bigint",
                         "alter table %s add column agep10 bigint",
                         "alter table %s add column gender1 bigint",
                         "alter table %s add column gender2 bigint",
                         "alter table %s add column race1 bigint",
                         "alter table %s add column race2 bigint",
                         "alter table %s add column race3 bigint",
                         "alter table %s add column race4 bigint",
                         "alter table %s add column race5 bigint",
                         "alter table %s add column race6 bigint",
                         "alter table %s add column race7 bigint",
                         "alter table %s add column race11 bigint",
                         "alter table %s add column race12 bigint",
                         "alter table %s add column race13 bigint",
                         "alter table %s add column race14 bigint",
                         "alter table %s add column race15 bigint",
                         "alter table %s add column race16 bigint",
                         "alter table %s add column race17 bigint",
                         "alter table %s add column race21 bigint",
                         "alter table %s add column race22 bigint",
                         "alter table %s add column race23 bigint",
                         "alter table %s add column race24 bigint",
                         "alter table %s add column race25 bigint",
                         "alter table %s add column race26 bigint",
                         "alter table %s add column race27 bigint",
                         "alter table %s add column employment1 bigint",
                         "alter table %s add column employment2 bigint",
                         "alter table %s add column employment3 bigint",
                         "alter table %s add column employment4 bigint",
                         "alter table %s add column childpresence1 bigint",
                         "alter table %s add column childpresence2 bigint",
                         "alter table %s add column groupquarter1 bigint",
                         "alter table %s add column hhldinc1 bigint",
                         "alter table %s add column hhldinc2 bigint",
                         "alter table %s add column hhldinc3 bigint",
                         "alter table %s add column hhldinc4 bigint",
                         "alter table %s add column hhldinc5 bigint",
                         "alter table %s add column hhldinc6 bigint",
                         "alter table %s add column hhldinc7 bigint",
                         "alter table %s add column hhldinc8 bigint",
                         "alter table %s add column hhldsize1 bigint",
                         "alter table %s add column hhldsize2 bigint",
                         "alter table %s add column hhldsize3 bigint",
                         "alter table %s add column hhldsize4 bigint",
                         "alter table %s add column hhldsize5 bigint",
                         "alter table %s add column hhldsize6 bigint",
                         "alter table %s add column hhldsize7 bigint",
                         "alter table %s add column hhldtype1 bigint",
                         "alter table %s add column hhldtype2 bigint",
                         "alter table %s add column hhldtype3 bigint",
                         "alter table %s add column hhldtype4 bigint",
                         "alter table %s add column hhldtype5 bigint",
                         "alter table %s add column hhldrage1 bigint",
                         "alter table %s add column hhldrage2 bigint",
                         "alter table %s add column hhldfam1 bigint",
                         "alter table %s add column hhldfam2 bigint",

                         "alter table %s add column check_gender bigint",
                         "alter table %s add column check_age bigint",
                         "alter table %s add column check_race bigint",
                         "alter table %s add column check_race1 bigint",
                         "alter table %s add column check_race2 bigint",
                         "alter table %s add column check_employment bigint",

                         "alter table %s add column check_type bigint",
                         "alter table %s add column check_size bigint",
                         "alter table %s add column check_fam bigint",
                         "alter table %s add column check_hhldrage bigint",
                         "alter table %s add column check_inc bigint",
                         "alter table %s add column check_child bigint",

                         "update %s set agep1 = (B01001000003)+(B01001000027)",
                         "update %s set agep2 = (B01001000004+B01001000005) + (B01001000028+B01001000029)",
                         "update %s set agep3 = (B01001000006+B01001000007+B01001000008+B01001000009+B01001000010) + (B01001000030+B01001000031+B01001000032+B01001000033+B01001000034)",
                         "update %s set agep4 = (B01001000011+B01001000012) + (B01001000035+B01001000036)",
                         "update %s set agep5 = (B01001000013+B01001000014) + (B01001000037+B01001000038)",
                         "update %s set agep6 = (B01001000015+B01001000016) + (B01001000039+B01001000040)",
                         "update %s set agep7 = (B01001000017+B01001000018+B01001000019) + (B01001000041+B01001000042+B01001000043)",
                         "update %s set agep8 = (B01001000020+B01001000021+B01001000022) + (B01001000044+B01001000045+B01001000046)",
                         "update %s set agep9 = (B01001000023+B01001000024) + (B01001000047+B01001000048)",
                         "update %s set agep10 = (B01001000025) + (B01001000049)",
                         "update %s set gender1 = B01001000002",
                         "update %s set gender2 = B01001000026",
                         "update %s set race1 = B02001000002",
                         "update %s set race2 = B02001000003",
                         "update %s set race3 = B02001000004",
                         "update %s set race4 = B02001000005",
                         "update %s set race5 = B02001000006",
                         "update %s set race6 = B02001000007",
                         "update %s set race7 = B02001000009+B02001000010",

                         "update %s set race11 = C01001A00001",
                         "update %s set race12 = C01001B00001",
                         "update %s set race13 = C01001C00001",
                         "update %s set race14 = C01001D00001",
                         "update %s set race15 = C01001E00001",
                         "update %s set race16 = C01001F00001",
                         "update %s set race17 = C01001G00001",

                         "update %s set race21 = B01001A00001",
                         "update %s set race22 = B01001B00001",
                         "update %s set race23 = B01001C00001",
                         "update %s set race24 = B01001D00001",
                         "update %s set race25 = B01001E00001",
                         "update %s set race26 = B01001F00001",
                         "update %s set race27 = B01001G00001",

                         """update %s set employment2 = (B23001000005 + B23001000007) + (B23001000012 + B23001000014) + """
                         """(B23001000019 + B23001000021) + (B23001000026 + B23001000028) + (B23001000033 + B23001000035) + """
                         """(B23001000040 + B23001000042) + (B23001000047 + B23001000049) + (B23001000054 + B23001000056) + """
                         """(B23001000061 + B23001000063) + (B23001000068 + B23001000070) + (B23001000075 + B23001000080 + B23001000085) + """
                         """(B23001000091 + B23001000093) + (B23001000098 + B23001000100) + """
                         """(B23001000105 + B23001000107) + (B23001000112 + B23001000114) + (B23001000119 + B23001000121) + """
                         """(B23001000126 + B23001000128) + (B23001000133 + B23001000135) + (B23001000140 + B23001000142) + """
                         """(B23001000147 + B23001000149) + (B23001000154 + B23001000156) + (B23001000161 + B23001000166 + B23001000171)""",

                         """update %s set employment3 = (B23001000008 + B23001000015 + B23001000022 + """
                         """B23001000029 + B23001000036 + B23001000043 + B23001000050 + B23001000057 + B23001000064 +"""
                         """B23001000071 + B23001000076 + B23001000081 + B23001000086 + B23001000094 + B23001000101 +"""
                         """B23001000108 + B23001000115 + B23001000122 + B23001000129 + B23001000136 + B23001000143 +"""
                         """B23001000150 + B23001000157 + B23001000162 + B23001000167 + B23001000172) """,

                         """update %s set employment4 = (B23001000009 + B23001000016 + B23001000023 + """
                         """B23001000030 + B23001000037 + B23001000044 + B23001000051 + B23001000058 + B23001000065 +"""
                         """B23001000072 + B23001000077 + B23001000082 + B23001000087 + B23001000095 + B23001000102 +"""
                         """B23001000109 + B23001000116 + B23001000123 + B23001000130 + B23001000137 + B23001000144 +"""
                         """B23001000151 + B23001000158 + B23001000163 + B23001000168 + B23001000173) """,

                         "update %s set employment1 = gender1 + gender2 - employment2 - employment3 - employment4",

                         "update %s set groupquarter1 = B26001000001",
                         "update %s set hhldinc1 = B19001000002 + B19001000003",
                         "update %s set hhldinc2 = B19001000004 + B19001000005",
                         "update %s set hhldinc3 = B19001000006 + B19001000007",
                         "update %s set hhldinc4 = B19001000008 + B19001000009",
                         "update %s set hhldinc5 = B19001000010 + B19001000011",
                         "update %s set hhldinc6 = B19001000012 + B19001000013",
                         "update %s set hhldinc7 = B19001000014 + B19001000015",
                         "update %s set hhldinc8 = B19001000016 + B19001000017",
                         "update %s set hhldsize1 = B25009000003+B25009000011",
                         "update %s set hhldsize2 = B25009000004+B25009000012",
                         "update %s set hhldsize3 = B25009000005+B25009000013",
                         "update %s set hhldsize4 = B25009000006+B25009000014",
                         "update %s set hhldsize5 = B25009000007+B25009000015",
                         "update %s set hhldsize6 = B25009000008+B25009000016",
                         "update %s set hhldsize7 = B25009000009+B25009000017",
                         "update %s set hhldtype1 = B11001000003",
                         "update %s set hhldtype2 = B11001000005",
                         "update %s set hhldtype3 = B11001000006",
                         "update %s set hhldtype4 = B11001000008",
                         "update %s set hhldtype5 = B11001000009",
                         """update %s set hhldrage1 = (B25007000003+B25007000004+B25007000005+B25007000006+B25007000007+B25007000008)+"""
                         """(B25007000013+B25007000014+B25007000015+B25007000016+B25007000017+B25007000018)""",
                         "update %s set hhldrage2 = (B25007000009+ B25007000010+B25007000011)+(B25007000019+ B25007000020+B25007000021)",
                         "update %s set hhldfam1 = hhldtype1 + hhldtype2 + hhldtype3",
                         "update %s set hhldfam2 = hhldtype4 + hhldtype5",
                         "update %s set childpresence1 = C23007000002",
                         "update %s set childpresence2 = C23007000017 + hhldtype4 + hhldtype5",

                         "update %s set check_gender = gender1 + gender2",
                         "update %s set check_age = agep1+agep2+agep3+agep4+agep5+agep6+agep7+agep8+agep9+agep10",
                         "update %s set check_race = race1+race2+race3+race4+race5+race6+race7",
                         "update %s set check_race1 = race11+race12+race13+race14+race15+race16+race17",
                         "update %s set check_race2 = race21+race22+race23+race24+race25+race26+race27",
                         "update %s set check_employment = employment1 + employment2 + employment3 + employment4",

                         "update %s set check_type = hhldtype1+hhldtype2+hhldtype3+hhldtype4+hhldtype5",
                         "update %s set check_size = hhldsize1+hhldsize2+hhldsize3+hhldsize4+hhldsize5+hhldsize6+hhldsize7",
                         "update %s set check_hhldrage = hhldrage1+hhldrage2",
                         "update %s set check_inc = hhldinc1+hhldinc2+hhldinc3+hhldinc4+hhldinc5+hhldinc6+hhldinc7+hhldinc8",
                         "update %s set check_fam = hhldfam1+hhldfam2",
                         "update %s set check_child = childpresence1+childpresence2",

                         "drop table hhld_marginals",
                         "drop table gq_marginals",
                         "drop table person_marginals",
                         """create table hhld_marginals select state, county, tract, bg, hhldinc1, hhldinc2, hhldinc3, hhldinc4, hhldinc5, hhldinc6, hhldinc7, hhldinc8,"""
                         """hhldsize1, hhldsize2, hhldsize3, hhldsize4, hhldsize5, hhldsize6, hhldsize7, hhldtype1, hhldtype2, hhldtype3, hhldtype4, hhldtype5,"""
                         """childpresence1, childpresence2, hhldrage1, hhldrage2, hhldfam1, hhldfam2 from %s""",
                         "create table gq_marginals select state, county, tract, bg, groupquarter1 from %s",
                         """create table person_marginals select state, county, tract, bg, agep1, agep2, agep3, agep4, agep5, agep6, agep7, agep8, agep9, agep10,"""
                         """gender1, gender2, race1, race2, race3, race4, race5, race6, race7 from %s"""]


import rooms
import asyncio
from asgiref.sync import async_to_sync
import json as encoder

class WebsocketFireClass():
    @async_to_sync
    async def new_chat_message(self, state):
        encoded_state = encoder.dumps({'type': 'new_chat_message', 'data': state})
        print("NEW CHAT MESSAGE, START FIRING...")
        if rooms.chat:
            await asyncio.wait([connection.send(encoded_state) for connection in rooms.chat])

    @async_to_sync
    async def new_chat_message2(self, state):
        await asyncio.sleep(2)


def run():
    mi_diccionario = {
        "llave1": 1,
        "llave2": 2,
        "llave3": 3,
    }
    # print(mi_diccionario["llave1"])
    # print(mi_diccionario["llave2"])
    # print(mi_diccionario["llave3"])

    poblacion_paises = {
        "Argentina" : 40234658,
        "Brasil" : 70548621,
        "Chile" : 526351485,
    }
    # print(poblacion_paises["Chile"])

    print("Imprimo las llaves")
    for pais in poblacion_paises.keys():
        print(pais)

    print("Imprimo los valosres de las llaves")
    for pais in poblacion_paises.values():
        print(pais)

    print("Imprimimos las llaves y valores")
    for pais, poblacion in poblacion_paises.items(): #lleva dos variables para almacenar las llaves y los valores
        print(pais + " tiene " + str(poblacion)+ " habitantes")

    longitud = len(mi_diccionario)
    print(longitud)

if __name__ == "__main__":
    run()


from rest_framework.permissions import BasePermission

from noticeboard.utils.notices import (
    user_allowed_banners,
    has_super_upload_right,
)

class IsUploader(BasePermission):
    """
    A custom Django REST permission layer to check authorization
    over different actions on notices.
    """

    def has_permission(self, request, view, **kwargs):
        """
        Primary permission for notices.
        :param request: Django request object
        :param view:
        :param kwargs: keyword arguments
        :return: boolean expression of permission
        """

        if request.method == 'GET' or request.method == 'DELETE':
            return True

        person = request.person
        data = request.data

        try:
            banner_id = data['banner']
        except KeyError:
            return False

        allowed_banner_ids = user_allowed_banners(person)
        if banner_id in allowed_banner_ids:
            if data.get('is_important', False):
                return has_super_upload_right(person, banner_id)
            else:
                return True
        else:
            return False

    def has_object_permission(self, request, view, obj, **kwargs):
        """
        Object level permission for notices.
        :param request: Django request object
        :param view:
        :param obj: instance of the model
        :param kwargs: keyword arguments
        :return: boolean expression of permission
        """
        if request.method == 'GET':
            return True

        return obj.uploader.id == request.person.id


# Configuration file for the Sphinx documentation builder.
#
# For the full list of built-in configuration values, see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html

# -- Project information -----------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
import os
import subprocess
import sys

import pygit2

sys.path.insert(0, os.path.abspath('../..'))

project = 'tensorrt_llm'
copyright = '2023, NVidia'
author = 'NVidia'
branch_name = pygit2.Repository('.').head.shorthand

# -- General configuration ---------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration

templates_path = ['_templates']
exclude_patterns = []

extensions = [
    'sphinx.ext.duration',
    'sphinx.ext.autodoc',
    'sphinx.ext.autosummary',
    'sphinx.ext.viewcode',
    'sphinx.ext.napoleon',
    'myst_parser',  # for markdown support
    "breathe",
    'sphinx.ext.todo',
]

myst_url_schemes = {
    "http":
    None,
    "https":
    None,
    "source":
    "https://github.com/NVIDIA/TensorRT-LLM/tree/" + branch_name + "/{{path}}",
}

autosummary_generate = True

# -- Options for HTML output -------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output

source_suffix = {
    '.rst': 'restructuredtext',
    '.txt': 'markdown',
    '.md': 'markdown',
}

html_theme = 'sphinx_rtd_theme'
html_static_path = ['_static']

# ------------------------  C++ Doc related  --------------------------
# Breathe configuration
breathe_default_project = "TensorRT-LLM"
breathe_projects = {"TensorRT-LLM": "../cpp_docs/xml"}

SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__))

CPP_INCLUDE_DIR = os.path.join(SCRIPT_DIR, '../../cpp/include/tensorrt_llm')
CPP_GEN_DIR = os.path.join(SCRIPT_DIR, '_cpp_gen')
print('CPP_INCLUDE_DIR', CPP_INCLUDE_DIR)
print('CPP_GEN_DIR', CPP_GEN_DIR)

def gen_cpp_doc(ofile_name: str, header_dir: str, summary: str):
    cpp_header_files = [
        file for file in os.listdir(header_dir) if file.endswith('.h')
    ]

    with open(ofile_name, 'w') as ofile:
        ofile.write(summary + "\n")
        for header in cpp_header_files:
            ofile.write(f"{header}\n")
            ofile.write("_" * len(header) + "\n\n")

            ofile.write(f".. doxygenfile:: {header}\n")
            ofile.write("   :project: TensorRT-LLM\n\n")

runtime_summary = f"""
Runtime
==========

.. Here are files in the cpp/include/runtime
.. We manually add subsection to enable detailed description in the future
.. It is also doable to automatically generate this file and list all the modules in the conf.py
    """.strip()

subprocess.run(['mkdir', '-p', CPP_GEN_DIR])
gen_cpp_doc(CPP_GEN_DIR + '/runtime.rst', CPP_INCLUDE_DIR + '/runtime',
            runtime_summary)


def hanoi(n, src, via, dst) :
  global cnt
  if n == 1 :
    cnt += 1
    # print(f"{src} -> {dst}")
  else :
    hanoi(n - 1, src, dst, via)
    hanoi(1, src, via, dst)
    hanoi(n - 1, via, src, dst)

N = int(input())
cnt = 0
hanoi(N, "A", "B", "C")
print(cnt)


from telegram import Bot, Update, ParseMode
from telegram.ext import run_async
import time
from bot.modules.helper_funcs.extraction import extract_user
from bot import dispatcher
from bot.modules.disable import DisableAbleCommandHandler

@run_async
def gdpr(bot: Bot, update: Update):
        message = update.effective_message
        chat = update.effective_chat
        user = update.effective_user
        if chat.type == 'private':
                message.reply_text("Deleting identifiable data...")
                time.sleep(2)
                message.reply_text("Almost done, Just be Patient")
                time.sleep(2)
                message.reply_text("My Ass! do not come here AGAIN. If you are gbanned this cmd will not revert it. So kindly GTFO.")
                message.reply_text("Pajeet confirm")

GDPR_HANDLER = DisableAbleCommandHandler("gdpr", gdpr)
dispatcher.add_handler(GDPR_HANDLER)


import collections
class Solution:
    def removeStones(self, stones: List[List[int]]) -> int:

        stones = list(map(tuple, stones))

        s = set(stones)
        dx = collections.defaultdict(set)
        dy = collections.defaultdict(set)

        for i,j in s:
            dx[i].add(j)
            dy[j].add(i)

        def dfs(i, j):
            for nextY in dx[i]:
                if (i, nextY) in s:
                    s.remove((i, nextY))
                    dfs(i, nextY)

            for nextX in dy[j]:
                if (nextX, j) in s:
                    s.remove((nextX, j))
                    dfs(nextX, j)

        island = 0

        for x, y in stones:
            if (x, y) not in s:
                continue
            island += 1
            dfs(x, y)

        return len(stones) - island


'''
Created on 15-Oct-2013

@author: Kashaj
'''
import re, sqlite3,os
db = sqlite3.connect('Train_Database.db')
db.text_factory = str
db.row_factory = sqlite3.Row
db.execute('drop table if exists TrainStationNode')

db.execute('create table TrainStationNode(Train_Num char[6],stn_code char[6],route int,arr_time text,dep_time text)')

def main():
    tr_num = open('List_Of_All_Train_Nums.txt','r')

    for num in tr_num:

        num = str(num)
        num = num.replace("\xa0","");
        num = num.replace("\n","");
        num = num.strip(' ')
        num = num.strip('\n')

        hread(num)
        tuples = hwork()
        hdatab(num,tuples)

    getData()
    db.commit()

def hread(filename):
    save_path = r'C:/Users/kashaj/Desktop/proj/data/schedule/'
    filename += '.html'
    completeName = os.path.join(save_path, filename)

    f = open(completeName,'r')
    text = f.read()
    text = text.strip('\n')
    f2 = open('loolws.txt','w')
    f2.write(text)
    f2.close()

def hwork():
    f = open('loolws.txt','r')
    text = f.read()
    tuples = re.findall(r'
\n\d+	\n(\w+\s*)	\n\w+.*	\n(\d)+	\n(.+)	\n(.+)	\n.*	\n\d+	\n\d+	',text,re.IGNORECASE)
    f.close()
    return(tuples)

def hdatab(num,tuples):
    for i in range(0,len(tuples)):
        if(i==0):
            db.execute('insert into TrainStationNode(Train_Num,stn_code,route,arr_time,dep_time) values (?,?,?,?,?)',(num,tuples[i][0],tuples[i][1],(tuples[i][2]).replace('', ''),(tuples[i][3])))
        elif(i == (len(tuples)-1)):
            db.execute('insert into TrainStationNode(Train_Num,stn_code,route,arr_time,dep_time) values (?,?,?,?,?)',(num,tuples[i][0],tuples[i][1],tuples[i][2],(tuples[i][3]).replace('', '')))

        else:
            db.execute('insert into TrainStationNode(Train_Num,stn_code,route,arr_time,dep_time) values (?,?,?,?,?)',(num,tuples[i][0],tuples[i][1],tuples[i][2],(tuples[i][3]).replace('', '')))

def getData():
    cursor = db.execute('Select Train_Num,stn_code,route,arr_time,dep_time from TrainStationNode')
    for row in cursor:
        print(row['Train_Num'],row['stn_code'],row['route'],row['arr_time'],row['dep_time'])

if __name__ == '__main__':
    main()


from loja.models import Produto
from loja.models import Pedido
from loja.models import CATEGORIAS
from rest_framework import serializers

class ProdutoSerializer(serializers.ModelSerializer):

    class Meta:
        model = Produto
        fields = (
            'id',
            'nome',
            'descricao',
            'valor',
            'categoria'
        )

class PedidoSerializer(serializers.ModelSerializer):

    valor_total = serializers.SerializerMethodField()

    class Meta:
        model = Pedido
        fields = (
            'id',
            'produtos',
            'cliente',
            'status',
            'data_realizacao',
            'valor_total',
        )

    def get_valor_total(self, obj):
        return obj.get_valor_total()

    def validate_produtos(self, attrs):
        msg = 'É necessesario escolher no minimo um produto de cada categoria'

        produtos = attrs
        if len(produtos) < len(CATEGORIAS):
            raise serializers.ValidationError(msg)

        categorias_index = list(dict(CATEGORIAS))
        for p in produtos:
            if not p.categoria in categorias_index:
                raise serializers.ValidationError(msg)

        return attrs

    def validate(self, attrs):
        return attrs


import os				#to access files
from PIL import Image			#to open JPEGs
import numpy as np

#-------------------------------Custom   INCLUDES-------------------------------

import lookupTables as lT

#-------------------------------Function DEFINITIONS----------------------------

def fittingEstimator(inDir, file_name, EV_calc_local, EV_calc_global, LUT):

	EV_calc_local[:]	= [0.0]	#list of statistics
	EV_calc_global[:]	= []

	#lattice parameter
	R=10

	#-------Opening image1
	#separate core of name, append jpg extension, open, BW
	name	= (file_name[0].split(".")[0] + ".jpg")
	img1 	= Image.open("./"+inDir+"/"+name)
	img1	= np.array( img1.convert("L") )

	#dimensions of image
	N,M	= img1.shape

	#fill the first plot list
	cntr	= -1
	x1	= np.array( [0.0]*(len(range(0,N,R))*len(range(0,M,R))) )
	x2	= np.array( [0.0]*(len(range(0,N,R))*len(range(0,M,R))) )
	for i in range(0,N,R):
		for j in range(0,M,R):
			cntr	+= 1
			x1[cntr]	= LUT( img1[i,j] )

	for name in file_name[1:]:
	#-------Opening image 2
		#separate core of name, append jpg extension, open, BW
		name	= (name.split(".")[0] + ".jpg")
		img2 	= Image.open("./"+inDir+"/"+name)
		img2	= np.array( img2.convert('L') )

		cntr	= -1

		for i in range(0,N,R):
			for j in range(0,M,R):

				cntr	+= 1
				x2[cntr]	= LUT( img2[i,j] )

		#now compare x1  and x2
		#fitting x+b is equivalent to calculating
		#print(np.average( x1-x2 ))

		xx1	= []
		xx2	= []

		for (x,y) in zip(x1,x2):
			if x>=1 and x<=7 and y>=1 and y<=7:
				xx1.append(x)
				xx2.append(y)
		if len(xx1) == 0 or len(xx2) == 0:
			print("WARNING!!")
			print(x2)
		EV_calc_local.append( np.average( np.array(xx2)-np.array(xx1) ) + EV_calc_local[-1] )

		#import matplotlib.pyplot as plt
		#plt.figure(1)
		#plt.plot(x1,x2,"x",xx1,xx2,"o")
		#plt.show()

		#change images
		img1[:]	= img2[:]
		x1[:]	= x2[:]
	EV_calc_global[:]	= EV_calc_local[:]


import os
import shutil
from fastapi import UploadFile

# UPLOAD_DIR = "model_upload_dir"

def upload_file(upload_dirname: str, file: UploadFile, filename: str):
    if file and filename:
        fileobj = file.file
        target_path = os.path.join(upload_dirname, filename)
        target_dir = os.path.dirname(target_path)
        os.makedirs(target_dir, exist_ok=True)
        upload_dir = open(target_path, "wb+")
        shutil.copyfileobj(fileobj, upload_dir)
        upload_dir.close()

        return {"status": "OK", "msg": f"uploaded files {filename} "}
    return {"status": "ERROR", "msg": "uploaded file is not found."}

def concat_file_chunks(
    upload_dirname: str, filename: str, chunkNum: int, dest_dirname: str
):
    target_path = os.path.join(upload_dirname, filename)
    target_dir = os.path.dirname(target_path)
    os.makedirs(target_dir, exist_ok=True)
    if os.path.exists(target_path):
        os.remove(target_path)
    with open(target_path, "ab") as out:
        for i in range(chunkNum):
            chunkName = f"{filename}_{i}"
            chunk_file_path = os.path.join(upload_dirname, chunkName)
            stored_chunk_file = open(chunk_file_path, "rb")
            out.write(stored_chunk_file.read())
            stored_chunk_file.close()
            os.remove(chunk_file_path)
        out.close()
    return {"status": "OK", "msg": f"concat files {out} "}


import requests
import csv
from bs4 import BeautifulSoup
import json
from collections import namedtuple
from typing import List, Dict

TOPICS_NUMBER = 6
LEVELS_NUMBER = 5
MIN_LEVEL_CONTEST_ID = "030813"
MAX_LEVEL_CONTEST_ID = "030817"
TABLE_URL = ("https://ejudge.lksh.ru/standings/dk/stand.php"
             "?from={}&to={}".format(MIN_LEVEL_CONTEST_ID,
                                     MAX_LEVEL_CONTEST_ID))

Student = namedtuple('Student', 'group, last_name, first_name, ejid')

def get_table(table_url) -> BeautifulSoup:
    """Fetches results table from ejudge, returns soup"""
    response = requests.get(table_url)
    soup = BeautifulSoup(response.text, "lxml")
    table = soup.select_one("table")
    return table

def parse_results(table_soup: BeautifulSoup) -> Dict[Student, List[int]]:
    """Returns dict like {Student: [1 if problem is solved else 0]}"""
    result = {}
    rows = [row for row in table_soup.select("tr") if row.has_attr("ejid")]
    for row in rows:
        [group, last_name, first_name], ejid = row.select_one("nobr").contents[
            0].split(), int(row['ejid'])

        problem_tags = [td for td in row.findAll("td") if td.has_attr("title")]
        solved = [1 if tag["class"] == ["ac"] else 0 for tag in problem_tags]
        result[Student(group, last_name, first_name, ejid)] = solved

    return result

def last_occurrence(list_, elem):
    return len(list_) - 1 - list_[::-1].index(elem)

def calculate_mark(solved: List[int]) -> int:
    """Calculates mark from a list of solved"""
    levels = set()
    max_levels = []
    for topic in range(TOPICS_NUMBER):
        solved_from_topic = solved[topic::TOPICS_NUMBER]
        if any(solved_from_topic):
            max_level = last_occurrence(solved_from_topic, 1)
            max_levels.append(max_level)

    max_levels.sort(reverse=True)
    for level in max_levels:
        while level in levels and level != 0:
            level -= 1
        levels.add(level)

    return min(len(levels), len(max_levels))

def get_table_to_render(parsed_table: Dict[Student, List[int]]) -> list:
    return sorted([(*student, calculate_mark(solved))
                   for student, solved in parsed_table.items()])

def get_table_json(parsed_table: Dict[Student, List[int]]) -> str:
    return json.dumps([{
                           'first_name': student.first_name,
                           'last_name': student.last_name,
                           'group': student.group,
                           'score': calculate_mark(solved),
                           'ejid': student.ejid
                       } for student, solved in parsed_table.items()],
                      ensure_ascii=False)

def get_personal_json(parsed_table: Dict[Student, List[int]], ejid: int) -> str:
    filtered_student = [(student, solved)
                        for student, solved in parsed_table.items()
                        if student.ejid == ejid]

    if filtered_student:
        student, solved = filtered_student[0]
        return json.dumps({'first_ name': student.first_name,
                           'last_name': student.last_name,
                           'group': student.group,
                           'score': calculate_mark(solved),
                           'solved': solved,
                           'ejid': student.ejid},
                          ensure_ascii=False)
    else:
        return json.dumps({'error': 'ID не найден'}, ensure_ascii=False)

if __name__ == '__main__':
    results_table = get_table(TABLE_URL)
    parsed_table = parse_results(results_table)
    table = get_table_to_render(parsed_table)
    with open("results.csv", "w", encoding="utf-8") as file:
        csv_writer = csv.writer(file)
        csv_writer.writerows(table)


"""Handles the creating of obstacles within the game instance."""
import pygame
from src.scripts.coordinate import Coordinate

class Obstacle:
    """Class for handling the creating of obstables."""
    def __init__(self) -> None:
        self.size = (50, 300)
        self.position = [
            Coordinate(700, 400),
            Coordinate(700, 0)
        ]
        self.can_move = True

    def get_rect(self) -> tuple[pygame.Rect, pygame.Rect]:
        """Get rect"""
        return (
            pygame.Rect(
                tuple(self.position[0])[0], tuple(self.position[0])[1], self.size[0], self.size[1]
            ), # bottom rect
            pygame.Rect(
                tuple(self.position[1])[0], tuple(self.position[1])[1], self.size[0], self.size[1]
            )  # top rect
        )

    def move(self) -> None:
        """Move the obstace foward."""
        if self.position[0].x < 45:
            self.can_move = False
        self.position[0].x -= 3
        self.position[1].x -= 3