import json
import os
import socket
import sys
import textwrap
import numpy as np
import random
import time
import numpy.random as npyrnd
from numpy import dtype as npydtype
from coordinator_udp_sender import Smart_UDP_Sender_Socket
from keras import models, layers
from typing import List
# from coordinator_udp_receiver import AlwaysOpenUDP_Receiver
# import paramiko
import select
import zipfile
import tensorflow as tf
import csv
import pathlib
import cv2
import pickle
import communication
import srudp

useful_characters = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f",  "g", "h", "i", "j", "k", "l", "m", "n", "o", "p",  "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "{", "}", "[", "]", ":", "-", ",", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", " ", "\"", "-", ".", ":"]

rand_string = ""
test_string = "test_string"
rand_text_length = 4500
string_length_per_packet = 1500

for i in range(rand_text_length):
    rand_string += "1"
rand_packets = textwrap.wrap(rand_string, string_length_per_packet)

def read_json_file():
    some_file_handle = open("results_22.json", "r")
    my_json_obj = json.load(some_file_handle)
    print(my_json_obj)

def read_already_open_file():
    some_file = open("test_file.txt", "r")
    some_file_copy = open("test_file.txt", "r")
    print(some_file)
    print(some_file_copy)
    print("Done")

def change_directory_test():
    curr_dir = os.getcwd()
    print(curr_dir)
    os.chdir("../images/")
    curr_dir = os.getcwd()
    print(curr_dir)
    print(os.curdir)

def create_numpy_array():
    some_numpy_ndarray = np.zeros(shape=(1, 10), dtype=float)
    some_numpy_ndarray_converted_to_list = some_numpy_ndarray.tolist()
    print(some_numpy_ndarray_converted_to_list)

def add_two_numpy_arrays():
    first_numpy_array = np.zeros(shape=(1, 10), dtype=float)
    second_numpy_array = np.arange(10)
    print(first_numpy_array + second_numpy_array)

def get_multidimensional_array_length():
    some_dumb_array = list(list([]))
    some_dumb_array.append([1, 2, 3, 4])
    some_dumb_array.append([3, 4, 5, 6, 7])
    print(some_dumb_array[0])
    print(len(some_dumb_array[0]))

def generate_random_numbers():
    nanoseconds_time = time.perf_counter_ns()
    random.seed(nanoseconds_time)
    print(random.random(), random.random(), random.random())
    random.seed(nanoseconds_time)
    print(random.random(), random.random(), random.random())
    print(random.randint(15, 20))
    print(random.sample([1, 2, 3, 4, 5, 6, 7, 8], 3))
    a = [1, 2, 3, 4, 5, 6, 7]
    random.shuffle(a)
    print(a)
    print("Betavariate: ", random.betavariate(2, 2))
    print("Gauss: ", random.gauss(0, 1))
    npyrnd.seed(15)
    print(npyrnd.rand(3))
    npyrnd.seed(15)
    print(npyrnd.rand(3))
    print(npyrnd.randint(low=55, high=100, dtype=int))

def send_custom_payload():
    remote_port = 5757
    remote_ip = "192.168.1.41"
    remote_address_tuple = (remote_ip, remote_port)
    custom_payload = "Some payload"
    packet_data = custom_payload.encode()
    some_socket = socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM)
    expected_byte_length = 1500
    packet = bytearray()
    packet.extend(bytearray(packet_data))
    while True:
        try:
            for i in range(expected_byte_length - len(packet_data) - 8):
                packet.extend(str(0).encode())
            some_socket.sendto(packet, remote_address_tuple)
        except socket.timeout:
            continue
        except KeyboardInterrupt:
            break

def send_reliable_data_router(remote_addr: str = "192.168.1.41", remote_port: int = 4040, pkt_rate=50, max_bytes_per_packet=1500, local_port_to_send_from: int = 5757, socket_arg: socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM) = None):

    PktPeriod = 1.0 / pkt_rate  # Period of packet generation
    sleeptime = PktPeriod  # time to sleep between packets

    print("Test source to MK1 on %s:%d" % (remote_addr, remote_port))
    rxsock = socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM)
    if socket_arg is None:
        rxsock = socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM)
    else:
        rxsock = socket_arg
    rxsock.bind(('', local_port_to_send_from))
    rxsock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
    Target = (remote_addr, remote_port)  # the target address and port
    new_time = time.time()
    start_pkt_num = 0
    last_pkt_num = 0
    pkt_count = 0
    last_update_time = time.time()
    start_time = last_update_time
    UpdatePeriod = 1.0
    PktRatePeriod = 1.0
    all_packets_sent_reliably = False
    try:
        # Main loop
        while not all_packets_sent_reliably:
            pkt_generation_time = time.time()
            pktbuf = bytearray()
            some_string = "abc"
            for i in range(len(some_string)):
                pktbuf.append(ord(some_string[i]) & 0xff)
                print(chr(ord(some_string[i])))
            for i in range(0, max_bytes_per_packet - len(some_string)):
                pktbuf.append(0 & 0xff)

            # print_byte_string(pktbuf)
            print('Total packets transmitted: %d' % (pkt_count + 1))
            # print ('')

            # Transmit the packet to the MK1 via the socket
            rxsock.sendto(pktbuf, Target)

            # Increment packet numbers
            pkt_count = pkt_count + 1

            if new_time - last_update_time > UpdatePeriod:
                tx_pkt_rate = ((pkt_count - last_pkt_num) /
                               (new_time - last_update_time))
                last_pkt_num = pkt_count
                last_update_time = new_time

            last_time = new_time
            new_time = time.time()

            timediff = new_time - last_time

            errtime = (PktPeriod * (pkt_count - start_pkt_num) -
                       (new_time - start_time))
            sleeptime = PktPeriod + errtime

            if new_time - start_time > PktRatePeriod:
                start_time = new_time
                start_pkt_num = pkt_count

            if sleeptime < 0:
                sleeptime = 0
            time.sleep(sleeptime)

        print("Transmitted %d packets" % pkt_count)
        return pkt_count
    except KeyboardInterrupt:
        rxsock.close()
        print('User CTRL-C, stopping packet source')
        sys.exit(1)

    except:
        rxsock.close()
        print("Got exception:", sys.exc_info()[0])
        raise

def send_reliable_data_loopback():
    reliable_packet_index = 0
    sender = Smart_UDP_Sender_Socket(udp_local_address_arg=("127.0.0.1", 5000), udp_target_address_arg=("127.0.0.1", 5250))
    sender.bind_to_local_address()
    sender.initiate_handshake()

def ord_long_string(some_long_string: str = "") -> bytearray:
    returned_list = bytearray()
    for i in range(len(some_long_string)):
        returned_list.append(ord(some_long_string[i]) & 0xff)
    return returned_list

def chr_long_string(some_byte_array_arg: bytearray) -> str:
    temp_str = ""
    some_bytes_object = bytes(some_byte_array_arg)
    some_bytes_object_decoded = some_bytes_object.decode()
    print()
    return temp_str

def ack_router_test():
    sender = Smart_UDP_Sender_Socket(udp_local_address_arg=("192.168.1.57", 5000),
                                     udp_target_address_arg=("192.168.1.31", 5757))
    sender.bind_to_local_address()
    sender.send_ACK_to_router(0)

def send_test_string():
    sender = Smart_UDP_Sender_Socket(udp_local_address_arg=("192.168.1.57", 4002),
                                     udp_target_address_arg=("192.168.1.31", 4000))
    sender.bind_to_local_address()
    sender.send_single_packet_to_router(curr_packet=test_string)

def keep_useful_characters(str_to_parse: str = ""):
    str_to_parse_len = len(str_to_parse)
    index = 0
    while index < str_to_parse_len:
        if str_to_parse[index] in useful_characters:
            index += 1
            continue
        else:
            str_to_parse = str_to_parse.replace(str_to_parse[index], "")
            str_to_parse_len = len(str_to_parse)
    return str_to_parse

def generate_list_of_floats_of_certain_length(length: int = 100) -> list:
    some_list = []
    for i in range(length):
        some_list.append(random.random())
    return some_list

def receive_test_string():
    some_socket = socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM)
    some_socket.bind(("192.168.1.57", 4002))
    recvd_bytes, recvd_from = some_socket.recvfrom(1500)
    print(recvd_bytes)
    print(recvd_from)
    some_socket.close()
    some_socket = socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM)
    some_socket.bind(("192.168.1.57", 4002))
    recvd_bytes, recvd_from = some_socket.recvfrom(1500)
    print(recvd_bytes)
    print(recvd_from)
    some_socket.close()

def remove_indicator_string(main_string: str = "mystr_some_mystr", indicator_string: str = "mystr"):
    main_string = main_string.replace(indicator_string, "")
    return main_string

def strip_away_indicators(input_string: str = "", indicator_string: str = "^||") -> str:
    indicator_found = input_string.find(indicator_string)
    input_string = input_string[indicator_found:]
    indicator_found = input_string.rfind(indicator_string)
    input_string = input_string[:indicator_found]
    indicator_found = input_string.find(indicator_string)
    indicator_found_reverse = input_string.rfind(indicator_string)
    while (indicator_found != indicator_found_reverse) and (indicator_found >= 0) and (indicator_found_reverse >= 0):
        input_string = input_string[indicator_found+len(indicator_string):]
        input_string = input_string[:indicator_found_reverse]
        indicator_found = input_string.find(indicator_string)
        indicator_found_reverse = input_string.rfind(indicator_string)
    input_string = input_string.replace(indicator_string, "")
    return input_string

def receive_long_string():
    test_socket = socket.socket()
    test_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    test_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
    test_socket.bind(("127.0.0.1", 5000))
    test_socket.listen()
    received_packets = []
    print(remove_indicator_string())
    while True:
        try:
            test_socket_connection, test_received_from = test_socket.accept()
            print("Connection complete")
            break
        except:
            print("Exception raised...")
            sys.exit(0)
    while True:
        try:
            some_string = test_socket_connection.recv(2500)
            if type(some_string) is not bytes:
                print(type(some_string))
            if some_string is not None:
                if "mystr" in some_string.decode():
                    print("Received a string of length: ", len(some_string.decode().replace("mystr", "")))
                    print(some_string.decode().replace("mystr", ""))
                    received_packets.append(some_string.decode().replace("mystr", ""))
                    print("Received packet count: ", len(received_packets))
                    print("Received packets cumulative length: ", len("".join(received_packets)))

        except KeyboardInterrupt:
            sys.exit(0)
        except TypeError:
            continue
        except:
            print(sys.exc_info())
            time.sleep(1.0)
            continue

def neural_net():
    x_train_new = np.load("images50_percent_training_data.npy")
    y_train = np.load("labels50_percent_training_data.npy")
    x_test_new = np.load("images50_percent_testing_data.npy")
    y_test = np.load("labels50_percent_testing_data.npy")
    model = models.Sequential()
    model.add(layers.Conv2D(16, (3, 3), activation='relu', input_shape=(200, 200, 1)))
    model.add(layers.MaxPooling2D((2, 2)))
    model.add(layers.Conv2D(32, (3, 3), activation='relu'))
    model.add(layers.MaxPooling2D((2, 2)))
    model.add(layers.Flatten())
    model.add(layers.Dense(128, activation='relu'))
    model.add(layers.Dense(2))
    model.summary()
    model.compile(optimizer='adam', loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
                  metrics=['accuracy'])
    history = model.fit(x_train_new, y_train, epochs=1, validation_data=(x_test_new, y_test))
    model_json = model.to_json()
    print(model_json)
    print(type(model_json))
    with open("model.json", "w") as json_file:
        json_file.write(model_json)
    # serialize weights to HDF5
    model.save_weights("model.h5")
    print("Saved model to disk")
    json_file = open('model.json', 'r')
    loaded_model_json = json_file.read()
    json_file.close()
    loaded_model = models.model_from_json(loaded_model_json)
    # load weights into new model
    loaded_model.load_weights("model.h5")
    print("Loaded model from disk")
    print(loaded_model)
    print(type(loaded_model))
    print(loaded_model.weights)
    print(loaded_model.layers)
    list_of_files_to_zip = ["model.h5", "model.json"]
    with zipfile.ZipFile('model_files.zip', 'w') as zipMe:
        for file in list_of_files_to_zip:
            zipMe.write(file, compress_type=zipfile.ZIP_DEFLATED)
    some_file = open("model_files.zip", "rb")
    my_bytes = some_file.read()
    print(len(my_bytes))
    sending_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sending_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    sending_socket.bind(("127.0.0.1", 5000))
    sending_socket.connect(("127.0.0.1",5001))
    print("Connected")
    sending_socket.sendall(my_bytes)

