"""
Defined here are ORM Miner models using
SQLAlchemy.
"""

import contextlib, enum, typing

from sqlalchemy import (
    create_engine,
    delete,
    insert,
    select,
    update,
    func,
    Delete,
    Engine,
    Insert,
    Select,
    Update)
from sqlalchemy import (
    Boolean,
    Enum,
    ForeignKey,
    Integer,
    Sequence,
    String,
    Table,
    TypeDecorator)
from sqlalchemy.orm import (
    declared_attr,
    mapped_column,
    relationship,
    DeclarativeBase,
    Mapped,
    Session)

from minerdb.error import RecordExists, RecordNotFound

Tt         = typing.TypeVar("Tt")
Ps         = typing.ParamSpec("Ps")
MDt        = typing.TypeVar("MDt", bound="MinerDB")
MMt        = typing.TypeVar("MMt", bound="MinerModelV1")
StmtT      = typing.TypeVar("StmtT", Select, Update, Insert, Delete)
DRCallable = typing.Callable[Ps, "DataResponse[MMt]"]

OperationMap = {
    "==": "__eq__",
    ">=": "__ge__",
    "<=": "__le__",
    ">":  "__gt__",
    "<":  "__lt__"
}

def data_drop(count: typing.Optional[int] = None) -> "DataResponse":
    """Create a data response for DROP call."""

    dr = data_new(count, status=DataStatus.DROPPED)
    dr.pop("result")
    return dr

def data_find(
    count: typing.Optional[int] = None,
    result: typing.Optional[typing.Iterable] = None) -> "DataResponse":
    """Create a data response for a FIND call."""

    status = DataStatus.FOUND if count else DataStatus.FOUND_NONE
    dr     = data_new(count, result, status)
    return dr

def data_push(count: typing.Optional[int] = None) -> "DataResponse":
    """Create a data response for a PUSH call."""

    status = DataStatus.UPDATED if count else DataStatus.CREATED
    dr     = data_new(count, status=status)
    dr.pop("result")
    return dr

def data_new(
    count: typing.Optional[int] = None,
    result: typing.Optional[typing.Iterable] = None,
    status: typing.Optional["DataStatus"] = None) -> "DataResponse":
    """Create a data response."""

    count  = count or 0
    result = result or iter(())
    status = status or DataStatus.OK

    return DataResponse(count=count, result=result, status=status)

def resource_repr(
    resource: "MinerModelV1",
    fields: dict[str, typing.Any]) -> str:
    """
    Create a string representation of a database
    record.
    """

    name   = resource.__class__.__qualname__
    fnames = ", ".join((f"{k}={v!r}" for k,v in fields.items()))
    return f"{name}(" + fnames + ")"

def version_compare(
    stmt: StmtT,
    model: "HasVersionOrders",
    version: str) -> StmtT:
    """
    Returms a modified version of the original
    statement to include a version comparison.
    """

    op, vers = "__eq__", version
    if vers[:2] in ("==", ">=", "<="):
        op, vers = OperationMap[vers[:2]], vers[2:]
    elif version[:1] in (">", "<"):
        op, vers = OperationMap[vers[:1]], vers[1:]

    parts  = version_parse_str(vers)
    orders = (model.major, model.minor, model.patch)
    for order, part in zip(orders, parts):
        cmp = order.__ge__
        if part >= 0:
            cmp = getattr(order, op)
        stmt = stmt.where(cmp(part))

    return stmt

def validate_pre_update(
    model: MMt,
    func: DRCallable[MMt], #type: ignore
    **kwds) -> "DataResponse[MMt]":
    """
    Check results to ensure an update call will
    not interfere with data integrity.
    """

    found  = func(**kwds)
    count  = found["count"]

    found["result"] = tuple(found["result"])
    if count > 1:
        raise RecordExists("Found too many records.")
    if count > 0 and found["result"][0] == model:
        raise RecordExists("Record exists.")

    return found

def version_parse_str(version: str) -> tuple[int, int, int]:
    """
    Parse a a version string into a 3 integer
    tuple.
    """

    parts = list(map(int, version.split(".", maxsplit=3)))
    ret   = [-1, -1, -1]
    for idx, part in enumerate(parts):
        ret[idx] = part
    return tuple(ret)

class ServiceAPI(enum.StrEnum):
    """Type of service API."""

    Bukkit   = enum.auto()
    Paper    = enum.auto()
    Spigot   = enum.auto()
    Velocity = enum.auto()

class ResourceKind(enum.StrEnum):
    """Type of purpose the resource serves."""

    Plugin    = enum.auto()
    PluginAPI = enum.auto()
    Proxy     = enum.auto()
    Server    = enum.auto()

class DataResponse(typing.TypedDict, typing.Generic[Tt]):
    """Data response from database lookup."""

    count:  int
    result: typing.Iterator[Tt]
    status: "DataStatus"

class DataStatus(enum.StrEnum):
    OK         = enum.auto()
    FOUND      = enum.auto()
    FOUND_NONE = enum.auto()
    CREATED    = enum.auto()
    DROPPED    = enum.auto()
    UPDATED    = enum.auto()

class MinerModelV1(DeclarativeBase):
    """
    Some object used in the search and
    procurement of Minecraft server resources.
    """

    __abstract__ = True

    @declared_attr
    def __tablename__(self):
        return "_".join(["mdb", self.__tablename__])

class HasVersionOrders(MinerModelV1):
    """
    Model abstract that has version information.
    """

    __abstract__ = True

    major: Mapped[int] = mapped_column(Integer(), default=0)
    minor: Mapped[int] = mapped_column(Integer(), default=0)
    patch: Mapped[int] = mapped_column(Integer(), default=0)

class Alias(MinerModelV1):
    """
    Name used in place of retrieveable from host.
    """

    __tablename__ = "aliases"

    id: Mapped[int] = mapped_column(Integer(), primary_key=True)
    resource: Mapped[int] = mapped_column(
        ForeignKey("resources.id"),
        primary_key=True)
    name: Mapped[str] = mapped_column(String(64), primary_key=True)

    # Relationships
    resources: Mapped["Resource"] = relationship(
        back_populates="aliases")

    def __repr__(self):
        return resource_repr(
            self,
            dict(name=self.name, resource=self.resource))

class Host(MinerModelV1):
    """Available hosts for aquiring resources."""

    __tablename__ = "hosts"

    id:   Mapped[int] = mapped_column(Integer(), primary_key=True)
    name: Mapped[str] = mapped_column(String(64))
    host: Mapped[str] = mapped_column(String(128))

    # Relationships
    resource_hosts: Mapped[list["ResourceByHost"]] = relationship(
        back_populates="hosts",
        cascade="all, delete-orphan")

    def __eq__(self, other: typing.Self):
        return self.name == other.name and self.host == other.host

    def __repr__(self):
        return resource_repr(
            self,
            dict(name=self.name, host=self.host))

class MinecraftVersion(HasVersionOrders):
    """
    Available Minecraft version information.
    """

    __tablename__ = "mc_versions"

    id: Mapped[int] = mapped_column(Integer(), primary_key=True)

    # Relationships
    versions: Mapped[list["Version"]] = relationship(
        back_populates="mc_versions"
    )

class Resource(MinerModelV1):
    """
    Data Master for constructing a single
    resource.
    """

    __tablename__ = "resources"

    id:   Mapped[int] = mapped_column(Integer(), primary_key=True)
    name: Mapped[str] = mapped_column(String(64))
    type: Mapped[ServiceAPI] = mapped_column(
        Enum(ServiceAPI),
        default=ServiceAPI.Paper)
    kind: Mapped[ResourceKind] = mapped_column(
        Enum(ResourceKind),
        default=ResourceKind.Plugin)

    # Relationships
    aliases: Mapped[list["Alias"]] = relationship(
        back_populates="resources",
        cascade="all, delete-orphan")
    resource_hosts: Mapped[list["ResourceByHost"]] = relationship(
        back_populates="resources",
        cascade="all, delete-orphan")
    versions: Mapped[list["Version"]] = relationship(
        back_populates="resources",
        cascade="all, delete-orphan")

    def __eq__(self, other: typing.Self):
        return all([
            self.id == other.id,
            self.name == other.name,
            self.type == other.type,
            self.kind == other.kind
        ])

    def __repr__(self):
        return resource_repr(self, dict(
            id=self.id,
            name=self.name,
            type=self.type,
            kind=self.kind))

class ResourceByHost(MinerModelV1):
    """Map resources to hosts."""

    __tablename__ = "resource_by_host"

    id: Mapped[int] = mapped_column(Integer(), primary_key=True)
    resource: Mapped[int] = mapped_column(
        ForeignKey("resources.id"),
        primary_key=True)
    host: Mapped[int] = mapped_column(
        ForeignKey("hosts.id"),
        primary_key=True)

    # Relationships
    hosts: Mapped["Host"] = relationship(
        back_populates="resource_hosts")
    resources: Mapped["Resource"] = relationship(
        back_populates="resource_hosts")

    def __repr__(self):
        return resource_repr(
            self,
            dict(resource=self.resource, host=self.host))

class Version(HasVersionOrders):
    """Version of some available resource."""

    __tablename__ = "versions"

    id:          Mapped[int]  = mapped_column(Integer(), primary_key=True)
    resource:    Mapped[int]  = mapped_column(ForeignKey("resources.id"), primary_key=True)
    build:       Mapped[str]  = mapped_column(String(16), nullable=True)
    is_snapshot: Mapped[bool] = mapped_column(Boolean(), default=False)
    mc_version:  Mapped[int]  = mapped_column(ForeignKey("mc_versions.id"))

    # Relationships
    resources: Mapped["Resource"] = relationship(
        back_populates="versions")
    mc_versions: Mapped[MinecraftVersion] = relationship(
        back_populates="versions")

    def __repr__(self):
        return resource_repr(
            self,
            dict(id=self.id, resource=self.resource))

class MinerDB(typing.Protocol):
    """MinerDB Interface Object."""

    @property
    def engine(self) -> Engine:
        """Underlying SQLAlchemy engine."""

    @property
    def root_model(self) -> type[MinerModelV1]:
        """MinerDB base object."""

    def create(self, model: MinerModelV1) -> Insert[MinerModelV1]:
        """Initialize an insert statement."""

    def count(self, statement: Select[tuple[MinerModelV1]]) -> int:
        """
        Get the result count from a `Select`
        statement.
        """

    def delete(self, model: MinerModelV1) -> Delete[MinerModelV1]:
        """Initializd a delete statement."""

    def push(self, *inst: MinerModelV1, commit: bool = ...):
        """
        Performs some action against the database.
        """

    def find(
        self,
        statement: Select[tuple[MinerModelV1]]) -> typing.Iterator[MinerModelV1]:
        """
        Executes a statement returning the result.
        """

    def init(self) -> None:
        """Initialize MirrirDB."""

    def select(
        self,
        *model: type[MinerModelV1]) -> Select[tuple[MinerModelV1]]:
        """Initialize a select statement."""

    def session(
        self,
        *,
        commit: bool = ...) -> typing.ContextManager[Session]:
        """Database session."""

    def update(self, model: Tt) -> Update[Tt]:
        """Initialize an update statement."""

    def __init__(self, *, debug: bool = ...) -> None:
        """Create an instance of `MinerDB`."""

class MinerDBSimple(MinerDB):
    """
    Manages an In-Memory instance of MirrirDB.
    """

    @property
    def engine(self):
        return self._engine

    @property
    def root_model(self):
        return self._root_model

    def create(self, model):
        return insert(model)

    def count(self, statement):
        # We have to filter out the joins in
        # the passed statement in order for
        # our count query to work.
        # Otherwise, SQLAlchemy renders the
        # JOINs multiple times leaving column
        # names ambiguous to the DB driver.
        froms = [f for f in statement.froms if isinstance(f, Table)]
        count = (statement
            .with_only_columns(func.count())
            .select_from(*froms)
            .order_by(None))

        with self.session() as sxn:
            return sxn.execute(count).scalar()

    def delete(self, model):
        return delete(model)

    def push(self, statement, commit=False):
        with self.session(commit=commit) as sxn:
            sxn.execute(statement)

    def find(self, statement):
        with self.session() as sxn:
            for row in sxn.scalars(statement):
                yield row

    def init(self):
        self.root_model.metadata.create_all(self.engine)

    def select(self, *model):
        return select(*model)

    @contextlib.contextmanager
    def session(self, *, commit=False):
        with Session(self.engine) as sxn:
            yield sxn

            if commit:
                sxn.commit()

    def update(self, model):
        return update(model)

    def __init__(self, *, debug=False):
        self._name       = "miner.sqlite"
        self._engine     = create_engine(f"sqlite:///{self._name}", echo=debug)
        self._root_model = MinerModelV1

