import json
import sys
import torch
from transformers import *
from torch.utils.data import TensorDataset, DataLoader, RandomSampler, SequentialSampler
from keras.preprocessing.sequence import pad_sequences
import numpy as np
from torch import nn

sys.path.insert(0,'../')
sys.path.insert(0,'../../')

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
n_gpu = torch.cuda.device_count()

torch.manual_seed(0)
MAX_LEN = 256

import os
try:
    dir_path = os.path.dirname(os.path.abspath( __file__ ))
except:
    dir_path = '.'

dir_path = dir_path+'/..'

def get_enlu(self, token, pos):  # only_lu=True
    result = False

    p = False
    if pos == 'NN' or pos == 'NNS':
        p = 'n'
    elif pos.startswith('V'):
        p = 'v'
    elif pos.startswith('J'):
        p = 'a'
    else:
        p = False

    # lemmatize

    if p:
        lemma = self.lemmatizer.lemmatize(token, p)
        if lemma:
            #                 if lemma != 'be':
            if self.masking == True:
                for lu in self.targetdic:
                    lu_pos = lu.split('.')[-1]
                    if self.only_lu == True:
                        if p == lu_pos:
                            candi = self.targetdic[lu]
                            if lemma in candi:
                                result = lu
                            else:
                                pass
                    else:
                        candi = self.targetdic[lu]
                        if lemma in candi:
                            result = lu
                        else:
                            pass
            else:
                result = lemma + '.' + pos

    return result