def change_float_type():
    some_np_arr = np.random.random((15, 1))
    some_np_arr_f16 = some_np_arr.astype(dtype=np.float16)
    print(some_np_arr)
    print(some_np_arr_f16)
    some_np_arr_f16_f32 = some_np_arr_f16.astype(dtype=np.float32)
    print(some_np_arr_f16_f32)

def edge_detection():
    print(pathlib.Path.home())
    some_image = cv2.imread("photos_common_directory/no20220719-124848-000001fframe0.jpg")
    print(some_image.shape)
    some_image = cv2.resize(some_image, (200,200))
    print(some_image.shape)
    some_input = np.ndarray(shape=(1,200,200,3), dtype=np.float32)
    some_input[0] = some_image
    some_tensor = tf.convert_to_tensor(some_image)
    # output = tf.keras.layers.Conv2D(3, 3, activation='relu', input_shape=some_input.shape)(some_input)
    # print(output.shape)
    img_gray = cv2.cvtColor(some_image, cv2.COLOR_BGR2GRAY)
    print(type(img_gray[0][0]))
    img_blur = cv2.GaussianBlur(img_gray, (3,3), 0)
    edges = cv2.Canny(image=img_blur, threshold1=100, threshold2=200)
    cv2.imshow('Canny Edge Detection', edges)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    print(edges.shape)
    print(type(edges[0][0]))
    print(edges)

def mini_batch(input_images: np.ndarray, image_labels: np.ndarray, batch_size: int):
    zip_obj = zip(input_images, image_labels)
    samples = random.sample(list(zip_obj), batch_size)
    output_images = np.ndarray(shape=(1, input_images.shape[1], input_images.shape[2]))
    output_labels = np.ndarray(shape=(1, image_labels.shape[1]))
    temp_image = np.ndarray(shape=(1, input_images.shape[1], input_images.shape[2]))
    temp_label = np.ndarray(shape=(1, image_labels.shape[1]))
    output_images[0] = samples[0][0]
    output_labels[0] = samples[0][1]
    for i in range(1, len(samples)):
        temp_image[0] = samples[i][0]
        temp_label[0] = samples[i][1]
        output_images = np.concatenate([output_images, temp_image])
        output_labels = np.concatenate([output_labels, temp_label])
    return output_images, output_labels

def view_images_and_labels(images: np.ndarray, labels: np.ndarray):
    for image, label in zip(images,labels):
        cv2.imshow("Current image", image)
        print("Label is: ", label)
        pressed_key = cv2.waitKey(0)
        if pressed_key == ord("q"):
            cv2.destroyAllWindows()
            break
        cv2.destroyAllWindows()

def receive_file_size(some_socket: socket.socket, file_length_keyword: str):
    while True:
        print("Started receival")
        try:
            bytez = some_socket.recv(1500)
            try:
                decoded_bytes = bytez.decode()
            except:
                continue
            print(decoded_bytes)
            if file_length_keyword in decoded_bytes:
                print("Prefix found")
                print(type(decoded_bytes))
                file_len = int(decoded_bytes.replace(file_length_keyword, ""))
                print(file_len)
                return file_len
            else:
                print("Did not get file size but got: ", decoded_bytes)
                continue
        except:
            pass

def receive_file(some_socket:socket.socket, file_length: int, packet_size: int = 1500):
    bytes_buffer = bytearray()
    while len(bytes_buffer) < file_length:
        recvd_bytes = some_socket.recv(packet_size)
        bytes_buffer.extend(recvd_bytes)
        print("Received bytes of length: ", len(recvd_bytes))
    return bytes_buffer

def receive_ID(some_socket: socket.socket, ID_keyword: str):
    recvd_bytes = some_socket.recv(1500)
    return int(recvd_bytes.decode().replace(ID_keyword, ""))

if __name__ == "__main__":
    my_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    my_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    my_socket.bind(("127.0.0.1", 2500))
    print("Socket bound")
    file_length = receive_file_size(my_socket, "file_len_")
    my_file_bytes = receive_file(my_socket, file_length)
    pass


from pynput import keyboard
import spotipy
import spotipy.util as util
import creds

scope = 'user-modify-playback-state user-read-playback-state'
token = util.prompt_for_user_token(creds.USERNAME,
                           scope,
                           client_id=creds.CLIENT_ID,
                           client_secret=creds.CLIENT_SECRET,
                           redirect_uri=creds.REDIRECT_URI)

sp = spotipy.client.Spotify(auth=token)
device_name = creds.DEVICE_NAME

def get_device(device_name):
    device_list = sp.devices()['devices']
    device = next(dev for dev in device_list if dev["name"] == device_name)
    return device

def vol_up():
    dev = get_device(device_name)
    vol = dev["volume_percent"]
    if vol < 100:
        vol += 5
    elif vol >= 100:
        vol = 100
    sp.volume(vol, device_id=dev["id"])
    print(f"Volume: {vol}")
    return

def vol_down():
    dev = get_device(device_name)
    vol = dev["volume_percent"]
    if vol > 0:
        vol -= 5
    elif vol <= 0:
        vol = 0
    sp.volume(vol, device_id=dev["id"])
    print(f"Volume: {vol}")
    return

def play_pause():
    dev = get_device(device_name)
    try:
        sp.start_playback(device_id=dev["id"])
        print("Play")
    except:
        sp.pause_playback(device_id=dev["id"])
        print("Pause")
    return

def next_track():
    dev = get_device(device_name)
    try:
        sp.next_track(device_id=dev["id"])
    except:
        print("Can't go next track")
    return

def prev_track():
    dev = get_device(device_name)
    try:
        sp.previous_track(device_id=dev["id"])
    except:
        print("Can't go prev track")
    return

# Setting up key combinations
current = set()
VOL_U = {keyboard.Key.cmd, keyboard.Key.f8}
VOL_D = {keyboard.Key.cmd, keyboard.Key.f7}
PREV = {keyboard.Key.cmd, keyboard.Key.f9}
PLAY_PAUSE = {keyboard.Key.cmd, keyboard.Key.f10}
NEXT = {keyboard.Key.cmd, keyboard.Key.f11}

def on_press(key):
    if key in VOL_D or VOL_U or PREV or PLAY_PAUSE or NEXT:
        current.add(key)
        if all(k in current for k in VOL_D):
            try:
                vol_down()
            except:
                print("Vol down action failed")
        elif all(k in current for k in VOL_U):
            try:
                vol_up()
            except:
                print("Vol up action failed")
        elif all(k in current for k in PLAY_PAUSE):
            play_pause()
        elif all(k in current for k in NEXT):
            next_track()
        elif all(k in current for k in PREV):
            prev_track()

def on_release(key):
    try:
        current.clear()
    except KeyError:
        pass

current.clear()
print("Listening")

with keyboard.Listener(on_press=on_press, on_release=on_release) as listener:
    listener.join()


from django.shortcuts import render, get_object_or_404

from filmapp.models import Director, Film
from filmapp.serializers  import DirectorSerializer, FilmSerializer

from rest_framework import status, viewsets
from rest_framework.response import Response

import datetime

def index(request):
   return render(request, "index.html", context={"data" : datetime.datetime.now()})

class DirectorViewSet(viewsets.ViewSet):
    def list(self, request):
        queryset = Director.objects.all()
        serializer = DirectorSerializer(queryset, many=True)
        return Response(serializer.data)

    def create(self, request):
        serializer = DirectorSerializer(data=request.data)

        if serializer.is_valid():
            director = Director()
            director.name = serializer.validated_data["name"]
            director.year = serializer.validated_data["year"]
            director.save()
            return Response({"status": "OK"})
        else:
            return Response(serializer.errors,
                            status=status.HTTP_400_BAD_REQUEST)

    def retrieve(self, request, pk=None):
        queryset = Director.objects.all() # помним про lazy-логику

        director = None
        try:
            director = get_object_or_404(queryset, pk=pk)
        except:
            pass
        serializer = DirectorSerializer(director)
        return Response(serializer.data)

class FilmViewSet(viewsets.ViewSet):
    def list(self, request):
        queryset = Film.objects.all()
        serializer = FilmSerializer(queryset, many=True)
        return Response(serializer.data)

    def create(self, request):
        serializer = FilmSerializer(data=request.data)

        if serializer.is_valid():
            film = Film()
            film.name = serializer.validated_data["name"]
            film.year = serializer.validated_data["year"]
            film.original_name = serializer.validated_data["original_name"]
            film.save()
            return Response({"status": "OK"})
        else:
            return Response(serializer.errors,
                            status=status.HTTP_400_BAD_REQUEST)

    def retrieve(self, request, pk=None):
        queryset = Film.objects.all() # помним про lazy-логику

        film = None
        try:
            film = get_object_or_404(queryset, pk=pk)
        except:
            pass
        serializer = FilmSerializer(film)
        return Response(serializer.data)


import os
import re
import shutil
from typing import Any, Dict, Iterable, List, Optional, Tuple, Union

import cv2
import numpy as np
import pandas as pd
from fastai.basic_train import Learner
from fastai.vision import MetricsList, Recorder, open_image
from imgaug import augmenters as iaa
from mrcnn import utils
from mrcnn.model import MaskRCNN
from skimage.io import imread

COLORS = {
    "blue": 0,
    "green": 1,
    "red": 2,
}

class SaveBestModel(Recorder):
    """Saves the best model based on scoring metric"""

    def __init__(self, learn: Learner, name: str = "best_model"):
        """Instanciates a `SaveBestModel` object.

        :param learn: learner to save the best model for.
        :param name: name of file to save."""
        super().__init__(learn)
        self.name = name
        self.best_loss = 0.0
        self.best_acc = 0.0
        self.save_method = self.save_when_acc

    def save_when_acc(self, metrics: Tuple[float, float]):
        """Callback used after each epoch to save the model if it is the best.

        :param metric: tuple containing the current loss as first element and
            the current accuracy as second element."""
        loss, acc = metrics[0], metrics[1]
        if acc > self.best_acc:
            self.best_acc = acc
            self.best_loss = loss
            self.learn.export(f"{self.name}.pkl")
            print("Save the best accuracy {:.5f}".format(self.best_acc))
        elif acc == self.best_acc and loss < self.best_loss:
            self.best_loss = loss
            self.learn.export(f"{self.name}.pkl")
            print("Accuracy is eq, Save the lower loss {:.5f}".format(self.best_loss))

    def on_epoch_end(self, last_metrics=MetricsList, **kwargs: Any):
        self.save_method(last_metrics)

def fmod(
    learn: Learner, list_images_paths: List[str], glaucoma_idx: int = 0
) -> Dict[str, float]:
    """
    fmod stands for: F_astai M_odel O_utput D_ictionary.

    :param learn: fast ai learner.
    :param list_images_paths: list of image paths to include in the output
        dictionary.
    :param glaucoma_idx: glaucoma label.
    :return: a dictionary with the images name as the key and the images
        glaucoma score as the associated value.
    """
    result_dic = {}
    for path in list_images_paths:
        path = str(path)
        pred_class, pred_idx, outputs = learn.predict(open_image(path))
        img_name = path.split(".")[0].split("/")[-1]
        result_dic[img_name] = float(outputs[glaucoma_idx])

    return result_dic

