from dataclasses import dataclass
from typing import Optional, Tuple

import torch.nn as nn
import torch
from transformers.models.dpr.modeling_dpr import DPRReaderOutput
from transformers.modeling_outputs import QuestionAnsweringModelOutput, ModelOutput, SequenceClassifierOutput
from transformers.models.vilt.modeling_vilt import ViltForImagesAndTextClassificationOutput
from transformers import VisualBertForQuestionAnswering, VisualBertForVisualReasoning, LxmertForQuestionAnswering
from transformers import ViltProcessor, ViltForImagesAndTextClassification
from transformers import BertForQuestionAnswering

from meerqat.train.losses import _calc_mml

class Trainee(nn.Module):
    """Base class for all Trainee models (to be trained by a Trainer)
    Should implement a forward function that returns loss between output and target (as a tuple, dict or ModelOutput)
    The actual forward pass should be done using the model attribute
    """
    def __init__(self, model):
        super().__init__()
        self.model = model

@dataclass
class DPRReaderForQuestionAnsweringOutput(DPRReaderOutput):
    """Same as DPRReaderOutput with an extra loss attribute (or as QuestionAnsweringModelOutput with relevance_logits)

    N. B. unfortunately we have to redefine everything so that loss is the first attribute
    """
    loss: Optional[torch.FloatTensor] = None
    start_logits: torch.FloatTensor = None
    end_logits: torch.FloatTensor = None
    relevance_logits: torch.FloatTensor = None
    hidden_states: Optional[Tuple[torch.FloatTensor]] = None
    attentions: Optional[Tuple[torch.FloatTensor]] = None

@dataclass
class MultiPassageBERTOutput(QuestionAnsweringModelOutput):
    """
    Same as QuestionAnsweringModelOutput but with start and end log-probabilities

    (equivalent to softmax(start_logits) when there is only one passage per question)
    """
    start_log_probs: torch.FloatTensor = None
    end_log_probs: torch.FloatTensor = None

@dataclass
class BERTRankerOutput(QuestionAnsweringModelOutput):
    """
    Same as MultiPassageBERTOutput but with relevance_logits important for ranking
    """
    loss: Optional[torch.FloatTensor] = None
    relevance_logits: torch.FloatTensor = None

@dataclass
class DPRBiEncoderOutput(ModelOutput):
    """
    Outputs from the question and context encoders
    (same as DPRQuestionEncoderOutput, DPRContextEncoderOutput with prefixes)
    """
    question_pooler_output: Optional[torch.FloatTensor] = None
    question_hidden_states: Optional[Tuple[torch.FloatTensor]] = None
    question_attentions: Optional[Tuple[torch.FloatTensor]] = None
    context_pooler_output: Optional[torch.FloatTensor] = None
    context_hidden_states: Optional[Tuple[torch.FloatTensor]] = None
    context_attentions: Optional[Tuple[torch.FloatTensor]] = None

class DPRBiEncoder(nn.Module):
    """Adapted from https://github.com/facebookresearch/DPR/blob/main/dpr/models/biencoder.py"""
    def __init__(self, question_model, context_model):
        """
        Parameters
        ----------

        question_model: transformers.DPRQuestionEncoder
            Encoder based on BERT used to encode the question/query
        context_model: transformers.DPRContextEncoder
            Encoder based on BERT used to encode the context/evidence/passage
            ('context' is confusing IMO but I keep it for consistency with DPR and transformers)
        """
        super().__init__()
        self.question_model = question_model
        self.context_model = context_model

    def forward(self, question_inputs, context_inputs, return_dict=None):
        """
        Embeds questions and contexts with their respective model and returns the embeddings.

        N - number of questions in a batch
        M - number of passages per questions
        L - sequence length
        d - dimension of the model/embeddings

        Parameters
        ----------
        question_inputs: dict[torch.LongTensor]
            input_ids: torch.LongTensor
                shape (N, L)
            usual BERT inputs, see transformers.DPRQuestionEncoder
        context_inputs: dict[torch.LongTensor]
            input_ids: torch.LongTensor
                shape (N*M, L)
            usual BERT inputs, see transformers.DPRContextEncoder
        return_dict: bool, optional
        """
        return_dict = return_dict if return_dict is not None else self.question_model.config.use_return_dict

        # embed questions and contexts
        question_outputs = self.question_model(**question_inputs)
        context_outputs = self.context_model(**context_inputs)

        return DPRBiEncoderOutput(
            question_pooler_output=question_outputs.pooler_output,
            question_hidden_states=question_outputs.hidden_states,
            question_attentions=question_outputs.attentions,
            context_pooler_output=context_outputs.pooler_output,
            context_hidden_states=context_outputs.hidden_states,
            context_attentions=context_outputs.attentions)

class DPRReaderForQuestionAnswering(Trainee):
    def forward(self,
                input_ids, attention_mask,
                start_positions=None, end_positions=None, answer_mask=None,
                return_dict=None, **kwargs):
        """Based on transformers.BertForQuestionAnswering and dpr.models.Reader"""
        return_dict = return_dict if return_dict is not None else self.model.config.use_return_dict
        # notations: N - number of questions in a batch, M - number of passages per questions, L - sequence length
        N, M, L = input_ids.size()
        outputs = self.model(input_ids, attention_mask, return_dict=True, **kwargs)

        # compute loss
        total_loss = None
        if start_positions is not None and end_positions is not None:
            start_positions = start_positions.view(N * M, -1)
            end_positions = end_positions.view(N * M, -1)
            answer_mask = answer_mask.view(N * M, -1)
            start_logits, end_logits, relevance_logits = outputs[:3]
            start_logits = start_logits.view(N * M, -1)
            end_logits = end_logits.view(N * M, -1)
            relevance_logits = relevance_logits.view(N * M)

            answer_mask = answer_mask.to(device=relevance_logits.device, dtype=torch.float32)

            # sometimes the start/end positions are outside our model inputs, we ignore these terms
            ignored_index = start_logits.size(1)
            start_positions = start_positions.clamp(0, ignored_index)
            end_positions = end_positions.clamp(0, ignored_index)
            loss_fct = nn.CrossEntropyLoss(reduction='none', ignore_index=ignored_index)

            # compute switch loss
            relevance_logits = relevance_logits.view(N, M)
            switch_labels = torch.zeros(N, dtype=torch.long, device=relevance_logits.device)
            switch_loss = torch.sum(loss_fct(relevance_logits, switch_labels))

            # compute span loss
            start_losses = [(loss_fct(start_logits, _start_positions) * _span_mask)
                            for (_start_positions, _span_mask)
                            in zip(torch.unbind(start_positions, dim=1), torch.unbind(answer_mask, dim=1))]

            end_losses = [(loss_fct(end_logits, _end_positions) * _span_mask)
                          for (_end_positions, _span_mask)
                          in zip(torch.unbind(end_positions, dim=1), torch.unbind(answer_mask, dim=1))]
            loss_tensor = torch.cat([t.unsqueeze(1) for t in start_losses], dim=1) + \
                          torch.cat([t.unsqueeze(1) for t in end_losses], dim=1)

            loss_tensor = loss_tensor.view(N, M, -1).max(dim=1)[0]
            span_loss = _calc_mml(loss_tensor)
            total_loss = span_loss + switch_loss

        if not return_dict:
            outputs = outputs.to_tuple()
            return ((total_loss,) + outputs) if total_loss is not None else outputs

        return DPRReaderForQuestionAnsweringOutput(loss=total_loss, **outputs)

class MultiPassageBERT(BertForQuestionAnswering):
    """
    PyTorch/Transformers implementation of Multi-passage BERT by Wang et. al (based on the global normalization by Clark et. al)
    i.e. groups passages per question before computing the softmax (and the NLL loss)
    so that spans scores are comparable across passages

    Code based on transformers.BertForQuestionAnswering, dpr.models.Reader
    and https://github.com/allenai/document-qa/blob/master/docqa/nn/span_prediction.py

    N. B. differences with DPRReaderForQuestionAnswering:
    * no projection layer between BERT and QA-extraction
    * no re-ranking (TODO implement MultiPassageDPRReader?)
    * global normalization

    References
    ----------
    @inproceedings{wang_multi-passage_2019,
        address = {Hong Kong, China},
        title = {Multi-passage {BERT}: {A} {Globally} {Normalized} {BERT} {Model} for {Open}-domain {Question} {Answering}},
        shorttitle = {Multi-passage {BERT}},
        url = {https://www.aclweb.org/anthology/D19-1599},
        doi = {10.18653/v1/D19-1599},
        urldate = {2021-06-14},
        booktitle = {Proceedings of the 2019 {Conference} on {Empirical} {Methods} in {Natural} {Language} {Processing} and the 9th {International} {Joint} {Conference} on {Natural} {Language} {Processing} ({EMNLP}-{IJCNLP})},
        publisher = {Association for Computational Linguistics},
        author = {Wang, Zhiguo and Ng, Patrick and Ma, Xiaofei and Nallapati, Ramesh and Xiang, Bing},
        month = nov,
        year = {2019},
        pages = {5878--5882}
    }

    @inproceedings{clark_simple_2018,
        address = {Melbourne, Australia},
        title = {Simple and {Effective} {Multi}-{Paragraph} {Reading} {Comprehension}},
        url = {https://aclanthology.org/P18-1078},
        doi = {10.18653/v1/P18-1078},
        urldate = {2021-07-08},
        booktitle = {Proceedings of the 56th {Annual} {Meeting} of the {Association} for {Computational} {Linguistics} ({Volume} 1: {Long} {Papers})},
        publisher = {Association for Computational Linguistics},
        author = {Clark, Christopher and Gardner, Matt},
        month = jul,
        year = {2018},
        pages = {845--855},
    }
    """

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.log_softmax = nn.LogSoftmax(1)

    def forward(self,
                input_ids,
                start_positions=None, end_positions=None, answer_mask=None,
                return_dict=None, **kwargs):
        """
        notations:
            N - number of distinct questions
            M - number of passages per question in a batch
            L - sequence length

        Parameters
        ----------
        input_ids: Tensor[int]
            shape (N * M, L)
            There should always be a constant number of passages (relevant or not) per question
        start_positions, end_positions: Tensor[int], optional
            shape (N, M, max_n_answers)
            The answer might be found several time in the same passage, maximum `max_n_answers` times
            Defaults to None (i.e. don’t compute the loss)
        answer_mask: Tensor[int], optional
            shape (N, M, max_n_answers)
            Used to mask the loss for answers that are not `max_n_answers` times in the passage
            Required if start_positions and end_positions are specified
        **kwargs: additional arguments are passed to BERT after being reshape like
        """
        return_dict = return_dict if return_dict is not None else self.config.use_return_dict
        outputs = self.bert(input_ids, return_dict=True, **kwargs)
        sequence_output = outputs[0]
        logits = self.qa_outputs(sequence_output)
        start_logits, end_logits = logits.split(1, dim=-1)
        start_logits = start_logits.squeeze(-1).contiguous()
        end_logits = end_logits.squeeze(-1).contiguous()

        # compute loss
        total_loss, start_log_probs, end_log_probs = None, None, None
        if start_positions is not None and end_positions is not None:
            n_times_m, L = input_ids.size()
            M = start_positions.size(1)
            assert n_times_m % M == 0
            N = n_times_m//M
            # sometimes the start/end positions are outside our model inputs, we ignore these terms
            ignored_index = L
            start_positions = start_positions.clamp(0, ignored_index)
            end_positions = end_positions.clamp(0, ignored_index)
            loss_fct = nn.NLLLoss(reduction='none', ignore_index=ignored_index)

            # reshape from (N * M, L) to (N, M * L) so that all M passages related to the same question
            # will share the same softmax normalization
            start_logits, end_logits = start_logits.view(N, M*L), end_logits.view(N, M*L)
            start_log_probs, end_log_probs = self.log_softmax(start_logits), self.log_softmax(end_logits)
            # after computing the softmax, reshape back to (N * M, L)
            # because the last dimension, L, must match the position indices (i.e. class label) in start_positions, end_positions
            start_log_probs, end_log_probs = start_log_probs.view(N*M, L), end_log_probs.view(N*M, L)
            start_logits, end_logits = start_logits.view(N*M, L), end_logits.view(N*M, L)

            # reshape to match model output
            start_positions, end_positions = start_positions.view(N*M, -1), end_positions.view(N*M, -1)
            answer_mask = answer_mask.to(device=input_ids.device, dtype=torch.float32).view(N*M, -1)

            # compute span loss for each answer position in passage (in range `max_n_answers`)
            start_losses = [(loss_fct(start_log_probs, _start_positions) * _span_mask)
                            for (_start_positions, _span_mask)
                            in zip(torch.unbind(start_positions, dim=1), torch.unbind(answer_mask, dim=1))]

            end_losses = [(loss_fct(end_log_probs, _end_positions) * _span_mask)
                          for (_end_positions, _span_mask)
                          in zip(torch.unbind(end_positions, dim=1), torch.unbind(answer_mask, dim=1))]
            loss_tensor = torch.cat([t.unsqueeze(1) for t in start_losses], dim=1) + \
                          torch.cat([t.unsqueeze(1) for t in end_losses], dim=1)

            # keep the maximum per passage for each question
            loss_tensor = loss_tensor.view(N, M, -1).max(dim=1)[0]
            total_loss = _calc_mml(loss_tensor)

        if not return_dict:
            output = (start_logits, end_logits, start_log_probs, end_log_probs) + outputs[2:]
            return ((total_loss,) + output) if total_loss is not None else output

        return MultiPassageBERTOutput(
            loss=total_loss,
            start_logits=start_logits,
            end_logits=end_logits,
            start_log_probs=start_log_probs,
            end_log_probs=end_log_probs,
            hidden_states=outputs.hidden_states,
            attentions=outputs.attentions,
        )

