import PyDAQmx
from daq9211 import *

import Tkinter as tk
import tkFileDialog
import tkMessageBox
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
from matplotlib import pyplot as plt
import matplotlib.animation as animation
import datetime
import ttk

class daq_config_frame(tk.Frame):
    def __init__(self, master, controller, daq9211):
        tk.Frame.__init__(self,master)
        self.master = master
        self.daq9211 = daq9211
        self.selectedchannel = tk.IntVar()
        self.selectedchannel.set(0)
        #keep track of raised tc or voltage frames
        self.selectedframes = [None, None, None, None]

        #self.grid_columnconfigure(0, weight=1)
        self.grid_columnconfigure(1, weight=1)
        self.grid_columnconfigure(2, weight=1)
        #self.grid_rowconfigure(1, weight = 1)
        self.grid_rowconfigure(3, weight = 1)
        self.label = tk.Label(self, text="DAQ Configuration", justify = tk.CENTER, font = ("tkDefaultFont",24))
        self.label.grid(row = 0, column = 0, columnspan = 2, sticky = 'ew')

        #add button frame to add and delete channels
        self.btnframe = tk.Frame(self)
        self.btnframe.grid(row = 1, column = 0, sticky = 'ne')
        self.selectedlbl_str = tk.StringVar()
        self.selectedlbl_str.set('Selected Channel: %d' % self.selectedchannel.get())
        self.selectedlbl = tk.Label(self.btnframe, textvariable = self.selectedlbl_str, font = ("tkDefaultFont",16))
        self.selectedlbl.grid(row = 0, column = 0, sticky = 'ew')
        self.addtcbtn = ttk.Button(self.btnframe, text = "Add Thermocouple", command = lambda: self.raise_frame(self.thermocouple_frames[self.selectedchannel.get()]))
        self.addtcbtn.grid(row = 1, column = 0, sticky = 'ew')
        self.addvolbtn = ttk.Button(self.btnframe, text = "Add Analog Voltage", command = lambda: self.raise_frame(self.voltage_frames[self.selectedchannel.get()]))
        self.addvolbtn.grid(row = 2, column = 0, sticky = 'ew')

        # ID frames - consisting of btn_ID_frames
        self.btn_ID_frame = tk.Frame(self,borderwidth = 5, relief = tk.GROOVE)
        self.btn_ID_frame.grid(row = 2, column = 0, sticky = 'new')
        for i in range (0,4):
            self.btn_ID_frame.grid_rowconfigure(i, weight = 1)
        self.btn_ID_frame.grid_columnconfigure(0, weight = 1)
        self.channelID_frames = []
        for i in range(0,4):
            self.channelID_frames.append(daq_channelID_frame(self.btn_ID_frame,controller,daq9211,i))
            self.channelID_frames[i].grid(row = i, column = 0, sticky = 'nsew')

        self.configbtn_frame = tk.Frame(self)
        self.configbtn_frame.grid_columnconfigure(0,weight = 1)
        self.configbtn_frame.grid(row = 3, column = 0, sticky = 'new')
        self.openconfig_btn = ttk.Button(self.configbtn_frame, text = "Open Config", command = lambda: self.open_config())
        self.openconfig_btn.grid(row = 0, column = 0, sticky = 'nsew')
        self.saveconfig_btn = ttk.Button(self.configbtn_frame, text = "Save Config", command = lambda: self.save_config())
        self.saveconfig_btn.grid(row = 1, column = 0, sticky = 'nsew')

        # tc and voltage frames
        self.mainchannelframe = tk.Frame(self, borderwidth = 5, relief = tk.GROOVE)
        self.mainchannelframe.grid(row = 1, column = 1, rowspan = 3, sticky = 'nsew')
        self.mainchannelframe.grid_columnconfigure(0, weight = 1)
        self.mainchannelframe.grid_rowconfigure(0, weight = 1)
        self.mainchannelframe.grid_rowconfigure(1, weight = 1)
        self.mainchannelframe.grid_rowconfigure(2, weight = 1)
        self.mainchannelframe.grid_rowconfigure(3, weight = 1)

        #tc channel frame
        self.thermocouple_frames = []
        for i in range(0,4):
            self.thermocouple_frames.append(daq_thermocouple_frame(self.mainchannelframe,controller,daq9211,i))
            self.thermocouple_frames[i].grid(row = i, column = 0, sticky = 'nsew')

        #voltage channel frame
        self.voltage_frames = []
        for i in range(0,4):
            self.voltage_frames.append(daq_voltage_frame(self.mainchannelframe,controller,daq9211,i))
            self.voltage_frames[i].grid(row = i, column = 0, sticky = 'nsew')

        #raise the click frames
        for frame in self.channelID_frames:
            frame.tkraise()

        #add frame to record configuration of daq instance
        self.config_frame = tk.Frame(self, borderwidth = 5, relief = tk.GROOVE)
        self.config_frame.grid(row = 1, column = 2, rowspan = 3, sticky = 'nsew')
        self.config_frame.grid_columnconfigure(0, weight = 1)
        self.config_frame.grid_columnconfigure(1, weight = 1)
        self.config_frame.grid_rowconfigure(1, weight = 1)
        #list box to show configureations
        self.config_lbl = tk.Label(self.config_frame, text = "Configured Channels", font = ("tkDefaultFont", 14))
        self.config_lbl.grid(row = 0, column = 0, columnspan = 2, sticky = 'new')
        self.config_listbox = tk.Listbox(self.config_frame)
        self.config_listbox.grid(row = 1, rowspan = 2, column = 0, columnspan = 2, sticky = 'nsew')
      #  self.setuptask_btn = ttk.Button(self.config_frame, text = 'Setup Channel Tasks', command = lambda: self.run_tasksetup())
       # self.setuptask_btn.grid(row = 3, column = 0, columnspan = 2, sticky = 'ew')

    def raise_frame(self, frame):
        self.selectedframes[self.selectedchannel.get()] = frame
        frame.tkraise()

    def open_config(self):
        f = tkFileDialog.askopenfile(initialdir = 'daq_config', defaultextension = '.dat')

        for line in f:
            if "Channel" in line:
                #get the channel ID
                channel_ID =  int(line.strip('Channel: ').strip('\n'))
                self.selectedchannel.set(channel_ID)
            if "Sensor" in line:
                if "Thermocouple" in line:
                    selected_frame = self.thermocouple_frames[self.selectedchannel.get()]
                    selected_frame.ID = channel_ID
                    self.raise_frame(selected_frame)
                elif "Voltage" in line:
                    selected_frame = voltage_frames[self.selectedchannel.get()]
                    selected_frame.ID = channel_ID
                    self.raise_frame(selected_frame)
                else:
                    selected_frame = None
            if "Type" in line:
                selected_frame.type_str.set(line.strip('Type: ').strip('\n'))
            if "Min" in line:
                selected_frame.min_str.set(line.strip('Min: ').strip('\n'))
            if "Max" in line:
                selected_frame.max_str.set(line.strip('Max: ').strip('\n'))
                #self.selectedchannel.set()#set the selected channel to be the one from the file
            if "CJC" in line:
                selected_frame.cjc_str.set(line.strip('CJC: ').strip('\n'))

    def save_config(self):
        #get configs from each of the 4 channel frames
        today = datetime.date.today().strftime('%Y%m%d')
        config_name = 'daq9211_%s' % today
        f = tkFileDialog.asksaveasfile(mode = 'w', initialdir = 'daq_config', initialfile = config_name, defaultextension = '.dat')
        for i in range(0,4):
            data = self.get_channel_info(i)
            if data is not None:
                if data['sensor'] == 'Thermocouple':
                    #write thermocouple config_str
                    config_str = 'Channel: %d\nSensor: Thermocouple\nType: %s\nMin: %s\nMax: %s\nCJC: %s\n' % (data['ID'], data['type'], data['min'], data['max'], data['cjc'])
                    f.write(config_str)
                elif data['sensor'] == 'Voltage':
                    #write voltage config_str
                    config_str = 'Channel: %d\n, Sensor: Voltage\n' % (data['ID'])
                    f.write(config_str)
                else:
                    config_str = ""

    def get_channel_info(self,ID):
        frame = self.selectedframes[ID]
        data = {}
        if isinstance(frame, daq_thermocouple_frame):
            data['sensor'] = 'Thermocouple'
            data['ID'] = frame.ID
            data['type'] = frame.type_str.get()
            data['min'] = frame.min_str.get()
            data['max'] = frame.max_str.get()
            data['cjc'] = frame.cjc_str.get()
            return data
        elif isinstance(frame,daq_voltage_frame):
            data['sensor'] = 'Voltage'
            data['ID'] = frame.ID

        else:
            return None

    def run_tasksetup(self):
        for i in range(0,len(self.daq9211.channels)):
            self.daq9211.channels[i].setup_task()

class daq_channelID_frame(tk.Frame):
    def __init__(self, master, controller, daq9211, ID):
        tk.Frame.__init__(self,master)
        self.config(borderwidth = 5, relief = tk.GROOVE)
        self.grid_rowconfigure(0, weight = 1)
        self.grid_columnconfigure(0, weight = 1)
        self.ID = ID
        self.btn = tk.Button(self,text = '%d' % self.ID, font = ("tkDefaultFont",16), command = lambda: self.update_selectedchannel())
        self.btn.grid(row = 0, column = 0, sticky = 'nsew')
    def update_selectedchannel(self):
        self.master.master.selectedchannel.set(self.ID)
        self.master.master.selectedlbl_str.set('Selected Channel: %d' % self.master.master.selectedchannel.get())

class daq_thermocouple_frame(tk.Frame):
    def __init__(self, master, controller, daq9211, ID):
        tk.Frame.__init__(self, master)
        self.config(borderwidth = 5, relief = tk.GROOVE)
        self.grid_rowconfigure(7, weight = 1)
        self.grid_columnconfigure(0, weight = 1)
        self.grid_columnconfigure(1, weight = 1)
       # self.grid_columnconfigure(2, weight = 1)
        self.ID = ID
        self.daq9211 = daq9211
        self.lbl = tk.Label(self, text = 'Thermocouple: Channel %d' % self.ID, font = ("tkDefaultFont",14))
        self.lbl.grid(row = 0, column = 0, sticky = 'nw')

        #thermocouple type menu
        self.type_lbl = tk.Label(self, text = 'Thermocouple Type', font = ("tkDefaultFont",12))
        self.type_lbl.grid(row = 1, column = 0, columnspan = 2, sticky = 'nw' )
        self.type_str = tk.StringVar()
        #self.type_list = ["J","K","N","R","S","T","B","E"]
        self.type_list = ["K", "E"]
        self.type_str.set(self.type_list[0])
        self.type_menu = ttk.OptionMenu(self, self.type_str, self.type_list[0], *self.type_list)
        self.type_menu.grid(row = 2, column = 0, columnspan = 2, sticky = 'nw')

        self.min_lbl = tk.Label(self, text = 'Temperature Min', font = ("tkDefaultFont", 12))
        self.min_lbl.grid(row = 3, column = 0, sticky = 'nw')
        self.min_str = tk.StringVar()
        self.min_str.set('77')
        self.min_entry = tk.Entry(self, textvariable = self.min_str)
        self.min_entry.grid(row = 4, column = 0, sticky = 'nw')

        self.max_lbl = tk.Label(self, text = 'Temperature Max', font = ("tkDefaultFont", 12))
        self.max_lbl.grid(row = 3, column = 1, sticky = 'nw')
        self.max_str = tk.StringVar()
        self.max_str.set('1000')
        self.max_entry = tk.Entry(self, textvariable = self.max_str)
        self.max_entry.grid(row = 4, column = 1, padx = 10, sticky = 'nw')

        self.cjc_lbl = tk.Label(self, text = 'Cold Junction Compensation', font = ("tkDefaultFont",12))
        self.cjc_lbl.grid(row = 5, column = 0, sticky = 'nw' )
        self.cjc_str = tk.StringVar()
        self.cjc_list = ["Built-in", "Constant"]
        self.cjc_str.set(self.type_list[0])
        self.cjc_menu = ttk.OptionMenu(self, self.cjc_str, self.cjc_list[0], *self.cjc_list)
        self.cjc_menu.grid(row = 6, column = 0, columnspan = 2, sticky = 'nw')

        self.config_btn = ttk.Button(self, text = 'Configure Channel', command = lambda: self.config_channel())
        self.config_btn.grid(row = 0, column = 2, rowspan = 8, padx = 5, sticky = 'nsew')

    def config_channel(self):
        #master is the mainchannel frame
        #master.master is daq_config_frame
        #self.ID is the channel ID
        #add channel information to listbox in master.master.config_listbox
        tc = thermocouple(self.type_str.get(), self.min_str.get(), self.max_str.get(), self.cjc_str.get())
        chan = channel('%s/ai%d' % (self.daq9211.name, self.ID), tc, int(self.ID))
        self.daq9211.add_channel(chan)
        item_str = "Channel: %s" % (chan.name)
        time_item_str = '[%s] %s' % (str(datetime.datetime.now().time().strftime("%H:%M:%S")),item_str)
        #first get all elements in the listbox
        all_elements = self.master.master.config_listbox.get(0,tk.END)
        for index, elem in enumerate(all_elements):
            if item_str in elem: #then the channel corresponding to index has been configured and needs to be overwritten
                self.master.master.config_listbox.delete(index)
        self.master.master.config_listbox.insert(tk.END, time_item_str)