def resizeAndPad(
    img: np.ndarray, size: Tuple[int, int], padColor: Union[int, Iterable[int]] = 0
) -> np.ndarray:
    """Resize the image keeping the height proportional to the width.

    :param img: image to resize and pad as a Numpy array.
    :param size: size of resized image.
    :param padColor: color used for padded pixels.
    :return: resized image."""
    h, w = img.shape[:2]
    sh, sw = size

    # interpolation method
    if h > sh or w > sw:  # shrinking image
        interp = cv2.INTER_AREA

    else:  # stretching image
        interp = cv2.INTER_CUBIC

    # aspect ratio of image
    aspect = float(w) / h
    saspect = float(sw) / sh

    if (saspect > aspect) or ((saspect == 1) and (aspect <= 1)):  # new horizontal image
        new_h = sh
        new_w = np.round(new_h * aspect).astype(int)
        pad_horz = float(sw - new_w) / 2
        pad_left, pad_right = np.floor(pad_horz).astype(int), np.ceil(pad_horz).astype(
            int
        )
        pad_top, pad_bot = 0, 0

    elif (saspect < aspect) or ((saspect == 1) and (aspect >= 1)):  # new vertical image
        new_w = sw
        new_h = np.round(float(new_w) / aspect).astype(int)
        pad_vert = float(sh - new_h) / 2
        pad_top, pad_bot = np.floor(pad_vert).astype(int), np.ceil(pad_vert).astype(int)
        pad_left, pad_right = 0, 0

    # set pad color
    if len(img.shape) == 3 and isinstance(padColor, int):
        # color image but only one color provided
        padColor = [padColor] * 3

    # scale and padBORDER_CONSTANT, value=padColor)

    # scale and pad
    scaled_img = cv2.resize(img, (new_w, new_h), interpolation=interp)
    scaled_img = cv2.copyMakeBorder(
        scaled_img,
        pad_top,
        pad_bot,
        pad_left,
        pad_right,
        borderType=cv2.BORDER_CONSTANT,
        value=padColor,
    )

    return scaled_img

def create_pathology_dataframe(
    image_path: str, mask_paths: Dict[str, str]
) -> pd.DataFrame:
    """Creates a dataframe mapping image paths to masks.

    :param image_path: path to the directory containing the images
        to include in the dataframe.
    :param mask_paths: a dictionnary mapping mask names to directories
        containing the mask files.
    :return: a dataframe mapping image paths to their masks."""
    files_image = os.listdir(image_path)
    images = []
    for path in files_image:
        if path != ".ipynb_checkpoints":  # temp fix to a bug
            path = os.path.join(image_path, path)
            images.append(path)
            images.sort()

    annotations = pd.DataFrame(images, columns=["Paths"])
    annotations["ID"] = annotations["Paths"].apply(
        lambda row: row.split(os.path.sep)[-1]
    )

    for mask_name, mask_path in mask_paths.items():
        files = os.listdir(mask_path)
        masks = []
        for path in files:
            if path != ".ipynb_checkpoints":  # temp fix to a bug
                path = os.path.join(mask_path, path)
                masks.append(path)
                masks.sort()

        annotations[mask_name] = masks

    return annotations

class DetectorDataset(utils.Dataset):
    """Dataset class for training our dataset."""

    def __init__(
        self,
        image_fps: List[str],
        image_annotations: pd.DataFrame,
        shape: Tuple[int, int],
        class_names: List[str],
        annotation_mask_names: List[str],
        mask_color: str,
    ):
        """Instanciate a detector dataset object.

        :param image_fps: list of image file paths to include in the dataset.
        :param image_annotations: dataframe mapping image paths to masks.
        :param shape: shape of images.
        :param class_names: list of all class names in the dataset.
        :param annotation_mask_names: list of all mask names in the dataset.
        :param mask_color: color of the mask in the mask images."""
        super().__init__(self)

        self.shape = shape
        self.annotation_mask_names = annotation_mask_names
        self.mask_color = mask_color

        # Add classes
        for i, class_name in enumerate(class_names):
            self.add_class("Magrabia", i, class_name)

        # add images
        for i, fp in enumerate(image_fps):
            path_img = image_annotations.query('ID =="' + fp + '"')["Paths"].iloc[0]
            annotations = []
            for mask_name in annotation_mask_names:
                annotations.append(
                    image_annotations.query('ID =="' + fp + '"')[mask_name].iloc[0]
                )
            self.add_image(
                "Magrabia",
                image_id=i,
                path=path_img,
                annotations=annotations,
                orig_width=shape[0],
                orig_height=shape[1],
            )

    def image_reference(self, image_id) -> str:
        """Return a link to the image in its source Website or details about
        the image that help looking it up or debugging it.

        :param image_id: id of image to return a reference for.
        :return: the path to `image_id`."""
        info = self.image_info[image_id]
        return info["path"]

    def load_image(self, image_id) -> np.ndarray:
        """Load the specified image.

        :param image_id: id of the image to load.
        :return: a [H,W,3] Numpy array."""
        info = self.image_info[image_id]
        fp = info["path"]
        image = imread(fp)
        image = resizeAndPad(image, self.shape)
        # If grayscale. Convert to RGB for consistency.
        if len(image.shape) != 3 or image.shape[2] != 3:
            image = np.stack((image,) * 3, -1)
        return image

    def load_mask(self, image_id) -> Tuple[List[bool], List[str]]:
        """Load instance masks for the given image.

        :param image_id: id of the image to load the masks for.
        :return: a tuple with:
            - a bool array of shape [height, width, instance count] with
              a binary mask per instance as first element
            - a 1D array of class IDs of the instance masks as second element.
        """
        n_classes = len(self.annotation_mask_names)
        masks = np.zeros((self.shape[0], self.shape[1], n_classes))
        for i in range(0, n_classes):
            info = self.image_info[image_id]
            mask = cv2.imread(info["annotations"][i])
            mask = resizeAndPad(mask, self.shape)
            mask = np.where(mask > 0, 1, 0)
            masks[:, :, i] = mask[:, :, self.mask_color]

        class_ids = np.array([i + 1 for i in list(range(n_classes))])

        return (masks, class_ids)

def sorted_alphanumeric(data: List[str]) -> List[str]:
    """Sort a list of alphanumeric strings.

    :param data: a list of alphanumeric strings.
    :return: `data` sorted."""

    def convert(text: str):
        return int(text) if text.isdigit() else text.lower()

    def alphanum_key(key: str):
        return [convert(c) for c in re.split("([0-9]+)", key)]

    return sorted(data, key=alphanum_key)

# path folder for testing images
def create_cropped_image(
    model: MaskRCNN,
    input_path: str,
    name_path: str,
    output_path: str,
    shape: Tuple[int, int],
) -> List[str]:
    """Crops an input images using an MRCNN model.

    :param model: the MRCNN model to be used when cropping
    :param input_path: path to the folder containing the images to crop
    :param name_path: base name for output file
    :param output_path: path to the cropped image folder
    :param shape: shape of the cropped image

    :return: List of paths to the cropped images"""
    # Image augmentation (light but constant)
    aug_detect = iaa.Sequential([iaa.CLAHE()])

    path = input_path
    images = sorted_alphanumeric(os.listdir(path))
    # print(images)

    skipped_files = []
    cropped_image_paths = []
    for name in images:
        print("===> ", name)

        try:
            img = imread(os.path.join(path, name))
        except ValueError:
            skipped_files.append(os.path.join(path, name))
            continue

        img_detect = img.copy()
        aug = False
        if aug:
            img_detect = aug_detect(image=img)
        # make prediction
        results = model.detect([img_detect], verbose=1)
        # visualize the results
        r = results[0]
        if r["rois"].size > 0:  # if Roi is found.
            y, x, h, w = r["rois"][0]
            y, x = y - 30, x - 30
            h, w = h + 30, w + 30
            roi = img[y:h, x:w, :]
            roi_resized = resizeAndPad(roi, shape)
            i = int(name.split("_")[0][2:6])
            target_path = os.path.join(
                output_path, name_path + "_roi_resized_{0}.png".format(i)
            )
            cropped_image_paths.append(target_path)
            cv2.imwrite(
                target_path,
                cv2.cvtColor(roi_resized, cv2.COLOR_RGB2BGR),
            )

        else:  # Roi not found
            print("roi not found")

    if len(skipped_files):
        print("The following files were skipped:")
        for path in skipped_files:
            print(path)

    return cropped_image_paths

MrcnnResultEntry = Dict[str, Any]

def get_best_mrcnn_result_index_for_class(
    mrcnn_result_entry: MrcnnResultEntry, class_id: int
) -> Optional[int]:
    """Given an mrcnn result entry.

    :return: the index of the best score for given class if 1 or more masks
        were detected and `None` otherwise."""
    best_index = None
    best_score = 0
    scores = mrcnn_result_entry.get("scores")
    if scores is not None:
        for i, score in enumerate(scores):
            class_ids = mrcnn_result_entry.get("class_ids")
            if class_ids is not None:
                if class_ids[i] == class_id:
                    if score > best_score:
                        best_score = score
                        best_index = i
    return best_index

def mrcnn_iou_eval(
    model: MaskRCNN, anns: pd.DataFrame, n_masks: int, col_names: List[str]
) -> List[List[float]]:
    """
    Evaluation of the roi and masks provided by the mrcnn model

    :param model: the model we want to evaluate
    :param anns: a dataframe with the filepaths of the evaluation images and
        masks.
    :param n_masks: number of masks
    :param col_names: name of the mask annotation columns

    :return: a list of iou values
    """
    spec: List[Tuple[List[float], str]] = [([], col_names[i]) for i in range(n_masks)]
    for idx in range(len(anns)):
        path = anns.loc[idx, "Paths"]
        img = imread(path)
        img_detect = img.copy()
        results = model.detect([img_detect], verbose=1)
        result = results[0]

        for i, spec_entry in enumerate(spec):
            class_id = i + 1
            list_iou, col_name = spec_entry
            class_ids = result.get("class_ids")
            if class_id in class_ids:
                best_class_score_index = get_best_mrcnn_result_index_for_class(
                    result, class_id
                )
                mask_org = imread(anns.loc[idx, col_name])
                mask_org = np.where(mask_org > 0, 1, 0)

                target = mask_org[:, :, 2]
                prediction = result.get("masks")[:, :, best_class_score_index]

                intersection = np.logical_and(target, prediction)
                union = np.logical_or(target, prediction)
                iou_score = np.sum(intersection) / np.sum(union)

                list_iou.append(iou_score)
            else:
                list_iou.append(0)

    return [spec_entry[0] for spec_entry in spec]

def train_valid_split(data_dir: str, healthy_name: str, glaucoma_name: str):
    """Split """
    # The list of Origa images in the train files
    # TODO remove hard coded file paths
    list_healthy_train_1 = os.listdir("/app/datasets/ORIGA/train/Healthy")
    list_glaucoma_train_1 = os.listdir("/app/datasets/ORIGA/train/Glaucoma")

    # The pictures ID of the images in the train files
    list_train_healthy = [int(pth.split("_")[0][3:]) for pth in list_healthy_train_1]
    list_train_glaucoma = [int(pth.split("_")[0][3:]) for pth in list_glaucoma_train_1]

    # All images resized for the second branch
    list_healthy_2 = os.listdir(os.path.join(data_dir, healthy_name))
    list_glaucoma_2 = os.listdir(os.path.join(data_dir, glaucoma_name))

    # Putting in the valid folder only the images that are in the valid folder of the 1st branch
    path_healthy = os.path.join(data_dir, healthy_name)
    path_healthy_train = os.path.join(data_dir, "train", healthy_name)
    path_healthy_valid = os.path.join(data_dir, "valid", healthy_name)

    for path in [
        path_healthy_train,
        path_healthy_valid,
    ]:
        os.makedirs(path, exist_ok=True)

    for im in list_healthy_2:
        im_index = int(im.split("_")[3][:-4])
        if im_index in list_train_healthy:
            shutil.copyfile(
                os.path.join(path_healthy, im), os.path.join(path_healthy_train, im)
            )
        else:
            shutil.copyfile(
                os.path.join(path_healthy, im), os.path.join(path_healthy_valid, im)
            )

    path_glaucoma = os.path.join(data_dir, glaucoma_name)
    path_glaucoma_train = os.path.join(data_dir, "train", glaucoma_name)
    path_glaucoma_valid = os.path.join(data_dir, "valid", glaucoma_name)

    for path in [
        path_glaucoma_train,
        path_glaucoma_valid,
    ]:
        os.makedirs(path, exist_ok=True)

    for im in list_glaucoma_2:
        im_index = int(im.split("_")[3][:-4])
        if im_index in list_train_glaucoma:
            shutil.copyfile(
                os.path.join(path_glaucoma, im), os.path.join(path_glaucoma_train, im)
            )
        else:
            shutil.copyfile(
                os.path.join(path_glaucoma, im), os.path.join(path_glaucoma_valid, im)
            )