class BERTRanker(BertForQuestionAnswering):
    """
    BERT-based Ranker Based on transformers.BertForQuestionAnswering
    and https://github.com/allenai/document-qa/blob/master/docqa/nn/span_prediction.py

    """

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.qa_classifier = nn.Linear(self.config.hidden_size, 1)

    def forward(self,
                input_ids,
                switch_labels=None,
                N=None, M=None,
                indices=None, relevants=None,
                return_dict=None, **kwargs):
        """
        notations:
            N - number of distinct questions
            M - number of passages per question in a batch
            L - sequence length

        Parameters
        ----------
        input_ids: Tensor[int]
            shape (N * M, L)
            There should always be a constant number of passages (relevant or not) per question
        **kwargs: additional arguments are passed to BERT after being reshape like
        """
        return_dict = return_dict if return_dict is not None else self.config.use_return_dict

        outputs = self.bert(input_ids, return_dict=True, **kwargs)
        sequence_output = outputs[0]
        relevance_logits = self.qa_classifier(sequence_output[:, 0, :])

        switch_loss = None
        if len(switch_labels) > 0:

            loss_fct = nn.CrossEntropyLoss(reduction='mean')

            # compute switch loss
            relevance_logits = relevance_logits.view(N, M)
            switch_loss = loss_fct(relevance_logits, switch_labels)

        if not return_dict:
            output = (relevance_logits) + outputs[2:]
            return ((switch_loss,) + output) if switch_loss is not None else output

        return BERTRankerOutput(
            loss=switch_loss,
            hidden_states=outputs.hidden_states,
            attentions=outputs.attentions,
            relevance_logits=relevance_logits,
        )

class ViLTRanker(ViltForImagesAndTextClassification):
    """
    ViLT-based Ranker Based on transformers.ViltForImagesAndTextClassification
    """

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        # Classifier head
        num_images = self.config.num_images
        self.qa_classifier = nn.Sequential(
            nn.Linear(self.config.hidden_size * num_images, self.config.hidden_size * num_images),
            nn.LayerNorm(self.config.hidden_size * num_images),
            nn.GELU(),
            nn.Linear(self.config.hidden_size * num_images, 1),
        )

    def forward(self,
                input_ids, pixel_values, pixel_mask,
                output_attentions=None,
                output_hidden_states=None,
                switch_labels=None,
                N=None, M=None,
                indices=None, relevants=None,
                return_dict=None, **kwargs):
        """
        notations:
            N - number of distinct questions
            M - number of passages per question in a batch
            L - sequence length

        Parameters
        ----------
        input_ids: Tensor[int]
            shape (N * M, L)
            There should always be a constant number of passages (relevant or not) per question
        **kwargs: additional arguments are passed to BERT after being reshape like
        """

        output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions
        output_hidden_states = (
            output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states
        )
        return_dict = return_dict if return_dict is not None else self.config.use_return_dict

        if pixel_values is not None and pixel_values.ndim == 4:
            # add dummy num_images dimension
            pixel_values = pixel_values.unsqueeze(1)
        num_images = pixel_values.shape[1]
        if num_images != self.config.num_images:
            raise ValueError(
                "Make sure to match the number of images in the model with the number of images in the input."
            )

        pooler_outputs = []
        hidden_states = [] if output_hidden_states else None
        attentions = [] if output_attentions else None

        for i in range(num_images):
            # forward every image through the model
            outputs = self.vilt(
                input_ids,
                pixel_values=pixel_values[:, i, :, :, :],
                pixel_mask=pixel_mask[:, i, :, :] if pixel_mask is not None else None,
                image_token_type_idx=i + 1,
                output_attentions=output_attentions,
                output_hidden_states=output_hidden_states,
                return_dict=return_dict,
                **kwargs
            )
            pooler_output = outputs.pooler_output if return_dict else outputs[1]
            pooler_outputs.append(pooler_output)
            if output_hidden_states:
                hidden_states.append(outputs.hidden_states)
            if output_attentions:
                attentions.append(outputs.attentions)

        pooled_output = torch.cat(pooler_outputs, dim=-1)
        relevance_logits = self.qa_classifier(pooled_output)

        switch_loss = None
        if len(switch_labels) > 0:

            loss_fct = nn.CrossEntropyLoss(reduction='mean')

            # compute switch loss
            relevance_logits = relevance_logits.view(N, M)
            switch_loss = loss_fct(relevance_logits, switch_labels)

        if not return_dict:
            output = (relevance_logits, hidden_states, attentions)
            return ((switch_loss,) + output) if switch_loss is not None else output

        return ViltForImagesAndTextClassificationOutput(
            loss=switch_loss,
            logits=relevance_logits,
            hidden_states=hidden_states,
            attentions=attentions,
        )


import re

def parse(html):
    # define the regex pattern for the url
    url_pattern = r"https?://(?:www\.)?youtube\.com/embed/(\w+)"

    # use re.search to find the first matching url in the HTML
    match = re.search(url_pattern, html, re.IGNORECASE)

    if match:
        # extract the video ID from the matched url
        video_id = match.group(1)

        # Generate the youtu.be url
        url = f"https://youtu.be/{video_id}"

        return url

def main():
    # get user input (HTML snippet)
    html = input("HTML: ").strip()

    if html.startswith("https://"):
        return None
    else:
        # call the parse function for extraction and print output
        result = parse(html)
        print(result)

if __name__ == "__main__":
    main()


from tkinter import*
from tkinter import ttk
from tkinter import Tk
from PIL import Image, ImageTk
from student import student
import os
import tkinter
from train import Train
from facereco import Face_Reco
from attendance import atendance
from developer import developer
from help import help

class facerecognitionsystem:
    def __init__(self, root):
        self.root = root
        self.root.geometry("1530x790+0+0")
        self.root.title("Face Recogn")

        img = Image.open(r"C:\Users\Dell\Desktop\tiet.jfif")
        img = img.resize((500,130),Image.ANTIALIAS)
        self.photoimg = ImageTk.PhotoImage(img)

        first_label = Label(self.root,image = self.photoimg)
        first_label.place(x=0,y=0,width=500,height=160)

        img1 = Image.open(r"C:\Users\Dell\Desktop\ss.jpg")
        img1 = img1.resize((500,130),Image.ANTIALIAS)
        self.photoimg1 = ImageTk.PhotoImage(img1)

        first_label = Label(self.root,image = self.photoimg1)
        first_label.place(x=500,y=0,width=500,height=160)

        img2 = Image.open(r"C:\Users\Dell\Desktop\sjd.jfif")
        img2 = img2.resize((500,130),Image.ANTIALIAS)
        self.photoimg2 = ImageTk.PhotoImage(img2)

        first_label = Label(self.root,image = self.photoimg2)
        first_label.place(x=1000,y=0,width=500,height=160)

        img3 = Image.open(r"C:\Users\Dell\Desktop\bg.jpg")
        img3 = img3.resize((1530,630),Image.ANTIALIAS)
        self.photoimg3 = ImageTk.PhotoImage(img3)

        bg_label = Label(self.root,image = self.photoimg3)
        bg_label.place(x=0,y=160,width=1530,height=630)

        title_lbl = Label(bg_label, text ="FACE RECOGNITION SYSYTEM ", font=("times new roman", 35, "bold"), bg = "white", fg = "green")
        title_lbl.place(x=0,y=0,width=1530,height=100)

        #student button
        img4 = Image.open(r"C:\Users\Dell\Desktop\student details.jfif")
        img4 = img4.resize((160,160),Image.ANTIALIAS)
        self.photoimg4 = ImageTk.PhotoImage(img4)

        b1 = Button(bg_label, image = self.photoimg4, command = self.student_details, cursor ="hand2")
        b1.place(x=150,y=80,width=160,height=160)

        b1_1 = Button(bg_label, text = "Student Details",command = self.student_details , cursor ="hand2", font=("times new roman", 15, "bold"), bg = "white", fg = "green")
        b1_1.place(x=150,y=240,width=160,height=40)

        #detect faces

        img5 = Image.open(r"C:\Users\Dell\Desktop\fr.jfif")
        img5 = img5.resize((160,160),Image.ANTIALIAS)
        self.photoimg5 = ImageTk.PhotoImage(img5)

        b2 = Button(bg_label, image = self.photoimg5, cursor ="hand2",command=self.face_data)
        b2.place(x=400,y=80,width=160,height=160)

        b2_1 = Button(bg_label, text = "Face Detector",command=self.face_data, cursor ="hand2", font=("times new roman", 15, "bold"), bg = "white", fg = "green")
        b2_1.place(x=400,y=240,width=160,height=40)

        img6 = Image.open(r"C:\Users\Dell\Desktop\attendance.jfif")
        img6 = img6.resize((160,160),Image.ANTIALIAS)
        self.photoimg6 = ImageTk.PhotoImage(img6)

        b3 = Button(bg_label, image = self.photoimg6, cursor ="hand2",command=self.attendance_data,)
        b3.place(x=700,y=80,width=160,height=160)

        b3_1 = Button(bg_label, text = "Attendance", cursor ="hand2",command=self.attendance_data, font=("times new roman", 15, "bold"), bg = "white", fg = "green")
        b3_1.place(x=700,y=240,width=160,height=40)

        img7 = Image.open(r"C:\Users\Dell\Desktop\help desk.png")
        img7 = img7.resize((160,160),Image.ANTIALIAS)
        self.photoimg7 = ImageTk.PhotoImage(img7)

        b4 = Button(bg_label, image = self.photoimg7,command = self.help1, cursor ="hand2")
        b4.place(x=1000,y=80,width=160,height=160)

        b4_1 = Button(bg_label, text = "Help Desk",command = self.help1, cursor ="hand2", font=("times new roman", 15, "bold"), bg = "white", fg = "green")
        b4_1.place(x=1000,y=240,width=160,height=40)

        img8 = Image.open(r"C:\Users\Dell\Pictures\training data.png")
        img8 = img8.resize((160,160),Image.ANTIALIAS)
        self.photoimg8 = ImageTk.PhotoImage(img8)

        b5 = Button(bg_label, image = self.photoimg8, cursor ="hand2", command =self.train_data)
        b5.place(x=150,y=350,width=160,height=160)

        b5_1 = Button(bg_label, text = "Train Data", cursor ="hand2", font=("times new roman", 15, "bold"), bg = "white", fg = "green",command=self.train_data)
        b5_1.place(x=150,y=510,width=160,height=40)

        #detect faces

        img9 = Image.open(r"C:\Users\Dell\Desktop\photos.jfif")
        img9 = img9.resize((160,160),Image.ANTIALIAS)
        self.photoimg9 = ImageTk.PhotoImage(img9)

        b6 = Button(bg_label, image = self.photoimg9, cursor ="hand2",command =self.open_image)
        b6.place(x=400,y=350,width=160,height=160)

        b6_1 = Button(bg_label, text = "Photos", cursor ="hand2",command =self.open_image ,font=("times new roman", 15, "bold"), bg = "white", fg = "green")
        b6_1.place(x=400,y=510,width=160,height=40)

        img10 = Image.open(r"C:\Users\Dell\Pictures\dev.png")
        img10 = img10.resize((160,160),Image.ANTIALIAS)
        self.photoimg10 = ImageTk.PhotoImage(img10)

        b7 = Button(bg_label, image = self.photoimg10, command = self.developer,cursor ="hand2")
        b7.place(x=700,y=350,width=160,height=160)

        b7_1 = Button(bg_label, text = "Developer",command = self.developer, cursor ="hand2", font=("times new roman", 15, "bold"), bg = "white", fg = "green")
        b7_1.place(x=700,y=510,width=160,height=40)

        img11 = Image.open(r"C:\Users\Dell\Desktop\exit.jfif")
        img11 = img11.resize((160,160),Image.ANTIALIAS)
        self.photoimg11 = ImageTk.PhotoImage(img11)

        b8 = Button(bg_label, image = self.photoimg11,command = self.exitf, cursor ="hand2")
        b8.place(x=1000,y=350,width=160,height=160)

        b8_1 = Button(bg_label, text = "Exit",command = self.exitf, cursor ="hand2", font=("times new roman", 15, "bold"), bg = "white", fg = "green")
        b8_1.place(x=1000,y=510,width=160,height=40)

    def open_image(self):
        os.startfile("data")

        #function buttons
    def student_details(self):

        self.new_window = Toplevel(self.root)
        self.app = student(self.new_window)

    def train_data(self):

        self.new_window = Toplevel(self.root)
        self.app = Train(self.new_window)

    def face_data(self):

        self.new_window = Toplevel(self.root)
        self.app = Face_Reco(self.new_window)

    def attendance_data(self):

        self.new_window = Toplevel(self.root)
        self.app = atendance(self.new_window)

    def developer(self):

        self.new_window = Toplevel(self.root)
        self.app = developer(self.new_window)

    def help1(self):

        self.new_window = Toplevel(self.root)
        self.app = help(self.new_window)

    def exitf(self):
        self.exitf = tkinter.messagebox.askyesno("Face Recognition", "Are you sure you want to exit?",parent = self.root)

        if self.exitf>0:
            self.root.destroy()
        else:
            return

if __name__ == "__main__":
    root = Tk()
    obj = facerecognitionsystem(root)
    root.mainloop()


import requests

city = input('enter the city... ')
api_address = 'https://samples.openweathermap.org/data/2.5/weather?q={},uk&appid=b6907d289e10d714a6e88b30761fae22'.format(
    city)

url = api_address + city
data = requests.get(url).json()
# print(data)

weather = data['weather']
print(weather[0]['description'])


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

# Change the display options
pd.options.display.max_columns = None
pd.options.display.max_rows = None

species_df = pd.read_csv('species_info.csv')
observations_df = pd.read_csv('observations.csv')

# print(species_df.head())
# print(observations_df.head())

# Describe data of species

# print(species_df.dtypes)

species = species_df.astype({'category': 'string',
                             'scientific_name': 'string',
                             'common_names': 'string',
                             'conservation_status': 'string'})  # Change our types of columns

# print(species_df.info())
print(species_df.describe())
print(species_df.category.value_counts())
# print(species_df.conservation_status.value_counts(normalize=True))

# Pie and bar of category
"""
sub_category = species_df.category.value_counts()

plt.figure(figsize=(10, 8))

plt.pie(species_df.category.value_counts().values, labels=species_df.category.value_counts().index, autopct='%1.1f%%')

plt.suptitle('Category of species', fontweight='bold')
plt.savefig('pie_category.png')
plt.show()
"""
# Describe data of observations

