import math

import torch

from ocpmodels.modules.scaling import ScaleFactor

from .atom_update_block import AtomUpdateBlock
from .base_layers import Dense, ResidualLayer
from .efficient import EfficientInteractionBilinear
from .embedding_block import EdgeEmbedding

class InteractionBlock(torch.nn.Module):
    """
    Interaction block for GemNet-Q/dQ.

    Arguments
    ---------
    emb_size_atom: int
        Embedding size of the atoms.
    emb_size_edge: int
        Embedding size of the edges.
    emb_size_trip_in: int
        (Down-projected) embedding size of the quadruplet edge embeddings
        before the bilinear layer.
    emb_size_trip_out: int
        (Down-projected) embedding size of the quadruplet edge embeddings
        after the bilinear layer.
    emb_size_quad_in: int
        (Down-projected) embedding size of the quadruplet edge embeddings
        before the bilinear layer.
    emb_size_quad_out: int
        (Down-projected) embedding size of the quadruplet edge embeddings
        after the bilinear layer.
    emb_size_a2a_in: int
        Embedding size in the atom interaction before the bilinear layer.
    emb_size_a2a_out: int
        Embedding size in the atom interaction after the bilinear layer.
    emb_size_rbf: int
        Embedding size of the radial basis transformation.
    emb_size_cbf: int
        Embedding size of the circular basis transformation (one angle).
    emb_size_sbf: int
        Embedding size of the spherical basis transformation (two angles).
    num_before_skip: int
        Number of residual blocks before the first skip connection.
    num_after_skip: int
        Number of residual blocks after the first skip connection.
    num_concat: int
        Number of residual blocks after the concatenation.
    num_atom: int
        Number of residual blocks in the atom embedding blocks.
    num_atom_emb_layers: int
        Number of residual blocks for transforming atom embeddings.
    quad_interaction: bool
        Whether to use quadruplet interactions.
    atom_edge_interaction: bool
        Whether to use atom-to-edge interactions.
    edge_atom_interaction: bool
        Whether to use edge-to-atom interactions.
    atom_interaction: bool
        Whether to use atom-to-atom interactions.
    activation: str
        Name of the activation function to use in the dense layers.
    """

    def __init__(
        self,
        emb_size_atom: int,
        emb_size_edge: int,
        emb_size_trip_in: int,
        emb_size_trip_out: int,
        emb_size_quad_in: int,
        emb_size_quad_out: int,
        emb_size_a2a_in: int,
        emb_size_a2a_out: int,
        emb_size_rbf: int,
        emb_size_cbf: int,
        emb_size_sbf: int,
        num_before_skip: int,
        num_after_skip: int,
        num_concat: int,
        num_atom: int,
        num_atom_emb_layers: int = 0,
        quad_interaction: bool = False,
        atom_edge_interaction: bool = False,
        edge_atom_interaction: bool = False,
        atom_interaction: bool = False,
        activation=None,
    ) -> None:
        super().__init__()

        ## ------------------------ Message Passing ----------------------- ##
        # Dense transformation of skip connection
        self.dense_ca = Dense(
            emb_size_edge,
            emb_size_edge,
            activation=activation,
            bias=False,
        )

        # Triplet Interaction
        self.trip_interaction = TripletInteraction(
            emb_size_in=emb_size_edge,
            emb_size_out=emb_size_edge,
            emb_size_trip_in=emb_size_trip_in,
            emb_size_trip_out=emb_size_trip_out,
            emb_size_rbf=emb_size_rbf,
            emb_size_cbf=emb_size_cbf,
            symmetric_mp=True,
            swap_output=True,
            activation=activation,
        )

        # Quadruplet Interaction
        if quad_interaction:
            self.quad_interaction = QuadrupletInteraction(
                emb_size_edge=emb_size_edge,
                emb_size_quad_in=emb_size_quad_in,
                emb_size_quad_out=emb_size_quad_out,
                emb_size_rbf=emb_size_rbf,
                emb_size_cbf=emb_size_cbf,
                emb_size_sbf=emb_size_sbf,
                symmetric_mp=True,
                activation=activation,
            )
        else:
            self.quad_interaction = None

        if atom_edge_interaction:
            self.atom_edge_interaction = TripletInteraction(
                emb_size_in=emb_size_atom,
                emb_size_out=emb_size_edge,
                emb_size_trip_in=emb_size_trip_in,
                emb_size_trip_out=emb_size_trip_out,
                emb_size_rbf=emb_size_rbf,
                emb_size_cbf=emb_size_cbf,
                symmetric_mp=True,
                swap_output=True,
                activation=activation,
            )
        else:
            self.atom_edge_interaction = None
        if edge_atom_interaction:
            self.edge_atom_interaction = TripletInteraction(
                emb_size_in=emb_size_edge,
                emb_size_out=emb_size_atom,
                emb_size_trip_in=emb_size_trip_in,
                emb_size_trip_out=emb_size_trip_out,
                emb_size_rbf=emb_size_rbf,
                emb_size_cbf=emb_size_cbf,
                symmetric_mp=False,
                swap_output=False,
                activation=activation,
            )
        else:
            self.edge_atom_interaction = None
        if atom_interaction:
            self.atom_interaction = PairInteraction(
                emb_size_atom=emb_size_atom,
                emb_size_pair_in=emb_size_a2a_in,
                emb_size_pair_out=emb_size_a2a_out,
                emb_size_rbf=emb_size_rbf,
                activation=activation,
            )
        else:
            self.atom_interaction = None

        ## -------------------- Update Edge Embeddings -------------------- ##
        # Residual layers before skip connection
        self.layers_before_skip = torch.nn.ModuleList(
            [
                ResidualLayer(
                    emb_size_edge,
                    activation=activation,
                )
                for i in range(num_before_skip)
            ]
        )

        # Residual layers after skip connection
        self.layers_after_skip = torch.nn.ModuleList(
            [
                ResidualLayer(
                    emb_size_edge,
                    activation=activation,
                )
                for i in range(num_after_skip)
            ]
        )

        ## -------------------- Update Atom Embeddings -------------------- ##
        self.atom_emb_layers = torch.nn.ModuleList(
            [
                ResidualLayer(
                    emb_size_atom,
                    activation=activation,
                )
                for _ in range(num_atom_emb_layers)
            ]
        )

        self.atom_update = AtomUpdateBlock(
            emb_size_atom=emb_size_atom,
            emb_size_edge=emb_size_edge,
            emb_size_rbf=emb_size_rbf,
            nHidden=num_atom,
            activation=activation,
        )

        ## ---------- Update Edge Embeddings with Atom Embeddings --------- ##
        self.concat_layer = EdgeEmbedding(
            emb_size_atom,
            emb_size_edge,
            emb_size_edge,
            activation=activation,
        )
        self.residual_m = torch.nn.ModuleList(
            [
                ResidualLayer(emb_size_edge, activation=activation)
                for _ in range(num_concat)
            ]
        )

        self.inv_sqrt_2 = 1 / math.sqrt(2.0)
        num_eint = 2.0 + quad_interaction + atom_edge_interaction
        self.inv_sqrt_num_eint = 1 / math.sqrt(num_eint)
        num_aint = 1.0 + edge_atom_interaction + atom_interaction
        self.inv_sqrt_num_aint = 1 / math.sqrt(num_aint)

    def forward(
        self,
        h,
        m,
        bases_qint,
        bases_e2e,
        bases_a2e,
        bases_e2a,
        basis_a2a_rad,
        basis_atom_update,
        edge_index_main,
        a2ee2a_graph,
        a2a_graph,
        id_swap,
        trip_idx_e2e,
        trip_idx_a2e,
        trip_idx_e2a,
        quad_idx,
    ):
        """
        Returns
        -------
        h: torch.Tensor, shape=(nEdges, emb_size_atom)
            Atom embeddings.
        m: torch.Tensor, shape=(nEdges, emb_size_edge)
            Edge embeddings (c->a).
        """
        num_atoms = h.shape[0]

        # Initial transformation
        x_ca_skip = self.dense_ca(m)  # (nEdges, emb_size_edge)

        x_e2e = self.trip_interaction(
            m,
            bases_e2e,
            trip_idx_e2e,
            id_swap,
        )
        if self.quad_interaction is not None:
            x_qint = self.quad_interaction(
                m,
                bases_qint,
                quad_idx,
                id_swap,
            )
        if self.atom_edge_interaction is not None:
            x_a2e = self.atom_edge_interaction(
                h,
                bases_a2e,
                trip_idx_a2e,
                id_swap,
                expand_idx=a2ee2a_graph["edge_index"][0],
            )
        if self.edge_atom_interaction is not None:
            h_e2a = self.edge_atom_interaction(
                m,
                bases_e2a,
                trip_idx_e2a,
                id_swap,
                idx_agg2=a2ee2a_graph["edge_index"][1],
                idx_agg2_inner=a2ee2a_graph["target_neighbor_idx"],
                agg2_out_size=num_atoms,
            )
        if self.atom_interaction is not None:
            h_a2a = self.atom_interaction(
                h,
                basis_a2a_rad,
                a2a_graph["edge_index"],
                a2a_graph["target_neighbor_idx"],
            )

        ## -------------- Merge Embeddings after interactions ------------- ##
        x = x_ca_skip + x_e2e  # (nEdges, emb_size_edge)
        if self.quad_interaction is not None:
            x += x_qint  # (nEdges, emb_size_edge)
        if self.atom_edge_interaction is not None:
            x += x_a2e  # (nEdges, emb_size_edge)
        x = x * self.inv_sqrt_num_eint

        # Merge atom embeddings after interactions
        if self.edge_atom_interaction is not None:
            h = h + h_e2a  # (nEdges, emb_size_edge)
        if self.atom_interaction is not None:
            h = h + h_a2a  # (nEdges, emb_size_edge)
        h = h * self.inv_sqrt_num_aint

        ## -------------------- Update Edge Embeddings -------------------- ##
        # Transformations before skip connection
        for _, layer in enumerate(self.layers_before_skip):
            x = layer(x)  # (nEdges, emb_size_edge)

        # Skip connection
        m = m + x  # (nEdges, emb_size_edge)
        m = m * self.inv_sqrt_2

        # Transformations after skip connection
        for _, layer in enumerate(self.layers_after_skip):
            m = layer(m)  # (nEdges, emb_size_edge)

        ## -------------------- Update Atom Embeddings -------------------- ##
        for layer in self.atom_emb_layers:
            h = layer(h)  # (nAtoms, emb_size_atom)

        h2 = self.atom_update(h, m, basis_atom_update, edge_index_main[1])

        # Skip connection
        h = h + h2  # (nAtoms, emb_size_atom)
        h = h * self.inv_sqrt_2

        ## ---------- Update Edge Embeddings with Atom Embeddings --------- ##
        m2 = self.concat_layer(h, m, edge_index_main)
        # (nEdges, emb_size_edge)

        for _, layer in enumerate(self.residual_m):
            m2 = layer(m2)  # (nEdges, emb_size_edge)

        # Skip connection
        m = m + m2  # (nEdges, emb_size_edge)
        m = m * self.inv_sqrt_2
        return h, m