class MinerDB_V1(MinerDBSimple):
    """MinerDB version: 1"""

    def drop_alias(self, id: int) -> DataResponse:
        """
        Attempt to delete an instance of `Alias`.
        """

        self.push(
            self.delete(Alias).where(Alias.id == id),
            commit=True)
        return data_drop(1)

    def drop_host(self, id: int) -> DataResponse:
        """
        Attempt to delete an instance of `Host`.
        """

        self.push(
            self.delete(Host).where(Host.id == id),
            commit=True)
        return data_drop(1)

    def drop_minecraft(self, id: int) -> DataResponse:
        """
        Attempt to delete an instance of
        `MinecraftVersion`.
        """

        self.push(
            self.delete(MinecraftVersion).where(MinecraftVersion.id == id),
            commit=True)
        return data_drop(1)

    def drop_resource(self, id: int) -> DataResponse:
        """
        Attempt to delete an instance of
        `Resource`.
        """

        self.push(
            self.delete(Resource).where(Resource.id == id),
            commit=True)
        return data_drop(1)

    def drop_version(self, id: int) -> DataResponse:
        """
        Attempt to delete an instance of
        `Version`.
        """

        self.push(
            self.delete(Version).where(Version.id == id),
            commit=True)

    def find_aliases(
        self,
        id: int | None = None,
        name: str | None = None,
        resource: int | None = None) -> DataResponse[Alias]:
        """
        Query database for instances of `Alias`.
        """

        stmt = self.select(Alias)
        if id is not None:
            stmt = stmt.where(Alias.id == id)
        if resource is not None:
            stmt = (stmt
                .join(Resource, Alias.resource == Resource.id)
                .where(Alias.resource == resource))
        if name is not None:
            stmt = stmt.where(Alias.name.contains(name))

        return data_find(self.count(stmt), self.find(stmt))

    def find_hosts(
        self,
        id: int | None = None,
        name: str | None = None,
        resource: int | None = None) -> DataResponse[Host]:
        """
        Query database for instances of `Host`.
        """

        stmt = self.select(Host)
        if id is not None:
            stmt = stmt.where(Host.id == id)
        if resource is not None:
            stmt = (stmt
                .join(ResourceByHost, Host.id == ResourceByHost.host)
                .where(ResourceByHost.resource == resource))
        if name is not None:
            stmt = stmt.where(Host.name.contains(name))

        return data_find(self.count(stmt), self.find(stmt))

    def find_minecraft(
        self,
        id: int | None = None,
        version: typing.Optional[str] = None):
        """
        Query database for instances of
        `MinecraftVersion`.
        """

        stmt = self.select(MinecraftVersion)
        if id is not None:
            stmt = stmt.where(MinecraftVersion.id == id)
        if version is not None:
            stmt = version_compare(stmt, MinecraftVersion, version)

        return data_find(self.count(stmt), self.find(stmt))

    def find_resources(
        self,
        id: int | None = None,
        name: str | None = None,
        type: ServiceAPI | None = None,
        kind: ResourceKind | None = None) -> DataResponse[Resource]:
        """
        Query database for instances of
        `Resource`.
        """

        stmt = self.select(Resource)
        if id is not None:
            stmt = stmt.where(Resource.id == id)
        if name is not None:
            stmt = stmt.where(Resource.name.contains(name))
        if type is not None:
            stmt = stmt.where(Resource.type == type)
        if kind is not None:
            stmt = stmt.where(Resource.kind == kind)

        return data_find(self.count(stmt), self.find(stmt))

    def find_versions(
        self,
        id: int | None = None,
        resource: int | None = None,
        version: str | None = None,
        build: str | None = None,
        compatibility: str | None = None,
        is_snapshot: bool | None = None) -> DataResponse[Version]:
        """
        Query database for instances of `Version`.
        """

        stmt = self.select(Version)
        if id is not None:
            stmt = stmt.where(Version.id == id)
        if resource is not None:
            stmt = (stmt
                .join(Resource, Resource.id == Version.resource)
                .where(Resource.id == resource))
        if version is not None:
            stmt = version_compare(stmt, Version, version)
        if build is not None:
            stmt = stmt.where(Version.build == build)
        if compatibility is not None:
            # Might not work without using join
            # clause.
            stmt = version_compare(stmt, MinecraftVersion, compatibility)
        if is_snapshot is not None:
            stmt = stmt.where(Version.is_snapshot == is_snapshot)

        return data_find(self.count(stmt), self.find(stmt))

    def make_alias(self, meta: dict[str, str]) -> DataResponse:
        """Create a new alias entry."""

        model, count = self.prevalidate_alias(meta)
        if count == 1:
            raise RecordExists("Alias exists.")

        self.push(
            self.create(Alias)
                .values(
                    resource=model.resource,
                    name=model.name),
            commit=True)

        return data_push(count)

    def make_host(self, meta: dict[str, str]) -> DataResponse:
        """Create a new host entry."""

        model, count = self.prevalidate_host(meta)
        if count == 1:
            raise RecordExists("Host exists.")

        self.push(
            self.create(Host)
                .values(host=model.host, name=model.name),
            commit=True)

        return data_push(count)

    def make_minecraft(self, meta: dict[str, str]) -> DataResponse:
        """Create a new Minecraft entry."""

        model, count = self.prevalidate_minecraft(meta)
        if count == 1:
            raise RecordExists("Minecraft exists.")

        self.push(
            self.create(MinecraftVersion)
                .values(
                    major=model.major,
                    minor=model.minor,
                    patch=model.patch),
            commit=True)

        return data_push(count)

    def make_resource(self, meta: dict[str, str]) -> DataResponse:
        """Create a new resource entry."""

        model, count = self.prevalidate_resource(meta)
        if count == 1:
            raise RecordExists("Resource exists.")

        self.push(
            self.create(Resource)
                .values(
                    name=model.name,
                    type=model.type,
                    kind=model.kind),
                commit=True)

        return data_push(count)

    def prevalidate_alias(self, meta: dict[str, str]) -> tuple[Alias, int]:
        """
        Validate a alias entry before it can be
        modified or created. Raises a
        `MinerException` if invalid, returns a
        query model and the result count
        otherwise.
        """

        owner_count = self.find_resources(meta["resource"])["count"]
        if owner_count > 1:
            raise RecordExists("Found too many resources.")
        if owner_count < 1:
            raise RecordNotFound("No resource exists.")

        model = Alias(**meta)
        found = validate_pre_update(
            model,
            self.find_aliases,
            resource=meta["resource"],
            name=meta.get("name", None))
        count = found["count"]

        if count > 0:
            model.id = found["result"][0].id
        return model, found["count"]

    def prevalidate_host(self, meta: dict[str, str]) -> tuple[Host, int]:
        """
        Validate a host entry before it can be
        modified or created. Raises a
        `MinerException` if invalid, returns a
        query model and the result count
        otherwise.
        """

        model = Host(**meta)
        found = validate_pre_update(
            model,
            self.find_hosts,
            id=meta.get("id", None),
            name=meta.get("name", None),
            resource=meta.get("resource", None))
        count = found["count"]

        if count > 0:
            model.id = found["result"][0].id
        return model, found["count"]

    def prevalidate_minecraft(
        self,
        meta: dict[str, str]) -> tuple[MinecraftVersion, int]:
        """
        Validate a Minecraft entry before it can
        be modified or created. Raises a
        `MinerException` if invalid, returns a
        query model and the result count
        otherwise.
        """

        maj, min, pat = version_parse_str(meta["version"])
        model = MinecraftVersion(major=maj, minor=min, patch=pat)
        found = validate_pre_update(
            model,
            self.find_minecraft,
            id=meta.get("id", None),
            version=meta.get("version", None))
        count = found["count"]

        if count > 0:
            model.id = found["result"][0].id
        return model, found["count"]

    def prevalidate_resource(
        self,
        meta: dict[str, str]) -> tuple[Resource, int]:
        """
        Validate a resource entry before it can
        be modified or created. Raises a
        `MinerException` if invalid, returns a
        query model and the result count
        otherwise.
        """

        model = Resource(**meta)
        found = validate_pre_update(
            model,
            self.find_resources,
            id=meta.get("id", None),
            name=meta.get("name", None))
        count = found["count"]

        if count > 0:
            model.id = found["result"][0].id
        return model, found["count"]

    def push_alias(self, meta: dict[str, str]) -> DataResponse:
        """Update an existing alias entry."""

        model, count = self.prevalidate_alias(meta)
        if count < 1:
            raise RecordNotFound("Alias not found.")

        self.push(
            self.update(Alias).values(name=model.name).where(id=model.id),
            commit=True)

        return data_push(count)

    def push_host(self, meta: dict[str, str]) -> DataResponse:
        """Update an existing host entry."""

        model, count = self.prevalidate_host(meta)
        if count < 1:
            raise RecordNotFound("Host not found.")

        self.push(
            self.update(Host)
                .values(host=model.host)
                .where(Host.id == model.id),
            commit=True)

        return data_push(count)

    def push_resource(self, meta: dict[str, str]) -> DataResponse:
        """
        Update an existing resource.
        """

        model, count = self.prevalidate_resource(meta)

        self.push(
            self.update(Resource)
                .values(
                    type=model.type,
                    kind=model.kind)
                .where(Resource.id == model.id),
            commit=True)

        return data_push(count)

if __name__ == "__main__":
    minerdb = MinerDB_V1(debug=True)
    minerdb.init()
    cnt, aliases = minerdb.find_aliases()


"""
.. module:: views.reports.lab
   :synopsis: Indivo view implementations for the lab report.

.. moduleauthor:: Daniel Haas <daniel.haas@post.harvard.edu>
.. moduleauthor:: Ben Adida <ben@adida.net>

"""

from django.http import HttpResponseBadRequest, HttpResponse
from indivo.lib.view_decorators import marsloader, DEFAULT_ORDERBY
from indivo.lib.query import FactQuery, DATE, STRING, NUMBER
from indivo.models import Lab

LAB_FILTERS = {
  'lab_type': ('lab_type', STRING),
  'date_measured': ('date_measured', DATE),
  'lab_test_name': ('first_lab_test_name', STRING),
  DEFAULT_ORDERBY : ('created_at', DATE)
}

LAB_TEMPLATE = 'reports/lab.xml'

def lab_list(*args, **kwargs):
  """ List the lab data for a given record.

  For 1:1 mapping of URLs to views. Just calls
  :py:meth:`~indivo.views.reports.lab._lab_list`.

  """

  return _lab_list(*args, **kwargs)

def carenet_lab_list(*args, **kwargs):
  """ List the lab data for a given carenet.

  For 1:1 mapping of URLs to views. Just calls
  :py:meth:`~indivo.views.reports.lab._lab_list`.

  """

  return _lab_list(*args, **kwargs)

@marsloader(query_api_support=True)
def _lab_list(request, group_by, date_group, aggregate_by,
             limit, offset, order_by,
             status, date_range, filters,
             record=None, carenet=None):
  """ List the lab objects matching the passed query parameters.

  See :doc:`/query-api` for a listing of valid parameters.

  Will return :http:statuscode:`200` with a list of labs on success,
  :http:statuscode:`400` if any invalid query parameters were passed.

  """

  q = FactQuery(Lab, LAB_FILTERS,
                group_by, date_group, aggregate_by,
                limit, offset, order_by,
                status, date_range, filters,
                record, carenet)
  try:
    return q.render(LAB_TEMPLATE)
  except ValueError as e:
    return HttpResponseBadRequest(str(e))


""" Test suite for the maltabar 'waitr' web API """

import unittest
import waitr
import json