class for_BERT():
    def __init__(self, srl='framenet', language='ko', fnversion=1.2, mode='train', masking=True, pretrained='bert-base-multilingual-cased', task='', use_definition=False, info=True):
        self.mode = mode
        self.masking = masking
        self.srl = srl
        self.definitions = None

        self.span2idx = {
            'X':0,
            'O':1,
            'B':2,
            'I':3
        }
        self.idx2span = dict(zip(self.span2idx.values(), self.span2idx.keys()))

        if 'multilingual' in pretrained:
            vocab_file_path = dir_path+'/data/bert-multilingual-cased-dict-add-tgt'
            self.tokenizer = BertTokenizer(vocab_file_path, do_lower_case=False, max_len=256)
            self.tokenizer.additional_special_tokens = ['<tgt>', '</tgt>', '<sp>']
        elif 'large' in pretrained:
            vocab_file_path = dir_path+'/data/bert-large-cased-dict-add-tgt'
            self.tokenizer = BertTokenizer(vocab_file_path, do_lower_case=False, max_len=256)
            self.tokenizer.additional_special_tokens = ['<tgt>', '</tgt>', '<sp>']
        else:
            vocab_file_path = dir_path+'/data/bert-multilingual-cased-dict-add-tgt'
            self.tokenizer = BertTokenizer(vocab_file_path, do_lower_case=False, max_len=256)
            self.tokenizer.additional_special_tokens = ['<tgt>', '</tgt>', '<sp>']

        if language == 'en':
            fnversion=1.7
            data_path = dir_path+'/koreanframenet/resource/info/fn'+str(fnversion)+'_'
        elif language == 'ko':
            data_path = dir_path+'/koreanframenet/resource/info/kfn'+str(fnversion)+'_'
            with open(dir_path + '/koreanframenet/data/1.2/used_FE.json', 'r') as f:
                self.used_fe = json.load(f)
        elif 'mul' in language:
            data_path = dir_path+'/koreanframenet/resource/info/mul_'
        else:
            data_path = dir_path+'/koreanframenet/resource/info/kfn'+str(fnversion)+'_'

        # lu dic = multilingual
        with open(data_path+'lu2idx.json','r') as f:
            self.lu2idx = json.load(f)
        self.idx2lu = dict(zip(self.lu2idx.values(),self.lu2idx.keys()))

        # frame, fe dic = FN1.7
        fname = dir_path+'/koreanframenet/resource/info/fn1.7_frame2idx.json'
        with open(fname,'r') as f:
            self.sense2idx = json.load(f)

        with open(data_path+'lufrmap.json','r') as f:
            self.lufrmap = json.load(f) # lu idx와 해당 lu가 속할 수 있는 frame indices.
            if language == "ko":
                self.lufrmap["5489"] = [x for x in range(len(self.sense2idx))]  # LU dict에 없는 애들
            else:
                self.lufrmap["10466"] = [x for x in range(len(self.sense2idx))]  # LU dict에 없는 애들

        with open(dir_path+'/koreanframenet/resource/info/fn1.7_fe2idx.json','r') as f:
            self.arg2idx = json.load(f)

        with open(dir_path+'/koreanframenet/resource/info/fn1.7_bio_fe2idx.json','r') as f:
            self.bio_arg2idx = json.load(f)  #각 FE에 대한 BI, O 태그 indices
        self.idx2bio_arg = dict(zip(self.bio_arg2idx.values(),self.bio_arg2idx.keys()))

        with open(dir_path+'/data/bio_arg2idx.json','r') as f:
            self.bio_argument2idx = json.load(f) # O, X, B-ARG, I-ARG
        self.idx2bio_argument = dict(zip(self.bio_argument2idx.values(),self.bio_argument2idx.keys()))

        with open(dir_path+'/data/framenet_info.json','r') as f:
            self.frame_info = json.load(f)

        with open(dir_path+'/koreanframenet/resource/info/fn1.7_frame_definitions.json','r') as f:
            self.frame_def = json.load(f)

        if language == 'en':
            frargmap_path = dir_path+'/koreanframenet/resource/info/fn1.7_bio_frargmap.json'
        else:
            frargmap_path = dir_path+'/koreanframenet/resource/info/mul_bio_frargmap.json'
            frargmap_path2 = dir_path + '/koreanframenet/resource/info/mul_frargmap.json'

        with open(frargmap_path,'r') as f:
            self.bio_frargmap = json.load(f)

        if language == 'ko':
            with open(frargmap_path2,'r') as f:
                self.frargmap = json.load(f)

        if info:
            print('used dictionary:')
            print('\t', data_path+'lu2idx.json')
            print('\t', data_path+'lufrmap.json')
            print('\t', frargmap_path)

        self.idx2sense = dict(zip(self.sense2idx.values(),self.sense2idx.keys()))
        self.idx2arg = dict(zip(self.arg2idx.values(),self.arg2idx.keys()))

        self.speaker2idx = {'seohee': 0, 'yijoon': 1, 'jeongsuk': 2, 'heeran': 3, 'haeyoung2': 4, 'jiya': 5, 'deogi': 6, 'soontack': 7, 'anna': 8, 'chairman': 9, 'gitae': 10, 'kyungsu': 11, 'hun':12, 'sukyung': 13, 'dokyung': 14, 'sangseok': 15, 'taejin': 16, 'sungjin': 17, 'jinsang': 18, 'haeyoung1': 19, 'none': 20}
        self.idx2speaker = dict(zip(self.speaker2idx.values(), self.speaker2idx.keys()))

        if use_definition:
            self.definitions = {}
            for k, v in self.frame_info.items():
                fes = v['fes']
                tokenized_fes = {}
                for fe_name, fe_v in fes.items():
                    orig_tokens, bert_tokens, orig_to_tok_map = self.bert_tokenizer(fe_v['definition'])
                    tokenized_fes[fe_name] = {
                        'tokens': bert_tokens,
                        'map': orig_to_tok_map
                    }
                self.definitions[k] = tokenized_fes

    def idx2tag(self, predictions, model='senseid'):
        if model == 'senseid':
            pred_tags = [self.idx2sense[p_i] for p in predictions for p_i in p]
        elif model == 'argid-dp':
            pred_tags = [self.idx2arg[p_i] for p in predictions for p_i in p]
        elif model == 'argid-span':
            pred_tags = [self.idx2bio_arg[p_i] for p in predictions for p_i in p]
        return pred_tags

    def bert_tokenizer(self, text, use_sp_token):
        orig_tokens = text.split(' ')
        bert_tokens = []
        orig_to_tok_map = []
        bert_tokens.append("[CLS]")
        for orig_token in orig_tokens:
            orig_to_tok_map.append(len(bert_tokens))
            bert_tokens.extend(self.tokenizer.tokenize(orig_token))
        if use_sp_token == 'sp':
            orig_to_tok_map.append(len(bert_tokens))  # sp 아니면 지워야함
            bert_tokens.append("<sp>")   # sp 아니면 지워야함.
        bert_tokens.append("[SEP]")

        return orig_tokens, bert_tokens, orig_to_tok_map

    def convert_to_bert_input_JointShallowSemanticParsing(self, input_data):
        tokenized_texts, lus, senses, args = [], [], [], []
        orig_tok_to_maps = []
        for i in range(len(input_data)):
            data = input_data[i]
            text = ' '.join(data[0])
            orig_tokens, bert_tokens, orig_to_tok_map = self.bert_tokenizer(text)

            orig_tok_to_maps.append(orig_to_tok_map)
            tokenized_texts.append(bert_tokens)

            ori_lus = data[1]
            lu_sequence = []
            for i in range(len(bert_tokens)):
                if i in orig_to_tok_map:
                    idx = orig_to_tok_map.index(i)
                    l = ori_lus[idx]
                    lu_sequence.append(l)
                else:
                    lu_sequence.append('_')
            lus.append(lu_sequence)

            if self.mode == 'train':
                ori_senses, ori_args = data[2], data[3]
                sense_sequence, arg_sequence = [], []
                for i in range(len(bert_tokens)):
                    if i in orig_to_tok_map:
                        idx = orig_to_tok_map.index(i)
                        fr = ori_senses[idx]
                        sense_sequence.append(fr)
                        ar = ori_args[idx]
                        arg_sequence.append(ar)
                    else:
                        sense_sequence.append('_')
                        arg_sequence.append('X')
                senses.append(sense_sequence)  # [_, _, _, frame_type, _, _, ..]
                args.append(arg_sequence)  # [X O X X,.. B-fe, I-fe, ...]

        input_ids = pad_sequences([self.tokenizer.convert_tokens_to_ids(txt) for txt in tokenized_texts],
                                  maxlen=MAX_LEN, dtype="long", truncating="post", padding="post")

        orig_tok_to_maps = pad_sequences(orig_tok_to_maps, maxlen=MAX_LEN, dtype="long", truncating="post",
                                         padding="post", value=-1)

        if self.mode == 'train':
            if self.srl == 'propbank-dp':
                arg_ids = pad_sequences([[self.arg2idx.get(ar) for ar in arg] for arg in args],
                                        maxlen=MAX_LEN, value=self.arg2idx["X"], padding="post",
                                        dtype="long", truncating="post")
            elif self.srl == 'framenet-argid':
                arg_ids = pad_sequences([[self.bio_argument2idx.get(ar) for ar in arg] for arg in args],
                                        maxlen=MAX_LEN, value=self.bio_argument2idx["X"], padding="post",
                                        dtype="long", truncating="post")
            else:
                arg_ids = pad_sequences([[self.bio_arg2idx.get(ar) for ar in arg] for arg in args],
                                        maxlen=MAX_LEN, value=self.bio_arg2idx["X"], padding="post",
                                        dtype="long", truncating="post")

        lu_seq, sense_seq = [], []
        for sent_idx in range(len(lus)):
            lu_items = lus[sent_idx]
            lu = []
            for idx in range(len(lu_items)):
                if lu_items[idx] != '_':
                    if len(lu) == 0:
                        if self.mode != 'train' and self.masking == False:
                            lu.append(1)
                        else:
                            lu.append(self.lu2idx[lu_items[idx]])

            lu_seq.append(lu)

            if self.mode == 'train':
                sense_items, arg_items = senses[sent_idx], args[sent_idx]
                sense = []
                for idx in range(len(sense_items)):
                    if sense_items[idx] != '_':
                        if len(sense) == 0:
                            sense.append(self.sense2idx[sense_items[idx]])
                sense_seq.append(sense)

        attention_masks = [[float(i > 0) for i in ii] for ii in input_ids]
        token_type_ids = [[0 if idx > 0 else 1 for idx in input_id] for input_id in input_ids]

        data_inputs = torch.tensor(input_ids)
        data_orig_tok_to_maps = torch.tensor(orig_tok_to_maps)
        data_lus = torch.tensor(lu_seq)
        data_token_type_ids = torch.tensor(token_type_ids)
        data_masks = torch.tensor(attention_masks)

        if self.mode == 'train':
            data_senses = torch.tensor(sense_seq)
            data_args = torch.tensor(arg_ids)
            bert_inputs = TensorDataset(data_inputs, data_orig_tok_to_maps, data_lus, data_senses, data_args,
                                        data_token_type_ids, data_masks)
        else:
            bert_inputs = TensorDataset(data_inputs, data_orig_tok_to_maps, data_lus, data_token_type_ids, data_masks)
        return bert_inputs

    def written_converter(self, input_data):
        tokenized_texts, orig_tok_to_maps, gold_args, targets, senses, speakers, special_tokens, bios, lus = [], [], [], [], [], [], [], [], []
        errors = 0
        for i in range(len(input_data)):
            data = input_data[i]
            text = ' '.join(data[0])
            scene_tokens = []
            scene_maps = []
            scene_special_tokens = []
            utter_speaker = []
            fe_spans = []

            orig_tokens, bert_tokens, orig_to_tok_map = self.bert_tokenizer(text)
            utter_speaker.append(-1)
            scene_tokens.append(bert_tokens)
            scene_maps.append(orig_to_tok_map)
            scene_special_tokens.append([0, len(bert_tokens) - 1])

            ori_lus = data[1]
            lu_sequence = []
            lu_ori_idx = [ii for ii, x in enumerate(ori_lus) if x != '_']
            try:
                lu_span = (0, orig_to_tok_map[lu_ori_idx[0]], orig_to_tok_map[lu_ori_idx[-1] + 1] - 1)
            except:
                lu_span = (0, orig_to_tok_map[lu_ori_idx[0]], len(bert_tokens) - 2)

            for i in range(len(bert_tokens)):
                if i in orig_to_tok_map:
                    idx = orig_to_tok_map.index(i)
                    l = ori_lus[idx]
                    lu_sequence.append(l)
                else:
                    lu_sequence.append('_')

            ori_senses, ori_args = data[2], data[3]
            sense_sequence, arg_sequence, span = [], [], []
            ar = 'O'
            for i in range(len(bert_tokens)):
                if i in orig_to_tok_map:
                    idx = orig_to_tok_map.index(i)
                    fr = ori_senses[idx]
                    sense_sequence.append(fr)
                    ar = ori_args[idx]
                    arg_sequence.append(ar)
                else:
                    sense_sequence.append('_')
                    if ar[0] == 'B':
                        arg_sequence.append('I' + ar[1:])
                    else:
                        arg_sequence.append(ar)

            bio = torch.ones(1, MAX_LEN).long()
            bio[0][orig_to_tok_map] = 0
            span = []
            label_list = []
            st, en, label = -1, -1, -1
            for ii, tag in enumerate(arg_sequence):
                if tag[0] == 'B' or tag[0] == 'O' or tag[0] == 'X':
                    if st != -1:
                        en = ii - 1
                        span.append((0, st, en, label))
                        label_list.append(label)

                        st = -1
                        en = -1
                if tag[0] == 'B':
                    st = ii
                    label = self.arg2idx[tag[2:]]
            if st != -1 and en == -1:
                en = len(bert_tokens) - 2
                span.append((0, st, en, label))
                label_list.append(label)

            if len(span) == 0:
                continue

            for uid, st, en, label in span:  # idx2arg, self.bio_arg2idx, idx2bio_arg
                label_str = self.idx2arg[label]
                bio[uid][st] = self.bio_arg2idx["B-{}".format(label_str)]
                bio[uid][st+1:en+1] = self.bio_arg2idx["I-{}".format(label_str)]

            for uid in range(1):
                cur_bio = bio[uid]
                cur_map = scene_maps[uid]
                for ii in range(256):
                    if ii not in cur_map:
                        cur_bio[ii] = 1    # [X O X X,.. B-fe, I-fe, ...]

            sense_items = sense_sequence
            sense = set()
            for idx in range(len(sense_items)):
                if sense_items[idx] != '_':
                    if len(sense) == 0:
                        sense.add(self.sense2idx[sense_items[idx]])  # frame type에 대한 index를 추가.
            sense = list(sense)
            is_error = False
            for ll in label_list:
                if ll not in self.frargmap[str(sense[0])]:
                    is_error = True
            if is_error:
                errors += 1
                continue

            text_bio = [self.idx2bio_arg[x.item()] for x in bio[0]]
            lu_idx = list(set([self.lu2idx[x] for x in ori_lus if x != '_']))

            senses += sense
            lus += lu_idx
            bios.append(bio)
            gold_args.append(span)
            orig_tok_to_maps.append(scene_maps)
            tokenized_texts.append(scene_tokens)
            targets.append(lu_span)
            speakers.append(utter_speaker)
            special_tokens.append(scene_special_tokens)

        if len(tokenized_texts) == 0:
            return None

        tokenized_ids = []
        for scene_txt in tokenized_texts:
            scene_ids = pad_sequences([self.tokenizer.convert_tokens_to_ids(txt) for txt in scene_txt], maxlen=MAX_LEN,
                                      dtype="long", truncating="post", padding="post")
            tokenized_ids.append(scene_ids)
        max_utter = np.max([tokenized.shape[0] for tokenized in tokenized_ids])  # 50
        utter_len = [tokenized.shape[0] for tokenized in tokenized_ids]
        input_ids = pad_sequences(tokenized_ids, maxlen=max_utter, dtype="long", truncating="post", padding="post")

        tensor_maps = []
        for scene_map in orig_tok_to_maps:
            map = pad_sequences(scene_map, maxlen=MAX_LEN, dtype="long", truncating="post",
                                padding="post", value=-1)
            tensor_maps.append(map)
        orig_tok_to_maps = pad_sequences(tensor_maps, maxlen=max_utter, dtype="long", truncating="post", padding="post",
                                         value=-1)
        special_tokens = pad_sequences(special_tokens, maxlen=max_utter, dtype="long", truncating="post",
                                       padding="post", value=-1)

        attention_masks = [[[float(i > 0) for i in ii] for ii in input_id] for input_id in input_ids]
        token_type_ids = [[[0 if idx > 0 else 1 for idx in input_id] for input_id in input] for input in input_ids]

        args_len = [len(arg) for arg in gold_args]
        gold_args = pad_sequences(gold_args,
                                  maxlen=20, value=(-1, -1, -1, -1), padding="post",
                                  dtype="long", truncating="post")  # start, end, fe index

        speaker_len = [len(speaker) for speaker in speakers]
        speakers = pad_sequences(speakers,
                                 maxlen=max_utter, value=-1, padding="post",
                                 dtype="long", truncating="post")  # start, end, fe index

        data_inputs = torch.tensor(input_ids)
        utter_len = torch.tensor(utter_len)
        data_orig_tok_to_maps = torch.tensor(orig_tok_to_maps)
        data_token_type_ids = torch.tensor(token_type_ids)
        data_masks = torch.tensor(attention_masks)
        bios = torch.stack(bios)

        gold_args = torch.tensor(gold_args)
        args_len = torch.tensor(args_len)
        targets = torch.tensor(targets)
        senses = torch.tensor(senses)
        lus = torch.tensor(lus)
        speakers = torch.tensor(speakers)
        speaker_len = torch.tensor(speaker_len)
        special_tokens = torch.tensor(special_tokens)

        bert_inputs = TensorDataset(data_inputs, utter_len, data_orig_tok_to_maps, data_token_type_ids, data_masks,
                                    targets,
                                    senses, gold_args, args_len, speakers, speaker_len, special_tokens, bios, lus)

        return bert_inputs

    def debug_lu(self, input_data):
        not_in_lu_dict = []
        n_instance = 0
        for scene_id, data in input_data.items():  # 172
            for instance in data['frames']:  # 20
                n_instance += 1
                lu = instance['lu']
                if lu not in self.lu2idx.keys():
                    not_in_lu_dict.append(lu)
        return not_in_lu_dict, n_instance

    def data_converter(self, input_data, tgt=False, lang='ko', only_lu_dict=True, use_sp_token=False):
        """ input_data : list of frame instance [#frame] """
        instance_ids = []
        total_num = 0
        long_txt = 0
        not_in_lu_dict = 0
        not_in_lufr_dict = 0
        made = 0
        err_flag = False
        tokenized_texts, orig_tok_to_maps, gold_args, targets, senses, speakers, special_tokens, bios, lus = [], [], [], [], [], [], [], [], []
        """
        tokenized_texts : list of utter token [#instance(frame), #max_utter, #token]
        orig_tok_to_maps : tokenized_texts에 대응하는 origin token, bert token map [#frame, #max_utter, ?]
        gold_args : list of fe span (fe가 발생한 utter_id, start, end, fe_id)  # [#frame, #fe, 4]
        targets : list of target span (utter id, start, end)  # [#frame, 3]
        senses : list of frame type id  [#frame]
        speakers : list of fe speaker  [#frame, #max_utter]  # scene내의 utter마다의 speakers
        """
        if lang[0] == 'k':
            utter_key = 'ko_utter'
        else:
            utter_key = 'plain'

        kk = list(self.lu2idx.keys())
        kk = [x.split('.')[-1] for x in kk]
        kk = list(set(kk))

        for scene_id, data in input_data.items():  # 172
            # if len(data['utterances']) > 10:
            #     continue
            for iid, instance in enumerate(data['frames']):
                total_num += 1
                scene_tokens = []
                scene_maps = []
                scene_special_tokens = []
                utter_speaker = []
                fe_spans = []
                # len(data['utterances'])
                lu_utter_id = int(instance['utter_id'].split('#')[-1])
                lu_ori_idx = instance['target_index']
                min_utter = max(0, lu_utter_id - 6)
                max_utter = min(len(data['utterances']) - 1, lu_utter_id + 4)
                constrant = list(range(min_utter, max_utter + 1))

                sense = self.sense2idx[instance['frame']]
                if tgt:
                    origin_utter = data['utterances'][lu_utter_id][utter_key]
                    origin_utter_word = origin_utter.split()
                    target_txt = [origin_utter_word[lu_ori_idx]]
                    tgted_target = " ".join(['<tgt>'] + target_txt + ['</tgt>'])
                    len_tgted_target = len([origin_utter_word[lu_ori_idx]]) + 2

                for uid, utter in enumerate(data['utterances']):
                    if tgt:
                        if uid == lu_utter_id:
                            origin_utter = data['utterances'][uid][utter_key]
                            origin_utter_word = origin_utter.split()
                            origin_utter_word = origin_utter_word[:lu_ori_idx] + ['<tgt>'] + [
                                origin_utter_word[lu_ori_idx]] + ['</tgt>'] + origin_utter_word[lu_ori_idx + 1:]
                            utter_txt = " ".join(origin_utter_word)
                        # elif uid < lu_utter_id:
                        #     utter_txt = utter[utter_key] + ' ' + tgted_target
                        # elif uid > lu_utter_id:
                        #     utter_txt = tgted_target + ' ' + utter[utter_key]
                        else:
                            utter_txt = utter[utter_key]

                    orig_tokens, bert_tokens, orig_to_tok_map = self.bert_tokenizer(utter_txt, use_sp_token)
                    utter_speaker.append(self.speaker2idx[utter['speaker']])
                    scene_tokens.append(bert_tokens)
                    scene_maps.append(orig_to_tok_map)
                    scene_special_tokens.append([0, len(bert_tokens) - 1])

                if max([max(map) for map in scene_maps]) > 255:
                    long_txt += 1
                    break

                bio = torch.ones(len(data['utterances']), MAX_LEN).long()
                for uid in range(len(data['utterances'])):
                    bio[uid][scene_maps[uid]] = 0

                lu_map = scene_maps[lu_utter_id]
                try:
                    lu_span = (lu_utter_id, lu_map[lu_ori_idx+1], lu_map[lu_ori_idx+2]-1)
                except:
                    lu_span = (lu_utter_id, lu_map[lu_ori_idx+1], len(scene_tokens[lu_utter_id])-2)

                # print(instance['lu'])
                # print(scene_tokens[lu_span[0]][lu_span[1]:lu_span[2]+1])

                fes = instance['elements']
                for fe_name, fe_info in fes.items():
                    if fe_name not in self.arg2idx.keys():
                        continue
                    fe_id = self.arg2idx[fe_name]
                    fe_idx = fe_info['idx']
                    if fe_idx[0] == -1:
                        continue
                    if fe_info['utter_id'][-1] != "r": # type: utter
                        fe_utter_id = int(fe_info['utter_id'].split('#')[-1])
                        fe_map = scene_maps[fe_utter_id]

                        for ii, fe_i in enumerate(fe_idx):
                            if fe_utter_id == lu_utter_id:
                                if fe_i > lu_ori_idx:
                                    fe_idx[ii] = fe_i + 2
                                elif fe_i == lu_ori_idx:
                                    fe_idx[ii] = fe_i + 1
                            # if fe_utter_id > lu_utter_id:
                            #     fe_idx[ii] += len_tgted_target

                        try:
                            fe_span = (fe_utter_id, fe_map[fe_idx[0]], fe_map[fe_idx[-1] + 1] - 1, fe_id)
                        except:
                            try:
                                if use_sp_token == 'sp':
                                    fe_span = (fe_utter_id, fe_map[fe_idx[0]], len(scene_tokens[fe_utter_id]) - 3, fe_id) #sp 아니면 -3 -> -2
                                else:
                                    fe_span = (fe_utter_id, fe_map[fe_idx[0]], len(scene_tokens[fe_utter_id]) - 2,
                                               fe_id)  # sp 아니면 -3 -> -2
                            except:
                                continue
                    else:  # speaker
                        candidates = []
                        for s_i, sp in enumerate(utter_speaker):

                            try:
                                a = self.speaker2idx[fe_info['text']]
                            except:
                                print(instance)

                            try:
                                a = self.speaker2idx[fe_info['text']]
                            except:
                                print(instance)

                            if self.speaker2idx[fe_info['text']] == sp:
                                candidates.append(s_i)
                        # candidates와 lu_utter_id와 가장 가까운 애를 찾아야함.
                        min_diff = 10000
                        nearest_utter_id = -1
                        for c in candidates:
                            diff = abs(c-lu_utter_id)
                            if min_diff > diff:
                                min_diff = diff
                                nearest_utter_id = c
                        fe_utter_id = nearest_utter_id
                        # fe_span = (fe_utter_id, 0, 0, fe_id)  # CLS token 사용
                        if use_sp_token == 'sp':
                            fe_span = (fe_utter_id, len(scene_tokens[fe_utter_id]) - 2, len(scene_tokens[fe_utter_id]) - 2, fe_id)  # SEP 사용 #sp 토큰 아니면 -2, -2 -> -1 -1
                        elif use_sp_token == 'cls':
                            fe_span = (fe_utter_id, 0, 0, fe_id)
                        else:
                            fe_span = (
                            fe_utter_id, len(scene_tokens[fe_utter_id]) - 1, len(scene_tokens[fe_utter_id]) - 1, fe_id)  # SEP 사용 #sp 토큰 아니면 -2, -2 -> -1 -1
                    a,b,c,d = fe_span

                    # print(lu_utter_id, a)
                    # print(fe_info)
                    # print(scene_tokens[a][b:c + 1], d)
                    # print()

                    fe_spans.append(fe_span)

                for uid, st, en, label in fe_spans:  # idx2arg, self.bio_arg2idx, idx2bio_arg
                    if st > 255:
                        continue
                    if en > 255:
                        continue
                    label_str = self.idx2arg[label]
                    bio[uid][st] = self.bio_arg2idx["B-{}".format(label_str)]
                    for ii in range(st+1, en+1):
                        if ii in scene_maps[uid]:
                            bio[uid][ii] = self.bio_arg2idx["I-{}".format(label_str)]

                if instance['lu'] not in self.lu2idx.keys():
                    # print(instance['lu'])
                    if lang == 'ko':
                        not_in_lu_dict += 1
                        continue
                    else:

                        # TODO get_enlu로 고치기.

                        token, pos = instance['lu'].split('.')
                        instance['lu'] = get_enlu(token, pos)

                    try:
                        lu_idx = self.lu2idx[instance['lu']]   # lu 사전에 없는애들이 발생하면 거르자..
                    except:
                        not_in_lu_dict += 1
                        continue

                text_bio = [[self.idx2bio_arg[x.item()] for x in b] for b in bio]
                lu_idx = self.lu2idx[instance['lu']]
                if sense not in self.lufrmap[str(lu_idx)]:  # 이거도 사전 업데이트를 해야함.
                    not_in_lufr_dict += 1
                    continue

                if constrant != list(range(len(data['utterances']))):
                    mapper = {}

                    for ii, val in enumerate(constrant):
                        mapper[val] = ii
                    bio = bio[constrant]

                    fe_spans = [(mapper[a],b,c,d) for (a,b,c,d) in fe_spans if a in constrant]
                    scene_maps = [map for ii, map in enumerate(scene_maps) if ii in constrant]
                    scene_tokens = [toks for ii, toks in enumerate(scene_tokens) if ii in constrant]
                    lu_span = (mapper[lu_span[0]], lu_span[1], lu_span[2])
                    utter_speaker = [sp for ii, sp in enumerate(utter_speaker) if ii in constrant]
                    scene_special_tokens = [toks for ii, toks in enumerate(scene_special_tokens) if ii in constrant]

                made += 1
                lus.append(lu_idx)
                bios.append(bio)
                senses.append(sense)
                gold_args.append(fe_spans) # fe_utter_id, st, en, fe_id
                orig_tok_to_maps.append(scene_maps)
                tokenized_texts.append(scene_tokens)
                targets.append(lu_span)
                speakers.append(utter_speaker)
                special_tokens.append(scene_special_tokens)

                # scene_id, iid 섞어만들기
                ep_id, s_id = scene_id.split('_')[:-1]
                ep_id = int(ep_id[-2:])
                s_id = int(s_id)
                instance_id = ep_id*10000000 + s_id*10000 + iid  # 00 000 0000 ep_id, scene_id, frame_id
                instance_ids.append(instance_id)

            if err_flag:
                err_flag = False
                break

        print("total instance: {}".format(total_num))
        print("not found LU in LU dict: {}".format(not_in_lu_dict))
        print("not found Frame in lufr dict: {}".format(not_in_lufr_dict))
        print("long_txt: {}".format(long_txt))
        print("input instance: {}".format(made))
        if len(tokenized_texts) == 0:
            return None

        tokenized_ids = []
        for scene_txt in tokenized_texts:
            scene_ids = pad_sequences([self.tokenizer.convert_tokens_to_ids(txt) for txt in scene_txt], maxlen=MAX_LEN, dtype="long", truncating="post", padding="post")
            tokenized_ids.append(scene_ids)
        max_utter = np.max([tokenized.shape[0] for tokenized in tokenized_ids])  # 50
        utter_len = [tokenized.shape[0] for tokenized in tokenized_ids]
        input_ids = pad_sequences(tokenized_ids, maxlen=max_utter, dtype="long", truncating="post", padding="post")

        tensor_maps = []
        for scene_map in orig_tok_to_maps:
            map = pad_sequences(scene_map, maxlen=MAX_LEN, dtype="long", truncating="post",
                                         padding="post", value=-1)
            tensor_maps.append(map)
        orig_tok_to_maps = pad_sequences(tensor_maps, maxlen=max_utter, dtype="long", truncating="post", padding="post", value=-1)
        tensor_bios = pad_sequences(bios, maxlen=max_utter, dtype="long", truncating="post", padding="post", value=-1)
        special_tokens = pad_sequences(special_tokens, maxlen=max_utter, dtype="long", truncating="post", padding="post", value=-1)

        attention_masks = [[[float(i > 0) for i in ii] for ii in input_id] for input_id in input_ids]
        token_type_ids = [[[0 if idx > 0 else 1 for idx in input_id] for input_id in input] for input in input_ids]

        args_len = [len(arg) for arg in gold_args]
        gold_args = pad_sequences(gold_args,
                                   maxlen=20, value=(-1, -1, -1, -1), padding="post",
                                   dtype="long", truncating="post")  # start, end, fe index

        speaker_len = [len(speaker) for speaker in speakers]
        speakers = pad_sequences(speakers,
                                  maxlen=max_utter, value=-1, padding="post",
                                  dtype="long", truncating="post")  # start, end, fe index

        data_inputs = torch.tensor(input_ids)
        utter_len = torch.tensor(utter_len)
        data_orig_tok_to_maps = torch.tensor(orig_tok_to_maps)
        data_token_type_ids = torch.tensor(token_type_ids)
        data_masks = torch.tensor(attention_masks)

        lus = torch.tensor(lus)
        gold_args = torch.tensor(gold_args)
        args_len = torch.tensor(args_len)
        targets = torch.tensor(targets)
        senses = torch.tensor(senses)
        speakers = torch.tensor(speakers)
        speaker_len = torch.tensor(speaker_len)
        special_tokens = torch.tensor(special_tokens)
        tensor_bios = torch.tensor(tensor_bios)
        instance_ids = torch.tensor(instance_ids)

        bert_inputs = TensorDataset(data_inputs, utter_len, data_orig_tok_to_maps, data_token_type_ids, data_masks, targets,
                                    senses, gold_args, args_len, speakers, speaker_len, special_tokens, tensor_bios, lus, instance_ids)

        return bert_inputs