def cup_to_disc_ratio(
    model: MaskRCNN, file_path: str
) -> Tuple[bool, Union[float, List[int]]]:
    """Calculates the cup/disc ratio for `file_path` using `model`.

    :param model: MaskRCNN model to use to calculate the masks.
    :param file_path: path to file to calculate ratio for.
    :return: a tuple with a boolean as first element set to `True` if the
        ratio could be calculated and `False` otherwise. The tuple's second
        element is the ratio if it could be calculated or a list of class ids
        that were found by the model if the ratio could not be calculated.
        this allows to see which mask could not be found (disc, cup or both)
        and prevented the ratio calculation."""
    img = imread(file_path)
    img_detect = img.copy()
    results = model.detect([img_detect], verbose=1)
    r = results[0]

    # Checking if both disc and cup where found
    if len(np.unique(r.get("class_ids"))) == 2:
        best_disc_index = get_best_mrcnn_result_index_for_class(r, 1)
        best_cup_index = get_best_mrcnn_result_index_for_class(r, 2)
        disc_pixel_sum = r.get("masks")[:, :, best_disc_index].sum()
        cup_pixel_sum = r.get("masks")[:, :, best_cup_index].sum()
        return True, cup_pixel_sum / disc_pixel_sum
    else:
        return False, r.get("class_ids")

def mmod(model: MaskRCNN, filenames: List[str]) -> Tuple[Dict[str, float], List[str]]:
    """fmod stands for: M_askRcnn M_odel O_utput D_ictionary

    :param model: model to be used to calculate the masks.
    :param filenames: list of path to images to calculate masks for.
    :return: a tuple with the first element being a dictionary with the images
        name as the key and the ratio of cup to disc as the associated value
        The second element being a list of images name the cup/disc ratio could
        not be calculated for."""
    result_dic: Dict[str, float] = {}
    list_failed_images = []
    for path in filenames:
        result = cup_to_disc_ratio(model, path)

        # Checking if both disc and cup where found
        if isinstance(result[1], float):
            ratio = result[1]
            img_name = path.split(".")[0].split("/")[-1]
            result_dic[img_name] = ratio
        else:
            class_ids = result[1]
            list_failed_images.append(img_name)
            print(
                "For picture {0} the model did not found a disc and a cup. class_ids: {1}".format(
                    path, class_ids
                )
            )

    return result_dic, list_failed_images

def mrcnn_b3_eval(
    model, anns, disc_annotation_colname, cup_annotation_colname
) -> Tuple[pd.DataFrame, List[str]]:
    """
    Evaluation of the mask provided by the mrcnn model
    by comparing the square error of the cup/disc ratio
    of the annotated images compared to the infered masks.

    :param model: the model we want to evaluate
    :param anns: a dataframe with the filepaths of the evaluation images and
        masks.
    :param disc_annotation_colname: column name in `anns` that contains the
        disc masks.
    :param cup_annotation_colname: column name in `anns` that contains the
        cup masks.

    :return: a tuple with:
        - first element: df: a dataframe with the error between the ratio
        - second element: list_failed_images: a list of images where the model
            couldn't find a disc and a cup
    """
    df = pd.DataFrame(columns=["ID", "ann", "inf", "err"])
    list_failed_images = []
    for idx in range(len(anns)):
        path = anns.loc[idx, "Paths"]
        temp_dic = {}
        img = imread(path)
        img_detect = img.copy()
        results = model.detect([img_detect], verbose=1)
        r = results[0]

        # Checking if both disc and cup where found
        if len(np.unique(r.get("class_ids"))) == 2:
            best_disc_index = get_best_mrcnn_result_index_for_class(r, 1)
            best_cup_index = get_best_mrcnn_result_index_for_class(r, 2)
            disc_pixel_sum = r.get("masks")[:, :, best_disc_index].sum()
            cup_pixel_sum = r.get("masks")[:, :, best_cup_index].sum()
            ratio = cup_pixel_sum / disc_pixel_sum
            temp_dic["ID"] = anns.loc[idx, "ID"]
            temp_dic["inf"] = ratio

            mask_disc_org = imread(anns.loc[idx, disc_annotation_colname])
            mask_disc_org = np.where(mask_disc_org > 0, 1, 0)
            disc_pixel_sum_org = mask_disc_org[:, :, 0].sum()

            mask_cup_org = imread(anns.loc[idx, cup_annotation_colname])
            mask_cup_org = np.where(mask_cup_org > 0, 1, 0)
            cup_pixel_sum_org = mask_cup_org[:, :, 0].sum()

            ratio_org = cup_pixel_sum_org / disc_pixel_sum_org

            temp_dic["ann"] = ratio_org

            square_error = (ratio - ratio_org) * (ratio - ratio_org)
            absolute_error = square_error ** (1 / 2)
            temp_dic["err"] = absolute_error

            df = df.append(temp_dic, ignore_index=True)

        else:
            list_failed_images.append(anns.loc[idx, "ID"])
            print(
                "For picture {0} the model did not found a disc and a cup. class_ids: {1}".format(
                    path, r.get("class_ids")
                )
            )

    return df, list_failed_images


from typing import List
class Solution:
    def findDuplicate(self, nums: List[int]) -> int:
        left, right = 1, len(nums) - 1
        while left < right:
            mid = left + right >> 1
            count = 0
            for n in nums:
                if n <= mid:
                    count += 1
            if count > mid:
                right = mid
            else:
                left = mid + 1
        return left

if __name__ == "__main__":
    nums = [1,3,4,2,2]
    r = Solution().findDuplicate(nums)
    print(r)


from api.authorinfo.models import Authorinfo
from rest_framework import serializers

class DynamicFieldsModelSerializer(serializers.ModelSerializer):

    def __init__(self, *args, **kwargs):
        # Don't pass the 'fields' arg up to the superclass
        fields = kwargs.pop('fields', None)

        # Instantiate the superclass normally
        super(DynamicFieldsModelSerializer, self).__init__(*args, **kwargs)

        if fields is not None:
            # Drop any fields that are not specified in the `fields` argument.
            allowed = set(fields)
            existing = set(self.fields.keys())
            for field_name in existing - allowed:
                self.fields.pop(field_name)

class AuthorinfoSerializer(DynamicFieldsModelSerializer):
    pub_date = serializers.DateTimeField(read_only=True)
    author_imageurl = serializers.ImageField(required=False)

    class Meta:
        model = Authorinfo
        fields = ('__all__')
        read_only_field = ["id"]

    def get_author_imageurl(self, Authorinfo):
        request = self.context.get('request')
        if Authorinfo.author_imageurl:
            author_imageurl = Authorinfo.author_imageurl.url
        else:
            author_imageurl = ''

        return request.build_absolute_uri(author_imageurl)


from setuptools import setup, find_packages

with open('README.md') as f:
    readme = f.read()

with open('LICENSE') as f:
    license = f.read()

setup(
    name='sprinklerctrl',
    version='0.0.1',
    description='A Sprinkler controller',
    long_description=readme,
    author='Ronny Falk',
    author_email='ronnyf@icloud.com',
    url='https://github.com/ronnyf/rpi-sprinklerctrl',
    license=license,
    packages=find_packages(exclude=('tests', 'docs'))
)


from django.shortcuts import render_to_response
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse
from django.db import connection
from django.http import HttpResponse, HttpResponseNotFound
from django.core.exceptions import *
from django.core.servers.basehttp import FileWrapper
from appy.pod.renderer import Renderer
import os
from models import *

import django.utils.simplejson as simplejson
import datetime
class JSONEncoder(simplejson.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, datetime.datetime):
            return obj.strftime('%Y-%m-%d %H:%M:%S')
        elif isinstance(obj,datetime.date):
            return obj.strftime('%Y-%m-%d')
        else:
            try:
                res = simplejson.JSONEncoder.default(self, obj)
            except TypeError:
                res = 'ERROR'
        return res

json2 = JSONEncoder()

def add_fields_to_persona(persone, *args, **kwargs):
    for persona in persone:
        try:
            call = Chiamata.objects.filter(persona = persona).latest()
        except ObjectDoesNotExist:
            continue
        persona.data_ultima_chiamata = call.data
        for k,v in risposta_choices:
            if call.risposta == k:
                persona.risposta = v
                break
    return persone

def index(request):
    return render_to_response('callcenter_index.html')

def search(request, emitter_format):
        p = Persona.objects.all().order_by('cognome')
        if request.GET.get('nome',''):
            p = p.filter(nome__icontains=request.GET.get('nome',''))
        if request.GET.get('cognome',''):
            p = p.filter(cognome__icontains=request.GET.get('cognome',''))
        if request.GET.get('secondo_cognome',''):
            p = p.filter(secondo_cognome__icontains=request.GET.get('secondo_cognome',''))
        if request.GET.get('indirizzo',''):
            p = p.filter(indirizzo__icontains=request.GET.get('indirizzo',''))
        if request.GET.get('citta',''):
            p = p.filter(citta__icontains=request.GET.get('citta',''))
        if request.GET.get('provincia',''):
            p = p.filter(provincia__icontains=request.GET.get('provincia',''))
        if request.GET.get('cap',''):
            p = p.filter(cap__icontains=request.GET.get('cap',''))
        if request.GET.get('telefono',''):
            p = p.filter(telefono__icontains=request.GET.get('telefono',''))
        if request.GET.get('email',''):
            p = p.filter(email__icontains=request.GET.get('email',''))
        if request.GET.get('cliente') == 'on':
            p = p.filter(cliente=True)
        if request.GET.get('problemi_udito') == 'on':
            p = p.filter(problemi_udito=True)
        if request.GET.get('porta_apparecchio') == 'on':
            p = p.filter(porta_apparecchio=True)
        if request.GET.get('venuto') == 'on':
            p = p.filter(venuto=True)
        if request.GET.get('spontaneo') == 'on':
            p = p.filter(spontaneo=True)
        if request.GET.get('perdita_media',''):
            p = p.filter(perdita_media__icontains=request.GET.get('perdita_media',''))
        if request.GET.get('note',''):
            p = p.filter(note__icontains=request.GET.get('note',''))
        if request.GET.get('preventivo',''):
            p = p.filter(preventivo_media__icontains=request.GET.get('preventivo',''))

        start = int(request.GET.get('start', 0))
        limit = int(request.GET.get('limit', len(p)))

        result = p[start:start+limit]

        result = add_fields_to_persona(result)

        return HttpResponse(json2.encode({"totalCount": len(p),"root": [pe.__dict__ for pe in result]}))

def ultimePersoneChiamate(request):
    calls = Chiamata.objects.all()
    p = list()
    for c in calls:
        c.persona.data_ultima_chiamata = c.data
        p.append(c.persona)

    start = int(request.GET.get('start', 0))
    limit = int(request.GET.get('limit', len(p)))

    return HttpResponse(json2.encode({"totalCount": len(p),"root": [x.__dict__ for x in p[start:start+limit]]}))

def Chiamate(request, id):
    calls = Chiamata.objects.filter(persona = Persona.objects.get(pk = id)).order_by('-data')

    start = int(request.GET.get('start', 0))
    limit = int(request.GET.get('limit', len(calls)))

    for x in calls[start:start+limit]:
        x.risposta = x.get_risposta_display()

    return HttpResponse(json2.encode({"totalCount": len(calls),"root": [x.__dict__ for x in calls[start:start+limit]]}))

def LetterePersone(request):
    p = Lettera.objects.filter(data_invio=None)

    start = int(request.GET.get('start', 0))
    limit = int(request.GET.get('limit', len(p)))

    res = [dict(x.__dict__,**x.persona.flat()) for x in p[start:start+limit]]

    return HttpResponse(json2.encode({"totalCount": len(res),"root": res }))

def genEtichette(request):

    basepath=os.path.join(os.path.dirname(os.path.realpath(__file__)), 'etichette')
    try:
        os.remove(os.path.join(basepath, 'etichette.odt'))
    except OSError:
        pass
    letters = Lettera.objects.filter(data_invio=None)
    p_list = list(set(x.persona for x in letters if x.persona.indirizzo != ''))
    p_list.sort(key=lambda x: x.cognome)
    renderer = Renderer(os.path.join(basepath,'EtichetteA4Cac.odt'), {'p_list':p_list}, os.path.join(basepath, 'etichette.odt'))
    renderer.run()
    response = HttpResponse(FileWrapper(open(os.path.join(basepath, 'etichette.odt'))), content_type='application/vnd.oasis.opendocument.text')
    response['Content-Disposition'] = 'attachment; filename=etichette.odt'
    response['Content-Length'] = os.path.getsize(os.path.join(basepath, 'etichette.odt'))
    return response