API = '/api/v1'

class TestProbes(unittest.TestCase):

    def setUp(self):
        waitr.app.config['TESTING'] = True
        self.app = waitr.app.test_client()
        self.app.debug = True

    def test_get_probes(self):
        rv = self.app.get(API + '/probes')
        self.assertEqual(rv.status_code, 200, 'got: ' + rv.status)
        data = json.loads(rv.data)
        assert 'probes' in data

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


import os
import pickle

from nltk.translate.bleu_score import sentence_bleu, SmoothingFunction
from rouge import Rouge

root_dir = os.path.abspath("..")

# считаем среднее значение метрики BLEU на тестовом датасете

def bleu_analysis(test_data, folder='mine-gen-func', root_dir=root_dir):
    smoothie = SmoothingFunction().method4
    scores = []

    with open(root_dir + "/reports/" + folder + "/test_generation", "rb") as fp:
        generated_list = pickle.load(fp)

    for num, item in enumerate(test_data):
        reference = item
        candidate = generated_list[num]
        scores.append(sentence_bleu([reference], candidate, smoothing_function=smoothie))

    with open(root_dir + "/reports/" + folder + "/test_generation_score", "wb") as fp:
        pickle.dump(scores, fp)
    return scores

def rogue_analysis(test_data, folder='mine-gen-func', root_dir=root_dir):
    rouge = Rouge()
    with open(root_dir + "/reports/" + folder + "/test_generation", "rb") as fp:
        generated_list = pickle.load(fp)

    rouge_score = rouge.get_scores(generated_list, test_data.tolist(), avg=True, ignore_empty=True)
    return rouge_score


from .equirectangular import Equirectangular
import bpy
from math import radians
from os.path import isfile

def transform_camera(camera: bpy.types.Object, distance, long, lat):
    """
    Set camera transformation
    Project position onto sphere of radius [distance] and align rotation
    :param camera: Camera to transform
    :param distance: Distance from centre point
    :param long: Longitudinal position
    :param lat: Latitudinal position
    """
    camera.location = Equirectangular.project_sphere((long, lat), False, distance)

    # rotate facing inwards, then apply lat & long
    rx, rz = 90 - lat, 180 + long
    camera.rotation_euler = (radians(rx), 0, radians(rz))

def create_pixel_sphere(radius, resolution):
    """
    Generate mesh with vertices for each projected pixel.
    Demonstrates position of each pixel.
    :param radius: Sphere radius
    :param resolution: Output image resolution
    """
    xR, yR = resolution

    # generate one vertex for each pixel
    verts = []
    for x in range(xR):
        for y in range(yR):
            v = Equirectangular.Pixel.project_sphere((x, y), resolution, radius)

            verts.append(v)

    name = f"Pixel Sphere ({xR}, {yR})"

    mesh = bpy.data.meshes.new(name)  # create mesh
    mesh.from_pydata(verts, [], [])
    obj = bpy.data.objects.new(name, mesh)  # create object; apply mesh

    bpy.context.scene.collection.objects.link(obj)  # place object in master collection
    bpy.context.view_layer.objects.active = obj  # make active object (?)
    obj.select_set(True)

def get_render_resolution(scene=None):
    if scene is None:
        scene = bpy.context.scene

    return scene.render.resolution_x, scene.render.resolution_y

def product(factors):
    result = 1
    for f in factors:
        result *= f
    return result

def iterate_flat(iterable, group_size):
    """
    Generator for iterating over [iterable] in groups of size [group_size]
    :param iterable: Target iterable
    :param group_size: Sub-group iteration size
    """
    if len(iterable) % group_size != 0:
        raise Exception("length of iterable must be divisible by four")

    for i in range(0, len(iterable), group_size):
        yield iterable[i: i + group_size]

class OutImage:
    @staticmethod
    def pixel_to_coord(pixel, res_width: int):
        """
        Convert pixel number to pixel coordinate
        :param pixel: Pixel number; start counting bottom left, go right
        :param res_width: x component of resolution
        :return: Pixel coordinates: zeroed bottom left
        """

        x = pixel % res_width
        y = pixel // res_width

        return x, y

    @staticmethod
    def coord_to_pixel(coord, res_width: int):
        """
        Convert pixel coordinate to pixel number
        :param coord: Pixel coordinates: zeroed bottom left
        :param res_width: x component of resolution
        :return: Pixel number; start counting bottom left, go right
        """
        x, y = coord

        return y * res_width + x

    @staticmethod
    def modify_filename(file_name):
        """
        Rename target file to ensure existing files are not overwritten
        """
        if not isfile(file_name):
            return file_name

        # does already exist
        count = 1
        while isfile(OutImage.insert_before_extension(file_name, count)):
            count += 1

        return OutImage.insert_before_extension(file_name, count)

    @staticmethod
    def insert_before_extension(filename: str, insert):
        """
        Insert string into filename before extension
        :param filename: target filename
        :param insert: string to be inserted
        """
        pos = filename.rfind('.')  # find extension dot position from right
        name, extension = filename[:pos], filename[pos:]
        return name + str(insert) + extension


import re
from ariblib.aribstr import AribString
from typing import cast, Literal

class TSInformation:
    """ 録画 TS ファイル内に含まれる番組情報のユーティリティ """

    # 映像のコーデック
    # ref: https://github.com/Chinachu/Mirakurun/blob/master/src/Mirakurun/EPG.ts#L23-L27
    STREAM_CONTENT = {
        0x01: 'MPEG-2',
        0x05: 'H.264',
        0x09: 'H.265',
    }

    # 映像の解像度
    # ref: https://github.com/Chinachu/Mirakurun/blob/master/src/Mirakurun/EPG.ts#L29-L63
    COMPONENT_TYPE = {
        0x01: '480i',
        0x02: '480i',
        0x03: '480i',
        0x04: '480i',
        0x83: '4320p',
        0x91: '2160p',
        0x92: '2160p',
        0x93: '2160p',
        0x94: '2160p',
        0xA1: '480p',
        0xA2: '480p',
        0xA3: '480p',
        0xA4: '480p',
        0xB1: '1080i',
        0xB2: '1080i',
        0xB3: '1080i',
        0xB4: '1080i',
        0xC1: '720p',
        0xC2: '720p',
        0xC3: '720p',
        0xC4: '720p',
        0xD1: '240p',
        0xD2: '240p',
        0xD3: '240p',
        0xD4: '240p',
        0xE1: '1080p',
        0xE2: '1080p',
        0xE3: '1080p',
        0xE4: '1080p',
        0xF1: '180p',
        0xF2: '180p',
        0xF3: '180p',
        0xF4: '180p',
    }

    # formatString() で使用する変換マップ
    __format_string_translation_map: dict[int, str] | None = None
    __format_string_regex: re.Pattern[str] | None = None
    __format_string_regex_table: dict[str, str] | None = None

    @classmethod
    def __buildFormatStringTranslationMap(cls) -> None:
        """
        formatString() で使用する変換マップや正規表現を構築する
        一度のみ実行され、以降はキャッシュされる
        """

        # すでに構築済みの場合は何もしない
        if cls.__format_string_translation_map is not None and cls.__format_string_regex is not None:
            return

        # 全角英数を半角英数に置換
        # ref: https://github.com/ikegami-yukino/jaconv/blob/master/jaconv/conv_table.py
        zenkaku_table = '０１２３４５６７８９ＡＢＣＤＥＦＧＨＩＪＫＬＭＮＯＰＱＲＳＴＵＶＷＸＹＺａｂｃｄｅｆｇｈｉｊｋｌｍｎｏｐｑｒｓｔｕｖｗｘｙｚ'
        hankaku_table = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
        merged_table = dict(zip(list(zenkaku_table), list(hankaku_table)))

        # 全角記号を半角記号に置換
        symbol_zenkaku_table = '＂＃＄％＆＇（）＋，－．／：；＜＝＞［＼］＾＿｀｛｜｝　'
        symbol_hankaku_table = '"#$%&\'()+,-./:;<=>[\\]^_`{|} '
        merged_table.update(zip(list(symbol_zenkaku_table), list(symbol_hankaku_table)))
        merged_table.update({
            # 一部の半角記号を全角に置換
            # 主に見栄え的な問題（全角の方が字面が良い）
            '!': '！',
            '?': '？',
            '*': '＊',
            '~': '～',
            # シャープ → ハッシュ
            '♯': '#',
            # 波ダッシュ → 全角チルダ
            ## EDCB は ～ を全角チルダとして扱っているため、KonomiTV でもそのように統一する
            ## TODO: 番組検索を実装する際は検索文字列の波ダッシュを全角チルダに置換する下処理が必要
            ## ref: https://qiita.com/kasei-san/items/3ce2249f0a1c1af1cbd2
            '〜': '～',
        })

        # 番組表で使用される囲み文字の置換テーブル
        ## ref: https://note.nkmk.me/python-chr-ord-unicode-code-point/
        ## ref: https://github.com/l3tnun/EPGStation/blob/v2.6.17/src/util/StrUtil.ts#L7-L46
        ## ref: https://github.com/xtne6f/EDCB/blob/work-plus-s-230526/EpgDataCap3/EpgDataCap3/ARIB8CharDecode.cpp#L1324-L1614
        enclosed_characters_table = {
            '\U0001f14a': '[HV]',
            '\U0001f14c': '[SD]',
            '\U0001f13f': '[P]',
            '\U0001f146': '[W]',
            '\U0001f14b': '[MV]',
            '\U0001f210': '[手]',
            '\U0001f211': '[字]',
            '\U0001f212': '[双]',
            '\U0001f213': '[デ]',
            '\U0001f142': '[S]',
            '\U0001f214': '[二]',
            '\U0001f215': '[多]',
            '\U0001f216': '[解]',
            '\U0001f14d': '[SS]',
            '\U0001f131': '[B]',
            '\U0001f13d': '[N]',
            '\U0001f217': '[天]',
            '\U0001f218': '[交]',
            '\U0001f219': '[映]',
            '\U0001f21a': '[無]',
            '\U0001f21b': '[料]',
            '\U0001f21c': '[前]',
            '\U0001f21d': '[後]',
            '\U0001f21e': '[再]',
            '\U0001f21f': '[新]',
            '\U0001f220': '[初]',
            '\U0001f221': '[終]',
            '\U0001f222': '[生]',
            '\U0001f223': '[販]',
            '\U0001f224': '[声]',
            '\U0001f225': '[吹]',
            '\U0001f14e': '[PPV]',
            '\U0001f200': '[ほか]',
        }

        # Unicode の囲み文字を大かっこで囲った文字に置換する
        ## EDCB で EpgDataCap3_Unicode.dll を利用している場合や、Mirakurun 3.9.0-beta.24 以降など、
        ## 番組情報取得元から Unicode の囲み文字が送られてくる場合に対応するためのもの
        ## Unicode の囲み文字はサロゲートペアなどで扱いが難しい上に KonomiTV では囲み文字を CSS でハイライトしているため、Unicode にするメリットがない
        ## ref: https://note.nkmk.me/python-str-replace-translate-re-sub/
        merged_table.update(enclosed_characters_table)

        # 変換マップを構築し、クラス変数に格納
        cls.__format_string_translation_map = str.maketrans(merged_table)

        # 逆に代替の文字表現に置換された ARIB 外字を Unicode に置換するテーブル
        ## 主に EDCB (EpgDataCap3_Unicode.dll 不使用) 環境向けの処理
        ## EDCB は通常 Shift-JIS で表現できない文字をサロゲートペア範囲外の文字も含めてすべて代替の文字表現に変換するが、これはこれで見栄えが悪い
        ## そこで、サロゲートペアなしで表現できて、一般的な日本語フォントでグリフが用意されていて、
        ## かつ他の文字表現から明確に判別可能でそのままでは分かりづらい文字表現だけ Unicode に置換する
        ## ref: https://github.com/xtne6f/EDCB/blob/work-plus-s-230526/EpgDataCap3/EpgDataCap3/ARIB8CharDecode.cpp#L1324-L1614
        cls.__format_string_regex_table = {
            # '[・]': '⚿',  # グリフが用意されていないことが多い
            '(秘)': '㊙',
            'm^2': 'm²',
            'm^3': 'm³',
            'cm^2': 'cm²',
            'cm^3': 'cm³',
            'km^2': 'km²',
            '[社]': '㈳',
            '[財]': '㈶',
            '[有]': '㈲',
            '[株]': '㈱',
            '[代]': '㈹',
            # '(問)': '㉄',  # グリフが用意されていないことが多い
            '^2': '²',
            '^3': '³',
            # '(箏): '㉇',  # グリフが用意されていないことが多い
            '(〒)': '〶',
            '()()': '⚾',
        }

        # 正規表現を構築し、クラス変数に格納
        cls.__format_string_regex = re.compile("|".join(map(re.escape, cls.__format_string_regex_table.keys())))

    @classmethod
    def formatString(cls, string: str | AribString) -> str:
        """
        文字列に含まれる英数や記号を半角に置換し、一律な表現に整える

        Args:
            string (str | AribString): str あるいは AribString の文字列

        Returns:
            str: 置換した文字列
        """

        # AribString になっている事があるので明示的に str 型にキャストする
        result = str(string)

        # 変換マップを構築 (初回以降はキャッシュされる)
        cls.__buildFormatStringTranslationMap()
        assert cls.__format_string_translation_map is not None
        assert cls.__format_string_regex is not None
        assert cls.__format_string_regex_table is not None

        # 置換を実行
        result = result.translate(cls.__format_string_translation_map)
        result = cls.__format_string_regex.sub(lambda match: cast(dict[str, str], cls.__format_string_regex_table)[match.group(0)], result)

        # 置換した文字列を返す
        return result

    @staticmethod
    def getNetworkType(network_id: int) -> Literal['GR', 'BS', 'CS', 'CATV', 'SKY', 'STARDIGIO', 'OTHER']:
        """
        ネットワーク ID からネットワークの種別を取得する
        種別は GR (地デジ)・BS・CS・CATV・SKY (SPHD)・STARDIGIO (スターデジオ)・OTHER (不明なネットワーク ID のチャンネル) のいずれか

        Args:
            network_id (int): ネットワーク ID

        Returns:
            str: GR・BS・CS・CATV・SKY・STARDIGIO・OTHER のいずれか
        """

        # 以下は ARIB STD-B10 第2部 付録N より抜粋
        # https://web.archive.org/web/2if_/http://www.arib.or.jp/english/html/overview/doc/2-STD-B10v5_3.pdf#page=256

        # 地上デジタルテレビジョン放送 (network_id: 30848 ~ 32744)
        if network_id >= 0x7880 and network_id <= 0x7FE8:
            return 'GR'

        # BSデジタル放送
        if network_id == 0x0004:
            return 'BS'

        # 110度CSデジタル放送
        # CS1: 0x0006 (旧プラット・ワン系)
        # CS2: 0x0007 (旧スカイパーフェクTV!2系)
        if network_id == 0x0006 or network_id == 0x0007:
            return 'CS'

        # ケーブルテレビ (リマックス方式・トランスモジュレーション方式)
        # ケーブルテレビ独自のチャンネルのみで、地上波・BS の再送信は含まない
        # デジタル放送リマックス: 0xFFFE (HD・SD チャンネル (MPEG-2))
        # デジタル放送高度リマックス: 0xFFFA (ケーブル4Kチャンネル (H.264, H.265))
        # JC-HITSトランスモジュレーション: 0xFFFD (HD・SD チャンネル (MPEG-2))
        # 高度JC-HITSトランスモジュレーション: 0xFFF9 (ケーブル4Kチャンネル (H.264, H.265))
        if network_id == 0xFFFE or network_id == 0xFFFA or network_id == 0xFFFD or network_id == 0xFFF9:
            return 'CATV'

        # 124/128度CSデジタル放送
        # SPHD: 0x000A (スカパー！プレミアムサービス)
        # SPSD-SKY: 0x0003 (運用終了)
        if network_id == 0x000A or network_id == 0x0003:
            return 'SKY'

        # 124/128度CSデジタル放送
        # SPSD-PerfecTV: 0x0001 (スターデジオ)
        if network_id == 1:
            return 'STARDIGIO'

        # 不明なネットワーク ID のチャンネル
        return 'OTHER'

    @staticmethod
    def getISO639LanguageCodeName(iso639_language_code: str) -> str:
        """
        ISO639 形式の言語コードが示す言語の名称を取得する

        Args:
            iso639_code (str): ISO639 形式の言語コード

        Returns:
            str: ISO639 形式の言語コードが示す言語の名称
        """

        if iso639_language_code == 'jpn':
            return '日本語'
        elif iso639_language_code == 'eng':
            return '英語'
        elif iso639_language_code == 'deu':
            return 'ドイツ語'
        elif iso639_language_code == 'fra':
            return 'フランス語'
        elif iso639_language_code == 'ita':
            return 'イタリア語'
        elif iso639_language_code == 'rus':
            return 'ロシア語'
        elif iso639_language_code == 'zho':
            return '中国語'
        elif iso639_language_code == 'kor':
            return '韓国語'
        elif iso639_language_code == 'spa':
            return 'スペイン語'
        else:
            return 'その他の言語'


