import torch
import torch.nn as nn
import torch.nn.functional as F
from bunch import Bunch

class SimpleAutoencoder(nn.Module):
    def __init__(self, config: Bunch) -> None:
        '''
        Initialize the model
        Args:
            config: config file
        '''
        super(SimpleAutoencoder, self).__init__()
        self.fc = nn.Linear(in_features=config.ts_length+config.context_count_size,
                            out_features=config.ts_length+config.context_count_size)

    def forward(self, x: torch.Tensor) -> torch.Tensor:
        '''
        Forward pass of the model.
        Args:
            x: the input to the model, (batch_size, ts_length+context_count_size)
        Returns:
            x: the learned representation of the model, (batch_size, emb_size, ts_length+context_count_size)
        '''
        x = self.fc(x)
        return x

class DeepAutoencoder(nn.Module):
    def __init__(self, config: Bunch) -> None:
        '''
        Initialize the model, 4 layers of the autoencoder
        Args:
            config: config file
        '''
        super(DeepAutoencoder, self).__init__()
        self.fc1 = nn.Linear(in_features=config.ts_length +
                             config.context_count_size, out_features=96)
        self.fc2 = nn.Linear(in_features=96, out_features=48)
        self.fc3 = nn.Linear(in_features=48, out_features=24)
        self.fc4 = nn.Linear(
            in_features=24, out_features=config.ts_length+config.context_count_size)

    def forward(self, x: torch.Tensor) -> torch.Tensor:
        '''
        Forward pass of the model.
        Args:
            x: the input to the model, (batch_size, ts_length+context_count_size)
        Returns:
            x: the learned representation of the model, (batch_size, emb_size, ts_length+context_count_size)
        '''
        x = self.fc1(x)
        x = self.fc2(x)
        x = self.fc3(x)
        x = self.fc4(x)
        return x

class CNN(nn.Module):
    # https://github.com/Wickstrom/MixupContrastiveLearning/blob/main/MixupContrastiveLearningExample.ipynb

    def __init__(self, config: Bunch) -> None:
        '''
        Initialize the model
        Args:
            config: config file
        '''
        super(CNN, self).__init__()
        self.config = config
        out_size = config.ts_length+config.context_count_size
        self.encoder = nn.Sequential(
            nn.Conv1d(1, 12, kernel_size=1),
            nn.BatchNorm1d(12),
            nn.ReLU(),
            nn.Conv1d(12, 24, kernel_size=1),
            nn.BatchNorm1d(24),
            nn.ReLU(),
            nn.Conv1d(24, out_size, kernel_size=1),
            nn.BatchNorm1d(out_size),
            nn.ReLU(),
            nn.AdaptiveAvgPool1d(1),
            nn.Flatten()
        )

    def forward(self, x: torch.Tensor) -> torch.Tensor:
        '''
        Forward pass of the model.
        Args:
            x: the input to the model, (batch_size, ts_length+context_count_size)
        Returns:
            x: the learned representation of the model, (batch_size, emb_size, ts_length+context_count_size)'''
        x = x.unsqueeze(1)
        h = self.encoder(x)
        return h

class LSTMencoder(nn.Module):
    ''' Encodes time-series sequence '''

    def __init__(self, config: Bunch) -> None:
        '''
        Encoder of the model
        Args:
            config: config file
        '''
        super(LSTMencoder, self).__init__()
        self.config = config
        self.lstm = nn.LSTM(input_size=1, hidden_size=config.bl_hidden_size,
                            num_layers=2, batch_first=True, dropout=config.dropout)
        self.fc = nn.Linear(in_features=config.bl_hidden_size, out_features=1)

    def forward(self, x: torch.Tensor) -> torch.Tensor:
        '''
        Forward pass of the model.
        Args:
            x: the input to the model, (batch_size, ts_length+context_count_size) for LSTM must be (batch_size, seq_len, input_size) if batch_first = True
        Returns:
            emb: the learned representation of the model,
            LSTM layer returns:
                lstm_out: (batch_size, emb_size, ts_length+context_count_size), all the hidden states in the sequence
                hidden: (2, batch_size, hidden_size), hidden state and cell state for the last element in the sequence
        '''
        x = x.reshape(x.shape[0], x.shape[1], -1)
        lstm_out, self.hidden = self.lstm(x)
        emb = self.fc(lstm_out)
        emb = emb.reshape(emb.shape[0], -1)
        return emb


import sys

"""
コマンドライン上で打てるように実装。
python3 get_minsellprice.py <<コインの値段>> <<コイン個数>> <<0.001コイン辺りの利益額>>

return: [1コイン辺りの最低売り金額, 買いの時との差, 売らなければいけないコイン個数]
"""

def getMinSellPrice(buyPrice, coinAmount=0.001, minEarn=1.0, extraFreeList=[0.0, 0.0]):
    #買ったコインを円に変換
    actualBuyYenPrice = buyPrice * coinAmount
    #売り（円）を設定
    idealSellYenPrice = actualBuyYenPrice + minEarn
    #売りのコイン値に変換
    idealSellPrice = idealSellYenPrice /coinAmount

    diffPrice = idealSellPrice - buyPrice

    return [idealSellPrice, diffPrice, coinAmount]

if __name__ == '__main__':
    args = sys.argv
    buyPrice = args[1]
    coinAmount = 0.001
    minEarn = 1.0
    if len(args) > 2:
        coinAmount = args[2]

    if len(args) > 3:
        minEarn = args[3]

    sellprice = getMinSellPrice(float(buyPrice), float(coinAmount), float(minEarn))

    # sellprice = getMinSellPrice(1000000.0, 0.001, 1.0)
    print(sellprice)


__author__ = " Parya Derakhshan "

import numpy as np
from collections import OrderedDict
from inout import Error,Log

EPSILON = '~'
START,END='START','EOF'
ACCEPT,ERROR,POP='ACCEPT','ERROR','POP'
errors = {
    'll1':'GrammarError',
    'prsr':'ParserError [LR1]'
}

class Item(): # variable --> [completed] . [expected] , [lookahead]
    def __init__(self, variable, completed, expected, lookahead):

        '''handle epsilon line an empty symbol'''
        if completed == EPSILON: completed=[]
        if expected == EPSILON: expected=[]
        if lookahead == EPSILON: lookahead=[]
        if EPSILON in completed: completed.remove(EPSILON)
        if EPSILON in expected: expected.remove(EPSILON)

        self.lookahead=[]
        for l in lookahead:
            if l == EPSILON or l==[]: continue
            '''delete repeates from lookahead'''
            if not l in self.lookahead: self.lookahead.append(l)

        self.variable,self.completed,self.expected=variable, completed, expected

    def same_rule(self, item):
        '''check if variable --> completed . expected are the same'''
        return self.variable==item.variable and self.completed==item.completed and self.expected==item.expected

    def equal(self,item):
        '''check if items are the same'''
        return self.same_rule(item) and self.lookahead==item.lookahead

    def print_item(self):
        '''return( variable --> completed . expected , lookahead)'''
        return '{}-->{}.{},{}'.format(self.variable, self.completed, self.expected, self.lookahead)

class State(): # header:item, closure:[items], edge:[(label,state)], id: int
    count=0 #state id
    def __init__(self, item):
        self.header = item
        self.closure, self.edge = [], []
        self.id = State.count
        State.count+=1

    def add_node(self,symbol,state):
        '''add (label,neighbor) to edge'''
        self.edge.append((symbol,state))

    def add_closure(self, item):
        '''add new closure item if it doesn't already exist'''
        for c in self.closure:
            if item.same_rule(c):
                '''if there's an item in the closure with different lookaheads just update lookaheads'''
                tmp = c.lookahead+item.lookahead
                c.lookahead = list(set(tmp))
                return True
        self.closure.append(item)

    def get_edges(self):
        '''get neighbor states based on the first symbol in [expected]'''
        header,closures=self.header, self.closure
        if not header.expected: return[] #leaf
        edges, items = [], ([header] + closures)
        for item in items:
            if len(item.expected)>0:
                tmp = item.completed + [item.expected[0]]
                item_new = Item(item.variable,tmp,item.expected[1:],item.lookahead)
                edges.append((item.expected[0],item_new))
        return edges

    def print_state(self):
        '''return id, header, number of edges'''
        r =('{}) \n\t{}\t:{} edges\n{}'.format(self.id,self.header.print_item(),len(self.edge),('_'*20)))
        '''return closure items'''
        for i in self.closure:
            r+=('{}\n\n'.format(i.print_item()))
        r+=('\n'*2)
        return r

class LR1():
    def __init__(self,grammar):
        self.productions, self.variables, self.terminals = self.read_grammar(grammar)
        if EPSILON in self.terminals: self.terminals.remove(EPSILON)
        self.symbols = self.variables+self.terminals
        self.epsilons = self.mark_epsilon()
        self.firsts = self.first()
        self.automata = self.graph()

    def components(self):
        return self.symbols,self.variables, self.automata, self.rules

    def read_grammar(self,lines): #read grammar.txt and sets terminals,variables and rules
        if len(lines)==0: Error().parser(errors['ll1'],'Grammar Not Found')
        productions,productions_all=OrderedDict(()),OrderedDict(())
        variables,terminals,words = [],[],[]
        for i in range(len(lines)):
            line = lines[i]
            line.strip()
            left,right = line.split('->')
            left = left.replace(' ','')
            if not left in variables: variables.append(left)
            key = str(i)+'.'+left
            productions_all[key]=[]
            for r in right.split(' '):
                r= r.strip()
                if r.isspace() or not r: continue
                if r ==EPSILON : productions_all[key]=r[0]
                else: productions_all[key].append(r)
                words.append(r)
        for w in words:
            if w not in terminals and w not in variables: terminals.append(w)
        for v in variables:
            productions[v]=[]
            for key,value in productions_all.items():
                if value[0]==EPSILON: value=value[0]
                if key.split('.')[1]==v: productions[v].append(value)
        self.rules = productions_all
        return productions,variables,terminals

    def mark_epsilon(self): #marking algorithm for variables that can drive epsilon
        marked = []
        variables = self.variables
        for v in variables:
            derivations = self.productions[v]
            if EPSILON in derivations: marked.append(v)
        for i in range(len(variables)):
            v = variables[i]
            if v in marked: continue
            derivations = self.productions[v]
            for der in derivations:
                all_marked =True
                for s in der:
                    if (s in self.terminals) or (s not in marked):
                        all_marked = False
                        break
                if all_marked:
                    i = 0
                    marked.append(v)
                    break
        return marked

    def relation_F(self): # relation F for firsts (matrix output)
        n = len(self.symbols)
        f1 = np.full((n, n), 0)
        for v in self.variables:
            i = self.symbols.index(v)
            derivations = self.productions[v]
            for der in derivations:
                if der[0] == EPSILON: continue
                j = self.symbols.index(der[0])
                if f1[i,j]==1: return Error().parser(errors['ll1'],'Condition I')
                f1[i,j]=1
        F, F_sum=[f1], f1
        while(F[-1].any()):
            f_p = np.linalg.matrix_power(f1,(len(F)+1))
            F.append(f_p)
            F_sum = np.add(F_sum,f_p)
            if F_sum.max()>1: return Error().parser(errors['ll1'],'Condition I')
        self.F = F_sum

    def first(self): # firsts for variables (dictionary output)
        self.relation_F()
        first = {}
        n_v = len(self.variables)
        for i in range(n_v):
            v = self.variables[i]
            first[v]=[]
            row =self.F[i,n_v:]
            for j in range(len(row)):
                if row[j]: first[v].append(self.terminals[j])
            if v in self.epsilons:
                first[v].append(EPSILON)
        return first

    def rule_index(self,var,der): # index)variable->derivation
        '''get rule index based on the variable and derivations in it'''
        for key,derivation in self.rules.items():
            index,variable = key.split('.')
            if variable == var and derivation==der: return index
        return ERROR

    def rule_derivation(self,i): # index)variable->derivation
        '''get rule's variable and derivations based on its index'''
        for key,derivation in self.rules.items():
            index,variable = key.split('.')
            if index == i: return variable, derivation
        return ERROR

    def expected_lookahead(self, expected, lookahead):
        '''for item with .[expected],[lookahead] returns closures:[(var,lookaheads)]'''

        '''leaf with no closure'''
        if not expected or expected[0] in self.terminals:  return 0

        '''no additional lookahead and just one variable'''
        if len(expected)==1: return[(expected[0],lookahead)]

        '''add the first expected variable and all possible lookaheads'''
        firsts=[(expected[0],self.lookahead(expected[1:],lookahead))]

        '''check for epsilon driven variables after the first expected symbol'''
        if expected[0] in self.epsilons:
            follow = self.expected_lookahead(expected[1:],lookahead)
            if follow: firsts += follow

        return firsts

    def lookahead(self,expected,lookahead):
        '''for item with .[expected[1:]],[lookahead] returns [lookaheads]'''

        '''leaf with no closures'''
        if not expected: return []

        '''the first symbol is a terminal'''
        if expected[0] in self.terminals: return [expected[0]]

        '''add the first variables firsts'''
        firsts, reach_end = self.firsts[expected[0]], True

        '''check for epsilon driven variables after the first expected variable'''
        if expected[0] in self.epsilons and len(expected)>1:
            follow = self.lookahead(expected[1:],lookahead)
            if follow: firsts+=follow

        '''if all the variables in expected and drive epsilon also add the original lookahead'''
        for e in expected:
            if not e in self.epsilons:
                reach_end=False
                break
        if reach_end: firsts+=lookahead

        return firsts

    def state_closures(self,state):
        '''calculate state's closure items'''

        '''state's header item'''
        header, check = state.header, []

        '''header's directly deriven closure items'''
        items = self.expected_lookahead(header.expected, header.lookahead)
        if items ==0: return state #no closure items
        for var,lookahead in items:
            for derivation in self.productions[var]:
                new_item = Item(var,[],derivation,lookahead)
                if not new_item in state.closure:
                    state.add_closure(new_item)
                    check.append(new_item)

        '''closure items driven from unchecked closure items in the state'''
        while check:
            item = check.pop(0)
            items = self.expected_lookahead(item.expected, item.lookahead)
            if items == 0: continue
            for var,lookahead in items:
                for derivation in self.productions[var]:
                    new_item = Item(var,[],derivation,lookahead)
                    if not new_item in state.closure:
                        state.add_closure(new_item)
                        check.append(new_item)

        return state

    def graph(self):
        '''parser's NFA'''
        automata ={}

        '''initial state: id0)ZERO-->[],START,EOF'''
        state0 = State(Item('ZERO', [], ['START'], ['EOF']))
        automata[state0.id]=state0

        '''create all possible states'''
        id=0
        while id<State.count:

            '''calculate closures based on the header'''
            state = self.state_closures(automata[id])

            '''claculate (edge,neighbor) based on first expected symbol'''
            edges= state.get_edges()

            for edge,item in edges:

                '''check if a state with similar header item doesn't already exist'''
                check,i=True,0
                for k, s in automata.items():
                    if s.header.equal(item):
                        check,i=False,s.id
                        break
                '''create new neighboring state'''
                if check:
                    state_new = State(item)
                    i= state_new.id
                    automata[i]=state_new

                '''add state's edges'''
                if (edge,i) not in state.edge: state.edge.append((edge,i))

            id+=1
        return automata