# print(observations_df.dtypes)

observations_df = observations_df.astype({'scientific_name': 'string',
                                          'park_name': 'string'})

# print(observations_df.info())
print(observations_df.describe())
# print(observations_df.observations.median())
# print(observations_df.observations.mode())
# print(observations_df.observations.mad())

# The distribution of conservation_status for animals
"""
status_counts = species_df.conservation_status.value_counts()
plt.figure(figsize=(10, 8))

plt.subplot(1, 2, 1)
sns.countplot(x='conservation_status', data=species_df)

plt.xlabel('Conservation status')
plt.ylabel('Count of status')

plt.xticks(rotation=15)

plt.subplot(1, 2, 2)
plt.pie(status_counts, labels=status_counts.index, autopct='%1.1f%%')

plt.axis('equal')

plt.suptitle('Distribution of conservation status for animals', fontweight='bold')
plt.subplots_adjust(wspace=0.5)
plt.savefig('dis_con_status.png')
plt.show()
plt.clf()
"""
# Certain types of species more likely to be endangered

influence = pd.crosstab(species_df.category, species_df.conservation_status)
influence_prop = influence / len(species_df)

print(influence)
print(influence_prop)

influence_marginals = influence_prop.sum(axis=0)
influence_marginals_1 = influence_prop.sum(axis=1)

print(influence_marginals)
print(influence_marginals_1)

chi2, pval, dof, expected = stats.chi2_contingency(influence)
print(expected)
print(chi2)

# Species were spotted the most at each park
"""
merged_df = species_df.merge(observations_df)

grouped_df = merged_df.groupby('category')['observations'].count()
print(grouped_df)
plt.figure(figsize=(15, 8))

plt.subplot(1, 2, 1)
sns.boxplot(x='category', y='observations', data=merged_df)

plt.xlabel('Species')
plt.ylabel('Number of observations')
plt.xticks(rotation=15)

plt.subplot(1, 2, 2)
plt.pie(grouped_df, labels=grouped_df.index, autopct='%1.1f%%')

plt.suptitle('Species were spotted the most at each park', fontweight='bold')

plt.savefig('species_observ.png')
plt.show()
plt.clf()
"""

# sns.histplot(x='observations', data=observations_df)
# plt.show()
print(species_df.scientific_name.mode())


from openzwave.network import ZWaveNetwork

#from openzwave.network import ZWaveNetwork
# Initialiser le réseau Z-Wave
network = ZWaveNetwork()
# Attendre que le réseau soit prêt
network.start()
print("Serveur Z-Wave démarré")
# Boucle principale du serveur
while True:
# Vérifier les événements Z-Wave
    network.update()# Traiter les événements reçus
for node in network.nodes:
    for value in network.nodes[node].get_changed_values():
            print(f"Node ID: {node} - Value ID: {value.value_id} - Nouvelle valeur: {value.data}")

# Arrêter le réseau Z-Wave
network.stop()


__author__ = 'Vivek'
#Given a sorted array and a target value, return the index if the target is found.
# If not, return the index where it would be if it were inserted in order.
#You may assume no duplicates in the array.
def searchInsert(A, B):
    """
    :param: A List of integers , B integer to be inserted
    :return: return index if B is already present in A , otherwise index at which B will be inserted
    """
    low = 0
    high = len(A) - 1
    while low <= high :
        mid = (low + high)/2
        if A[mid] == B :
            return mid
        if mid + 1 != len(A) and A[mid] < B < A[mid+1] :
            return mid + 1
        elif mid == len(A) - 1  and A[mid] < B :
            return mid + 1
        elif mid != 0 and A[mid - 1] < B < A[mid] :
            return mid
        elif mid == 0 and A[mid] > B :
            return mid
        if B < A[mid] :
            high = mid - 1
        elif B > A[mid] :
            low = mid + 1


from http import HTTPStatus
from flask import current_app, jsonify, request
from app.models.vacine_model import Vacine
from sqlalchemy.exc import IntegrityError
from app.exc.errors import CpfInvalid
from app.services.verif_data import verify_data
from app.services.generate_data import data_generate

def get_vacines():
    vacines = Vacine.query.all()

    serialized = [
        {
            "cpf": vacine.cpf,
            "name": vacine.name,
            "vaccine_name": vacine.vaccine_name,
            "health_unit_name": vacine.health_unit_name,
            "first_shot_date": vacine.first_shot_date,
            "second_shot_date": vacine.second_shot_date
        }
        for vacine in vacines
    ]

    return jsonify(serialized), 200

def create_vacine():
    data = request.get_json()

    verify_data(data)

    for key in data.keys():
        if type(data[key]) != str:
            return {"error": f" A chave {key} está em um formato inválido."}

    try:
        new_vaccine = Vacine(
            cpf=data["cpf"],
            name=data["name"],
            vaccine_name=data["vaccine_name"],
            health_unit_name=data["health_unit_name"],
            first_shot_date=data_generate(),
            second_shot_date=data_generate()
        )

        session = current_app.db.session

        session.add(new_vaccine)
        session.commit()

        return jsonify(new_vaccine), 201

    except IntegrityError:
        return {"message": "CPF já cadastrado."}, HTTPStatus.CONFLICT

    except CpfInvalid:
        return {"message": "O CPF não está no formato correto."}, HTTPStatus.BAD_REQUEST

    except KeyError as err:
        return {"message": f"Está faltando a Key {str(err)}."}, HTTPStatus.BAD_REQUEST


import hashlib
import json
import urllib.parse
from typing import Union, Dict

import asks
from asks.response_objects import Response

from spins_halp_line.constants import Credentials
from spins_halp_line.util import get_logger, SynchedCache

_cred_key = "resource_space"
_field_ids = {
    "adventure_name": 86,
    "player": 87
}

_base_url = "base_url"
_user = "user"
_secret = "secret"

_l = get_logger()

# search:
# [
# 	{
# 		"score":"0",
# 		"ref":"1001",
# 		"resource_type":"4",
# 		"has_image":"0",
# 		"is_transcoding":"0",
# 		"creation_date":"2020-11-18 19:13:51",
# 		"rating":"",
# 		"user_rating":"",
# 		"user_rating_count":"",
# 		"user_rating_total":"",
# 		"file_extension":"mp3",
# 		"preview_extension":"jpg",
# 		"image_red":"",
# 		"image_green":"",
# 		"image_blue":"",
# 		"thumb_width":"",
# 		"thumb_height":"",
# 		"archive":"0",
# 		"access":"0",
# 		"colour_key":"",
# 		"created_by":"1",
# 		"file_modified":"2020-11-18 19:13:51",
# 		"file_checksum":"",
# 		"request_count":"0",
# 		"new_hit_count":"8",
# 		"expiry_notification_sent":"0",
# 		"preview_tweaks":"0|1",
# 		"file_path":"",
# 		"modified":"2020-11-19 03:58:07",
# 		"group_access":"",
# 		"user_access":"",
# 		"field12":"2020-11-18 19:13",
# 		"field8":"Shipwreck Front Yard",
# 		"field3":"",
# 		"order_by":"",
# 		"total_hit_count":"8"
# 	}
# ]
# get_resource_data
# {
# 	"ref":"1001", // both
# 	"title":"", // not the title field in the ui lol
# 	"resource_type":"4", // both
# 	"has_image":"0", // both
# 	"is_transcoding":"0", // both
# 	"hit_count":"8",
# 	"new_hit_count":"8", // both
# 	"creation_date":"2020-11-18 19:13:51", // both
# 	"rating":"", // both
# 	"user_rating":"", // both
# 	"user_rating_count":"", // both
# 	"user_rating_total":"", // both
# 	"country":"",
# 	"file_extension":"mp3", // both
# 	"preview_extension":"jpg", // both
# 	"image_red":"", // both
# 	"image_green":"", // both
# 	"image_blue":"", // both
# 	"thumb_width":"", // both
# 	"thumb_height":"", // both
# 	"archive":"0", // both
# 	"access":"0", // both
# 	"colour_key":"", // both
# 	"created_by":"1", // both
# 	"file_path":"", // both
# 	"file_modified":"2020-11-18 19:13:51", // both
# 	"file_checksum":"", // both
# 	"request_count":"0", // both
# 	"expiry_notification_sent":"0", // both
# 	"preview_tweaks":"0|1", // both
# 	"geo_lat":"",
# 	"geo_long":"",
# 	"mapzoom":"",
# 	"disk_usage":"623803",
# 	"disk_usage_last_updated":"2020-11-18 19:13:52",
# 	"file_size":"623803",
# 	"preview_attempts":"1",
# 	"field12":"2020-11-18 19:13", // both (?)
# 	"field8":"Shipwreck Front Yard", // both (title)
# 	"field3":"", // both (?)
# 	"modified":"2020-11-19 03:58:07",
# 	"last_verified":"",
# 	"integrity_fail":"0",
# 	"google_vision_processed":"",
# 	"lock_user":""
# }

# Community boards are useful: https://groups.google.com/g/resourcespace?pli=1

# static cache
_global_cache = SynchedCache()

class RSResource(object):

    @classmethod
    async def for_room(cls, room_name):
        # https://www.resourcespace.com/knowledge-base/user/special-search-terms
        # todo: The caching logic here could use improvement. We cache the data from a particular room
        # todo: so if we load the same room again we won't repeat those requests...but it seems wrong to
        # todo: cache searches? This caching model is based on a read-only assumption - that the server
        # todo: will be restarted if we make changes in the CMS. Maybe we should cache search results?
        # todo: In any case, since these calls should mostly be made once, it's possible that any caching
        # todo: is properly viewed as premature optimization.
        files = await cls._get(
            'do_search',
            {
                'search': f'room:{room_name}'
            }
        )
        files = [f for f in files if f['field8'] == room_name]
        return await cls._from_list(files)

    @classmethod
    async def _from_list(cls, resources):
        result = []
        for r in resources:
            obj = RSResource(r)
            await obj.load()
            result.append(obj)

        return result

    _k_id = 'ref'
    _k_ext = 'file_extension'
    _k_ui_title = 'field8'
    _k_d_url = 'data_url'
    _k_adventure = 'adventure_name'
    _k_player = 'player'
    _k_room = 'room'
    _k_date = 'date'
    _k_duration = 'duration'
    _k_path = 'path'

    _extended_fields = [
        _k_adventure,
        _k_player,
        _k_room,
        _k_date,
        _k_duration,
        _k_path
    ]

    _resource_types = {
        '1': 'photo',
        '2': 'document',
        '3': 'video',
        '4': 'audio'
    }

    def __init__(self, data: Union[Dict[str, str], str, int]):
        global _global_cache
        self._cache = _global_cache
        self._data = {}
        self._loaded = False
        self._id = None
        if isinstance(data, dict):
            self._data = data
            self._loaded_basic = True
            # self._id = data.get(self._k_id)
        elif isinstance(data, int) or isinstance(data, str):
            self._id = int(data)

    def _throw_if_not_loaded(self):
        if not self._loaded:
            raise ValueError(f'{self} has not had its fields loaded!')

    async def load(self):
        cache_key = self.id

        # support caching results
        # todo: this cache doesn't work
        data = await self._cache.get(cache_key)
        print(f'loading resource {self.id}')
        if data is None:
            data = await self.get_info()
            data = await self.load_extended_fields(data)

            self._data = data
            # do this last so the extension is loaded
            data[self._k_d_url] = await self.get_data_url()

            await self._cache.set(cache_key, data)

        self._data = data
        self._loaded = True

    async def load_extended_fields(self, data):
        for field in (await self.get_all_fields()):
            name = field['name']

            if name in self._extended_fields:
                data[name] = field['value']

        return data

    @property
    def id(self):
        return self._data.get(self._k_id, self._id)

    @property
    def ext(self):
        return self._data.get(self._k_ext)

    @property
    def title(self):
        return self._data.get(self._k_ui_title)

    @property
    def url(self):
        return self._data.get(self._k_d_url)

    @property
    def adventure(self):
        return self._data.get(self._k_adventure)

    @property
    def player(self):
        return self._data.get(self._k_player)

    @property
    def room(self):
        return self._data.get(self._k_room)

    @property
    def date(self):
        return self._data.get(self._k_date)

    @property
    def duration(self):
        return self._data.get(self._k_duration)

    @property
    def path(self):
        return self._data.get(self._k_path)

    async def get_data_url(self):
        return await self._get(
            'get_resource_path',
            {
                'ref': self.id,
                'getfilepath': 0,
                'extension': self.ext,
                # 'generate': True,
                # 'alternative': -1,
                # 'size': ''
            }
        )

    async def get_info(self):

        return await self._get(
            'get_resource_data',
            {
                'resource': self.id
            }
        )

    # Example response JSON:
    # [
    #     {"value": "Shipwreck Adventure", "resource_type_field": "86", "ref": "86", "name": "adventure_name",
    #      "title": "Adventure Name", "field_constraint": "0", "type": "3", "order_by": "0", "keywords_index": "1",
    #      "partial_index": "0", "resource_type": "0", "resource_column": "", "display_field": "1",
    #      "use_for_similar": "1", "iptc_equiv": "", "display_template": "", "tab_name": "", "required": "0",
    #      "smart_theme_name": "", "exiftool_field": "", "advanced_search": "1", "simple_search": "0", "help_text": "",
    #      "display_as_dropdown": "0", "external_user_access": "1", "autocomplete_macro": "", "hide_when_uploading": "0",
    #      "hide_when_restricted": "0", "value_filter": "", "exiftool_filter": "", "omit_when_copying": "0",
    #      "tooltip_text": "", "regexp_filter": "", "sync_field": "", "display_condition": "", "onchange_macro": "",
    #      "linked_data_field": "", "automatic_nodes_ordering": "0", "fits_field": "", "personal_data": "0",
    #      "include_in_csv_export": "1", "browse_bar": "1", "read_only": "0", "active": "1", "full_width": "0",
    #      "frequired": "0", "fref": "86"},
    #     {"value": "", "resource_type_field": "87", "ref": "87", "name": "player", "title": "Player",
    #      "field_constraint": "0", "type": "0", "order_by": "0", "keywords_index": "1", "partial_index": "0",
    #      "resource_type": "0", "resource_column": "", "display_field": "1", "use_for_similar": "1", "iptc_equiv": "",
    #      "display_template": "", "tab_name": "", "required": "0", "smart_theme_name": "", "exiftool_field": "",
    #      "advanced_search": "1", "simple_search": "0", "help_text": "", "display_as_dropdown": "0",
    #      "external_user_access": "1", "autocomplete_macro": "", "hide_when_uploading": "0", "hide_when_restricted": "0",
    #      "value_filter": "", "exiftool_filter": "", "omit_when_copying": "0", "tooltip_text": "", "regexp_filter": "",
    #      "sync_field": "", "display_condition": "", "onchange_macro": "", "linked_data_field": "",
    #      "automatic_nodes_ordering": "0", "fits_field": "", "personal_data": "0", "include_in_csv_export": "1",
    #      "browse_bar": "1", "read_only": "0", "active": "1", "full_width": "0", "frequired": "0", "fref": "87"},
    #     {"value": "Shipwreck Yard Front", "resource_type_field": "88", "ref": "88", "name": "room", "title": "Room",
    #      "field_constraint": "", "type": "3", "order_by": "0", "keywords_index": "1", "partial_index": "0",
    #      "resource_type": "0", "resource_column": "", "display_field": "1", "use_for_similar": "1", "iptc_equiv": "",
    #      "display_template": "", "tab_name": "", "required": "0", "smart_theme_name": "", "exiftool_field": "",
    #      "advanced_search": "1", "simple_search": "0", "help_text": "", "display_as_dropdown": "0",
    #      "external_user_access": "1", "autocomplete_macro": "", "hide_when_uploading": "0", "hide_when_restricted": "0",
    #      "value_filter": "", "exiftool_filter": "", "omit_when_copying": "0", "tooltip_text": "", "regexp_filter": "",
    #      "sync_field": "", "display_condition": "", "onchange_macro": "", "linked_data_field": "",
    #      "automatic_nodes_ordering": "0", "fits_field": "", "personal_data": "0", "include_in_csv_export": "1",
    #      "browse_bar": "1", "read_only": "0", "active": "1", "full_width": "0", "frequired": "0", "fref": "88"},
    #     {"value": "Description", "resource_type_field": "8", "ref": "8", "name": "title", "title": "Title",
    #      "field_constraint": "", "type": "0", "order_by": "10", "keywords_index": "1", "partial_index": "0",
    #      "resource_type": "0", "resource_column": "title", "display_field": "0", "use_for_similar": "1",
    #      "iptc_equiv": "2#005", "display_template": "", "tab_name": "", "required": "1", "smart_theme_name": "",
    #      "exiftool_field": "Title", "advanced_search": "1", "simple_search": "0", "help_text": "",
    #      "display_as_dropdown": "0", "external_user_access": "1", "autocomplete_macro": "", "hide_when_uploading": "0",
    #      "hide_when_restricted": "0", "value_filter": "", "exiftool_filter": "", "omit_when_copying": "",
    #      "tooltip_text": "", "regexp_filter": "", "sync_field": "", "display_condition": "", "onchange_macro": "",
    #      "linked_data_field": "", "automatic_nodes_ordering": "0", "fits_field": "", "personal_data": "0",
    #      "include_in_csv_export": "1", "browse_bar": "1", "read_only": "0", "active": "1", "full_width": "0",
    #      "frequired": "1", "fref": "8"},
    #     ...
    # ]

    async def get_all_fields(self):
        return await self._get(
            'get_resource_field_data',
            {
                'resource': self.id
            }
        )

    def _add_extended_field(self, field):
        self._data[field['name']] = field['']

    @staticmethod
    async def _get(function, params, unwrap=True) -> dict:
        base_url = Credentials[_cred_key][_base_url]

        params['function'] = function
        params['user'] = Credentials[_cred_key][_user]
        qstring = urllib.parse.urlencode(params)

        secret = Credentials[_cred_key][_secret]
        signer = hashlib.sha256()
        signer.update(f'{secret}{qstring}'.encode("utf-8"))

        request = f'{base_url}?{qstring}&sign={signer.hexdigest()}'
        result: Response = await asks.get(request)
        # print("-" * 60)
        # print(request)
        # print(">" * 5)
        # print(result)
        # print("\\/" * 5)
        # print(result.content.decode("utf-8"))
        # print("-" * 60)

        # if unwrap and result.status_code >= 200 and result.status_code < 300:
        result: dict = json.loads(result.content.decode("utf-8"))

        return result

    def __str__(self):
        return f'RSR[{self.id}] {self.url}'

    def __repr__(self):
        return str(self)