class QuadrupletInteraction(torch.nn.Module):
    """
    Quadruplet-based message passing block.

    Arguments
    ---------
    emb_size_edge: int
        Embedding size of the edges.
    emb_size_quad_in: int
        (Down-projected) embedding size of the quadruplet edge embeddings
        before the bilinear layer.
    emb_size_quad_out: int
        (Down-projected) embedding size of the quadruplet edge embeddings
        after the bilinear layer.
    emb_size_rbf: int
        Embedding size of the radial basis transformation.
    emb_size_cbf: int
        Embedding size of the circular basis transformation (one angle).
    emb_size_sbf: int
        Embedding size of the spherical basis transformation (two angles).
    symmetric_mp: bool
        Whether to use symmetric message passing and
        update the edges in both directions.
    activation: str
        Name of the activation function to use in the dense layers.
    """

    def __init__(
        self,
        emb_size_edge,
        emb_size_quad_in,
        emb_size_quad_out,
        emb_size_rbf,
        emb_size_cbf,
        emb_size_sbf,
        symmetric_mp=True,
        activation=None,
    ) -> None:
        super().__init__()
        self.symmetric_mp = symmetric_mp

        # Dense transformation
        self.dense_db = Dense(
            emb_size_edge,
            emb_size_edge,
            activation=activation,
            bias=False,
        )

        # Up projections of basis representations,
        # bilinear layer and scaling factors
        self.mlp_rbf = Dense(
            emb_size_rbf,
            emb_size_edge,
            activation=None,
            bias=False,
        )
        self.scale_rbf = ScaleFactor()

        self.mlp_cbf = Dense(
            emb_size_cbf,
            emb_size_quad_in,
            activation=None,
            bias=False,
        )
        self.scale_cbf = ScaleFactor()

        self.mlp_sbf = EfficientInteractionBilinear(
            emb_size_quad_in, emb_size_sbf, emb_size_quad_out
        )
        self.scale_sbf_sum = ScaleFactor()
        # combines scaling for bilinear layer and summation

        # Down and up projections
        self.down_projection = Dense(
            emb_size_edge,
            emb_size_quad_in,
            activation=activation,
            bias=False,
        )
        self.up_projection_ca = Dense(
            emb_size_quad_out,
            emb_size_edge,
            activation=activation,
            bias=False,
        )
        if self.symmetric_mp:
            self.up_projection_ac = Dense(
                emb_size_quad_out,
                emb_size_edge,
                activation=activation,
                bias=False,
            )

        self.inv_sqrt_2 = 1 / math.sqrt(2.0)

    def forward(
        self,
        m,
        bases,
        idx,
        id_swap,
    ):
        """
        Returns
        -------
        m: torch.Tensor, shape=(nEdges, emb_size_edge)
            Edge embeddings (c->a).
        """

        x_db = self.dense_db(m)  # (nEdges, emb_size_edge)

        # Transform via radial basis
        x_db2 = x_db * self.mlp_rbf(bases["rad"])  # (nEdges, emb_size_edge)
        x_db = self.scale_rbf(x_db2, ref=x_db)

        # Down project embeddings
        x_db = self.down_projection(x_db)  # (nEdges, emb_size_quad_in)

        # Transform via circular basis
        x_db = x_db[idx["triplet_in"]["in"]]
        # (num_triplets_int, emb_size_quad_in)

        x_db2 = x_db * self.mlp_cbf(bases["cir"])
        # (num_triplets_int, emb_size_quad_in)
        x_db = self.scale_cbf(x_db2, ref=x_db)

        # Transform via spherical basis
        x_db = x_db[idx["trip_in_to_quad"]]
        # (num_quadruplets, emb_size_quad_in)
        x = self.mlp_sbf(bases["sph"], x_db, idx["out"], idx["out_agg"])
        # (nEdges, emb_size_quad_out)
        x = self.scale_sbf_sum(x, ref=x_db)

        # =>
        # rbf(d_db)
        # cbf(d_ba, angle_abd)
        # sbf(d_ca, angle_cab, angle_cabd)

        if self.symmetric_mp:
            # Upproject embeddings
            x_ca = self.up_projection_ca(x)  # (nEdges, emb_size_edge)
            x_ac = self.up_projection_ac(x)  # (nEdges, emb_size_edge)

            # Merge interaction of c->a and a->c
            x_ac = x_ac[id_swap]  # swap to add to edge a->c and not c->a
            x_res = x_ca + x_ac
            x_res = x_res * self.inv_sqrt_2
            return x_res
        else:
            x_res = self.up_projection_ca(x)
            return x_res

class TripletInteraction(torch.nn.Module):
    """
    Triplet-based message passing block.

    Arguments
    ---------
    emb_size_in: int
        Embedding size of the input embeddings.
    emb_size_out: int
        Embedding size of the output embeddings.
    emb_size_trip_in: int
        (Down-projected) embedding size of the quadruplet edge embeddings
        before the bilinear layer.
    emb_size_trip_out: int
        (Down-projected) embedding size of the quadruplet edge embeddings
        after the bilinear layer.
    emb_size_rbf: int
        Embedding size of the radial basis transformation.
    emb_size_cbf: int
        Embedding size of the circular basis transformation (one angle).
    symmetric_mp: bool
        Whether to use symmetric message passing and
        update the edges in both directions.
    swap_output: bool
        Whether to swap the output embedding directions.
        Only relevant if symmetric_mp is False.
    activation: str
        Name of the activation function to use in the dense layers.
    """

    def __init__(
        self,
        emb_size_in: int,
        emb_size_out: int,
        emb_size_trip_in: int,
        emb_size_trip_out: int,
        emb_size_rbf: int,
        emb_size_cbf: int,
        symmetric_mp: bool = True,
        swap_output: bool = True,
        activation=None,
    ) -> None:
        super().__init__()
        self.symmetric_mp = symmetric_mp
        self.swap_output = swap_output

        # Dense transformation
        self.dense_ba = Dense(
            emb_size_in,
            emb_size_in,
            activation=activation,
            bias=False,
        )

        # Up projections of basis representations, bilinear layer and scaling factors
        self.mlp_rbf = Dense(
            emb_size_rbf,
            emb_size_in,
            activation=None,
            bias=False,
        )
        self.scale_rbf = ScaleFactor()

        self.mlp_cbf = EfficientInteractionBilinear(
            emb_size_trip_in, emb_size_cbf, emb_size_trip_out
        )
        self.scale_cbf_sum = ScaleFactor()
        # combines scaling for bilinear layer and summation

        # Down and up projections
        self.down_projection = Dense(
            emb_size_in,
            emb_size_trip_in,
            activation=activation,
            bias=False,
        )
        self.up_projection_ca = Dense(
            emb_size_trip_out,
            emb_size_out,
            activation=activation,
            bias=False,
        )
        if self.symmetric_mp:
            self.up_projection_ac = Dense(
                emb_size_trip_out,
                emb_size_out,
                activation=activation,
                bias=False,
            )

        self.inv_sqrt_2 = 1 / math.sqrt(2.0)

    def forward(
        self,
        m,
        bases,
        idx,
        id_swap,
        expand_idx=None,
        idx_agg2=None,
        idx_agg2_inner=None,
        agg2_out_size=None,
    ):
        """
        Returns
        -------
        m: torch.Tensor, shape=(nEdges, emb_size_edge)
            Edge embeddings.
        """

        # Dense transformation
        x_ba = self.dense_ba(m)  # (nEdges, emb_size_edge)

        if expand_idx is not None:
            x_ba = x_ba[expand_idx]

        # Transform via radial basis
        rad_emb = self.mlp_rbf(bases["rad"])  # (nEdges, emb_size_edge)
        x_ba2 = x_ba * rad_emb
        x_ba = self.scale_rbf(x_ba2, ref=x_ba)

        x_ba = self.down_projection(x_ba)  # (nEdges, emb_size_trip_in)

        # Transform via circular spherical basis
        x_ba = x_ba[idx["in"]]

        # Efficient bilinear layer
        x = self.mlp_cbf(
            basis=bases["cir"],
            m=x_ba,
            idx_agg_outer=idx["out"],
            idx_agg_inner=idx["out_agg"],
            idx_agg2_outer=idx_agg2,
            idx_agg2_inner=idx_agg2_inner,
            agg2_out_size=agg2_out_size,
        )
        # (num_atoms, emb_size_trip_out)
        x = self.scale_cbf_sum(x, ref=x_ba)

        # =>
        # rbf(d_ba)
        # cbf(d_ca, angle_cab)

        if self.symmetric_mp:
            # Up project embeddings
            x_ca = self.up_projection_ca(x)  # (nEdges, emb_size_edge)
            x_ac = self.up_projection_ac(x)  # (nEdges, emb_size_edge)

            # Merge interaction of c->a and a->c
            x_ac = x_ac[id_swap]  # swap to add to edge a->c and not c->a
            x_res = x_ca + x_ac
            x_res = x_res * self.inv_sqrt_2
            return x_res
        else:
            if self.swap_output:
                x = x[id_swap]
            x_res = self.up_projection_ca(x)  # (nEdges, emb_size_edge)
            return x_res

class PairInteraction(torch.nn.Module):
    """
    Pair-based message passing block.

    Arguments
    ---------
    emb_size_atom: int
        Embedding size of the atoms.
    emb_size_pair_in: int
        Embedding size of the atom pairs before the bilinear layer.
    emb_size_pair_out: int
        Embedding size of the atom pairs after the bilinear layer.
    emb_size_rbf: int
        Embedding size of the radial basis transformation.
    activation: str
        Name of the activation function to use in the dense layers.
    """

    def __init__(
        self,
        emb_size_atom,
        emb_size_pair_in,
        emb_size_pair_out,
        emb_size_rbf,
        activation=None,
    ) -> None:
        super().__init__()

        # Bilinear layer and scaling factor
        self.bilinear = Dense(
            emb_size_rbf * emb_size_pair_in,
            emb_size_pair_out,
            activation=None,
            bias=False,
        )
        self.scale_rbf_sum = ScaleFactor()

        # Down and up projections
        self.down_projection = Dense(
            emb_size_atom,
            emb_size_pair_in,
            activation=activation,
            bias=False,
        )
        self.up_projection = Dense(
            emb_size_pair_out,
            emb_size_atom,
            activation=activation,
            bias=False,
        )

        self.inv_sqrt_2 = 1 / math.sqrt(2.0)

    def forward(
        self,
        h,
        rad_basis,
        edge_index,
        target_neighbor_idx,
    ):
        """
        Returns
        -------
        h: torch.Tensor, shape=(num_atoms, emb_size_atom)
            Atom embeddings.
        """
        num_atoms = h.shape[0]

        x_b = self.down_projection(h)  # (num_atoms, emb_size_edge)
        x_ba = x_b[edge_index[0]]  # (num_edges, emb_size_edge)

        Kmax = torch.max(target_neighbor_idx) + 1
        x2 = x_ba.new_zeros(num_atoms, Kmax, x_ba.shape[-1])
        x2[edge_index[1], target_neighbor_idx] = x_ba
        # (num_atoms, Kmax, emb_size_edge)

        x_ba2 = rad_basis @ x2
        # (num_atoms, emb_size_interm, emb_size_edge)
        h_out = self.bilinear(x_ba2.reshape(num_atoms, -1))

        h_out = self.scale_rbf_sum(h_out, ref=x_ba)
        # (num_atoms, emb_size_edge)

        h_out = self.up_projection(h_out)  # (num_atoms, emb_size_atom)

        return h_out


"""Module containing class for collection of cases"""
from typing import Union, List, Dict
from sumo.wrapper import SumoClient
from fmu.sumo.explorer.objects._document_collection import DocumentCollection
from fmu.sumo.explorer.objects.case import Case
from fmu.sumo.explorer.pit import Pit

_CASE_FIELDS = [
    "_id",
    "fmu.case.name",
    "fmu.case.user.id",
    "_sumo.status",
    "access.asset",
    "masterdata.smda.field",
]

class CaseCollection(DocumentCollection):
    """A class for representing a collection of cases in Sumo"""

    def __init__(self, sumo: SumoClient, query: Dict = None, pit: Pit = None):
        """
        Args:
            sumo (SumoClient): connection to Sumo
            query (dict): elastic query object
            pit (Pit): point in time
        """
        super().__init__("case", sumo, query, _CASE_FIELDS, pit)

    @property
    def names(self) -> List[str]:
        """List of unique case names"""
        return self._get_field_values("fmu.case.name.keyword")

    @property
    async def names_async(self) -> List[str]:
        """List of unique case names"""
        return await self._get_field_values_async("fmu.case.name.keyword")

    @property
    def statuses(self) -> List[str]:
        """List of unique statuses"""
        return self._get_field_values("_sumo.status.keyword")

    @property
    async def statuses_async(self) -> List[str]:
        """List of unique statuses"""
        return await self._get_field_values_async("_sumo.status.keyword")

    @property
    def users(self) -> List[str]:
        """List of unique user names"""
        return self._get_field_values("fmu.case.user.id.keyword")

    @property
    async def users_async(self) -> List[str]:
        """List of unique user names"""
        return await self._get_field_values_async("fmu.case.user.id.keyword")

    @property
    def assets(self) -> List[str]:
        """List of unique asset names"""
        return self._get_field_values("access.asset.name.keyword")

    @property
    async def assets_async(self) -> List[str]:
        """List of unique asset names"""
        return await self._get_field_values_async("access.asset.name.keyword")

    @property
    def fields(self) -> List[str]:
        """List of unique field names"""
        return self._get_field_values(
            "masterdata.smda.field.identifier.keyword"
        )

    @property
    async def fields_async(self) -> List[str]:
        """List of unique field names"""
        return await self._get_field_values_async(
            "masterdata.smda.field.identifier.keyword"
        )

    def __getitem__(self, index: int) -> Case:
        doc = super().__getitem__(index)
        return Case(self._sumo, doc, self._pit)

    async def getitem_async(self, index: int) -> Case:
        doc = await super().getitem_async(index)
        return Case(self._sumo, doc)

    def filter(
        self,
        uuid: Union[str, List[str]] = None,
        name: Union[str, List[str]] = None,
        status: Union[str, List[str]] = None,
        user: Union[int, List[int]] = None,
        asset: Union[int, List[int]] = None,
        field: Union[str, List[str]] = None,
    ) -> "CaseCollection":
        """Filter cases

        Args:
            uuid (str or List[str]): case uuid
            name (str or List[str]): case name
            status (str or List[str]): case status
            user (str or List[str]): name of case owner
            asset (str or List[str]): asset
            field (str or List[str]): field

        Returns:
            CaseCollection: A filtered CaseCollection
        """
        must = self._utils.build_terms(
            {
                "_id": uuid,
                "fmu.case.name.keyword": name,
                "_sumo.status.keyword": status,
                "fmu.case.user.id.keyword": user,
                "access.asset.name.keyword": asset,
                "masterdata.smda.field.identifier.keyword": field,
            }
        )

        query = super()._add_filter({"bool": {"must": must}})
        return CaseCollection(self._sumo, query, self._pit)