class daq_voltage_frame(tk.Frame):
    def __init__(self, master, controller, daq9211, ID):
        tk.Frame.__init__(self, master)
        self.config(borderwidth = 5, relief = tk.GROOVE, width = 100, height = 50)
        self.grid_rowconfigure(1,weight = 1)
        self.grid_columnconfigure(0, weight = 1)
        self.grid_columnconfigure(1, weight = 1)
       # self.grid_columnconfigure(2, weight = 1)
        self.ID = ID
        self.daq9211 = daq9211
        self.lbl = tk.Label(self, text = 'Voltage: Channel %d' % self.ID, font = ("tkDefaultFont",14))
        self.lbl.grid(row = 0, column = 0, sticky = 'nw')
        self.config_btn = ttk.Button(self, text = 'Configure Channel', command = lambda: self.config_channel())
        self.config_btn.grid(row = 0, column = 2, rowspan = 2, padx = 5, sticky = 'nsew')

    def config_channel(self):
        #master is the mainchannel frame
        #master.master is daq_config_frame
        #self.ID is the channel ID
        #add channel information to listbox in master.master.config_listbox
        tc = voltage(self.ID)
        chan = channel('%s/ai%d' % (self.daq9211.name, self.ID), tc, int(self.ID))
        self.daq9211.add_channel(chan)
        item_str = "Channel: %s" % (chan.name)
        time_item_str = '[%s] %s' % (str(datetime.datetime.now().time().strftime("%H:%M:%S")),item_str)
        #first get all elements in the listbox
        all_elements = self.master.master.config_listbox.get(0,tk.END)
        for index, elem in enumerate(all_elements):
            if item_str in elem: #then the channel corresponding to index has been configured and needs to be overwritten
                self.master.master.config_listbox.delete(index)
        self.master.master.config_listbox.insert(tk.END, time_item_str)


#!/usr/bin/env python
# coding: utf-8

# In[3]:

import os
import glob
import sys

if len(sys.argv) < 2:
    print ("Please enter the path to the data directory")

f = {}
for root, directories, filenames in os.walk(sys.argv[1]): #Change to Data_MPHI for MPHI dataset
    for directory in directories:
        f[os.path.join(root, directory)] = {}
    for filename in filenames:
        f[root][os.path.splitext(filename)[0]] = os.path.join(root,filename)
print (f)

# In[4]:

import csv

lexicon = {}
with open('./MPQA/lexicon_easy.csv',"r") as csvfile:
    data = csv.reader(csvfile)
    for row in data:
        row[1] = int(row[1])
        row[2] = int(row[2])
        lexicon[row[0]] = {}
        lexicon[row[0]]['subj'] = row[1]
        lexicon[row[0]]['sent'] = row[2]

# In[5]:

# In[6]:

from nltk.corpus import wordnet as wn
from nltk.stem import WordNetLemmatizer
from nltk.corpus import sentiwordnet as swn
from nltk import sent_tokenize, word_tokenize, pos_tag
from nltk import ngrams,bigrams

def mpqa_subj(tweet):
    feat = 0
    score = 0
    tokens = word_tokenize(tweet)
    for token in tokens:
        if token in lexicon:
            score+= lexicon [token]['subj']
    if score > 2 or score < -2:
        feat = 1
    return feat

def pot_adj(tweet):
    feat = 0
    tokens = word_tokenize(tweet)
    for token in tokens:
        synsets = wn.synsets(token)
        for s in synsets:
            if s.pos() == 'a':
                feat = 1
    return feat

# In[7]:

lemmatizer = WordNetLemmatizer()

def penn_to_wn(tag):
    """
    Convert between the PennTreebank tags to simple Wordnet tags
    """
    if tag.startswith('J'):
        return wn.ADJ
    elif tag.startswith('N'):
        return wn.NOUN
    elif tag.startswith('R'):
        return wn.ADV
    elif tag.startswith('V'):
        return wn.VERB
    return None

def swn_polarity(tweet):
    """
    Return a sentiment polarity: 0 = negative, 1 = positive
    """

    sentiment = 0.0
    tokens_count = 0

    tagged_sentence = pos_tag(word_tokenize(tweet))

    for word, tag in tagged_sentence:
        wn_tag = penn_to_wn(tag)
        if wn_tag not in (wn.NOUN, wn.ADJ, wn.ADV):
            continue

        lemma = lemmatizer.lemmatize(word, pos=wn_tag)
        if not lemma:
            continue

        synsets = wn.synsets(lemma, pos=wn_tag)
        if not synsets:
            continue

        # Take the first sense, the most common
        synset = synsets[0]
        swn_synset = swn.senti_synset(synset.name())

        if swn_synset.pos_score() - swn_synset.neg_score()>0:
            sentiment+=1
        elif swn_synset.pos_score() - swn_synset.neg_score()<0:
            sentiment+=-1
        tokens_count += 1

    # judgment call ? Default to positive or negative
    if not tokens_count:
        return 0

    return sentiment

def sentiword_mpqa_sentiment(tweet):
    feat = [0,0]
    feat[0] = swn_polarity(tweet)
    tokens = word_tokenize(tweet)
    for token in tokens:
        if token in lexicon:
            feat[1]+= lexicon[token]['sent']
    return feat

def target_yn(tweet,target):
    if target in tweet:
        return 1
    else:
        return 0

def word_ngrams(tweet,target):
    feat= [0,0,0]
    tweet_sent = tweet.split()
    target_sent =target.split()
    for k in range(1,4):
        for target_gram in ngrams(target_sent,k):
            for tweet_gram in ngrams(tweet_sent,k):
                if tweet_gram == target_gram:
                    feat[k-1] = 1
    return feat

def char_ngrams(tweet,target):
    feat= [0,0,0]
    tweet_sent = ''.join(e for e in tweet if e.isalnum())
    target_sent = ''.join(e for e in target if e.isalnum())
    for k in range(2,5):
        for target_gram in ngrams(target_sent,k):
            for tweet_gram in ngrams(tweet_sent,k):
                if tweet_gram == target_gram:
                    feat[k-2] = 1
    return feat

# In[8]:

import numpy as np
from sklearn.feature_extraction.text import CountVectorizer

data = {}
for key in sorted(f.keys()):
    features = {}

    #Setting up the file names
    train_file = f[key]['train_clean']
    test_file = f[key]['test_clean']

    #Set up the TF-IDF Vectorizer
    corpus = []
    with open(train_file,'r') as fr:
        lines = fr.readlines()
        for line in lines:
            row = line.split('\t')
            if row[0] == 'ID':
                continue
            tweet = row[2].lower()
            corpus.append(tweet)
    with open(test_file,'r') as fr:
        lines = fr.readlines()
        for line in lines:
            row = line.split('\t')
            if row[0] == 'ID':
                continue
            tweet = row[2].lower()
            corpus.append(tweet)
    vectorizer = CountVectorizer()
    X = vectorizer.fit_transform(corpus)
    X = X.todense()

    #Train Feature Extraction
    train_ph1 = []
    train_ph2 = []
    i = 0
    with open(train_file,'r') as fr:
        lines = fr.readlines()
        for line in lines:
            feature_vector_1 = []
            feature_vector_2 = []
            row = line.split('\t')
            if row[0] == 'ID':
                continue
            tweet = row[2].lower()
            target = row[1].lower()

            #First phase features
            feature_vector_1.append(mpqa_subj(tweet))
            feature_vector_1.append(pot_adj(tweet))
            #Uncomment the following line to add count vectorizer
            #feature_vector_1.extend(X[i].tolist()[0])

            #Second Phase features
            senti = sentiword_mpqa_sentiment(tweet)
            feature_vector_2.extend(senti)
            feature_vector_2.append(target_yn(tweet,target))
            feature_vector_2.extend(word_ngrams(tweet,target))
            feature_vector_2.extend(char_ngrams(tweet,target))
            #Uncomment the following line to add count vectorizer
            #feature_vector_2.extend(X[i].tolist()[0])

            i+=1

            category = row[3].rstrip()
#             print (category)
            if category == 'NONE':
                feature_vector_1.append(1)
                train_ph1.append(feature_vector_1)
            else:
                feature_vector_1.append(0)
                train_ph1.append(feature_vector_1)
                if category == 'AGAINST':
                    feature_vector_2.append(0)
                    train_ph2.append(feature_vector_2)
                else:
                    feature_vector_2.append(1)
                    train_ph2.append(feature_vector_2)

    #Load the test data and calculate features
    test = []
    test_y = []
    with open(test_file,'r') as fr:
        lines = fr.readlines()
        for line in lines:
            feature_vector_1 = []
            feature_vector_2 = []
            row = line.split('\t')
            if row[0] == 'ID':
                continue
            tweet = row[2].lower()
            target = row[1].lower()

            #First phase features
            feature_vector_1.append(mpqa_subj(tweet))
            feature_vector_1.append(pot_adj(tweet))
            #Uncomment the following line to add count vectorizer
            #feature_vector_1.extend(X[i].tolist()[0])

            #Second Phase features
            senti = sentiword_mpqa_sentiment(tweet)
            feature_vector_2.extend(senti)
            feature_vector_2.append(target_yn(tweet,target))
            feature_vector_2.extend(word_ngrams(tweet,target))
            feature_vector_2.extend(char_ngrams(tweet,target))
            #Uncomment the following line to add count vectorizer
            #feature_vector_2.extend(X[i].tolist()[0])

            i+=1

            test.append((np.array(feature_vector_1,dtype=np.int32),np.array(feature_vector_2,dtype=np.int32)))

            category = row[3].rstrip()
            if category == 'NONE':
                test_y.append(2)
            else:
                if category == 'AGAINST':
                    test_y.append(1)
                else:
                    test_y.append(0)
#     print (train_ph1[0])
    train_ph1 = np.array(train_ph1, dtype = np.int32)
    train_ph2 = np.array(train_ph2,dtype = np.int32)
#     test = np.array(test,dtype = np.int32)
    test_y = np.array(test_y,dtype = np.int32)
    print (key)
    print (train_ph1.shape)
    print (train_ph2.shape)
    print (test_y.shape)
    data[key] = (train_ph1,train_ph2,test,test_y)
    print ()

# In[9]:

from sklearn.svm import LinearSVC
from sklearn.utils import shuffle

def predict(clf1,clf2,x):
    ph1 = [x[0]]
#     print (ph1)
    ph2 = [x[1]]
#     print (ph2)
    p1 = clf1.predict(ph1)
#     print (p1)
    if p1[0] == 1:
        return 2
    else:
        p2 = clf2.predict(ph2)
        if p2[0] == 1:
            return 0
        else:
            return 1

def score(y_true,y_pred):
    fav = [0,0,0]
    ag = [0,0,0]
    tot = [fav,ag]
    corr = 0
    for y_t,y_p in zip(y_true,y_pred):
        if y_t < 2:
            tot[y_t][2]+=1
        if y_p < 2:
            tot[y_p][1]+=1
        if y_t == y_p and y_t < 2:
            tot[y_t][0]+=1
        if y_t == y_p:
            corr+=1

        r0 = tot[0][0]/(tot[0][2]+1e-5)
        p0 = tot[0][0]/(tot[0][1]+1e-5)
        r1 = tot[1][0]/(tot[1][2]+1e-5)
        p1 = tot[1][0]/(tot[1][1]+1e-5)
        f0 = 2*r0*p0/(r0+p0+1e-5)
        f1 = 2*r1*p1/(r1+p1+1e-5)

        f_avg = (f0+f1)/2
    return tot,f_avg

# In[ ]:

import numpy as np
from sklearn.model_selection import GridSearchCV