from loader import dp
from aiogram import types
from aiogram.dispatcher import FSMContext
from aiogram.dispatcher.filters import Text
from loguru import logger
from datetime import datetime

@dp.message_handler(commands='reload', state='*')
@dp.message_handler(Text(equals='reload',
                         ignore_case=True), state='*')
async def cmd_reload(message: types.Message,
                     state: FSMContext) -> None:
    """
    Функция ресетит машину состояний
    :param msg: Message сообщение пользователя
    :param state: FSMContext машина состояний
    """
    cur_state = await state.get_state()
    logger.info(
        f'\nПользователь: {message.from_user.full_name}, '
        f'id: {message.from_user.id}, выполнил перезагрузку,'
        f'пользователь был в состоянии {cur_state},'
        f'дата: {datetime.now()}'
    )
    await message.answer('Перезагрузка')
    await state.reset_state()


import sys
sys.path.append("..") # Adds higher directory to python modules path.

import to_bip as tb
import blocks as bl
import shapegen as sh

def main():
    print(" ---- Pyramid ----")
    py = sh.Pyramid(5)
    py.generate()
    py_blocks = bl.init_blocks_3D(py.matlist())
    py_conn = bl.connect_blocks_3D(py_blocks)

    for block in py_conn.values():
        bl.visual_print_2D(block)
        print("\n")

    print("LAYERS:")
    for mat in py.matlist():
        bl.print_matrix(mat)
        print("\n")
    print("\n")

    tb.write_BIP("pyramid.bip", py_conn)

if __name__ == "__main__":
    main()


from pyplasm import *
import os,sys
sys.path.insert(0, 'lib/py/')
from lar2psm import *
from larcc import *
from sysml import *

#Funzioni Utili
DRAW = COMP([VIEW,STRUCT,MKPOLS])
DRAW2 = COMP([STRUCT,MKPOLS])

def rgbToPlasmColor(color):
	return [color[0]/255., color[1]/255., color[2]/255.]

def creaFinestre(x,z):
 finestra0=CUBOID([x,0.1,z])
 anta1=CUBOID([0.1,0.1,z-0.1])
 anta1=T([2,3])([-0.1,0.1])(anta1)
 anta2=CUBOID([0.1,0.1,z-0.1])
 anta2=T([1,2,3])([x-0.1,-0.1,0.1])(anta2)
 anta3=CUBOID([x,0.1,0.1])
 anta3=T(2)(-0.1)(anta3)
 anta4=CUBOID([x,0.1,0.1])
 anta4=T([2,3])([-0.1,z-0.1])(anta4)
 anta5=CUBOID([0.1,0.1,z-0.1])
 anta5=T([1,2,3])([(x-0.1)/2,-0.1,0.1])(anta5)
 ante=STRUCT([anta1,anta2,anta3,anta4,anta5])
 ante=COLOR(rgbToPlasmColor([153,51,0]))(ante)
 finestra0=COLOR(rgbToPlasmColor([153,203,255]))(finestra0)
 finestra=STRUCT([finestra0,ante])
 return finestra

def creaPorta(x,z):
 porta0=CUBOID([x,0.1,z])
 porta0=COLOR(rgbToPlasmColor([192,64,0]))(porta0)
 cilind_T = CYLINDER([0.025, (10.0/12)*0.1])(50)
 cilind_T=ROTATE([2,3])(PI/2)(cilind_T)
 cilind_T=T([1,3])([x-0.1,z/2])(cilind_T)
 cilind_T=COLOR(rgbToPlasmColor([205,133,63]))(cilind_T)
 porta=STRUCT([porta0,cilind_T])

 return porta

#Camera1
master = assemblyDiagramInit([5,3,2])([[.1,1.5,1,1.5,.1],[.1,3,.1],[.1,2.7]])
V,CV = master
hpc = SKEL_1(STRUCT(MKPOLS(master)))
hpc= cellNumbering (master,hpc)(range(len(CV)),CYAN,2)

#Porta
toMerge = 23
diagram0 = assemblyDiagramInit([3,1,2])([[1.5,2,1.5],[.1],[2.2,.5]])
master = diagram2cell(diagram0,master,toMerge)
hpc = SKEL_1(STRUCT(MKPOLS(master)))
hpc = cellNumbering (master,hpc)(range(len(master[1])),CYAN,2)

#Finestra
toMerge = 13
diagram0 = assemblyDiagramInit([1,1,3])([[3],[.1],[1,1.2,.5]])
master = diagram2cell(diagram0,master,toMerge)
hpc = SKEL_1(STRUCT(MKPOLS(master)))
hpc = cellNumbering (master,hpc)(range(len(master[1])),CYAN,2)

#Rimozione
toRemove = [30,35,9,14,20]
master = master[0], [cell for k,cell in enumerate(master[1]) if not (k in toRemove)]
camera=DRAW2(master)

camera=COLOR(rgbToPlasmColor([255	,204,153]))(camera)
finestra1=creaFinestre(1,1.2)
finestra1=T([1,3])([1.6,1.1])(finestra1)

porta0=creaPorta(0.6,2.2)
porta0=ROTATE([1,2])(PI)(porta0)
porta0=T([1,2,3])([3.65,3.2,0.1])(porta0)

camera1=STRUCT([camera,finestra1,porta0])

#Camera2
master = assemblyDiagramInit([5,3,2])([[.1,1.5,1,1.5,.1],[.1,3,.1],[.1,2.7]])
V,CV = master
hpc = SKEL_1(STRUCT(MKPOLS(master)))
hpc= cellNumbering (master,hpc)(range(len(CV)),CYAN,2)

#Porta
toMerge = 19
diagram0 = assemblyDiagramInit([3,1,2])([[1.5,2,1.5],[.1],[2.2,.5]])
master = diagram2cell(diagram0,master,toMerge)
hpc = SKEL_1(STRUCT(MKPOLS(master)))
hpc = cellNumbering (master,hpc)(range(len(master[1])),CYAN,2)

#Finestra
toMerge = 17
diagram0 = assemblyDiagramInit([1,1,3])([[3],[.1],[1,1.2,.5]])
master = diagram2cell(diagram0,master,toMerge)
hpc = SKEL_1(STRUCT(MKPOLS(master)))
hpc = cellNumbering (master,hpc)(range(len(master[1])),CYAN,2)

#Rimozione
toRemove = [30,35,9,15,19]
master = master[0], [cell for k,cell in enumerate(master[1]) if not (k in toRemove)]
camera2Temp=DRAW2(master)
camera2Temp=COLOR(rgbToPlasmColor([255	,204,153]))(camera2Temp)

finestra0=creaFinestre(1.2,1.2)
finestra0=ROTATE([1,2])(PI)(finestra0)
finestra0=T([1,2,3])([2.6,3.2,1.1])(finestra0)

porta0=creaPorta(0.6,2.2)

porta0=T([1,3])([3.05,0.1])(porta0)
camera2=STRUCT([camera2Temp,finestra0,porta0])
camera2=T(2)(5)(camera2)

#Bagno2
master = assemblyDiagramInit([3,5,2])([[.1,2.2,.1],[.1,.4,0.9,.4,.1],[.1,2.7]])
V,CV = master
hpc = SKEL_1(STRUCT(MKPOLS(master)))
hpc = cellNumbering (master,hpc)(range(len(CV)),CYAN,2)

#Porta
toMerge = 25
diagram2 = assemblyDiagramInit([1,1,2])([[2],[.1],[2.2,.5]])
master = diagram2cell(diagram2,master,toMerge)
hpc = SKEL_1(STRUCT(MKPOLS(master)))
hpc = cellNumbering (master,hpc)(range(len(master[1])),CYAN,2)

#Finestra
toMerge = 5
diagram0 = assemblyDiagramInit([1,1,3])([[3],[.1],[1,1.2,.5]])
master = diagram2cell(diagram0,master,toMerge)
hpc = SKEL_1(STRUCT(MKPOLS(master)))
hpc = cellNumbering (master,hpc)(range(len(master[1])),CYAN,1)

#Rimozione
toRemove = [14,16,12,28,31]
master = master[0], [cell for k,cell in enumerate(master[1]) if not (k in toRemove)]
bagnoTemp=DRAW2(master)

bagnoTemp=COLOR(rgbToPlasmColor([255	,204,153]))(bagnoTemp)

finestra0=creaFinestre(1,1.2)
finestra0=ROTATE([1,2])(-PI/2)(finestra0)
finestra0=T([2,3])([1.5,1.1])(finestra0)

porta0=creaPorta(0.9,2.2)
porta0=ROTATE([1,2])(PI/2)(porta0)
porta0=T([1,2,3])([2.4,0.5,0.1])(porta0)

bagno=STRUCT([bagnoTemp,finestra0,porta0])

bagno=T(2)(3.1)(bagno)

#Stireria
master = assemblyDiagramInit([5,3,2])([[.1,1.4,1,.5,.1],[.1,2.1,.1],[.1,2.7]])
V,CV = master
hpc = SKEL_1(STRUCT(MKPOLS(master)))
hpc = cellNumbering (master,hpc)(range(len(CV)),CYAN,2)

#Porta
toMerge = 13
diagram3 = assemblyDiagramInit([1,1,2])([[2],[.1],[2.2,.5]])
master = diagram2cell(diagram3,master,toMerge)
hpc = SKEL_1(STRUCT(MKPOLS(master)))
hpc = cellNumbering (master,hpc)(range(len(master[1])),CYAN,2)