def sendLetter(request, id):
    try:
        p = Persona.objects.get(pk=int(id))
    except Persona.DoesNotExist:
        return HttpResponseNotFound()
    l = Lettera(persona=p, data=datetime.date.today(), data_invio=None)
    l.save()
    return HttpResponse(json2.encode({"totalCount": 1, 'root':l.__dict__}))

def lettersSent(request):
    for x in Lettera.objects.filter(data_invio=None):
        x.data_invio=datetime.date.today()
        x.save()
    return HttpResponse(json2.encode({"totalCount": 1, 'success':True}))

def listLettersSent(request, id):
    l_list = Lettera.objects.filter(persona__pk=id)

    start = int(request.GET.get('start', 0))
    limit = int(request.GET.get('limit', len(l_list)))

    return HttpResponse(json2.encode({"totalCount": len(l_list),"root": [x.__dict__ for x in l_list[start:start+limit]]}))


import sentencepiece as spm
import argparse

def segment(model_path: str, input: str, output_file: str, no_sample: bool) -> None:
    sp = spm.SentencePieceProcessor()
    sp.load(model_path)

    with open(input, "r") as f:
        contents = [x.strip("\n") for x in f.readlines()]

    piece_lengths = []
    for content in contents:
        if no_sample:
            pieces = sp.encode_as_pieces(content)
        else:
            pieces = sp.sample_encode_as_pieces(content, -1, 0.5)
        pieces_str = ""
        # pieces_length_str = ""
        for piece in pieces:
            pieces_str += piece + " "
            # pieces_length_str += str(len(piece)) + " "
        print(pieces_str)
        piece_lengths.append(len(pieces))

    with open(output_file, "w") as f:
        for x in piece_lengths:
            f.write('%s\n' % x)

if __name__ == "__main__":
    parser = argparse.ArgumentParser("Segments text using sentencepiece")
    parser.add_argument("--model", help="path to sentencepiece model", required=True)
    parser.add_argument("--input", help="input file", required=True)
    parser.add_argument("--ofile", help="input file", required=False)
    parser.add_argument("--nos", "--verbose", help="increase output verbosity",
                        action="store_true", required=False)
    args = parser.parse_args()

    segment(args.model, args.input, args.ofile, args.nos)


import json

import pytest
from sklearn.metrics import mean_squared_error

from cases.data.data_utils import get_scoring_case_data_paths
from fedot.core.data.data import InputData
from fedot.core.operations.atomized_model import AtomizedModel
from fedot.core.pipelines.node import PrimaryNode, SecondaryNode
from fedot.core.pipelines.pipeline import Pipeline
from test.unit.utilities.test_pipeline_import_export import create_correct_path, create_func_delete_files

@pytest.fixture(scope='session', autouse=True)
def preprocessing_files_before_and_after_tests(request):
    paths = ['test_save_load_atomized_pipeline_correctly',
             'test_save_load_fitted_atomized_pipeline_correctly_loaded',
             'test_save_load_fitted_atomized_pipeline_correctly']

    delete_files = create_func_delete_files(paths)

    delete_files()
    request.addfinalizer(delete_files)

def create_pipeline() -> Pipeline:
    pipeline = Pipeline()
    node_logit = PrimaryNode('logit')

    node_lda = PrimaryNode('lda')
    node_lda.custom_params = {'n_components': 1}

    node_xgboost = SecondaryNode('xgboost')
    node_xgboost.custom_params = {'n_components': 1}
    node_xgboost.nodes_from = [node_logit, node_lda]

    pipeline.add_node(node_xgboost)

    return pipeline

def create_atomized_model() -> AtomizedModel:
    """
    Example, how to create Atomized operation.
    """
    pipeline = create_pipeline()
    atomized_model = AtomizedModel(pipeline)

    return atomized_model

def create_atomized_model_with_several_atomized_models() -> AtomizedModel:
    pipeline = Pipeline()
    node_atomized_model_primary = PrimaryNode(operation_type=create_atomized_model())
    node_atomized_model_secondary = SecondaryNode(operation_type=create_atomized_model())
    node_atomized_model_secondary_second = SecondaryNode(operation_type=create_atomized_model())
    node_atomized_model_secondary_third = SecondaryNode(operation_type=create_atomized_model())

    node_atomized_model_secondary.nodes_from = [node_atomized_model_primary]
    node_atomized_model_secondary_second.nodes_from = [node_atomized_model_primary]
    node_atomized_model_secondary_third.nodes_from = [node_atomized_model_secondary,
                                                      node_atomized_model_secondary_second]

    pipeline.add_node(node_atomized_model_secondary_third)
    atomized_model = AtomizedModel(pipeline)

    return atomized_model

def create_pipeline_with_several_nested_atomized_model() -> Pipeline:
    pipeline = Pipeline()
    atomized_op = create_atomized_model_with_several_atomized_models()
    node_atomized_model = PrimaryNode(operation_type=atomized_op)

    node_atomized_model_secondary = SecondaryNode(operation_type=create_atomized_model())
    node_atomized_model_secondary.nodes_from = [node_atomized_model]

    node_knn = SecondaryNode('knn')
    node_knn.custom_params = {'n_neighbors': 9}
    node_knn.nodes_from = [node_atomized_model]

    node_knn_second = SecondaryNode('knn')
    node_knn_second.custom_params = {'n_neighbors': 5}
    node_knn_second.nodes_from = [node_atomized_model, node_atomized_model_secondary, node_knn]

    node_atomized_model_secondary_second = \
        SecondaryNode(operation_type=create_atomized_model_with_several_atomized_models())

    node_atomized_model_secondary_second.nodes_from = [node_knn_second]

    pipeline.add_node(node_atomized_model_secondary_second)

    return pipeline

def create_data_for_train():
    train_file_path, test_file_path = get_scoring_case_data_paths()
    train_data = InputData.from_csv(train_file_path)
    test_data = InputData.from_csv(test_file_path)

    return train_data, test_data

def test_save_load_atomized_pipeline_correctly():
    pipeline = create_pipeline_with_several_nested_atomized_model()

    json_actual = pipeline.save('test_save_load_atomized_pipeline_correctly')

    json_path_load = create_correct_path('test_save_load_atomized_pipeline_correctly')

    with open(json_path_load, 'r') as json_file:
        json_expected = json.load(json_file)

    pipeline_loaded = Pipeline()
    pipeline_loaded.load(json_path_load)

    assert pipeline.length == pipeline_loaded.length
    assert json_actual == json.dumps(json_expected, indent=4)

def test_save_load_fitted_atomized_pipeline_correctly():
    pipeline = create_pipeline_with_several_nested_atomized_model()

    train_data, test_data = create_data_for_train()
    pipeline.fit(train_data)

    json_actual = pipeline.save('test_save_load_fitted_atomized_pipeline_correctly')

    json_path_load = create_correct_path('test_save_load_fitted_atomized_pipeline_correctly')

    pipeline_loaded = Pipeline()
    pipeline_loaded.load(json_path_load)
    json_expected = pipeline_loaded.save('test_save_load_fitted_atomized_pipeline_correctly_loaded')

    assert pipeline.length == pipeline_loaded.length
    assert json_actual == json_expected

    before_save_predicted = pipeline.predict(test_data)

    pipeline_loaded.fit(train_data)
    after_save_predicted = pipeline_loaded.predict(test_data)

    bfr_tun_mse = mean_squared_error(y_true=test_data.target, y_pred=before_save_predicted.predict)
    aft_tun_mse = mean_squared_error(y_true=test_data.target, y_pred=after_save_predicted.predict)

    assert aft_tun_mse <= bfr_tun_mse

def test_fit_predict_atomized_model_correctly():
    train_data, test_data = create_data_for_train()

    pipeline = create_pipeline_with_several_nested_atomized_model()
    atomized_model = AtomizedModel(pipeline)

    pipeline.fit(train_data)
    predicted_values = pipeline.predict(test_data)

    atomized_model.fit(train_data)
    predicted_atomized_output = atomized_model.predict(None, test_data)
    predicted_atomized_values = predicted_atomized_output.predict

    bfr_tun_mse = mean_squared_error(y_true=test_data.target, y_pred=predicted_values.predict)
    aft_tun_mse = mean_squared_error(y_true=test_data.target, y_pred=predicted_atomized_values)

    assert aft_tun_mse == bfr_tun_mse

def test_create_empty_atomized_model_raised_exception():
    with pytest.raises(Exception):
        empty_pipeline = Pipeline()
        AtomizedModel(empty_pipeline)

def test_fine_tune_atomized_model_correct():
    train_data, test_data = create_data_for_train()

    atm_model = create_atomized_model()
    dummy_atomized_model = create_atomized_model()

    fine_tuned_atomized_model = atm_model.fine_tune(loss_function=mean_squared_error,
                                                    input_data=train_data,
                                                    iterations=5,
                                                    timeout=1)
    dummy_atomized_model.fit(train_data)

    after_tuning_output = fine_tuned_atomized_model.predict(None, data=test_data)
    after_tuning_predicted = after_tuning_output.predict
    before_tuning_output = dummy_atomized_model.predict(None, data=test_data)
    before_tuning_predicted = before_tuning_output.predict

    aft_tun_mse = mean_squared_error(y_true=test_data.target, y_pred=after_tuning_predicted)
    bfr_tun_mse = mean_squared_error(y_true=test_data.target, y_pred=before_tuning_predicted)

    deviation = 0.50 * bfr_tun_mse
    assert aft_tun_mse <= (bfr_tun_mse + deviation)


from django.urls import path
from rest_framework.urlpatterns import format_suffix_patterns

from . import views

urlpatterns = [
    path('buckets/', views.BucketList.as_view()),
    path('buckets/<int:pk>/', views.BucketDetail.as_view()),
    path('bucketlist/', views.BucketListDropdown.as_view()),
    path('transactions/', views.TransactionList.as_view()),
    path('transactions/<int:pk>/', views.TransactionDetail.as_view()),
    path('expenses/', views.ExpenseList.as_view()),
    path('expenses/<int:pk>/', views.ExpenseDetail.as_view()),
]

urlpatterns = format_suffix_patterns(urlpatterns)


from google.cloud import bigquery
from google.cloud import storage

CONFIG = {
    'bucket_name': 'mozilla-mach-data',
    'project': 'moz-fx-data-taskclu-prod-8fbf',
    'dataset_id': 'taskclusteretl',
    'tables': {
        'task_duration_estimates': 'task_duration_history.json',
        'calculated_machtry_quantiles': 'machtry_quantiles.csv',
    }
}

def export_all_files(request, payload):
    for table, blob_name in CONFIG['tables'].items():
        if blob_name.endswith('.csv'):
            export_format = bigquery.job.DestinationFormat().CSV
        else:
            export_format = bigquery.job.DestinationFormat().NEWLINE_DELIMITED_JSON
        export_table(table, blob_name, export_format)

def export_table(table, blob_name, export_format):
    storage_client = storage.Client()
    client = bigquery.Client()

    temporary_blob_name = blob_name + ".temp"
    destination_uri = "gs://{}/{}".format(CONFIG['bucket_name'], temporary_blob_name)
    dataset_ref = client.dataset(CONFIG['dataset_id'], project=CONFIG['project'])
    table_ref = dataset_ref.table(table)
    job_config = bigquery.job.ExtractJobConfig(
        destination_format=export_format
    )

    extract_job = client.extract_table(
        table_ref,
        destination_uri,
        # Location must match that of the source table.
        location="US",
        job_config=job_config,
    )  # API request
    extract_job.result()  # Waits for job to complete.

    bucket = storage_client.get_bucket(CONFIG['bucket_name'])
    blob = bucket.blob(temporary_blob_name)
    bucket.rename_blob(blob, blob_name)

    blob = bucket.blob(blob_name)
    blob.make_public()


import os
import cv2

name = input('Enter name of the person : ')
target_dir = os.path.join('dataset_images', name)
os.mkdir(target_dir)

image_num = 0

webcam = cv2.VideoCapture(0)

ret, frame = webcam.read()
while ret and not(cv2.waitKey(15) & 0xFF == ord('d')):
    cv2.imshow('Video Recording', frame)
    if cv2.waitKey(15) & 0xFF == ord(' '):
        cv2.imshow('Captured Image', frame)
        cv2.waitKey(500)
        cv2.destroyWindow('Captured Image')
        filename = os.path.join(target_dir, f'{name}{image_num}.jpg')
        cv2.imwrite(filename, frame)
        image_num += 1
    ret, frame = webcam.read()