from itertools import combinations

def isPrime(number):
    if number < 2:
        return False
    else:
        for num in range(2, number):
            if number % num == 0:
                return False
        return True

def Prime(n):
    prime_num = []
    for num in range(n):
        if isPrime(num):
            prime_num.append(num)
    return prime_num

def solution(nums):
    answer = 0
    num_combines = combinations(nums, 3)
    nums_sum = sum(nums)
    prime_num = Prime(nums_sum)
    for num in num_combines:
        if sum(num) in prime_num:
            answer += 1
    return answer

nums = [1,2,7,6,4]
print(solution(nums))

알고리즘/3주 모의고사 소수.py

3주 모의고사 소수.py


from flask import Flask, render_template, request
import jsonify
import requests
import pickle
import numpy as np
import sklearn

app = Flask(__name__)
model = pickle.load(open('insurance_rf.pkl', 'rb'))

@app.route('/')
def home():
    return render_template('index.html')

@app.route("/predict", methods=['POST'])
def predict():
    northwest=0
    southeast=0
    southwest=0
    if request.method == 'POST':
        Age = int(request.form['age'])
        Gender=request.form['gender']
        BMI=float(request.form['bmi'])
        Children=int(request.form['children'])
        Smoker=request.form['smoker']
        Region=request.form['region']
        if(Gender=='male'):
            Gender=1
        else:
            Gender=0
        if(Smoker=='yes'):
            Smoker=1
        else:
            Smoker=0
        if(Region=='northwest'):
            northwest=1
            southeast=0
            southwest=0
        elif(Region=='southeast'):
            northwest=0
            southeast=1
            southwest=0
        elif(Region=='southwest'):
            northwest=0
            southeast=0
            southwest=1
        else:
            northwest=0
            southeast=0
            southwest=0

        prediction=model.predict([[Age,BMI,Children,Gender,Smoker,northwest,southeast,southwest]])
        output=round(prediction[0],2)
        return render_template('index.html',prediction_text="INSURANCE CHARGES- {}".format(output))

if __name__=="__main__":
    app.run(debug=True)


import subprocess as sp
from collections import defaultdict
import numpy as np
import pandas as pd
import argparse
import pickle
import os
import re

'''
This script creates feature matrix from VCF files for downstream ML analysis
'''
parser=argparse.ArgumentParser(description='Append MIC phenotype to MIC dataframe')
parser.add_argument('-MIC',help='MIC phenotype dataframe',required=True)
parser.add_argument('-pheno',help='Output folder',required=True)
args=parser.parse_args()

drug=(os.path.basename(args.pheno)).split('_')[0]
print(drug)
pheno_series={}

with open(args.pheno,'r') as f:
    for l in f:
        sample,pheno=l.strip().split()
        pheno_series[sample]=pheno

pheno_series=pd.Series(pheno_series,name=drug,dtype='category')
print(pheno_series.cat.categories)
pheno_series=pheno_series.cat.reorder_categories(['NA','Sus','Low','High','Resistant'],ordered=True)
print(pheno_series.cat.categories)

df=pickle.load(open(args.MIC,'rb'))
print(f'Preivous shape: {df.shape}')
print(df.head())
out_df=pd.concat([df,pheno_series],axis=1,join='inner')
print(f'New shape: {out_df.shape}')
print(out_df.head())
#print(f'Sorted {out_df[drug].sort_values()}')

out_df.to_pickle(path=args.MIC)


import numpy as np

from qiskit import Aer, QuantumCircuit
from qiskit.circuit import Parameter
from qiskit.circuit.library import RealAmplitudes, ZZFeatureMap
from qiskit.opflow import StateFn, PauliSumOp,AerPauliExpectation,ListOp,Gradient

from qiskit.utils import QuantumInstance,algorithm_globals

algorithm_globals.random_seed = 42

# set method to calculate expeceted values
expval  = AerPauliExpectation()

# define gradient method
gradient = Gradient()

# define quantum instances (statevector and sample based)
qi_sv = QuantumInstance(Aer.get_backend("aer_simulator_statevector"))

# we set shots to 10 as this will determine the number of samples later on.
qi_qasm = QuantumInstance(Aer.get_backend("aer_simulator"),shots = 10)

from qiskit_machine_learning.neural_networks import OpflowQNN

# constuct parameterized circuit
params1 = [Parameter("input1"),Parameter("weights1")]
qc1 = QuantumCircuit(1)
qc1.h(0)
qc1.ry(params1[0],0)
qc1.rx(params1[1],0)
qc_sfn1 = StateFn(qc1)

# construct the cost operator
H1 = StateFn(PauliSumOp.from_list([("Z",1.0),("X",1.0)]))

# combine operator and circuit to objective function
op1 = ~H1 @ qc_sfn1
print(op1)
# construct opflowqnn with the operator, the input parameters, the weight parameters
qnn1 = OpflowQNN(op1, [params1[0]], [params1[1]], expval, gradient, qi_sv)

input1 = algorithm_globals.random.random(qnn1.num_inputs)
weights1 = algorithm_globals.random.random(qnn1.num_weights)

out = qnn1.forward(input1,weights1)
print(out)
back = qnn1.backward(input1, weights1)
print(back)
print("End of the calculation")


from RadialBasisFunction import *
import numpy as np
from sklearn import datasets

C=3
F=2
X,Y = datasets.make_classification(
    n_features=C,
    n_classes=F,
    n_samples=200,
    n_redundant=0,
    n_clusters_per_class=1
)

X=X.T
Y=np.array([Y])

RBF =RadialBasisFunction(C,4)
RBF.Train(X,Y,5,100)


import os
from pathlib import Path
from unittest.mock import patch

import pytest
import pytest_check as check
import yaml
from msticpy.config.comp_edit import CompEditStatusMixin
from msticpy.config.ce_azure_sentinel import CEAzureSentinel, _validate_ws
from msticpy.config.ce_common import get_def_tenant_id
from msticpy.config.ce_data_providers import CEDataProviders
from msticpy.config.ce_keyvault import CEKeyVault
from msticpy.config.ce_other_providers import CEOtherProviders
from msticpy.config.ce_ti_providers import CETIProviders
from msticpy.config.ce_user_defaults import CEAutoLoadComps, CEAutoLoadQProvs
from msticpy.config.compound_ctrls import ArgControl
from msticpy.config.mp_config_control import MpConfigControls, get_mpconfig_definitions

from ..nbtools.test_user_config import CONFIG_TEXT
from ..unit_test_lib import TEST_DATA_PATH

__author__ = "Ian Hellen"

# pylint: disable=redefined-outer-name

@pytest.fixture
def mp_conf_ctrl():
    """Create MPConfigControl instance."""
    CompEditStatusMixin.testing = True
    mp_defn = get_mpconfig_definitions()
    config_path = Path(TEST_DATA_PATH).joinpath("msticpyconfig.yaml")
    conf_settings = {}
    with open(config_path, "r") as conf_h:
        conf_settings = yaml.safe_load(conf_h)

    # modify the LocalData to be AzureSentinel
    user_defaults = yaml.safe_load(CONFIG_TEXT)

    nb_settings = user_defaults["UserDefaults"]["LoadComponents"]["Notebooklets"]
    q_prov = nb_settings["query_provider"]["LocalData"]
    del nb_settings["query_provider"]["LocalData"]
    nb_settings["query_provider"]["AzureSentinel"] = q_prov
    conf_settings.update(user_defaults)

    return MpConfigControls(mp_config_def=mp_defn, mp_config=conf_settings)

_EDITORS = [
    pytest.param((CEAzureSentinel, ["Placeholder"]), id="CEAzureSentinel"),
    pytest.param(
        (CEDataProviders, ["Splunk", "AzureCLI", "LocalData", "Mordor"]),
        id="CEDataProviders",
    ),
    pytest.param(
        (CETIProviders, ["OTX", "VirusTotal", "AzureSentinel", "TorExitNodes"]),
        id="CETIProviders",
    ),
    pytest.param((CEOtherProviders, ["GeoIPLite", "IPStack"]), id="CEOtherProviders"),
    pytest.param(
        (
            CEAutoLoadComps,
            [
                "TILookup",
                "GeoIpLookup",
                "Notebooklets",
                "Pivot",
                "AzureData",
                "AzureSentinelAPI",
            ],
        ),
        id="CEAutoLoadComps",
    ),
    pytest.param(
        (
            CEAutoLoadQProvs,
            [
                "AzureSentinel.Default",
                "Mordor",
                "LocalData",
                "AzureSecurityCenter",
                "Splunk",
                "MDE",
                "SecurityGraph",
            ],
        ),
        id="CEAutoLoadQProvs",
    ),
]

def _get_select_labels(control):
    return (opt[0] if isinstance(opt, tuple) else opt for opt in control.options)

def _is_current_option(option, control):
    return option in _get_select_labels(control)

# pylint: disable=protected-access
@pytest.mark.parametrize("editor_test", _EDITORS)
def test_item_editor_controls(editor_test, mp_conf_ctrl):
    """Items edit controls."""
    editor, cases = editor_test
    edit_comp = editor(mp_controls=mp_conf_ctrl)
    _execute_item_editor_test(edit_comp, cases)

def _execute_item_editor_test(edit_comp, cases):
    check.is_not_none(edit_comp.help.html_help.value)
    check.is_not_none(edit_comp._DESCRIPTION)
    check.is_not_none(edit_comp._COMP_PATH)
    check.greater_equal(len(edit_comp._HELP_URI), 1)

    for test_opt in cases:
        print(f"Testing {edit_comp.__class__.__name__}, {test_opt}")
        opts = edit_comp.select_item.options
        n_opts = len(opts)

        # If this control has an options list - select the first of these
        prov_opts = getattr(edit_comp, "prov_options", None)
        if prov_opts and prov_opts.options:
            edit_comp.prov_options.value = test_opt

        # If there is an existing item, delete this
        if _is_current_option(test_opt, edit_comp.select_item):
            edit_comp.select_item.label = test_opt
            edit_comp.edit_buttons.btn_del.click()
            n_opts -= 1

        # Add a new one
        edit_comp.edit_buttons.btn_add.click()
        # Save the current item
        edit_comp.edit_buttons.btn_save.click()
        check.equal(len(edit_comp.select_item.options), n_opts + 1, "Item added")

        if isinstance(edit_comp, CEAzureSentinel):
            if _is_current_option("Default", edit_comp.select_item):
                edit_comp.select_item.label = "Default"
                edit_comp.edit_buttons.btn_del.click()
                n_opts -= 1

            edit_comp.btn_set_default.click()
            edit_comp.edit_buttons.btn_save.click()
            n_opts += 1
            check.equal(
                len(edit_comp.select_item.options), n_opts + 1, "AzSent default added"
            )

        if prov_opts and prov_opts.options:
            edit_comp.prov_options.value = test_opt
            edit_comp.edit_buttons.btn_add.click()
            # check that we didn't add a duplicate
            check.equal(
                len(edit_comp.select_item.options), n_opts + 1, "Dup item not added"
            )

        # delete whatever we've just added
        edit_comp.edit_buttons.btn_del.click()
        check.equal(len(edit_comp.select_item.options), n_opts, "New item deleted")