class Parser():
    def __init__(self):
        self.stack,self.output=[0],[]

    def table_automata(self,grammar):
        self.grammar = LR1(grammar)
        self.symbols,self.variables,self.automata,self.productions = self.grammar.components()
        self.table=self.parsing_table( self.symbols,self.variables,self.automata)
        return self.table_output()

    def parsing_table(self,symbols,variables,automata):
        table,self.ids = {},[]
        '''table[id][terminal-variable]'''
        for id, state in automata.items():
            self.ids.append(id)
            table[id]={}
            for symbol in symbols: table[id][symbol]=ERROR
            for edge, node in state.edge:
                if edge in variables: table[id][edge]=('G',node) #GoTo
                else: table[id][edge]=('S',node) #shiftTo
            items = [state.header]+state.closure
            for item in items:
                if not item.expected:  #leaf or epsilon derivation
                    var,der = item.variable, item.completed
                    if not item.completed: der = EPSILON
                    elif item.lookahead == [END] and item.completed==[START]:
                        for s in symbols: table[id][s]=ACCEPT
                        self.accept_id = id
                        continue
                    index = self.grammar.rule_index(var,der)
                    for terminal in item.lookahead:
                        table[id][terminal]=('R',index) #ReduceTo
        return table

    def table_output(self):
        txt = []
        txt.append('{:4s}'.format(' '))
        for symbol in self.symbols: txt.append('|{:11s}'.format(symbol))
        txt.append('\n'+'_'*(4+12*len(self.symbols))+'\n')
        for id in self.ids:
            txt.append('{:4.0f}'.format(id))
            for symbol in self.symbols:
                txt.append('|{:11s}'.format(str(self.table[id][symbol])))
            txt.append('\n'+'_'*(4+12*len(self.symbols))+'\n')
        return txt

    def automata_output(self):
        txt=[]
        for id, state in self.automata.items():
            txt.append(state.print_state())
        return txt

    def parse_tokens(self,tokens): #read tokens.txt
        if len(tokens)==0: return Error().parser(errors['prsr'],'Tokens Not Found')
        symbols=[]
        for token in tokens:
            code,const = token.split(EPSILON)
            symbols.append(const.strip())
        symbols.append(END)
        result = self.parse(symbols)
        if result==ERROR:
            self.output.append('<Production Rule Not Found>')
            Error().parser(errors['prsr'],'Invalid Command')
        else: Log().success('Program Was Parsed Successfully [LR1]')
        self.output.reverse()
        return self.output

    def get_rule(self,number,var,rule):
        der = ''
        for symbol in rule: der+= (symbol+' ')
        return number+') '+var+' -> '+der.strip()+'\n'

    def parse(self,tokens): #parse tokens according to the parse table
        while tokens:
            A ,a = self.stack[-1],tokens[0]
            if A in self.variables: #GoTo
                A2 = self.stack[-2]
                M = self.table[A2][A]
                if not type(M) is tuple or not M[0] =='G': return ERROR
                self.stack.append(M[1])
            elif A in self.ids:
                M = self.table[A][a]
                if M== ACCEPT: return self.output
                if not type(M) is tuple: return ERROR
                instruction, id = M
                if instruction not in ['R','S']: return ERROR
                if instruction=='S': #ShifTo
                    del tokens[0]
                    self.stack.append(a)
                    self.stack.append(id)
                else: #ReduceTo
                    variable, derivation = self.grammar.rule_derivation(id)
                    if derivation!=EPSILON:
                        for i in range(len(derivation)-1,-1,-1):
                            if self.stack[-2]!= derivation[i]: return ERROR
                            self.stack.pop(-1)
                            self.stack.pop(-1)
                    self.stack.append(variable)
                    self.output.append(self.get_rule(id,variable,derivation))
            else: return ERROR

def run(files,dir_grammar,dir_parsetable,dir_automata,dir_tokens,dir_rules):
    '''read grammar and calculate first and automata'''
    grammar = files.set_directory(dir_grammar,dir_parsetable)
    parser = Parser()
    '''calculate and print parsing table'''
    table = parser.table_automata(grammar)
    files.write(table)
    files.close()
    '''print automata'''
    f = files.set_directory(dir_grammar,dir_automata)
    files.write(parser.automata_output())
    files.close()
    '''read tokens and parse the program'''
    tokens = files.set_directory(dir_tokens,dir_rules)
    rules = parser.parse_tokens(tokens)
    '''print rules'''
    files.write(rules)
    files.close()

if __name__ == "__main__":
    from inout import File

    dir_program = 'program.txt'
    vis,outs = 'visualizations','outputs'
    files = File(dir_program,[vis,outs])

    dir_tokens, dir_grammar, dir_rules_lr1 = (outs+'/tokens.txt'),'grammar.txt', (outs+'/rules_lr1.txt')
    dir_parsetable_lr1, dir_automata =(vis+'/parsetable_lr1.txt'), (vis+'/automata.txt')

    run(files,dir_grammar,dir_parsetable_lr1,dir_automata,dir_tokens,dir_rules_lr1)


import tornado.ioloop
from tornado.web import RequestHandler, Application, url

class MainHandler(RequestHandler):
    def get(self):
        for i in range(1, 4):
            self.write('link to story {}
'.format(
                    self.reverse_url("story", str(i)), i))

class StoryHandler(RequestHandler):
    def initialize(self, db):
        self.db = db

    def get(self, story_id):
        self.write("this is story %s" % story_id)

if __name__ == "__main__":
    db = 'dummy db. work nothing'
    app = Application([  # ncluding the routing table that maps requests to handlers.
        # routing table is a list of URLSpec objects (or tuples)
        url(r"/", MainHandler),  # at least a regular expression and a handler class
        url(r"/story/([0-9]+)",  # the regular expression contains capturing groups, these groups are the path arguments and will be passed to the handler’s HTTP method
            StoryHandler,
            dict(db=db),  # If a dictionary is passed as the third element of the URLSpec, it supplies the initialization arguments which will be passed to RequestHandler.initialize.
            name="story")  # the URLSpec may have a name, which will allow it to be used with RequestHandler.reverse_url.
        ])
    # dict 関数の keyword args が辞書の中身になる
    app.listen(8888)
    tornado.ioloop.IOLoop.current().start()


import os
import argparse
import stat
import pickle as p
import cv2
import numpy as np
from PIL import Image
from tqdm import tqdm

model_config = {
    'resize': 32,
    'mean': [0.5070751592371323, 0.48654887331495095, 0.4409178433670343],
    'std': [0.2673342858792401, 0.2564384629170883, 0.27615047132568404],
}

def resize(img, size, interpolation=Image.BILINEAR):
    if isinstance(size, int):
        w, h, _ = img.shape
        if (w <= h and w == size) or (h <= w and h == size):
            return img
        if w < h:
            ow = size
            oh = int(size * h / w)
            return img.resize((ow, oh), interpolation)
        else:
            oh = size
            ow = int(size * w / h)
            return img.resize((ow, oh), interpolation)
    else:
        return img.resize(size[::-1], interpolation)

def load_CIFAR_batch(filename):
    """ load single batch of cifar """
    with open(filename, 'rb') as f:
        datadict = p.load(f, encoding='bytes')
        # take out data in the form of a dict
        X = datadict[b'data']
        Y = datadict[b'fine_labels']
        X = X.reshape(10000, 3, 32, 32)
        Y = np.array(Y)
        return X, Y

def create_image_dataset(path):
    """ create Visual dataset """
    imgX, imgY = load_CIFAR_batch(path)
    flags = os.O_WRONLY | os.O_CREAT | os.O_EXCL
    modes = stat.S_IWUSR | stat.S_IRUSR
    with os.fdopen(os.open('img_label.txt', flags, modes), 'w') as f:
        for i in range(imgY.shape[0]):
            f.write('img' + str(i) + ' ' + str(imgY[i]) + '\n')
    for i in tqdm(range(imgX.shape[0])):
        imgs = imgX[i]
        img0 = imgs[0]
        img1 = imgs[1]
        img2 = imgs[2]
        i0 = Image.fromarray(img0)
        i1 = Image.fromarray(img1)
        i2 = Image.fromarray(img2)
        img = Image.merge("RGB", (i0, i1, i2))
        name = "img" + str(i) + ".png"
        img.save("./pic/" + name, "png")
    print("create visual dataset successfully")

def amct_input_bin(pic_path, save_path):
    imgs_to_label = {}
    with open('./img_label.txt', 'r') as f:
        for line in f.readlines():
            img, label = line.split()[0], line.split()[1]
            imgs_to_label[img] = int(label)

    for img_name in tqdm(imgs_to_label.keys()):
        image_name = img_name + '.png'
        img = cv2.imread(os.path.join(pic_path, image_name))
        img = resize(img, model_config['resize']) # Resize
        img = img.transpose(2, 0, 1) # ToTensor: HWC -> CHW
        img = np.expand_dims(img, 0)
        img = img/255. # ToTensor: div 255
        img = np.vstack([img]*24).astype(dtype=np.float32)
        img -= np.array(model_config['mean'], dtype=np.float32)[:, None, None] # Normalize: mean
        img /= np.array(model_config['std'], dtype=np.float32)[:, None, None] # Normalize: std
        img.tofile(os.path.join(save_path, image_name.split('.')[0] + ".bin"))

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('--src_path', type=str, default='./cifar-100-python/test')
    parser.add_argument('--save_path', type=str, default='./amct_bin_data')
    parser.add_argument('--amct', action='store_true')
    args = parser.parse_args()
    src_path = os.path.realpath(args.src_path)
    save_path = os.path.realpath(args.save_path)
    pic_path = "./pic"
    if not os.path.exists(pic_path):
        os.makedirs(pic_path)
        create_image_dataset(src_path)
    if not os.path.exists(save_path):
        os.makedirs(save_path)
    if args.amct:
        amct_input_bin(pic_path, save_path)