parameters = {
    'C' : np.logspace(start = 0.001,stop = 5,num = 10),
    'dual' : [True, False]
}
tot = np.array([[0,0,0],[0,0,0]])
for key in data.keys():
    train_ph1 = shuffle(data[key][0])
    train_ph2 =shuffle(data[key][1])
    test = data[key][2]
    test_y = data[key][3]

    #Phase 1 Training
    train_ph1_x = train_ph1[:,:-1]
    train_ph1_y = train_ph1[:,-1]
#     print(train_ph1_x)
#     print(train_ph1_y)
    svc = LinearSVC(max_iter = 100000)
    clf1  = GridSearchCV(svc, parameters, cv=5)
    clf1.fit(train_ph1_x,train_ph1_y)

    #Phase 2 Training
    train_ph2_x = train_ph2[:,:-1]
    train_ph2_y = train_ph2[:,-1]

    clf2 = GridSearchCV(svc, parameters, cv=5)
    clf2.fit(train_ph2_x,train_ph2_y)

    #Testing
    preds = []
    for x in test:
        preds.append(predict(clf1,clf2,x))
#     print (preds)
#     print (test_y)
    print (key+":")
    arr, sc = score(test_y,preds)
    print ("Score - %f"%sc)
    print ()
    tot = tot + np.array(arr)
    cat = key.replace(sys.argv[1],"")
    with open(key+'/predict_'+cat+'.txt','w') as pf:
        for pred in preds:
            if pred == 0:
                pf.write("FAVOR\n")
            elif pred == 1:
                pf.write("AGAINST\n")
            elif pred == 2:
                pf.write("NONE\n")

# In[ ]:

r0 = tot[0][0]/(tot[0][2]+1e-5)
p0 = tot[0][0]/(tot[0][1]+1e-5)
r1 = tot[1][0]/(tot[1][2]+1e-5)
p1 = tot[1][0]/(tot[1][1]+1e-5)
f0 = 2*r0*p0/(r0+p0+1e-5)
f1 = 2*r1*p1/(r1+p1+1e-5)

f_avg = (f0+f1)/2
print ("Overall Score - %f"%f_avg)

# In[ ]:


import pandas as pd
import numpy as np
from pathlib import Path
import itertools
import matplotlib.pyplot as plt
plt.style.use('seaborn-white')
from operator import is_not
from functools import partial
import logging

# create file handler which logs even debug messages
logging.basicConfig(filename=Path(__file__).parent / 'output.log',
                            filemode='w',
                            format='%(asctime)s,%(msecs)d %(name)s %(levelname)s %(message)s',
                            datefmt='%H:%M:%S',
                            level=logging.DEBUG)
day = 'Day 11'
logging.info(f"{day} - Dumbo Octopuses")
logger = logging.getLogger(day)

# inputfile = Path(__file__).parent / 'input_sample.csv'
inputfile = Path(__file__).parent / 'input.csv'

data = []
data = pd.read_csv(inputfile, header=None, dtype=str)
data = data[0].apply(lambda x: pd.Series(list(x)))
data = data.astype(int)

def find_adjancent(data, x, y):
    adj_lookup = [[col + y, row + x] for row in (-1,0,1) for col in (-1,0,1) if [row + x, col + y] != [x,y]]
    # the order comes out as NW, W, SW, N, S, NE, E, SE

    # TODO: map to a better order of N, NE, E, SE, S, SW, W, NW
    adj_values = []
    for index, adj in enumerate(adj_lookup):
        if adj[0] < 0 or adj[1] < 0 or adj[0] > data.shape[1] - 1 or adj[1] > data.shape[0] - 1:
            adj_values.append(None)
        else:
            adj_values.append(data.at[adj[0], adj[1]])

    return data.at[y,x], adj_values

def inc_neighbors(data, x, y):
    adj_lookup = [[col + y, row + x] for row in (-1,0,1) for col in (-1,0,1) if [row + x, col + y] != [x,y]]
    # the order comes out as NW, W, SW, N, S, NE, E, SE

    inc_array = []
    for index, adj in enumerate(adj_lookup):
        if adj[0] < 0 or adj[1] < 0 or adj[0] > data.shape[1] - 1 or adj[1] > data.shape[0] - 1:
            pass
        else:
            data.at[adj[0], adj[1]] += 1
            # Check if this is a new flash, or just incrementing past 10
            new = False
            if data.at[adj[0], adj[1]] == 10:
                new = True
            else:
                new = False
            inc_array.append([new, adj[1], adj[0], data.at[adj[0], adj[1]]])

    return inc_array

def resolve_flashes(data):
    result = {
        "new_flash_count": 0,
    }

    processed_flash = ~(data >= 10)
    while processed_flash.all(axis=None) == False:
        # print("iterating")
        for y in range(0, data.shape[0]):
            for x in range(0, data.shape[1]):
                if not processed_flash.at[y, x]:
                    for new_flash in inc_neighbors(data, x, y):
                        if new_flash[0]:
                            processed_flash.at[new_flash[2], new_flash[1]] = False

                        # else:
                            # processed_flash.at[new_flash[2], new_flash[1]] = True

                    processed_flash.at[y, x] = True

    # now reset the frame back to 0's for the flashed elements!
    result['new_flash_count'] += data[data >= 10].count().sum()
    data[data >= 10] = 0
    return result

totals = 0
sync_iter = None
for step in range(0, 1000):
    print(f"iterating on step {step}")
    data += 1
    print(data)
    r = resolve_flashes(data)
    print(data)
    if step < 100:
        totals += r['new_flash_count']

    # check if synchronous
    sync_count = 0
    sync_count = data[data == 0].count().sum()
    print(sync_count)

    if sync_count == 100:
        sync_iter = step+1
        break

print(f'Part 1 has {totals} flashes')
print(f'Part 2 synchronized at iter {sync_iter}')


import csv  # For parsing tables/users.csv
from typing import List, NamedTuple  # For creating a named tuple representing a user

from gmail import send_email  # For sending an email to a user
from last_fm import get_tracks_above_threshold  # For getting the top tracks for a user
from spotify import (
    create_playlist,
    get_playlist_id,
    update_playlist,
    errors,
)  # For creating and updating a playlist

DEBUG = True  # Debug mode prevents emails from being sent to users

# A named tuple representing a user in the users.csv table
class User(NamedTuple):
    name: str  # Example: "abosh"
    email: str  # Example: "abosh@email.com"
    last_fm_username: str  # Example: "yayabosh"
    thresholds: List[int]  # Example: 100
    moniker: str  # Example: "Abosh Has", so the Spotify playlist will be named "Songs {Abosh Has} Listened To 100+ Times"
    month_joined: int  # Example: 0 for first month, 1 for second month, etc.

# Get users from users.csv and create a list of User objects
users = []
with open("tables/users.csv", newline="") as f:
    # Parse each line in users.csv, ignoring lines that start with a #
    reader = csv.DictReader(row for row in f if not row.startswith("#"))
    for row in reader:
        # Create a User object for each row in `users.csv` and add it to the users list
        thresholds = row["thresholds"].split(",")
        users.append(
            User(
                row["name"],
                row["email"],
                row["last_fm_username"],
                sorted([int(threshold) for threshold in thresholds], reverse=True),
                row["moniker"],
                int(row["month_joined"]),
            )
        )

# For each user in the users list, get their top tracks (tracks above their
# threshold) from Last.fm and create a playlist for them in Spotify
for user in users:
    # A mapping from the playlist ID for a user's threshold to the songs in the
    # playlist.
    # Example: {[id: 1]: (threshold: 100, [song1, song2, song3]),
    #           [id: 2]: (threshold: 200, [song1, song2, song3])}
    playlist_id_map = {}
    # Iterate through each threshold for the user and create or update a playlist
    # for them
    for threshold in user.thresholds:
        # Get the tracks of the user played more than the given threshold
        get_tracks_above_threshold(user, threshold)
        # Get the playlist ID for the user's playlist, if it exists
        playlist_id = get_playlist_id(user, threshold)
        # If the playlist doesn't exist, create it
        if playlist_id is None:
            playlist_id = create_playlist(user, threshold)

        # Update the playlist with the the tracks played more than the given threshold.
        new_tracks = update_playlist(playlist_id)

        # Map the playlist ID to a tuple containing the threshold and the new
        # songs in the playlist. This will be used when sending an email to the user.
        playlist_id_map[playlist_id] = (threshold, new_tracks)

    # Send an update email to the user
    if not DEBUG:
        send_email(user, playlist_id_map, errors)

    errors = set()


import unittest
import requests

HOST = "http://127.0.0.1:6000"

class TestApi(unittest.TestCase):

    def test_sub_endpoint(this):
        response = requests.get(f"{HOST}/api/sub", params={
            "lhs": 10,
            "rhs": 2
        })
        assert response.status_code == 200
        assert response.json().get("result") == 8

    def test_multipy_endpoint(this):
        response = requests.get(f"{HOST}/api/multiply", params={
            "lhs": 5,
            "rhs": 5
        })
        assert response.status_code == 200
        assert response.json().get("result") == 25

    def test_divide_endpoint(this):
        response = requests.get(f"{HOST}/api/divide", params={
            "lhs": 10,
            "rhs": 2
        })
        assert response.status_code == 200
        assert response.json().get("result") == 5

    def test_divide_endpoint_divisor_is_zero(this):
        response = requests.get(f"{HOST}/api/divide", params={
            "lhs": 10,
            "rhs": 0
        })
        assert response.status_code == 400
        assert response.json().get("error") == "Denominator can't be equal to 0"

    def test_sub_endpoint_invalid_input(this):
        response = requests.get(f"{HOST}/api/sub", params={
            "lhs": "a",
            "rhs": "b"
        })
        assert response.status_code == 400
        assert response.json().get("error") == "could not convert string to float: \'a\'"

    def test_sub_endpoint_with_no_parameters(this):
        response = requests.get(F"{HOST}/api/sub")
        assert response.status_code == 400
        assert response.json().get("error") == "Provide 'lhs' and 'rhs' parameters in request"


import os
import numpy as np
import logging
import argparse
import time
import tensorflow as tf

from skimage import transform
from skimage import morphology
from skimage.morphology import disk
import math
from sklearn.ensemble import RandomForestClassifier
import pickle
import modelProd as model
import functions

logging.basicConfig(level=logging.INFO, format='%(asctime)s %(message)s')

def unet2DvLGE(image_file,output_file, checkpoint_path, do_postprocessing=False, use_iter=None,num_channels=3):

    image_size = (212, 212)
    batch_size = 1
    target_resolution = (1.36719, 1.36719)
    nx, ny = image_size[:2]
    image_tensor_shape = [batch_size] + list(image_size) + [1]
    images_pl = tf.placeholder(tf.float32, shape=image_tensor_shape, name='images')
    mask_pl, softmax_pl = model.predict(images_pl,num_channels)
    saver = tf.train.Saver()
    init = tf.global_variables_initializer()

    with tf.Session() as sess:

        sess.run(init)
        saver.restore(sess, checkpoint_path)

        total_time = 0
        total_volumes = 0

        img_dat = functions.load_nii(image_file)
        img3D = img_dat[0].copy()

        print("img3D.shape : " + str(img3D.shape) )
        is3D = len(img3D.shape)==3
        if (not is3D):
            print("ERROR image needs to be 3D")
            return False

        Uncertainties=[]

        start_time = time.time()
        output_fileConf=output_file.replace(".nii.gz","Conf.txt")
        file = open(output_fileConf,"w")

        img = functions.normalise_image(img3D)

        pixel_size = (img_dat[2].structarr['pixdim'][1], img_dat[2].structarr['pixdim'][2])
        Nimg= functions.PrepareImages2D(img3D,pixel_size,0,1)
        scale_vector = (pixel_size[0] / target_resolution[0],
                        pixel_size[1] / target_resolution[1])

        predictions = []
        for zz in range(img.shape[2]):

            slice_img = np.squeeze(img[:,:,zz])
            slice_rescaled = transform.rescale(slice_img,
                                                scale_vector,
                                                order=1,
                                                preserve_range=True,
                                                mode='constant')

            x, y = slice_rescaled.shape

            x_s = (x - nx) // 2
            y_s = (y - ny) // 2
            x_c = (nx - x) // 2
            y_c = (ny - y) // 2

            # Crop section of image for prediction
            if x > nx and y > ny:
                slice_cropped = slice_rescaled[x_s:x_s+nx, y_s:y_s+ny]
            else:
                slice_cropped = np.zeros((nx,ny))
                if x <= nx and y > ny:
                    slice_cropped[x_c:x_c+ x, :] = slice_rescaled[:,y_s:y_s + ny]
                elif x > nx and y <= ny:
                    slice_cropped[:, y_c:y_c + y] = slice_rescaled[x_s:x_s + nx, :]
                else:
                    slice_cropped[x_c:x_c+x, y_c:y_c + y] = slice_rescaled[:, :]

            # GET PREDICTION
            network_input = np.float32(np.tile(np.reshape(slice_cropped, (nx, ny, 1)), (batch_size, 1, 1, 1)))
            mask_out, logits_out = sess.run([mask_pl, softmax_pl], feed_dict={images_pl: network_input})