@pytest.mark.parametrize("editor_test", _EDITORS)
def test_item_editor_controls_empty(editor_test, mp_conf_ctrl):
    """Items edit controls."""
    conf_ctrl = MpConfigControls(mp_config_def=mp_conf_ctrl.config_defn, mp_config={})
    editor, cases = editor_test
    edit_comp = editor(mp_controls=conf_ctrl)
    if isinstance(edit_comp, CEAutoLoadQProvs) and "AzureSentinel.Default" in cases:
        cases.remove("AzureSentinel.Default")
    _execute_item_editor_test(edit_comp, cases)

def test_item_editor_load_comp_notebooklets(mp_conf_ctrl):
    """Items edit controls."""
    edit_comp = CEAutoLoadComps(mp_controls=mp_conf_ctrl)

    prev_val = mp_conf_ctrl.get_value("UserDefaults.LoadComponents.Notebooklets")
    edit_comp.select_item.label = "Notebooklets"
    edit_comp.edit_buttons.btn_save.click()
    new_val = mp_conf_ctrl.get_value("UserDefaults.LoadComponents.Notebooklets")
    check.equal(prev_val, new_val)

STORE_TEXT = "Text"
STORE_ENV_VAR = "EnvironmentVar"
STORE_KEYVAULT = "KeyVault"

def test_arg_controls(mp_conf_ctrl):
    """Argcontrol is a sub-component for editing Args."""
    edit_comp = CETIProviders(mp_controls=mp_conf_ctrl)
    edit_comp.select_item.label = "VirusTotal"
    provider = edit_comp.select_item.label
    # get the control for this provider
    ctrl_path = f"TIProviders.{provider}.Args.AuthKey"
    arg_ctrl = mp_conf_ctrl.get_control(ctrl_path)
    store_type = arg_ctrl.rb_store_type.value
    check.is_in(store_type, (STORE_TEXT, STORE_KEYVAULT, STORE_ENV_VAR))

    arg_ctrl.rb_store_type.value = STORE_TEXT
    arg_ctrl.txt_val.value = "test_value"
    edit_comp.edit_buttons.btn_save.click()
    saved_val = mp_conf_ctrl.get_value(ctrl_path)
    check.equal(saved_val, "test_value")
    check.equal(arg_ctrl.cb_kv_def.layout.visibility, "hidden")
    check.equal(arg_ctrl.btn_add_kv_secret.layout.visibility, "visible")

    arg_ctrl.rb_store_type.value = STORE_ENV_VAR
    edit_comp.edit_buttons.btn_save.click()
    saved_val = mp_conf_ctrl.get_value(ctrl_path)
    check.equal(saved_val, {STORE_ENV_VAR: "test_value"})
    check.equal(arg_ctrl.cb_kv_def.layout.visibility, "hidden")
    check.equal(arg_ctrl.btn_add_kv_secret.layout.visibility, "visible")

    arg_ctrl.rb_store_type.value = STORE_KEYVAULT
    arg_ctrl.cb_kv_def.value = True
    edit_comp.edit_buttons.btn_save.click()
    saved_val = mp_conf_ctrl.get_value(ctrl_path)
    check.equal(saved_val, {STORE_KEYVAULT: None})
    check.equal(arg_ctrl.cb_kv_def.layout.visibility, "visible")
    check.equal(arg_ctrl.btn_add_kv_secret.layout.visibility, "hidden")
    check.is_true(arg_ctrl.txt_val.disabled)
    check.equal(arg_ctrl.txt_val.value, "")

    arg_ctrl.cb_kv_def.value = False
    check.is_false(arg_ctrl.txt_val.disabled)

KV_SEC_CLIENT_PATCH = ArgControl.__module__ + ".BHKeyVaultClient"

@patch(KV_SEC_CLIENT_PATCH)
def test_arg_controls_kv(kv_sec, mp_conf_ctrl):
    """Argcontrol is a sub-component for editing Args."""
    edit_comp = CETIProviders(mp_controls=mp_conf_ctrl)
    edit_comp.select_item.label = "VirusTotal"
    provider = edit_comp.select_item.label
    # get the control for this provider
    ctrl_path = f"TIProviders.{provider}.Args.AuthKey"
    arg_ctrl = mp_conf_ctrl.get_control(ctrl_path)

    arg_ctrl.rb_store_type.value = STORE_ENV_VAR
    arg_ctrl.txt_val.value = "test_var"
    os.environ["test_var"] = "test_value"

    arg_ctrl.btn_add_kv_secret.click()
    check.is_true(arg_ctrl.txt_val.disabled)
    check.equal(arg_ctrl.txt_val.value, "")
    set_secret, ss_args, _ = kv_sec.mock_calls[1]
    check.equal(set_secret, "().set_secret")
    check.equal(ss_args[0], "TIProviders-VirusTotal-Args-AuthKey")
    check.equal(ss_args[1], "test_value")
    check.equal(arg_ctrl.rb_store_type.value, STORE_KEYVAULT)

    arg_ctrl.rb_store_type.value = STORE_TEXT
    arg_ctrl.txt_val.value = "test_value2"
    arg_ctrl.btn_add_kv_secret.click()
    check.is_true(arg_ctrl.txt_val.disabled)
    check.equal(arg_ctrl.txt_val.value, "")
    check.equal(arg_ctrl.rb_store_type.value, STORE_KEYVAULT)
    set_secret, ss_args, _ = kv_sec.mock_calls[3]
    check.equal(set_secret, "().set_secret")
    check.equal(ss_args[0], "TIProviders-VirusTotal-Args-AuthKey")
    check.equal(ss_args[1], "test_value2")

    kv_call_count = len(kv_sec.mock_calls)
    arg_ctrl.rb_store_type.value = STORE_TEXT
    arg_ctrl.txt_val.value = ""
    arg_ctrl.btn_add_kv_secret.click()
    # verify we didn't call KV with blank value
    check.equal(len(kv_sec.mock_calls), kv_call_count)

def test_get_tenant_id():
    """Test get tenantID function."""
    tenantid = get_def_tenant_id("40dcc8bf-0478-4f3b-b275-ed0a94f2c013")
    check.equal(tenantid.casefold(), "72f988bf-86f1-41af-91ab-2d7cd011db47".casefold())

def test_azure_sentinel_editor(mp_conf_ctrl):
    """Items edit controls."""
    edit_comp = CEAzureSentinel(mp_controls=mp_conf_ctrl)

    n_opts = len(edit_comp.select_item.options)
    edit_comp.edit_buttons.btn_add.click()
    check.equal(n_opts + 1, len(edit_comp.select_item.options))
    new_ws = edit_comp.current_workspace
    result, _ = _validate_ws(new_ws, mp_conf_ctrl, edit_comp._COMP_PATH)
    check.is_false(result)

    edit_comp.edit_ctrls.children[1].value = "40dcc8bf-0478-4f3b-b275-ed0a94f2c013"
    edit_comp.edit_ctrls.children[2].value = "40dcc8bf-0478-4f3b-b275-ed0a94f2c013"
    edit_comp.edit_buttons.btn_save.click()
    result, _ = _validate_ws(new_ws, mp_conf_ctrl, edit_comp._COMP_PATH)
    check.is_true(result)

    # Save the current item
    edit_comp.edit_buttons.btn_save.click()
    check.is_not_none(mp_conf_ctrl.get_value(f"{edit_comp._COMP_PATH}.{new_ws}"))

    # Rename
    edit_comp.edit_ctrls.children[0].value = "TestWS"
    edit_comp.edit_buttons.btn_save.click()
    ren_workspace_settings = mp_conf_ctrl.get_value(f"{edit_comp._COMP_PATH}.TestWS")
    check.is_not_none(ren_workspace_settings)

    edit_comp.btn_set_default.click()
    def_ws = mp_conf_ctrl.get_value(f"{edit_comp._COMP_PATH}.Default")
    check.equal(def_ws, ren_workspace_settings)

def test_key_vault_editor(mp_conf_ctrl):
    """Items edit controls."""
    edit_comp = CEKeyVault(mp_controls=mp_conf_ctrl)

    check.is_not_none(edit_comp.help.html_help.value)
    check.is_not_none(edit_comp._DESCRIPTION)
    check.is_not_none(edit_comp._COMP_PATH)
    check.greater_equal(len(edit_comp._HELP_URI), 1)

    edit_comp.controls["TenantId"].value = "tenant"  # invalid UUID
    edit_comp.controls["SubscriptionId"].value = "sub"  # invalid UUID
    edit_comp.controls["ResourceGroup"].value = ""  # OK to have empty
    edit_comp.controls["AzureRegion"].value = ""  # OK to have empty
    edit_comp.controls["VaultName"].value = ""  # invalid to have empty
    edit_comp.btn_save.click()

    results = mp_conf_ctrl.validate_setting(f"{edit_comp._COMP_PATH}")
    check.equal(len(results), 3)

    edit_comp.controls["TenantId"].value = "40dcc8bf-0478-4f3b-b275-ed0a94f2c013"
    edit_comp.controls["SubscriptionId"].value = "40dcc8bf-0478-4f3b-b275-ed0a94f2c013"
    edit_comp.controls["ResourceGroup"].value = "resgroup"
    edit_comp.controls["AzureRegion"].value = "Europe"
    edit_comp.controls["VaultName"].value = "MyVault"
    edit_comp.controls["Authority"].value = "global"
    edit_comp.btn_save.click()

    results = mp_conf_ctrl.validate_setting(f"{edit_comp._COMP_PATH}")
    check.equal(len(results), 0)


import os
import sys
import json
import requests
from dotenv import load_dotenv

load_dotenv()

try:
    path = sys.argv[1]
except IndexError:
    path = input('Path to .md file:\n')

with open(path, 'r') as file:
    md_text = file.read()

TOKEN = os.getenv('TOKEN')
URL = 'https://api.github.com/markdown'
HEADERS = {
    'Accept': 'application/vnd.github+json',
    'Authorization': f'token {TOKEN}'
}
body = {
    'text': md_text
}
response = requests.post(URL, data=json.dumps(body), headers=HEADERS)

if response.ok:
    print(response.text)

    path_dest = path.replace('.md', '.html')
    if os.path.exists(path_dest):
        while True:
            answer = input(
                'An HTML file with that name already exists, '
                'do you wish to overwrite this file? (y/n)'
            ).strip().lower()
            if answer in ('n', 'no'):
                print('\n---File was not written.')
                input('Press any key to close')
                sys.exit()
            elif answer in ('y', 'yes'):
                break

    with open(path_dest, 'w+') as file:
        file.write(response.text)

    print('\n---Operation successful')
else:
    print('Something went wrong')
    print(response.status_code)

input('Press any key to close')


from functools import reduce

numeros = input("ingrese numeros:")
numerosEnList = sorted(numeros)
print(numerosEnList)
numerosImpares = []

for i in numerosEnList:
    if int(i) % 2 != 0:
        numerosImpares.append(int(i))

print(numerosImpares)

def suma(a, b):
    return a + b

resultado = reduce(suma, numerosImpares)

print(resultado)


import pygame
import datetime
pygame.init()