# Basics Requirements
import pathlib
import os
import dash
import dash_core_components as dcc
import dash_html_components as html
import plotly.graph_objects as go
import dash_bootstrap_components as dbc
from dash.dependencies import Input, Output, State, ClientsideFunction
from dash.exceptions import PreventUpdate
#from .data.dataframes_ftr import get_df
from app import app
# from app import app, cache
from .data.dataframes import df_c, df_c2

# PLACE THE COMPONENTS IN THE LAYOUT
layout = html.Div(
    [
        dbc.Alert(
            [
                html.H3("Clustering Analysis", style={"color": "#F37126"}),
                html.P(
                    "You will find an analysis of how your clients relate to"
                    " each other based on their transaction behavior",
                    style={"color": "#8190A5", "font-weight": "bold"},
                ),
            ],
            style={"background-color": "#F8F6F6", "border": "0px"},
        ),
    ]
)

available_indicators = ['transaction_card_type',
                        'merchant_classification',
                        'category_hour',
                        'category_paymentmethod_franchise',
                        'category_response_code']

cluster_tab = dbc.Row(
    dbc.Col(
        [
            html.Div(
                [
                    html.P("Choose a category", className="choose_category"),
                ],
            ),
            dbc.Select(
                id="select",
                options=[{"label": i, "value": i} for i in available_indicators],
                value="transaction_card_type",
            ),
            dcc.Graph(id="indicator-graphic"),
        ],
        width={"size": 6, "offset": 3},
    )
)

@app.callback(
    dash.dependencies.Output("indicator-graphic", "figure"),
    [
        dash.dependencies.Input("select", "value"),
    ],
)
# @cache.memoize(timeout=120)
def update_graph(select):
    fig = go.Figure()
    fig.add_trace(
        go.Bar(
            x=df_c["{}".format(select)],
            y=(df_c[df_c['cluster_predicted']==0]).value_counts(),
            name="cluster 0",
            marker_color="tomato",
        )
    )
    fig.add_trace(
        go.Bar(
            x=df_c["{}".format(select)],
            y=(df_c[df_c['cluster_predicted']==1]).value_counts(),
            name="cluster 1",
            marker_color="slategray",
        )
    )
    fig.update_layout(title="Clusterization by {}".format(select),
                      xaxis=dict(title=df_c['{}'.format(select)].name,
                                 titlefont_size=16,
                                 tickfont_size=14,
                                ),
                      yaxis=dict(title='Number transactions',
                                 titlefont_size=16,
                                 tickfont_size=14,
                                ),
                      barmode='group',
                    )
    fig.update_xaxes(ticktext = [text for text in df_c2['{}'.format(select)].unique()],
                     tickvals = [val for val in df_c['{}'.format(select)].unique()])
    return fig


from rest_framework import serializers

from ..models import Tag
from ..serializers import AvailableTagSerializer

class TagSerializer(serializers.ModelSerializer):
    tag = AvailableTagSerializer(read_only=True)

    class Meta:
        model = Tag
        fields = [
            "id",
            "tag",
            "created_at",
        ]

        lookup_field = "id"


from bottle import run, route, static_file, template

@route('/')
def index ():
    return template('index2')

@route('/staticf/<filename>')
def staticf(filename):
    l_fileName = filename
    print('In Method staticf')
    return(static_file(filename, root='./static_images'))

if __name__ == '__main__':
    run(debug=True, reloader=True)


import bpy

from math import radians
from mathutils import Vector

def link_to_pivot(object, pivot):
    # Add 'Transform' constraint
    transform = object.constraints.new('TRANSFORM')
    transform.target = pivot
    transform.target_space = 'LOCAL'
    transform.owner_space = 'LOCAL'
    transform.map_from = 'SCALE'
    transform.from_min_y_scale = 0
    transform.from_max_y_scale = 100000
    transform.map_to = 'LOCATION'
    transform.map_to_z_from = 'Y'
    transform.to_max_z = 100000

    # Add 'Child of' constraint
    child_of = object.constraints.new('CHILD_OF')
    child_of.target = pivot
    child_of.use_scale_x = False
    child_of.use_scale_y = False
    child_of.use_scale_z = False

def create_light_controller(parent):
    # Create light pivot
    light_pivot = bpy.data.objects.new("Light Pivot", None)
    light_pivot.empty_display_type = 'SPHERE'
    light_pivot.location = parent.location
    light_pivot.rotation_euler = parent.rotation_euler.copy()
    light_pivot.scale = parent.scale * 0.8

    # Add 'Child of' constraint
    light_child_of = light_pivot.constraints.new('CHILD_OF')
    light_child_of.target = parent
    light_child_of.use_scale_x = False
    light_child_of.use_scale_y = False
    light_child_of.use_scale_z = False

    # Create light
    light_data = bpy.data.lights.new("Light", type="AREA")
    light = bpy.data.objects.new("Light", light_data)
    light.location = parent.location
    light.rotation_euler = parent.rotation_euler.copy()
    light.rotation_euler.rotate_axis('X', radians(90))
    light.scale = light_pivot.scale * 4

    link_to_pivot(light, light_pivot)

    # Lock transforms
    light.lock_location[0] = True
    light.lock_location[1] = True
    light.lock_location[2] = True
    light.lock_rotation[0] = True
    light.lock_rotation[1] = True
    light.lock_rotation[2] = True

    # Add to collection
    collection = bpy.data.collections.new("Light Controller")
    collection.objects.link(light_pivot)
    collection.objects.link(light)

    return collection, light, light_pivot

def create_camera_controller(location, radius):
    # Create camera pivot
    camera_pivot = bpy.data.objects.new("Camera Pivot", None)
    camera_pivot.empty_display_type = "SPHERE"
    camera_pivot.location = location
    camera_pivot.scale = Vector((radius, radius, radius))

    # Create camera
    camera_data = bpy.data.cameras.new(name="Camera")
    camera = bpy.data.objects.new("Camera", camera_data)
    camera.location = location
    camera.rotation_euler = (radians(90), 0, 0)

    link_to_pivot(camera, camera_pivot)

    # Lock camera transform
    camera.lock_location[0] = True
    camera.lock_location[1] = True
    camera.lock_location[2] = True
    camera.lock_rotation[0] = True
    camera.lock_rotation[1] = True
    camera.lock_rotation[2] = True
    camera.lock_scale[0] = True
    camera.lock_scale[1] = True
    camera.lock_scale[2] = True

    # Add to collection
    collection = bpy.data.collections.new("Camera Controller")
    collection.objects.link(camera)
    collection.objects.link(camera_pivot)

    # Return controller
    return collection, camera, camera_pivot

def vector_mean(vectors):
    total = Vector()
    for vector in vectors:
        total += vector
    return total / len(vectors)

def get_selection_center(context):
    selected_objects = context.selected_objects
    if selected_objects:
        return vector_mean([obj.location for obj in selected_objects])
    else:
        return context.scene.cursor.location.copy()

def get_selection_diameter(context, center):
    selected_objects = context.selected_objects

    if not selected_objects:
        return 1

    if len(selected_objects) == 1:
        if hasattr(selected_objects[0], "dimensions"):
            max_dimension = max(selected_objects[0].dimensions)
            return max(1, max_dimension)
        return 1

    distances = [(obj.location - center).magnitude for obj in selected_objects]
    max_distance = max(distances)
    return max_distance * 2