################## Measure uncertainties based on softmax prediction=logits_out ################
            Myocardium=(mask_out==1)*1
            TotalSize=functions.GetArea(Myocardium[0])
            Certain=0
            MeanValue=0
            if(TotalSize>0):
                Probabilities=logits_out[:,:,:,1]*Myocardium
                CertaintySlice=np.sum(Probabilities)
                MeanValueSlice=np.sum(Nimg[zz]*Myocardium)

                Certain=CertaintySlice/TotalSize
                MeanValue=MeanValueSlice/TotalSize

            Uncertainties=[zz/img.shape[2],MeanValue,Certain]
            file.write(" ".join(str(elem) for elem in Uncertainties) + "\n")
################### create output mask ########################
            prediction_cropped = np.squeeze(logits_out[0,...])

            # ASSEMBLE BACK THE SLICES
            slice_predictions = np.zeros((x,y,num_channels))
            # insert cropped region into original image again
            if x > nx and y > ny:
                #print("prediction_cropped.shape : " + str(prediction_cropped.shape))
                slice_predictions[x_s:x_s+nx, y_s:y_s+ny,:] = prediction_cropped
            else:
                if x <= nx and y > ny:
                    slice_predictions[:, y_s:y_s+ny,:] = prediction_cropped[x_c:x_c+ x, :,:]
                elif x > nx and y <= ny:
                    slice_predictions[x_s:x_s + nx, :,:] = prediction_cropped[:, y_c:y_c + y,:]
                else:
                    slice_predictions[:, :,:] = prediction_cropped[x_c:x_c+ x, y_c:y_c + y,:]

            # RESCALING ON THE LOGITS
            scale_vector2 = (1.0/scale_vector[0], 1.0/scale_vector[1])
            prediction = transform.rescale(slice_predictions,
                                            scale_vector2,
                                            order=1,
                                            preserve_range=True,
                                            mode='constant')

            prediction = np.uint8(np.argmax(prediction, axis=-1))
            predictions.append(prediction)
        print("------------Uncertainty measures:",Uncertainties)
        prediction_arr = np.transpose(np.asarray(predictions, dtype=np.uint8), (1,2,0))

        # This is the same for 2D and 3D again
        if do_postprocessing:
            prediction_arr = functions.keep_largest_connected_componentsVersionScar(prediction_arr)

        elapsed_time = time.time() - start_time
        total_time += elapsed_time
        total_volumes += 1
        logging.info('Evaluation of volume took %f secs.' % elapsed_time)

        # Save prediced mask
        out_affine = img_dat[1]
        out_header = img_dat[2]
        logging.info('saving to: %s' % output_file)
        functions.save_nii(output_file, prediction_arr, out_affine, out_header)

        logging.info('Average time per volume: %f' % (total_time/total_volumes))

def selectNetRF(prediction3D,Select_out):

    mask3D = prediction3D[0].copy()
    class_out=Select_out
    print(class_out)

    apexSlice=len(class_out)
    basalSlice=0
    pred2D = functions.SplitTo2D(mask3D)
    numberSlices=len(pred2D)
    print(numberSlices)
    for zz in range(int((numberSlices/3) +0.5)):
        if class_out[zz]==1:
            basalSlice=zz
            break
    for zz in range(int((numberSlices/3) +0.5)):
        if class_out[numberSlices-zz-1]==1:
            apexSlice=numberSlices-zz-1
            break

    print("basalSlice : " + str(basalSlice))
    print("apexSlice : " + str(apexSlice))

    null2Dimage=np.zeros(pred2D[0].shape)
    SlicesPred=[]
    for zz in range(numberSlices):
        if ((zz>=basalSlice) and (zz<=apexSlice)):
            EndoPred=(pred2D[zz]==2)*1
            ScarPred=(pred2D[zz]==3)*2
            EpiPred = (pred2D[zz] == 1) * 1

            if (EpiPred.max()==0 and EndoPred.max()==0):
                ScarPred=ScarPred*0

            EpiPred = (((EndoPred==1) + (EpiPred==1) + (ScarPred==2))>=1)
            areaEndo=functions.GetArea(EndoPred)
            areaEpi=functions.GetArea(EpiPred)
            if(areaEpi>3):
                slice_img = EpiPred
                EpiPred=functions.getConvexHull(slice_img)
            if(areaEndo>3):
                slice_img2 = EndoPred
                EndoPred=functions.getConvexHull(slice_img2)
            KeepEpi=EpiPred*2

            ## 2. remove extra contouring by doing epi= dilated endo with fixed radius
            dilatationRadius=math.sqrt(areaEpi/math.pi)-math.sqrt(functions.GetArea(EndoPred)/math.pi)+1
            ss=disk(int(dilatationRadius))

            if (EndoPred.max()==1):
                if (dilatationRadius>0):
                    Correctionmask=morphology.binary_dilation(EndoPred,ss)
                    KeepEpi=(EpiPred*(Correctionmask==1))*2

                if (zz==basalSlice):
                    EndoPred=morphology.binary_dilation(EndoPred,disk(1))
            Myo=((KeepEpi+EndoPred)==2)
            SlicesPred.append(KeepEpi+EndoPred+ScarPred*Myo)	#### put Endo at 3 and Epi at 2 and scar at 4
        else:
            SlicesPred.append(null2Dimage)

    recon3d = functions.Recon3D(SlicesPred)
    return recon3d

def callSelectorRF(prediction_file,Conf_file,modelSelection_path,output_file):
    prediction3D=functions.load_nii(prediction_file)

    logging.info('Selector called')
    Input=[]
    with open(Conf_file) as fd:
       for ln in fd:
          Input.append([float(str.strip(x)) for x in ln.split(' ')])

    print(Input)

    logging.info('RF selection')
    SelectionModel = pickle.load(open(modelSelection_path, 'rb'))

    Select_out=SelectionModel.predict(Input)
    print(Select_out)

    Result = selectNetRF(prediction3D,Select_out)
    logging.info('Editing the prediction with the slices selected')

    logging.info('Selected segmentation save to : %s' %output_file)

    functions.save_nii(output_file, Result, prediction3D[1], prediction3D[2])

if __name__ == '__main__':

    parser = argparse.ArgumentParser(
        description="Script to process data of a specific project")
    parser.add_argument('-image', '--image_file', type=str,help='(Single case mode) path to 3D image')
    args = parser.parse_args()

    dir_path = os.path.dirname(os.path.realpath(__file__))
    model_path = os.path.join(dir_path,"Models/LGE/")
    modelSegmentaion_path = os.path.join(model_path, 'LGESegmentationModel')
    modelSliceSelectionRF=os.path.join(model_path, 'LGE_RF_model.sav')
    image_file = args.image_file

    if image_file is None:
        logging.warning('image_file should be set')
    elif os.path.exists(image_file):
        MyoScarPrediction_file=image_file.replace(".nii.gz","MyoScarSeg.nii.gz")
        if os.path.exists(MyoScarPrediction_file):
            logging.info("Prediction found -> We don't need to perform a new prediction for "+ image_file)
        else:
            tf.reset_default_graph()
            unet2DvLGE(image_file,MyoScarPrediction_file, modelSegmentaion_path, do_postprocessing=True, use_iter=None,num_channels=4)
            logging.info("Segmentation mask created : "+ MyoScarPrediction_file)

            ## ---------- RF slice selection ------------
        Conf_file=MyoScarPrediction_file.replace("MyoScarSeg.nii.gz","MyoScarSegConf.txt")
        RFpredictionSelected_file = MyoScarPrediction_file.replace(".nii.gz","SelectedRF.nii.gz")
        if os.path.exists(RFpredictionSelected_file):
            logging.info("Prediction Selected found -> We don't need to perform a new selection for "+ MyoScarPrediction_file)
        else:
            callSelectorRF(MyoScarPrediction_file,Conf_file,modelSliceSelectionRF,RFpredictionSelected_file)


import math

class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right

root = TreeNode(2)
root.left = TreeNode(1)
root.right = TreeNode(3)

def findClosestValueInBst(tree, target):
    total_values = []
    tree_values = get_tree_values(tree, total_values)
    return closest_value(tree_values, target)

def get_tree_values(node, total_values):
    def node_values(node, total_values, lower=-math.inf, upper=math.inf):
        if node is None:
            return total_values
        if node.value >= upper or node.value <= lower:
            return total_values
        total_values.append(node.value)
        return node_values(node.left, total_values, lower, node.value) and node_values(
            node.right, total_values, node.value, upper
        )

    return node_values(node, total_values)

def closest_value(tree_values, target):
    smallest_val_so_far = tree_values[0]
    prev_difference = None

    for value in tree_values:
        curr_difference = abs(value - target)
        if prev_difference == None:
            prev_difference = curr_difference
            continue
        if curr_difference < prev_difference:
            prev_difference = curr_difference
            smallest_val_so_far = value
    return smallest_val_so_far


import gc
import os
import time

import boto3
import dask
import fsspec
import joblib
import numpy as np
import pandas as pd
import rasterio as rio
import rioxarray
import utm
import xarray as xr
import xgboost as xgb
from pyproj import CRS
from rasterio.session import AWSSession
from s3fs import S3FileSystem

import carbonplan_trace.v1.model as m
from carbonplan_trace.v1.glas_allometric_eq import ECO_TO_REALM_MAP
from carbonplan_trace.v1.landsat_preprocess import scene_seasonal_average

from ..v1 import load, utils

# flake8: noqa

fs = S3FileSystem(requester_pays=True)

def write_nodata(ds):
    for var in ds.data_vars:
        ds[var].rio.write_nodata(np.nan, inplace=True)

def write_crs_dataset(ds, zone=None, overwrite=False):
    '''
    This function will set a CRS for a dataset (whether or not
    one already exists!) so be sure you want to do that!
    '''
    if zone is None:
        zone = '{}{}'.format(ds.utm_zone_number, ds.utm_zone_letter)
    crs = CRS.from_dict({'proj': 'utm', 'zone': zone})
    ds = ds.rio.set_crs(crs)
    return ds

def check_mins_maxes(ds):
    lat_lon_crs = CRS.from_epsg(4326)
    reprojected = ds.rio.reproject(lat_lon_crs)
    min_lat = reprojected.y.min().values
    max_lat = reprojected.y.max().values
    min_lon = reprojected.x.min().values
    max_lon = reprojected.x.max().values
    return min_lat, max_lat, min_lon, max_lon

def create_target_grid(min_lat, max_lat, min_lon, max_lon):
    tiles = utils.find_tiles_for_bounding_box(min_lat, max_lat, min_lon, max_lon)
    if len(tiles) > 0:
        full_target_ds = utils.open_and_combine_lat_lon_data(
            's3://carbonplan-climatetrace/intermediate/ecoregions_mask/',
            tiles=tiles,
            lat_lon_box=[min_lat, max_lat, min_lon, max_lon],
            consolidated=False,
        )
        full_target_ds = full_target_ds.rename({'lat': 'y', 'lon': 'x'})
        buffer = 0.01
        target = full_target_ds.sel(
            y=slice(min_lat - buffer, max_lat + buffer), x=slice(min_lon - buffer, max_lon + buffer)
        )
        target.attrs["crs"] = "EPSG:4326"
        del full_target_ds
        return target, tiles
    else:
        return None, []