#Finestra
toMerge = 16
diagram0 = assemblyDiagramInit([3,1,3])([[3,3,3],[.1],[1,1.2,.5]])
master = diagram2cell(diagram0,master,toMerge)
hpc = SKEL_1(STRUCT(MKPOLS(master)))
hpc = cellNumbering (master,hpc)(range(len(master[1])),CYAN,2)

#Rimozione
toRemove = [34,28,9,14,19,31,37]
master = master[0], [cell for k,cell in enumerate(master[1]) if not (k in toRemove)]
DRAW2(master)
stireriaTemp=DRAW2(master)
stireriaTemp=COLOR(rgbToPlasmColor([255	,204,153]))(stireriaTemp)

finestra0=creaFinestre(1,1.2)
finestra0=ROTATE([1,2])(-PI)(finestra0)
finestra0=T([1,2,3])([2.5,2.3,1.1])(finestra0)

porta0=creaPorta(1,2.2)
porta0=T([1,3])([1.5,0.1])(porta0)

stireria=STRUCT([stireriaTemp,finestra0,porta0])
stireria=T([1,2])([10.8,8.2])(stireria)

#Cucina
master = assemblyDiagramInit([5,6,2])([[.1,1,1,2,.1],[.1,1.5,1,1.2,0.3,.1],[.1,2.7]])
V,CV = master
hpc = SKEL_1(STRUCT(MKPOLS(master)))
hpc = cellNumbering (master,hpc)(range(len(CV)),CYAN,2)
#hpc4=T([1,2])([13.2,4.1])(hpc4)

#Finestra
toMerge = 53
diagram = assemblyDiagramInit([1,1,3])([[3],[.1],[1,1.2,.5]])
master = diagram2cell(diagram,master,toMerge)
hpc = SKEL_1(STRUCT(MKPOLS(master)))
hpc = cellNumbering (master,hpc)(range(len(master[1])),CYAN,2)

#Porta
toMerge = 35
diagram = assemblyDiagramInit([1,1,2])([[2],[.1],[2.2,.5]])
master = diagram2cell(diagram,master,toMerge)
hpc = SKEL_1(STRUCT(MKPOLS(master)))
hpc = cellNumbering (master,hpc)(range(len(master[1])),CYAN,2)

#Porta
toMerge = 25
diagram = assemblyDiagramInit([1,1,2])([[2],[.1],[2.2,.5]])
master = diagram2cell(diagram,master,toMerge)
hpc = SKEL_1(STRUCT(MKPOLS(master)))
hpc = cellNumbering (master,hpc)(range(len(master[1])),CYAN,2)

#Porta
toMerge = 7
diagram = assemblyDiagramInit([1,1,2])([[2],[.1],[2.2,.5]])
master = diagram2cell(diagram,master,toMerge)
hpc = SKEL_1(STRUCT(MKPOLS(master)))
hpc = cellNumbering (master,hpc)(range(len(master[1])),CYAN,2)

#Rimozione
toRemove = [61,63,57,31,59,14,25,36,16,27,38,18,29,40,20,31,42]
master = master[0], [cell for k,cell in enumerate(master[1]) if not (k in toRemove)]
cucinaTemp=DRAW2(master)
cucinaTemp=COLOR(rgbToPlasmColor([255	,204,153]))(cucinaTemp)

finestra0=creaFinestre(1,1.2)
finestra0=ROTATE([1,2])(PI/2)(finestra0)
finestra0=T([1,2,3])([4.2,1.6,1.1])(finestra0)

porta0=creaPorta(1,2.2)
porta0=ROTATE([1,2])(PI)(porta0)
porta0=T([1,2,3])([2.1,4.2,0.1])(porta0)

porta1=creaPorta(1,2.2)
porta1=T([1,3])([1.1,0.1])(porta1)

porta2=creaPorta(1.2,2.2)
porta2=ROTATE([1,2])(-PI/2)(porta2)
porta2=T([2,3])([3.8,0.1])(porta2)

cucina=STRUCT([cucinaTemp,finestra0,porta0,porta1,porta2])
cucina=T([1,2])([13.2,4.1])(cucina)

#Bagno2
master = assemblyDiagramInit([5,3,2])([[.1,1.4,1,.4,.1],[.1,1.2,.1],[.1,2.7]])
V,CV = master
hpc = SKEL_1(STRUCT(MKPOLS(master)))
hpc = cellNumbering (master,hpc)(range(len(CV)),CYAN,2)
#hpc=T([1,2])([10.6,5.3])(hpc)

#Porta
toMerge = 17
diagram = assemblyDiagramInit([1,1,2])([[2],[.1],[2.2,.5]])
master = diagram2cell(diagram,master,toMerge)
hpc = SKEL_1(STRUCT(MKPOLS(master)))
hpc = cellNumbering (master,hpc)(range(len(master[1])),CYAN,2)

#Rimozione
toRemove = [29,15,9,20]
master = master[0], [cell for k,cell in enumerate(master[1]) if not (k in toRemove)]
bagnoTemp2=DRAW2(master)
bagnoTemp2=COLOR(rgbToPlasmColor([255	,204,153]))(bagnoTemp2)

porta0=creaPorta(1,2.2)
porta0=ROTATE([1,2])(PI)(porta0)
porta0=T([1,2,3])([2.5,1.4,0.1])(porta0)

bagno2=STRUCT([porta0,bagnoTemp2])
bagno2=T([1,2])([10.2,5.3])(bagno2)

#Scale
master = assemblyDiagramInit([3,5,2])([[.1,3.4,.1],[.1,.2,1,.2,.1],[.1,2.7]])
V,CV= master
hpc = SKEL_1(STRUCT(MKPOLS(master)))
hpc = cellNumbering (master,hpc)(range(len(CV)),CYAN,2)
hpc = SKEL_1(STRUCT(MKPOLS(master)))
hpc = cellNumbering (master,hpc)(range(len(master[1])),CYAN,2)

#Porta
toMerge = 25
diagram2 = assemblyDiagramInit([1,1,2])([[2],[.1],[2.2,.5]])
master = diagram2cell(diagram2,master,toMerge)
hpc = SKEL_1(STRUCT(MKPOLS(master)))
hpc = cellNumbering (master,hpc)(range(len(master[1])),CYAN,2)

#Finestra
toMerge = 19
diagram0 = assemblyDiagramInit([3,1,3])([[3,3,3],[.1],[1,1.2,.5]])
master = diagram2cell(diagram0,master,toMerge)
hpc = SKEL_1(STRUCT(MKPOLS(master)))
hpc = cellNumbering (master,hpc)(range(len(master[1])),CYAN,2)

#Rimozione
toRemove = [28,15,34,13,17,14]
master = master[0], [cell for k,cell in enumerate(master[1]) if not (k in toRemove)]
scaleTemp=DRAW2(master)
scaleTemp=COLOR(rgbToPlasmColor([255	,204,153]))(scaleTemp)

finestra0=creaFinestre(1.2,1.2)
finestra0=ROTATE([1,2])(PI)(finestra0)
finestra0=T([1,2,3])([2.4,1.6,1.1])(finestra0)

porta0=creaPorta(1,2.2)
porta0=ROTATE([1,2])(PI/2)(porta0)
porta0=T([1,2,3])([3.6,0.3,0.1])(porta0)

scale=STRUCT([scaleTemp,finestra0,porta0])

scale=T([1,2])([4,6.6])(scale)

#Remove
master = assemblyDiagramInit([3,3,2])([[.1,1.3,.1],[.1,1.4,.1],[.1,2.7]])
V,CV= master
hpc = SKEL_1(STRUCT(MKPOLS(master)))
hpc = cellNumbering (master,hpc)(range(len(CV)),CYAN,2)

#Remove
toRemove = [5,11,17,3,9,15]
master = master[0], [cell for k,cell in enumerate(master[1]) if not (k in toRemove)]
remove=DRAW2(master)
remove=T([1,2])([7.6,6.6])(remove)
remove=COLOR(rgbToPlasmColor([255	,204,153]))(remove)

finestra0=creaFinestre(1.2,1.2)
finestra0=ROTATE([1,2])(PI)(finestra0)
finestra0=T([1,2,3])([2.4,1.6,1.1])(finestra0)

#Soggiorno2
master = assemblyDiagramInit([5,3,2])([[.15,0.8,1.6,0.8,.15],[.1,6.0,.1],[.1,2.7]])
V,CV= master
hpc = SKEL_1(STRUCT(MKPOLS(master)))
hpc = cellNumbering (master,hpc)(range(len(CV)),CYAN,2)

#Porta
toMerge = 13
diagram0 = assemblyDiagramInit([1,1,2])([[2],[.1],[2.2,.5]])
master = diagram2cell(diagram0,master,toMerge)
hpc = SKEL_1(STRUCT(MKPOLS(master)))
hpc = cellNumbering (master,hpc)(range(len(master[1])),CYAN,2)

#Rimozione
toRemove = [29,3,9,14,20,26,11,16,22]
master = master[0], [cell for k,cell in enumerate(master[1]) if not (k in toRemove)]
soggiornoTemp2=DRAW2(master)

soggiornoTemp2=COLOR(rgbToPlasmColor([255	,204,153]))(soggiornoTemp2)

finestra0=creaFinestre(1.6,2.3)
finestra0=T([1])(0.95)(finestra0)
soggiorno2=STRUCT([soggiornoTemp2,finestra0])
soggiorno2=T([1,2])([4.1,0.5])(soggiorno2)

#Soggiorno3
master = assemblyDiagramInit([7,4,2])([[.4,1,1,0.9,1,1,.3],[.1,.4,4.8,.1],[.1,2.7]])
V,CV= master
hpc = SKEL_1(STRUCT(MKPOLS(master)))
hpc= cellNumbering (master,hpc)(range(len(CV)),CYAN,2)

#Porta
toMerge = 41
diagram0 = assemblyDiagramInit([1,1,2])([[2],[.1],[2.2,.5]])
master = diagram2cell(diagram0,master,toMerge)
hpc = SKEL_1(STRUCT(MKPOLS(master)))
hpc = cellNumbering (master,hpc)(range(len(master[1])),CYAN,2)
#Porta
toMerge = 33
diagram0 = assemblyDiagramInit([1,1,2])([[2],[.1],[2.2,.5]])
master = diagram2cell(diagram0,master,toMerge)
hpc = SKEL_1(STRUCT(MKPOLS(master)))
hpc = cellNumbering (master,hpc)(range(len(master[1])),CYAN,2)
#Porta
toMerge = 17
diagram0 = assemblyDiagramInit([1,1,2])([[2],[.1],[2.2,.5]])
master = diagram2cell(diagram0,master,toMerge)
hpc = SKEL_1(STRUCT(MKPOLS(master)))
hpc = cellNumbering (master,hpc)(range(len(master[1])),CYAN,2)
#Porta
toMerge = 9
diagram0 = assemblyDiagramInit([1,1,2])([[2],[.1],[2.2,.5]])
master = diagram2cell(diagram0,master,toMerge)
hpc = SKEL_1(STRUCT(MKPOLS(master)))
hpc = cellNumbering (master,hpc)(range(len(master[1])),CYAN,2)

#Rimozione
toRemove = [58,56,54,52,5,12,19,27,34,41,49,7,14,21,29,36,43,51,10,17,32,39]
master = master[0], [cell for k,cell in enumerate(master[1]) if not (k in toRemove)]
soggiornoTemp3=DRAW2(master)
soggiornoTemp3=COLOR(rgbToPlasmColor([255	,204,153]))(soggiornoTemp3)
finestra0=creaFinestre(2,2.3)
finestra0=T(1)(0.4)(finestra0)

finestra1=creaFinestre(2,2.3)
finestra1=T(1)(3.3)(finestra1)

soggiorno3=STRUCT([soggiornoTemp3,finestra0,finestra1])

soggiorno3=T([1])([7.6])(soggiorno3)

#Sala pranzo
master = assemblyDiagramInit([5,3,2])([[.1,1,2,1,.1],[.1,3.5,.1],[.1,2.7]])
V,CV= master
hpc = SKEL_1(STRUCT(MKPOLS(master)))
hpc = cellNumbering (master,hpc)(range(len(CV)),CYAN,2)

#Finestra
toMerge = 13
diagram0 = assemblyDiagramInit([1,1,2])([[2],[.1],[2.2,.5]])
master = diagram2cell(diagram0,master,toMerge)
hpc = SKEL_1(STRUCT(MKPOLS(master)))
hpc = cellNumbering (master,hpc)(range(len(master[1])),CYAN,2)

#Rimozione
toRemove = [29,9,14,20,3,28,5,11,16,22,23]
master = master[0], [cell for k,cell in enumerate(master[1]) if not (k in toRemove)]
soggiornoTemp4=DRAW2(master)
soggiornoTemp4=COLOR(rgbToPlasmColor([255	,204,153]))(soggiornoTemp4)

finestra0=creaFinestre(2,2.3)
finestra0=T(1)(1.1)(finestra0)

soggiorno4=STRUCT([soggiornoTemp4,finestra0])

soggiorno4=T([1,2])([13.2,0.5])(soggiorno4)

#Camino
master = assemblyDiagramInit([3,3,2])([[.1,1,.1],[.1,2,.1],[.1,2.7]])
V,CV= master
hpc = SKEL_1(STRUCT(MKPOLS(master)))
hpc = cellNumbering (master,hpc)(range(len(CV)),CYAN,2)

master = master[0], [cell for k,cell in enumerate(master[1]) ]
camino=DRAW2(master)
camino=T([1,2])([6.5,2])(camino)

#Remove2
master = assemblyDiagramInit([4,5,2])([[.1,3.6,2.6,.1],[.1,2.8,1.1,1.1,.1],[.1,2.7]])
V,CV= master
hpc = SKEL_1(STRUCT(MKPOLS(master)))
hpc = cellNumbering (master,hpc)(range(len(CV)),CYAN,2)