webcam.release()
cv2.destroyAllWindows()


# Module pour appareils TWI (I2C) sur le RaspberryPi

import time
import logging
import datetime

import smbus  # Installer sur RPi (bus TWI)

from threading import Event

class LcdHandler:

    # Define some device parameters
    I2C_ADDR = 0x27  # I2C device address
    LCD_WIDTH = 16  # Maximum characters per line

    # Define some device constants
    LCD_CHR = 1  # Mode - Sending data
    LCD_CMD = 0  # Mode - Sending command

    LCD_LINE_1 = 0x80  # LCD RAM address for the 1st line
    LCD_LINE_2 = 0xC0  # LCD RAM address for the 2nd line
    LCD_LINE_3 = 0x94  # LCD RAM address for the 3rd line
    LCD_LINE_4 = 0xD4  # LCD RAM address for the 4th line
    LCD_LINES = [LCD_LINE_1, LCD_LINE_2, LCD_LINE_3, LCD_LINE_4]

    LCD_BACKLIGHT_ON = 0x08  # On
    LCD_BACKLIGHT_OFF = 0x00  # Off

    ENABLE = 0b00000100  # Enable bit

    # Timing constants
    E_PULSE = 0.0005
    E_DELAY = 0.0005

    def __init__(self):
        self.__logger = logging.getLogger(__name__ + '.' + self.__class__.__name__)
        self.lines = dict()
        self.lines[0] = "Initialising"
        self.lines[1] = "0%"
        self.LCD_BACKLIGHT = LcdHandler.LCD_BACKLIGHT_ON
        self.bus = None

    def initialise(self):
        self.__logger.debug("LcdHandler.initialise()")
        self.bus = smbus.SMBus(1)  # Rev 2 Pi uses 1

        # Initialise display
        self.lcd_byte(0x33, LcdHandler.LCD_CMD)  # 110011 Initialise
        self.lcd_byte(0x32, LcdHandler.LCD_CMD)  # 110010 Initialise
        self.lcd_byte(0x06, LcdHandler.LCD_CMD)  # 000110 Cursor move direction
        self.lcd_byte(0x0C, LcdHandler.LCD_CMD)  # 001100 Display On,Cursor Off, Blink Off
        self.lcd_byte(0x28, LcdHandler.LCD_CMD)  # 101000 Data length, number of lines, font size
        self.lcd_byte(0x01, LcdHandler.LCD_CMD)  # 000001 Clear display
        time.sleep(LcdHandler.E_DELAY)

    # Close LCD, shut down the backlight. Write "Stopped".
    def close(self):
        self.lcd_string("Stopped", LcdHandler.LCD_LINE_1)
        self.lcd_string("", LcdHandler.LCD_LINE_2)
        time.sleep(LcdHandler.E_DELAY)

        self.LCD_BACKLIGHT = LcdHandler.LCD_BACKLIGHT_OFF
        self.lcd_byte(0x01, LcdHandler.LCD_CMD)  # 000001 Clear display
        time.sleep(LcdHandler.E_DELAY)

    def lcd_byte(self, bits, mode):
        # Send byte to data pins
        # bits = the data
        # mode = 1 for data
        #        0 for command

        bits_high = mode | (bits & 0xF0) | self.LCD_BACKLIGHT
        bits_low = mode | ((bits << 4) & 0xF0) | self.LCD_BACKLIGHT

        # High bits
        self.bus.write_byte(LcdHandler.I2C_ADDR, bits_high)
        self.lcd_toggle_enable(bits_high)

        # Low bits
        self.bus.write_byte(LcdHandler.I2C_ADDR, bits_low)
        self.lcd_toggle_enable(bits_low)

    def lcd_toggle_enable(self, bits):
        # Toggle enable
        time.sleep(LcdHandler.E_DELAY)
        self.bus.write_byte(LcdHandler.I2C_ADDR, (bits | LcdHandler.ENABLE))
        time.sleep(LcdHandler.E_PULSE)
        self.bus.write_byte(LcdHandler.I2C_ADDR, (bits & ~LcdHandler.ENABLE))
        time.sleep(LcdHandler.E_DELAY)

    def lcd_string(self, message, line):
        # Send string to display

        message = message.ljust(LcdHandler.LCD_WIDTH, " ")

        self.lcd_byte(line, LcdHandler.LCD_CMD)

        for i in range(LcdHandler.LCD_WIDTH):
            self.lcd_byte(ord(message[i]), LcdHandler.LCD_CHR)

    def set_backlight(self, actif):
        if actif:
            self.LCD_BACKLIGHT = LcdHandler.LCD_BACKLIGHT_ON
        else:
            self.LCD_BACKLIGHT = LcdHandler.LCD_BACKLIGHT_OFF

        # Ecrire un byte dummy pour activer le changement
        self.lcd_byte(0x00, LcdHandler.LCD_CMD)  # 000000 No effect

    def afficher(self, lignes_lcd: list):
        for no_ligne in range(0, min(2, len(lignes_lcd))):
            self.lcd_string(lignes_lcd[no_ligne], self.LCD_LINES[no_ligne])

    def toggle_lcd_onoff(self, valeur: str):
        super().toggle_lcd_onoff(valeur)
        self.set_backlight(self._affichage_actif)

def main():
    test = LcdHandler()
    test.initialise()
    test.set_backlight(False)
    Event().wait(1)
    test.set_backlight(True)
    test.afficher(['Un lapin', 'se promene'])
    Event().wait(1)
    test.afficher(['pour souper', 'poutine!'])
    Event().wait(4)
    test.set_backlight(False)

if __name__ == '__main__':
    main()


"""
Bundle of methods to read the configuration Files.
"""

import xml.etree.ElementTree as ET

from src import SomeIPPacket

def getDeviceConfig(name, deviceFile, verbose):
    """
    Extracts the device information from the configuration file, this includes MAC, IP and Ports for all devices (server and client)
    """
    tree = ET.parse(deviceFile)
    root = tree.getroot()

    config = {}

    for dev in root.iter('device'):
        if (dev.get('name') == name):
            config['mac'] = dev.get('mac')
            config['ip'] = dev.get('ip')
            config['sendPort'] = int(dev.get('sendPort'))
            config['recPort'] = int(dev.get('recPort'))

    if verbose:
        print ('Device Config (',name,') :',config)

    return config

def str2bool(s):
    if s == 'True' or s == 'true':
        return True
    else:
        return False

def getClientConfig(name, serviceFile, deviceFile, verbose):
    """
    Extracts the meta information from the configuration file for clients, this includes clientID, services and methods allowed to request, servers providing those services and methods, information about time sentitiveness of notifications and resend intervals
    """
    tree = ET.parse(serviceFile)
    root = tree.getroot()

    config = {}
    config['clientID'] = int(getOwnID(name, deviceFile))

    services = []

    for serv in root.iter('service'):
        # client is capable of service
        if (serv.find("./method/client[@id='"+str(name)+"']") != None) :
            # service description
            service = {}
            service['id'] = int(serv.get('id'),0)

            # servers providing service
            servers = []
            for server in serv.iter('server'):
                servers.append(server.get('id'))
            service['server'] = servers

            # find methods suitable for client
            methods = []
            for method in serv.iter('method'):
                if (method.find("./client[@id='"+str(name)+"']") != None) :
                    methodSpec = {}
                    methodSpec['id'] = int(method.get('id'),0)
                    methodSpec['type'] = SomeIPPacket.messageTypes[method.get('type')]

                    minValue = 1
                    maxValue = 10
                    resendMin = 1
                    resendMax = 5
                    timesensitive = False

                    # go through all clients specifying this method
                    for curClient in method.iter('client'):
                        # only one match here
                        if curClient.get('id') == name:

                            if curClient.get('min') != None:
                                minValue = float(curClient.get('min'))
                            if curClient.get('max') != None:
                                maxValue = float(curClient.get('max'))
                            interval = (minValue, maxValue)

                            if curClient.get('timesensitive') != None:
                                timesensitive = str2bool(curClient.get('timesensitive'))

                            if curClient.get('resendMin') != None:
                                resendMin = float(curClient.get('resendMin'))
                            if curClient.get('resendMax') != None:
                                resendMax = float(curClient.get('resendMax'))

                    methodSpec['resendMin'] = resendMin
                    methodSpec['resendMax'] = resendMax
                    methodSpec['interval'] = interval
                    methodSpec['timesensitive'] = timesensitive
                    methods.append(methodSpec)
            service['method'] = methods

            services.append(service)

    config['service'] = services

    if verbose:
        print ('Client Config (',name,') :',config)

    return config

def getServerConfig(name, serviceFile, verbose):
    """
    Extracts the meta information from the configuration file for servers, this includes provided services and methods, error rates and response intervals
    """
    tree = ET.parse(serviceFile)
    root = tree.getroot()

    config = {}

    for serv in root.iter('service'):
        if (serv.find("./servers/server[@id='"+str(name)+"']") != None) :
            methods = []
            for method in serv.iter('method'):
                methodSpec = {}
                methodSpec['id'] = int(method.get('id'),0)
                methodSpec['type'] = SomeIPPacket.messageTypes[method.get('type')]
                methods.append(methodSpec)
            config[int(serv.get('id'),0)] = {}
            config[int(serv.get('id'),0)]['methods'] = methods
            for curServer in serv.iter('server'):
                if curServer.get('id') == name:
                    config[int(serv.get('id'),0)]['errorRate'] = float(curServer.get('errorRate'))
                    config[int(serv.get('id'),0)]['min'] = int(curServer.get('min'))
                    config[int(serv.get('id'),0)]['max'] = int(curServer.get('max'))

    if verbose:
        print ('Server Config (',name,') :',config)

    return config

def getOwnID(name, configFile):
    tree = ET.parse(configFile)
    root = tree.getroot()

    for dev in root.iter('device'):
        if (dev.get('name') == name):
            return dev.get("clientID")


import cv2
from matplotlib import pyplot as plt

img = cv2.imread('gradient.png', 0)
_, th1 = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)
_, th2 = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY_INV)
_, th3 = cv2.threshold(img, 127, 255, cv2.THRESH_TRUNC)  # the image pixel density will remain 127 after 127th pixel
# the pixel value will be zero for all the pixel density smaller than 127
_, th4 = cv2.threshold(img, 127, 255, cv2.THRESH_TOZERO)
_, th5 = cv2.threshold(img, 127, 255, cv2.THRESH_TOZERO_INV)

titles = ['Original Image', 'BINARY', 'BINARY_INV', 'TRUNC', 'TOZERO', 'TOZERO_INV']
images = [img, th1, th2, th3, th4, th5]

for i in range(6):
    plt.subplot(2, 3, i+1)
    plt.imshow(images[i], 'gray')
    plt.title(titles[i])
    plt.xticks([])
    plt.yticks([])

plt.show()
cv2.waitKey(0)
cv2.destroyAllWindows()


import torch
import torch.nn as nn
import torch.nn.functional as F

class Sender(nn.Module):
    def __init__(self, n_hidden, n_features, n_intentions):
        super(Sender, self).__init__()
        self.n_features = n_features
        self.fc1 = nn.Linear(n_features, n_hidden)      # embed input features
        self.fc2 = nn.Linear(n_intentions, n_hidden)      # embed intentions
        self.fc3 = nn.Linear(2 * n_hidden, n_hidden)    # linear layer to merge embeddings

    def forward(self, x, aux_input=None):
        features = x[:, 0:self.n_features]
        intentions = x[:, self.n_features:]
        feature_embedding = F.relu(self.fc1(features))
        intention_embedding = F.relu(self.fc2(intentions))
        joint_embedding = torch.cat([feature_embedding, intention_embedding], dim=1)
        return self.fc3(joint_embedding).tanh()

class Receiver(nn.Module):
    def __init__(self, n_hidden, n_features):
        super(Receiver, self).__init__()
        self.fc1 = nn.Linear(n_features, n_hidden)      # embed input features

    def forward(self, x, features, aux_input=None):
        feature_embeddings = self.fc1(features).tanh()
        energies = torch.matmul(feature_embeddings, torch.unsqueeze(x, dim=-1))
        return energies.squeeze()


from threading import Thread
import logging
from socket import timeout
from ..common.packet import MAX_PACKET_SIZE