def get_masks(datas, mapdata, num_label=2, masking=True):  # datas : lus [bsz, 1]
    masks = []
    with torch.no_grad():
        if masking == True:
            for idx in datas:
                torch.cuda.set_device(0)
                indx = idx.item()
                mask = torch.zeros(num_label)
                candis = mapdata[str(indx)]  # 해당 lu가 가질 수 있는 frame type indices.
                for candi_idx in candis:
                    mask[candi_idx] = 1
                masks.append(mask)
        else:
            for idx in datas:
                mask = torch.ones(num_label)
                masks.append(mask)
    masks = torch.stack(masks)
    return masks

def masking_logit(logit, mask):
    with torch.no_grad():
        if type(logit) is np.ndarray:
            pass
        else:
            logit = logit.cpu().numpy()
        mask = mask.cpu().numpy()
        masking = np.multiply(logit, mask)
    masking[masking==0] = np.NINF
    masking = torch.tensor(masking)
    return masking

def probs2idx(probs):
    return None

def logit2pos(start_logit, end_logit):
    sm = nn.Softmax()
    st_logits = sm(start_logit).view(1, -1)
    en_logits = sm(end_logit).view(1, -1)
    score, st = st_logits.max(1)
    score, en = en_logits.max(1)
    return int(st), int(en)