'''
Description
Design an algorithm to encode a list of strings to a string. The encoded string is then sent over the network and is decoded back to the original list of strings.

Please implement encode and decode

Contact me on wechat to get Amazon、Google requent Interview questions . (wechat id : jiuzhang0607)

Example
Example1

Input: ["lint","code","love","you"]
Output: ["lint","code","love","you"]
Explanation:
One possible encode method is: "lint:;code:;love:;you"
Example2

Input: ["we", "say", ":", "yes"]
Output: ["we", "say", ":", "yes"]
Explanation:
One possible encode method is: "we:;say:;:::;yes"

'''

class Solution:
    """
    @param: strs: a list of strings
    @return: encodes a list of strings to a single string.
    """
    def encode(self, strs):
        # write your code here
        enc_str = ""
        for word in strs:
            enc_str += str(len(word))+"#"+word

        return enc_str

    """
    @param: str: A string
    @return: dcodes a single string to a list of strings
    """

    def decode(self, str):
        # write your code here
        decoded_arr = []
        i =0
        while i < (len(str)):
            try:
                if isinstance(int(str[i]),int):
                    word_len = int(str[i])
            except:
                pass

            if str[i] == "#":
                decoded_arr.append(str[i+1:word_len+i+1])
                i = word_len+i+1
            else:
                i =i +1

        return decoded_arr

if __name__ == "__main__":
    sol = Solution()
    enc = sol.encode(["we", "sa#id", ":q2","yes"])
    print(enc)
    res = sol.decode(enc)
    print(res)


from tkinter import *
import sqlite3

root = Tk()
root.geometry('900x600')
root.title("Registration Form")

Fullname = StringVar()
Email = StringVar()
var = StringVar()
c = StringVar()
var1 = StringVar()
Address = StringVar()
Phonenumber = StringVar()
months = StringVar()
days = StringVar()
year = StringVar()

def database():
    name1 = Fullname.get()
    email = Email.get()
    phone = Phonenumber.get()
    address = Address.get()
    DOBDay = days.get()
    DOBMonth = months.get()
    DOBYear = year.get()
    gender = var.get()
    country = c.get()
    prog = var1.get()
    conn = sqlite3.connect('Form.db')
    with conn:
        cursor = conn.cursor()
    cursor.execute(
        'CREATE TABLE IF NOT EXISTS Student (Fullname TEXT,Email TEXT,Gender TEXT,country TEXT,Programming TEXT,'
        'Address TEXT,Phone TEXT,DOBDay TEXT,DOBMonth TEXT, DOBYear TEXT)')
    cursor.execute(
        'INSERT INTO Student (FullName,Email,Gender,country,Programming,Address,Phone, DOBDay, DOBMonth, '
        'DOBYear) VALUES(?,?,?,?,?,?,?,?,?,?)',
        (name1, email, gender, country, prog, address, phone, DOBDay, DOBMonth, DOBYear))
    conn.commit()

def dayss():
    dayss = list(range(1, 32))
    return dayss

def moonths():
    moonths = list(range(1, 13))
    return moonths

def yearr():
    yearr = list(range(1990, 2005))
    return yearr

label0 = Label(root, text="Registration Form", width=20, font=("bold", 20))
label0.place(x=290, y=53)

labela = Label(root, text="Address", width=20, font=("bold", 10))
labela.place(x=480, y=130)

entrya = Entry(root, textvar=Address, width=40)
entrya.place(x=640, y=130)

label1 = Label(root, text="Full Name", width=20, font=("bold", 10))
label1.place(x=80, y=130)

entry1 = Entry(root, textvar=Fullname, width=30)
entry1.place(x=240, y=130)

label2 = Label(root, text="Email", width=20, font=("bold", 10))
label2.place(x=68, y=180)

labelp = Label(root, text="Phone Number", width=20, font=("bold", 10))
labelp.place(x=480, y=180)

entryp = Entry(root, textvar=Phonenumber)
entryp.place(x=640, y=180)

entry2 = Entry(root, textvar=Email)
entry2.place(x=240, y=180)

label3 = Label(root, text="Gender", width=20, font=("bold", 10))
label3.place(x=70, y=230)

Radiobutton(root, text="Male", padx=5, variable=var, value="Male").place(x=235, y=230)
Radiobutton(root, text="Female", padx=20, variable=var, value="Female").place(x=290, y=230)

label4 = Label(root, text="country", width=20, font=("bold", 10))
label4.place(x=70, y=280)

list1 = ['Canada', 'India', 'UK', 'Nippal', 'Iceland', 'South Africa'];

droplist = OptionMenu(root, c, *list1)
droplist.config(width=25)
c.set('Select Your Country')
droplist.place(x=240, y=280)

label4 = Label(root, text="Language", width=20, font=("bold", 10))
label4.place(x=75, y=330)

list2 = ['C', 'C++', 'Java', 'Python']

droplist2 = OptionMenu(root, var1, *list2)
droplist2.config(width=25)
var1.set('Select Preffered Language')
droplist2.place(x=240, y=330)

labeldob = Label(root, text="Date Of Birth", width=20, font=("bold", 10))
labeldob.place(x=480, y=235)

days1 = dayss()
droplist3 = OptionMenu(root, days, *days1)
days.set("DD")
droplist3.place(x=640, y=230)

months1 = moonths()
droplist4 = OptionMenu(root, months, *months1)
months.set("MM")
droplist4.place(x=710, y=230)

year1 = yearr()
droplist5 = OptionMenu(root, year, *year1)
year.set("YYYY")
droplist5.place(x=790, y=230)

Button(root, text='Submit', width=20, bg='brown', fg='white', command=database).place(x=380, y=400)

root.mainloop()


import torch
import torch.nn as nn
import torch.nn.functional as F
import logging
import numpy as np

from .quant import conv3x3, conv1x1
from .layers import norm, actv
from torch.nn.modules.utils import _quadruple