if __name__ == '__main__':
    main()


import json
import requests

from data_collection.general.static import end_date, endpoints, start_date
from data_collection.general.user import username, user_token

def update_commit_stats(pr_contribution_nodes, commit_stats):
    for pr_node in pr_contribution_nodes:
        pr = pr_node["pullRequest"]
        if pr["merged"]:
            repo_name = pr["repository"]["name"]
            if repo_name in commit_stats:
                commit_stats[repo_name]["commits"] += pr["commits"]["totalCount"]
                commit_stats[repo_name]["deletions"] += pr["deletions"]
                commit_stats[repo_name]["additions"] += pr["additions"]
                commit_stats[repo_name]["changed_files"] += pr["changedFiles"]
            else:
                commit_stats[repo_name] = {
                    "commits": pr["commits"]["totalCount"],
                    "deletions": pr["deletions"],
                    "additions": pr["additions"],
                    "changed_files": pr["changedFiles"]
                }

def get_commit_stats(user):
    cursor_str = ""
    commit_stats_per_repo = {}

    while True:
        query = f"""  query {{
            user(login:"{user}"){{
                contributionsCollection(from: "{start_date}", to:"{end_date}"){{
                    pullRequestContributions(first:20 {cursor_str}){{
                        pageInfo{{
                            hasNextPage
                            endCursor
                        }}
                        nodes{{
                            pullRequest {{
                                repository {{
                                    name
                                }}
                                merged
                                changedFiles
                                additions
                                deletions
                                commits(first:1){{
                                    totalCount
                                }}
                            }}
                        }}
                    }}
                }}
            }}
        }}"""

        r = requests.post(
            endpoints["github"], headers={"Authorization": f"token {user_token}"}, json={"query": query})
        response = json.loads(r.text)
        update_commit_stats(response["data"]["user"]["contributionsCollection"]
                            ["pullRequestContributions"]["nodes"], commit_stats_per_repo)

        pageInfo = response["data"]["user"]["contributionsCollection"]["pullRequestContributions"]["pageInfo"]
        if not pageInfo["hasNextPage"]:
            break
        cursor = pageInfo["endCursor"]
        cursor_str = f", after: \"{cursor}\""
    return commit_stats_per_repo

if __name__ == "__main__":
    # get commit stats for all PRs you opened (so anything you paired with someone else on won't be included)
    commit_stats_per_repo = get_commit_stats(user=username)
    print(commit_stats_per_repo)

    #calculate total stats
    num_additions = 0
    num_deletions = 0
    num_files_changes = 0
    num_total_commits = 0
    for repo_name, repo_val in commit_stats_per_repo.items():
        num_additions += repo_val["additions"]
        num_deletions += repo_val["deletions"]
        num_files_changes += repo_val["changed_files"]
        num_total_commits += repo_val["commits"]

    print("Total additions: ", num_additions)
    print("Total deletions: ", num_deletions)
    print("Total files changed: ", num_files_changes)
    print("Total commits in merged PRs: ", num_total_commits)


import logging

from rest_framework import status

from rest_framework.views import APIView
from weibo_oauth import Weibo
from rest_framework.response import Response
from django.conf import settings
from rest_framework_jwt.settings import api_settings

from .models import OAuthWeiBoUser
from .serializers import WeiBoAuthUserSerializer
from .utils import generate_save_user_token
from ...utils.myresponse import APIResponse

logger = logging.getLogger("django")

class WeiBoOauthURLView(APIView):
    """拼接微博的请求url"""

    def get(self, request):
        # 提取前端传入的next参数记录用户从哪里去到login页面

        # 利用微博登陆工具对象
        oauth = Weibo(app_id=settings.APP_KEY, app_key=settings.APP_SECRET,
                      redirect_uri=settings.REDIRECT_URI)
        login_url = oauth.get_authorize_url()

        return APIResponse({'login_url': login_url})

class WeiBoAuthUserView(APIView):
    """微博登陆成功后的回调处理"""

    def get(self, request):
        # 获取前端传递code
        code = request.query_params.get("code")

        if not code:
            return Response({"message": "获取code失败"}, status=status.HTTP_400_BAD_REQUEST)
        # 创建微博登陆工具对象
        oauth = Weibo(app_id=settings.APP_KEY, app_key=settings.APP_SECRET,
                      redirect_uri=settings.REDIRECT_URI)

        # 调用方法获取access_token
        try:
            data = oauth.get_access_token(code)
            access_token = data.get('access_token')
            weibo_uid = oauth.get_token_uid(access_token)  # 获取到的微博token
        except Exception as e:
            return Response({"message": "调用微博接口异常"}, status=status.HTTP_503_SERVICE_UNAVAILABLE)
        existed = OAuthWeiBoUser.objects.filter(openid=weibo_uid).exists()

        if existed:
            userModel = OAuthWeiBoUser.objects.filter(openid=weibo_uid)
            user = userModel[0].user
            jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
            jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

            payload = jwt_payload_handler(user)
            token = jwt_encode_handler(payload)
            return APIResponse(
                {
                    'token': token,
                    'username': user.username,
                    'user_id': user.id
                }
            )
        else:
            acc_token_openid = generate_save_user_token(weibo_uid)
            return APIResponse({'access_token': acc_token_openid})

    def post(self, request):
        """openid绑定用户接口"""
        serializer = WeiBoAuthUserSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        user = serializer.save()

        jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
        jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

        payload = jwt_payload_handler(user)
        token = jwt_encode_handler(payload)

        return APIResponse({
            "token": token,
            "username": user.username,
            "user_id": user.id
        })


outfile_name = '500cargoes.txt'

# Number of cargoes
N = 500

## Script ( No need to edit below this) ########################################
##

# Internal import
import lib_Speculative as libS

# External imports
import os.path

fout = open(os.path.join('outputs', '500cargoes.txt'), 'w')
for i in range(N):
    stock = libS.GetOneCargo()
    fout.write('Cargo %d -------------------------\n'%(i+1)  + libS.PrettyPrint(stock) + '\n\n')
fout.close()


"""Tests for cell_img.image_grid.ts_index_lib."""

import copy

from absl.testing import absltest
from cell_img.image_grid import ts_index_lib
import numpy as np
import pandas as pd

class Single1DTest(absltest.TestCase):

  def test_get_index_individually(self):
    lookup = ts_index_lib._Single1D(
        ['zero', 'one', 'two', 'three', 'four', 'five'])
    self.assertEqual(lookup.get_index('five'), 5)
    self.assertEqual(lookup.get_index('one'), 1)
    self.assertEqual(lookup.get_index('four'), 4)
    self.assertEqual(lookup.get_index('three'), 3)
    self.assertEqual(lookup.get_index('two'), 2)
    self.assertEqual(lookup.get_index('zero'), 0)

  def test_get_index_multiple(self):
    lookup = ts_index_lib._Single1D(
        ['zero', 'one', 'two', 'three', 'four', 'five'])
    result = lookup.get_index(['two', 'five'])
    np.testing.assert_equal(result, [2, 5])

    result = lookup.get_index(np.array(['two', 'five']))
    np.testing.assert_equal(result, [2, 5])

    result = lookup.get_index(pd.Series(['two', 'five']))
    np.testing.assert_equal(result, [2, 5])

  def test_get_index_non_existent_raises(self):
    lookup = ts_index_lib._Single1D(
        ['zero', 'one', 'two', 'three', 'four', 'five'])
    with self.assertRaisesRegex(
        ValueError, 'Not all values of the query are in the index.'):
      lookup.get_index('six')
    with self.assertRaisesRegex(
        ValueError, 'Not all values of the query are in the index.'):
      lookup.get_index(['two', 'five', 'six'])

  def test_get_value_individually(self):
    lookup = ts_index_lib._Single1D(
        ['zero', 'one', 'two', 'three', 'four', 'five'])
    self.assertEqual(lookup.get_value(5), 'five')

  def test_get_value_multiple(self):
    lookup = ts_index_lib._Single1D(
        ['zero', 'one', 'two', 'three', 'four', 'five'])
    np.testing.assert_equal(lookup.get_value([2, 5]), ['two', 'five'])

  def test_bad_dimensions_raises(self):
    with self.assertRaisesRegex(ValueError, 'Expected 1D input but got.*'):
      ts_index_lib._Single1D([['A1', 'A2'], ['B1', 'B2']])

  def test_empty_raises(self):
    with self.assertRaisesRegex(ValueError, 'Input cannot be empty.'):
      ts_index_lib._Single1D([])

  def test_dim_length_one_works(self):
    lookup = ts_index_lib._Single1D(['one_value'])
    self.assertEqual(lookup.get_index('one_value'), 0)
    self.assertEqual(lookup.get_value(0), 'one_value')
    np.testing.assert_equal(
        lookup.get_index(['one_value', 'one_value']), [0, 0])
    np.testing.assert_equal(
        lookup.get_value([0, 0]), ['one_value', 'one_value'])