#Finestra
toMerge = 19
diagram0 = assemblyDiagramInit([3,1,3])([[3,3,3],[.1],[1,1.2,.5]])
master = diagram2cell(diagram0,master,toMerge)
hpc = SKEL_1(STRUCT(MKPOLS(master)))
hpc = cellNumbering (master,hpc)(range(len(master[1])),CYAN,2)

#Finestra
toMerge = 7
diagram = assemblyDiagramInit([1,1,2])([[2],[.1],[2.2,.5]])
master = diagram2cell(diagram,master,toMerge)
hpc = SKEL_1(STRUCT(MKPOLS(master)))
hpc = cellNumbering (master,hpc)(range(len(master[1])),CYAN,2)

#Rimozione
toRemove = [47,42,12,21,14,23,16,25,3,10,1,19,31,29,33,35,37,27]
master = master[0], [cell for k,cell in enumerate(master[1]) if not (k in toRemove)]
remove2Temp=DRAW2(master)

remove2Temp=COLOR(rgbToPlasmColor([255	,204,153]))(remove2Temp)

porta0=creaPorta(1.1,2.2)
porta0=ROTATE([1,2])(-PI/2)(porta0)
porta0=T([2,3])([5.1,0.1])(porta0)

finestra0=creaFinestre(1.2,1.2)
finestra0=ROTATE([1,2])(PI)(finestra0)
finestra0=T([1,2,3])([2.5,5.2,1.1])(finestra0)

remove2=STRUCT([remove2Temp,finestra0,porta0])
remove2=T([1,2])([7.5,5.3])(remove2)

#Remove3
master = assemblyDiagramInit([3,3,2])([[.1,2.1,.1],[.1,2,.1],[.1,2.7]])
V,CV= master
hpc = SKEL_1(STRUCT(MKPOLS(master)))
hpc = cellNumbering (master,hpc)(range(len(CV)),CYAN,2)

toRemove = [1,3,5,7,9,11,13,15,17]
master = master[0], [cell for k,cell in enumerate(master[1]) if not (k in toRemove)]
remove3=DRAW2(master)
remove3=T([1,2])([2.4,3.1])(remove3)

#Scale
gradino2_vertici = [ [0,0], [0,0.3], [1.3,0], [1.3,0.3] ];
gradino2_num_lati = [range(1,5)]
gradino2_2D = MKPOL([gradino2_vertici, gradino2_num_lati, None])
gradino2 = PROD([gradino2_2D, Q(0.2)])

gradino3 = PROD([gradino2_2D, Q(0.2)])
gradino3=T([2,3])([0.2,0.2])(gradino3)

gradino4 = PROD([gradino2_2D, Q(0.2)])
gradino4=T([2,3])([0.4,0.4])(gradino4)

gradino5 = PROD([gradino2_2D, Q(0.2)])
gradino5=T([2,3])([0.6,0.6])(gradino5)

gradino6 = PROD([gradino2_2D, Q(0.2)])
gradino6=T([2,3])([0.8,0.8])(gradino6)

gradino7 = PROD([gradino2_2D, Q(0.2)])
gradino7=T([2,3])([1,1])(gradino7)

gradino8 = PROD([gradino2_2D, Q(0.2)])
gradino8=T([2,3])([1.2,1.2])(gradino8)

gradino9 = PROD([gradino2_2D, Q(0.2)])
gradino9=T([2,3])([1.4,1.4])(gradino9)

gradino10 = PROD([gradino2_2D, Q(0.2)])
gradino10=T([2,3])([1.6,1.6])(gradino10)

gradino11 = PROD([gradino2_2D, Q(0.2)])
gradino11=T([2,3])([1.8,1.8])(gradino11)

gradino12 = PROD([gradino2_2D, Q(0.2)])
gradino12=T([2,3])([2,2])(gradino12)

gradino13 = PROD([gradino2_2D, Q(0.2)])
gradino13=T([2,3])([2.2,2.2])(gradino13)

gradino14 = PROD([gradino2_2D, Q(0.2)])
gradino14=T([2,3])([2.4,2.4])(gradino14)

gradino15 = PROD([gradino2_2D, Q(0.2)])
gradino15=T([2,3])([2.6,2.6])(gradino15)

#Assemblo la scalinata
scalinata=STRUCT([gradino2,gradino3,gradino4,gradino5,gradino6,gradino7,gradino8,gradino9,gradino10,
	gradino11,gradino12,gradino13,gradino14,gradino15])

scalinata=ROTATE([1,2])(PI/2)(scalinata)

#La traslo sui 3 assi al centro della parte frontale
scalinata=T([1,2])([7.3,5.3])(scalinata)

#Faccio la seconda scala
scalinata2=scalinata

#Traslo la seconda scala
scalinata2=T([1,2,3])([-11.9,-13.4,-2.7])(scalinata2)
scalinata2=ROTATE([1,2])(-PI)(scalinata2)

#Esterno
est1= CUBOID([4,6,0.2])
est1=T([1,2,3])([13.2,-5.5,-0.1])(est1)

est2= CUBOID([14.7,2.8,0.2])
est2=T([1,2,3])([-1.5,-2.3,-0.1])(est2)

est3=CUBOID([14.5,0.2,0.2])
est3=T([1,2,3])([-1.5,-2.5,-0.1])(est3)
est3=COLOR(rgbToPlasmColor([147,147,147]))(est3)

est4=CUBOID([0.2,3.2,0.2])
est4=T([1,2,3])([13,-5.5,-0.1])(est4)
est4=COLOR(rgbToPlasmColor([147,147,147]))(est4)

est5=CUBOID([4,0.2,0.2])
est5=T([1,2,3])([13,-5.7,-0.1])(est5)
est5=COLOR(rgbToPlasmColor([147,147,147]))(est5)

est6=CUBOID([0.5,1.7,0.5])
est6=T([1,2,3])([16.9,-7,-0.1])(est6)
est6=COLOR(rgbToPlasmColor([255	,204,153]))(est6)

colonna1=CUBOID([0.5,0.5,2.8])
colonna1=T([1,2])([3,-1])(colonna1)
colonna2=CUBOID([0.5,0.5,2.8])
colonna2=T([1,2])([7,-1])(colonna2)
colonna3=CUBOID([0.5,0.5,2.8])
colonna3=T([1,2])([10.5,-1])(colonna3)
colonna4=CUBOID([0.5,0.5,2.8])
colonna4=T([1,2])([14,-1])(colonna4)
colonna5=CUBOID([0.5,0.5,2.8])
colonna5=T([1,2])([3.9,10])(colonna5)
colonne=STRUCT([colonna1,colonna2,colonna3,colonna4,colonna5])

ext4_vertici = [ [0,0], [0,2], [0.5,0], [0.5,2] ];
ext4_num_lati = [range(1,5)]
ext4_2D = MKPOL([ext4_vertici, ext4_num_lati, None])
ext4 = PROD([ext4_2D, Q(2.8)])
ext4=T(2)(-2)(ext4)

ext5_vertici = [ [0,0], [0,6], [2.8,0],[2.8,2.5],[0.3,6] ];
ext5_num_lati = [range(1,6)]
ext5_2D = MKPOL([ext5_vertici, ext5_num_lati, None])
ext5 = PROD([ext5_2D, Q(0.5)])
ext5=ROTATE([1,3])(PI/2)(ext5)
ext5=ROTATE([1,2])(PI)(ext5)
ext5=T([1,2])([16.9,0.5])(ext5)

baseEsterno=STRUCT([est1,est2])
esterno=STRUCT([ext4,ext5,colonne])

#ParteSuperiore
parteSup=CUBOID([17.4,10.3,0.7])
parteSup=T([2,3])([-2,2.8])(parteSup)
#Tetto

tetto_vertici = [ [0,0], [10.3,0], [5.15,1.5], ];
tetto_num_lati = [range(1,4)]
tetto_2D = MKPOL([tetto_vertici, tetto_num_lati, None])
#Porto in 2,5D
tetto = PROD([tetto_2D, Q(17.4)])
tetto=ROTATE([2,3])(PI/2)(tetto)
tetto=ROTATE([1,2])(PI/2)(tetto)
tetto=T([2,3])([-2,3.5])(tetto)

#Creo La mansarda

#Camera1
master = assemblyDiagramInit([7,6,2])([[.1,0.5,1.1,2,1,1,.1],[.1,0.5,1.3,2,1.3,.2],[.1,2.3]])
V,CV = master
hpc = SKEL_1(STRUCT(MKPOLS(master)))
hpc= cellNumbering (master,hpc)(range(len(CV)),CYAN,2)

#Finestra
toMerge = 49
diagram0 = assemblyDiagramInit([1,1,3])([[3],[.1],[1,1.2,.2]])
master = diagram2cell(diagram0,master,toMerge)
hpc = SKEL_1(STRUCT(MKPOLS(master)))
hpc = cellNumbering (master,hpc)(range(len(master[1])),CYAN,2)

#Porta
toMerge = 35
diagram0 = assemblyDiagramInit([1,1,2])([[3],[.1],[2.2,.2]])
master = diagram2cell(diagram0,master,toMerge)
hpc = SKEL_1(STRUCT(MKPOLS(master)))
hpc = cellNumbering (master,hpc)(range(len(master[1])),CYAN,2)

toMerge = 25
diagram0 = assemblyDiagramInit([1,1,2])([[3],[.1],[2.2,.2]])
master = diagram2cell(diagram0,master,toMerge)
hpc = SKEL_1(STRUCT(MKPOLS(master)))
hpc = cellNumbering (master,hpc)(range(len(master[1])),CYAN,2)

toMerge = 9
diagram0 = assemblyDiagramInit([1,1,2])([[3],[.1],[2.2,.2]])
master = diagram2cell(diagram0,master,toMerge)
hpc = SKEL_1(STRUCT(MKPOLS(master)))
hpc = cellNumbering (master,hpc)(range(len(master[1])),CYAN,2)

toMerge = 5
diagram0 = assemblyDiagramInit([1,1,2])([[3],[.1],[2.2,.2]])
master = diagram2cell(diagram0,master,toMerge)
hpc = SKEL_1(STRUCT(MKPOLS(master)))
hpc = cellNumbering (master,hpc)(range(len(master[1])),CYAN,2)

#Rimozione
toRemove = [80,88,84,86,24,26,28,30,35,37,39,41,46,48,50,52,58,60,62,64,13,15,17,19,82]
master = master[0], [cell for k,cell in enumerate(master[1]) if not (k in toRemove)]
cameraManTemp=DRAW2(master)

cameraManTemp=COLOR(rgbToPlasmColor([255	,204,153]))(cameraManTemp)

finestra0=creaFinestre(1,1.2)
finestra0=T([1,3])([3.7,1])(finestra0)

porta0=creaPorta(1.1,2.1)
porta0=T([1,3])([0.6,0.1])(porta0)

porta1=creaPorta(1.1,2.1)
porta1=ROTATE([1,2])(PI)(porta1)
porta1=T([1,2,3])([1.7,5.3,0.1])(porta1)

porta2=creaPorta(1.3,2.1)
porta2=ROTATE([1,2])(-PI/2)(porta2)
porta2=T([2,3])([1.9,0.1])(porta2)

porta3=creaPorta(1.3,2.1)
porta3=ROTATE([1,2])(-PI/2)(porta3)
porta3=T([2,3])([5.2,0.1])(porta3)

cameraMan=STRUCT([cameraManTemp,finestra0,porta0,porta1,porta2,porta3])

cameraMan=T([1])([4.1])(cameraMan)

#bagnoMan
master = assemblyDiagramInit([5,5,2])([[.1,0.5,1.5,2,.1],[.1,0.5,1.3,1.5,.1],[.1,2.3]])
V,CV = master
hpc = SKEL_1(STRUCT(MKPOLS(master)))
hpc= cellNumbering (master,hpc)(range(len(CV)),CYAN,2)

toMerge = 21
diagram0 = assemblyDiagramInit([1,1,3])([[3],[.1],[1,1.2,.3]])
master = diagram2cell(diagram0,master,toMerge)
hpc = SKEL_1(STRUCT(MKPOLS(master)))
hpc = cellNumbering (master,hpc)(range(len(master[1])),CYAN,2)

#Rimozione
toRemove = [50,17,26,36,46,15,24,34,44,13,22,32,42]
master = master[0], [cell for k,cell in enumerate(master[1]) if not (k in toRemove)]
bagnoManTemp=DRAW2(master)

bagnoManTemp=COLOR(rgbToPlasmColor([255	,204,153]))(bagnoManTemp)

finestra0=creaFinestre(1.6,1.2)
finestra0=T([1,3])([0.5,1])(finestra0)

bagnoMan=STRUCT([bagnoManTemp,finestra0])

#Balcone

master = assemblyDiagramInit([3,3,3])([[.1,9.8,.1],[.1,1.3,.1],[.1,1.5,.1]])
V,CV = master
hpc = SKEL_1(STRUCT(MKPOLS(master)))
hpc= cellNumbering (master,hpc)(range(len(CV)),CYAN,2)

#Rimozione
toRemove = [13,16,17,14]
master = master[0], [cell for k,cell in enumerate(master[1]) if not (k in toRemove)]
balcone=DRAW2(master)
balcone=T(2)(-1.5)(balcone)

#muro
muro=CUBOID([0.1,1.8,2.4])
muro=T(2)(3.5)(muro)

#muro2
muro2=CUBOID([4.5,0.1,2.4])
muro2=T(2)(5.3)(muro2)

#ParteSupTettoMansarda
ParteSupTettoMansarda=CUBOID([10,9.7,0.3])
ParteSupTettoMansarda=T([2,3])([-0.7,2.4])(ParteSupTettoMansarda)

#TettoMansarda
tettoM_vertici = [ [0,0], [9.7,0], [4.85,1.5], ];
tettoM_num_lati = [range(1,4)]
tettoM_2D = MKPOL([tettoM_vertici, tettoM_num_lati, None])
#Porto in 2,5D
tettoM = PROD([tettoM_2D, Q(10)])
tettoM=ROTATE([2,3])(PI/2)(tettoM)
tettoM=ROTATE([1,2])(PI/2)(tettoM)
tettoM=T([2,3])([-0.7,2.7])(tettoM)