def logit2span(logit):
    """ 'X':0, 'O':1, 'B':2, 'I':3 """
    pred_bio = torch.argmax(logit, dim=1)  # [tok_len]
    in_span = False
    st, en = -1, -1
    span = []
    for i, x in enumerate(pred_bio):
        if x == 2:  # B
            if in_span == True:  # 직전까지를 span으로 결정.
                en = i - 1
                span.append((st, en))
            # 새로운 span 생성.
            in_span = True
            st = i
        if x == 0 or x == 1:  # X or O
            if in_span:  # 직전까지를 span으로 결정.
                en = i - 1
                in_span = False
                span.append((st, en))
        elif (i == len(logit) - 1) and in_span:
            en = i
            span.append((st, en))
    return span

def logit2label(masked_logit):
    sm = nn.Softmax()
    pred_logits = sm(masked_logit).view(1,-1)
    score, label = pred_logits.max(1)
    score = float(score)

    return label, score

def logit2candis(masked_logit, candis=1, idx2label=False):
    sm = nn.Softmax()
    pred_logits = sm(masked_logit).view(1,-1)

    logit_len = pred_logits.size()[-1]
    if candis >= logit_len:
        candis = logit_len

    scores, labels = pred_logits.topk(candis)

    candis = []
    for i in range(len(scores[0])):
        score = round(float(scores[0][i]),4)
        idx = int(labels[0][i])
        if idx2label:
            label = idx2label[idx]
        else:
            label = idx

        candi = (label, score)
        candis.append(candi)

    return candis

def get_tgt_idx(bert_tokens, tgt=False):
    tgt_idx = []
    try:
        if tgt == False:
            for i in range(len(bert_tokens)):
                if bert_tokens[i] == '<':
                    if bert_tokens[i+1] == 't' and bert_tokens[i+2] == '##gt' and bert_tokens[i+3] == '>':
                        tgt_idx.append(i)
                        tgt_idx.append(i+1)
                        tgt_idx.append(i+2)
                        tgt_idx.append(i+3)
                    elif bert_tokens[i+1] == '/' and bert_tokens[i+2] == 't' and bert_tokens[i+3] == '##gt' and bert_tokens[i+4] == '>':
                        tgt_idx.append(i)
                        tgt_idx.append(i+1)
                        tgt_idx.append(i+2)
                        tgt_idx.append(i+3)
                        tgt_idx.append(i+4)
        else:
            tgt_token_list = ['<tgt>', '</tgt>']
            for i in range(len(bert_tokens)):
                if bert_tokens[i] in tgt_token_list:
                    tgt_idx.append(i)
    except KeyboardInterrupt:
        raise
    except:
        pass

    return tgt_idx

# 파일 이름으로 json 로드(utf-8만 해당)
def jsonload(fname, encoding="utf-8"):
    with open(fname, encoding=encoding) as f:
        j = json.load(f)
    return j

# json 개체를 파일이름으로 깔끔하게 저장
def jsondump(j, fname):
    with open(fname, "w", encoding="UTF8") as f:
        json.dump(j, f, ensure_ascii=False, indent="\t")


# %%
import sqlite3
from pathlib import Path
from typing import Any, Dict, List

from graphnet.utilities.logging import get_logger
from icecube.constants import *

logger = get_logger(log_folder=log_dir)

import numpy as np
import pandas as pd
import torch
from pytorch_lightning.callbacks import (EarlyStopping, LearningRateMonitor,
                                         ModelCheckpoint)
from pytorch_lightning.loggers import WandbLogger
from pytorch_lightning.profiler import SimpleProfiler
from sklearn.model_selection import KFold
from torch.optim import SGD
from tqdm import tqdm

from graphnet.data.constants import FEATURES, TRUTH
from graphnet.models import StandardModel
from graphnet.models.detector.icecube import IceCubeKaggle
from graphnet.models.gnn import DynEdge
from graphnet.models.graph_builders import KNNGraphBuilder
from graphnet.models.task.reconstruction import \
    DirectionReconstructionWithKappa
from graphnet.training.callbacks import PiecewiseLinearLR, ProgressBar
from graphnet.training.labels import Direction
from graphnet.training.loss_functions import VonMisesFisher3DLoss
from graphnet.training.utils import make_dataloader

torch.set_float32_matmul_precision("high")

PULSEMAP = "pulse_table"
DATABASE_PATH = database_dir / "batch_51_100.db"
# DATABASE_PATH = "/media/eden/sandisk/projects/icecube/input/sqlite/batch_1.db"
PULSE_THRESHOLD = 400
SEED = 42

# Training configs
MAX_EPOCHS = 100
LR = 5e-4
MOMENTUM = 0.9
BS = 256
ES = 10
NUM_FOLDS = 5
NUM_WORKERS = 16

# Paths
FOLD_PATH = input_dir / "folds"
COUNT_PATH = FOLD_PATH / "batch51_100_counts.csv"
CV_PATH = FOLD_PATH / f"batch51_100_cv_max_{PULSE_THRESHOLD}_pulses.csv"
WANDB_DIR = log_dir
PROJECT_NAME = "icecube"
GROUP_NAME = "pretrain_sub_5_batch_51_100_large_resume"

CREATE_FOLDS = False

def make_selection(
    df: pd.DataFrame, num_folds: int = 5, pulse_threshold: int = 200
) -> None:
    """Creates a validation and training selection (20 - 80). All events in both selections satisfies n_pulses <= 200 by default."""
    n_events = np.arange(0, len(df), 1)
    df["fold"] = 0

    kf = KFold(n_splits=num_folds, shuffle=True, random_state=SEED)
    for i, (_, val_idx) in enumerate(kf.split(n_events)):
        df.loc[val_idx, "fold"] = i

    # Remove events with large pulses from training and validation sample (memory)
    df["fold"][df["n_pulses"] > pulse_threshold] = -1

    df.to_csv(CV_PATH)
    return

def get_number_of_pulses(db: Path, event_id: int, pulsemap: str) -> int:
    with sqlite3.connect(str(db)) as con:
        query = f"select event_id from {pulsemap} where event_id = {event_id} limit 20000"
        data = con.execute(query).fetchall()
    return len(data)

def count_pulses(database: Path, pulsemap: str) -> pd.DataFrame:
    """Will count the number of pulses in each event and return a single dataframe that contains counts for each event_id."""
    with sqlite3.connect(str(database)) as con:
        query = "select event_id from meta_table"
        events = pd.read_sql(query, con)
    counts = {"event_id": [], "n_pulses": []}

    for event_id in tqdm(events["event_id"]):
        a = get_number_of_pulses(database, event_id, pulsemap)
        counts["event_id"].append(event_id)
        counts["n_pulses"].append(a)

    df = pd.DataFrame(counts)
    df.to_csv(COUNT_PATH)
    return df

def build_model(
    config: Dict[str, Any], train_dataloader: Any
) -> StandardModel:
    """Builds GNN from config"""
    # Building model
    detector = IceCubeKaggle(
        graph_builder=KNNGraphBuilder(nb_nearest_neighbours=8),
    )
    gnn = DynEdge(
        nb_inputs=detector.nb_outputs,
        global_pooling_schemes=["min", "max", "mean"],
    )

    if config["target"] == "direction":
        task = DirectionReconstructionWithKappa(
            hidden_size=gnn.nb_outputs,
            target_labels=config["target"],
            loss_function=VonMisesFisher3DLoss(),
        )
        prediction_columns = [
            config["target"] + "_x",
            config["target"] + "_y",
            config["target"] + "_z",
            config["target"] + "_kappa",
        ]
        additional_attributes = ["zenith", "azimuth", "event_id"]

    model = StandardModel(
        detector=detector,
        gnn=gnn,
        tasks=[task],
        optimizer_class=SGD,
        optimizer_kwargs={
            "lr": LR,
            "momentum": MOMENTUM,
            "nesterov": True,
        },
        scheduler_class=PiecewiseLinearLR,
        scheduler_kwargs={
            "milestones": [
                0,
                len(train_dataloader) / 2,
                len(train_dataloader) * config["fit"]["max_epochs"],
            ],
            "factors": [1e-03, 1, 1e-03],
        },
        scheduler_config={
            "interval": "step",
        },
    )
    model.prediction_columns = prediction_columns
    model.additional_attributes = additional_attributes

    return model

def load_pretrained_model(
    config: Dict[str, Any],
    state_dict_path: str = "/kaggle/input/dynedge-pretrained/dynedge_pretrained_batch_1_to_50/state_dict.pth",
) -> StandardModel:
    train_dataloader, _ = make_dataloaders(config=config)
    model = build_model(config=config, train_dataloader=train_dataloader)
    # model._inference_trainer = Trainer(config['fit'])
    state_dict = torch.load(state_dict_path)["state_dict"]
    model.load_state_dict(state_dict)
    model.prediction_columns = [
        config["target"] + "_x",
        config["target"] + "_y",
        config["target"] + "_z",
        config["target"] + "_kappa",
    ]
    model.additional_attributes = ["zenith", "azimuth", "event_id"]
    return model

def make_dataloaders(config: Dict[str, Any], fold: int = 0) -> List[Any]:
    """Constructs training and validation dataloaders for training with early stopping."""
    df_cv = pd.read_csv(CV_PATH)

    val_idx = (
        df_cv[df_cv["fold"] == fold][config["index_column"]].ravel().tolist()
    )
    train_idx = (
        df_cv[~df_cv["fold"].isin([-1, fold])][config["index_column"]]
        .ravel()
        .tolist()
    )

    train_dataloader = make_dataloader(
        db=config["path"],
        selection=train_idx,
        pulsemaps=config["pulsemap"],
        features=FEATURES.KAGGLE,
        truth=TRUTH.KAGGLE,
        batch_size=config["batch_size"],
        num_workers=config["num_workers"],
        shuffle=True,
        labels={"direction": Direction()},
        index_column=config["index_column"],
        truth_table=config["truth_table"],
    )

    validate_dataloader = make_dataloader(
        db=config["path"],
        selection=val_idx,
        pulsemaps=config["pulsemap"],
        features=FEATURES.KAGGLE,
        truth=TRUTH.KAGGLE,
        batch_size=config["batch_size"],
        num_workers=config["num_workers"],
        shuffle=False,
        labels={"direction": Direction()},
        index_column=config["index_column"],
        truth_table=config["truth_table"],
    )

    return train_dataloader, validate_dataloader