class Multi1DTest(absltest.TestCase):

  def get_three_level_lookup(self):
    coordinate_arrays = {
        'plate': ['plate0', 'plate1', 'plate2'],
        'well_col': ['1', '2', '3', '4', '5'],
        'site_col': ['site_col0', 'site_col1'],
    }
    coordinate_names = ['plate', 'well_col', 'site_col']

    lookup = ts_index_lib._Multi1D(coordinate_names, coordinate_arrays)
    return lookup

  def test_valid_missing_coords(self):
    valid_missing_coord_names = [['site_col',], ['site_col', 'well_col']]
    lookup = self.get_three_level_lookup()
    for coord_names in valid_missing_coord_names:
      # does not raise
      _ = lookup._check_valid_missing_coords(coord_names)

  def test_raises_when_not_smallest_coord(self):
    lookup = self.get_three_level_lookup()
    invalid_missing_coord_names = [['well_col',], ['plate']]
    for coord_names in invalid_missing_coord_names:
      with self.assertRaises(KeyError):
        lookup._check_valid_missing_coords(coord_names)

  def test_raises_when_all_missing(self):
    lookup = self.get_three_level_lookup()
    invalid_missing_coords = ['site_col', 'well_col', 'plate']
    with self.assertRaises(KeyError):
      lookup._check_valid_missing_coords(invalid_missing_coords)

  def test_raises_when_not_consecutive(self):
    lookup = self.get_three_level_lookup()
    invalid_missing_coords = ['site_col', 'plate']
    with self.assertRaises(KeyError):
      lookup._check_valid_missing_coords(invalid_missing_coords)

  def test_missing_coord_names_site(self):
    lookup = self.get_three_level_lookup()
    self.assertEqual(
        lookup._get_missing_coords({
            'plate': ['value1',],
            'well_col': ['value1',]
        }), ['site_col',])

  def test_missing_coord_names_site_well(self):
    lookup = self.get_three_level_lookup()
    self.assertEqual(
        lookup._get_missing_coords({
            'plate': ['value1',],
        }), ['well_col', 'site_col'])

  def test_get_well_level_smallest_block_size(self):
    lookup = self.get_three_level_lookup()
    well_level_labels = {'plate': ['plate0',], 'well_col': ['1',]}
    expected_block_size = 2  # 2 sites per well
    self.assertEqual(
        lookup.get_smallest_block_size(well_level_labels),
        expected_block_size)

  def test_get_plate_level_smallest_block_size(self):
    lookup = self.get_three_level_lookup()
    plate_level_labels = {'plate': ['plate0',]}
    expected_block_size = 2 * 5  # 2 sites per well, 5 wells per plate
    self.assertEqual(
        lookup.get_smallest_block_size(plate_level_labels),
        expected_block_size)

  def test_get_index_two_level(self):
    names = ['year', 'month']
    name_to_values = {
        'year': ['2019', '2020', '2021'],
        'month': [
            'jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', 'aug', 'sep',
            'oct', 'nov', 'dec'
        ]
    }
    lookup = ts_index_lib._Multi1D(names, name_to_values)
    self.assertEqual(lookup.get_index({'year': '2019', 'month': 'jan'}), 0)
    self.assertEqual(lookup.get_index({'year': '2019', 'month': 'aug'}), 7)
    self.assertEqual(lookup.get_index({'year': '2020', 'month': 'aug'}), 19)
    self.assertEqual(lookup.get_index({'year': '2021', 'month': 'aug'}), 31)
    self.assertEqual(lookup.get_index({'year': '2021', 'month': 'dec'}), 35)

    np.testing.assert_equal(
        lookup.get_index({
            'year': ['2019', '2019', '2020', '2021', '2021'],
            'month': ['jan', 'aug', 'aug', 'aug', 'dec']
        }), [0, 7, 19, 31, 35])

  def test_get_index_non_existent_raises(self):
    names = ['year', 'month']
    name_to_values = {
        'year': ['2019', '2020', '2021'],
        'month': [
            'jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', 'aug', 'sep',
            'oct', 'nov', 'dec'
        ]
    }
    lookup = ts_index_lib._Multi1D(names, name_to_values)
    with self.assertRaisesRegex(
        ValueError, 'Not all values of the query are in the index.'):
      lookup.get_index({'year': '2021', 'month': 'NON_EXISTENT'})
    with self.assertRaisesRegex(
        ValueError, 'Not all values of the query are in the index.'):
      lookup.get_index({
          'year': ['2020', '2021'],
          'month': ['feb', 'NON_EXISTENT']
      })

  def test_get_index_individually(self):
    names = ['x', 'y', 'z']
    name_to_values = {
        'x': ['x0', 'x1', 'x2'],
        'y': ['y0', 'y1', 'y2', 'y3'],
        'z': ['z0', 'z1']
    }
    lookup = ts_index_lib._Multi1D(names, name_to_values)
    self.assertEqual(lookup.get_index({'x': 'x0', 'y': 'y0', 'z': 'z0'}), 0)
    self.assertEqual(lookup.get_index({'x': 'x1', 'y': 'y2', 'z': 'z1'}), 13)
    self.assertEqual(lookup.get_index({'x': 'x2', 'y': 'y3', 'z': 'z1'}), 23)

  def test_get_index_multiple(self):
    names = ['x', 'y', 'z']
    name_to_values = {
        'x': ['x0', 'x1', 'x2'],
        'y': ['y0', 'y1', 'y2', 'y3'],
        'z': ['z0', 'z1']
    }
    lookup = ts_index_lib._Multi1D(names, name_to_values)
    results = lookup.get_index({
        'x': ['x0', 'x1'],
        'y': ['y0', 'y2'],
        'z': ['z0', 'z1']
    })
    np.testing.assert_equal(results, [0, 13])

  def test_get_index_exhaustive(self):
    names = ['x', 'y', 'z']
    name_to_values = {
        'x': ['x0', 'x1', 'x2'],
        'y': ['y0', 'y1', 'y2', 'y3'],
        'z': ['z0', 'z1']
    }
    lookup = ts_index_lib._Multi1D(names, name_to_values)

    i = 0
    for x in name_to_values['x']:
      for y in name_to_values['y']:
        for z in name_to_values['z']:
          self.assertEqual(lookup.get_index({'x': x, 'y': y, 'z': z}), i)
          i += 1

class TensorstoreIndexTest(absltest.TestCase):

  def setUp(self):
    super().setUp()
    coordinate_arrays = {
        'batch': ['batch0', 'batch1'],
        'plate': ['plate0', 'plate1', 'plate2'],
        'well_row': ['A', 'B', 'C', 'D'],
        'well_col': ['1', '2', '3', '4', '5'],
        'site_row': ['site_row0', 'site_row1'],
        'site_col': ['site_col0', 'site_col1'],
        'stain': ['stain0', 'stain1']
    }
    axes = ['X', 'Y', 'stain']
    axes_wrap = {
        'X': ['plate', 'well_col', 'site_col'],
        'Y': ['batch', 'well_row', 'site_row']
    }
    image_shape = (480, 640)
    unit_sizes = {'X': image_shape[1], 'Y': image_shape[0]}

    self.lookup = ts_index_lib.TensorstoreIndex(axes, axes_wrap,
                                                coordinate_arrays, unit_sizes)

  def test_get_dimensions(self):
    self.assertEqual(self.lookup.get_dimensions(), [19200, 7680, 2])

  def test_get_coords_individually(self):
    query = {
        'batch': 'batch0',
        'plate': 'plate0',
        'well_row': 'A',
        'well_col': '1',
        'site_row': 'site_row0',
        'site_col': 'site_col0',
        'stain': 'stain0',
    }
    self.assertEqual(self.lookup.get_coords(query), [0, 0, 0])
    # Move along the stain coordinate by one.
    query['stain'] = 'stain1'
    self.assertEqual(self.lookup.get_coords(query), [0, 0, 1])
    # Move along the Y coordinate by one image by going to the second site_row.
    query['site_row'] = 'site_row1'
    self.assertEqual(self.lookup.get_coords(query), [0, 480, 1])
    # Move along the X coordinate by one image by going to the second site_col.
    query['site_col'] = 'site_col1'
    self.assertEqual(self.lookup.get_coords(query), [640, 480, 1])

  def test_get_coords_raises_when_missing_key(self):
    valid_query = {
        'batch': 'batch0',
        'plate': 'plate0',
        'well_row': 'A',
        'well_col': '1',
        'site_row': 'site_row0',
        'site_col': 'site_col0',
        'stain': 'stain0',
    }
    # valid_query should not raise.
    _ = self.lookup.get_coords(valid_query)
    # Assert that it raises when the query is missing a key
    invalid_missing_keys = ['batch', 'plate', 'well_row', 'well_col', 'stain']
    for k in invalid_missing_keys:
      query = copy.deepcopy(valid_query)
      del query[k]
      with self.assertRaises(KeyError):
        self.lookup.get_coords(query)

  def test_get_coords_valid_when_missing_key(self):
    valid_query = {
        'batch': 'batch0',
        'plate': 'plate0',
        'well_row': 'B',
        'well_col': '2',
        'site_row': 'site_row1',
        'site_col': 'site_col1',
        'stain': 'stain0',
    }
    # valid_query should not raise.
    valid_coords = np.array([640*3, 480*3, 0])
    self.assertEqual(self.lookup.get_coords(valid_query), list(valid_coords))
    # Assert that it doesn't raise when missing smallest key(s)
    # drop site_row
    query = copy.deepcopy(valid_query)
    del query['site_row']
    expected_coords = valid_coords - np.array([0, 480, 0])
    self.assertEqual(self.lookup.get_coords(query), list(expected_coords))

    # drop [well_col, site_ col]
    query = copy.deepcopy(valid_query)
    del query['site_col']
    del query['well_col']
    expected_coords = valid_coords - np.array([640*3, 0, 0])
    self.assertEqual(self.lookup.get_coords(query), list(expected_coords))

  def test_get_block_sizes(self):
    valid_query = {
        'batch': 'batch0',
        'plate': 'plate0',
        'well_row': 'B',
        'well_col': '2',
        'site_row': 'site_row1',
        'site_col': 'site_col1',
        'stain': 'stain0',
    }
    # All dimensions are present, size should be 1 * unit_sizes
    self.assertEqual(self.lookup.get_block_sizes(valid_query), [640, 480, 1])

  def test_get_block_sizes_missing_site(self):
    valid_query = {
        'batch': 'batch0',
        'plate': 'plate0',
        'well_row': 'B',
        'well_col': '2',
        'stain': 'stain0',
    }
    # Missing sites, so sizes should be num_sites_per_well * unit_sizes
    self.assertEqual(
        self.lookup.get_block_sizes(valid_query), [2 * 640, 2 * 480, 1])

  def test_get_block_sizes_missing_site_well(self):
    valid_query = {
        'batch': 'batch0',
        'plate': 'plate0',
        'stain': 'stain0',
    }
    # Missing sites and wells, so sizes should be
    # num_wells_per_plate * num_sites_per_well * unit_sizes
    self.assertEqual(
        self.lookup.get_block_sizes(valid_query), [10 * 640, 8 * 480, 1])

  def test_get_coords_with_dataframe(self):
    query_df = pd.DataFrame.from_dict({
        'batch': ['batch0', 'batch0'],
        'plate': ['plate0', 'plate0'],
        'well_row': ['A', 'A'],
        'well_col': ['1', '1'],
        'site_row': ['site_row0', 'site_row1'],
        'site_col': ['site_col0', 'site_col1'],
        'stain': ['stain0', 'stain1'],
    })
    coords_dict = self.lookup.get_coords_dict(query_df)
    self.assertSameElements(coords_dict.keys(), ['X', 'Y', 'stain'])
    np.testing.assert_equal(coords_dict['X'], [0, 640])
    np.testing.assert_equal(coords_dict['Y'], [0, 480])
    np.testing.assert_equal(coords_dict['stain'], [0, 1])

  def test_get_whole_image_slice(self):
    valid_query = {
        'batch': 'batch0',
        'plate': 'plate0',
        'well_row': 'A',
        'well_col': '1',
        'site_row': 'site_row0',
        'site_col': 'site_col0',
        'stain': 'stain0',
    }
    whole_img = self.lookup.get_whole_image_slice(valid_query)
    np.testing.assert_equal(whole_img[0], slice(0, 640, None))
    np.testing.assert_equal(whole_img[1], slice(0, 480, None))
    np.testing.assert_equal(whole_img[2], 0)

  def test_get_whole_image_slice_fails_on_multiple_labels(self):
    invalid_query = {
        'batch': ['batch0', 'batch0'],
        'plate': ['plate0', 'plate0'],
        'well_row': ['A', 'A'],
        'well_col': ['1', '1'],
        'site_row': ['site_row0', 'site_row1'],
        'site_col': ['site_col0', 'site_col1'],
        'stain': ['stain0', 'stain1'],
    }
    with self.assertRaises(TypeError):
      _ = self.lookup.get_whole_image_slice(invalid_query)

  def test_get_square_patch_slice(self):
    valid_query = {
        'batch': 'batch0',
        'plate': 'plate0',
        'well_row': 'A',
        'well_col': '1',
        'site_row': 'site_row0',
        'site_col': 'site_col0',
        'stain': 'stain0',
    }
    offsets = {'X': 16, 'Y': 16}
    patch_size = 32
    slice_img = self.lookup.get_square_patch_slice(
        valid_query, offsets, patch_size)
    np.testing.assert_equal(slice_img[0], slice(0, 32, None))
    np.testing.assert_equal(slice_img[1], slice(0, 32, None))
    np.testing.assert_equal(slice_img[2], 0)

  def test_get_square_patch_slice_fails_offset_not_used(self):
    valid_query = {
        'batch': 'batch0',
        'plate': 'plate0',
        'well_row': 'A',
        'well_col': '1',
        'site_row': 'site_row0',
        'site_col': 'site_col0',
        'stain': 'stain0',
    }
    # There is no 'Z' axis
    offsets = {'X': 16, 'Y': 16, 'Z': 16}
    patch_size = 32
    with self.assertRaises(ValueError):
      self.lookup.get_square_patch_slice(valid_query, offsets, patch_size)

  def test_get_square_patch_slice_fails_across_whole_images(self):
    valid_query = {
        'batch': 'batch0',
        'plate': 'plate0',
        'well_row': 'A',
        'well_col': '1',
        'site_row': 'site_row0',
        'site_col': 'site_col0',
        'stain': 'stain0',
    }
    # Make a patch before the first site
    offsets = {'X': 0, 'Y': 0}
    patch_size = 32
    with self.assertRaises(ValueError):
      self.lookup.get_square_patch_slice(valid_query, offsets, patch_size)
    # Make a patch across the first and second site
    offsets = {'X': 630, 'Y': 0}
    patch_size = 32
    with self.assertRaises(ValueError):
      self.lookup.get_square_patch_slice(valid_query, offsets, patch_size)
    # Make a patch across the first and second site in the Y direction
    offsets = {'X': 0, 'Y': 450}
    patch_size = 32
    with self.assertRaises(ValueError):
      self.lookup.get_square_patch_slice(valid_query, offsets, patch_size)
    # No exception if we turn off the require_within_single_image flag.
    offsets = {'X': 630, 'Y': 0}
    patch_size = 32
    self.lookup.get_square_patch_slice(valid_query, offsets, patch_size,
                                       require_within_single_image=False)

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