#Sottotetto
master = assemblyDiagramInit([5,5,2])([[.1,3,.1,6.7,.1],[.1,1,1,1.4,.1],[.1,2.3]])
V,CV = master
hpc = SKEL_1(STRUCT(MKPOLS(master)))
hpc= cellNumbering (master,hpc)(range(len(CV)),CYAN,2)

toMerge = 25
diagram0 = assemblyDiagramInit([1,1,2])([[3],[.1],[2.2,.2]])
master = diagram2cell(diagram0,master,toMerge)
hpc = SKEL_1(STRUCT(MKPOLS(master)))
hpc = cellNumbering (master,hpc)(range(len(master[1])),CYAN,2)

#Rimozione
toRemove = [11,21,30,49,13,15,17,36,34,32]
master = master[0], [cell for k,cell in enumerate(master[1]) if not (k in toRemove)]
sottotetto=DRAW2(master)
sottotetto=T([2])(5.4)(sottotetto)

tettoM=COLOR(rgbToPlasmColor([206,48,24]))(tettoM)
ParteSupTettoMansarda=COLOR(rgbToPlasmColor([123,27	,2	]))(ParteSupTettoMansarda)
balcone=COLOR(rgbToPlasmColor([255	,204,153]))(balcone)
muro=COLOR(rgbToPlasmColor([255	,204,153]))(muro)
muro2=COLOR(rgbToPlasmColor([255	,204,153]))(muro2)

tettoM=COLOR(rgbToPlasmColor([206,48,24]))(tettoM)
ParteSupTettoMansarda=COLOR(rgbToPlasmColor([123,27	,2	]))(ParteSupTettoMansarda)
cameraMan=COLOR(rgbToPlasmColor([255	,204,153]))(cameraMan)
sottotetto=COLOR(rgbToPlasmColor([255	,204,153]))(sottotetto)
bagnoMan=COLOR(rgbToPlasmColor([255	,204,153]))(bagnoMan)
balcone=COLOR(rgbToPlasmColor([255	,204,153]))(balcone)
muro=COLOR(rgbToPlasmColor([255	,204,153]))(muro)
muro2=COLOR(rgbToPlasmColor([255	,204,153]))(muro2)

Mansarda=STRUCT([cameraMan,bagnoMan,balcone,muro,muro2,sottotetto,ParteSupTettoMansarda,tettoM])
#ParteSupTettoMansarda,tettoM

Mansarda=T([1,2,3])([3.9,1.5,2.8])(Mansarda)

#Rimozione
rimozione=CUBOID([10.1,14,3.8])
rimozione=T([1,3])([3.9,2.8])(rimozione)
tetto=DIFFERENCE([tetto,rimozione])
parteSup=DIFFERENCE([parteSup,rimozione])

#Giardino
domain1D = larDomain([32])
domain2D = larIntervals([32,48],'simplex')([1,1])
b1 = BEZIER(S1)([[-1.5,4], [0.5,-7], [6.5,-7], [7.5,0]])
b2=BEZIER(S1)([[-1.5,4], [0.5,5], [6.5,5], [7.5,0]])
controls = [b1,b2]
mapping = BEZIER(S2)(controls)
path = STRUCT(MKPOLS(larMap(mapping)(domain2D)))
giardino1 = PROD([path, Q(2.8)])
giardino1=T([2,3])([-14.3,-2.9])(giardino1)

b1 = BEZIER(S1)([[9.5,0], [10.5,-7], [16.5,-7], [17.3,4]])
b2=BEZIER(S1)([[9.5,0], [9.5,5], [16.5,5], [17.3,4]])
controls = [b1,b2]
mapping = BEZIER(S2)(controls)
path = STRUCT(MKPOLS(larMap(mapping)(domain2D)))
giardino2 = PROD([path, Q(2.8)])
giardino2=T([2,3])([-14.3,-2.9])(giardino2)

giardino3=CUBOID([18.8,6,2.8])
giardino3=T([1,2,3])([-1.5,-10.4,-2.9])(giardino3)

giardino4=CUBOID([13,6,2.8])
giardino4=T([1,2,3])([2,-14,-2.9])(giardino4)

#Assemblo
giardino=STRUCT([giardino1,giardino2,
	giardino4])
giardino=T([2])(3.4)(giardino)
giardino3=T([2])(3.4)(giardino3)

#GiardinoREMOVE
domain1D = larDomain([32])
domain2D = larIntervals([32,48],'simplex')([1,1])
b1 = BEZIER(S1)([[-1.3,4], [0.7,-7], [6.3,-7], [7.3,0]])
b2=BEZIER(S1)([[-1.3,4], [0.7,5], [6.3,5], [7.3,0]])
controls = [b1,b2]
mapping = BEZIER(S2)(controls)
path = STRUCT(MKPOLS(larMap(mapping)(domain2D)))
giardinoR1 = PROD([path, Q(0.1)])
giardinoR1=T([2,3])([-14.3,0.1])(giardinoR1)

b1 = BEZIER(S1)([[9.7,0], [10.7,-7], [16.3,-7], [17.1,4]])
b2=BEZIER(S1)([[9.7,0], [9.7,5], [16.3,5], [17.1,4]])
controls = [b1,b2]
mapping = BEZIER(S2)(controls)
path = STRUCT(MKPOLS(larMap(mapping)(domain2D)))
giardinoR2 = PROD([path, Q(0.1)])
giardinoR2=T([2,3])([-14.3,0.1])(giardinoR2)

giardinoR3=CUBOID([18.4,4.5,0.1])
giardinoR3=T([1,2,3])([-1.3,-10.5,0.1])(giardinoR3)

giardinoR4=CUBOID([12.8,6,0.1])
giardinoR4=T([1,2,3])([2.1,-14,0.1])(giardinoR4)

#Assemblo
giardinoR=STRUCT([giardinoR1,giardinoR2,
        giardinoR4])
giardinoR=T([2])(3.4)(giardinoR)
giardinoR3=T([2])(3.4)(giardinoR3)
giardinoRemove=STRUCT([giardinoR,giardinoR3])
giardinoRemove=T(3)(-0.2)(giardinoRemove)
giardinoRemove=COLOR(rgbToPlasmColor([34,139,34	]))(giardinoRemove)

#Assemblo

principale=STRUCT([camera1,camera2,bagno,stireria,scale,soggiorno2,soggiorno3,soggiorno4,cucina
	,bagno2,remove,remove2,remove3])

#Coloro

camino=COLOR(rgbToPlasmColor([240,248,255]))(camino)
scalinata=COLOR(rgbToPlasmColor([153,51,0]))(scalinata)
scalinata2=COLOR(rgbToPlasmColor([229,228,226]))(scalinata2)
parteSup=COLOR(rgbToPlasmColor([123	,27	,2	]))(parteSup)
esterno=COLOR(rgbToPlasmColor([255	,204,153]))(esterno)
baseEsterno=COLOR(rgbToPlasmColor([255	,204,153]))(baseEsterno)
tetto=COLOR(rgbToPlasmColor([206,48,24]))(tetto)
giardino=COLOR(rgbToPlasmColor([184	,115	,51]))(giardino)
giardino3= COLOR(rgbToPlasmColor([255	,204,153]))(giardino3)
est3=COLOR(rgbToPlasmColor([147,147,147]))(est3)

#Creo la siepe
pianta= CUBOID([0.5,0.5,0.8])
Tp=T(2)(0.6)
piante1=STRUCT(NN(8)([Tp, pianta]))
piante1=T([1,2])([-1.3,-8.2])(piante1)

pianta2=T([1,2])([-1.1,-8.2])(pianta)
pianta3=T([1,2])([-1.0,-8.8])(pianta)
pianta4=T([1,2])([-0.8,-9.4])(pianta)
pianta5=T([1,2])([-0.6,-10])(pianta)
pianta6=T([1,2])([-0.4,-10.6])(pianta)
pianta7=T([1,2])([-0.2,-11.2])(pianta)
pianta8=T([1,2])([0,-11.8])(pianta)
pianta9=T([1,2])([0.2,-12.4])(pianta)
pianta10=T([1,2])([0.6,-13])(pianta)
pianta11=T([1,2])([0.9,-13.6])(pianta)
pianta12=T([1,2])([1.3,-14.2])(pianta)
pianta13=T([1,2])([1.7,-14.8])(pianta)
pianta14=T([1,2])([2.3,-15.4])(pianta)
pianta15=T([1,2])([2.8,-15.6])(pianta)
pianta16=T([1,2])([3.4,-15.8])(pianta)
pianta17=T([1,2])([4.0,-15.8])(pianta)
pianta18=T([1,2])([4.6,-15.6])(pianta)
pianta19=T([1,2])([5.1,-15.4])(pianta)
pianta20=T([1,2])([5.4,-14.9])(pianta)
pianta21=T([1,2])([5.8,-14.4])(pianta)
pianta22=T([1,2])([6.2,-13.8])(pianta)
pianta23=T([1,2])([6.4,-13.2])(pianta)
pianta24=T([1,2])([6.6,-12.6])(pianta)
pianta25=T([1,2])([6.8,-12])(pianta)
pianta26=T([1,2])([7,-11.4])(pianta)
pianta27=T([1,2])([7,-10.6])(pianta)
pianta28=T([1,2])([9.3,-10.6])(pianta)

siepe1=STRUCT([pianta18,pianta19,pianta20,pianta21,pianta22,pianta23,pianta24,pianta25])
siepe2=STRUCT([pianta18,pianta19,pianta20,pianta21,pianta22,pianta23,pianta24,pianta25])
siepe2=T(1)(9)(siepe2)
siepe3=STRUCT([pianta7,pianta8,pianta9,pianta10,pianta11,pianta12,pianta13,pianta14,pianta15,pianta16,pianta17])
siepe4=STRUCT([pianta7,pianta8,pianta9,pianta10,pianta11,pianta12,pianta13,pianta14,pianta15,pianta16,pianta17])
siepe4=T(1)(9.5)(siepe4)
siepe5=STRUCT([pianta5,pianta6,pianta7,pianta8,pianta9])
siepe6=STRUCT([pianta5,pianta6,pianta7,pianta8,pianta9])
siepe6=ROTATE([1,3])(PI)(siepe6)
siepe6=T([1,2,3])([16.6,1,0.8])(siepe6)
siepe7=STRUCT([pianta2,pianta3,pianta4])
siepe8=STRUCT([pianta2,pianta3])
siepe8=ROTATE([1,3])(PI)(siepe8)
siepe8=T([1,2,3])([16.2,0.5,0.8])(siepe8)

siepe=STRUCT([siepe1,siepe2,siepe3,siepe4,siepe5,siepe6,siepe7,siepe8,piante1,
        pianta26,pianta27,pianta28])
siepe=COLOR(rgbToPlasmColor([128 ,128,0]))(siepe)

plan1 = STRUCT([principale,scalinata,scalinata2,esterno,baseEsterno,parteSup,giardino,camino,
	Mansarda,tetto,giardino3,giardinoRemove,siepe,est3,est4,est5,est6])
#tetto,Mansarda

#Visualizzo
VIEW(plan1)


from argparse import ArgumentParser

from sudoku_solver import SudokuSolver
from sudoku import Sudoku

def get_args():
    parser = ArgumentParser()
    parser.add_argument('--sudoku', required=True)

    return parser.parse_args()

def main():
    args = get_args()
    sudoku = Sudoku.from_file(args.sudoku)
    solver = SudokuSolver(sudoku)
    solved_sudoku = solver.solve()
    solved_sudoku.print_sudoku()

if __name__ == '__main__':
    main()


'''
Terminal
!pip install dash==0.26.5  # The core dash backend
!pip install dash-html-components==0.12.0  # HTML components
!pip install dash-core-components==0.28.0  # Supercharged components
!pip install dash_bootstrap_components==0.13.1
'''

# Run this app with `python app.py` and
# visit http://127.0.0.1:8050/ in your web browser.

from dash import Dash, dcc, html
import plotly.express as px
import pandas as pd
import dash_bootstrap_components as dbc
import numpy as np
import plotly.graph_objects as go
from plotly.subplots import make_subplots
# create dash
app = Dash(__name__)

colors = {
    'background': '#FFFFFF',
    'text': '#288CC2'
}

### bar chart example
df = pd.DataFrame({
    "Fruit": ["Apples", "Oranges", "Bananas", "Apples", "Oranges", "Bananas"],
    "Amount": [4, 1, 2, 2, 4, 5],
    "City": ["SF", "SF", "SF", "Montreal", "Montreal", "Montreal"]
})
fig = px.bar(df, x="Fruit", y="Amount", color="City", barmode="group")
fig.update_layout(
    #plot_bgcolor=colors['background'],
    #paper_bgcolor=colors['background'],
    font_color=colors['text']
)

### scatter plot example
df2 = pd.read_csv('https://gist.githubusercontent.com/chriddyp/5d1ea79569ed194d432e56108a04d188/raw/a9f9e8076b837d541398e999dcbac2b2826a81f8/gdp-life-exp-2007.csv')
fig2 = px.scatter(df2, x="gdp per capita", y="life expectancy",
                 size="population", color="continent", hover_name="country",
                 log_x=True, size_max=60)

fig2.update_layout(
	font_color=colors['text'])

### violin plot example 1
df3 = pd.DataFrame(
    {'x':np.tile(['no', 'yes'], 80000),
     'y':np.random.normal(0, 1, 160000),
     'cl':np.repeat([0, 1], 80000)

    }
)

fig3 = px.violin(df3, x="x", y="y", color='cl', box=True, hover_data=df3.columns)
fig4 = px.violin(df3, y="y", color='cl',
                violinmode='overlay', # draw violins on top of each other
                # default violinmode is 'group' as in example above
                hover_data=df3.columns)

### violin plot example 2
df4 = pd.read_csv("https://raw.githubusercontent.com/plotly/datasets/master/violin_data.csv")

fig5 = go.Figure()