def convert_to_3d(df: pd.DataFrame) -> pd.DataFrame:
    """Converts zenith and azimuth to 3D direction vectors"""
    df["true_x"] = np.cos(df["azimuth"]) * np.sin(df["zenith"])
    df["true_y"] = np.sin(df["azimuth"]) * np.sin(df["zenith"])
    df["true_z"] = np.cos(df["zenith"])
    return df

def calculate_angular_error(df: pd.DataFrame) -> pd.DataFrame:
    """Calcualtes the opening angle (angular error) between true and reconstructed direction vectors"""
    df["angular_error"] = np.arccos(
        df["true_x"] * df["direction_x"]
        + df["true_y"] * df["direction_y"]
        + df["true_z"] * df["direction_z"]
    )
    return df

# %%
config = {
    "inference_database_path": "/media/eden/sandisk/projects/icecube/input/sqlite/test_batch_641_660.db",
    "path": str(DATABASE_PATH),
    "pulsemap": "pulse_table",
    "truth_table": "meta_table",
    "features": FEATURES.KAGGLE,
    "truth": TRUTH.KAGGLE,
    "index_column": "event_id",
    "batch_size": BS,
    "num_workers": NUM_WORKERS,
    "target": "direction",
    "run_name_tag": "batch_1_50",
    "early_stopping_patience": ES,
    "fit": {
        "max_epochs": MAX_EPOCHS,
        "gpus": [0],
        "distribution_strategy": None,
        "limit_train_batches": 0.1,  # debug
        "limit_val_batches": 0.1,
    },
    "base_dir": "training",
    "wandb": {
        "project": PROJECT_NAME,
        "group": GROUP_NAME,
    },
    "lr": LR,
}

# %%
ckpt = "/media/eden/sandisk/projects/icecube/models/graphnet/ft_graphnet_50_100.ckpt"

# %%
run_name = f"dynedge_{config['target']}_{config['run_name_tag']}"

model = load_pretrained_model(config, state_dict_path=ckpt)

test_dataloader = make_dataloader(
    db = config['inference_database_path'],
    selection = None, # Entire database
    pulsemaps = config['pulsemap'],
    features = config["features"],
    truth = config["truth"],
    batch_size = config['batch_size'],
    num_workers = config['num_workers'],
    shuffle = False,
    labels = {'direction': Direction()},
    index_column = config['index_column'],
    truth_table = config['truth_table'],
)

# %%
from torchmetrics import Metric

class MeanAngularError(Metric):
    def __init__(self):
        super().__init__()
        self.add_state(
            "err",
            default=torch.tensor(0.0, dtype=torch.float32),
            dist_reduce_fx="sum",
        )
        self.add_state(
            "total",
            default=torch.tensor(0, dtype=torch.long),
            dist_reduce_fx="sum",
        )

    def update(self, preds: torch.Tensor, target: torch.Tensor):
        if preds.size(1) > target.size(1):
            preds = preds[:, : target.size(1)]

        assert (
            preds.shape == target.shape
        ), f"preds in size {preds.shape} doesn't match target in size {target.shape}"

        rt = torch.linalg.vector_norm(target, dim=-1, keepdim=True)
        rp = torch.linalg.vector_norm(preds, dim=-1, keepdim=True)

        target = target / rt
        preds = preds / rp

        err = torch.arccos(
            target[:, 0] * preds[:, 0]
            + target[:, 1] * preds[:, 1]
            + target[:, 2] * preds[:, 2]
        )

        err = torch.clip(err, 0, 2*torch.pi)

        self.err += err.sum()
        self.total += preds.size(0)

    def compute(self):
        return self.err.item() / self.total.item()

# %%
model = model.to("cuda").eval()
mae = MeanAngularError()

# %%
model.predict_as_dataframe(
    dataloader=test_dataloader,
    gpus=[0],
    prediction_columns=model.prediction_columns,
    additional_attributes=model.additional_attributes,
)

# %%


from PIL import Image
import cv2
import os
#os.system('export GOOGLE_APPLICATION_CREDENTIALS="/home/manas/Desktop/Friday/Django_Server/Raspberry_server_django/APIs/Python_APIs/Friday-d95a615e29fd.json"')
#import subprocess
#command = 'export GOOGLE_APPLICATION_CREDENTIALS="/home/manas/Desktop/Friday/Django_Server/Raspberry_server_django/APIs/Python_APIs/Friday-d95a615e29fd.json"'
#res = subprocess.check_output(['bash','-c', command])
def detect_document(path):
	global resultString
	"""Detects document features in an image."""
	from google.cloud import vision
	import io
	client = vision.ImageAnnotatorClient()
	with io.open(path, 'rb') as image_file:
		content = image_file.read()
	image = vision.types.Image(content=content)
	response = client.document_text_detection(image=image)
	for page in response.full_text_annotation.pages:
		for block in page.blocks:
			print('\nBlock confidence: {}\n'.format(block.confidence))

			for paragraph in block.paragraphs:
				print('Paragraph confidence: {}'.format(
					paragraph.confidence))
				for word in paragraph.words:
					word_text = ''.join([
						symbol.text for symbol in word.symbols
					])
					resultString += word_text+"#"
					print(word_text)
					print('Word text: {} (confidence: {})'.format(
						word_text, word.confidence))
	if response.error.message:
		raise Exception(
			'{}\nFor more info on error messages, check: '
			'https://cloud.google.com/apis/design/errors'.format(
				response.error.message))

	import os
	os.remove("live.jpeg")
	print("File Removed!")

resultString = str()
camera = cv2.VideoCapture(0)
return_value, image = camera.read()
file = 'live.jpeg'
cv2.imwrite(file, image)
detect_document("live.jpeg")
print('ans = '+resultString)


import pytest
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from pages.onboard_landing import OnboardLanding
import time

def test_correct_landing():
    driver = webdriver.Chrome()
    landing_page = OnboardLanding(driver)
    driver.get('https://onboard.henrymeds.com/')
    page_title = "Phentermine Appointment - Henry Meds"
    assert page_title == driver.title
    driver.quit()

def test_successful_click_to_schedule_page():
    driver = webdriver.Chrome()
    landing_page = OnboardLanding(driver)
    driver.get('https://onboard.henrymeds.com/')
    time.sleep(1)
    landing_page.click_utah_button()
    assert driver.current_url == "https://onboard.henrymeds.com/?state=utah"
    driver.quit()

def test_happypath():
    driver = webdriver.Chrome()
    landing_page = OnboardLanding(driver)
    driver.get('https://onboard.henrymeds.com/')
    time.sleep(1)
    landing_page.click_utah_button()
    landing_page.click_time_slot_button()
    assert landing_page.provider_continue_button

    landing_page.click_provider_continue_button()
    landing_page.enter_first_name("foo")
    landing_page.enter_last_name("bar")
    landing_page.enter_email("foobar@mail.com")
    landing_page.enter_dob("12/25/1975")
    landing_page.enter_phone_number("(555) 255-7310")
    landing_page.select_sex()
    landing_page.select_pronouns()
    landing_page.click_details_continue()
    landing_page.enter_address1("123 my street")
    landing_page.enter_city("Sandy")
    landing_page.ender_zip("84043")
    landing_page.click_continue_to_billing

    driver.quit()


from django import forms
from django.forms import ModelForm
from .models import Personaje
from django.utils.translation import gettext_lazy as _

#Crear un formulario para añadir personajes
class PersonajeForm(ModelForm):
    class Meta:
        model = Personaje
        fields = ("raza", "peliculas", "nombre", "genero", "colorOjos", "colorPelo", "estatura", "imagen")
        labels = {
            'raza': _('Raza del Personaje'),
            'peliculas': _('Peliculas en las que ha aparecido'),
            'nombre': _('Nombre del Personaje'),
            'genero': _('Genero del Personaje'),
            'colorOjos': _('Color de ojos'),
            'colorPelo': _('Color de pelo'),
            'estatura': _('Estatura en cm'),
            'imagen': _('Imagen')}


#!/usr/bin/env python3
import numpy as np
import math
from latqcdtools.plotting import *
from latqcdtools.readin import *
import matplotlib.pyplot as plt
import argparse

parser = argparse.ArgumentParser()
parser.add_argument('filename')
parser.add_argument('--nt', '-nt', type = int, dest = "nt", default = -1)
parser.add_argument('--nbins', '-nbins', type = int, dest = "nbins", default = None)
parser.add_argument('--title', dest = "title", default = None)
parser.add_argument('--col', '-col', type = int, dest = "col", default = 2)
parser.add_argument('--logx', action = 'store_true')
parser.add_argument('--out-name', dest = 'out_name', default = 'hist.pdf')
parser.add_argument('--show-plot', dest = 'show_plot', action = 'store_true')
args = parser.parse_args()

if args.nt != -1:
    xdata, data, nconfs = read_in_pure(args.filename, 1, args.col, symmetrize = False)
    nt = args.nt
    index = list(xdata).index(nt)
    data = data[index]
else:
    data = np.loadtxt(args.filename)
    try:
        data[0][0]
        data = data.transpose()[args.col - 1]
    except (ValueError, IndexError):
        pass

latexify()
plot_hist(data, args.logx, args.nbins)

set_params(title = args.title)

plt.savefig(args.out_name)

if args.show_plot:
    plt.show()


"""
Definition of views.
"""

from django.shortcuts import render
from django.http import HttpRequest
from django.template import RequestContext
from django.http import JsonResponse

from pydap.client import open_url
from datetime import date, datetime, timedelta;
import json
import requests
import urllib.request
import urllib3
import os

def plotter(request):
    # Renders plotting tool page

    return render(
        request,
        'app/plotter.html', {'req_data': {}}
    )

def plotter_get(request):
    # Renders plotting tool page

    return render(
        request,
        'app/plotter.html', {'req_data': json.dumps(request.GET.dict()) }
    )

#==================================================================================
#-  AJAX URLs
#==================================================================================

def getTSData(request):

    flag = 'fast'

    if (flag == 'fast'):
        dct_response = getTSData_fast(request)
    else:
        dct_response = getTSData_slow(request)

    return JsonResponse(dct_response, safe=False)