#!/usr/bin/env python3
import argparse
import urllib.parse
import os
import sys
import shutil
import subprocess
from ruamel import yaml

yaml.rload = lambda *z: yaml.load(*z, Loader=yaml.RoundTripLoader)
yaml.rdump = lambda *z: yaml.dump(*z, Dumper=yaml.RoundTripDumper)

def main():
    template = yaml.rload(open('install.dist.yml'))

    # Parse the arguments once to look for the profile.
    args = parser(template, partial=True).parse_args()

    # If the profile exists, load that instead.
    if os.path.isfile(args.profile):
        template = yaml.rload(open(args.profile))

    # Reparse the arguments with new defaults.
    args = parser(template).parse_args()

    profile = generate_profile(template, args)
    yaml.rdump(profile, open(args.profile, 'w'))

def generate_profile(profile, args):
    profile['config']['xmpp']['domain'] = args.domain

    args.protocol = args.protocol or ((args.websocket and 'ws' or 'http') + (args.secure and 's' or ''))
    args.host = args.host or args.domain
    args.path = args.path or (args.websocket and '/websocket' or '/http-bind')
    args.port = args.port or str(5280 + args.secure)

    profile['config']['xmpp']['url'] = args.url or args.protocol + '://' + args.host + ':' + args.port + args.path

    profile['config']['xmpp']['muc'] = args.muc or 'conference.' + args.domain

    packs = {folder for folder in os.listdir('emoticon-packs')
            if os.path.isfile('emoticon-packs/{}/emoticons.yml'.format(folder))}
    profile['install']['packs'] = sorted(packs)

    if 'version' not in profile['config'] and os.path.isdir('.git'):
        p = subprocess.run(['git', 'describe'], stdout=subprocess.PIPE)
        profile['config']['version'] = p.stdout.decode('utf8').strip()

    styles = {x[:-4] for x in os.listdir('assets/css/alt/') if x[-4:] == '.css'}
    profile['install']['styles'] = sorted(styles)

    languages = {x[:-4] for x in os.listdir('locales/') if x[-4:] == '.yml'}
    profile['install']['languages'] = sorted(languages)

    profile['install']['target'] = args.target or profile['install']['target']

    return profile

def parser(defaults, partial=False):
    domain = defaults['config']['xmpp']['domain']
    url = urllib.parse.urlparse(defaults['config']['xmpp']['url'] or '')

    #m = re.match('^(?:\[(?P<ip6>.*)\]|(?P<host>.*))(?::(?P<port>\d+))', url.netloc)

    websocket = url.scheme in ('ws', 'wss')
    secure = url.scheme in ('wss', 'https')
    custom_scheme = url.scheme not in ('ws', 'wss', 'http', 'https')
    custom_port = url.port not in (5280, 5281)
    custom_path = url.path not in ('/websocket', '/http-bind')
    custom_host = url.hostname != domain

    muc = defaults['config']['xmpp']['muc']
    custom_muc = domain and (muc != 'conference.' + domain)
    parser = argparse.ArgumentParser(
      prog='./configure.py',
      description='''Configure cadence for installation.
    '''
      )
    parser.add_argument(
      '-s', '--secure', '--https', action='store_const',
      help='Generate secure URLs (append "s" and increment port number)', dest='secure', const=True, default=secure
      )
    parser.add_argument(
      '-ws', '--websocket', action='store_const',
      help='Use websocket instead of BOSH', dest='websocket', const=True, default=websocket
      )
    parser.add_argument(
      '--domain', type=str,
      help='XMPP domain to log in on.', dest='domain', metavar='DOMAIN', required=not partial and not domain,
      default=domain
      )
    parser.add_argument(
      '--protocol', type=str,
      help='Protocol\n[(ws|http)s?]', dest='protocol', metavar='PROTOCOL', default=custom_scheme and url.scheme or ''
      )
    parser.add_argument(
      '--host', type=str,
      help='Hostname\n[DOMAIN]', dest='host', metavar='HOST', default=custom_host and url.hostname or ''
      )
    parser.add_argument(
      '--port', type=str,
      help='Port\n[5280|5281]', dest='port', metavar='PORT', default=custom_port and url.port or ''
      )
    parser.add_argument(
      '--path', type=str,
      help='Path\n[/http-bind|/websocket]', dest='path', metavar='PATH', default=custom_path and url.path or ''
      )
    parser.add_argument(
      '--url', '--bosh', type=str,
      help='Socket URL to connect to [PROTOCOL://HOST:PORT/PATH]', metavar='URL', dest='url', default=''
      )
    parser.add_argument(
      '--session-auth', type=str,
      help='The URL to use for session authentication.', metavar='AUTH', dest='session_auth', default=defaults['config']['xmpp']['sessionAuth']
      )
    parser.add_argument(
      '--muc', type=str,
      help='The MUC conference server to connect to.', metavar='MUC', dest='muc', default=custom_muc and muc or ''
      )
    parser.add_argument(
      '--profile', type=str,
      help='Where to put the configuration file. ["install.yml"]', dest='profile', default='install.yml'
    )
    parser.add_argument(
      '--target', type=str,
      help='Installation target. ["."]', dest='target', default=''
    )

    return parser

main()


from aiogram.types import ReplyKeyboardRemove, \
    ReplyKeyboardMarkup, KeyboardButton, \
    InlineKeyboardMarkup, InlineKeyboardButton

from parserVK import WallParse
from db import Postgers

parser = WallParse()
db = Postgers()

def write_kb(user_id):
	domains = db.get_domains(user_id)

	domains_kb = ReplyKeyboardMarkup(resize_keyboard=False, one_time_keyboard=True)

	for domain in domains:
		pub_name = parser.get_pub_name(domain[0])

		pub_name_btn = KeyboardButton(pub_name + ' / '+ str(domain[0]))
		domains_kb.add(pub_name_btn)

	return domains_kb

# write_kb(1365882584)


from black import re
from code_challenges.stack_and_queue.stack import Stack

class PseudoQueue:
    def __init__(self):
        self.top = None
        self.stack1 = Stack()
        self.stack2 = Stack()

    # a method to push values in stack1
    def enqueue(self, value):
        self.stack1.push(value)
    # a method to add items popped out from stack1 into stack2 using push method and then return values when dequeue called
    def dequeue(self):
        if self.stack2.isEmpty():
            if self.stack1.isEmpty():
                print("Stack is empty")

        while not self.stack1.isEmpty():
            item = self.stack1.pop()
            self.stack2.push(item)
            #print("stack2: ", self.stack2)
        return_value = self.stack2.pop()
        return return_value

    # a methoded to print string representation of the elements
    def __str__(self):
        stack = " "
        if self.stack1.isEmpty():
            current = self.stack2.top

        if self.stack2.isEmpty():
            current = self.stack1.top
        if self.stack2.isEmpty() and self.stack1.isEmpty():
            empty = "Stack is empty"
            return empty
        while(current):
            stack += (f'{{ {current.value} }} -> ')
            current = current.next
        stack = (f'{stack}NULL')
        return stack

if __name__ == "__main__":
    que = PseudoQueue()
    que.enqueue(1)
    que.enqueue(2)
    que.enqueue(3)
    que.dequeue()

    print(que.__str__())


def makeline(symb, len, dir):
    if dir == "Горизонтальная":
        print(*[symb for x in range(len)], sep='')

    elif dir == 'Вертикальная':
        for i in range(int(len)):
            print(symb)
    else:
        print('Введены неверные операции')
makeline('%', 3, 'Горизонтальная')
print("------")
makeline(';)', 5, 'Вертикальная')
print("------")
makeline(';)', 5, 'Какой-то бред')


# All rights reserved by forest fairy.
# You cannot modify or share anything without sacrifice.
# If you don't agree, keep calm and don't look at code bellow!

__author__ = "VirtualV <https://github.com/virtualvfix>"
__date__ = "11/30/2017 10:32 AM"

import asyncio
from config import CONFIG
from .config import FILTERS_NAMES

class Wait:
    """
    Unittest await help tools
    """

    @staticmethod
    async def wait_for_available_cases():
        """
        Waiting till TestCases are loaded to CONFIG
        """
        while True:
            if CONFIG.UNITTEST.AVAILABLE_TEST_CASES is not None:
                break
            await asyncio.sleep(0)

    @staticmethod
    async def wait_for_selected_cases():
        """
        Waiting till TestCases are filtered according to selection criteria
        """
        while True:
            if CONFIG.UNITTEST.SELECTED_TEST_CASES is not None:
                break
            await asyncio.sleep(0)

    @staticmethod
    async def wait_for_selected_suites():
        """
        Waiting till TestSuites are filtered according to selection criteria
        """
        # wait selected cases
        await Wait.wait_for_selected_cases()

        while True:
            if False not in [True if FILTERS_NAMES['suite_select'] in x['filters'] else False
                             for x in CONFIG.UNITTEST.SELECTED_TEST_CASES]:
                break
            await asyncio.sleep(0)

    @staticmethod
    async def wait_for_load_tests():
        """
        Waiting till Tests are loaded for selected TestSuites
        """
        # wait selected TestSuites
        await Wait.wait_for_selected_suites()
        while True:
            if False not in [True if FILTERS_NAMES['test_load'] in x['filters'] else False
                             for x in CONFIG.UNITTEST.SELECTED_TEST_CASES]:
                break
            await asyncio.sleep(0)

    @staticmethod
    async def wait_for_selected_tests():
        """
        Waiting till Tests are filtered according to selection criteria
        """
        # wait selected suites
        await Wait.wait_for_load_tests()

        while True:
            if False not in [True if FILTERS_NAMES['test_select'] in x['filters'] else False
                             for x in CONFIG.UNITTEST.SELECTED_TEST_CASES]:
                break
            await asyncio.sleep(0)

    @staticmethod
    async def wait_for_device():
        """
        Waiting till device detected
        """
        pass


import pygame

from tic_tac_toe.game_manager import GameManager
from tic_tac_toe.constans import SCREEN_SIZE, BACKGROUND_COLOR

pygame.init()

screen = pygame.display.set_mode(SCREEN_SIZE)
clock = pygame.time.Clock()

game_manager = GameManager(main_screen=screen)
game_manager.init_game()

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            raise SystemExit
        if event.type == pygame.MOUSEBUTTONUP and event.button == pygame.BUTTON_LEFT:
            game_manager.handle_click(pygame.mouse.get_pos())

    screen.fill(BACKGROUND_COLOR)
    game_manager.draw()

    pygame.display.flip()

    clock.tick(60)


import time, pytest, inspect
import utils
from utils import run_brave, create_config_file
from PIL import Image

'''
Does the mixer correctly position inputs, so that we can do picture-in-picture or a video-wall?
'''

def test_mixer_positioning(run_brave, create_config_file):
    subtest_start_brave_with_multiple_positioned_inputs(run_brave, create_config_file)
    subtest_move_input3_right()
    subtest_cut_with_position_and_size()
    subtest_cut_by_setting_source_property()

def subtest_start_brave_with_multiple_positioned_inputs(run_brave, create_config_file):
    config = {
        'inputs': [
            {'type': 'test_video', 'pattern': 3}, # white
            {'type': 'test_video', 'pattern': 4}, # red
            {'type': 'test_video', 'pattern': 5}, # green
            {'type': 'test_video', 'pattern': 6}, # blue
        ],
        'mixers': [
            {'width': 160, 'height': 90, 'pattern': 2, 'sources': [
                { 'uid': 'input1', 'zorder': 1 },
                { 'uid': 'input2', 'zorder': 2, 'width': 80 },
                { 'uid': 'input3', 'zorder': 3, 'width': 80, 'height': 45 },
                { 'uid': 'input4', 'zorder': 4, 'xpos': 80, 'ypos': 45 }
            ]}
        ],
        'outputs': [{'type': 'image', 'width': 160, 'height': 90}]
    }
    config_file = create_config_file(config)
    run_brave(config_file.name)
    utils.check_brave_is_running()
    time.sleep(4)
    utils.assert_everything_in_playing_state()
    utils.assert_mixers([{
        'id': 1,
        'sources': [
            {'uid': 'input1', 'in_mix': True, 'zorder': 1},
            {'uid': 'input2', 'in_mix': True, 'zorder': 2, 'width': 80},
            {'uid': 'input3', 'in_mix': True, 'zorder': 3, 'width': 80, 'height': 45},
            {'uid': 'input4', 'in_mix': True, 'zorder': 4, 'xpos': 80, 'ypos': 45}
        ]
    }])

    im = utils.get_raw_image_for_output(1)
    utils.assert_image_color_at_dimension(im, (10,10), (0, 255, 0))
    utils.assert_image_color_at_dimension(im, (150,10), (255, 255, 255))
    utils.assert_image_color_at_dimension(im, (10, 80), (255, 0, 0))
    utils.assert_image_color_at_dimension(im, (150,80), (0, 0, 255))