def reproject_dataset_to_fourthousandth_grid(ds, zone=None):
    ds = write_crs_dataset(ds, zone=zone)
    min_lat, max_lat, min_lon, max_lon = check_mins_maxes(ds)
    if max_lon >= 170 and min_lon <= -170:
        data_list, tiles_list, bounding_box_list = [], [], []

        target_east, tiles_east = create_target_grid(min_lat, max_lat, max_lon, 180)
        if len(tiles_east) > 0:
            reprojected_east = ds.rio.reproject_match(target_east).compute()
            reprojected_east = reprojected_east.where(reprojected_east < 1e100)
            data_list.append(reprojected_east)
            tiles_list.append(tiles_east)
            bounding_box_list.append([min_lat, max_lat, max_lon, 180])
        del target_east

        target_west, tiles_west = create_target_grid(min_lat, max_lat, -180, min_lon)
        if len(tiles_west) > 0:
            reprojected_west = ds.rio.reproject_match(target_west).compute()
            reprojected_west = reprojected_west.where(reprojected_west < 1e100)
            data_list.append(reprojected_west)
            tiles_list.append(tiles_west)
            bounding_box_list.append([min_lat, max_lat, -180, min_lon])
        del target_west

        return data_list, tiles_list, bounding_box_list

    else:
        target, tiles = create_target_grid(min_lat, max_lat, min_lon, max_lon)
        # the numbers aren't too big but if we normalize they might turn into decimals
        reprojected = ds.rio.reproject_match(target).compute()
        del ds
        del target
        reprojected = reprojected.where(reprojected < 1e100)
        return [reprojected], [tiles], [[min_lat, max_lat, min_lon, max_lon]]

def dataset_to_tabular(ds):
    '''
    Convert dataset to tabular form for inference

    Parameters
    ----------
    ds : xarray dataset
        xarray dataset with multiple bands

    Returns
    -------
    df : pandas dataframe
        dataframe with columns of bands

    '''
    df = ds.to_dataframe()
    del ds
    # drop any nan values so we only carry around pixels we have landsat for
    # this will drop both the parts of the dataset that are empty because
    # the landsat scenes might be rotated w.r.t. the x/y grid
    # but will also drop any cloud-masked regions
    # TODO: further investigate %-age of nulls and root cause
    df = df.dropna(how='any').reset_index()
    return df

def convert_to_lat_lon(df, utm_zone_number, utm_zone_letter):
    '''
    Given dataframe with x/y coordinates, project
    into the correct lat/lon coordinates, based upon UTM zone.

    Parameters
    ----------
    df : pandas dataframe
        geodataframe whose rows are entries for each row/path scene. Must
        include variables 'lon', 'lat'
    utm_zone_number : str/int
        string or int for the zone number (longitude) appropriate for that
        scene as defined by USGS
    utm_zone_letter : str
        string or int for the zone letter (latitude) appropriate for that
        scene as defined by USGS
    Returns
    -------
    df : pandas dataframe
        The projected information for each pixel
    '''

    return utm.to_latlon(df['x'], df['y'], int(utm_zone_number), utm_zone_letter)

def add_all_variables(data, tiles, year, lat_lon_box=None):
    data = load.aster(data, tiles, lat_lon_box=lat_lon_box)
    data = load.worldclim(data)
    # data = load.treecover2000(data, tiles)
    data = load.ecoregion(data, tiles, lat_lon_box=lat_lon_box)

    return data

def make_inference(input_data, model):
    """
    input_data is assumed to be a pandas dataframe, and model uses standard sklearn API with .predict
    """
    input_data['NIR_V'] = m.calc_NIR_V(input_data)
    input_data = input_data.replace([np.nan, np.inf, -np.inf, None], np.nan)
    input_data = input_data.dropna(subset=m.features)
    gc.collect()
    print(f'predicting on {len(input_data)} records')
    t0 = time.time()
    with joblib.parallel_backend('threading', n_jobs=8):
        model.n_jobs = 8
        input_data['biomass'] = model.predict(input_data)
    t1 = time.time()
    print(f'took {round(t1-t0)} seconds')
    return input_data[['x', 'y', 'biomass']]

def predict(
    model_folder,
    path,
    row,
    year,
    access_key_id,
    secret_access_key,
    output_write_bucket=None,
    input_write_bucket=None,
    bands_of_interest='all',
):
    core_session = boto3.Session(
        aws_access_key_id=access_key_id,
        aws_secret_access_key=secret_access_key,
        region_name='us-west-2',
    )
    aws_session = AWSSession(core_session, requester_pays=True)
    fs = S3FileSystem(key=access_key_id, secret=secret_access_key, requester_pays=True)

    with rio.Env(aws_session):
        # create the landsat scene for that year
        with dask.config.set(scheduler='single-threaded'):
            t0 = time.time()
            landsat_ds = scene_seasonal_average(
                path,
                row,
                year,
                access_key_id,
                secret_access_key,
                aws_session,
                core_session,
                fs,
                write_bucket=None,
                bands_of_interest='all',
                landsat_generation='landsat-7',
            )
            t1 = time.time()
            print(f'averaging landsat took {round(t1-t0)} seconds')
            if landsat_ds:
                # reproject from utm to lat/lon
                landsat_zone = landsat_ds.utm_zone_number + landsat_ds.utm_zone_letter
                # sets null value to np.nan
                write_nodata(landsat_ds)

                data_list, tiles_list, bounding_box_list = reproject_dataset_to_fourthousandth_grid(
                    landsat_ds.astype('float32'), zone=landsat_zone
                )
                del landsat_ds

                dfs = []
                for data, tiles, bounding_box in zip(data_list, tiles_list, bounding_box_list):
                    # add in other datasets
                    data = add_all_variables(data, tiles, year, lat_lon_box=bounding_box).load()
                    df = dataset_to_tabular(data.drop(['spatial_ref']))
                    dfs.append(df)
                    del df
                    del data
                df = pd.concat(dfs)
                df = df.loc[df.ecoregion > 0]
                df['realm'] = df.ecoregion.apply(ECO_TO_REALM_MAP.__getitem__)
            else:
                df = pd.DataFrame({})

        # apply the correct model for each realm
        if len(df) > 0:
            # write input
            if input_write_bucket is not None:
                utils.write_parquet(df, input_write_bucket, access_key_id, secret_access_key)
            rf_result = []
            xg_result = []
            for realm, sub in df.groupby('realm'):
                rf = m.random_forest_model(
                    realm=realm,
                    df_train=None,
                    df_test=None,
                    output_folder=model_folder,
                    validation_year='none',
                    overwrite=False,
                )
                rf_result.append(make_inference(sub, rf))

                xg = m.xgb_model(
                    realm=realm,
                    df_train=None,
                    df_test=None,
                    output_folder=model_folder,
                    validation_year='none',
                    overwrite=False,
                )
                xg_result.append(make_inference(sub, xg))

            rf_result = pd.concat(rf_result)
            xg_result = pd.concat(xg_result)

            del df
        else:
            rf_result = pd.DataFrame([[np.nan, np.nan, np.nan]], columns=['x', 'y', 'biomass'])
            xg_result = pd.DataFrame([[np.nan, np.nan, np.nan]], columns=['x', 'y', 'biomass'])

        if output_write_bucket is not None:
            # random forest
            output_filepath = f'{output_write_bucket}/rf/{year}/{path:03d}{row:03d}.parquet'
            utils.write_parquet(rf_result, output_filepath, access_key_id, secret_access_key)
            output_filepath = f'{output_write_bucket}/xg/{year}/{path:03d}{row:03d}.parquet'
            utils.write_parquet(xg_result, output_filepath, access_key_id, secret_access_key)
            return ('pass', output_filepath)
        else:
            return rf_result

predict_delayed = dask.delayed(predict)


# -*- coding: cp1252 -*-.
# Created on 21/mag/2014
# @author: mda
#!/usr/local/bin/python
import datetime
from pygeocoder import Geocoder
from pygeolib import GeocoderError
import re
import rThinkGbl as gL
import phonenumbers
import inspect
import urllib

def SetNow():
    # data corrente del run
    wrk = datetime.datetime.now()
    return str(wrk.replace(microsecond = 0))

def StdCar(stringa):

    if isinstance(stringa, list):
        clean = stringa[0]
    else:
        clean = stringa
    CaratteriVietati = ['#', '(', ')', '/', '.', '-', ';',  '"']
    for ch in CaratteriVietati:
        if ch in clean:
            clean = clean.replace(ch, "")
    clean = " ".join(clean.split())
    stringa = clean.strip()
    return stringa

def StdName(stringa):

    stringa = gL.StdCar(stringa)
    return stringa.title()

def StdPhone(stringa, country):
    try:

        test = stringa.split(' - ')   # due numeri di tel separati da trattino
        if len(test) > 1:
            stringa = test[0]

        ISO = gL.CountryISO.get(country)
        if ISO is None:
            gL.cSql.execute("select CountryISO2 from T_Country where Country = ?", ([country]))
            row = gL.cSql.fetchone()
            if row:
                ISO = row['countryiso2']
                gL.CountryISO[country] = ISO

        if ISO is None:
            gL.log(gL.ERROR, "Lingua non trovata")
            return False
    except:
        gL.log(gL.ERROR, stringa)
        gL.log(gL.ERROR, err)
        return False, False

    # formatta telefono
    try:
        newphone = '' ; newphone1 = '' ; idx = 0
        numeri = phonenumbers.PhoneNumberMatcher(stringa, ISO)
        while numeri.has_next():
            idx = idx + 1
            match = numeri.next()
            #print(phonenumbers.format_number(b.number, phonenumbers.PhoneNumberFormat.INTERNATIONAL))
            if idx == 1:
                newphone = phonenumbers.format_number(match.number, phonenumbers.PhoneNumberFormat.INTERNATIONAL)
                newphone = newphone.replace('(','')
                newphone = newphone.replace(')','')
            if idx == 2:
                #match = phonenumbers.parse(stringa, ISO)
                newphone1 = phonenumbers.format_number(match.number, phonenumbers.PhoneNumberFormat.INTERNATIONAL)
                #newphone = phonenumbers.format_number(y, phonenumbers.PhoneNumberFormat.INTERNATIONAL)
                newphone1 = newphone1.replace('(','')
                newphone1 = newphone1.replace(')','')
    except:
        msg ="%s - %s" % ("Phone stdz error", stringa)
        gL.log(gL.ERROR, msg)
        newphone = stringa
        return False, False

    return (newphone, newphone1)

def GetFunzione(tipo, source, assettype, country):
    for k in gL.Funzioni:
        if k['source'] == source and k['assettype'] == assettype and k['country'] == country:
            if tipo == "PARSE":
                return k['parsefn']
            if tipo == "QUEUE":
                return k['queuefn']
            if tipo == "NEXT":
                return k['nextpagefn']
    return False

def StdZip(stringa):
    stringa = gL.StdCar(stringa)
    # formatta ZIP
    return stringa

def CercaFrase(frase, stringa, operatore, replacew):
    try:
        mod = False
        stringa = str(stringa)
        newstringa = stringa
        a = []
        b = []
        idx = []
        out = []
        wrk = []
        a = stringa.split()
        b = frase.split()
        if replacew:
            c = replacew.split()
        maxa = len(a)
        maxb = len(b)
        conta = 0;
        trovato = False

        if a and b and maxa >= maxb:
            for i, x in enumerate(a):
                conta = 0
                #idx = a.index(x)
                if x == b[0]:
                    idx.append(i)
                    out.append(x)
                    trovato = True
                    for z in b[1:]:
                        conta = conta + 1
                        if conta+i < maxa:
                            if z != a[conta+i]:
                                trovato = False
                                idx = []
                                out = []
                            else:
                                idx.append(conta+i)
                                out.append(z)
                    if trovato:
                        break

        if operatore == "Keep":
            return trovato, mod, newstringa, idx

        if trovato:
            if operatore == "Delete" or operatore == "Replace":
                conta = 0
                for zz in a:
                    if not conta in idx:
                        wrk.append(zz)
                        mod = True
                    conta = conta + 1
                newstringa = " ".join(wrk)

            if operatore == "Replace":
                conta = 0
                if idx[0] == 0:
                    ind = 0
                    indrpc = 0
                else:
                    ind = idx[0] + 1
                    indrpc = idx[0]
                if ind > len(wrk):   # se sono alla fine della stringa
                    for rplc in c:
                        wrk.append(rplc)
                        mod = True
                else:
                    for rplc in reversed(c):
                        wrk.insert(indrpc, rplc)
                        mod = True

                newstringa = " ".join(wrk)

        return trovato, mod, newstringa, idx

    except Exception as err:

        gL.log(gL.ERROR, err)
        return False, False, False, False

def xstr(s):

    if s is None:
        return ''
    return str(s)

def OkParam():
    return True