#------------------------------------------------------------
#-  Retrieve time series data via OPeNDAP request for aggregated data:
#------------------------------------------------------------
def getTSData_fast(request):

    # Pydap Docs: http://pydap.readthedocs.io/en/latest/client.html

    # Initialize dictionary for JSON response:
    dct_response = {}
    ncFlag = True          #Flag indicating that data was read from netCDF file

    #--------------------------------------------------------
    # Retrieve input data from POST request:
    #--------------------------------------------------------
    dct_request = request.POST.dict()

    data_type = dct_request['data_type'] #request.POST['data_type']

    lst_locs = request.POST.getlist('loc_arr[]')
    dct_owners = json.loads(dct_request['owners'])

    lst_params = request.POST.getlist('param_arr[]')

    # Start & end date/time:
    str_date1 = dct_request['date_start']
    str_date2 = dct_request['date_end']

    date_start = datetime.strptime(str_date1, '%m/%d/%Y')
    date_end = datetime.strptime(str_date2, '%m/%d/%Y')

    # Time averaging interval:
    avg_ivld = dct_request['avg_ivld']

    #--------------------------------------------------------
    # Iterate over locations list:
    #--------------------------------------------------------
    for loc_id in lst_locs:

        dct_data = {}       #initialize data dictionary

        lst_timerng = getTimeIndices(loc_id, date_start, date_end)
        tidx1 = lst_timerng[0]; tidx2 = lst_timerng[1]

        # Initialize parameters in data dictionary:
        for param_id in lst_params:
            dct_data[param_id] = {}                  #empty dict.
            dct_data[param_id]['values'] = []        #empty list
            dct_data[param_id]['units'] = ''
            dct_data[param_id]['desc'] = ''

        lst_times = []
        lst_dattim  = []
        initFlag = True

        #-------------------------------------------------------
        #- "Buoy" monitoring type:
        #-------------------------------------------------------
        if (data_type == 'buoy'):

            # Construct URL for OpenDAP access of date-specific netCDF file (** currently hardcoded for buoys**):
            url_nc = 'http://tds.glos.us/thredds/dodsC/buoy_agg/{0}/{0}.ncml'.format(loc_id)

            try:
                ds = open_url(url_nc);
                lstKeys = list(ds.keys());

                # Extend "times" list:
                #times = ds['time'];
                lst_times.extend(ds['time'][tidx1:tidx2]);

                # Determine time zero:
                if initFlag :
                    lst = ds['time'].units.split('since')
                    tunit = lst[0].strip()
                    tzero = datetime.strptime(lst[1].strip(), '%Y-%m-%d %H:%M:%S')

                # Download data for each parameter:
                for param_id in lst_params:
                    if param_id in lstKeys:
                        var = ds[param_id]
                        dct_data[param_id]['values'].extend(var.data[tidx1:tidx2])

                        if (initFlag == True):
                            dct_data[param_id]['units'] = var.attributes['units']
                            dct_data[param_id]['desc'] = var.attributes['description']

                # Reset initialization flag:
                initFlag = False

            except:

                if (dct_owners[loc_id] == 'NOAA-NDBC'):
                    ncFlag = False

                    break       #TMR!!! - break and return no data

                    # TMR!!! - example retrieval for data from past years provided below
                    txtResp = urllib.request.urlopen('http://www.ndbc.noaa.gov/view_text_file.php?filename={0}h2016.txt.gz&dir=data/historical/stdmet/'.format(loc_id))
                    lines = txtResp.readlines()

                    ln_ct = 0
                    lst_pidx = []

                    for l in lines:
                        ln_ct += 1
                        if (ln_ct > 5002): break

                        lst_vals = l.decode('UTF-8').strip().split()

                        if (ln_ct == 1):
                            lst_fields = lst_vals
                            for param_id in lst_params:
                                i_par = lst_fields.index(param_id)
                                lst_pidx.append(i_par)

                        elif (ln_ct == 2):
                            lst_units = lst_vals
                        else:
                            #Get date/time:
                            iyr = int(lst_vals[0]); imon = int(lst_vals[1]); iday = int(lst_vals[2])
                            ihr = int(lst_vals[3]); imin = int(lst_vals[4])
                            dt = datetime(iyr,imon,iday,ihr,imin)
                            lst_dattim.append(dt)

                            #Get parameter values:
                            ipar = 0
                            for param_id in lst_params:

                                dct_data[param_id]['values'].append(float(lst_vals[lst_pidx[ipar]]))
                                dct_data[param_id]['units'] = lst_units[lst_pidx[ipar]]
                                dct_data[param_id]['desc'] = param_id           #TMR!!!

                                ipar += 1
                    pass

                # TMR - need error handling here?
                pass

        #-----------------------------------
        # Conduct time averaging (*TMR!!! - code to be developed*):
        #-----------------------------------
        #if (int(avg_ivld) > 0):
        #    ichk = 0

        #-----------------------------------
        # Convert list of times to date:
        #-----------------------------------
        if (len(lst_times) > 0 and len(lst_dattim) == 0):
            for t in lst_times:
                lst_dattim.append(tzero + timedelta(seconds=t))
        #-----------------------------------

        # Augment dictionary for JSON response:
        dct_response[loc_id] = {}
        dct_response[loc_id]['dattim'] = lst_dattim
        dct_response[loc_id]['params'] = dct_data

    #--------------------------------------------------------
    #- End location loop
    #--------------------------------------------------------

    # Return response:
    return dct_response
    #return JsonResponse(dct_response, safe=False)

#------------------------------------------------------------
#-  Retrieve time series data via daily netCDF files:
#------------------------------------------------------------

def getTSData_slow(request):

    # Pydap Docs: http://pydap.readthedocs.io/en/latest/client.html
    # Example URL: 'http://tds.glos.us/thredds/dodsC/buoys/45020/2017/45020_20170903.nc');

    # Retrieve list of locations and parameters from request:
    lst_locs = request.POST.getlist('loc_arr[]')
    lst_params = request.POST.getlist('param_arr[]')

    # Start & end date/time + averaging interval:
    str_date1 = request.POST['date_start']
    str_date2 = request.POST['date_end']

    date_start = datetime.strptime(str_date1, '%m/%d/%Y')
    date_end = datetime.strptime(str_date2, '%m/%d/%Y')

    avg_ivld = request.POST['avg_ivld']
#    try:
#        avg_ivld = int(avg_ivld)       #averaging period
#    except:
#        avg_ivld = -999

    # Initialize dictionary for JSON response:
    dct_response = {}

    # Iterate over locations list:
    for loc_id in lst_locs:

        dct_data = {}       #initialize data dictionary

        # Initialize parameters in data dictionary:
        for param_id in lst_params:
            dct_data[param_id] = {}                  #empty dict.
            dct_data[param_id]['values'] = []        #empty list
            dct_data[param_id]['units'] = ''
            dct_data[param_id]['desc'] = ''

        #data_all = [];
        lst_times = [];
        initFlag = True

        #--- Start date loop ------------------------------------------
        for dateVal in dateRange(date_start, date_end):

            # Construct URL for OpenDAP access of date-specific netCDF file:
            url_nc = 'http://tds.glos.us/thredds/dodsC/buoys/{0}/{1}/{0}_{2}.nc'.format(loc_id, dateVal.strftime("%Y"), dateVal.strftime("%Y%m%d"));

            try:
                ds = open_url(url_nc);
                lstKeys = list(ds.keys());

                # Extend "times" list:
                #times = ds['time'];
                lst_times.extend(ds['time']);

                if initFlag :
                    lst = ds['time'].units.split('since')
                    tunit = lst[0].strip()
                    tzero = datetime.strptime(lst[1].strip(), '%Y-%m-%d %H:%M:%S')

                # Download data for each parameter:
                for param_id in lst_params:
                    if param_id in lstKeys:
                        var = ds[param_id]
                        dct_data[param_id]['values'].extend(var.data[:])

                        if (initFlag == True):
                            dct_data[param_id]['units'] = var.attributes['units']
                            dct_data[param_id]['desc'] = var.attributes['description']

                initFlag = False

            except:
               test = 0
               # Add error handling
        #--- End date loop ------------------------------------------

        ichk = 0;

        # Conduct time averaging (*code to be developed*):
        if (int(avg_ivld) > 0):
            ichk = 0

        # Convert list of times to date:
        lst_dattim = []

        for t in lst_times:
            lst_dattim.append(tzero + timedelta(seconds=t))

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

        # Augment dictionary for JSON response:
        dct_response[loc_id] = {}
        dct_response[loc_id]['dattim'] = lst_dattim
        dct_response[loc_id]['params'] = dct_data

    #x = getTSIntervals('45025')

    # Return response:
    return dct_response
    #return JsonResponse(dct_response, safe=False)

# Function to provide iteration over date range between two dates:
def dateRange(start_date, end_date):
    for n in range(int((end_date - start_date).days)):
        yield start_date + timedelta(n)

# Function to return a list with indices referencing the start date and end date:
def getTimeIndices(loc_id, date_start, date_end):

    url_nc = 'http://tds.glos.us/thredds/dodsC/buoy_agg/{0}/{0}.ncml'.format(loc_id)

    try:
        ds = open_url(url_nc);

        # "times" list:
        lst_times = []      #empty list
        lst_times.extend(ds['time']);

        lst = ds['time'].units.split('since')
        tunit = lst[0].strip()
        tzero = datetime.strptime(lst[1].strip(), '%Y-%m-%d %H:%M:%S')

        # Convert start & end dates to seconds:
        lst_dsec = []
        lst_rdates = [date_start, date_end]

        dt_today = datetime.today()

        for dt in lst_rdates:
            lst_dsec.append(int((dt - tzero).total_seconds()))

        lst_idx = []
        lst_sign = [1, -1]

        i = -1
        for idsec in lst_dsec:
            i += 1
            date_chk = lst_rdates[i]

            if (date_chk > dt_today):
                try:
                    idx = lst_times.index(idsec)
                    idx = (len(lst_times) - 1)
                    lst_idx.append(idx)
                    continue
                except:
                    pass

            try:
                idx = lst_times.index(idsec)
            except:
                idx = -9999

                for dday in range(1, 365):           #Check for start date
                    date_tmp = date_chk + timedelta(lst_sign[i] * dday)    #check forward or backward, 1 day at a time
                    if (i == 0 and date_tmp >= date_end): break
                    if (i == 1 and date_tmp <= date_start): break

                    try:
                        dsec = int((date_tmp - tzero).total_seconds())        # Number of seconds elapsed
                        idx = lst_times.index(dsec)
                        break
                    except:
                        idx = -9999

            lst_idx.append(idx)

        return lst_idx

    except Exception as inst:
        print(inst)
        return [-9999, -9999]

def getTSInterval(loc_id):

    # Check for existing "[loc_id]_intervals.json":
    strFile = './json/' + loc_id + '_intervals.json'

    if (os.path.isfile(strFile)):
        pFile = open(strFile)
        json_data = pFile.read()
        pFile.close()

        dctData = json.loads(json_data)

    else:
        # Read the aggregate dataset and parse
        i = 0

        url_nc = 'http://tds.glos.us/thredds/dodsC/buoy_agg/{0}/{0}.ncml'.format(loc_id)

        try:
            ds = open_url(url_nc);

            # "times" list:
            lst_times = ds['time'];

            lst = ds['time'].units.split('since')
            tunit = lst[0].strip()
            tzero = datetime.strptime(lst[1].strip(), '%Y-%m-%d %H:%M:%S')

            # Convert list of times to date:
            lst_dattim = []

            dctData = {}
            for iyr in range(2001, datetime.today().year):
                dctData[iyr] = {}

            for t in lst_times:
                dattim = tzero + timedelta(seconds=t)

                #lst_dattim.append(dattim)

        except:
            pass

    return dctData

    # Check


from util import set_position, parse_color

class Clock:
    def __init__(self, config, screen):
        self.config = config
        self.screen = screen
        tz_text = config.get("timezone")
        if tz_text:
            import pytz

            self.expected_tz = pytz.timezone(tz_text)
        else:
            self.expected_tz = self.screen.timezone
        self.id = self.config.get("id", "clock")
        font_size = self.config.get("font_size", "large").lower()
        font_type = self.config.get("font_size", "sans").lower()
        self.font = self.screen.theme.get_font(font_size, font_type)
        self.color = parse_color(
            self.config.get("color", self.screen.theme.get_primary_color())
        )
        self.time_format = self.config.get("format", "%I:%M %p")

    def prepare(self):
        pass

    def draw(self):
        now = self.screen.utc_time.astimezone(self.expected_tz).strftime(
            self.time_format
        )

        text_surf = self.font.render(now, True, self.color)
        text_rect = text_surf.get_rect()

        text_rect = set_position(text_rect, self.screen.rects, self.config)

        self.screen.rects[self.id] = text_rect
        self.screen.blit(text_surf, text_rect)