def subtest_move_input3_right():
    utils.overlay_source('input3', 1, details={'xpos': 80})
    utils.assert_mixers([{
        'id': 1,
        'sources': [
            {'uid': 'input1', 'in_mix': True, 'zorder': 1},
            {'uid': 'input2', 'in_mix': True, 'zorder': 2, 'width': 80},
            {'uid': 'input3', 'in_mix': True, 'zorder': 3, 'xpos': 80, 'width': 80, 'height': 45},
            {'uid': 'input4', 'in_mix': True, 'zorder': 4, 'xpos': 80, 'ypos': 45}
        ]
    }])
    time.sleep(3)
    # Top-right now green, top-left falls back to red
    im = utils.get_raw_image_for_output(1)
    utils.assert_image_color_at_dimension(im, (10,10), (255, 0, 0))
    utils.assert_image_color_at_dimension(im, (150,10), (0, 255, 0))
    utils.assert_image_color_at_dimension(im, (10, 80), (255, 0, 0))
    utils.assert_image_color_at_dimension(im, (150,80), (0, 0, 255))

def subtest_cut_with_position_and_size():
    # 'Cut' rather than 'overlay' will remove all other sources
    # 'width' and 'height' are bigger than the mixer
    # xpos not being set, so should retain the value from earlier.
    utils.cut_to_source('input4', 1, details={'ypos': 0, 'width': 300, 'height': 300})
    time.sleep(0.5)
    utils.assert_mixers([{
        'id': 1,
        'sources': [
            {'uid': 'input1', 'in_mix': False, 'zorder': 1},
            {'uid': 'input2', 'in_mix': False, 'zorder': 2, 'width': 80},
            {'uid': 'input3', 'in_mix': False, 'zorder': 3, 'xpos': 80, 'width': 80, 'height': 45},
            {'uid': 'input4', 'in_mix': True, 'zorder': 4, 'xpos': 80, 'ypos': 0, 'width': 300, 'height': 300}
        ]
    }])

    time.sleep(3)
    # Right-hand-side blue, left-hand-side black
    im = utils.get_raw_image_for_output(1)
    utils.assert_image_color_at_dimension(im, (10,10), (0, 0, 0))
    utils.assert_image_color_at_dimension(im, (150,10), (0, 0, 255))
    utils.assert_image_color_at_dimension(im, (10, 80), (0, 0, 0))
    utils.assert_image_color_at_dimension(im, (150,80), (0, 0, 255))

def subtest_cut_by_setting_source_property():
    utils.update_mixer(1, {'sources': [
        {'uid': 'input1'},
        {'uid': 'input4', 'xpos': 0, 'height': 45}
    ]})
    time.sleep(0.5)
    utils.assert_mixers([{
        'id': 1,
        'sources': [
            {'uid': 'input1', 'in_mix': True, 'zorder': 1},
            {'uid': 'input2', 'in_mix': False, 'zorder': 2, 'width': 80},
            {'uid': 'input3', 'in_mix': False, 'zorder': 3, 'xpos': 80, 'width': 80, 'height': 45},
            {'uid': 'input4', 'in_mix': True, 'zorder': 4, 'xpos': 0, 'ypos': 0, 'width': 300, 'height': 45}
        ]
    }])

    time.sleep(3)
    # Top blue, bottom white
    im = utils.get_raw_image_for_output(1)
    utils.assert_image_color_at_dimension(im, (10,10), (0, 0, 255))
    utils.assert_image_color_at_dimension(im, (150,10), (0, 0, 255))
    utils.assert_image_color_at_dimension(im, (10, 80), (255, 255, 255))
    utils.assert_image_color_at_dimension(im, (150,80), (255, 255, 255))


def primefactors(n):
    if n < 2:
        print("Cannot be factored")
    else:
        factor = 2
        while factor <= n:
            if n % factor == 0:
                print(factor)
                n /= factor
            else:
                factor += 1

n = int(input("Enter a number (2 or greater): "))
print("The prime factors of", n, "are: ")
primefactors(n)


__license__ = "MIT"
__author__ = "Augusto Cunha, Axelle Pochet"
__email__ = "acunha@tecgraf.puc-rio.br, axelle@tecgraf.puc-rio.br"
__credits__ = ["Augusto Cunha", "Axelle Pochet", "Helio Lopes", "Marcelo Gattass"]

from tensorflow.keras import backend as K
# K.set_image_dim_ordering('tf')
# K.set_image_data_format('channels_last')

import tensorflow as tf
config = tf.ConfigProto()
config.gpu_options.allow_growth=True
K.set_session(tf.Session(config=config))

import gc
import cv2, os, numpy, sys
import pandas as pd
import multiprocessing
import time

from tensorflow.keras.models import model_from_json, Sequential
from joblib import Parallel, delayed

numpy.random.seed(1337)

# Reset Keras Session
def reset_keras(base_model, model):
    sess = K.get_session()
    K.clear_session()
    sess.close()
    sess = K.get_session()

    try:
        del base_model
        del model
    except:
        pass

    print(gc.collect()) # if it's done something you should see a number being outputted

    # use the same config as you used to create the session
    config = tf.ConfigProto()
    config.gpu_options.allow_growth=True
    #config.gpu_options.visible_device_list = "0"
    K.set_session(tf.Session(config=config))

def processPatches(data, patch_size, pixel_step, resize, nb_channels):
    # get data
    if isinstance(data, pd.DataFrame):
        section_mat = data.values
    else:
        section_mat = data
    half_patch = int(patch_size/2)

    # get image info
    nb_rows = data.shape[0]
    nb_cols = data.shape[1]
    #print(nb_rows)
    #print(nb_cols)

    count_patches = 0
    patch_name_list = []
    patch_list = []
    for i in range (half_patch, nb_rows - half_patch, pixel_step):
        for j in range (half_patch, nb_cols - half_patch, pixel_step):
            # create patch
            start_row = i - half_patch
            start_col = j - half_patch
            patch =  numpy.zeros((patch_size,patch_size)) # 1 empty patch
            for x in range(patch_size):
                for y in range(patch_size):
                    patch[x][y] = section_mat[start_row + x][start_col + y]
            # resize, clip
            patch = cv2.resize(patch, dsize=(resize, resize), interpolation=cv2.INTER_CUBIC)
            patch = numpy.clip(patch, -1., 1.)
            # append to global list
            patch_list.append(patch)
            patch_name = 'patch_p_' + str(i) + '_' + str(j) + '.csv'
            patch_name_list.append(patch_name)
            # count
            count_patches +=1

    return patch_list, patch_name_list

def classify(input_dir, patch_size, resize_size, pixel_step, jsonModelFilePath, weightsFilePath, modelName):
    start_time = time.time()

    # set params
    resize = resize_size
    imageChannels = 1

    # create output directory
    directory = "output/classification/"
    if not os.path.exists(directory):
        os.makedirs(directory)

    # read all files in 1 step
    df_list = []
    df_names = []
    files = os.listdir(input_dir)
    for i in range(0, len(files)):
        filename = files[i]
        section_name = filename.split('_')[0]
        df = pd.read_csv(input_dir + filename, delimiter=' ', header = None)
        df_list.append(df)
        df_names.append(modelName + "_" + section_name)

    # load model
    jsonModelFile = open(jsonModelFilePath, 'r' )
    base_model = jsonModelFile.read()
    jsonModelFile.close()
    model = model_from_json(base_model)
    model.load_weights(weightsFilePath)
    model.compile( loss='binary_crossentropy', optimizer='sgd', metrics=[ 'accuracy' ] )

    # prepare save prediction for all sections
    nb_sections = len(df_list)

    # create patches in parrallel
    s = 0
    nb_section = len(df_list)
    section_step = 4
    while 1 :
        s_init = s

        if(s == nb_section):
            break

        if(s+section_step > len(df_list)):
            df_sub_list = df_list[s:len(df_list)]
            s = nb_section
        else:
            df_sub_list = df_list[s:s+section_step]
            s = s+section_step

        print("Creating patches...")
        num_cores = multiprocessing.cpu_count()
        results = Parallel(n_jobs=num_cores, verbose = 100)(delayed(processPatches)(i,  patch_size, pixel_step, resize, imageChannels) for i in df_sub_list)
        current_sections_patch_lists, current_sections_patch_name_lists = zip(*results)

        # classify and save
        current_sections_prediction_lists = []
        for i in range(0, len(current_sections_patch_lists)):
            print("Classifying section " + str(s_init + i + 1) + "/" + str(nb_section))
            patch_list = current_sections_patch_lists[i]
            patches = numpy.array( patch_list )
            patches = patches.reshape( patches.shape[0], resize, resize, imageChannels)
            patches = patches.astype( 'float32' )
            # classify
            classesPredictionList = []
            classesPredictionList = model.predict_classes(patches)
            current_sections_prediction_lists.append(classesPredictionList)

        print("Writing classification files...")
        for i in range(0, len(current_sections_patch_lists)):
            print("Section " + df_names[s_init + i])
            predictionsFile = open(directory + 'classification_' + df_names[s_init + i] + '.txt', 'w')
            for j in range(0, len(current_sections_prediction_lists[i])):
                patch_name = current_sections_patch_name_lists[i][j]
                prediction = current_sections_prediction_lists[i][j]
                predictionsFile.write( patch_name + " " + str(prediction) + "\n" )
            predictionsFile.close()

    reset_keras(base_model,model)
    print("--- %s seconds ---" % (time.time() - start_time))

def classifySVM(input_dir, patch_size, resize_size, pixel_step, jsonModelFilePath, weightsFilePath, modelName, svmModelPath):
    start_time = time.time()

    # set params
    resize = resize_size # todo = read from json model
    imageChannels = 1

    # create output directory
    directory = "output/classification/"
    if not os.path.exists(directory):
        os.makedirs(directory)

    # read all files in 1 step
    df_list = []
    df_names = []
    files = os.listdir(input_dir)
    for i in range(0, len(files)):
        filename = files[i]
        section_name = filename.split('_')[0]
        df = pd.read_csv(input_dir + filename, delimiter=' ', header = None)
        df_list.append(df)
        df_names.append(modelName + "_" + section_name)

    # load CNN
    jsonModelFile = open(jsonModelFilePath, 'r' )
    jsonModel = jsonModelFile.read()
    jsonModelFile.close()
    base_model = model_from_json(jsonModel)
    base_model.load_weights(weightsFilePath)
    #------ delete last layers -------
    model = Sequential(base_model.layers[:-7])

    #------ Load SVM
    from sklearn.externals import joblib
    clf = joblib.load(svmModelPath)

    # prepare save prediction for all sections
    nb_sections = len(df_list)

    # create patches in parrallel
    s = 0
    nb_section = len(df_list)
    section_step = 4
    while 1 :

        s_init = s

        if(s == nb_section):
            break

        if(s+section_step > len(df_list)):
            df_sub_list = df_list[s:len(df_list)]
            s = nb_section
        else:
            df_sub_list = df_list[s:s+section_step]
            s = s+section_step

        print("Creating patches...")
        num_cores = multiprocessing.cpu_count()
        results = Parallel(n_jobs=num_cores, verbose = 100)(delayed(processPatches)(i,  patch_size, pixel_step, resize, imageChannels) for i in df_sub_list)
        current_sections_patch_lists, current_sections_patch_name_lists = zip(*results) # returns tuples :/

        # classify and save
        current_sections_prediction_lists = []
        for i in range(0, len(current_sections_patch_lists)):
            print("Classifying section " + str(s_init + i + 1) + "/" + str(nb_section))
            patch_list = current_sections_patch_lists[i]
            patches = numpy.array( patch_list )
            patches = patches.reshape( patches.shape[0], resize, resize, imageChannels)
            patches = patches.astype( 'float32' )
            # classify
            classesPredictionList = []
            features = model.predict(patches)
            classesPredictionList = clf.predict(features)
            current_sections_prediction_lists.append(classesPredictionList)

        print("Writing classification files...")
        for i in range(0, len(current_sections_patch_lists)):
            print("Section " + df_names[s_init + i])
            predictionsFile = open(directory + 'classification_' + df_names[s_init + i] + '.txt', 'w')
            for j in range(0, len(current_sections_prediction_lists[i])):
                patch_name = current_sections_patch_name_lists[i][j]
                prediction = current_sections_prediction_lists[i][j]
                predictionsFile.write( patch_name + " " + str(prediction) + "\n" )
            predictionsFile.close()

    reset_keras(base_model,model)
    print("--- %s seconds ---" % (time.time() - start_time))