# Prone-net: Point-wise and Reshape only Neural Network
class Prone(nn.Module):
    def __init__(self, out_channel, in_channel=3, stride=4, groups=1, kernel_size=3, force_fp=True, args=None, feature_stride=1, keepdim=True):
        super(Prone, self).__init__()
        self.stride = stride * 2
        self.in_channel = in_channel * self.stride * self.stride
        self.out_channel = out_channel * 4
        self.keepdim = keepdim
        self.conv = conv1x1(self.in_channel, self.out_channel, groups=groups, args=args, force_fp=force_fp)

        self.bn_before_restore = False
        if hasattr(args, 'keyword'):
            self.bn_before_restore = 'bn_before_restore' in args.keyword
        if self.bn_before_restore:
            self.bn = norm(self.out_channel, args)

    def forward(self, x):
        # padding zero when cannot just be divided
        B, C, H, W = x.shape
        if H % self.stride != 0:
            pad = (self.stride - (H % self.stride)) // 2
            x = F.pad(x, _quadruple(pad), mode="constant", value=0)

        B, C, H, W = x.shape
        #print(B, C, H, W, self.stride)
        # consider to employ the PixelShuffle layer instead
        x = x.reshape(B, C, H // self.stride, self.stride, W // self.stride, self.stride)
        x = x.transpose(4, 3).reshape(B, C, 1, H // self.stride, W // self.stride, self.stride * self.stride)
        x = x.transpose(2, 5).reshape(B, C * self.stride * self.stride, H // self.stride, W // self.stride)
        x = self.conv(x)
        if self.bn_before_restore:
            x = self.bn(x)

        if self.keepdim: # restore the channel dimension, however resolution might be altered
            B, C, H, W = x.shape
            x = x.reshape(B, C//4, 4, H, W, 1)
            x = x.transpose(2, 5).reshape(B, C//4, H, W, 2, 2)
            x = x.transpose(4, 3).reshape(B, C//4, H * 2, W * 2)
        return x

def qprone(in_channel, out_channel, stride=1, groups=1, padding=1, args=None, force_fp=False, feature_stride=1, kernel_size=3, keepdim=True):
    assert kernel_size in [3], "Only kernel size = 3 support"
    assert stride in [1, 2], "Stride must be 1 or 2"
    #assert groups in [1], "groups must be 1"
    return Prone(out_channel, in_channel, stride, groups, kernel_size, force_fp, args, feature_stride, keepdim)


from PIL import Image
import os
import cv2
import numpy as np
in_dir = '../Downloads/coloring_test/segmentation/test/final_test/'
#out_dir = '../Downloads/coloring_test/segmentation/train_d
out_dir = '../Downloads/coloring_test/segmentation/test/final_test_thick/'

imgs = list(sorted(os.listdir(os.path.join(in_dir))))
for filename in imgs:
    img = Image.open(in_dir  + filename).convert("RGB")
    name, ext = os.path.splitext (filename)
    #mask_name = name + '_tf.png'
    print(filename)

    #output = Image.open(out_dir+ mask_name).convert("RGB")
    output = Image.open(in_dir  + filename).convert("RGB")

    masking = output.load()

    (width,height) = img.size
    black = (0,0,0)
    yellow = (255,255,0)
    #output = img.load()
    for y in range(0,height-1):
        for x in range(0,width-1):
            r, g, b = img.getpixel((x,y))
            #print(str(x)+','+str(y))

            if r<5 and g < 5 and b< 5:
                masking[x,y] = black

                masking[x,y+1] = black
                masking[x+1,y] = black

                masking[x-1,y] = black
                masking[x,y-1] = black
    '''
    for x in range(0,width):
        masking[x,0] = (0,0,0)
        masking[x,1] = (0,0,0)
        masking[x,2] = (0,0,0)
        masking[x,3] = (0,0,0)
        masking[x,716] = (0,0,0)
        masking[x,719] = (0,0,0)
        masking[x,718] = (0,0,0)
        masking[x,717] = (0,0,0)
    '''

    output.save(out_dir + filename)


from sourpea.primitives import *
from sourpea.util import *
import pandas as pd
import os
_dir=os.path.dirname(__file__)
_dir=os.path.dirname(__file__)
gqvtib = Factor("gqvtib", ["svwrfb", "qqg"])
cvtja = Factor("cvtja", ["dcsdm", "whgt"])
daifg = Factor("daifg", ["yso", "dfb"])
constraints = []
crossing = [[gqvtib, cvtja, daifg],]

design=[gqvtib,cvtja,daifg]
sequence_code_1=trials_from_csv(os.path.join(_dir,'out_code_1/1_3_0.csv'))
sequence_code_2=trials_from_csv(os.path.join(_dir,'out_code_2/1_3_0.csv'))
p_code_1 = 0
p_code_2 = 0
crossing = [gqvtib, cvtja, daifg]
block = Block(design, crossing, [])
p_code_1 += block.test(sequence_code_1)["pValue"] >= 1
p_code_2 += block.test(sequence_code_2)["pValue"] >= 1
crossing = []
block = Block(design, crossing, [])
p_code_1 += block.test(sequence_code_1)["pValue"] >= 1
p_code_2 += block.test(sequence_code_2)["pValue"] >= 1
df = pd.read_csv(os.path.join(_dir, "result_sour_2.csv"))
df.loc[len(df.index)] = [p_code_1, p_code_2]
df.to_csv(os.path.join(_dir, "result_sour_2.csv"), index=False)


#-*- coding: utf-8 -*-
"""
verdi command show
"""
import click

from aiida_verdi import arguments, options

@click.command()
@arguments.node()
@arguments.comment_id(required=False)
@options.user()
@options.dry_run()
@options.non_interactive()
def show(node, comment_id, user, dry_run, non_interactive):
    """
    Show the comments (with COMMENT_ID) of a NODE in the database.
    """
    from aiida_verdi.utils.aiidadb import ensure_aiida_dbenv
    ensure_aiida_dbenv()
    from aiida.backends.utils import get_automatic_user

    user = get_automatic_user()

    all_comments = node.get_comments(pk=comment_id)

    if user:
        to_print = [i for i in all_comments if i['user__email'] == user.email]
        if not to_print:
            click.echo("Nothing found for user '{}'.".format(user))
            click.echo(
                "Valid users found for Node {} are: {}.".format(node.pk,
                                                                ", ".join(set(
                                                                    ["'" + i['user__email'] + "'" for i in
                                                                     all_comments]))))
    else:
        to_print = all_comments

    if comment_id > 0:
        to_print = [i for i in to_print if i['pk'] == comment_id]

    for i in to_print:
        click.echo("*"*58)
        click.echo("Comment of '{}' on {}".format(i['user__email'],
                                                  i['ctime'].strftime("%Y-%m-%d %H:%M")))
        click.echo("ID: {}. Last modified on {}".format(i['pk'],
                                                        i['mtime'].strftime("%Y-%m-%d %H:%M")))
        click.echo("")
        click.echo("{}".format(i['content']))
        click.echo("")

    # If there is nothing to print, print a message
    if not to_print:
        click.echo("No comment found.")


import joblib
import numpy as np
import json
import sys
import os

# Determine the absolute path to the current script's directory
script_dir = os.path.dirname(os.path.abspath(__file__))

# Load the trained model and scaler using the absolute paths
model_path = os.path.join(script_dir, 'housemodel.joblib')
scaler_path = os.path.join(script_dir, 'scaler.joblib')

model = joblib.load(model_path)
scaler = joblib.load(scaler_path)

# Extract input from command line arguments
try:
    data = json.loads(sys.argv[1])
    input_data = data['input']
except (IndexError, KeyError, json.JSONDecodeError):
    print(json.dumps({'error': 'Invalid input format'}))
    sys.exit(1)

# Define the expected features and their ranges
expected_features = ['medInc', 'houseAge', 'aveRooms', 'aveBedrms', 'population',
                     'aveOccup', 'latitude', 'longitude']
feature_ranges = [(0, 10), (0, 50), (0, 10), (0, 5), (0, 5000), (0, 10), (33, 42),
                  (-124, -114)]

# Validate the input data
if len(input_data) != len(expected_features):
    print(json.dumps({'error': 'Invalid input data'}))
    sys.exit(1)

for i in range(len(input_data)):
    # Convert input_data[i] to float before comparison
    try:
        value = float(input_data[i])
    except ValueError:
        print(json.dumps({'error': f'Invalid value for {expected_features[i]}'}))
        sys.exit(1)

    if not feature_ranges[i][0] <= value <= feature_ranges[i][1]:
        print(json.dumps({'error': f'Invalid value for {expected_features[i]}'}))
        sys.exit(1)

# Convert the input data, reshape, scale, and predict
input_data = np.array([float(i) for i in input_data]).reshape(1, -1)
input_data = scaler.transform(input_data)
prediction = model.predict(input_data)

# Get the feature importances
importances = model.feature_importances_

# Create the response payload
response = {
    'prediction': prediction.tolist(),
    'importances': importances.tolist()
}

# Print the response as JSON
print(json.dumps(response))


import torch
import torch.nn as nn
import torch.nn.functional as F
import torchvision.models as models

### model1: Unet with based on pretrained resnet18

class decoder_Res18(nn.Module):
    def __init__(self, inC, MiddleC, outC):
        super(decoder_Res18, self).__init__()

        self.sequence = nn.Sequential(
            nn.Conv2d(inC, MiddleC, 3, padding=1),
            nn.ReLU(inplace=True),
            nn.BatchNorm2d(MiddleC),
            nn.ConvTranspose2d(MiddleC, outC, kernel_size=4, stride=2, padding=1),
            nn.ReLU(inplace=True),
            nn.BatchNorm2d(outC)
        )

    def forward(self, x):
        return self.sequence(x)

class Generator_resnet_unet(nn.Module):
    def __init__(self, input_nc, output_nc, pretrained=True, Dropout=0.3):

        super(Generator_resnet_unet, self).__init__()
        if pretrained:
            self.encoder = models.resnet18(pretrained=pretrained)
        else:
            print('please defined your own model here')

        # fix the parameters in resnet18
        # for param in self.encoder.parameters():
        #     param.requires_grad = False

        self.number_class = output_nc
        self.Dropout = Dropout
        self.relu = nn.ReLU(inplace=True)
        self.pool = nn.MaxPool2d(2, 2)
        self.dropout_2d = nn.Dropout2d(p=Dropout)
        self.conv1 = nn.Sequential(self.encoder.conv1,
                                   self.encoder.bn1,
                                   self.encoder.relu,
                                   self.pool
                                   )
        self.conv2 = self.encoder.layer1
        self.conv3 = self.encoder.layer2
        self.conv4 = self.encoder.layer3
        self.conv5 = self.encoder.layer4

        self.decov = decoder_Res18(512, 512, 256)
        self.decov5 = decoder_Res18(512 + 256, 512, 256)
        self.decov4 = decoder_Res18(256 + 256, 512, 256)
        self.decov3 = decoder_Res18(128 + 256, 256, 64)
        self.decov2 = decoder_Res18(64 + 64, 128, 128)
        self.decov1 = decoder_Res18(128, 128, 32)
        self.decov0 = nn.Sequential(
            nn.Conv2d(32, self.number_class, kernel_size=1)
        )

    def Pad_Same(self, x1, x2):
        diffY = torch.tensor([x2.size()[2] - x1.size()[2]])
        diffX = torch.tensor([x2.size()[3] - x1.size()[3]])

        x1 = F.pad(x1, [diffX // 2, diffX - diffX // 2,
                        diffY // 2, diffY - diffY // 2])
        x = torch.cat([x2, x1], dim=1)
        return x

    def forward(self, x):

        conv1 = self.conv1(x)
        conv2 = self.dropout_2d(self.conv2(conv1))
        conv3 = self.dropout_2d(self.conv3(conv2))
        conv4 = self.dropout_2d(self.conv4(conv3))
        conv5 = self.dropout_2d(self.conv5(conv4))

        mid = self.decov(self.pool(conv5))

        decov5 = self.decov5(self.Pad_Same(mid, conv5))
        decov4 = self.decov4(self.Pad_Same(decov5, conv4))
        decov3 = self.decov3(self.Pad_Same(decov4, conv3))
        decov2 = self.decov2(self.Pad_Same(decov3, conv2))
        decov1 = self.decov1(self.dropout_2d(decov2))

        output = self.decov0(decov1)

        return output

### model 2 resnet self defined
class ResidualBlock(nn.Module):
    def __init__(self, in_features):
        super(ResidualBlock, self).__init__()

        conv_block = [nn.ReflectionPad2d(1),
                      nn.Conv2d(in_features, in_features, 3),
                      nn.InstanceNorm2d(in_features),
                      nn.ReLU(inplace=True),
                      nn.ReflectionPad2d(1),
                      nn.Conv2d(in_features, in_features, 3),
                      nn.InstanceNorm2d(in_features)]

        self.conv_block = nn.Sequential(*conv_block)

    def forward(self, x):
        return x + self.conv_block(x)

class Generator_resnet(nn.Module):
    def __init__(self, input_nc, output_nc, n_residual_blocks=9):
        super(Generator_resnet, self).__init__()

        # Initial convolution block
        model = [nn.ReflectionPad2d(3),
                 nn.Conv2d(input_nc, 64, 7),
                 nn.InstanceNorm2d(64),
                 nn.ReLU(inplace=True)]

        # Downsampling
        in_features = 64
        out_features = in_features * 2
        for _ in range(2):
            model += [nn.Conv2d(in_features, out_features, 3, stride=2, padding=1),
                      nn.InstanceNorm2d(out_features),
                      nn.ReLU(inplace=True)]
            in_features = out_features
            out_features = in_features * 2

        # Residual blocks
        for _ in range(n_residual_blocks):
            model += [ResidualBlock(in_features)]

        # Upsampling
        out_features = in_features // 2
        for _ in range(2):
            model += [nn.ConvTranspose2d(in_features, out_features, 3, stride=2, padding=1, output_padding=1),
                      nn.InstanceNorm2d(out_features),
                      nn.ReLU(inplace=True)]
            in_features = out_features
            out_features = in_features // 2

        # Output layer
        model += [nn.ReflectionPad2d(3),
                  nn.Conv2d(64, output_nc, 7),
                  nn.Tanh()]

        self.model = nn.Sequential(*model)

    def forward(self, x):
        return self.model(x)

class Discriminator(nn.Module):
    def __init__(self, input_nc):
        super(Discriminator, self).__init__()

        # A bunch of convolutions one after another
        model = [nn.Conv2d(input_nc, 64, 4, stride=2, padding=1),
                 nn.LeakyReLU(0.2, inplace=True)]

        model += [nn.Conv2d(64, 128, 4, stride=2, padding=1),
                  nn.InstanceNorm2d(128),
                  nn.LeakyReLU(0.2, inplace=True)]

        model += [nn.Conv2d(128, 256, 4, stride=2, padding=1),
                  nn.InstanceNorm2d(256),
                  nn.LeakyReLU(0.2, inplace=True)]

        model += [nn.Conv2d(256, 512, 4, padding=1),
                  nn.InstanceNorm2d(512),
                  nn.LeakyReLU(0.2, inplace=True)]

        # FCN classification layer
        model += [nn.Conv2d(512, 1, 4, padding=1)]

        self.model = nn.Sequential(*model)

    def forward(self, x):
        x = self.model(x)
        # Average pooling and flatten
        return F.avg_pool2d(x, x.size()[2:]).view(x.size()[0], -1)


#!/bin/python3

import math
import os
import random
import re
import sys

# Complete the minimumSwaps function below.

def minimumSwaps(arr):
    cnt = 0
    min_idx = 0

    for i in range(len(arr)):
        min_idx = i
        for j in range(i + 1, len(arr)):
            if arr[min_idx] > arr[j]:
                min_idx = j

        arr[i], arr[min_idx] = arr[min_idx], arr[i]
        cnt += 1

    return cnt

if __name__ == '__main__':

    n = int(input())

    arr = list(map(int, input().rstrip().split()))

    res = minimumSwaps(arr)

    print(res)


"""
Programming Practice: Adding Numbers
Somayeh is in second grade at elementary school and is
just starting to learn the numbers. The teacher puts a
number on the board and the students have to count the numbers.
To make things easier, the numbers that need to be added are
just one, two, and three. But that's not enough, and the
student can only do the sum when the numbers are arranged in
descending order (ie, first one, then two, and then three).
And at the output of the phrase that was explained so Somayeh
and the other students could calculate it.
Sample input:
1 + 1 + 3 + 1 + 3
Sample output:
1 + 1 + 1 + 3 + 3
"""

array_number = input()
str_fin = []
list_number = []

array_number = array_number.replace('+', '')
array_number = list(array_number)

for i in range(0, len(array_number)):
    array_number[i] = int(array_number[i])

array_number.sort()
fin_list = [str(i) for i in array_number]

for i in range(0,len(fin_list)):
    str_fin.append(fin_list[i])
    str_fin.append('+')
separator = ''
print(separator.join(str_fin[:len(str_fin)-1]))


import sqlite3
import os

root = os.path.dirname(__file__)
conn = sqlite3.connect(root + '/db/smarthome.db')

c = conn.cursor()
c.execute('CREATE TABLE IF NOT EXISTS sensors (id INTEGER PRIMARY KEY AUTOINCREMENT, sensor1 real, sensor2_value_t real, sensor2_value_h real, datetime string )')

class Sensors():
    def getLast(self):
        c.execute('SELECT round(sensor1, 2), round(sensor2_value_t, 2), round(sensor2_value_h, 2)  FROM sensors ORDER BY id DESC LIMIT 1')
        return c.fetchone()

    def getDay(self):
      sql =  "select "
      sql += "substr(datetime,12,4) || '0' as date, "
      sql += "round(min(sensor1), 2) as sensor1, "
      sql += "round(min(sensor2_value_t), 2) as sensor2_value_t "
      sql += "from sensors "
      sql += "where id in ( select id from sensors order by id desc limit 1440 ) "
      sql += "group by substr(datetime,1,15) || '0' "
      c.execute(sql)
      return c.fetchall()

    def InsertData(self, sensor1, sensor2_value_t, sensor2_value_h, datetime):
        c.execute("INSERT INTO sensors (sensor1, sensor2_value_t, sensor2_value_h, datetime)  VALUES ("+str(sensor1)+","+str(sensor2_value_t)+","+str(sensor2_value_h)+",'"+datetime+"')")
        conn.commit()

'''
from peewee import *

db = SqliteDatabase('/root/weatherstation/sensors.db')

class Sensors(Model):
    id = PrimaryKeyField()
    sensor1 = FloatField()
    datetime = DateTimeField()

    class Meta:
        database = db

    def getLast(self):
        return Sensors.select(Sensors.sensor1).order_by(Sensors.id.desc()).limit(1).get()

    def getDay(self):
        res= Sensors.select(
            fn.Substr(Sensors.datetime, 12, 4).concat('0').alias('date'),
            fn.round(fn.avg(Sensors.sensor1), 2).alias('sensor1')
            ).group_by('date').get()
        return [r[0] for r in res.fetchall()]

#        return Sensors.select(
#            fn.Substr(Sensors.datetime, 12, 4).concat('0').alias('date'),
#            fn.round(fn.avg(Sensors.sensor1), 2).alias('sensor1')
#            ).where(id in Sensors.select(Sensors.id).order_by(Sensors.id).desc().limit(1440).get()  ).group_by('date').get()

# Sensors.create_table()
# Sensors.insert(sensor1=10.5, datetime = datetime.today()).execute()
# print Sensors().getLast().sensor1
#print Sensors().getDay()

if __name__ == "__main__":
    try:
        print 'xxxxxxxxxxxxxxxxx'
        Sensors.create_table()
    except peewee.OperationalError:
        print "sensors table already exists!"

'''


# 20. Valid Parentheses
# Given a string containing just the characters '(', ')', '{', '}', '[' and ']', determine if the input string is valid.
# An input string is valid if:
# Open brackets must be closed by the same type of brackets.
# Open brackets must be closed in the correct order.
# Note that an empty string is also considered valid.
from utils import timing

class Solution:
    def isValid(self, s: str) -> bool:
        CLOSE_TO_OPEN = {
            ")": "(",
            "]": "[",
            "}": "{",
        }

        stack = []

        for c in s:
            if c in CLOSE_TO_OPEN.values():
                stack.append(c)
            elif c in CLOSE_TO_OPEN.keys():
                if not stack or stack.pop() != CLOSE_TO_OPEN[c]:
                    return False
            else:
                raise Exception("Invalid input")

        # After exhausting the input, return True only if the stack is empty
        return not bool(stack)

try:
    import pytest

    @pytest.mark.parametrize(
        ("s", "expected"),
        [
            ("()", True),
            ("()[]{}", True),
            ("(]", False),
            ("([)]", False),
            ("{[]}", True),
        ],
    )
    def testIsValid(s: str, expected: bool) -> None:
        with timing(f"test"):
            assert Solution().isValid(s) == expected

except ModuleNotFoundError:
    pass


# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.test import TestCase
from django.urls import reverse
from unittest import skip
from rest_framework import status
from mailservice.models import *

class MailHistoryApiTest(TestCase):
    def test_get_mail(self):
        url = reverse('mail')
        response = self.client.get(url, format='json')
        self.assertEqual(response.status_code, status.HTTP_200_OK)

    def test_get_mail_with_filter(self):
        url = reverse('mail')
        response = self.client.get(url, {'subject': 'hello'}, format='json')
        self.assertEqual(response.status_code, status.HTTP_200_OK)

class MailSendingApiTest(TestCase):
    def test_create_account_null_body(self):
        url = reverse('mail')
        data = {}
        response = self.client.post(url, data, format='json')
        self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)

    def test_create_account_invalid_email(self):
        url = reverse('mail')
        data = {
            "from_mail": "sender",
            "to_mail": "receiver"
        }
        response = self.client.post(url, data, format='json')
        self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)

    @skip("TODO: mock mail provider")
    def test_create_account_valid_body(self):
        url = reverse('mail')
        data = {
            "from_mail": "sender@mail.com",
            "to_mail": "receiver@mail.com"
        }
        response = self.client.post(url, data, format='json')
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(Mail.objects.count(), 1)


import sys
sys.path.append("/home/ccjh/demo_git/sele_po_demo")
import unittest, time, HTMLTestRunner
from config.parameter import test_case_path, report_name
from src.common import send_mail

suite = unittest.defaultTestLoader.discover(start_dir = test_case_path, pattern='test*.py')

if __name__ =="__main__":
    report = report_name+"Report.html"
    fb = open(report, 'wb')
    runner = HTMLTestRunner.HTMLTestRunner(
        stream = fb,
        title = "test",
        description = "u know"
    )
    runner.run(suite)
    fb.close()
    time.sleep(10)
    email = send_mail.send_mail()
    email.sendReport()


import gcj

def paths_from(mx, i):
	pf = 0
	B = len(mx)

	if i == B - 1:
		return 0

	for j in range(i + 1, B):
		if j == B - 1 and mx[i][j]:
			pf += 1
		elif mx[i][j]:
			pf += paths_from(mx, j)

	#print("pf " + str(i) + " = " + str(pf))
	return pf

def check(mx, M):
	pf = paths_from(mx, 0)
	#rint(mx, M, pf)
	return pf == M

ifile, ofile = gcj.get_files('B')

T = int(ifile.readline().strip())
for t in range(T):
	B, M = map(int, ifile.readline().strip().split(' '))

	paths = []
	for i in range(0, B - 1):
		for  j in range(i + 1, B):
			paths.append([i,j])

	L = len(paths)
	ans = "IMPOSSIBLE"
	for X in range(1 << L):
		mx = [[0] * B for b in range(B)]
		for l in range(L):
			if (X >> l) & 1:
				mx[paths[l][0]][paths[l][1]] = 1

			#print("---")
			if check(mx, M):
				ans = "POSSIBLE"
				for i in range(B):
					ans += "\n" + ''.join(list(map(str, mx[i])))
				break

	gcj.print_answer(ofile, t, ans)


from keras.applications.vgg16 import VGG16, preprocess_input
# from keras.applications.vgg19 import VGG19, preprocess_input
from keras.applications.xception import Xception, preprocess_input
# from keras.applications.resnet50 import ResNet50, preprocess_input
from keras.applications.inception_v3 import InceptionV3, preprocess_input
from keras import applications
from keras.preprocessing import image
from keras.models import Model
from keras.models import model_from_json
import logging
# other imports
from sklearn.preprocessing import LabelEncoder
import numpy as np
import glob
import h5py
import os
import json
import pickle as cPickle
import datetime
import time

from sklearn.metrics import accuracy_score
# organize imports
from sklearn.metrics import classification_report
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import confusion_matrix

logging.basicConfig(level=logging.DEBUG)

logger.debug("Load Config file")

with open('conf/config.json') as f:
	config=json.load(f)

logger.debug("Load Model parameters")
img_width, img_height = config["size"],config["size"]
train_data_dir = config["test"]
validation_data_dir = config["val"]
batch_size = config["batch_size"]
epochs = config["epochs"]
vgg_output=config["vgg"]
inception_output=config["inception"]
xception_output=config["xception"]

# Load moedels
logger.debug("Load VGG Model")
model_vgg = applications.VGG16(weights='imagenet',include_top=False, input_shape = (img_width, img_height, 3))
logger.debug("Load Inception Model")
model_inception = applications.InceptionV3(weights='imagenet',include_top=False, input_shape = (img_width, img_height, 3))
logger.debug("Load Xception Model")
model_xception =applications.Xception(weights='imagenet',include_top=False, input_shape = (img_width, img_height, 3))

# Define Feature extractor
logger.debug("Define Feature extractors")
feat_ext_vgg=Model(input=model_vgg.input, output=model_vgg.get_layer(vgg_output).output)
feat_ext_inception=Model(input=model_inception.input, output=model_inception.get_layer(inception_output).output)
feat_ext_xception=Model(input=model_xception.input, output=model_xception.get_layer(xception_output).output)

if os.path.isdir(train_data_dir) :
	# path to training dataset
	logger.debug("Load Training Dataset")
	train_labels = os.listdir()
else:
	logger.debug("Training Directory not found")
	raise FileNotFoundError('Training Directory not found')

# variables to hold inception features and labels
inception_features = []
inception_test_features = []

# variables to hold vgg features and labels
vgg_features = []
vgg_test_features = []

# variables to hold vgg features and labels
sq_features = []
sq_test_features = []

labels   = []
test_labels =[]

image_size=(img_width, img_height)
# loop over all the labels in the folder
logger.debug("Loop over all the labels in the train folder")
for label in train_labels:
	cur_path = train_data_dir + "/" + label
	print(cur_path)
	for image_path in glob.glob(cur_path + "/*.jpg"):
		img = image.load_img(image_path, target_size=image_size)
		x = image.img_to_array(img)
		x = np.expand_dims(x, axis=0)
		x = preprocess_input(x)
		feature = feat_ext_inception.predict(x)
		flat = feature.flatten()
		inception_features.append(flat)
		feature = feat_ext_vgg.predict(x)
		flat = feature.flatten()
		vgg_features.append(flat)
		feature = feat_ext_xception.predict(x)
		flat = feature.flatten()
		x_features.append(flat)
		labels.append(label)

# loop over all the labels in the folder
logger.debug("Loop over all the labels in the validation folder")
for label in train_labels:
	cur_path = validation_data_dir + "/" + label
	for image_path in glob.glob(cur_path + "/*.jpg"):
		img = image.load_img(image_path, target_size=image_size)
		x = image.img_to_array(img)
		x = np.expand_dims(x, axis=0)
		x = preprocess_input(x)
		feature = feat_ext_inception.predict(x)
		flat = feature.flatten()
		inception_test_features.append(flat)
		feature = feat_ext_vgg.predict(x)
		flat = feature.flatten()
		vgg_test_features.append(flat)
		feature = feat_ext_xception.predict(x)
		flat = feature.flatten()
		x_test_features.append(flat)
		test_labels.append(label)

# encode the labels using LabelEncoder
logger.debug("Encode the labels using LabelEncoder")
targetNames = np.unique(labels)
le = LabelEncoder()
le_labels = le.fit_transform(labels)
test_labels=le.transform(test_labels)

logger.debug("Concatenate Features ")
features = np.concatenate( [np.asarray(vgg_features), np.asarray(inception_features), np.asarray(x_features)], axis=1 )
test_features = np.concatenate( [np.asarray(vgg_test_features), np.asarray(inception_test_features),np.asarray(x_test_features)], axis=1)
seed=config["seed"]

# use logistic regression as the model
print("[INFO] creating Logistic Regression...")
logger.debug("Creating Logistic Regression ")
clf = LogisticRegression(random_state=seed)
clf.fit(features, le_labels)
# evaluate the model of test data
logger.debug("Evaluate the model of test data")
preds = clf.predict(test_features)
print(classification_report(le.inverse_transform(preds),le.inverse_transform(test_labels)))
print("Accuracy :",accuracy_score(le.inverse_transform(preds),le.inverse_transform(test_labels)))
logger.debug(classification_report(le.inverse_transform(preds),le.inverse_transform(test_labels)))
logger.debug("Accuracy :",accuracy_score(le.inverse_transform(preds),le.inverse_transform(test_labels)))

# Xgboost
import xgboost as xgb

# Prepare the inputs for the model
train_X = np.asmatrix(features)
test_X = np.asmatrix(test_features)
#train_y = train_df['Survived']

# You can experiment with many other options here, using the same .fit() and .predict()
# methods; see http://scikit-learn.org
# This example uses the current build of XGBoost, from https://github.com/dmlc/xgboost
print("[INFO] creating XGBoost...")
logger.debug("Creating XGBoost")
gbm = xgb.XGBClassifier(max_depth=3, n_estimators=300, learning_rate=0.05).fit(train_X, le_labels)
preds = gbm.predict(test_X)

print(classification_report(le.inverse_transform(preds),le.inverse_transform(test_labels)))
print("Accuracy :",accuracy_score(le.inverse_transform(preds),le.inverse_transform(test_labels)))
logger.debug(classification_report(le.inverse_transform(preds),le.inverse_transform(test_labels)))
logger.debug("Accuracy :",accuracy_score(le.inverse_transform(preds),le.inverse_transform(test_labels)))

if config["pca"]:
	# Apply PCA
	logger.debug("Apply PCA")
	from sklearn.decomposition import PCA
	logger.debug("Concatenate Test and Train feature set")
	X=np.concatenate( [features,test_features], axis=0 )
	logger.debug("Create PCA with {} of principal components".format(config["n_components"]))
	pca = PCA(n_components=config["n_components"])
	pca.fit(X)

	train_x = pca.transform(features)
	test_x = pca.transform(test_features)

	# Apply Logistic Regression with PCA
	print("[INFO] creating Logistic Regression with PCA...")
	logger.debug("Creating Logistic Regression with PCA")
	clf = LogisticRegression(random_state=seed)
	clf.fit(train_x, le_labels)

	# evaluate the model of test data
	preds = clf.predict(test_x)
	print(classification_report(le.inverse_transform(preds),le.inverse_transform(test_labels)))
	print("Accuracy :",accuracy_score(le.inverse_transform(preds),le.inverse_transform(test_labels)))
	logger.debug(classification_report(le.inverse_transform(preds),le.inverse_transform(test_labels)))
	logger.debug("Accuracy :",accuracy_score(le.inverse_transform(preds),le.inverse_transform(test_labels)))
	# Apply Xgboost with PCA
	# Prepare the inputs for the model
	train_X = np.asmatrix(train_x)
	test_X = np.asmatrix(test_x)

	# You can experiment with many other options here, using the same .fit() and .predict()
	# methods; see http://scikit-learn.org
	# This example uses the current build of XGBoost, from https://github.com/dmlc/xgboost
	print("[INFO] creating XGBoost with PCA...")
	logger.debug("Creating XGBoost with PCA")
	gbm = xgb.XGBClassifier(max_depth=config["xgb_max_dept"], n_estimators=config["xgb_n_estimator"], \
					learning_rate=config["xgb_learning_rate"]).fit(train_X, le_labels)
	preds = gbm.predict(test_X)

	print(classification_report(le.inverse_transform(preds),le.inverse_transform(test_labels)))
	print("Accuracy :",accuracy_score(le.inverse_transform(preds),le.inverse_transform(test_labels)))
	logger.debug(classification_report(le.inverse_transform(preds),le.inverse_transform(test_labels)))
	logger.debug("Accuracy :",accuracy_score(le.inverse_transform(preds),le.inverse_transform(test_labels)))


import json
from builtins import object

from django.contrib.auth.decorators import login_required
from django.http import HttpResponse
from django.shortcuts import render, redirect

# Create your views here.
from django.utils import timezone

from Course.models import Course, CourseWork, Quiz
from main.models import MyCourse, MyQuiz, MyQuizDetail

@login_required
def index(request):
    # print('Hy')
    # return HttpResponse("This sad be landing page.")
    test = ['1', 2,"three"]

    return render(request, 'index.html', {
        'foo': test,
    })

def CourseSelected(request, courseId=0):
    resp = {}
    resp["course"] = Course.objects.get(pk= courseId)
    resp["mineCourse"] = MyCourse.objects.filter(course__course_id=resp["course"].course_id , user=request.user).first()

    if resp["mineCourse"] is None:
        resp["mineCourse"] = MyCourse(user=request.user, course=resp["course"])
        resp["mineCourse"].save()

    if resp["mineCourse"].current_course_work is None:
        if (resp["course"].coursework_set.count() == 0):
            return render(request, 'extra/error.html', {
                'error_heading': 'No Course Work',
                'error_message': 'There is no course work for ' + resp["course"].__str__()
            })

        courseWork = resp["course"].coursework_set.all()
        resp["mineCourse"].current_course_work = courseWork.first()
        resp["mineCourse"].save()

    if resp["mineCourse"].percentage==100:
        return  redirect('home')

    resp["activeCourseWork"] = resp["mineCourse"].current_course_work
    resp["courseWorkList"] = resp["course"].coursework_set.all()
    if resp["activeCourseWork"].work_type==CourseWork.LECTURE:
        return render(request, 'course/lecture.html', resp)
    else:
        return HandleQuiz(request, resp["activeCourseWork"])

def NextCourseWork(request, CourseId, CurrentCourseWorkId):
    course = Course.objects.get(pk=CourseId)
    mineCourse = MyCourse.objects.filter(course__course_id=course.course_id, user=request.user)
    if mineCourse.count() == 0:
        mineCourse = MyCourse(user=request.user, course=course)
        mineCourse.save()
    else:
        mineCourse = mineCourse.first()

    courseWorkList = course.coursework_set.all()

    nextCourseWorks = []
    for courseWork in courseWorkList:
        if(courseWork.pk  > CurrentCourseWorkId):
            nextCourseWorks.append(courseWork)
    if nextCourseWorks.__len__() == 0:
        mineCourse.percentage = 100
        mineCourse.course_completed = True
    else:
        mineCourse.percentage = (1.00 - (nextCourseWorks.__len__() / courseWorkList.count()))*100
        nextCourseWork = nextCourseWorks[nextCourseWorks.__len__() - 1]
        mineCourse.current_course_work = nextCourseWork

    mineCourse.save()

    if mineCourse.percentage==100:
        return  redirect('home')

    activeCourseWork = mineCourse.current_course_work
    # courseWorkList = course.coursework_set.all()
    nextURL = ''
    # if  is None:
    if activeCourseWork.work_type == CourseWork.LECTURE:
        return render(request, 'course/lecture.html', {
            'activeCourseWork': activeCourseWork,
            'course': course,
            'courseWorkList': courseWorkList,
            'nextURL': nextURL,
            'mineCourse': mineCourse,
        })
    else:
        return HandleQuiz(request, activeCourseWork)
    # return  HttpResponse('
Pending work
')

def HandleQuiz(request, activeCourseWork):
    # quizDetails = activeCourseWork.quiz_set

    mineQuiz = MyQuiz.objects.filter(course_work=activeCourseWork, user=request.user, is_finish=False).first()
    if mineQuiz is None:
        mineQuiz = MyQuiz()
        mineQuiz.course_work  = activeCourseWork
        mineQuiz.user = request.user
        mineQuiz.start_time = timezone.now()
        mineQuiz.is_finish = False
        mineQuiz.save()
    total_questions = json.loads(activeCourseWork.data)['total_questions']
    question_number = 1
    quizQuestion = Quiz.objects.filter(CourseWork=activeCourseWork, question_number=question_number).first()
    question = quizQuestion.quiz_question
    pk = quizQuestion.pk
    options = json.loads(quizQuestion.quiz_options)

    return render(request, 'course/quiz.html', {
        'mineQuiz':mineQuiz,
        'quizQuestion':quizQuestion,
        'question':question,
        'pk':pk,
        'myQuizPk':mineQuiz.pk,
        'activeCourseWork': activeCourseWork,
        'total_questions': total_questions,
        'question_number': question_number,
        'course': activeCourseWork.course,
        'options':options
    })

def SubmitQuizAnswer(request):
    mineQuiz = MyQuiz.objects.get(pk=request.POST.get('myQuizPk'))
    quizQuestion = Quiz.objects.get(pk=request.POST.get('pk'))
    activeCourseWork = quizQuestion.CourseWork
    total_questions = json.loads(activeCourseWork.data)['total_questions']
    quizDetail = MyQuizDetail()
    quizDetail.myQuiz = mineQuiz
    quizDetail.selected_option = request.POST.get('quizanswer')
    quizDetail.right_option = quizQuestion.right_option
    quizDetail.is_right = quizDetail.selected_option==quizDetail.right_option
    quizDetail.save()
    question_number = quizQuestion.question_number + 1
    if question_number>total_questions:
        return  QuizFinished(request, mineQuiz, activeCourseWork)
    quizQuestion = Quiz.objects.filter(CourseWork=activeCourseWork, question_number=question_number).first()
    question = quizQuestion.quiz_question
    pk = quizQuestion.pk
    options = json.loads(quizQuestion.quiz_options)
    return render(request, 'course/quiz.html', {
        'mineQuiz':mineQuiz,
        'quizQuestion':quizQuestion,
        'question':question,
        'pk':pk,
        'myQuizPk':mineQuiz.pk,
        'activeCourseWork': activeCourseWork,
        'total_questions': total_questions,
        'question_number': question_number,
        'course': activeCourseWork.course,
        'options':options})

def QuizFinished(request, myQuiz, activeCourseWork):
    UpdateQuizMarks(myQuiz)
    course = activeCourseWork.course
    mineCourse = MyCourse.objects.filter(course__course_id=course.course_id, user=request.user)
    if mineCourse.count() == 0:
        mineCourse = MyCourse(user=request.user, course=course)
        mineCourse.save()
    else:
        mineCourse = mineCourse.first()
    courseWorkList = course.coursework_set.all()

    nextCourseWorks = []
    for courseWork in courseWorkList:
        if (courseWork.pk > activeCourseWork.pk):
            nextCourseWorks.append(courseWork)
    if nextCourseWorks.__len__() == 0:
        mineCourse.percentage = 100
        mineCourse.course_completed = True
    else:
        mineCourse.percentage = (1.00 - (nextCourseWorks.__len__() / courseWorkList.count())) * 100
        nextCourseWork = nextCourseWorks[nextCourseWorks.__len__() - 1]
        mineCourse.current_course_work = nextCourseWork

    mineCourse.save()

    if mineCourse.percentage==100:
        return redirect('Index')

    activeCourseWork = mineCourse.current_course_work
    nextURL = ''
    # if  is None:
    if activeCourseWork.work_type == CourseWork.LECTURE:
        return render(request, 'course/lecture.html', {
            'activeCourseWork': activeCourseWork,
            'course': course,
            'courseWorkList': courseWorkList,
            'nextURL': nextURL,
            'mineCourse': mineCourse,
        })
    else:
        return HandleQuiz(request, activeCourseWork)

def UpdateQuizMarks(myQuiz):
    quizDetails = MyQuizDetail.objects.filter(myQuiz=myQuiz).all()
    totalMarks = 0
    for quizDetail in quizDetails:
        if quizDetail.is_right:
            totalMarks = totalMarks + 1

    myQuiz.obtained_marks = totalMarks
    myQuiz.total_marks = quizDetails.count()
    myQuiz.is_finish = True
    myQuiz.save()


#Write a program to compute the number of chracters, words and lines in a file.

#For Chracters:
a=open("exp1.txt","r")
b=a.read()
c=0
for i in b:
    c=c+1
print(c)
a.close()

#For finding numbers of words:
d=open("exp1.txt","r")
e=d.read()
f=1
for i in e:
    if i==" ":
        f=f+1
print(f)
d.close()

#For finding numbers of lines:
g=open("exp1.txt","r")
h=g.read()
j=1
for i in h:
    if i=="\n":
     j=j+1
print(j)
g.close()


def solve():
	l, x = (int(x) for x in input().split())
	s = input() * x
	sgn = 1
	tr = {'1': 0, 'i': 1, 'j': 2, 'k': 3}
	mult = [[0, 1, 2, 3],
	        [1, 0, 3, 2],
	        [2, 3, 0, 1],
	        [3, 2, 1, 0]]
	sign = [[1, 1, 1, 1],
	        [1, -1, 1, -1],
	        [1, -1, -1, 1],
	        [1, 1, -1, -1]]
	sgn = 1
	val = 0
	for i in range(l * x):
		c = tr[s[i]]
		sgn *= sign[val][c]
		val = mult[val][c]
		if sgn == 1 and val == 1:
			break
	else:
		return 'NO'
	sgn = 1
	val = 0
	for i in range(i + 1, l * x):
		c = tr[s[i]]
		sgn *= sign[val][c]
		val = mult[val][c]
		if sgn == 1 and val == 2:
			break
	else:
		return 'NO'
	sgn = 1
	val = 0
	for i in range(i + 1, l * x):
		c = tr[s[i]]
		sgn *= sign[val][c]
		val = mult[val][c]
	if sgn == 1 and val == 3:
		return 'YES'
	return 'NO'

n = int(input())
for t in range(n):
	print("Case #{}: {}".format(t + 1, solve()))