#!/usr/bin/env python3

import struct
import argparse

def fmt_size(val):
    if val == 0:
        return "HUD_ELEMENT_SIZE_8x8"
    elif val == 1:
        return "HUD_ELEMENT_SIZE_16x16"
    elif val == 2:
        return "HUD_ELEMENT_SIZE_24x24"
    elif val == 3:
        return "HUD_ELEMENT_SIZE_32x32"
    elif val == 4:
        return "HUD_ELEMENT_SIZE_48x48"
    elif val == 5:
        return "HUD_ELEMENT_SIZE_64x64"
    elif val == 6:
        return "HUD_ELEMENT_SIZE_8x16"
    elif val == 7:
        return "HUD_ELEMENT_SIZE_16x8"
    elif val == 8:
        return "HUD_ELEMENT_SIZE_16x24"
    elif val == 9:
        return "HUD_ELEMENT_SIZE_16x32"
    elif val == 10:
        return "HUD_ELEMENT_SIZE_64x32"
    elif val == 11:
        return "HUD_ELEMENT_SIZE_32x16"
    elif val == 12:
        return "HUD_ELEMENT_SIZE_12x12"
    elif val == 13:
        return "HUD_ELEMENT_SIZE_48x24"
    elif val == 14:
        return "HUD_ELEMENT_SIZE_32x8"
    elif val == 15:
        return "HUD_ELEMENT_SIZE_24x8"
    elif val == 16:
        return "HUD_ELEMENT_SIZE_64x16"
    elif val == 17:
        return "HUD_ELEMENT_SIZE_16x64"
    elif val == 18:
        return "HUD_ELEMENT_SIZE_192x32"
    elif val == 19:
        return "HUD_ELEMENT_SIZE_40x40"
    elif val == 20:
        return "HUD_ELEMENT_SIZE_24x16"
    elif val == 21:
        return "HUD_ELEMENT_SIZE_32x40"
    elif val == 22:
        return "HUD_ELEMENT_SIZE_40x16"
    elif val == 23:
        return "HUD_ELEMENT_SIZE_40x24"
    elif val == 24:
        return "HUD_ELEMENT_SIZE_32x24"
    else:
        return val

class HudElementScript:
    def __init__(self, symbol):
        self.symbol = symbol
        self.buffer = []

    def feed(self, word):
        self.buffer.append(word)

    def print(self):
        buf = iter(self.buffer)
        indent = "    "
        op = 99

        print(f"HudScript {self.symbol} = {{")

        while op:
            op = next(buf, -1)
            if op == -1:
                break

            if op == 0x00:
                print(f"{indent}hs_End")
            elif op == 0x01:
                print(f"{indent}hs_SetRGBA({next(buf)}, {next(buf)}, {next(buf)})")
            elif op == 0x02:
                print(f"{indent}hs_SetCI({next(buf)}, {next(buf)}, {next(buf)})")
            elif op == 0x03:
                indent = indent[4:]
                print(f"{indent}hs_Restart")
            elif op == 0x04:
                print(f"{indent}hs_Loop")
                indent = indent + "    "
            elif op == 0x05:
                print(f"{indent}hs_SetTileSize({fmt_size(next(buf))})")
            elif op == 0x06:
                print(f"{indent}hs_SetSizesAutoScale({fmt_size(next(buf))}, {fmt_size(next(buf))})")
            elif op == 0x07:
                print(f"{indent}hs_SetSizesFixedScale({fmt_size(next(buf))}, {fmt_size(next(buf))})")
            elif op == 0x08:
                print(f"{indent}hs_SetVisible")
            elif op == 0x09:
                print(f"{indent}hs_SetHidden")
            elif op == 0x0A:
                print(f"{indent}hs_AddTexelOffsetX({next(buf)})")
            elif op == 0x0B:
                print(f"{indent}hs_AddTexelOffsetY({next(buf)})")
            elif op == 0x0C:
                print(f"{indent}hs_SetTexelOffset({next(buf)}, {next(buf)})")
            elif op == 0x0D:
                print(f"{indent}hs_SetIcon({next(buf)}, {next(buf)}, {next(buf)}, {next(buf)}, {next(buf)})")
            elif op == 0x0E:
                print(f"{indent}hs_SetScale({next(buf)})")
            elif op == 0x0F:
                print(f"{indent}hs_SetAlpha({next(buf)})")
            elif op == 0x10:
                print(f"{indent}hs_RandomDelay({next(buf)}, {next(buf)})")
            elif op == 0x11:
                print(f"{indent}hs_Delete")
            elif op == 0x12:
                print(f"{indent}hs_UseIA8")
            elif op == 0x13:
                print(f"{indent}hs_SetCustomSize({next(buf)}, {next(buf)})")
            elif op == 0x14:
                print(f"{indent}hs_RandomRestart({next(buf)}, {next(buf)})")
            elif op == 0x15:
                print(f"{indent}hs_op_15({next(buf)})")
            elif op == 0x17:
                count = next(buf)
                args = []
                for i in range(count):
                    args.append(next(buf))
                print(f"{indent}hs_RandomBranch({', '.join(args)})")
            elif op == 0x18:
                print(f"{indent}hs_SetFlags({next(buf)})")
            elif op == 0x19:
                print(f"{indent}hs_ClearFlags({next(buf)})")
            elif op == 0x1A:
                print(f"{indent}hs_PlaySound({next(buf)})")
            elif op == 0x1B:
                print(f"{indent}hs_SetPivot({next(buf)})")
            else:
                print(f"{indent}{op},")

        print("};\n")

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("file", type=str, help=".data.s file to dissassemble")

    args = parser.parse_args()

    with open(args.file, "r") as f:
        lines = f.readlines()
        current_script = None

        for line in lines:
            line = line.strip()

            if line.startswith("glabel"):
                if current_script:
                    current_script.print()

                current_script = HudElementScript(line.split(" ")[1])
            elif line.startswith(".word"):
                words = line[6:].split(", ")

                for word in words:
                    try:
                        word = int(word, base=0)

                        if word > 0x8000000:
                            word = f"0x{word:X}"
                        else:
                            (word,) = struct.unpack(">i", struct.pack(">I", word))
                            print(word)
                    except ValueError:
                        pass

                    current_script.feed(word)

        if current_script:
            current_script.print()


import pygame
from classes.tree import Tree
from ui.button import Button
from ui.slider import Slider
from ui.checkbox import CheckBox
from multifile import WINDOW_WIDTH, WINDOW_HEIGHT
import os

pygame.init()
CLOCK = pygame.time.Clock()
FPS = 30

win = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))

# Values start maxed out
tree_parameters = {
    'pos': ((WINDOW_WIDTH - 400) / 2 + 400, WINDOW_HEIGHT),
    'angle': 90,
    'tick': 15,
    'vel': 10,
    'number': 14,
    'division_ratio': 2,
    'division_angle': 90,
    'divide_angles': True,
    'divide_distance': True,
    'fruits': False
}

buttons = {
    'button_reset': Button((50, WINDOW_HEIGHT - 125, 300, 75), 'Reset', outline_width=4),
    'button_hide': Button((415, 25, 25, 25), '<', size=30, outline_width=2)

}

sliders = {
    'slider_number': Slider((50, WINDOW_HEIGHT - 225, 300, 75), 'Divisions', tree_parameters['number']),
    'slider_division_ratio': Slider((50, WINDOW_HEIGHT - 350, 300, 75), 'Division Ratio', tree_parameters['division_ratio']),
    'slider_division_angle': Slider((50, WINDOW_HEIGHT - 475, 300, 75), 'Division Angle', tree_parameters['division_angle'])
}

checkboxes = {
    'checkbox_divide_angles': CheckBox((50, 200), 'Divide Angles'),
    'checkbox_divide_distance': CheckBox((50, 125), 'Divide Distance'),
    'checkbox_fruits': CheckBox((50, 50), "Spawn 'Fruits'")
}
checkboxes['checkbox_divide_angles'].checked = True
checkboxes['checkbox_divide_distance'].checked = True

sliders['slider_number'].set_round(0)
sliders['slider_division_ratio'].set_percentage(60)
sliders['slider_division_angle'].set_percentage(37)
sliders['slider_number'].set_percentage(85)

tree_parameters['number'] = sliders['slider_number'].get_value()
tree_parameters['division_ratio'] = sliders['slider_division_ratio'].get_value()
tree_parameters['division_angle'] = sliders['slider_division_angle'].get_value()

tree1 = Tree(pos=tree_parameters['pos'],
             angle=tree_parameters['angle'],
             ticks=tree_parameters['tick'],
             vel=tree_parameters['vel'],
             number=tree_parameters['number'],
             division_ratio=tree_parameters['division_ratio'],
             division_angle=tree_parameters['division_angle'],
             divide_angles=tree_parameters['divide_angles'],
             divide_distance=tree_parameters['divide_distance'],
             fruits=tree_parameters['fruits'])

mouse_pos = None

clicked = False
holding_click = False
hidden_hud = False