from typing import Any, BinaryIO, Optional

from .model import BaiDuResponse
from .network import HandOver

class BaiDu(HandOver):
    def __init__(self, **request_kwargs: Any):
        super().__init__(**request_kwargs)

    async def search(
        self, url: Optional[str] = None, file: Optional[BinaryIO] = None
    ) -> BaiDuResponse:
        params = {"from": "pc"}
        files = None
        if url:
            params["image"] = url
        elif file:
            files = {"image": file}
        else:
            raise ValueError("url or file is required")
        resp = await self.post(
            "https://graph.baidu.com/upload", params=params, files=files
        )
        resp = await self.get(resp.json()["data"]["url"])
        return BaiDuResponse(resp)


import torch
import torch.nn as nn
import numpy as np

"""
This script implements a kernel logistic regression model, a radial basis function network model
and a two-layer feed forward network.
"""

class Kernel_Layer(nn.Module):

    def __init__(self, sigma, hidden_dim=None):
        """
        Set hyper-parameters.
        Args:
            sigma: the sigma for Gaussian kernel (radial basis function)
            hidden_dim: the number of "kernel units", default is None, then the number of "kernel units"
                                       will be set to be the number of training samples
        """
        super(Kernel_Layer, self).__init__()
        self.sigma = sigma
        self.hidden_dim = hidden_dim

    def reset_parameters(self, X):
        """
        Set prototypes (stored training samples or "representatives" of training samples) of
        the kernel layer.
        """
        if self.hidden_dim is not None:
            X = self._k_means(X)
        self.prototypes = nn.Parameter(torch.tensor(X).float(), requires_grad=False)

    def _k_means(self, X):
        """
        K-means clustering

        Args:
            X: A Numpy array of shape [n_samples, n_features].

        Returns:
            centroids: A Numpy array of shape [self.hidden_dim, n_features].
        """
        ### YOUR CODE HERE
        inputs = torch.as_tensor(X)
        rand_points = torch.randint(0, X.shape[0], (self.hidden_dim,), dtype=torch.long)
        # randomly initialize centroids
        centroids = inputs[rand_points, :]
        # previous assignment
        prev = torch.randint(0, self.hidden_dim, (X.shape[0],), dtype=torch.long)
        iter = 0
        while iter < 1000:
            iter += 1
            # distance between each pair of vector
            cdist = torch.cdist(inputs, centroids, p=2)
            # cluster assignment
            new = cdist.argmin(dim=1)
            # stop if nothing changed
            if new.eq(prev).all() and iter > 1:
                break
            else:
                prev = new
            # new centroids
            for k in range(self.hidden_dim):
                centroids[k, :] = torch.mean(inputs[new.eq(k), :], dim=0)
        if iter == 1000:
            print("iter limit reached")
        ### END YOUR CODE
        return centroids

    def forward(self, x):
        """
        Compute Gaussian kernel (radial basis function) of the input sample batch
        and self.prototypes (stored training samples or "representatives" of training samples).

        Args:
            x: A torch tensor of shape [batch_size, n_features]

        Returns:
            A torch tensor of shape [batch_size, num_of_prototypes]
        """
        assert x.shape[1] == self.prototypes.shape[1]
        ### YOUR CODE HERE
        # Basically you need to follow the equation of radial basis function
        # in the section 5 of note at http://people.tamu.edu/~sji/classes/nnkernel.pdf
        r = torch.empty(x.shape[0], self.prototypes.shape[0])
        dimension = (x.shape[0], self.prototypes.shape[0], x.shape[1])
        xi = x.unsqueeze(1).expand(dimension)
        xj = self.prototypes.unsqueeze(0).expand(dimension)
        #print(xi.shape)
        norms = ((xi - xj)**2).sum(-1)
        r = torch.exp(-1 * norms / (2 * (self.sigma ** 2)))
        return r

        ### END YOUR CODE

class Kernel_LR(nn.Module):

    def __init__(self, sigma, hidden_dim):
        """
        Define network structure.

        Args:
            sigma: used in the kernel layer.
            hidden_dim: the number of prototypes in the kernel layer,
                                       in this model, hidden_dim has to be equal to the
                                       number of training samples.
        """
        super(Kernel_LR, self).__init__()
        self.hidden_dim = hidden_dim
        ### YOUR CODE HERE
        # Use pytorch nn.Sequential object to build a network composed of a
        # kernel layer (Kernel_Layer object) and a linear layer (nn.Linear object)

        # Remember that kernel logistic regression model uses all training samples
        # in kernel layer, so set 'hidden_dim' argument to be None when creating
        # a Kernel_Layer object.

        self.net = nn.Sequential(
            Kernel_Layer(sigma),
            nn.Linear(in_features=hidden_dim,out_features=1,bias=False)
        )

        # How should we set the "bias" argument of nn.Linear?

        ### END YOUR CODE

    def forward(self, x):
        """
        Forward pass.

        Args:
            x: A torch tensor of shape [batch_size, n_features]

        Returns:
            A torch tensor of shape [batch_size, 1]
        """
        return self.net(x)

    def reset_parameters(self, X):
        """
        Initialize the weights of the linear layer and the prototypes of the kernel layer.

        Args:
            X: A Numpy array of shape [n_samples, n_features], training data matrix.
        """
        assert X.shape[0] == self.hidden_dim
        for layer in self.net:
            if hasattr(layer, 'reset_parameters'):
                if isinstance(layer, Kernel_Layer):
                    layer.reset_parameters(X)
                else:
                    layer.reset_parameters()

class RBF(nn.Module):

    def __init__(self, sigma, hidden_dim):
        """
        Define network structure.

        Args:
            sigma: used in the kernel layer.
            hidden_dim: the number of prototypes in the kernel layer,
                                       in this model, hidden_dim is a user-specified hyper-parameter.
        """
        super(RBF, self).__init__()
        ### YOUR CODE HERE
        # Use pytorch nn.Sequential object to build a network composed of a
        # kernel layer (Kernel_Layer object) and a linear layer (nn.Linear object)
        # How should we set the "bias" argument of nn.Linear?
        self.net = nn.Sequential(
            Kernel_Layer(sigma, hidden_dim),
            nn.Linear(in_features=hidden_dim, out_features=1, bias=False)
        )
        ### END CODE HERE

    def forward(self, x):
        """
        Forward pass.

        Args:
            x: A torch tensor of shape [batch_size, n_features]

        Returns:
            A torch tensor of shape [batch_size, 1]
        """
        return self.net(x)

    def reset_parameters(self, X):
        """
        Initialize the weights of the linear layer and the prototypes of the kernel layer.

        Args:
            X: A Numpy array of shape [n_samples, n_features], training data matrix.
        """
        for layer in self.net:
            if hasattr(layer, 'reset_parameters'):
                if isinstance(layer, Kernel_Layer):
                    layer.reset_parameters(X)
                else:
                    layer.reset_parameters()

class FFN(nn.Module):

    def __init__(self, input_dim, hidden_dim):
        """
        Define network structure.

        Args:
            input_dim: number of features of each input.
            hidden_dim: the number of hidden units in the hidden layer, a user-specified hyper-parameter.
        """
        super(FFN, self).__init__()
        ### YOUR CODE HERE
        # Use pytorch nn.Sequential object to build a network composed of
        # two linear layers (nn.Linear object)
        self.net = nn.Sequential(
            nn.Linear(in_features=input_dim, out_features=hidden_dim, bias=False),
            nn.Linear(in_features=hidden_dim, out_features=1, bias=False)
        )
        ### END CODE HERE

    def forward(self, x):
        """
        Forward pass.

        Args:
            x: A torch tensor of shape [batch_size, n_features]

        Returns:
            A torch tensor of shape [batch_size, 1]
        """
        return self.net(x)

    def reset_parameters(self):
        """
        Initialize the weights of the linear layers.
        """
        for layer in self.net:
            if hasattr(layer, 'reset_parameters'):
                layer.reset_parameters()


from flask import Flask, render_template, request, jsonify
from decouple import config
import requests
import random
app = Flask(__name__)

# 토큰 변수 설정 후 api url 설정
token = config("TOKEN")
google_key=config("GOOGLE_API_KEY")
google_url = "https://translation.googleapis.com/language/translate/v2"

api_url = f"https://api.telegram.org/bot{token}"
update_url = f"{api_url}/getUpdates"

# getUpdate
# response = requests.get(update_url).json()
# chat_id = response["result"][0]["message"]["chat"]["id"]

# 메세지에 로또 번호 6개 뽑아서 보내주기
# message = random.sample(range(1,46), 6)
# message_url = f"{api_url}/sendMessage?chat_id={chat_id}&text={message}"
# requests.get(message_url)

@app.route('/write')
def write():
    return render_template('write.html')

@app.route('/send')
def send():
    message = request.args.get("message")
    message_url = f"{api_url}/sendMessage?chat_id={chat_id}&text={message}"
    requests.get(message_url)
    return "메세지 전송 완료했어요!"

@app.route(f'/{token}',methods=["POST"])
def telegram():
    message =request.get_json()
    dialog_flow = message["originalDetectIntentRequest"]["payload"]
    print(dialog_flow)
    text=dialog_flow["text"]

    # 먼저 chat_id를 가져옵니다.
    # chat_id = message["message"]["chat"]["id"]
    # 우리가 텔레그램에서 보낸 메세지를 꺼냅니다.
    # text=message["message"]["text"]
    # 메세지를 보내는 요청 주소를 통해 텔레그램에 전달

    if text =="로또":
        reply = random.sample(range(1,46),6) # list형태로 6자리 저장되어있는데 str타입으로 전달해야함
        # print(reply)
        reply = ' '.join(str(reply))

    elif text[0:3] == "/번역":
        data = {
            'q':text[4:],
            'source':'ko',
            'target':'en'
        }
        response = requests.post(f'{google_url}?key={google_key}',data).json()
        reply=response["data"]["translations"][0]["translatedText"]
    # else:
    #     reply=text

    # message_url = f"{api_url}/sendMessage?chat_id={chat_id}&text={reply}"
    # requests.get(message_url)
    result = {'fulfillmentText':reply}
    return jsonify(result)
    # return '', 200 #응답코드

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


import torch
from torch import nn
import torch.nn.functional as F
import networks.settings_dcsfn as settings
from itertools import combinations,product
import math