def StdAddress(AddrStreet, AddrZIP, AddrCity, AddrCountry, indirizzo=''):
    gL.GmapNumcalls = gL.GmapNumcalls + 1

    AddrRegion = ''
    AddrLat    = 0
    AddrCounty = ''
    AddrLong   = 0
    FormattedAddress = ''

    if indirizzo == '':
        indirizzo = xstr(AddrStreet) + " " + xstr(AddrZIP) + " " + xstr(AddrCity) + " " + xstr(AddrCountry)

    try:
        while True:
            results = Geocoder.geocode(indirizzo)
            if results is None:
                msg = "Indirizzo: " + indirizzo + " non trovato"
                gL.log(gL.WARNING, msg)
                return (False, AddrStreet, AddrCity, AddrZIP, 0, 0, '', '', '')

            if results.count > 0:
                result = results[0]   # solo il primo valore ritornato
                AddrCounty = ""
                for component in result.current_data['address_components']:
                    a = component['types']
                    if a:
                        if a[0] == "administrative_area_level_2":
                            AddrCounty = component['short_name']
                            break
                if result.route and result.street_number:
                    AddrStreet = result.route + " " + result.street_number
                AddrCity = result.locality
                AddrZIP =  result.postal_code
                if result.coordinates[0]:
                    AddrLat  = result.coordinates[0]
                if result.coordinates[1]:
                    AddrLong = result.coordinates[1]
                if result.administrative_area_level_1:
                    AddrRegion = result.administrative_area_level_1
                if result.formatted_address:
                    FormattedAddress = result.formatted_address
                return True, AddrStreet, AddrCity, AddrZIP, AddrLat, AddrLong, AddrRegion, AddrCounty, FormattedAddress
            else:
                return (False, AddrStreet, AddrCity, AddrZIP, 0, 0, '', '', '')
    except GeocoderError as err:
        if err.status == "ZERO_RESULT":
            indirizzo = nome + " " + indirizzo
        return (False, AddrStreet, AddrCity, AddrZIP, 0, 0, '', '', '')


import pygame

# Initialize Pygame and set the window size
pygame.init()
size = (700, 500)
screen = pygame.display.set_mode(size)

# Set the background color for the empty grid spaces
bg_color = (255, 255, 255)
screen.fill(bg_color)

# Create entities using rectangles
food_color = (0, 255, 0)
food = pygame.draw.rect(screen, food_color, (10, 10, 20, 20))

water_color = (0, 0, 255)
water = pygame.draw.rect(screen, water_color, (30, 30, 20, 20))

poison_color = (255, 0, 0)
poison = pygame.draw.rect(screen, poison_color, (50, 50, 20, 20))

# Create agents using circles
agent_color = (255, 255, 0)
agent = pygame.draw.circle(screen, agent_color, (75, 75), 10)

# Update the display
pygame.display.flip()

# Handle user input
running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

# Quit Pygame
pygame.quit()


import math
from copy import deepcopy

def findCombinations(goal, coins, printCombinations=False):
    emptySet = dict([(coin, 0) for coin in coins])
    sets = [emptySet]
    for coin in reversed(coins):
        newSets = []
        for currentSet in sets:
            amountLeft = goal - sum([k*v for k,v in currentSet.items()])
            maxCoins = math.floor(amountLeft/coin)
            minCoins = 0 if coin != coins[0] else maxCoins
            for n in range(minCoins,maxCoins+1):
                newSet = deepcopy(currentSet)
                newSet[coin] = n
                newSets.append(newSet)
        sets = newSets
    sets = [ currentSet for currentSet in sets if sum([k * v for k, v in currentSet.items()]) == goal]
    finalCombos = ["-".join(["".join([str(k)]*combi[k]) for k in sorted(combi.keys())]) for combi in sets]
    if printCombinations:
        for f in sorted(finalCombos):
            print(f)
    return len(finalCombos)

print(findCombinations(200, [1, 2, 5, 10, 20, 50, 100, 200], printCombinations=True))


import os
import json
from flask import Flask, render_template, request
from run_model import bag_of_words

app = Flask(__name__)

@app.route("/ping", methods=["GET"])
def home_view():
    return "pong"

@app.route("/bag_of_words", methods=["POST"])
def help_view():
    message = request.json
    q = message['question']
    result = bag_of_words(q)
    return { 'status': 'OK', 'data': json.dumps(result) }

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


import dash
from dash import dcc
from dash import html
import yfinance as yf
import pandas as pd
import plotly.graph_objects as go
from dash.dependencies import Input, Output
import numpy as np

stock_data = None
last_symbol = None

def get_stock_data(symbol):
    stock_data = yf.download(symbol, start='2021-01-01', end='2023-06-01')
    return stock_data

# App initialisieren
app = dash.Dash(__name__)

# Dropdown-Optionen für Aktienliste
stock_options = [
    {'label': 'Tesla', 'value': 'TSLA'},
    {'label': 'Apple', 'value': 'AAPL'},
    {'label': 'Alphabet (Google)', 'value': 'GOOGL'},
    {'label': 'Microsoft', 'value': 'MSFT'},
]

# Dropdown-Optionen für Indikatoren
indicator_options = [
    {'label': 'SMA 50', 'value': 'sma50'},
    {'label': 'SMA 200', 'value': 'sma200'},
    {'label': 'EMA 12', 'value': 'ema12'},
    {'label': 'EMA 24', 'value': 'ema24'},
    {'label': 'Weighted Moving Average (WMA)', 'value': 'wma'},
    {'label': 'Hull Moving Average (HMA)', 'value': 'hma'},
    {'label': 'Triple Exponential Moving Average (TEMA)', 'value': 'tema'},
    {'label': 'Volume Weighted Average Price (VWAP)', 'value': 'vwap'},
]

# Dash-Layout erstellen
app.layout = html.Div([
    html.H1('Aktiendaten mit Indikatoren'),

    html.Label('Aktie auswählen'),
    dcc.Dropdown(
        id='stock-dropdown',
        options=stock_options,
        value='TSLA'
    ),

    html.Label('Indikatoren auswählen'),
    dcc.Dropdown(
        id='indicator-dropdown',
        options=indicator_options,
        value=['sma50'],
        multi=True
    ),

    dcc.Graph(id='stock-chart')
])

# Callback für Diagramm-Update
@app.callback(
    Output('stock-chart', 'figure'),
    Input('stock-dropdown', 'value'),
    Input('indicator-dropdown', 'value'))
def update_stock_chart(stock_symbol, indicators):

    global stock_data, last_symbol

    # Aktualisiere Aktiendaten nur, wenn 'stock-dropdown' verändert wurde
    if stock_data is None or stock_symbol != last_symbol:
        stock_data = get_stock_data(stock_symbol)
        last_symbol = stock_symbol

    figure = go.Figure(data=[go.Candlestick(
        x=stock_data.index,
        open=stock_data['Open'],
        high=stock_data['High'],
        low=stock_data['Low'],
        close=stock_data['Close'],
        name='Aktienkurs'
    )])

    # Layout anpassen, um die Höhe zu konfigurieren
    figure.update_layout(height=800,
                         xaxis_rangeslider_visible=False,
                         )

    for indicator in indicators:
        if indicator == 'sma50':
            sma = stock_data['Close'].rolling(window=50).mean()
            figure.add_trace(go.Scatter(x=stock_data.index, y=sma, name='SMA 50'))
        elif indicator == 'sma200':
            sma = stock_data['Close'].rolling(window=200).mean()
            figure.add_trace(go.Scatter(x=stock_data.index, y=sma, name='SMA 200'))
        elif indicator == 'ema12':
            ema = stock_data['Close'].ewm(span=12, adjust=False).mean()
            figure.add_trace(go.Scatter(x=stock_data.index, y=ema, name='EMA 12'))
        elif indicator == 'ema24':
            ema = stock_data['Close'].ewm(span=24, adjust=False).mean()
            figure.add_trace(go.Scatter(x=stock_data.index, y=ema, name='EMA 24'))
        elif indicator == 'wma':
            wma = stock_data['Close'].rolling(window=50).apply(lambda x: np.dot(x, np.arange(1, 51)) / np.sum(np.arange(1, 51)))
            figure.add_trace(go.Scatter(x=stock_data.index, y=wma, name='WMA'))
        elif indicator == 'hma':
            hma = 2 * stock_data['Close'].rolling(window=int(len(stock_data)/2)).mean() - stock_data['Close'].rolling(window=len(stock_data)).mean().rolling(window=int(np.sqrt(len(stock_data)))).mean()
            figure.add_trace(go.Scatter(x=stock_data.index, y=hma, name='HMA'))
        elif indicator == 'tema':
            tema = stock_data['Close'].ewm(span=12, adjust=False).mean().ewm(span=12, adjust=False).mean().ewm(span=12, adjust=False).mean()
            figure.add_trace(go.Scatter(x=stock_data.index, y=tema, name='TEMA'))
        elif indicator == 'vwap':
            vwap = (stock_data['Close'] * stock_data['Volume']).cumsum() / stock_data['Volume'].cumsum()
            figure.add_trace(go.Scatter(x=stock_data.index, y=vwap, name='VWAP'))

    return figure

# App ausführen
if __name__ == '__main__':
    app.run_server(debug=True)


import torch
import unittest

from torch_blade import utils
from torch_blade.version import cuda_available
from tests.disc.testing_base import \
    DiscTestCase, skipTorchGE, skipTorchLT, isTorchMlirEnable

class TestDiscNNOps(DiscTestCase):

    def _test_nn_ops(self, nn_ops_func, x=None):
        test_data = torch.randn([2, 3, 224, 224], device=self.device) \
            if x is None else x
        if (isinstance(test_data, torch.Tensor)):
            test_data = (test_data.to(self.device),)
        self._test_cvt_to_disc(nn_ops_func, test_data)

    def test_softmax(self):
        softmax = torch.nn.Softmax(dim=-1)
        self._test_nn_ops(softmax)

        if isTorchMlirEnable() or utils.torch_version_number() \
                >= utils.parse_version("1.12.0"):
            # TODO(yancey.yx): support i32 input
            return

        @torch.jit.script
        def softmax_func(x):
            return torch.nn.functional.softmax(x, dim=-1, dtype=torch.float32)

        self._test_nn_ops(
            softmax_func, torch.randint(-3, 3, [2, 3, 4], dtype=torch.int32)
        )

    def test_log_softmax(self):
        log_softmax = torch.nn.LogSoftmax(dim=-1)
        self._test_nn_ops(log_softmax)

        if isTorchMlirEnable() or utils.torch_version_number() \
                >= utils.parse_version("1.12.0"):
            # TODO(tanyo): support i32 input
            return

        @torch.jit.script
        def log_softmax_func(x):
            return torch.nn.functional.log_softmax(x, dim=-1,
                                                   dtype=torch.float32)

        self._test_nn_ops(
            log_softmax_func,
            torch.randint(-3, 3, [2, 3, 4], dtype=torch.int32)
        )

    @unittest.skipIf(not cuda_available, "run only on cuda")
    def test_softmax_return_half(self):
        @torch.jit.script
        def softmax_func_return_half(x):
            return torch.nn.functional.softmax(x, dim=1, dtype=torch.half)

        @torch.jit.script
        def log_softmax_func_return_half(x):
            return torch.nn.functional.log_softmax(x, dim=-1, dtype=torch.half)

        inputs = (torch.randn([2, 3, 4], device=self.device),)
        self._test_cvt_to_disc(
            softmax_func_return_half, inputs, atol=1e-2
        )
        self._test_cvt_to_disc(
            log_softmax_func_return_half, inputs, atol=1e-2
        )

    @unittest.skipIf(not cuda_available, "Please fix incorrect results")
    @skipTorchGE("1.12.0")
    def test_softmax_func(self):
        @torch.jit.script
        def softmax(x):
            reduce_dim = -1
            x = torch.sub(x, 255)
            exp = x.exp()
            sum_exp = exp.sum(dim=reduce_dim, keepdim=True)
            b_sum_exp = sum_exp.expand_as(exp)
            return exp / b_sum_exp

        self._test_nn_ops(softmax)

    def test_masked_fill(self):
        @torch.jit.script
        def masked_fill(x, mask):
            return x.masked_fill(mask, 5)

        x = torch.randn([2, 3], device=self.device)
        mask = torch.tensor([[1] * 3] * 2, device=self.device).to(torch.bool)
        self._test_nn_ops(masked_fill, x=(x, mask))

        x = torch.randn([2, 3, 224, 224], device=self.device)
        mask = torch.randint(1, [224], device=self.device).to(torch.bool)
        self._test_nn_ops(masked_fill, x=(x, mask))

    def test_embedding(self):
        embedding = torch.nn.Embedding(10, 3).to(self.device)
        input = torch.LongTensor([[0, 2, 0, 5]]).to(self.device)
        self._test_nn_ops(embedding, input)
        input = torch.LongTensor([0, 2, 0, 5]).to(self.device)
        self._test_nn_ops(embedding, input)
        input = torch.LongTensor([9]).to(self.device)
        self._test_nn_ops(embedding, input)
        input = torch.LongTensor([]).to(self.device)
        self._test_nn_ops(embedding, input)
        input = torch.tensor(8, dtype=torch.int64).to(self.device)
        self._test_nn_ops(embedding, input)

    def test_gru_cell(self):
        # TODO(gty): Support torch.nn.GRUCell(4, 8, false)
        rnn = torch.nn.GRUCell(4, 8).to(self.device)
        input = torch.ones(3, 4, device=self.device)
        hx = torch.ones(3, 8, device=self.device)
        self._test_nn_ops(rnn, (input, hx))

    @skipTorchLT("1.12.0")
    def test_constant_pad(self):
        @torch.jit.script
        def constant_pad(t4d):
            # pad by (0, 1), (2, 1), and (3, 3)
            p3d = (0, 1, 2, 1, 3, 3)
            return t4d.pad(p3d, "constant", 3.0)

        x = torch.randn([2, 3, 4, 5], device=self.device)
        self._test_nn_ops(constant_pad, x=(x,))

        x = torch.randn([2, 3, 224, 224], device=self.device)
        self._test_nn_ops(constant_pad, x=(x,))

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