WIDTH=1080
HEIGHT=720
screen = pygame.display.set_mode((WIDTH, HEIGHT))
clock=pygame.image.load("images/main-clock.png").convert()
scale_clock = pygame.transform.scale(
    clock, (clock.get_width() // 2,
              clock.get_height() // 2))
clockr=scale_clock.get_rect(center=(WIDTH/2, HEIGHT/2))

second=pygame.image.load("images/left-hand.png").convert_alpha()
scale_second=pygame.transform.scale(
    second, (second.get_width() // 2,
               second.get_height() // 2))

minute=pygame.image.load("images/right-hand.png").convert_alpha()
scale_minute=pygame.transform.scale(
    minute, (minute.get_width() // 2,
               minute.get_height() // 2))

done = False
while not done:
        for event in pygame.event.get():
                if event.type == pygame.QUIT:
                        done = True
        screen.fill((255,255,255))
        screen.blit(scale_clock, clockr)
        t=datetime.datetime.now()
        minutes, seconds=t.minute, t.second
        rots = pygame.transform.rotate(scale_second, (-6*seconds)+90)
        rots_rect = rots.get_rect(center=(540, 360))
        screen.blit(rots, rots_rect)
        rotm = pygame.transform.rotate(scale_minute, (-6*minutes)+90) #(-6*minutes-0.1*seconds)+90
        rotm_rect = rotm.get_rect(center=(540, 360))
        screen.blit(rotm, rotm_rect)
        pygame.display.update()


# Creating a Bouncing Ball Screensaver using OpenCV-Python
# Task- Create a Window that we can write text on. If we don’t write for 5 seconds screensaver will start.

import cv2
import numpy as np

def screensaver():
    img = np.zeros((480,640,3),dtype='uint8')
    dx,dy =1,1
    x,y = 100,100
    while True:
        # Display the image
        cv2.imshow('Screensaver',img)
        k = cv2.waitKey(10)
        img = np.zeros((480,640,3),dtype='uint8')  #This line will help in making different circle everytime loop runs.
        # Increment the position
        x = x+dx
        y = y+dy
        cv2.circle(img,(x,y),20,(255,130,140),-1)
        if k != -1:
            break
        # Change the sign of increment on collision with the boundary
        if y >=480 or y<=0 :
           dy *= -1

        if x >=640 or x<=0 :
           dx *= -1
    cv2.destroyAllWindows()

# Background Image
img1 = cv2.imread('./images/aryan__bindal.jpg')
# Initialize these for text placement
i = 0
a,b = 30,30
while True:
    cv2.imshow('My Photo',img1)
    k = cv2.waitKey(5000)
    # If no key is pressed, display the screensaver
    if k == -1:
        screensaver()
    # Press q to quit
    elif k == ord('q'):
        break
    # Otherwise write real time text on the image.
    # This is used for visualization only
    # You can use anything here.
    else:
        font = cv2.FONT_HERSHEY_SIMPLEX
        cv2.putText(img1,chr(k),(a+i,b), font, 1,(0,0,0),3,cv2.LINE_AA)
 # The shape[] attribute for numpy arrays returns the dimensions of the array. If Y has n rows and m columns, then Y.shape is (n,m).
 # So Y.shape[0] is n and Y.shape[1] is m.
        if a+i >= img1.shape[1]:
            b = b+15
            i = 0
        i +=20

cv2.destroyAllWindows()


import numpy as np
import gudhi
import gudhi.representations
import cv2
from skimage.feature import local_binary_pattern

def img_gray(path):
  img = cv2.imread(path)
  h,w = img.shape[:2] #获取图片的high和wide
  img_gray=np.zeros([h,w],img.dtype) #创建一张和当前图片大小一样的单通道图片
  for i in range(h):
      for j in range(w):
          m = img[i,j]
          img_gray[i,j] =int(m[0]*0.11+m[1]*0.59+m[2]*0.3) #将BGR坐标转换为gray坐标
  return img_gray

def lbp(pixels):

  features = []
  img = pixels.tolist()
  lbp = local_binary_pattern(img, 8, 1, "default")
  binary = [192,96,48,24,12,6,3,129]
  for k in range(8):
    point_position = []
    dgms_normal = []
    for i in range(256):
      for j in range(256):
        if lbp[i][j] == binary[k]:
          point_position.append([j,i])
    normal_pcs = point_position
    rips = gudhi.RipsComplex(points=normal_pcs).create_simplex_tree(max_dimension=2)
    rips.compute_persistence()
    dgms_normal.append(rips.persistence_intervals_in_dimension(1))
    matrix = dgms_normal[0]
    data = matrix.tolist()
    if data == []:
      features.append(0)
    else:
      count=0
      for i in range(len(data)):
        if 20 <= data[i][1] and 20 >= data[i][0]:
          count+=1
      features.append(count)
  return features

for i in range(1,11):
  path = "/content/drive/MyDrive/Colab Notebooks/"+str(i)+".tiff"
  pixels = img_gray(path)
  print(lbp(pixels))

for i in range(1,11):
  path = "/content/drive/MyDrive/Colab Notebooks/morph"+str(i)+".png"
  pixels = img_gray(path)
  print(lbp(pixels))


import numpy as np
import pandas as pd

import imageio as io
from skimage.measure import label, regionprops
from skimage.color import label2rgb,gray2rgb
from skimage.segmentation import watershed
import cv2
import os
import scipy.ndimage as ndi

def watershedSegStack(seg_stack,num_lesions,postprocess_dir,cam_num):

    seg_stack = seg_stack.copy()
    imgs,rows,cols = seg_stack.shape
    sum_stack = np.sum(seg_stack,axis=(0)) / imgs
    seg_stack_save_pth = os.path.join(postprocess_dir,'cam' + str(cam_num) + 'segstack.png')
    cv2.imwrite( seg_stack_save_pth,255.0*gray2rgb(sum_stack) )

    bin_img = np.where(sum_stack > 0, True, False)
    distance = ndi.distance_transform_edt(bin_img)

    min_lesions_over_threshold = float('inf')
    max_lesions_under_threshold = 0
    enough_lesions_found = False
    best_labels = None
    threshold = 1.0
    for i in range(20):

        threshold -= 0.05
        starting_regions = np.where(sum_stack >= threshold, 1, 0)
        labels = label(starting_regions)

        label_map_save_pth = os.path.join(postprocess_dir, 'cam' + str(cam_num) + 'label_map_T{}.png'.format(str(int(threshold*100))))
        cv2.imwrite(label_map_save_pth,255.0*label2rgb(labels, colors=['red', 'green', 'blue', 'purple', 'pink', 'black']))

        num_good_lesions_found = 0
        regions = regionprops(labels)
        for region in regions:
            # maybe use circularity as a filter too?
            # TODO use circularity as well
            circularity = 4*np.pi*region.area / (region.perimeter * region.perimeter)
            x,y = region.centroid
            if region.area > 500 and circularity > 0.5:
                if x > rows * 0.1 and x < rows * 0.9 and y > cols * 0.1 and y < cols * 0.9:
                    num_good_lesions_found += 1
                else:
                    labels = np.where(labels==region.label,0,labels)
            else:
                labels = np.where(labels==region.label,0,labels)
        if num_good_lesions_found == num_lesions:
            best_labels = labels
            break
        elif num_good_lesions_found < min_lesions_over_threshold and num_good_lesions_found >= num_lesions:
            min_lesions_over_threshold = num_good_lesions_found
            enough_lesions_found = True
            best_labels = labels
        elif num_good_lesions_found > max_lesions_under_threshold and enough_lesions_found == False:
            max_lesions_under_threshold = num_good_lesions_found
            best_labels = labels

    labels = best_labels
    counts = []
    # regions doesn't include background
    regions = regionprops(labels)
    for region in regions:
        counts.append([region.area,region.label])
    counts.sort()

    while len(counts) > num_lesions:
        area, label_num = counts.pop(0)
        labels = np.where(labels == label_num, 0, labels)

    # now all the labels will be 1-num_lesion
    labels_unique = np.unique(labels)
    for i,lab_u in enumerate(labels_unique):
        labels = np.where(labels==lab_u,i,labels)

    label_map_ws = watershed(-distance, labels, mask=bin_img)
    label_map_rgb = np.array(255.0*label2rgb(label_map_ws,colors=['red','green','blue','purple','pink','black']),dtype='float32')
    label_map_bgr = cv2.cvtColor(label_map_rgb,cv2.COLOR_RGB2BGR)

    label_map_save_pth = os.path.join(postprocess_dir, 'cam' + str(cam_num) + 'label_map.png')
    rgb_label_map = np.float32(255.0*label2rgb(label_map_ws,colors=['red','green','blue','purple','pink','black']))
    cv2.imwrite( label_map_save_pth,cv2.cvtColor(rgb_label_map,cv2.COLOR_RGB2BGR) )

    return label_map_ws

def processSegStack(seg_stack,img_stack,num_lesions,labels_ws,imageDF,resize_ratio,postprocess_dir,imgsWLesions_dir):
    seg_stack = seg_stack.copy()
    # add first fake segmentation of zero to make processing easier
    num_imgs,rows,cols = seg_stack.shape
    first_seg = np.zeros((1,rows,cols))
    seg_stack = np.concatenate((first_seg,seg_stack),axis=0)

    alpha = 0.4
    #alpha = 1.0
    for i in range(num_imgs):
        df_index = i*num_lesions
        img_name = imageDF.iloc[df_index].loc['Image Name']
        leaf_img = np.array(img_stack[i],dtype='float32') # leaf_img is RGB

        original_img = leaf_img.copy()
        original_seg = original_img.copy()
        original_seg[:,:,0] = np.where(seg_stack[i+1,:,:]==1,255,original_seg[:,:,0])
        original_seg[:,:,1] = np.where(seg_stack[i+1,:,:]==1,0,original_seg[:,:,1])
        original_seg[:,:,2] = np.where(seg_stack[i+1,:,:]==1,0,original_seg[:,:,2])
        orig_seg_img = cv2.addWeighted(original_img,1-alpha,original_seg,alpha,0.0)
        orig_seg_img_pth = os.path.join(postprocess_dir, img_name.replace('.png','') + '_OSeg.png')
        orig_img_pth = os.path.join(postprocess_dir, img_name.replace('.png','') + '_OImg.png')
        cv2.imwrite(orig_seg_img_pth,cv2.cvtColor(orig_seg_img,cv2.COLOR_RGB2BGR))
        cv2.imwrite(orig_img_pth,cv2.cvtColor(original_img,cv2.COLOR_RGB2BGR))

        # current image is the previous segmentation AND the current segmentation
        # so that lesions don't randomly disappear
        seg_stack[i+1,:,:] = seg_stack[i+1,:,:] + seg_stack[i,:,:]
        continuous_seg = seg_stack[i+1,:,:]
        curr_labels = np.where(continuous_seg>0, labels_ws, 0)
        num_lesions_segmented = np.max(curr_labels)
        seg_image = 255.0*label2rgb(curr_labels,colors=['red','green','blue','purple','pink','black'])

        seg_image_mask = np.sum(seg_image,axis=2,keepdims=True)
        seg_image_mask = np.where(seg_image_mask>0,1,0)

        overlay = np.where(seg_image_mask==1,seg_image,leaf_img)
        overlay = np.array(overlay,dtype='float32')

        img_w_lesions = cv2.addWeighted(leaf_img,1-alpha,overlay,alpha,0.0)
        img_w_lesions_pth = os.path.join(imgsWLesions_dir, img_name.replace('.png','_lesions.png'))
        cv2.imwrite(img_w_lesions_pth,cv2.cvtColor(img_w_lesions,cv2.COLOR_RGB2BGR))

        lesion_total = 0
        for l in range(num_lesions_segmented):
                area_str = 'Lesion #'
                imageDF.at[df_index+l, area_str] = l+1
                lesion_size = np.count_nonzero(np.where(curr_labels==l+1,l+1,0))
                imageDF.at[df_index+l,'Lesion Area Pixels'] = lesion_size
                imageDF.at[df_index+l, 'Adjusted Lesion Pixels'] = lesion_size * resize_ratio
                lesion_total += lesion_size

        lesion_avg = lesion_total / num_lesions_segmented

        # Only record Avg Adj Pixel Size one time per image for easier statistical analysis
        #for l in range(num_lesions):
        #    imageDF.at[df_index+l, 'Avg Adj Pixel Size'] = lesion_avg * resize_ratio
        imageDF.at[df_index, 'Avg Adj Pixel Size'] = lesion_avg * resize_ratio

    return imageDF

def cleanDF(df):
    clean_df = df[[
        'Image Name',
        'File Location',
        'CameraID',
        'Year',
        'Month',
        'Day',
        'Hour',
        'Innoc Year',
        'Innoc Month',
        'Innoc Day',
        'Innoc Hour',
        'Hours Elapsed',
        'Lesion #',
        'Lesion Area Pixels',
        'ResizeRatio',
        'Adjusted Lesion Pixels',
        'Avg Adj Pixel Size',
        'Camera #',
        'Array #',
        'Leaf #',
        'Leaf Section #',
        'Covariable 1',
        'Covariable 2',
        'Covariable 3',
        'Covariable 4',
        'Vector Name',
        'Gene of Interest',
        'Comments',
        'Description']]
    return clean_df


'''

RESPONSE WITH HTML CONTENTS

Let's response with our first web page written in HTML. We know nothing about HTML. It is the language used for the
creating web pages,that describes the structure of the document.

Web browsers receive HTML documents from a web server or from local storage and render the documents into multimedia web
pages. HTML describes the structure of a web page semantically and originally included cues for the appearance of the
document.

HTML elements are the building blocks of HTML pages. With HTML constructs, images and other objects such as interactive forms may be embedded into the rendered page.

In our server we are changing the contents. Instead of responding with a string, we will send a message in HTML. It is
important to change the Content-type header from text/plain to text/html for indicating that we are sending HTML code
instead of plain text.

'''

import socket
import termcolor

IP = "192.168.0.195"
PORT = 8080
MAX_OPEN_REQUESTS = 5

def process_client(cs):
    """Process the client request.
    Parameters:  cs: socket for communicating with the client"""

    # Read client message. Decode it as a string
    msg = cs.recv(2048).decode("utf-8")

    # Print the received message, for debugging
    print()
    print("Request message: ")
    termcolor.cprint(msg, 'green')

    # Build the HTTP response message. It has the following lines
    # Status line
    # header
    # blank line
    # Body (content to send)

    # This new contents are written in HTML language
    contents = """
    <!DOCTYPE html>

        <meta charset="utf-8">
        <title>Green server</title>

GREEN SERVER

I am the Green Server! :-)

    """

    # -- Everything is OK
    status_line = "HTTP/1.1 200 OK\r\n"

    # -- Build the header
    header = "Content-Type: text/html\r\n"
    header += "Content-Length: {}\r\n".format(len(str.encode(contents)))

    # -- Build the message by joining together all the parts
    response_msg = str.encode(status_line + header + "\r\n" + contents)
    cs.send(response_msg)

    # Close the socket
    cs.close()

# MAIN PROGRAM

# create an INET, STREAMing socket
serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# Bind the socket to the IP and PORT
serversocket.bind((IP, PORT))

# Configure the server sockets
# MAX_OPEN_REQUESTS connect requests before refusing outside connections
serversocket.listen(MAX_OPEN_REQUESTS)

print("Socket ready: {}".format(serversocket))

while True:
    # accept connections from outside
    # The server is waiting for connections
    print("Waiting for connections at {}, {} ".format(IP, PORT))
    (clientsocket, address) = serversocket.accept()

    # Connection received. A new socket is returned for communicating with the client
    print("Attending connections from client: {}".format(address))

    # Service the client
    process_client(clientsocket)


from sys import platform
import pandas as pd
import numpy as np
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.metrics.pairwise import cosine_similarity
from tabulate import tabulate
import string
import settings
df = pd.read_csv("Cleaned_dataset.csv")

df = df.iloc[0:10000,:]

features = ['Name', 'Platform', 'Genre']
def combine_features (row):
    return row['Name'] + " " +  row['Platform'] + " " + row['Genre']

searchTerms = []
df["combine_features"] = df.apply(combine_features, axis=1)

def get_genre_from_name(name):
    genres_to_return = []
    sep_games = name.split()
    print (sep_games)
    i = 0
    while (i < len(sep_games)):
        for index, row in df.iterrows():

            all_games_with_no_spaces = ""
            all_genres = row['Genre'].lower()
            all_games  = row['Name'].lower()
            all_games_with_no_spaces += all_games.replace (" ", "" )
            if all_games_with_no_spaces in sep_games[i] or sep_games[i] in all_games_with_no_spaces:
                 genres_to_return.append(all_genres)
        i = i + 1
    genres_to_return = set(genres_to_return)
    return(genres_to_return)

def list_to_string(lst):
    game_string  = ""
    for g in lst:
        game_string += g + " "
    return game_string

def get_genres():
  print("Enter your favourite video game genres (Action, sport, Shooter, etc.)")
  genres = input("type 'skip' OR if multiple separate them with comma:  ")
  genres = " ".join(["".join(n.split()) for n in genres.lower().split(',')])
  return genres

def get_platforms():
  print("\nEnter your favourite gaming platform(s) (PC, Playstation, etc.)")
  platforms = input("type 'skip' OR if multiple separate them with comma:  ")
  platforms = " ".join(["".join(n.split()) for n in platforms.lower().split(',')])
  return platforms

def get_games():
  print("\nEnter some games that you previously played and enjoyed (Wii Sports, Resident Evil, Call of Duty, etc.)")
  games = input("type 'skip' OR if multiple separate them with comma:  ")
  games = " ".join(["".join(n.split()) for n in games.lower().split(',')])
  return games

def get_searchTerms():

  genre = get_genres()
  if genre != 'skip':
    searchTerms.append(genre)

  platform = get_platforms()
  if platform != 'skip':
    searchTerms.append(platform)

  game = get_games()
  genres_from_games = []
  if game != 'skip':
    genres_from_games = (get_genre_from_name(game))
    str_genres_from_games = list_to_string(genres_from_games)
    searchTerms[0] = searchTerms[0] + " " + str_genres_from_games
  # print (searchTerms)
  return searchTerms

def make_recommendation(searchTerms, games = df):
  new_row = games.iloc[-1,:].copy()

  # searchTerms = get_searchTerms()
  new_row.iloc[-1] = " ".join(searchTerms)
  games = df.append(new_row)

  count = CountVectorizer(stop_words='english')
  count_matrix = count.fit_transform(games['combine_features'])

  cosine_sim  = cosine_similarity(count_matrix, count_matrix)
  settings.games = games
  return cosine_sim
  # settings.sim_scores = list(enumerate(cosine_sim2[-1,:]))
  # settings.sim_scores = sorted(settings.sim_scores, key=lambda x: x[1], reverse=True)

  # lst = []
  # for i in range(1, 50):
  #   indx = settings.sim_scores[i][0]

  #   format_dec = "{:.2f}%".format((((settings.sim_scores[i][1])+1.0)/2.0)*100.0)
  #   tmp = [settings.games['Name'].iloc[indx],settings.games['Genre'].iloc[indx],settings.games['Platform'].iloc[indx], settings.games['Year_of_Release'].iloc[indx], settings.games['Publisher'].iloc[indx],
  #   settings.games['Critic_Score'].iloc[indx], settings.games['User_Score'].iloc[indx], settings.games['Rating'].iloc[indx], format_dec]
  #   lst.append(tmp)
  #   return lst
  # print(tabulate(lst, headers=['Name','Genre', 'Platform', 'Year_of_Release', 'Publisher','Critic_Score', 'User_Score', 'Rating', 'Compatibility']))

make_recommendation(searchTerms)


from flask import Flask, request, render_template
import numpy as np
import tensorflow as tf
from tensorflow.keras.preprocessing import image
import os

app = Flask(__name__)

# Get the absolute path to your application's directory
#app_directory = os.path.dirname(os.path.abspath(__file__))

# Construct the absolute path to model.keras
#model_file_path = os.path.join(app_directory, "/home/deepak04/mysite/plant_disease_prediction.h5")

# Load the trained Keras model without custom objects
#model_keras = tf.keras.models.load_model(model_file_path)

# Specify the directory and model file name
directory = ''
model_filename = 'plant_disease_prediction.h5'

# Construct the full filepath
model_filepath = os.path.join(directory, model_filename)
print(model_filepath)
# Load the Keras model
model_keras = tf.keras.models.load_model(model_filepath)

output_class = ["corn maize_northen leaf blight","Corn(maize)_Cercospora_leaf_spot","Orange", "Peach_bacterial_spot", "Peach_healthy", "Pepper bell bacterial spot", "pepper bell healthy", "potato early blight", "potato helathy", "potato late blight","rasberry healthy","squash powdery mildew","strawberry leaf scorch","strawberry healthy","Tomato bacterial spot","Tomato early blight","Tomato healthy","Tomato late blight","Tomato leaf mold","Tomato mosaic virus","Tomato septoria leaf spot","Tomato spider mites","Tomato target spot","Tomato yellow leaf curl virus","apple scab","apple blac rot","apple cedar apple rust","apple helathy","blueberry healthy","cherry(including sour) powder mildew","cherry(including sour)healthy","corn maize common rust","corn maize healthy","grape esca","grape black rot","grape healthy","grape leaf blight","soyabean healthy"]

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/predict', methods=['POST'])
def predict():
    # Get the uploaded image
    img = request.files['image']

    if img.filename == '':
        return render_template('index.html', error="No file selected")

    img_path = "static/uploaded_image.jpg"
    img.save(img_path)

    test_image = image.load_img(img_path, target_size=(224, 224))
    test_image = image.img_to_array(test_image) / 255
    test_image = np.expand_dims(test_image, axis=0)

    predicted_array = model_keras.predict(test_image)
    predicted_value = output_class[np.argmax(predicted_array)]
    predicted_accuracy = round(np.max(predicted_array) * 100, 2)

    return render_template('index.html', prediction_value=predicted_value,
                               prediction_accuracy=predicted_accuracy,image_path=img_path)

if __name__ == '__main__':
    app.run(debug=True)


import requests
from bs4 import BeautifulSoup
import os
#os.chdir('~/crawl')

from selenium import webdriver
from selenium.webdriver import FirefoxOptions
from selenium.webdriver.common.by import By
opts = FirefoxOptions()
opts.add_argument("--headless")
browser = webdriver.Firefox(firefox_options=opts)
#browser = webdriver.Firefox()
browser.get(("https://investment.credit-suisse.com/Search/Start?start=1&PageContext=ArticleSearch"))
html_source = browser.page_source

browser.find_element_by_xpath("//select[@id='DomicilePoolpartyConceptId']/option[@value='http://poolpartyw.csintra.net/SolutionNetThesaurus/Switzerland']").click()
browser.find_element_by_xpath("//select[@id='UiLanguagePoolpartyConceptId']/option[@value='http://poolpartyw.csintra.net/SolutionNetThesaurus/English']").click()
browser.find_element_by_id('loginButton').click()

globalCount = 0
count = 0
url = browser.current_url

current = url

while True:
    print(browser.current_url)
    links = []
    sources = []
    for url in browser.find_elements_by_xpath('//a[starts-with(@href, "/Article")]'):
        article = url.get_attribute('href')
        links.append(article)
    for url in links:
        browser.get(url)
        print(browser.current_url)
        content = browser.page_source
        sources.append(content)
        text_file = open(os.path.join("~/crawl/rawDat",str(globalCount)+"_Output.txt"), "w")
        text_file.write(content)
        text_file.close()
        print(globalCount)
        globalCount = globalCount + 1
    browser.get(current)
    count = count + 25
    current = 'https://investment.credit-suisse.com/Search/Start?start=%s&PageContext=ArticleSearch' % (count)


from __future__ import unicode_literals

import json
import datetime

from django.template.defaultfilters import escape

from program.models import Program
from notification.models import Notif
from ourjseditor import api
from .models import Comment

# /program/PRO_ID/comment/new
@api.StandardAPIErrors("POST")
@api.login_required
def new_comment(request, program_id):
    data = json.loads(request.body)

    # A JSON of `null` gets parsed into a Python of `None`
    # If parent isn't passed, KeyError, caught by StandardAPIErrors
    parent_comment = data["parent"]
    if parent_comment is None:
        depth = 0
    else:
        try:
            parent_comment = Comment.objects.get(comment_id=parent_comment, program_id=program_id)
        except Comment.DoesNotExist:
            return api.error("Invalid comment parent")
        depth = parent_comment.depth + 1

    if depth > 1:
        return api.error("Comments have gone too deep!")

    if parent_comment is not None:
        parent_comment.reply_count += 1
        parent_comment.save()

    program = Program.objects.get(program_id=program_id)

    created_comment = Comment.objects.create(
        user=request.user,
        program=program,
        parent=parent_comment,
        depth=depth,
        content=data["content"],
        original_content=data["content"],
    )

    link = "/program/{0}#comment-{1}".format(created_comment.program.program_id, created_comment.comment_id)

    if depth == 0:
        if program.user != created_comment.user:
            Notif.objects.create(
                target_user=program.user,
                link=link,
                description="{0} left a comment on your program, {1}".format(
                    escape(request.user.profile.display_name), escape(program.title)
                ),
                source_comment=created_comment
            )
    else:
        # Create a list of everyone in the comment thread and spam them all
        to_notify = set(Comment.objects
            .filter(parent=parent_comment)
            .exclude(user=parent_comment.user) # Not the thread starter, they get a different message
            .exclude(user=created_comment.user) # Not the user who posted this comment
            .values_list("user", flat=True)
        )

        for user in to_notify:
            Notif.objects.create(
                target_user_id=user,
                link=link,
                description="{0} commented on a thread on {1}".format(
                    escape(request.user.profile.display_name), escape(program.title)
                ),
                source_comment=created_comment
            )

        # Notify the original comment creator separately, if that's not the same person that posted this reply
        if parent_comment.user != created_comment.user:
            Notif.objects.create(
                target_user=parent_comment.user,
                link=link,
                description="{0} replied to your comment on {1}".format(
                    escape(request.user.profile.display_name), escape(program.title)
                ),
                source_comment=created_comment
            )

    response = api.succeed({"id": created_comment.comment_id}, status=201)
    response["Location"] = link
    return response

# /api/program/PRO_ID/comment/COMMENT_ID
# /api/comment/COMMENT_ID
@api.StandardAPIErrors("GET", "PATCH", "DELETE")
def comment(request, *args):
    if len(args) == 1:
        comment_id = args[0]

        requested_comment = Comment.objects.get(comment_id=comment_id)
    elif len(args) == 2:
        program_id = args[0]
        comment_id = args[1]

        requested_comment = Comment.objects.get(program_id=program_id, comment_id=comment_id)

    if request.method == "GET":
        return api.succeed(requested_comment.to_dict())

    # Comment editing!
    elif request.method == "PATCH":
        data = json.loads(request.body)

        if request.user != requested_comment.user:
            return api.error("Not authorized.", status=401)

        requested_comment.content = data["content"]
        requested_comment.edited = datetime.datetime.now()

        requested_comment.save()

        return api.succeed()
    elif request.method == "DELETE":
        if request.user != requested_comment.user:
            return api.error("Not authorized.", status=401)

        parent = requested_comment.parent
        if parent is not None:
            parent.reply_count -= 1
            parent.save()

        requested_comment.delete()

        return api.succeed()

# Endpoint for what KA calls replies, i.e. comments on comments, i.e. comments with a depth > 0
# Note: POST requests for these are still made to /api/program/PRO_ID/comments, just with "parent": "COMMENT_ID"
# /api/program/PRO_ID/comment/COMMENT_ID/comments
# /api/comment/COMMENT_ID/comments
@api.StandardAPIErrors("GET")
def comment_comments(request, *args):
    if len(args) == 1:
        comment_id = args[0]

        comments = Comment.objects.select_related("user__profile").filter(parent__comment_id=comment_id).order_by("created")
    elif len(args) == 2:
        program_id = args[0]
        comment_id = args[1]

        comments = Comment.objects.select_related("user__profile").filter(program_id=program_id, parent__comment_id=comment_id).order_by("created")

    comments = list(comments)
    return api.succeed({
        "comments": [c.to_dict() for c in comments]
    })

# /program/PRO_ID/comments
@api.StandardAPIErrors("GET")
def program_comments(request, program_id):
    comments = list(Comment.objects.select_related("user__profile").filter(program_id=program_id, depth=0).order_by("-created"))
    return api.succeed({
        "comments": [c.to_dict() for c in comments]
    })


import pandas as pd
import re
from utils import ANALYTICS_DATASET, ENVIRONMENT_SHORT_NAME

def get_data_archiving(sql_file):
    """Run SQL query and save data in a dataframe."""

    params = {"{{ANALYTICS_DATASET}}": ANALYTICS_DATASET}

    file = open(sql_file, "r")
    sql = file.read()

    for param, table_name in params.items():
        sql = sql.replace(param, table_name)

    archives_df = pd.read_gbq(sql, dialect="standard")

    return archives_df

def preprocess_data_archiving(
    _df,
    object_type,
    parent_folder_to_archive,
    limit_inactivity_in_days,
):

    # Compute the number of days since last activity of a card
    _df = _df.assign(
        days_since_last_execution=lambda _df: pd.to_datetime("today")
        - _df["last_execution_date"].dt.tz_localize(None)
    )

    if ENVIRONMENT_SHORT_NAME == "prod":
        _df["destination_collection_id"] = (  # Get the archive collection id
            _df["archive_location_level_2"]
            .dropna()
            .str.split("/")
            .apply(lambda x: x[-1])
        )
        _df = _df[
            ~_df["archive_location_level_2"].isna()
        ]  # Remove elements for which destination collection is empty.
        # Filter the inactive cards in the folder we want to archive.
        _df = _df[
            (
                _df["days_since_last_execution"]
                >= pd.to_timedelta(limit_inactivity_in_days, unit="d")
            )
            & (_df["parent_folder"].isin(parent_folder_to_archive))
        ]

    if ENVIRONMENT_SHORT_NAME == "dev" or ENVIRONMENT_SHORT_NAME == "stg":
        _df["destination_collection_id"] = 29
        # In dev, we consider a card to be inactive after 1 day of inactivity.
        _df = _df[(_df["days_since_last_execution"] >= pd.to_timedelta(1, unit="d"))]

    if object_type == "card":
        _df_to_archive = (
            _df.drop("collection_id", axis=1)
            .rename(
                columns={
                    "card_id": "id",
                    "card_name": "name",
                    "card_collection_id": "collection_id",
                }
            )
            .assign(
                object_type=object_type
            )  # Take the min of the 'archive_question' boolean to be more restrictive
        )

        _dict_to_archive = (  # Stock data in a dict
            _df_to_archive[
                [
                    "id",
                    "name",
                    "object_type",
                    "collection_id",
                    "destination_collection_id",
                    "total_users",
                    "total_views",
                    "nbr_dashboards",
                    "last_execution_date",
                    "last_execution_context",
                    "total_errors",
                    "parent_folder",
                    "days_since_last_execution",
                ]
            ]
            .assign(
                destination_collection_id=lambda _df: _df[
                    "destination_collection_id"
                ].astype(int)
            )
            .sort_values("id")
            .drop_duplicates()
            .to_dict(orient="records")
        )

        return _dict_to_archive

class move_to_archive:
    def __init__(self, movement, metabase, gcp_project, analytics_dataset):
        self.movement = movement
        self.id = movement.get("id", None)
        self.name = movement.get("name", None)
        self.object_type = movement.get("object_type", None)
        self.destination_collection = movement.get("destination_collection_id", None)
        self.collection_id = movement.get("collection_id", None)
        self.last_execution_date = movement.get("last_execution_date", None)
        self.last_execution_context = movement.get("last_execution_context", None)
        self.parent_folder = movement.get("parent_folder", None)
        self.gcp_project = gcp_project
        self.analytics_dataset = analytics_dataset

        self.metabase_connection = metabase

    def rename_archive_object(self):
        """Rename the object to archive. Add ['Archive - '] prefix to object name."""

        if re.search("archive", self.name, re.IGNORECASE):
            archive_name = self.name
        else:
            archive_name = "[Archive] - " + self.name

        params = {"name": archive_name}

        if self.object_type == "card":
            result = self.metabase_connection.put_card(self.id, params)

        return result

    def move_object(self):
        """Move the object from its original collection to the archive collection."""

        id_list = [self.id]

        if self.object_type == "card":
            result = self.metabase_connection.update_card_collections(
                id_list, self.destination_collection
            )

        archived_logs = []

        if result.get("status") == "ok":
            archived_logs.append(
                {
                    "id": self.id,
                    "object_type": self.object_type,
                    "status": "success",
                    "new_collection_id": self.destination_collection,
                    "previous_collection_id": self.collection_id,
                    "archived_at": pd.Timestamp.now(),
                    "last_execution_date": self.last_execution_date,
                    "last_execution_context": self.last_execution_context,
                    "parent_folder": self.parent_folder,
                }
            )
        else:
            archived_logs.append(
                {
                    "id": self.id,
                    "object_type": self.object_type,
                    "status": result.get("status"),
                    "new_collection_id": self.destination_collection,
                    "previous_collection_id": self.collection_id,
                    "archived_at": pd.Timestamp.now(),
                    "last_execution_date": self.last_execution_date,
                    "last_execution_context": self.last_execution_context,
                    "parent_folder": self.parent_folder,
                }
            )
        return archived_logs

    def save_logs_bq(self):
        """Save the movement in a BQ table."""

        archived_logs_dict = self.move_object()
        archived_logs_df = pd.DataFrame(archived_logs_dict)
        archived_logs_df.to_gbq(
            f"""{self.gcp_project}.{self.analytics_dataset}.logs_metabase_archiving""",
            project_id=self.gcp_project,
            if_exists="append",
        )
        return "Logs saved in BQ"


import multiprocessing as mp
from parallel_data_processing.parallel_join.hash_join import hash_join
def range_partition(data, range_indices):

    result = []

    new_data = data[:]
    new_data=sorted(new_data,key=lambda new_data:new_data[1])

    # Calculate the number of bins
    range_index = len(range_indices)

    # For each bin, perform the following
    for i in range(range_index):
        # Find elements to be belonging to each range
        lower_part = [x for x in new_data if x[1] < range_indices[i]]
        # Add the partitioned list to the result
        result.append(lower_part)
        # Find the last element in the previous partition
        last_element = lower_part[-1]
        # Find the index of of the last element
        last = new_data.index(last_element)
        # Remove the partitioned list from the dataset
        new_data = new_data[last + 1:]

    #append the remeaning list
    result.append(new_data)

    return result

def disjoint_join(table_1, table_2, processor_num):

    result = []

    ### START CODE HERE ###

    # --- Implement the algorithm

    # Partition T1 & T2 into sub-tables using range_partition().
    partition_result_1=range_partition(table_1,[10,20])
    partition_result_2=range_partition(table_2,[10,20])
    data_size=len(partition_result_1)
    assert (data_size==processor_num), "The number of the sub-tables must be the equal to the n_processor"
    pool = mp.Pool(processes=processor_num)

    parallel_result=[pool.apply_async(hash_join,[partition_result_1[index],partition_result_2[index]])
                     for index in range(data_size)]

    for processor in parallel_result:
        output=processor.get()
        result.append(output)

    ### END CODE HERE ###

    return result

if __name__ == '__main__':
    table_r = [('Adele', 8), ('Bob', 22), ('Clement', 16), ('Dave', 23), ('Ed', 11),
               ('Fung', 25), ('Goel', 3), ('Harry', 17), ('Irene', 14), ('Joanna', 2),
               ('Kelly', 6), ('Lim', 20), ('Meng', 1), ('Noor', 5), ('Omar', 19)]

    table_s = [('Arts', 8), ('Business', 15), ('CompSc', 2), ('Dance', 12), ('Engineering', 7),
               ('Finance', 21), ('Geology', 10), ('Health', 11), ('IT', 18)]

    print(disjoint_join(table_r,table_s,3))


import glob
import os

import corner
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import scipy.stats

import matplotlib.lines as mlines

VIOLET_COLOR = "#8E44AD"
BILBY_BLUE_COLOR = '#0072C1'

PARAMS = dict(
    # chi_eff=dict(l=r"$\chi_{eff}$", r=(-1, 1)),
    # chi_p=dict(l=r"$\chi_{p}$", r=(-1, 1)),
    cos_tilt_1=dict(l=r"$\cos(t1)$", r=(-1, 1)),
    # cos_tilt_2=dict(l=r"$\cos(t2)$", r=(-1, 1)),
    # cos_theta_12=dict(l=r"$\cos \theta_{12}$", r=(-1, 1)),
    cos_theta_1L=dict(l=r"$\cos \theta_{1L}$", r=(-1, 1)),
    tilt_1=dict(l=r"$tilt_{1}$", r=(0, np.pi)),
    theta_1L=dict(l=r"$\theta_{1L}$", r=(0, np.pi)),
    diff=dict(l=r"diff", r=(-np.pi, np.pi)),
)

CORNER_KWARGS = dict(
    smooth=0.9,
    label_kwargs=dict(fontsize=30),
    title_kwargs=dict(fontsize=16),
    truth_color='tab:orange',
    quantiles=[0.16, 0.84],
    levels=(1 - np.exp(-0.5), 1 - np.exp(-2), 1 - np.exp(-9 / 2.)),
    plot_density=False,
    plot_datapoints=False,
    fill_contours=True,
    max_n_ticks=3,
    verbose=False,
    use_math_text=True,
)

def add_agn_samples_to_df(df):
    df['s1x'], df['s1y'], df['s1z'] = df['spin_1x'], df['spin_1y'], df['spin_1z']
    df['s2x'], df['s2y'], df['s2z'] = df['spin_2x'], df['spin_2y'], df['spin_2z']
    df['s1_dot_s2'] = (df['s1x'] * df['s2x']) + (df['s1y'] * df['s2y']) + (df['s1z'] * df['s2z'])
    df['s1_mag'] = np.sqrt((df['s1x'] * df['s1x']) + (df['s1y'] * df['s1y']) + (df['s1z'] * df['s1z']))
    df['s2_mag'] = np.sqrt((df['s2x'] * df['s2x']) + (df['s2y'] * df['s2y']) + (df['s2z'] * df['s2z']))
    df['cos_theta_12'] = df['s1_dot_s2'] / (df['s1_mag'] * df['s2_mag'])
    # Lhat = [0, 0, 1]
    df['cos_theta_1L'] = df['s1z'] / (df['s1_mag'])
    print(df['cos_theta_1L'].describe())
    return df

def calculate_weight(df, sigma):
    mean = 1
    clip_a, clip_b = -1, 1
    a, b = (clip_a - mean) / sigma, (clip_b - mean) / sigma
    costheta_prior = scipy.stats.truncnorm(a=a, b=b, loc=mean, scale=sigma)
    df['weight'] = np.abs(np.exp(costheta_prior.logpdf(df['cos_theta_1L'])))
    df['weight'] = df['weight'] * np.abs(np.exp(costheta_prior.logpdf(df['cos_theta_12'])))
    return df

def process_res(r):
    params = list(PARAMS.keys())
    labels = [PARAMS[p]['l'] for p in params]
    range = [PARAMS[p]['r'] for p in params]

    label = os.path.basename(r).split("_")[0]
    df = pd.read_csv(r, " ")
    df = add_agn_samples_to_df(df)
    df['tilt1'], df['theta_1L'] = np.arccos(df['cos_tilt_1']), np.arccos(df['cos_theta_1L'])
    df['diff'] = df['tilt1'] - df['theta_1L']

    df = calculate_weight(df, sigma=0.5)
    kwargs = CORNER_KWARGS.copy()
    kwargs.update(labels=labels, range=range)

    fig = corner.corner(df[params], color=BILBY_BLUE_COLOR, **kwargs)

    #
    # dfnew = df.copy()
    # dfnew = dfnew.sample(
    #     frac=0.1,
    #     weights='weight',
    #     replace=True
    # )
    # normalising_weights_s2 = np.ones(len(dfnew)) * len(df) / len(dfnew)
    # fig = corner.corner(dfnew[params], color=VIOLET_COLOR, weights=normalising_weights_s2,  fig=fig, **kwargs)
    #
    # orig_line = mlines.Line2D([], [], color=BILBY_BLUE_COLOR, label="Original Posterior")
    # weighted_line = mlines.Line2D([], [], color=VIOLET_COLOR,label=r"Reweighted Posterior" )
    # plt.legend(handles=[orig_line, weighted_line], fontsize=25,
    #            frameon=False,
    #            bbox_to_anchor=(1, len(PARAMS)), loc="upper right")

    fig.suptitle(label, fontsize=24)
    fig.savefig(f"{label}.png")
    plt.close(fig)

def main():
    res = glob.glob(
        "../datafiles/samples/downsampled_posterior_samples_v1.0.0/*_samples.dat")
    for r in res:
        try:
            process_res(r)
            print(f"Processed {r}")
        except Exception:
            print(f"Skipping {r}")

if __name__ == '__main__':
    # main()
    process_res("../datafiles/samples/downsampled_posterior_samples_v1.0.0/GW150914_downsampled_posterior_samples.dat")


from datetime import datetime, timedelta
import requests
import json
import eel

@eel.expose
def ten_newest_question(tag):
    url = "http://api.stackexchange.com/2.2/search?order=desc&sort=creation&tagged=" + tag + \
          "&site=stackoverflow&filter=withbody&pagesize=10"
    data = requests.get(url).json()

    with open('./nginx-1.17.8/html/demo/json/ten_newest_question.json', 'w') as f:
        json.dump(data, f)

@eel.expose
def ten_voted_question(tag):
    last_week = datetime.today() - timedelta(days=7)
    url = "http://api.stackexchange.com/2.2/search?order=desc&sort=votes&tagged=" + tag + \
          "&site=stackoverflow&filter=withbody&pagesize=10&fromdate="+str(int(last_week.timestamp()))
    data = requests.get(url).json()

    with open('./nginx-1.17.8/html/demo/json/ten_voted_question.json', 'w') as f:
        json.dump(data, f)

eel.init('nginx-1.17.8')
eel.start('html/demo/index.html')


import pytest
import requests

@pytest.fixture
def api_base_address():
    return "http://localhost:5000"

@pytest.fixture
def pq_data():
    return [(0, 4), (1, 7)]

@pytest.fixture
def pq_get_data():
    return {"highest": {"index": 1, "key": 7}, "content": [
        {"index": 1, "key": 7}, {"index": 0, "key": 4}
    ]}

@pytest.fixture
def pq_endpoint(api_base_address):
    return f"{api_base_address}/queue"

@pytest.fixture
def pq_index_endpoint(api_base_address):
    return f"{api_base_address}/queue/0"

def test_hello_world(api_base_address):
    res = requests.get(api_base_address)
    assert res.status_code == 200
    data = res.json()
    assert data == "Hello, World"

def test_404_scenarios(pq_endpoint, pq_index_endpoint):

    res = requests.get(pq_endpoint)
    assert res.status_code == 404
    res = requests.delete(pq_endpoint)
    assert res.status_code == 404

    res = requests.get(pq_index_endpoint)
    assert res.status_code == 404
    res = requests.put(pq_index_endpoint, data={"key": "10"})
    assert res.status_code == 404

def test_pq_operations(api_base_address, pq_endpoint, pq_data, pq_get_data):

    # Testint post requests to pq indices
    for index, key in pq_data:
        pq_index_endpoint = f"{api_base_address}/queue/{index}"
        res = requests.post(pq_index_endpoint, data={"key": key})
        assert res.status_code == 201
        assert res.json() == {"index": index, "key": key}

    # Testing get request to pq
    res = requests.get(pq_endpoint)
    assert res.status_code == 200
    assert res.json() == pq_get_data

    # Testing put and get request to pq index
    index, key = 1, 99
    pq_index_endpoint = f"{api_base_address}/queue/{index}"
    res = requests.put(pq_index_endpoint, data={"key": key})
    assert res.status_code == 201
    assert res.json() == {"index": index, "key": key}
    res = requests.get(pq_index_endpoint)
    assert res.status_code == 200
    assert res.json() == {"index": index, "key": key}

    # Testing delete request to pq to get highest priority item
    res = requests.delete(pq_endpoint)
    assert res.status_code == 200
    assert res.json() == {"index": index, "key": key}


#!/usr/bin/env python3
import collections
import os
import subprocess

DATE = "2022-01-01"
BRANCH = 'main'

print("Statistics on the %s branch after %s" % (BRANCH, DATE))
print("cwd: %s" % os.getcwd())
proc = subprocess.run(['git', 'log', '--after=%s' % DATE, BRANCH],
                      stdout=subprocess.PIPE,
                      universal_newlines=True)
authors = collections.Counter()
for line in proc.stdout.splitlines():
    if line.startswith('Author: '):
        line = line[8:]
        name = line.split(' <')[0]
        authors[name] += 1
for name, commits in authors.most_common():
    if commits < 5:
        break
    print(commits, name)


import argparse
import zipfile
import io
from lxml import etree

namespace = "{http://schemas.microsoft.com/3dmanufacturing/core/2015/02}"

if __name__ == "__main__":

    parser = argparse.ArgumentParser(description='Strip metadata from 3MF files')
    parser.add_argument('source', metavar='source', type=str, nargs='+',
                        help='Source 3mf file')
    parser.add_argument('dest', metavar='dest', type = str, nargs='+', help='Destination of the stripped file')

    args = parser.parse_args()

    new_model_data = ""

    try:
        with zipfile.ZipFile(args.source[0], "r") as source_archive, zipfile.ZipFile(args.dest[0], "w", compression = zipfile.ZIP_DEFLATED) as target_archive:
            model_data = source_archive.open("3D/3dmodel.model").read()
            root = etree.fromstring(model_data)

            search = './/{0}metadata'.format(namespace)

            for e in root.findall(search):
                parent = e.getparent()
                try:
                    root.remove(e)
                except:
                    pass

            new_model_data = etree.tostring(root,
                            pretty_print=True,
                            xml_declaration=True,
                            encoding='UTF-8')

            for source_archive_info in source_archive.infolist():
                with source_archive.open(source_archive_info) as source_archive_file:
                    if source_archive_info.filename == "3D/3dmodel.model":
                        content = new_model_data
                    else:
                        content = source_archive_file.read()
                    target_archive.writestr(source_archive_info.filename, content)

    except Exception as e:
        print("oh no!", e)


from tkinter import simpledialog
import math
import pygame

pygame.init()

tamanho = (850, 560)
tela = pygame.display.set_mode(tamanho)
pygame.display.set_caption("Space Marker")

# Definir o ícone da janela
icone = pygame.image.load("space.png")
pygame.display.set_icon(icone)
fundo = pygame.image.load("bg.jpg")
pygame.mixer.music.load("space_machine.mp3")
pygame.mixer.music.play(-1)

estrelas = []  # Lista para armazenar as estrelas
linhas = []  # Lista para armazenar as linhas

instrucoes = [
    "Pressione F10 para Salvar os Pontos",
    "Pressione F11 para Carregar os Pontos",
    "Pressione F12 para Deletar os Pontos"
]
# Loop principal
running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_ESCAPE:
                running = False
            elif event.key == pygame.K_F10:
                # Lógica para salvar os pontos
                arquivo = open("pontos.txt", "w")
                for posicao, nome in estrelas:
                    arquivo.write(f"{nome},{posicao[0]},{posicao[1]}\n")
                arquivo.close()
                print("Pontos salvos")
            elif event.key == pygame.K_F11:
                # Lógica para carregar os pontos
                arquivo = open("pontos.txt", "r")
                estrelas = []
                for linha in arquivo:
                    dados = linha.strip().split(",")
                    nome = dados[0]
                    posicao = (int(dados[1]), int(dados[2]))
                    estrelas.append((posicao, nome))
                arquivo.close()
                print("Pontos carregados")
            elif event.key == pygame.K_F12:
                # Lógica para deletar os pontos
                estrelas = []
                print("Pontos deletados")
        elif event.type == pygame.MOUSEBUTTONDOWN:
            mouse_pos = pygame.mouse.get_pos()
            nome_estrela = simpledialog.askstring("Nome da estrela", "Digite o nome da estrela:")
            if nome_estrela:
                # Marcar a estrela na tela
                pygame.draw.circle(tela, (255, 0, 0), mouse_pos, 5)
                fonte = pygame.font.Font(None, 20)
                texto = fonte.render(nome_estrela, True, (255, 255, 255))
                tela.blit(texto, (mouse_pos[0] + 10, mouse_pos[1]))
                estrelas.append((mouse_pos, nome_estrela))
            else:
                print("Nenhum nome fornecido")

    # Atualizar tela
    tela.blit(fundo, (0, 0))

    # Desenhar nomes das estrelas na tela
    for posicao, nome in estrelas:
        fonte = pygame.font.Font(None, 33)
        texto = fonte.render(nome, True, (255, 255, 255))
        tela.blit(texto, (posicao[0] + 10, posicao[1]))

    # Desenhar linhas entre as estrelas e exibir distâncias
    for i in range(len(estrelas)):
        for j in range(i + 1, len(estrelas)):
            posicao_estrela1, nome_estrela1 = estrelas[i]
            posicao_estrela2, nome_estrela2 = estrelas[j]

            # Desenhar linha entre as estrelas
            pygame.draw.line(tela, (255, 0, 255), posicao_estrela1, posicao_estrela2)

            # Calcular a distância entre as estrelas
            distancia = math.sqrt(
                (posicao_estrela2[0] - posicao_estrela1[0]) * 2 + (posicao_estrela2[1] - posicao_estrela1[1]) * 2
            )
            distancia_texto = f"{distancia:.2f}"
            fonte_distancia = pygame.font.Font(None, 20)
            texto_distancia = fonte_distancia.render(distancia_texto, True, (255, 255, 255))

            # Posicionar o texto da distância no meio da linha
            texto_posicao_x = (posicao_estrela1[0] + posicao_estrela2[0]) // 2
            texto_posicao_y = (posicao_estrela1[1] + posicao_estrela2[1]) // 2
            tela.blit(texto_distancia, (texto_posicao_x, texto_posicao_y))

    # Exibir instruções na tela
    for i, instrucao in enumerate(instrucoes):
        fonte_instrucao = pygame.font.Font(None, 25)
        texto_instrucao = fonte_instrucao.render(instrucao, True, (255, 255, 255))
        tela.blit(texto_instrucao, (10, 10 + i * 30))

    # Exibir informações do autor
    fonte_autor = pygame.font.Font(None, 20)
    texto_autor1 = fonte_autor.render("Emily Biecoski 1134316", True, (255, 255, 255))
    tela.blit(texto_autor1, (10, tamanho[1] - 20))

    texto_autor2 = fonte_autor.render("Carlos Henrique Ferrão 1135230", True, (255, 255, 255))
    tela.blit(texto_autor2, (10, tamanho[1] - 40))

    pygame.display.flip()

# Encerrar o pygame
pygame.quit()