class Inner_scale_connection_block(nn.Module):
    def __init__(self):
        super(Inner_scale_connection_block, self).__init__()
        self.channel = 20

        self.scale1 = nn.ModuleList()
        self.scale2 = nn.ModuleList()
        self.scale4 = nn.ModuleList()
        self.scale8 = nn.ModuleList()

        for i in range(4):
            self.scale1.append(nn.Sequential(nn.Conv2d(self.channel, self.channel, 3, 1, 1), nn.LeakyReLU(0.2)))
            self.scale2.append(nn.Sequential(nn.Conv2d(self.channel, self.channel, 3, 1, 1), nn.LeakyReLU(0.2)))
            self.scale4.append(nn.Sequential(nn.Conv2d(self.channel, self.channel, 3, 1, 1), nn.LeakyReLU(0.2)))
            self.scale8.append(nn.Sequential(nn.Conv2d(self.channel, self.channel, 3, 1, 1), nn.LeakyReLU(0.2)))
        self.fusion84 = nn.Sequential(nn.Conv2d(2 * self.channel, self.channel, 1, 1), nn.LeakyReLU(0.2))
        self.fusion42 = nn.Sequential(nn.Conv2d(2 * self.channel, self.channel, 1, 1), nn.LeakyReLU(0.2))
        self.fusion21 = nn.Sequential(nn.Conv2d(2 * self.channel, self.channel, 1, 1), nn.LeakyReLU(0.2))
        self.pooling8 = nn.MaxPool2d(8, 8)
        self.pooling4 = nn.MaxPool2d(4, 4)
        self.pooling2 = nn.MaxPool2d(2, 2)
        self.fusion_all = nn.Sequential(nn.Conv2d(4 * self.channel, self.channel, 1, 1), nn.LeakyReLU(0.2))

    def forward(self, x):
        feature8 = self.pooling8(x)
        b8, c8, h8, w8 = feature8.size()
        feature4 = self.pooling4(x)
        b4, c4, h4, w4 = feature4.size()
        feature2 = self.pooling2(x)
        b2, c2, h2, w2 = feature2.size()
        feature1 = x
        b1, c1, h1, w1 = feature1.size()
        for i in range(4):
            feature8 = self.scale8[i](feature8)
        scale8 = feature8
        feature4 = self.fusion84(torch.cat([feature4, F.upsample(scale8, [h4, w4])], dim=1))
        for i in range(4):
            feature4 = self.scale4[i](feature4)
        scale4 = feature4
        feature2 = self.fusion42(torch.cat([feature2, F.upsample(scale4, [h2, w2])], dim=1))
        for i in range(4):
            feature2 = self.scale2[i](feature2)
        scale2 = feature2
        feature1 = self.fusion21(torch.cat([feature1, F.upsample(scale2, [h1, w1])], dim=1))
        for i in range(4):
            feature1 = self.scale1[i](feature1)
        scale1 = feature1
        fusion_all = self.fusion_all(torch.cat([scale1, F.upsample(scale2, [h1, w1]), F.upsample(scale4, [h1, w1]), F.upsample(scale8, [h1, w1])], dim=1))
        return fusion_all + x

class Encoder_decoder_block(nn.Module):
    def __init__(self):
        super(Encoder_decoder_block, self).__init__()
        self.channel_num = settings.channel
        self.encoder_conv1 = nn.Sequential(
            nn.Conv2d(self.channel_num, self.channel_num, 3, 1, 1),
            nn.LeakyReLU(0.2)
        )
        self.encoder_conv2 = nn.Sequential(
            nn.Conv2d(self.channel_num, self.channel_num, 3, 1, 1),
            nn.LeakyReLU(0.2)
        )
        self.encoder_conv3 = nn.Sequential(
            nn.Conv2d(self.channel_num, self.channel_num, 3, 1, 1),
            nn.LeakyReLU(0.2)
        )
        self.decoder_conv1 = nn.Sequential(
            nn.Conv2d(self.channel_num, self.channel_num, 3, 1, 1),
            nn.LeakyReLU(0.2)
        )
        self.decoder_conv2 = nn.Sequential(
            nn.Conv2d(self.channel_num, self.channel_num, 3, 1, 1),
            nn.LeakyReLU(0.2)
        )
        self.decoder_conv3 = nn.Sequential(
            nn.Conv2d(self.channel_num, self.channel_num, 3, 1, 1),
            nn.LeakyReLU(0.2)
        )
        self.fusion2_1 = nn.Sequential(
            nn.Conv2d(2 * self.channel_num, self.channel_num, 1, 1),
            nn.LeakyReLU(0.2)
        )
        self.fusion2_2 = nn.Sequential(
            nn.Conv2d(2 * self.channel_num, self.channel_num, 1, 1),
            nn.LeakyReLU(0.2)
        )
        self.fusion2_3 = nn.Sequential(
            nn.Conv2d(2 * self.channel_num, self.channel_num, 1, 1),
            nn.LeakyReLU(0.2)
        )
        self.pooling2 = nn.MaxPool2d(2, 2)

    def forward(self, x):
        input = x
        encoder1 = self.encoder_conv1(x)
        b1, c1, h1, w1 = encoder1.size()
        pooling1 = self.pooling2(encoder1)
        encoder2 = self.encoder_conv2(pooling1)
        b2, c2, h2, w2 = encoder2.size()
        pooling2 = self.pooling2(encoder2)
        encoder3 = self.encoder_conv3(pooling2)

        decoder_conv1 = self.decoder_conv1(encoder3)
        decoder_conv2 = self.decoder_conv2(self.fusion2_2(torch.cat([F.upsample(encoder2, [h2, w2]), F.upsample(decoder_conv1, [h2, w2])], dim=1)))
        decoder_conv3 = self.decoder_conv3(self.fusion2_3(torch.cat([F.upsample(encoder1, [h1, w1]), F.upsample(decoder_conv2, [h1, w1])], dim=1)))
        return decoder_conv3 + input

Scale_block = Inner_scale_connection_block()

class ConvGRU(nn.Module):
    def __init__(self, inp_dim, oup_dim, kernel, dilation):
        super().__init__()
        pad_x = int(dilation * (kernel - 1) / 2)
        self.conv_xz = nn.Conv2d(inp_dim, oup_dim, kernel, padding=pad_x, dilation=dilation)
        self.conv_xr = nn.Conv2d(inp_dim, oup_dim, kernel, padding=pad_x, dilation=dilation)
        self.conv_xn = nn.Conv2d(inp_dim, oup_dim, kernel, padding=pad_x, dilation=dilation)

        pad_h = int((kernel - 1) / 2)
        self.conv_hz = nn.Conv2d(oup_dim, oup_dim, kernel, padding=pad_h)
        self.conv_hr = nn.Conv2d(oup_dim, oup_dim, kernel, padding=pad_h)
        self.conv_hn = nn.Conv2d(oup_dim, oup_dim, kernel, padding=pad_h)

        self.relu = nn.LeakyReLU(0.2)

    def forward(self, x, h=None):
        if h is None:
            z = F.sigmoid(self.conv_xz(x))
            f = F.tanh(self.conv_xn(x))
            h = z * f
        else:
            z = F.sigmoid(self.conv_xz(x) + self.conv_hz(h))
            r = F.sigmoid(self.conv_xr(x) + self.conv_hr(h))
            n = F.tanh(self.conv_xn(x) + self.conv_hn(r * h))
            h = (1 - z) * h + z * n

        h = self.relu(h)

        return h, h

RecUnit = {
    'GRU': ConvGRU,
}['GRU']

class Encoder(nn.Module):
    def __init__(self):
        super(Encoder, self).__init__()
        self.unit_num = 16
        self.units = nn.ModuleList()
        self.channel_num = 20
        self.conv1x1 = nn.ModuleList()
        for i in range(self.unit_num):
            self.units.append(Scale_block)
            self.conv1x1.append(nn.Sequential(nn.Conv2d((i + 2) * self.channel_num, self.channel_num, 1, 1), nn.LeakyReLU(0.2)))

    def forward(self, x):
        catcompact = []
        catcompact.append(x)
        feature = []
        out = x
        for i in range(self.unit_num):
            tmp = self.units[i](out)
            feature.append(tmp)
            catcompact.append(tmp)
            out = self.conv1x1[i](torch.cat(catcompact, dim=1))
        return out, feature

class Decoder(nn.Module):
    def __init__(self):
        super(Decoder, self).__init__()
        self.unit_num = 16
        self.units = nn.ModuleList()
        self.channel_num = 20
        self.conv1x1 = nn.ModuleList()
        for i in range(self.unit_num):
            self.units.append(Scale_block)
            self.conv1x1.append(nn.Sequential(nn.Conv2d((i + 2) * self.channel_num, self.channel_num, 1, 1), nn.LeakyReLU(0.2)))

    def forward(self, x, feature):
        catcompact=[]
        catcompact.append(x)
        out = x
        for i in range(self.unit_num):
            tmp = self.units[i](out + feature[i])
            catcompact.append(tmp)
            out = self.conv1x1[i](torch.cat(catcompact, dim=1))
        return out

class Multi_model_fusion_learning(nn.Module):
    def __init__(self):
        super(Multi_model_fusion_learning, self).__init__()
        self.channel_num = 20
        self.convert = nn.Sequential(
            nn.Conv2d(3, self.channel_num, 3, 1, 1),
            nn.LeakyReLU(0.2)
        )

        self.encoder_scale1 = Encoder()
        self.encoder_scale2 = Encoder()
        self.encoder_scale4 = Encoder()

        self.fusion_1_2_1 = nn.Sequential(
            nn.Conv2d(2 * self.channel_num, self.channel_num, 1, 1),
            nn.LeakyReLU(0.2))
        self.fusion_1_2_2 = nn.Sequential(
            nn.Conv2d(2 * self.channel_num, self.channel_num, 1, 1),
            nn.LeakyReLU(0.2))
        self.fusion_2_2_1 = nn.Sequential(
            nn.Conv2d(2 * self.channel_num, self.channel_num, 1, 1),
            nn.LeakyReLU(0.2))
        self.fusion_2_2_2 = nn.Sequential(
            nn.Conv2d(2 * self.channel_num, self.channel_num, 1, 1),
            nn.LeakyReLU(0.2))

        self.decoder_scale1 = Decoder()
        self.decoder_scale2 = Decoder()
        self.decoder_scale4 = Decoder()

        self.rec1_1 = RecUnit(self.channel_num, self.channel_num, 3, 1)
        self.rec1_2 = RecUnit(self.channel_num, self.channel_num, 3, 1)
        self.rec1_4 = RecUnit(self.channel_num, self.channel_num, 3, 1)

        self.rec2_1 = RecUnit(self.channel_num, self.channel_num, 3, 1)
        self.rec2_2 = RecUnit(self.channel_num, self.channel_num, 3, 1)
        self.rec2_4 = RecUnit(self.channel_num, self.channel_num, 3, 1)

        self.merge = nn.Sequential(
            nn.Conv2d(3 * self.channel_num, 3, 1, 1),
            nn.LeakyReLU(0.2),
            nn.Conv2d(3, 3, 3, 1, 1)
        )

        self.pooling2 = nn.MaxPool2d(2, 2)
        self.pooling4 = nn.MaxPool2d(4, 4)

    def forward(self, x):
        convert = self.convert(x)
        feature1 = convert
        feature2 = self.pooling2(convert)
        feature4 = self.pooling4(convert)

        b1, c1, h1, w1 = feature1.size()
        b2, c2, h2, w2 = feature2.size()
        b4, c4, h4, w4 = feature4.size()

        scale1_encoder, scale1_feature = self.encoder_scale1(feature1)
        scale2_encoder, scale2_feature = self.encoder_scale2(feature2)
        scale4_encoder, scale4_feature = self.encoder_scale4(feature4)

        current1_4, rec1_4 = self.rec1_4(scale4_encoder)
        rec1_4_ori = rec1_4

        rec1_4 = F.upsample(rec1_4_ori, [h2, w2])
        current1_2, rec1_2 = self.rec1_2(scale2_encoder, rec1_4)
        rec1_2_ori = rec1_2
        rec1_2 = F.upsample(rec1_2_ori, [h1, w1])
        rec1_4 = F.upsample(rec1_4_ori, [h1, w1])
        current1_1, rec1_1 = self.rec1_1(scale1_encoder, self.fusion_1_2_1(torch.cat([rec1_2, rec1_4], dim=1)))

        current2_1, rec2_1 = self.rec2_1(current1_1)
        rec2_1_ori = rec2_1

        rec2_1 = F.upsample(rec2_1_ori, [h2, w2])
        current2_2, rec2_2 = self.rec2_2(current1_2, rec2_1)
        rec2_2_ori = rec2_2
        rec2_2 = F.upsample(rec2_2_ori, [h4, w4])
        rec2_1 = F.upsample(rec2_1_ori, [h4, w4])
        current2_4, rec2_4 = self.rec2_4(current1_4, self.fusion_2_2_1(torch.cat([rec2_1, rec2_2],dim=1)))

        scale1_decoder = self.decoder_scale1(current2_1, scale1_feature)
        scale2_decoder = self.decoder_scale2(current2_2, scale2_feature)
        scale4_decoder = self.decoder_scale4(current2_4, scale4_feature)
        merge = self.merge(torch.cat([scale1_decoder, F.upsample(scale2_decoder,[h1,w1]), F.upsample(scale4_decoder,[h1,w1])],dim=1))

        return x-merge

Net = Multi_model_fusion_learning