""" Script for blob detection originaly inspired by http://www.learnopencv.com/blob-detection-using-opencv-python-c/ at 13th of Juny 2015
    Now it returns clusterBuster relics and hsitogramms
"""

# Standard imports
import numpy as np
import cv2
#import pyfits as fits
#import scipy.ndimage.morphology    as morp #morp.binary_dilation(input, structure=None, iterations=1, mask=None, output=None, border_value=0, origin=0, brute_force=False)
from scipy import ndimage                # used to compute the centroid
import clusterbuster.surveyclasses as cbclass
import clusterbuster.maput as maput

def RelicExtraction(image, z, contourMask = [], Imcenter=False, GCl=False, dinfo=False, rinfo= False, faintexcl=False,
                    subtracted=False, term=False, cnt_minlength=5, gather_histo_information=True):

    """ Extracts Relics from a numpy array
    gather_histo_information: 0 of not derived, 1 if derived

    See http://photutils.readthedocs.io/en/stable/api/photutils.detect_sources.html
    for possible alternative of implementation
    """

    if not GCl:
        GCl = cbclass.Galaxycluster('NoName', 0, 0, z)
    if not dinfo: #If no detection info specified, create a default one
        dinfo = cbclass.DetInfo()
    if not rinfo: #If no relic region is specified, create a default one
        rinfo = cbclass.RelicRegion(name='', cnt=contourMask, rtype=-1, alpha=1.2)
    if not Imcenter:
        Imcenter = [[0,0], [image.shape[0]/2, image.shape[1]/2]]  # [ [Astronomical Coords], [Pixelcoords] ]

    if term:
        print('###==== Sub-Step X.1: Executing RelicExtraction(2d-numpy array) ====###')

    relics = []

    ## Way of extracting relics: Relic detection by simple thresholding
    (contours, hierarchy) = maput.GetThreshContours(image, dinfo.limit, rinfo.cnt)

    for jj, cnt in enumerate(contours):
        if term:
            print('%6i out of %6i: len(cnt)=%6i' % (jj+1, len(contours), len(cnt)))

        M = cv2.moments(cnt)
        if cnt.shape[0] < cnt_minlength or M['m00'] == 0 : # cnt >= 3 needed for moment analysis & cnt >= 5 for ellipse fitting
            #print 'Contour of', len(cnt), 'ergo less than', cnt_minlength, 'points identified. It will not be considered further.'
            continue

        #cx = int(M['m10']/M['m00'])
        #cy = int(M['m01']/M['m00'])

        # Minimal enclosing circle
        (x, y), radius = cv2.minEnclosingCircle(cnt)

        # mask image, so that every value outside of the contour is set to zero
        region = maput.ContourMasking(image, [cnt])

        flux             = 1e3*np.sum(region)/dinfo.Abeam[0]  # in mJy
        GCl.flux_vol     = 1e3*np.sum(image )/dinfo.Abeam[0]  # in mJy
        if faintexcl and flux < faintexcl:
            continue

        try:
            subregion = maput.ContourMasking(subtracted, [cnt])
            flux_ps = 1e3*np.sum(subregion)/dinfo.Abeam[0]
        except:
            flux_ps = 0

        centroid = ndimage.measurements.center_of_mass(region)
        cov, theta_iner = maput.inertial_axis(region)[2:4]  # compute moment of inertia and gaussian fit

        Dec = Imcenter[0][1] + (centroid[0]-Imcenter[1][1])*dinfo.spixel/3600
        RA  = Imcenter[0][0] - (centroid[1]-Imcenter[1][0])*dinfo.spixel/3600/np.cos(Dec*np.pi/180)  #Please mind the additional factor due to the projection!

        theta_elong = (np.degrees(theta_iner)+180) % 180
        LAS = 2*radius*(dinfo.spixel/60)
        area = (dinfo.spixel/60)**2*cv2.contourArea(cnt)

        region[np.isnan(region)] = 0
        rel = np.where(region > 0)

        if gather_histo_information:
            """ Creates the necessary masks and array for the FLUX histogram """
            """ The same is done with Distance, Angle and Mach number """
            RA_arr  = Imcenter[0][0] - (rel[1] - Imcenter[1][0])*dinfo.spixel/3600/np.cos(Dec*np.pi/180)
            Dec_arr = Imcenter[0][1] + (rel[0] - Imcenter[1][1])*dinfo.spixel/3600
            distance = np.sqrt(np.add(np.power(np.abs(GCl.RA.value-RA_arr) * np.cos(Dec_arr*np.pi/180), 2),
                                       np.power(np.abs(Dec_arr-GCl.Dec.value), 2))) * GCl.cosmoPS * 3600      #2D-array in kpc, np.linalg.norm( [GCl.RA-RA, Dec-GCl.Dec] ) * GCl.cosmoPS *3600
            angle = np.mod(np.arctan2(-(GCl.RA.value-RA_arr)*np.cos(Dec_arr*np.pi/180), Dec_arr-GCl.Dec.value)
                           + 0.5*np.pi, 2.*np.pi)   #2D-array in kpc, np.linalg.norm( [GCl.RA-RA, Dec-GCl.Dec] ) * GCl.cosmoPS *3600
            weights = region[rel]
            Dproj_pix = np.average(distance, weights=weights)  # in kpc
        else:
            distance = None
            angle = None
            weights = None
            Dproj_pix = 0

        relic = cbclass.Relic(rinfo, dinfo, RA, Dec, LAS, area, GCl=GCl, alpha=rinfo.alpha, alphaFLAG=rinfo.alphaFLAG,
                              theta_elong=theta_elong, cov=cov, cnt=cnt, F=flux, F_ps=flux_ps, Dproj_pix=Dproj_pix,
                              sparseD=distance, sparseW=weights, sparseA=angle, pmask=rel)
        relics.append(relic)

    return relics


import os, shutil, errno, sys

def copy_filedir(src, dst):
    try:
        shutil.copytree(src, dst)
    except OSError as exc: # python >2.5
        if exc.errno in (errno.ENOTDIR, errno.EINVAL):
            shutil.copy(src, dst)
        else: raise

if len(sys.argv) > 1:
    unity_path = str(sys.argv[1])
else:
    print("ERROR: You need to pass the path to Unity editor executable.")
    exit()

nodisplay =  "-nodisplay" in sys.argv
package_name = 'UnityAsyncTextureImport.unitypackage'
plugin_folder_name = 'UnityAsyncTextureImport'
unity_project_dir = 'unity-async-textureimport'

export_project_path = "tmp-package-export"

if os.path.exists(export_project_path):
    shutil.rmtree(export_project_path)
os.mkdir(export_project_path)

assets = ["Assets", "ACKNOWLEDGEMENTS.txt", "ACKNOWLEDGEMENTS.txt", "LICENSE", "README.md", "FreeImage-license-GPLv3"]

for asset in assets:
    src_asset = os.path.join(unity_project_dir, asset)
    dest_asset = os.path.join(export_project_path, "Assets", plugin_folder_name, asset)
    copy_filedir(src_asset, dest_asset)

# Copy binaries
freeImage_bin_dir = os.path.join(export_project_path, "Assets", plugin_folder_name, "Assets", "Plugins", "FreeImage")
os.mkdir(os.path.join(freeImage_bin_dir, "Android"))
os.mkdir(os.path.join(freeImage_bin_dir, "Android", "arm64-v8a"))
copy_filedir(os.path.join("binaries", "arm64-v8a", "libFreeImage.so"), os.path.join(freeImage_bin_dir, "Android", "arm64-v8a", "libFreeImage.so"))
os.mkdir(os.path.join(freeImage_bin_dir, "Android", "armeabi-v7a"))
copy_filedir(os.path.join("binaries", "armeabi-v7a", "libFreeImage.so"), os.path.join(freeImage_bin_dir, "Android", "armeabi-v7a", "libFreeImage.so"))
#os.mkdir(os.path.join(freeImage_bin_dir, "Linux"))
copy_filedir(os.path.join("binaries", "linux", "libFreeImage.so"), os.path.join(freeImage_bin_dir, "Linux", "libFreeImage.so"))
# Copy meta files
shutil.copy(os.path.join("bin-meta", "arm64-v8a.meta"), os.path.join(freeImage_bin_dir, "Android", "arm64-v8a", "libFreeImage.so.meta"))
shutil.copy(os.path.join("bin-meta", "armeabi-v7a.meta"), os.path.join(freeImage_bin_dir, "Android", "armeabi-v7a", "libFreeImage.so.meta"))
shutil.copy(os.path.join("bin-meta", "linux.meta"), os.path.join(freeImage_bin_dir, "Linux", "libFreeImage.so.meta"))

command_string = "\"{unity_path}\" -projectPath {project_path} -exportPackage Assets {package_name} -batchmode -nographics -silent-crashes -quit".format(unity_path=unity_path, project_path=export_project_path, package_name=package_name)
# Run through cvfb if no display available (building in container, etc.).
if nodisplay:
    command_string = "xvfb-run --auto-servernum --server-args=\'-screen 0 640x480x24\' " + command_string
print(command_string)
os.system(command_string)

shutil.copy(os.path.join(export_project_path, package_name), package_name)

shutil.rmtree(export_project_path)


import  unittest

from LinkedList import LinkedList

class Testing(unittest.TestCase):

	def insert_elements(self):
		self.list = LinkedList()
		for i in range(0, 1234):
			self.list.insert(i)

	def test_search(self):
		self.insert_elements()
		self.assertEqual(self.list.search(0),0)
		self.assertEqual(self.list.search(50),50)
		self.assertIsNone(self.list.search(1234))

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


from webassets.filter.closure import ClosureJS

class SimpleClosureJS(ClosureJS):
    """
    This filter uses the Google Closure Compiler with simple optimizations
    turned on.
    """

    def __init__(self, disable_ie_checks=False):
        super(SimpleClosureJS, self).__init__()

        self.disable_ie_checks = disable_ie_checks

    def setup(self):
        super(SimpleClosureJS, self).setup()

        # Configure default closure compiler options
        self.opt = 'SIMPLE_OPTIMIZATIONS'

        if self.disable_ie_checks:
            self.extra_args = ['--jscomp_off', 'internetExplorerChecks']


from flask import Flask
from src.config.env import Env

from werkzeug.utils import import_string

api_blueprints = ["hook_bp"]

def create_app():
    app = Flask(__name__)

    # Register blueprints
    for bp_name in api_blueprints:
        print("Registering bp: %s" % bp_name)
        bp = import_string("src.routes.%s:bp" % (bp_name))
        app.register_blueprint(bp)

    return app

if __name__ == "__main__":
    app = create_app()

    app.run(port=Env().PORT)


"""Task 7."""
import functools
import itertools

def valuesunion(*dicts):
    answ = set()
    for d in dicts:
        for el in d.values():
            answ.add(el)
    return answ

def popcount(n):
    s = bin(n)
    sum = 0
    for i in range(2, len(s)):
        if s[i] == '1':
            sum += 1
    return sum

def powers(n, m):
    answ = {}

    def power(n):
        a = 1
        for i in range(n):
            a *= n
        return a

    for i in range(1, n+1):
        answ[i] = power(i) % m
    return answ