class ReceiverOrchestrator(Thread):
    def __init__(self, listener_queue, listener_socket, clients):
        super().__init__()
        self.clients = clients
        self.listener_socket = listener_socket
        self.listener_queue = listener_queue
        self.listener_socket.settimeout(1)
        self.working = True

    def run(self):
        try:
            while (self.working):
                try:
                    msg, addr = self.listener_socket.recvfrom(MAX_PACKET_SIZE)
                    if (len(msg) <= 0):
                        continue
                    client = self.clients.get_client(addr)
                    if (client):
                        client.push(msg)
                    else:
                        self.listener_queue.put((msg, addr))
                except timeout:
                    pass
        except OSError:
            logging.error("Server listener is closed.")

    def stop(self):
        self.working = False
        self.join()

    def __del__(self):
        if (self.working):
            self.stop()


from collections import deque #library used for rotation

# all required matrix

RS_matrix=[[0x01,0xA4,0x55,0x87,0x5A,0x58,0xDB,0x9E],[0xA4,0x56,0x82,0xF3,0x1E,0xC6,0x68,0xE5],[0x02,0xA1,0xFC,0xC1,0x47,0xAE,0x3D,0x19],[0xA4,0x55,0x87,0x5A,0x58,0xDB,0x9E,0x03]]
tq0=[[0x8,0x1,0x7,0xD,0x6,0xF,0x3,0x2,0x0,0xB,0x5,0x9,0xE,0xC,0xA,0x4],[0xE,0xC,0xB,0x8,0x1,0x2,0x3,0x5,0xF,0x4,0xA,0x6,0x7,0x0,0x9,0xD],[0xB,0xA,0x5,0xE,0x6,0xD,0x9,0x0,0xC,0x8,0xF,0x3,0x2,0x4,0x7,0x1],[0xD,0x7,0xF,0x4,0x1,0x2,0x6,0xE,0x9,0xB,0x3,0x0,0x8,0x5,0xC,0xA]]
tq1=[[0x2,0x8,0xB,0xD,0xF,0x7,0x6,0xE,0x3,0x1,0x9,0x4,0x0,0xA,0xC,0x5],[0x1,0xE,0x2,0xB,0x4,0xC,0x3,0x7,0x6,0xD,0xA,0x5,0xF,0x9,0x0,0x8],[0x4,0xC,0x7,0x5,0x1,0x6,0x9,0xA,0x0,0xE,0xD,0x8,0x2,0xB,0x3,0xF],[0xB,0x9,0x5,0x1,0xC,0x3,0xD,0xE,0x6,0x4,0x7,0xF,0x2,0x0,0x8,0xA]]

MDS=[[0x01,0xEF,0x5B,0x5B],[0x5B,0xEF,0xEF,0x01],[0xEF,0x5B,0x01,0xEF],[0xEF,0x01,0xEF,0x5B]]

# Polynomials used for multiplication in RF and MDS matrix
gf_mod = 2**8 + 2**6 + 2**5 + 2**3 + 1
rs_mod = 2**8 + 2**6 + 2**3 + 2**2 + 1

t=[tq0,tq1]
S0=[]
S1=[]

# Function to multiply in Galois Field with correct polynomial
# Here modulus is used as the value of 2^n in the polynomial
def gf2n_multiply(a, b,modulus):
    overflow = 0x100
    sum1 = 0
    while (b > 0):
        if (b & 1):
            sum1 = sum1 ^ a
        b = b >> 1
        a = a << 1
        if (a & overflow):
            a = a ^ modulus
    return sum1

# Right rotation of number with rotation and bits as the parameter

def ROR(num,rot,bits):
    num=bin(num)[2:]
    num=num.zfill(bits)
    num=[int(i) for i in num]

    items=deque(num)
    items.rotate(rot)
    num=list(items)
    num=''.join([str(i) for i in num])
    num=int(num,2)
    return num

# Left rotation of number with rotation and bits as the parameter

def ROL(num,rot,bits):
    num=bin(num)[2:]
    num=num.zfill(bits)
    num=[int(i) for i in num]

    items=deque(num)
    items.rotate(-rot)
    num=list(items)
    num=''.join([str(i) for i in num])
    num=int(num,2)
    return num

# Permuatation function q1 used in the SBOX
def q1(inp):

    t0=t[1][0]
    t1=t[1][1]
    t2=t[1][2]
    t3=t[1][3]

    inp=bin(inp)[2:]
    inp=inp.zfill(8)
    a0=int(inp[:4],2)
    b0=int(inp[4:],2)
    a1=a0^b0
    b1=a0^(ROR(b0,1,4))^((8*a0)%16)
    a2=t0[a1]
    b2=t1[b1]
    a3=a2^b2
    b3=a2^(ROR(b2,1,4))^((8*a2)%16)
    a4=t2[a3]
    b4=t3[b3]
    y=16*b4+a4
    return y

# Permuatation function q0 used in the SBOX

def q0(inp):

    t0=t[0][0]
    t1=t[0][1]
    t2=t[0][2]
    t3=t[0][3]

    inp=bin(inp)[2:]
    inp=inp.zfill(8)
    a0=int(inp[:4],2)
    b0=int(inp[4:],2)
    a1=a0^b0
    b1=a0^(ROR(b0,1,4))^((8*a0)%16)
    a2=t0[a1]
    b2=t1[b1]
    a3=a2^b2
    b3=a2^(ROR(b2,1,4))^((8*a2)%16)
    a4=t2[a3]
    b4=t3[b3]
    y=16*b4+a4
    return y

# pseudo-Hadamard transform (PHT) function
# a=(a+b)% 2^32
# b=(a+2b)% 2^32

def PHT(a,b):
    num1=(a+b)%(pow(2,32))
    num2=(a+2*b)%pow(2,32)
    return num1,num2

# g function used inside the F function

def g_function(inp_r):

    global S0,S1

    S_0=S0
    S_1=S1
    arr=[]
    h=hex(inp_r)[2:].zfill(8)

    for i in range(0,len(h),2):
        tmp=int(h[i:i+2],16)
        arr.append(tmp)
    arr=arr[::-1]

    inp0=arr[0]
    inp1=arr[1]
    inp2=arr[2]
    inp3=arr[3]

    output=[0,0,0,0]

    # Taking the output of the SBOXES used in the G_function
    output[0] = q1(q0(q0(inp0) ^ S_0[0]) ^ S_1[0])
    output[1] = q0(q0(q1(inp1) ^ S_0[1]) ^ S_1[1])
    output[2] = q1(q1(q0(inp2) ^ S_0[2]) ^ S_1[2])
    output[3] = q0(q1(q1(inp3) ^ S_0[3]) ^ S_1[3])

    # Matrix multiplication under the Galois filed with modulus of GF
    output=mat_mul(MDS,output,gf_mod)
    # Little endian
    output=output[::-1]

    # Combining 4 8-bit numbers to 1 32-bit number
    output=int(''.join([bin(i)[2:].zfill(8) for i in output]),2)

    return output

# A helper function for the main function H used in round key generation

def helper_h(inp1,M1,M2):

    output=[0,0,0,0]

    output[0] = q1(q0(q0(inp1) ^ M1[0]) ^ M2[0])
    output[1] = q0(q0(q1(inp1) ^ M1[1]) ^ M2[1])
    output[2] = q1(q1(q0(inp1) ^ M1[2]) ^ M2[2])
    output[3] = q0(q1(q1(inp1) ^ M1[3]) ^ M2[3])
    output=mat_mul(MDS,output,gf_mod)

    return output

# H function used in key scheduling
def h_function(M_even,M_odd):

    M0=M_even[0]
    M2=M_even[1]
    M1=M_odd[0]
    M3=M_odd[1]

    K_keys=[]

    # Loop for making 40 keys
    for i in range(0,40,2):
        inp1=i
        inp2=i+1

        # Calling helper function which is performing the S-Box operations

        key1=helper_h(inp1,M2,M0)
        key2=helper_h(inp2,M3,M1)

        fin_key1=[]
        fin_key2=[]

        # Making the 4 8-bit keys to a combined 32 bit key with adjusting little endian
        for i in range(4):
            fin_key1.append(bin(key1[i])[2:].zfill(8))
            fin_key2.append(bin(key2[i])[2:].zfill(8))

        fin_key1=fin_key1[::-1]
        fin_key2=fin_key2[::-1]

        # binary to decimal conversion
        key1=int(''.join(fin_key1),2)
        key2=int(''.join(fin_key2),2)

        # Rotating the key by 8 bits
        key2=ROL(key2,8,32)

        # pseudo-Hadamard transform of the key1 and key2
        key1,key2=PHT(key1,key2)

        # Left rotation by 9 bits of key2
        key2=ROL(key2,9,32)

        # Finally appending the keys to main key list
        K_keys.append(key1)
        K_keys.append(key2)

    return K_keys

# A function for matrix multiplication which uses the Field multiplication and addition rules

def mat_mul(mat1,mat2,modulus):
    row1=len(mat1)
    col1=len(mat1[0])

    fin=[]
    for i in range(row1):
        val=0
        for j in range(col1):
            tmp1=gf2n_multiply((mat1[i][j]),mat2[j],modulus)
            val=val^tmp1
        fin.append(val)
    return fin

# Main function for Key scheduling
def key_schedule(key):

    global S0,S1
    m_array=[]

    # array of 16 8 bit-keys provided by user
    for i in range(0,len(key),2):
        tmp=int(key[i:i+2],16)
        m_array.append(tmp)

    # Making the Sbox S0 and S1 with RS modulo multiplication

    S0=mat_mul(RS_matrix,m_array[:8],rs_mod)
    S1=mat_mul(RS_matrix,m_array[8:16],rs_mod)

    # Odd even matrix for round keys generation
    M_even=[]
    M_odd=[]

    val=0

    # Making the even and odd lists
    for i in range(0,len(m_array),4):
        tmp=m_array[i:i+4]
        if(val%2==0):
            M_even.append(tmp)
        else:
            M_odd.append(tmp)
        val+=1
    # Calling H function with parameter Meven and Modd

    K_keys=h_function(M_even,M_odd)

    # for i in range(0,40,2):
    #     print(hex(K_keys[i])[2:].zfill(8),hex(K_keys[i+1])[2:].zfill(8))

    return K_keys

# Function for Input Whitening

def whitening(plaintext,white_keys):
    plain=[]
    new_key=[]
    val=0
    # Converting plaintext to a array of 16 length

    for i in range(0,len(plaintext),2):
        tmp=int(plaintext[i:i+2],16)
        plain.append(tmp)
    arr2=[]

    # taking 4 8-bit number together and then adjusting little endian
    for i in range(0,len(plain),4):
        tmp=plain[i:i+4]
        tmp=tmp[::-1]   #reversing the list for little endian adjustments
        arr2+=tmp
    plain=arr2

    # Expanding 4 32 bit numbers to 16 8-bit number array
    for j in range(len(white_keys)):
        x=hex(white_keys[j])[2:].zfill(8)
        for k in range(0,len(x),2):
            tmp=int(x[k:k+2],16)
            new_key.append(tmp)
    r_array=[]

    # Now both key and plaintext is 16 8-bit array so we can XOR
    for i in range(len(plain)):
        r_array.append(new_key[i]^plain[i])

    # Returning the round State

    r0=r_array[:4]
    r1=r_array[4:8]
    r2=r_array[8:12]
    r3=r_array[12:16]
    r_array=[r0,r1,r2,r3]

    return r_array

# The F function used in Encryption

def f_function(r_array,k1,k2):

    r0=r_array[0]
    r1=r_array[1]

    # Rotationg left
    r1=ROL(r1,8,32)
       # Calling G function for  r0 and r1 and then obtaining t0 and t1
    t0=g_function(r0)
    t1=g_function(r1)

    # print(hex(t0),end= " ")
    # print(hex(t1))
    # exit()

    # pseudo-Hadamard transform of t0 and t1
    t0,t1=PHT(t0,t1)

    # addition of round keys with modulo 2^32
    f0=(t0+k1)%pow(2,32)
    f1=(t1+k2)%pow(2,32)

    # returning f0 and f1
    return f0,f1