fig5.add_trace(go.Violin(x=df4['day'][ df4['smoker'] == 'Yes' ],
                        y=df4['total_bill'][ df4['smoker'] == 'Yes' ],
                        legendgroup='Yes', scalegroup='Yes', name='Yes',
                        side='negative',
                        line_color='blue')
             )
fig5.add_trace(go.Violin(x=df4['day'][ df4['smoker'] == 'No' ],
                        y=df4['total_bill'][ df4['smoker'] == 'No' ],
                        legendgroup='No', scalegroup='No', name='No',
                        side='positive',
                        line_color='orange')
             )
fig5.update_traces(meanline_visible=True) # orientation='h' -> horizontal
fig5.update_layout(violingap=0, violinmode='overlay')

### subplot example
df5 = px.data.iris()
fig6 = make_subplots(rows=1,
                    cols=2,
                    subplot_titles=[
                        'Fruit',  # 1. subplot title
                        'City'  # 2. subplot title
])

fig6.add_trace(go.Bar(x=df['Fruit'], y=df['Amount']),row=1, col=1)

fig6.add_trace(go.Bar(x=df['City'], y=df['Amount'], text=df['Amount'],
            textposition='auto',), row=1, col=2)

fig6.update_layout(title='Count', title_x=0.5)

# set the web layout
app.layout = html.Div(style={'backgroundColor': colors['background']}, children=[

    html.H1(
        children='Hello Dash',
        style={
            'textAlign': 'center',
            'color': colors['text']
        }
    ),

    html.Div(children='Dash: A web application framework for your data.', style={
        'textAlign': 'center',
        'color': colors['text']
    }),

    dcc.Graph(
        id='example-graph-1',
        figure=fig
    ),

    dcc.Graph(
        id='example-graph-2',
        figure=fig2
    ),

    dcc.Graph(
		id='example-graph-3',
		figure=fig3
	),

    dcc.Graph(
        id='example-graph-5',
        figure=fig5
    ),

    dcc.Graph(
        id='example-graph-6',
        figure=fig6
    ),

])

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


# Created on 24 September 2019

from square import Square, getScaledFont
from random import randint
from math import cos, sin, pi, atan, copysign
from pygame.mixer import *
from pygame.draw import rect
from pygame.locals import *
from pygame.time import Clock
from pygame.display import update
from pygame.mouse import get_pos

class GameDriver:
    def __init__(self, dim, w):
        self.dim = dim
        self.w = w
        self.squares = []
        self.vals = []
        # Stores sets of ((x,y): (#Squares to slide, surface))
        self.slides = {}
        self.slide_duration = 300
        self.v = (0, 0)
        self.score = 0
        self.prev_score = 0
        for y in range(dim[1]):
            row = []
            val = []
            for x in range(dim[0]):
                row.append(None)
                val.append(-1)
            self.squares.append(row)
            self.vals.append(val)

    def drawBoard(self, display):
        for y, row in enumerate(self.squares):
            for x, s in enumerate(row):
                if s != None:
                    display.blit(s.surface, (x * self.w, y * self.w))
                else:
                    rect(display, (0, 0, 0), (x * self.w, y * self.w, self.w, self.w))
                    rect(display, (255, 255, 255), (x * self.w, y * self.w, self.w, self.w), 2)
        update()

    def move(self, display, undo):
        if len(self.slides) == 0:
            return
        if undo:
            self.score = self.prev_score
            for y, (row1, row2) in enumerate(zip(self.squares, self.vals)):
                for x, (s, val) in enumerate(zip(row1, row2)):
                    if val == -1 and s != None:
                        self.squares[y][x] = None
                    elif val != -1 and s == None:
                        self.squares[y][x] = Square(val, self.w)
                    elif val != -1 and s != None:
                        self.squares[y][x].changeVal(val)
        updates = 20
        for i in range(updates):
            for x, y in self.slides.keys():
                v, surface = self.slides[(x, y)]
                xf, yf = x + v[0], y + v[1]
                if undo:
                    v = (-v[0], -v[1])
                    x, xf = xf, x
                    y, yf = yf, y
                v = (v[0] * self.w, v[1] * self.w)
                x1, y1 = x * self.w, y * self.w
                dx, dy = v[0] * i / updates, v[1] * i / updates
                rect(display, (0, 0, 0), (x1 + dx, y1 + dy, self.w, self.w))
                dx, dy = v[0] * (i + 1) / updates, v[1] * (i + 1) / updates
                display.blit(surface, (x1 + dx, y1 + dy))
            update()
            Clock().tick(updates * 1000 / self.slide_duration)
        self.drawBoard(display)

    def addSquares(self, display):
        nones = []
        for y, row in enumerate(self.squares):
            for x, s in enumerate(row):
                if s == None:
                    nones.append((x, y))
        for i in range(min(len(nones), 2)):
            idx = randint(0, len(nones) - 1)
            x, y = nones[idx]
            s = Square(2, self.w)
            self.squares[y][x] = s
            display.blit(s.surface, (x * self.w, y * self.w))
            nones.pop(idx)
        update()

    def lost(self):
        for y, row in enumerate(self.squares):
            for x, s in enumerate(row):
                if s == None:
                    return False
                else:
                    adjacent = []
                    for delta in ((-1, 0), (1, 0), (0, -1), (0, 1)):
                        x1, y1 = x + delta[0], y + delta[1]
                        in_range = 0 <= x1 < self.dim[0] and 0 <= y1 < self.dim[1]
                        if in_range and self.squares[y1][x1] != None:
                            adjacent.append(self.squares[y1][x1].val)
                    if s.val in adjacent:
                        return False
        return True

    def updateScore(self, display, score_rect):
        font = getScaledFont("Times New Roman", (score_rect.w, score_rect.h), str(self.score))
        text = font.render(str(self.score), 1, (255, 255, 255))
        text_rect = text.get_rect(center=(score_rect.centerx, score_rect.centery))
        rect(display, (0, 0, 0), text_rect)
        display.blit(text, text_rect)

    def run(self, display, events, undo_rect, score_rect):
        for e in events:
            if e.type == MOUSEBUTTONUP and e.button == BUTTON_LEFT and \
                    undo_rect.collidepoint(get_pos()):
                self.move(display, True)
                self.slides.clear()
            elif e.type == KEYUP:
                if e.key == K_LEFT:
                    self.v = (-1, 0)
                elif e.key == K_RIGHT:
                    self.v = (1, 0)
                elif e.key == K_UP:
                    self.v = (0, -1)
                elif e.key == K_DOWN:
                    self.v = (0, 1)
                else:
                    continue
                self.slides.clear()
                self.prev_score = self.score
                move_x = self.v[0] != 0
                is_neg = -1 in self.v
                idx = 0 if move_x else 1
                lb = 0 if is_neg else -abs(self.dim[idx] * self.v[idx]) + 1
                ub = abs(self.dim[idx] * self.v[idx]) if is_neg else 1
                blanks = []
                merges = []
                prev = []
                for v1 in range(lb, ub):
                    for v2 in range(self.dim[1 - idx]):
                        if len(blanks) <= v2:
                            blanks.append(0)
                            prev.append(0)
                            merges.append(0)
                        x = abs(v1) if move_x else v2
                        y = v2 if move_x else abs(v1)
                        s = self.squares[y][x]
                        self.vals[y][x] = -1 if s == None else s.val
                        if s == None:
                            blanks[v2] += 1
                        else:
                            offset = blanks[v2] + merges[v2]
                            dx, dy = self.v[0] * offset, self.v[1] * offset
                            last_val = prev[v2]
                            prev[v2] = s.val
                            if last_val == s.val:
                                offset += 1
                                dx1, dy1 = self.v[0] * offset, self.v[1] * offset
                                self.slides[(x, y)] = ((dx1, dy1), s.surface)
                                self.squares[y + dy1][x + dx1].upgrade()
                                self.squares[y][x] = None
                                prev[v2] = 0
                                merges[v2] += 1
                                self.score += s.val * 2
                            elif offset != 0:
                                self.slides[(x, y)] = ((dx, dy), s.surface)
                                self.squares[y + dy][x + dx] = s
                                self.squares[y][x] = None
                self.move(display, False)
                self.addSquares(display)
                if sum(merges) >= 3:
                    music.load("bomb.mp3")
                    music.play()
            self.updateScore(display, score_rect)
            return self.lost()


n, m = map(int, input().split())
graph = []
arr = []
cnt = 0

for _ in range(n):
    graph.append(list(map(int, input())))

def dfs(x, y):
    global cnt
    if x<0 or y<0 or x>=n or y>=m:
        return False

    if graph[x][y] == 1:
        cnt += 1
        graph[x][y] = 0

        dfs(x-1, y)
        dfs(x, y-1)
        dfs(x+1, y)
        dfs(x, y+1)

        value = cnt
        cnt = 0
        return True

result = 0
for i in range(n):
    for j in range(m):
        if dfs(i,j) == True:
            arr.append(cnt)
            result += 1
print(max(arr))

print(result)


import pandas as pd

def distance_in_yards(object_size_actual,object_size_mils):
    try:
        float(object_size_actual) and float(object_size_mils)
    except ValueError:
         return "Please enter a valid number."

    object_distance_yards = (float(object_size_actual)*27.8)/float(object_size_mils)
    return round(object_distance_yards,2)

def correction_moa(correction_inches_seen,known_distance):
    try:
        float(correction_inches_seen) and float(known_distance)
    except ValueError:
        return "Please enter a valid number."

    correction_required = float(correction_inches_seen)/(float(known_distance)/100)
    return round(correction_required,2)

def wind_correction(range_to_target,windspeed):
    try:
        float(range_to_target) and float(windspeed)
    except ValueError:
        return "Please enter a valid number."

    if float(range_to_target) <= 500:
        wind_correction_factor = ((float(range_to_target)/100)*float(windspeed))/15
        return wind_correction_factor
    if 500 < float(range_to_target) <= 600:
        wind_correction_factor = ((float(range_to_target)/100)*float(windspeed))/14
        return wind_correction_factor
    if 600 < float(range_to_target) <= 800:
         wind_correction_factor = ((float(range_to_target)/100)*float(windspeed))/13
         return wind_correction_factor
    if 800 < float(range_to_target) <= 900:
        wind_correction_factor = ((float(range_to_target)/100)*float(windspeed))/12
        return wind_correction_factor
    if 900 < float(range_to_target) <= 1000:
        wind_correction_factor = ((float(range_to_target)/100)*float(windspeed))/11
        return wind_correction_factor
    else:
        return "Shot is too far for windage rule"

def hw_tw_correction (range_to_target_hw_tw,windspeed_hw_tw,hw_or_tw):
    try:
        float(range_to_target_hw_tw) and float(windspeed_hw_tw)
    except ValueError:
        return "Please enter a valid number."
    hw_tw_correction_final = ((float(range_to_target_hw_tw)/100)*float(windspeed_hw_tw))/4
    return round(hw_tw_correction_final,2)

def new_range_zero(sight_height,known_zero_range,desired_zero_range,bullet_type):
    try: float(sight_height)
    except ValueError:
        return "Please enter a valid number"

    df_ballistics_chart = pd.read_excel(r"C:\Users\bnofi\OneDrive\Desktop\Long_range_shooting\hornady_excel_document.xlsx")
    bullet_drop_known_zero = df_ballistics_chart.query('BULLET == @bullet_type')[known_zero_range]
    bullet_drop_desired_zero = df_ballistics_chart.query('BULLET == @bullet_type' )[desired_zero_range]

    sight_adjustment = (float(bullet_drop_known_zero) - float(sight_height)) + (float(known_zero_range)/float(desired_zero_range)) * (float(sight_height) - (float(bullet_drop_desired_zero)))
    return round(sight_adjustment,2)

def new_range_zero_moa(sight_height_moa,known_zero_range_moa,desired_zero_range_moa,bullet_type_moa):
    try: float(sight_height_moa)
    except ValueError:
        return "Please enter a valid number"

    df_ballistics_chart = pd.read_excel(r"C:\Users\bnofi\OneDrive\Desktop\Long_range_shooting\hornady_excel_document.xlsx")

    bullet_drop_known_zero_moa = df_ballistics_chart.query('BULLET == @bullet_type_moa')[known_zero_range_moa]
    bullet_drop_desired_zero_moa = df_ballistics_chart.query('BULLET == @bullet_type_moa' )[desired_zero_range_moa]

    a_one = 95.493*((float(sight_height_moa)-(float(bullet_drop_known_zero_moa)))/float(known_zero_range_moa))
    a_two = 95.493*((float(sight_height_moa)-(float(bullet_drop_desired_zero_moa)))/float(desired_zero_range_moa))

    final_moa_correction = float(a_two) - float(a_one)

    return round(final_moa_correction,2)


from typing import Optional

class ListNode:
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next

class Solution:
    def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
        dummy = ListNode()

        while head:
            cur = head
            head = head.next
            cur.next = dummy.next
            dummy.next = cur

        return dummy.next


from random import randint

print("Welcome to the Number GuessingGame!")
print("I'm thinkin of a number between 1 and 100.")

#select hard, you get 5 guesses/ select easy you get 10
def guessGame():
    number2Guess = randint(1,100)
    guessed = False
    global lives
    lives = setLives()
    #game begins
    while guessed == False:
        print(f"You have {lives} attempts remaining to guess the number.") #you have x Lives and you can guess
        guessed = howClose(int(input("Make a guess: ")),number2Guess) #calls our function, if true we get out and we it
    again = input("Would you like to play again? 'y' or 'n': ")
    if again == 'y':
        guessGame()
    else:
        print("Game over")

def setLives():
    difficulty = input("Choose a difficulty. Type 'easy' or 'hard': ")
    if difficulty == 'easy':
        lives = 10
        return lives
    elif difficulty == 'hard':
        lives = 5
        return lives
    else:
        guessGame()

def howClose(guess,hiddenNumber):
    global lives
    if guess == hiddenNumber:
        print(f"Congratulations the answer was {hiddenNumber}")
        return True
    elif guess < hiddenNumber:
        print("Too low")
        lives-=1
        return False
    elif guess > hiddenNumber:
        print("Too high")
        lives-=1
        return False

guessGame()