run = True
while run:
    clicked = False
    if pygame.mouse.get_pressed()[0] == 1 and not holding_click:
        clicked = True
        holding_click = True

    if pygame.mouse.get_pressed()[0] == 0:
        holding_click = False

    CLOCK.tick(FPS)
    run = False if pygame.QUIT in [event.type for event in pygame.event.get()] else True
    pygame.display.set_caption(f'fps: {CLOCK.get_fps()}')

    if hidden_hud:
        for slider in sliders:
            sliders[slider].move_frame((-415, 0))
        for button in buttons:
            buttons[button].move_frame((-415, 0))
        for checkbox in checkboxes:
            checkboxes[checkbox].move_frame((-415, 0))

        buttons['button_hide'].text = '>'
        buttons['button_hide'].move_frame((-407.5, 0))

        tree_parameters['pos'] = (WINDOW_WIDTH / 2, WINDOW_HEIGHT)
    else:
        tree_parameters['pos'] = ((WINDOW_WIDTH - 400) / 2 + 400, WINDOW_HEIGHT)
        buttons['button_hide'].text = '<'

    tree_parameters['number'] = sliders['slider_number'].get_value()
    tree_parameters['division_ratio'] = sliders['slider_division_ratio'].get_value() if sliders['slider_division_ratio'].get_value() != 0 else 0.1
    tree_parameters['division_angle'] = sliders['slider_division_angle'].get_value()
    tree_parameters['divide_angles'] = checkboxes['checkbox_divide_angles'].is_checked()
    tree_parameters['divide_distance'] = checkboxes['checkbox_divide_distance'].is_checked()
    tree_parameters['fruits'] = checkboxes['checkbox_fruits'].is_checked()

    if pygame.key.get_pressed()[pygame.K_r]:
        tree1 = Tree(pos=tree_parameters['pos'],
                     angle=tree_parameters['angle'],
                     ticks=tree_parameters['tick'],
                     vel=tree_parameters['vel'],
                     number=tree_parameters['number'],
                     division_ratio=tree_parameters['division_ratio'],
                     division_angle=tree_parameters['division_angle'],
                     divide_angles=tree_parameters['divide_angles'],
                     divide_distance=tree_parameters['divide_distance'],
                     fruits=tree_parameters['fruits'])

    if clicked:
        if buttons['button_reset'].check_clicked():
            tree1 = Tree(pos=tree_parameters['pos'],
                         angle=tree_parameters['angle'],
                         ticks=tree_parameters['tick'],
                         vel=tree_parameters['vel'],
                         number=tree_parameters['number'],
                         division_ratio=tree_parameters['division_ratio'],
                         division_angle=tree_parameters['division_angle'],
                         divide_angles=tree_parameters['divide_angles'],
                         divide_distance=tree_parameters['divide_distance'],
                         fruits=tree_parameters['fruits'])
        for checkbox in checkboxes:
            if checkboxes[checkbox].check_clicked():
                checkboxes[checkbox].checked = not checkboxes[checkbox].checked
        if buttons['button_hide'].check_clicked():
            hidden_hud = not hidden_hud

    for slider in sliders:
        sliders[slider].check_clicked(clicked, holding_click)
        sliders[slider].move(pygame.mouse.get_pos()[0])

    if not any([sliders[slider].holding_click for slider in sliders]):
        if pygame.mouse.get_pressed()[0] == 1:
            previous_mouse_pos = mouse_pos
            mouse_pos = pygame.mouse.get_pos()

            if mouse_pos != previous_mouse_pos and previous_mouse_pos is not None:
                dx = mouse_pos[0] - previous_mouse_pos[0]
                dy = mouse_pos[1] - previous_mouse_pos[1]
                tree1.move_center(dx, dy)

        elif pygame.mouse.get_pressed()[0] == 0:
            mouse_pos = None

    tree1.create_new()

    tree1.move()

    win.fill((64, 64, 64))
    tree1.draw(win)
    if not hidden_hud:
        pygame.draw.rect(win, (0, 0, 0), (0, 0, 455, WINDOW_HEIGHT))
    else:
        pygame.draw.rect(win, (0, 0, 0), (0, 0, 40, WINDOW_HEIGHT))

    for button in buttons:
        buttons[button].draw(win)
    for slider in sliders:
        sliders[slider].draw(win)
    for checkbox in checkboxes:
        checkboxes[checkbox].draw(win)
    pygame.display.flip()


# Base model objects for resource database

import os

import sqlalchemy as sa
from sqlalchemy.orm import sessionmaker

_TABLE_NAMES = (
    'allocation_items',
    'allocations',
    'capabilities',
    'consumer_types',
    'consumers',
    'distance_types',
    'distances',
    'inventories',
    'object_names',
    'object_types',
    'partitions',
    'provider_capabilities',
    'provider_distances',
    'provider_group_members',
    'provider_groups',
    'provider_trees',
    'provider_types',
    'providers',
    'resource_types',
)
_TABLES = {}

def get_engine():
    db_user = os.environ.get('RUNM_TEST_RESOURCE_DB_USER', 'root')
    db_pass = os.environ.get('RUNM_TEST_RESOURCE_DB_PASS', '')
    db_uri = 'mysql+pymysql://{0}:{1}@localhost/test_resources'
    db_uri = db_uri.format(db_user, db_pass)
    return sa.create_engine(db_uri)

def get_session():
    engine = get_engine()
    sess = sessionmaker(bind=engine)
    return sess()

def load_tables():
    if _TABLES:
        return

    engine = get_engine()
    meta = sa.MetaData(engine)
    for tbl_name in _TABLE_NAMES:
        _TABLES[tbl_name] = sa.Table(tbl_name, meta, autoload=True)

def get_table(tbl_name):
    load_tables()
    return _TABLES[tbl_name]


import multiprocessing
from multiprocessing import Process, Value, Array
import time
import random
from game import game

def HGRHandler(gesture):
    while True:
        time.sleep(1)
        gesture.value = random.randint(0,2)
        print(gesture.value)

def a(gesture):
    while True:
        print(gesture.value)

if __name__ == "__main__":
    gesture = Value('d', 0)

    p1 = multiprocessing.Process(target=HGRHandler, args= (gesture,))
    p2 = multiprocessing.Process(target=game, args=(gesture,))

    p1.start()
    p2.start()

    p1.join()
    p2.join()


# -*- coding:utf-8 -*-

import salt.client
import multiprocessing
import time

def salt_client(host,cmd):
	client = salt.client.LocalClient()
	if type(host) == list:
		result = client.cmd(host,"cmd.run",[cmd],expr_form="list")
	else:
		#print '''client.cmd(%s,"cmd.run",[%s])''' % (host,cmd)
		result = client.cmd(host,"cmd.run",[cmd])
	log = ""
	for k,v in result.items():
		log = log + '''
Fllow message from : %s
=======================================================
%s''' % (k,v) + "\n"
	return log


from django.urls import path
from .views import *
from chat.views import message_list, load_messages
from rest_framework.authtoken import views

app_name = 'api'
urlpatterns = [
    path('user/', UserRecordView.as_view(), name='users'),
    path('image/<int:id>/', imageDisplay, name='image'),
    path('messages/<int:sender>/<int:receiver>/', message_list, name='message-detail'),
    path('messages/', message_list, name='message-list'),
    path('loadmessages/', load_messages.as_view(), name='load_message'),
    path('api-token-auth/', views.obtain_auth_token, name='api-token-auth'),
    path('register/', Registration.as_view(), name="register"),
    path('data/', TrainingData.as_view(), name='training data'),
    path('exercise/', ExerciseData.as_view(), name='exercise data'),
    path('sets/', SetEntry.as_view(), name='set data'),
    path('setfeedback/', SetEntryFeedback.as_view(), name='set feedback'),
    path('getfeedback/', getSetFeedback.as_view(), name='get feedback'),
    path('groups/', TrackingData.as_view(), name='group_data'),
    path('trackingValsGet/', TrackingValuesGet.as_view(), name='tracking_vals_get'),
    path('trackingValsUpdate/', TrackingValuesUpdate.as_view(), name='tracking_vals_update'),
    path('syncmfp/', SyncMyFitnessPal.as_view(), name='sync_mfp'),
    path('checkupdates/', CheckForUpdates.as_view(), name='check_updates'),
]


#위상정렬
from collections import deque

n=int(input())
graph=[[] for _ in range(n+1)]
indegrees=[]
for i in range(1,n+1):
    cl = list(map(int,input().split()))
    pre=[]
    for j in cl[1:]:
        while(j!= -1):
            pre.append(j)
    graph[i].append((cl[0],pre))
    indegrees[i]=len(pre)

q=deque()
for i in indegrees[1:]:
    if i==0:
        q.append(i)

while(q):
    #뽑음
    now = q.popleft()

    #새로넣음
    for i in graph[now][1]:
        indegrees[i]-=1
        if indegrees[i]==0:
            q.append(i)

이것이코딩테스트다_풀이/그래프이론/커리큘럼.py


from typing import List, Optional

from pydantic import BaseModel, Extra, root_validator

from mindsdb.integrations.handlers.utilities.validation_utilities import ParameterValidationUtilities

class TwelveLabsHandlerConfig(BaseModel):
    "Configuration for TwelveLabsHandler."

    index_name: str
    engine_id: Optional[str] = None
    api_key: Optional[str] = None
    index_options: List[str]
    addons: List[str] = []
    video_urls: Optional[List[str]] = None
    video_urls_col: Optional[str] = None
    video_files: Optional[List[str]] = None
    video_files_col: Optional[str] = None
    task: str = None
    search_options: Optional[List[str]] = None

    class Config:
        extra = Extra.forbid

    @root_validator(pre=True, allow_reuse=True, skip_on_failure=True)
    def check_param_typos(cls, values):
        """Check if there are any typos in the parameters."""

        ParameterValidationUtilities.validate_parameter_spelling(cls, values)

    @root_validator(allow_reuse=True, skip_on_failure=True)
    def check_for_video_urls_or_video_files(cls, values):
        """Check if video_urls or video_files have been provided."""

        video_urls = values.get("video_urls")
        video_urls_col = values.get("video_urls_col")
        video_files = values.get("video_files")
        video_files_col = values.get("video_files_col")

        if not video_urls and not video_files and not video_urls_col and not video_files_col:
            raise ValueError(
                "Neither video_urls, video_files, video_urls_col nor video_files_col have been provided. Please provide one of them."
            )

        return values

    @root_validator(allow_reuse=True, skip_on_failure=True)
    def check_for_task(cls, values):
        """Check if task has been provided along with the other relevant parameters for each task."""

        task = values.get("task")

        if task == "search":
            search_options = values.get("search_options")
            if not search_options:
                raise ValueError(
                    "search_options have not been provided. Please provide search_options."
                )

            # search options should be a subset of index options
            index_options = values.get("index_options")
            if not set(search_options).issubset(set(index_options)):
                raise ValueError(
                    "search_options should be a subset of index_options."
                )

        else:
            raise ValueError(
                f"task {task} is not supported. Please provide a valid task."
            )

        return values


from specutils import Spectrum1D
from astropy.units import Quantity

class SpectrumSerializer():

    def serialize(self, spectrum: Spectrum1D) -> dict:
        """
        Serializes a Spectrum1D in order to store in a ReducedDatum object. The serialization stores only what's
        necessary to rebuild the Spectrum1D--namely, flux and wavelength, and their respective units.

        :param spectrum: Spectrum1D to be serialized
        :type spectrum: specutils.Spectrum1D

        :returns: JSON representation of spectrum
        :rtype: dict
        """
        serialized = {}
        serialized['flux'] = spectrum.flux.value.tolist()
        serialized['flux_units'] = spectrum.flux.unit.to_string()
        serialized['wavelength'] = spectrum.wavelength.value.tolist()
        serialized['wavelength_units'] = spectrum.wavelength.unit.to_string()
        return serialized

    def deserialize(self, spectrum: dict) -> Spectrum1D:
        """
        Constructs a Spectrum1D from the spectrum value stored in a ReducedDatum

        :param spectrum: JSON representation used to construct the Spectrum1D
        :type spectrum: dict

        :returns: Spectrum1D representing the spectrum information
        :rtype: specutil.Spectrum1D
        """
        flux = Quantity(value=spectrum['flux'], unit=spectrum['flux_units'])
        wavelength = Quantity(value=spectrum['wavelength'], unit=spectrum['wavelength_units'])
        spectrum = Spectrum1D(flux=flux, spectral_axis=wavelength)
        return spectrum


import os, logging
import datetime as dt

from flask import Flask, Response, request
from requests import get
from helpers import fail, set_headers

app = Flask(__name__)

logging.basicConfig(level=logging.DEBUG)

MIDDLEWARE_SERVICE = os.getenv("MIDDLEWARE_SERVICE")

@app.route("/")
def hello():
	return "
Hello
"

@app.route("/time")
def get_time():
	h = set_headers(request.headers)
	t = get(MIDDLEWARE_SERVICE + "/time", headers=h)
	f = h.get('fail')

	if t.ok:
		if fail(f):
			return "Frontend service unavailable", 503
		else:
			return "
Frontend --> {}
".format(t.text)
	else:
		logging.error("{} {}".format(t.status_code, t.text))
		return "
Error {} : {}
".format(t.status_code, t.text)

if __name__ == "__main__":
	app.run(host="0.0.0.0", port=os.getenv("PORT", 8080))