# Encrypt function of Twofish
def encrypt(plaintext,key):

    # Making the required keys
    round_keys=key_schedule(key)
    white_keys=round_keys[:4]
    output_keys=round_keys[4:8]

    # Whitening the Input
    r1_array=whitening(plaintext,white_keys)

    r_array=[]

    # Converting the array to a 16 8-bit numbers from 4 32-bit number
    for i in r1_array:
        num=int("".join([bin(j)[2:].zfill(8) for j in i]),2)
        r_array.append(num)

    # looping 16 time for each round

    for r in range(16):
        # Calling F function
        f0,f1=f_function(r_array,round_keys[2*r+8],round_keys[2*r+9])
        c2=f0^r_array[2]
        c2=ROR(c2,1,32)
        r3=r_array[3]
        c3=ROL(r3,1,32)
        c3=f1^c3

        r_array=[c2,c3,r_array[0],r_array[1]]

    # undo the steps
    r_array=[r_array[2],r_array[3],r_array[0],r_array[1]]
    # printing the output
    ciphertext=[]
    for i in range(len(output_keys)):
        ciphertext.append(hex(output_keys[i]^r_array[i])[2:].zfill(8))
    # converting little endian
    output=""
    for i in ciphertext:
        ans=[i[j:j+2] for j in range(0,len(i),2)]
        ans=ans[::-1]
        output+=''.join(ans)
    return(output)

# Decryption fucntion
def decrypt(ciphertext,key):

    # Making the required keys with scheduling
    round_keys=key_schedule(key)
    white_keys=round_keys[:4]
    output_keys=round_keys[4:8]

    # Converting ciphertext to array of 16
    ciphertext=[ciphertext[i:i+8] for i in range(0,len(ciphertext),8) ]
    r_array=[]

    # Adjusting the little endian format
    for i in ciphertext:
        q=i
        s=[]
        for j in range(0,len(q),2):
            s.append(q[j:j+2])
        s=s[::-1]
        s=''.join(s)
        r_array.append(int(s,16))

    # Ciphertext whitening with output whiten keys
    for j in range(len(output_keys)):
        r_array[j]=r_array[j]^output_keys[j]

    # Doing the criss cross swapping in Fiestal cipher
    r_array=[r_array[2],r_array[3],r_array[0],r_array[1]]

    # Calling the loop for 16 rounds
    for r in range(15,-1,-1):

        # Reversing the states ,the 3rd and 4th element will be 1st and 2nd element of previous round state array
        a=r_array[2]
        b=r_array[3]
        c2=r_array[0]
        c3=r_array[1]

        # Calling the F function with the 3rd and 4th element
        f0,f1=f_function([a,b],round_keys[2*r+8],round_keys[2*r+9])

        # Reversing to get the r2 and r3 of previous round in ecryption
        r2=ROL(c2,1,32)
        r2=r2^f0

        r3=f1^c3
        r3=ROR(r3,1,32)

        r_array=[a,b,r2,r3]

    # After 16 rounds ,whitening the array with input whiten keys this time

    for i in range(4):
        r_array[i]=hex(r_array[i]^white_keys[i])[2:].zfill(8)

    ans=""

    # Printing the output in Big Endian format
    for i in r_array:
        tmp=[]
        for j in range(0,len(i),2):
            tmp.append(i[j:j+2])
        tmp=tmp[::-1]
        ans+=''.join(tmp)

    return(ans)

typ=input("Enter the type (Encrypt/Decrypt) : ")
key=input("Enter the key 128 bit (Hexadecimal) : ")
key=key.zfill(32)
if(typ.lower()=="encrypt"):
    plaintext=input("Enter the plaintext 128 bit (Hexadecimal) : ")
    plaintext=plaintext.zfill(32)
    print("The Ciphertext is : ",end=" ")
    print(encrypt(plaintext,key))

else:
    Ciphertext=input("Enter the Ciphertext 128 bit (Hexadecimal) : ")
    print("The Decoded plaintext is : ",end=" ")
    print(decrypt(Ciphertext,key))


# Python script to differentate between dry and wet models. Output: a figure and the list of wet and dry models. (Figure 21 report)
# Wet models are the models with a scaled change in precipitation averaged over the Caribbean region wetter than the 70th percentile
# Dry models are the models with a scaled change in precipitation averaged over the Caribbean region dryier than the 30 th percentile

import xarray as xr
import numpy as np
import matplotlib.pyplot as plt
import matplotlib
import os
import pandas as pd
import datetime
from cftime import DatetimeNoLeap
import cartopy.crs as ccrs
import cartopy.feature as cfeature
import cmocean.cm as cmo
from matplotlib import cm

# ------------------ Things to select ----------------------

scaling = True
ssp = 'ssp585'
season_list = ['annual']#,'dry','wet']

# ----------------------------------------------------------

#Functions

def time_period(da,period):
    """
    Select only the months inside the season of interest ('period') and takes running mean 30 yr window
    """
    if period == 'annual':
        da_time = da
        #da_time = da_time.rolling(time=30*12,center=False).mean(dim='time')
    elif period == 'wet':
        da_time = da.where((da.time.dt.month>=5) & (da.time.dt.month<=11),drop=True)#.dropna(dim='time')
        #da_time = da_time.rolling(time=30*7,center=False).mean(dim='time')
    elif period == 'dry':
        da_time = da.where((da.time.dt.month<=4) | (da.time.dt.month>=12),drop=True)#.dropna(dim='time')
        #da_time = da_time.rolling(time=30*5,center=False).mean(dim='time')
    return da_time #.dropna(dim='time')

def boxmean(da):
    """Compute spatial mean"""
    weights = np.cos(np.deg2rad(da.lat))
    weights.name = 'weights'
    boxmean = da.weighted(weights).mean(dim=('lat','lon'))
    return boxmean

def preprocessing_area_mean(ds):
    """
    Function to call when importing netcdf files with xr.open_mfdataset.
    - Sets all the datasets to the same datetime and time axis
    - Deletes from the files inconsistent dimensions/coordinates and saves models name
    """
    if ds.indexes['time'].inferred_type != "datetime64":
            ds['time'] = ds.indexes['time'].to_datetimeindex()
    ds['time'] = pd.date_range(start=str(ds.time[0].dt.year.values)+'-0'+str(ds.time[0].dt.month.values)+'-01',end='2100-12-16',periods=len(ds.time))
    if 'plev_bnds' in ds:
        ds =  ds.drop('plev_bnds')
    if 'plev' in ds:
        ds = ds.drop('plev')
    if 'height' in ds:
        ds = ds.drop('height')
    if 'file_qf' in ds:
        ds = ds.drop('file_qf')
    return ds

#------------------------INPUT------------------------#

season_title = {'annual':'Annual','dry': 'Dry season (December-April)','wet':'Wet season (May-November)'}
title_ssp = {'ssp126':'SSP1-2.6', 'ssp245': 'SSP2-4.5', 'ssp585': 'SSP5-8.5'}

#------------------------CALCULATIONS------------------------#

# Import data

pr_BES_cmip6 = xr.open_mfdataset('/home/bbrotonsbl/shared_data/volume_2/bbrotonsbl/resampling/Method-2014/preprocessed_data/CMIP6/03_area_mean/BES2/pr/*'+ssp+'*.nc',concat_dim = 'model',combine = 'nested',preprocess = preprocessing_area_mean)
tas_40S_40N_cmip6 = xr.open_mfdataset('/home/bbrotonsbl/shared_data/volume_2/bbrotonsbl/resampling/Method-2014/preprocessed_data/CMIP6/03_area_mean/40N_40S/tas/*'+ssp+'*.nc',concat_dim = 'model',combine = 'nested', preprocess = preprocessing_area_mean)
pr_BES_cmip6 = pr_BES_cmip6.load()
tas_40S_40N_cmip6 = tas_40S_40N_cmip6.load()

pr_BES_cmip6 = pr_BES_cmip6.sortby(pr_BES_cmip6.model_name) # to avoid different models order!
tas_40S_40N_cmip6 = tas_40S_40N_cmip6.sortby(tas_40S_40N_cmip6.model_name)

models = tas_40S_40N_cmip6.model_name

#---- Define wet and dry models:-----

for season in season_list:

    tas_period = time_period(tas_40S_40N_cmip6,season)
    pr_period = time_period(pr_BES_cmip6,season)

    # Compute change in tempertature
    dtas_40S_40N = tas_period.sel(time=slice('1-1-2071', '31-12-2100')).mean(dim='time') - tas_40S_40N_cmip6.sel(time=slice('1-1-1991', '31-12-2020')).mean(dim='time') # target-ref
    dpr_area_mean = pr_period.sel(time=slice('1-1-2071', '31-12-2100')).mean(dim='time') - pr_BES_cmip6.sel(time=slice('1-1-1991', '31-12-2020')).mean(dim='time') # target-ref

    if scaling == True:
        dpr_dt40 = dpr_area_mean.pr/dtas_40S_40N.tas #scaled region mean precipitation
        ylaebl_name = r'Scaled $\Delta$ Precipitation (Carib) [mm/day $^{\circ}$C]'; sc = ''; title = 'Scaled precipitation'
    elif scaling == False:
        dpr_dt40 = dpr_area_mean.pr
        ylaebl_name = r'$\Delta$ Precipitation (Carib) [mm/day $^{\circ}$C]'; sc = '_nonscaled'; title = 'Non-scaled precipitation'
    dpr_dt40_quant = dpr_dt40.quantile((0.3,0.7))
    # dpr_dt40_quant = dpr_dt40.quantile((0.45,0.55))
    wet_idx = np.where(dpr_dt40>=dpr_dt40_quant[1])[0]
    dry_idx = np.where(dpr_dt40<=dpr_dt40_quant[0])[0]

    print('Scaling = '+str(scaling))
    print(season)
    models_wet = []
    print('Wet models are:')
    for i in range(len(wet_idx)):
        models_wet.append(models[int(wet_idx[i])])
        print('-', models[int(wet_idx[i])].values)

    models_dry = []
    print('Dry models are:')
    for i in range(len(dry_idx)):
        models_dry.append(models[int(dry_idx[i])])
        print('-', tas_40S_40N_cmip6.model_name[int(dry_idx[i])].values)

    models_names = ['ACCESS-CM2', 'ACCESS-ESM1-5', 'AWI-CM-1-1-MR', 'BCC-CSM2-MR','    CESM2', 'CESM2-WACCM   ', '    CIESM', 'CMCC-CM2-SR5', 'CNRM-CM6-1','CNRM-CM6-1-HR', 'CNRM-ESM2-1', 'CanESM5', 'CanESM5-CanOE','EC-Earth3', 'EC-Earth3-Veg', 'FGOALS-f3-L', 'FGOALS-g3', 'GFDL-ESM4', 'GISS-E2-1-G', 'HadGEM3-GC31-LL   ', '     INM-CM4-8   ', '   INM-CM5-0  ', '   IPSL-CM6A-LR    ', 'KACE-1-0-G', 'MIROC-ES2L', 'MIROC6','MPI-ESM1-2-HR', 'MPI-ESM1-2-LR', 'MRI-ESM2-0', 'NESM3', 'NorESM2-MM', 'UKESM1-0-LL']
    breakpoint()
    plt.figure(345678)
    fig,ax = plt.subplots(1,1,figsize=(15,10))
    #fig.suptitle(title)
    ax.set_title(season_title[season],loc='right',fontsize=16)
    ax.set_title(title_ssp[ssp],loc='left',fontsize=16)
    plt.scatter(range(0,len(models)),dpr_dt40* 86400,s=100,c='black')
    plt.ylabel(ylaebl_name,fontsize=18)
    plt.axhline(dpr_dt40_quant[0]* 86400, color='peru', linestyle='--',label='P30')
    plt.axhline(dpr_dt40_quant[1]* 86400, color='teal', linestyle='--',label='P70')
    plt.scatter(dry_idx,dpr_dt40[dry_idx]* 86400,s = 200, c = 'peru')
    plt.scatter(wet_idx,dpr_dt40[wet_idx]* 86400,s = 200, c = 'teal')
    ax.set_xticks(np.linspace(-1.5,30.5,len(models)))#,rotation=50)
    ax.set_xticklabels(models_names,rotation=50,fontsize = 14)
    #ax.set_xticklabels(np.arange(1,33),rotation=50,fontsize = 14)
    plt.yticks(fontsize=16)
    plt.legend(fontsize=16)
    plt.tight_layout()
    # plt.savefig('/home/bbrotonsbl/shared_data/volume_2/bbrotonsbl/resampling/Method-2014/output_plots/definitivos/wet_dry_deffinition_'+season+sc+'.png')
    plt.savefig('/home/bbrotonsbl/shared_data/volume_2/bbrotonsbl/resampling/Method-2014/output_plots/report/wet_dry_deffinition_'+season+sc+'.png',dpi = 1200)