def subpalindrome(s):
    max = 0
    answ = ''

    def is_palindrome(word):
        if len(word) == 1:
            return True
        return all(word[i] == word[-1*(i+1)] for i in range(len(word)//2))

    for i in range(len(s)):
        for j in range(i + 1, len(s) + 1):
            if is_palindrome(s[i:j]):
                if j - i > max:
                    answ = s[i:j]
                    max = j - i
                elif j - i == max:
                    if s[i:j] < answ:
                        answ = s[i:j]
    return answ

def isIPv4(s):
    for i in s:
        if i not in ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.'):
            return False
    num = s.split('.')
    if len(num) != 4:
        return False
    for n in num:
        if int(n) < 0 or int(n) > 255:
            return False
        if n[0] == '0' and len(n) != 1:
            return False
    return True

def pascals():
    prev = (1,)

    for i in itertools.count(1):
        act = []
        act.append(1)
        for k in range(len(prev) - 1):
            act.append(prev[k] + prev[k + 1])
        act.append(1)
        yield tuple(prev)
        prev = act

def spiral(n):
    i = 1
    a = [[0 for i in range(n)] for j in range(n)]
    for l in range(n):
        a[0][l] = i
        i += 1
    h1 = 1
    h2 = n - 1
    v1 = 0
    v2 = n - 1
    while i <= (n*n):
        # down
        for l in range(h2 - h1 + 1):
            a[h1 + l][v2] = i
            i += 1
        v2 -= 1

        # left
        for l in range(v2 - v1 + 1):
            a[h2][v2 - l] = i
            i += 1
        h2 -= 1

        # up
        for l in range(h2 - h1 + 1):
            a[h2 - l][v1] = i
            i += 1
        v1 += 1

        # right
        for l in range(v2 - v1 + 1):
            a[h1][v1 + l] = i
            i += 1
        h1 += 1
    return a

def fibonacci(n):
    return functools.reduce(lambda x, n: [x[1], x[0] + x[1]],
                                      range(n), [0, 1])[0]

def brackets2(n, m, pref='', balance1=0, balance2=0):

    def count1(pref):
        return sum(map(lambda x: 1 if x in ('(', ')') else 0, pref))

    def count2(pref):
        return sum(map(lambda x: 1 if x in ('[', ']') else 0, pref))

    def stack_check(pref):
        stack = []
        for el in pref:
            n = len(stack)
            if n == 0:
                stack.append(el)
            elif stack[n - 1] == '(' and el == ')':
                stack.pop()
            elif stack[n - 1] == '['and el == ']':
                stack.pop()
            else:
                stack.append(el)
        if len(stack) == 0:
            return True
        else:
            return False

    if count1(pref) == 2 * n and count2(pref) == 2 * m\
       and balance1 == 0 and balance2 == 0 and stack_check(pref):
        yield pref
    else:
        for i in ('(', ')', '[', ']'):
            new_pref = pref + i
            if i == '(':
                new_balance1 = balance1 + 1
                new_balance2 = balance2
            elif i == ')':
                new_balance1 = balance1 - 1
                new_balance2 = balance2
            elif i == '[':
                new_balance2 = balance2 + 1
                new_balance1 = balance1
            elif i == ']':
                new_balance2 = balance2 - 1
                new_balance1 = balance1
            if count1(new_pref) <= 2 * n and count2(pref) <= 2 * m\
                        and new_balance1 >= 0 and new_balance2 >= 0:
                yield from brackets2(n, m, new_pref, new_balance1,
                                     new_balance2)

if __name__ == "__main__":
    assert valuesunion({1: 2, 4: 8}) == {2, 8}
    assert valuesunion({1: 2}, {4: 8}) == {2, 8}
    assert valuesunion({1: 2, 4: 8}, {'a': 'b'}, {}, {}) == {2, 8, 'b'}
    print("valuesunion - OK")

    assert popcount(0) == 0
    assert popcount(1) == 1
    assert popcount(10) == 2
    assert popcount(1023) == 10

    assert powers(3, 1000000000) == {1: 1, 2: 4, 3: 27}
    assert powers(4, 50) == {1: 1, 2: 4, 3: 27, 4: 6}
    assert powers(1, 1) == {1: 0}
    print("powers - OK")

    assert subpalindrome('abc') == 'a'
    assert subpalindrome('aaaa') == 'aaaa'
    assert subpalindrome('abaxfgf') == 'aba'
    assert subpalindrome('abacabad') == 'abacaba'
    print("subpalindrome - OK")

    assert isIPv4('192.168.0.15')
    assert isIPv4('255.255.255.255')
    assert not isIPv4('555.555.555.555')
    assert not isIPv4('190+2.168.0.0')
    assert not isIPv4('abacaba')
    assert not isIPv4('')
    print('isIPv4 - OK')

    it = pascals()
    for i in range(9):
        print(next(it))
    print("pascal - OK")

    assert spiral(1) == [[1]]
    assert spiral(2) == [[1, 2],
                         [4, 3]]
    assert spiral(4) == [[1, 2, 3, 4],
                         [12, 13, 14, 5],
                         [11, 16, 15, 6],
                         [10, 9, 8, 7]]
    print("spiral - OK")

    assert fibonacci(1) == 1
    assert fibonacci(2) == 1
    assert fibonacci(3) == 2
    assert fibonacci(4) == 3
    assert fibonacci(5) == 5
    assert fibonacci(6) == 8
    assert fibonacci(7) == 13
    print("fibonacci - OK")

    assert list(brackets2(1, 0)) == ['()']
    assert list(brackets2(0, 1)) == ['[]']
    assert list(brackets2(1, 1)) == ['()[]', '([])', '[()]', '[]()']
    assert list(brackets2(3, 0)) == ['((()))', '(()())', '(())()', '()(())',
                                     '()()()']
    assert list(brackets2(2, 1)) == ['(())[]', '(()[])', '(([]))', '()()[]',
                                     '()([])', '()[()]', '()[]()', '([()])',
                                     '([]())', '([])()', '[(())]', '[()()]',
                                     '[()]()', '[](())', '[]()()']
    print("brackets - OK")
    print(subpalindrome("gzicy"))


from pyramid.httpexceptions import HTTPBadRequest
from pyramid_jsonapi.http_query import QueryInfo
from rqlalchemy import RQLQueryMixIn
from sqlalchemy.orm import load_only, Query as BaseQuery

class PJQueryMixin:

    @staticmethod
    def from_view(view, **kwargs):
        query = view.dbsession.query(
            view.model
        )
        query.__class__ = RQLQuery
        query.pj_view = view
        return query.pj_options(**kwargs)

    def pj_options(self, **kwargs):
        query = self
        for key, val in kwargs.items():
            query = getattr(query, f'_opt_{key}')(val)
        return query

    def _opt_loadonly(self, loadonly):
        if not loadonly:
            loadonly = self.pj_view.allowed_requested_query_columns.keys()
        return self.options(load_only(*loadonly))

    def pj_count(self):
        return self.count()

    def add_filtering(self):
        return self.pj_view.query_add_filtering(self)

    def add_relative_paging(self):
        query = self
        view = self.pj_view
        qinfo = QueryInfo(view.__class__, view.request)
        pinfo = qinfo.paging_info

        # We just add filters here. The necessary joins will have been done by the
        # Sorting that after relies on.
        # Need >= or <= on all but the last prop.
        if pinfo.start_type.endswith('_id'):
            before_after = self.before_after_from_id(qinfo, pinfo.item_id)
        else:
            before_after = pinfo.before_after
        for sinfo, after in zip(qinfo.sorting_info[:-1], before_after[:-1]):
            ascending = not sinfo.ascending if query._pj_reversed else sinfo.ascending
            if ascending:
                query = query.filter(sinfo.prop >= after)
            else:
                query = query.filter(sinfo.prop <= after)
        # And > or < on the last one.
        ascending = qinfo.sorting_info[-1].ascending
        ascending = not ascending if query._pj_reversed else ascending
        # first and last have empty before_afters
        if before_after:
            if ascending:
                query = query.filter(qinfo.sorting_info[-1].prop > before_after[-1])
            else:
                query = query.filter(qinfo.sorting_info[-1].prop < before_after[-1])

        return query

    def before_after_from_id(self, qinfo, item_id):
        item = self.pj_view.get_item(item_id)
        if not item:
            raise HTTPBadRequest(f'Could not find item with after_id {item_id}')
        vals = [self.get_prop_value(item, info) for info in qinfo.sorting_info]
        return vals

    def get_prop_value(self, item, prop_info):
        val = item
        for key in prop_info.colspec:
            val = getattr(val, key)
        return val

    def id_only(self):
        return self.options(load_only(self.pj_view.key_column.name))

    def iterate_paged(self, page_size=None):
        page_size = page_size or self.pj_view.query_info.paging_info.limit
        cur_query = self.limit(page_size)
        records_yielded = 0
        records_from_cur = 0
        while True:
            # Loop through records in a page:
            for record in cur_query:
                records_yielded += 1
                records_from_cur += 1
                yield record
            # End of a page
            if records_from_cur < page_size:
                break
            records_from_cur = 0
            cur_query = self.offset(records_yielded).limit(page_size)

class RQLQuery(BaseQuery, RQLQueryMixIn, PJQueryMixin):

    def _rql_ilike(self, args):
        attr, value = args

        attr = self._rql_attr(attr)
        value = self._rql_value(value, attr)
        value = value.replace("*", "%")

        return attr.ilike(value)

    def _rql_icontains(self, args):
        attr, value = args
        attr = self._rql_attr(attr)
        value = self._rql_value(value, attr)
        return attr.ilike(f'%{value}%')

    def _rql_isempty(self, args):
        attr = self._rql_attr(args[0])
        return attr.__eq__('')

    def _rql_isnull(self, args):
        attr = self._rql_attr(args[0])
        # None value translates to 'IS NULL'
        return attr.__eq__(None)

    def _rql_isnotempty(self, args):
        attr = self._rql_attr(args[0])
        return attr.__ne__('')

    def _rql_isnotnull(self, args):
        attr = self._rql_attr(args[0])
        # None value translates to 'IS NOT NULL'
        return attr.__ne__(None)

    def _rql_istrue(self, args):
        attr = self._rql_attr(args[0])
        return attr.__eq__(True)

    def _rql_isfalse(self, args):
        attr = self._rql_attr(args[0])
        return attr.__eq__(False)


# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.contrib import admin
from .models import Product, Provider, Purchase, Departure, Inventory, Brand
from .forms import DepartureForm, PurchaseForm, InventoryForm

# Register your models here.

@admin.register(Product)
class AdminProduct(admin.ModelAdmin):
    list_display = ['id_product', 'name_product', 'category', 'description']

@admin.register(Brand)
class AdminBrand(admin.ModelAdmin):
    list_display = ['id_brand', 'name_brand']

@admin.register(Provider)
class AdminProvider(admin.ModelAdmin):
    list_display = ['nit_provider', 'name_provider', 'address', 'category', 'level']

@admin.register(Purchase)
class AdminPurchase(admin.ModelAdmin):
    list_display = ['id_product', 'id_brand', 'quantity', 'cost', 'value_sale']
    form = PurchaseForm

@admin.register(Departure)
class AdminDeparture(admin.ModelAdmin):
    list_display = ['nom_product', 'id_brand', 'quantity', 'total']
    form = DepartureForm

@admin.register(Inventory)
class AdminInventory(admin.ModelAdmin):
    list_display = ['id_product', 'id_brand', 'quantity']
    form = InventoryForm

"""admin.site.register(Product, AdminProduct)
admin.site.register(Provider, AdminProduct)
admin.site.register(DetailProduct, AdminDetailProduct)
admin.site.register(DepartureInventory, AdminDepartureInventory)"""

"""admin.site.register(Product)
admin.site.register(Provider)
admin.site.register(DetailProduct)
admin.site.register(DepartureInventory)"""


from rest_framework import serializers
from .models import File

class FileListSerializer(serializers.Serializer) :
    user_id = serializers.IntegerField()
    name = serializers.CharField(max_length=50)
    one_file = serializers.ListField(
                       child=serializers.FileField( max_length=100000,
                                         allow_empty_file=False,
                                         use_url=False )
                                )

    def create(self, validated_data):
        user_id = validated_data.pop('user_id')
        name=validated_data.pop('name')

        one_file=validated_data.pop('one_file')
        for file in one_file:
            f = File.objects.create(user_id=user_id,name=name, one_file=file,**validated_data)
        return f

class FileSerializer(serializers.ModelSerializer):
    class Meta:
        model = File
        fields = '__all__'