from __future__ import absolute_import, division, print_function, unicode_literals
import tensorflow as tf
from tensorflow.keras.models import Sequential, Model
from tensorflow.keras.layers import *
from tensorflow.keras import optimizers
from tensorflow.keras.regularizers import l2
import os
import numpy as np
import matplotlib.pyplot as plt
import tensorflowUtils as tfu
import sys
import scipy.io as sio

# FROM : https://github.com/krasserm/super-resolution/blob/master/model/srgan.py
def res_block(x_in,num_filters):
    x = Conv1D(num_filters, kernel_size=3, padding='same')(x_in)
    x = PReLU()(x)
    x = Conv1D(num_filters, kernel_size=3, padding='same')(x)
    x = Add()([x_in, x])
    return x

# FROM : https://github.com/krasserm/super-resolution/blob/master/model/srgan.py
def upsample(x_in, num_filters):
    x = Conv1D(num_filters, kernel_size=3, padding='same')(x_in)
    return PReLU()(x)

def make_SRNN_SC_model(Case):
    if Case['n_data']%Case['n_upsample'] > 0:
        print('n_data should be divisible by n_upsample')
        print('n_data =',Case['n_data'])
        print('n_upsample =',Case['n_upsample'])
        sys.exit()

    num_filters = Case['numFilters']
    numBlocks = Case['numBlocks']

    x_in = Input(shape=(Case['n_qoi'],1))
    x = Flatten()(x_in)
    x = Dense(Case['n_upsample'])(x)
    x = PReLU()(x)
    x = Reshape((Case['n_upsample'],1))(x)
    x = Conv1D(num_filters, kernel_size=3, padding='same')(x)
    x = x_1 = PReLU()(x)

    for _ in range(numBlocks):
        x = res_block(x, num_filters)

    x = Conv1D(num_filters, kernel_size=3, padding='same')(x)
    x = Add()([x_1, x])
    x = upsample(x,Case['n_data']//Case['n_upsample'])

    x = Reshape((Case['n_data'], 1))(x)

    return Model(x_in, x)

def makeModel(Case):
    SRNN = make_SRNN_SC_model(Case)
    SRNN.compile(optimizer='adam',
                  loss='mse',
                  metrics=['mse'])
    SRNN.summary()
    return SRNN

def train(SRNN,Case):
    print("Num GPUs Available: ", len(tf.config.experimental.list_physical_devices('GPU')))
    EPOCHS = 10
    BATCH_SIZE=min(512 ,Case['nSnapTrain'])
    Case['dsTrain'] = Case['dsTrain'].shuffle(100).repeat(EPOCHS).batch(BATCH_SIZE)
    Case['dsTest'] = Case['dsTest'].batch(BATCH_SIZE)
    WeightFolder = Case['weightFolder']+'/WeightsSC_filt_'+str(Case['numFilters'])+'_blocks_'+str(Case['numBlocks'])
    path = WeightFolder.split('/')
    for i in range(len(path)):
         directory = os.path.join(*path[:i+1])
         os.makedirs(directory,exist_ok=True)

    #mc = tf.keras.callbacks.ModelCheckpoint(WeightFolder+'/weights{epoch:08d}.h5', period=100)
    mc = tf.keras.callbacks.ModelCheckpoint(WeightFolder+'/best.h5', save_best_only=True, mode='min')
    csv_logger = tf.keras.callbacks.CSVLogger(WeightFolder +'/training.log')

    history = SRNN.fit(
        Case['dsTrain'],
        steps_per_epoch=Case['nSnapTrain'] // BATCH_SIZE,
        epochs=EPOCHS,
        validation_data=Case['dsTest'],
        validation_steps=Case['nSnapTest'] // BATCH_SIZE,
        callbacks = [mc,csv_logger]
    )


import numpy as np
from matplotlib import pyplot as plt

def read_data():
    """
        Function to read in data and build a dictionary of the various required properties of the data.
    """
    book_fname = 'goblet_book.txt'
    fid = open(book_fname, 'r').read()

    book_data = fid
    book_chars = list(set(fid))
    k = len(book_chars)

    # char_to_ind, chars as keys
    # ind_to_char, ints as keys
    char_to_ind = {}
    ind_to_char = {}

    for i, val in enumerate(book_chars):
        char_to_ind[val] = i
        ind_to_char[i] = val

    return {'book_data': book_data, 'book_chars': book_chars, 'k': k, 'char_to_ind': char_to_ind, 'ind_to_char': ind_to_char}

class RNN():

    def __init__(self, data, m, eta, seq_length):

        self.data = data
        self.m = m
        self.eta = eta
        self.seq_length = seq_length

        self.b, self.c, self.W, self.U, self.V = self.initialize_hyperparameters(
            m, self.data['k'])

        self.grads = {'W': np.zeros_like(self.W), 'V': np.zeros_like(self.V), 'U': np.zeros_like(
            self.U), 'b': np.zeros_like(self.b), 'c': np.zeros_like(self.c)}

        self.m_values = {'W': np.zeros_like(self.W), 'V': np.zeros_like(self.V), 'U': np.zeros_like(
            self.U), 'b': np.zeros_like(self.b), 'c': np.zeros_like(self.c)}

    def reset_grads(self):
        """
            Resets the parameter gradients.
        """
        self.grads = {'W': np.zeros_like(self.W), 'V': np.zeros_like(self.V), 'U': np.zeros_like(
            self.U), 'b': np.zeros_like(self.b), 'c': np.zeros_like(self.c)}

    def initialize_hyperparameters(self, m, k):
        """
            Initializes the model parameters as stated in the assignment.
        """

        sigma = 0.01

        b = np.zeros((m, 1))
        c = np.zeros((k, 1))

        W = np.random.normal(0, sigma, size=(m, m))
        U = np.random.normal(0, sigma, size=(m, k))
        V = np.random.normal(0, sigma, size=(k, m))

        return b, c, W, U, V

    def softmax(self, x):
        return np.exp(x) / np.sum(np.exp(x), axis=0)

    def tanh(self, x):
        return np.tanh(x)

    def synthesize_chars(self, h0, x0, y, n):
        """
            Synthesizes sequence of characters of length n.
        """

        synthesized_text = []
        x = x0
        h = h0

        for i in range(n):
            a, h, o, p = self.evaluate_classifier(h, x, y, i, True)

            cp = np.cumsum(p, axis=0)
            a = np.random.rand()
            ixs = np.nonzero(cp - a > 0)
            ii = ixs[0][0]
            x = np.zeros((self.data["k"], 1))
            x[ii][0] = 1
            synthesized_text.append(x)

        return synthesized_text

    def evaluate_classifier(self, h, x, y, i, synth=False):
        """
            Forward pass of the learning process.
        """

        at = np.matmul(self.W, h) + np.matmul(self.U, x) + self.b
        ht = self.tanh(at)

        ot = np.matmul(self.V, ht) + self.c
        pt = self.softmax(ot)

        if not synth:
            loss = -np.log(np.dot(y[:, i].T, pt))
            return loss, at, ht, ot, pt
        else:
            return at, ht, ot, pt

    def compute_gradients(self, x, y, h):
        """
            General function for analytical computation of parameter gradients. Encapsulates both forward and backward pass.
        """

        #x_list = {}
        hidden_list = {}
        prod_list = {}

        hidden_list[-1] = np.copy(h)
        loss_sum = 0

        self.reset_grads()

        # forward-pass
        for i in range(x.shape[1]):
            x_t = x[:, i].reshape(x.shape[0], 1)

            loss, a, hidden_list[i], o, prod_list[i] = self.evaluate_classifier(
                hidden_list[i-1], x_t, y, i)

            loss_sum += loss

        # backward-pass
        grad_a = np.zeros_like(a)
        for i in reversed(range(x.shape[1])):
            x_t = x[:, i].reshape(x.shape[0], 1)
            y_t = y[:, i].reshape(y.shape[0], 1)
            grad_o = -(y_t-prod_list[i]).T

            g = grad_o
            self.grads["c"] += g.T

            self.grads["V"] = np.matmul(g.T, hidden_list[i].T)

            grad_h = np.dot(self.V.T, g.T) + np.dot(self.W.T, grad_a)
            grad_a = grad_h * (1 - (hidden_list[i] ** 2))

            g = grad_a
            self.grads["b"] += g

            self.grads["W"] = np.matmul(g, hidden_list[i-1].T)
            self.grads["U"] = np.matmul(g, x_t.T)

        # clipping with np.clip
        self.grads["W"] = np.clip(self.grads["W"], -5, 5)
        self.grads["V"] = np.clip(self.grads["V"], -5, 5)
        self.grads["U"] = np.clip(self.grads["U"], -5, 5)
        self.grads["b"] = np.clip(self.grads["b"], -5, 5)
        self.grads["c"] = np.clip(self.grads["c"], -5, 5)

        return loss_sum, hidden_list[-1]

    def compute_gradients_analyt(self, x, y, h):
        """
            Analytical computation of gradients, only utilized in gradient comparison check.
        """

        #x_list = {}
        hidden_list = {}
        prod_list = {}

        hidden_list[-1] = np.copy(h)
        loss_sum = 0

        self.reset_grads()

        # forward-pass
        for i in range(x.shape[1]):
            x_t = x[:, i].reshape(x.shape[0], 1)

            loss, a, hidden_list[i], o, prod_list[i] = self.evaluate_classifier(
                hidden_list[i-1], x_t, y, i)

            loss_sum += loss

        # backward-pass
        grad_a = np.zeros_like(a)
        for i in reversed(range(x.shape[1])):
            x_t = x[:, i].reshape(x.shape[0], 1)
            y_t = y[:, i].reshape(y.shape[0], 1)
            grad_o = -(y_t-prod_list[i]).T

            g = grad_o
            self.grads["c"] += g.T

            self.grads["V"] = np.matmul(g.T, hidden_list[i].T)

            grad_h = np.dot(self.V.T, g.T) + np.dot(self.W.T, grad_a)
            grad_a = grad_h * (1 - (hidden_list[i] ** 2))

            g = grad_a
            self.grads["b"] += g

            self.grads["W"] = np.matmul(g, hidden_list[i-1].T)
            self.grads["U"] = np.matmul(g, x_t.T)

        return self.grads["W"], self.grads["V"], self.grads["U"], self.grads["b"], self.grads["c"]

    def evaluate_classifier_num(self, h, x, y):
        """
            Modified forward pass utilized in gradient comparison check.
        """
        P = {}
        H = {}
        H[-1] = h
        loss = 0
        for t in range(x.shape[1]):
            Xt = x[:, t].reshape(x.shape[0], 1)
            at = np.dot(self.U, Xt) + np.dot(self.W, H[t-1]) + self.b
            H[t] = np.tanh(at)
            ot = np.dot(self.V, H[t]) + self.c
            P[t] = np.exp(ot) / np.sum(np.exp(ot))
            loss += -np.log(np.dot(y[:, t].T, P[t]))
        return loss, 0, H, 0, P

    def compute_gradients_num(self, x, y, h0):
        """
            Numerical computation of parameter gradients.
        """
        h = 1e-4
        db = np.zeros_like(self.b)
        dc = np.zeros_like(self.c)
        du = np.zeros_like(self.U)
        dw = np.zeros_like(self.W)
        dv = np.zeros_like(self.V)
        for i in range(len(self.b)):
            b = self.b
            temp = b
            temp[i] -= h
            self.b[i] = temp[i]
            l1, _, H, _, P = self.evaluate_classifier_num(h0, x, y)
            temp = b
            temp[i] += h
            self.b[i] = temp[i]
            l2, _, H, _, P = self.evaluate_classifier_num(h0, x, y)
            self.b = b
            db[i] = (np.sum(l2) - np.sum(l1)) / (h)
        for i in range(len(self.c)):
            c = self.c
            temp = c
            temp[i] -= h
            self.c[i] = temp[i]
            l1, _, H, _, P = self.evaluate_classifier_num(h0, x, y)
            temp = c
            temp[i] += h
            self.c[i] = temp[i]
            l2, _, H, _, P = self.evaluate_classifier_num(h0, x, y)
            self.c = c
            dc[i] = (np.sum(l2) - np.sum(l1)) / (h)
        for i in range(self.U.shape[0]):
            for j in range(self.U.shape[1]):
                u = self.U
                temp = u
                temp[i][j] -= h
                self.U[i][j] = temp[i][j]
                l1, _, H, _, P = self.evaluate_classifier(h0, x, y, i)
                temp = u
                temp[i][j] += h
                self.U[i][j] = temp[i][j]
                l2, _, H, _, P = self.evaluate_classifier(h0, x, y, i)
                self.U = u
                du[i][j] = (np.sum(l2) - np.sum(l1)) / (h)
        for i in range(self.W.shape[0]):
            for j in range(self.W.shape[1]):
                w = self.W
                temp = w
                temp[i][j] -= h
                self.W[i][j] = temp[i][j]
                l1, _, H, _, P = self.evaluate_classifier_num(h0, x, y)
                temp = w
                temp[i][j] += h
                self.W[i][j] = temp[i][j]
                l2, _, H, _, P = self.evaluate_classifier_num(h0, x, y)
                self.W = w
                dw[i][j] = (np.sum(l2) - np.sum(l1)) / (h)
        for i in range(self.V.shape[0]):
            for j in range(self.V.shape[1]):
                v = self.V
                temp = v
                temp[i][j] -= h
                self.V[i][j] = temp[i][j]
                l1, _, H, _, P = self.evaluate_classifier_num(h0, x, y)
                temp = v
                temp[i][j] += h
                self.V[i][j] = temp[i][j]
                l2, _, H, _, P = self.evaluate_classifier_num(h0, x, y)
                self.V = v
                dv[i][j] = (np.sum(l2) - np.sum(l1)) / (h)
        return dw, dv, du, db, dc

    def create_one_hot(self, data):
        """
            Function to create a one-hot-encoding from a given set of character data.
        """
        one_hot = np.zeros((self.data["k"], len(data)))

        for b in range(len(data)):
            one_hot[self.data["char_to_ind"][data[b]]][b] = 1

        return one_hot

    def create_chars(self, text):
        """
            Function to create a sequence of characters from a given one-hot-encoding.
        """
        chars = ""
        for i in range(len(text)):
            pos = np.where(text[i] != 0)
            chars += self.data["ind_to_char"][pos[0][0]]

        return chars

    def adagrad(self):
        """
            Implementation of adagrad optimizer with parameter updates.
        """
        gradients = [self.grads["W"], self.grads["U"],
                     self.grads["V"], self.grads["b"], self.grads["c"]]
        m_values = [self.m_values["W"], self.m_values["U"],
                    self.m_values["V"], self.m_values["b"], self.m_values["c"]]
        params = [self.W, self.U, self.V, self.b, self.c]

        for i in range(len(params)):
            m_values[i] += (gradients[i] ** 2)

            params[i] += - ((self.eta / np.sqrt(m_values[i] +
                                                np.finfo(np.float32).eps)))*gradients[i]

    def rms_prop(self):
        """
            Implementation of RMSProp optimizer with parameter updates.
        """
        gradients = [self.grads["W"], self.grads["U"],
                     self.grads["V"], self.grads["b"], self.grads["c"]]
        m_values = [self.m_values["W"], self.m_values["U"],
                    self.m_values["V"], self.m_values["b"], self.m_values["c"]]
        params = [self.W, self.U, self.V, self.b, self.c]
        gamma = 0.9

        for i in range(len(params)):
            m_values[i] = gamma * m_values[i] + \
                (1 - gamma) * (gradients[i] ** 2)

            params[i] += - ((self.eta / np.sqrt(m_values[i] +
                                                np.finfo(np.float32).eps)))*gradients[i]

    def compare_gradients(self):
        """
            Main function for gradient comparison check.
        """
        position = 0
        x = self.data["book_data"][position:position+self.seq_length]
        y = self.data['book_data'][position +
                                   1:position+self.seq_length+1]

        x_one_hot = self.create_one_hot(x)
        y_one_hot = self.create_one_hot(y)
        h = np.zeros((self.m, 1))

        W1, V1, U1, b1, c1 = self.compute_gradients_analyt(
            x_one_hot, y_one_hot, h)
        self.reset_grads()
        W2, V2, U2, b2, c2 = self.compute_gradients_num(
            x_one_hot, y_one_hot, h)
        eps = 10**-6

        # mean absolute error
        print(np.mean(np.abs(b1 - b2)))
        print(np.mean(np.abs(c1 - c2)))
        print(np.mean(np.abs(W1 - W2)))
        print(np.mean(np.abs(U1 - U2)))
        print(np.mean(np.abs(V1 - V2)))

        # maximum relative error
        print(np.mean(np.abs(b1 - b2))/max(eps, np.mean(np.abs(b1) + np.abs(b2))))
        print(np.mean(np.abs(c1 - c2))/max(eps, np.mean(np.abs(c1) + np.abs(c2))))
        print(np.mean(np.abs(W1 - W2))/max(eps, np.mean(np.abs(W1) + np.abs(W2))))
        print(np.mean(np.abs(U1 - U2))/max(eps, np.mean(np.abs(U1) + np.abs(U2))))
        print(np.mean(np.abs(V1 - V2))/max(eps, np.mean(np.abs(V1) + np.abs(V2))))

    def plot_loss(self, iters, losses):
        """
            Plots loss across a given number of iterations.
        """
        iters = np.arange(iters)
        plt.figure(1)
        plt.plot(iters, losses, color='m')
        plt.xlabel('Iterations')
        plt.ylabel('Smooth Loss')
        plt.show()

    def train(self, epochs):
        """
            Main function for training process. Initializes necessary variables, and performs training across a given number of epochs.
        """

        iters = 0
        maximum_iter = 1000
        losses = []
        smooth_loss = 0
        all_params = []

        for epoch in range(epochs):
            position = 0
            hprev = np.zeros((self.m, 1))

            while position < (len(self.data["book_data"]) - self.seq_length - 1):

                x = self.data["book_data"][position:position +
                                           self.seq_length]
                y = self.data['book_data'][position +
                                           1:position+self.seq_length+1]

                x_one_hot = self.create_one_hot(x)
                y_one_hot = self.create_one_hot(y)

                loss, hprev = self.compute_gradients(
                    x_one_hot, y_one_hot, hprev)

                if smooth_loss == 0:
                    smooth_loss = loss

                smooth_loss = 0.999 * smooth_loss + 0.001 * loss
                losses.append(smooth_loss)
                all_params.append([self.grads["W"], self.grads["U"],
                                   self.grads["V"], self.grads["b"], self.grads["c"]])

                if iters == 0 or iters % 1000 == 0:
                    print("Iteration " + str(iters) + " " + "(epoch " +
                          str(epoch) + ")" + ": " + str(smooth_loss))

                    if iters == 0 or iters % 10000 == 0:
                        synth = self.synthesize_chars(
                            hprev, x_one_hot[:, 0], y_one_hot, 200)
                        generated_text = self.create_chars(synth)
                        print(generated_text)

                # Adagrad SGD
                self.adagrad()

                position += self.seq_length
                iters += 1

        lowest_loss = np.argmin(losses)
        best_params = all_params[lowest_loss]
        synth = self.synthesize_chars(
            hprev, x_one_hot[:, 0], y_one_hot, 1000)
        generated_text = self.create_chars(synth)
        print(generated_text)

        self.plot_loss(iters, losses)

def main(check=False):
    if not check:
        data = read_data()
        rnn = RNN(data, 100, 0.1, 25)
        rnn.train(3)
    else:
        data = read_data()
        rnn = RNN(data, 5, 0.1, 25)
        rnn.compare_gradients()

if __name__ == "__main__":
    main()


__all__ = (
    'even_odd',
)

def even_odd(arr: list[int]) -> float:
    """
    Функция возвращает отношение суммы четных элементов массив к сумме нечетных
    Пример:
    even_odd([1, 2, 3, 4, 5]) == 0.8889
    """
    if not arr:
        return 0

    even_list= list(filter(lambda element: element % 2 == 0, arr))
    odd_list = list(filter(lambda element: element % 2 != 0, arr))

    if not odd_list:
        return 0
    if not even_list:
        return 0

    return sum(even_list) / sum(odd_list)


n = int(input())

matrix = []

for row in range(n):
    chars = [i for i in input()]
    matrix.append(chars)

# print(matrix)

special_char = input()

found = False

for row in range(len(matrix)):
    for col in range(len(matrix[row])):
        if matrix[row][col] == special_char:
            result = (row, col)
            print(result)
            found = True
            break
    if found:
        break

if not found:
    print(f'{special_char} does not occur in the matrix')


import openpyxl
import os
from common.contants import DATA_DIR
#用来存储用例对象
class CaseData():
    pass
class ReadExcel(object):
    def __init__(self,filename,sheet_name):
        '''

        :param filename: 文件名
        :param sheet_name: 表单名
        '''
        self.filename=filename
        self.sheet_name=sheet_name

    def open(self):
        self.wb=openpyxl.load_workbook(self.filename)
        self.sh=self.wb[self.sheet_name]
    def save(self):
        self.wb.save(self.filename)
        self.close()
    def close(self):
        self.wb.close()
    def read_data(self):
        self.open()
        #按行获取所有格子对象
        rows=list(self.sh.rows)
        #获取第一行数据
        title=[]
        for i in rows[0]:
            title.append(i.value)
        #创建一个空列表，用来存储改行的数据
        cases = []
        #遍历第二行开始的数据
        for row in rows[1:]:
            data = []
            #再次遍历每一个格子
            for r in row:
                #格子里面的数据，添加到data里面
                data.append(r.value)
            #title和data聚合打包成字典
            case = dict(zip(title, data))
            cases.append(case)
        print(cases)
        self.close()
        return cases
    def read_data_object(self):
        self.open()

        #按行获取所有的格子对象
        rows=list(self.sh.rows)
        #获取第一行数据
        title=[]
        for i in rows[0]:
            title.append(i.value)
        #创建一个空列表
        cases=[]
        #遍历第二行开始的数据
        for row in rows[1:]:
            data = []
            # 再次遍历每一个格子
            for r in row:
                # 格子里面的数据，添加到data里面
                data.append(r.value)
            # title和data聚合打包成字典转换成列表
            case = list(zip(title, data))
            #创建一个对象用来保存该行的用例数据
            case_obj=CaseData()
            #遍历列表中该行用例数据，使用setarr设置成对象的属性和属性值
            for k,v in case:
                setattr(case_obj,k,v)
            #将对象添加到cases这个列表中
            cases.append(case_obj)
        #返回cases(包含所有用例数据对象的对象)
        return cases

    def write_data(self,row,column,value):
        #打开工作簿，写入数据
        self.open()
        #写入数据
        self.sh.cell(row=row,column=column,value=value)
        #保存文件
        self.wb.save(self.filename)
        self.close()
if __name__=='__main__':
    excel1=ReadExcel(os.path.join(DATA_DIR,"case.xlsx"),"login")
    excel2 = ReadExcel(os.path.join(DATA_DIR, "case.xlsx"), "register")
    data1=excel1.read_data()
    data2=excel2.read_data()
    print(data1)
    print(data2)


from django.template import loader
from django.core.mail import EmailMultiAlternatives

from donation.models import Donation

def donation_has_exception(donation):
    if donation.coinbase_charge:
        if donation.coinbase_charge.status == 'UNRESOLVED':
            return True
    return False

def get_donation_info(donation):
    coinbase_charge = donation.coinbase_charge
    status = coinbase_charge.status
    if status == 'UNRESOLVED':
        status = 'MULTIPLE' if coinbase_charge.payments.count(
        ) > 1 else coinbase_charge.charge_status_context
    return {
        'amount': donation.amount,
        'order_number': coinbase_charge.charge_code,
        'order_date': coinbase_charge.created_at,
        'receipt_url': coinbase_charge.get_receipt_url(),
        'status': status,
        'received_amount': donation.amount,
        'expected_amount': coinbase_charge.pricing.local
    }

def send_donation_confirm_email(donation_id):
    donation = Donation.objects.get(id=donation_id)
    if donation.email:
        email_template = loader.get_template(
            'donation/donationconfirm.html')
        msg = EmailMultiAlternatives(
            subject='Baza Foundation Donation',
            body='Thank you for donating to Baza Foundation',
            from_email='donation-noreply@baza.foundation',
            to=[donation.email]
        )
        msg.attach_alternative(email_template.render({
            'donation_info': get_donation_info(donation),
            'has_exception': donation_has_exception(donation)
        }), 'text/html')
        msg.send()


import os
import glob

from base import Project, Gatherer, GitRepoException

class Languages(Gatherer):
    name = 'language'

    def run(self):
        extentions = {}
        for file in glob.glob("%s/**/**" % self.project.repo.working_tree_dir):
            if os.path.isfile(file):
                ext = file.split('.')[-1].strip('~ ')
                if ext in extentions:
                    extentions[ext] += 1
                else:
                    extentions[ext] = 1

        keys = extentions.keys()
        keys.sort(key=extentions.__getitem__, reverse=True)
        if not keys:
            return "Unknown"
        main_ext = keys.pop(0)
        if main_ext == 'rb':
            return 'Ruby'
        if main_ext == 'py':
            return 'Python'
        if main_ext == 'html':
            return 'HTML'
        if main_ext == 'js':
            return 'JavaScript'
        return main_ext


import pymongo
import os
import pprint
import json
from pymongo import MongoClient

# Populates the database
# Place this file into the root of the comics folder
# Requires a directory structure like this:

# |-- comic_a
# |   |-- chapter_1
# |   |   |-- 01.jpg
# |   |   `-- 02.jpg
# |   |-- chapter_2
# |   |   |-- 01.jpg
# |   |   `-- 02.jpg
# |   `-- info.json
# |-- comic_b
# |   |-- chapter_1
# |   |   |-- 01.jpg
# |   |   `-- 02.jpg
# |   `-- chapter_2
# |-- comic_c
# |   |-- chapter_1
# |   `-- chapter_2
# `-- database.py

client = MongoClient('localhost').comics

series = [x for x in os.listdir(".") if not os.path.isfile(x)];
chapters = []

listOfSeriesTitles = [x['title'] for x in client.series.find()];

for serial in series:
    if (serial not in listOfSeriesTitles):
        client.series.insert({"title": serial});

for serial in series:
    chapterList = [x for x in os.listdir("./" + serial) if os.path.isdir("./" + serial + "/" + x)]
    chapters.append(chapterList)
    for chapter in chapterList:
        query = client.chapters.find({'title': chapter, 'series': serial})
        if (query.count() == 0):
            client.chapters.insert({"title": chapter, "series": serial})

        pageList = [x for x in os.listdir("./" + serial + "/" + chapter) if os.path.isfile("./" + serial + "/" + chapter + "/" + x)]

        for page in pageList:
            query = client.pages.find({"title": page, "series": serial, "chapter": chapter});

            if (query.count() == 0 and page != ".DS_Store"):

                client.pages.insert({"title": page, "series": serial, "chapter": chapter, "page number" : int(page.strip(".jpg"))});


# ------------------------------------------------------------------------------
#  Copyleft 2015-2020  PacMiam
#
#  This program is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation; either version 3 of the License, or
#  (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software
#  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
#  MA 02110-1301, USA.
# ------------------------------------------------------------------------------

# Filesystem
from pathlib import Path
from shutil import rmtree

# GEM
from geode_gem.engine.api import GEM
from geode_gem.engine.utils import copy, get_data
from geode_gem.engine.lib.configuration import Configuration

from geode_gem.ui.data import Icons, Columns, Folders, Metadata
from geode_gem.ui.utils import magic_from_file

# Logging
from logging import getLogger

# System
from argparse import ArgumentParser
from os import environ

# Translation
from gettext import textdomain, bindtextdomain
from gettext import gettext as _

# ------------------------------------------------------------------------------
#   Launcher
# ------------------------------------------------------------------------------

def init_environment():
    """ Initialize main environment
    """

    # Initialize localization
    bindtextdomain("gem", str(get_data("data", "i18n")))
    textdomain("gem")

    # Initialize metadata
    metadata = Configuration(get_data("data", "config", "metadata.conf"))

    # Retrieve metadata informations
    if metadata.has_section("metadata"):
        for key, value in metadata.items("metadata"):
            setattr(Metadata, key.upper(), value)

    # Retrieve icons informations
    if metadata.has_section("icons"):
        for key, value in metadata.items("icons"):
            setattr(Icons, key.upper(), value)
            setattr(Icons.Symbolic, key.upper(), f"{value}-symbolic")

    if metadata.has_section("icon-sizes"):
        for key, value in metadata.items("icon-sizes"):
            setattr(Icons.Size, key.upper(), value.split())

    # Retrieve columns informations
    if metadata.has_section("misc"):
        setattr(Columns, "ORDER",
                metadata.get("misc", "columns_order", fallback=str()))

    if metadata.has_section("list"):
        for key, value in metadata.items("list"):
            setattr(Columns.List, key.upper(), int(value))

    if metadata.has_section("grid"):
        for key, value in metadata.items("grid"):
            setattr(Columns.Grid, key.upper(), int(value))

def init_configuration(gem):
    """ Initialize user configuration

    Parameters
    ----------
    gem : gem.engine.api.GEM
        GEM API instance
    """

    move_collection = False

    # ----------------------------------------
    #   Configuration
    # ----------------------------------------

    for filename in ("gem.conf", "consoles.conf", "emulators.conf"):
        path = gem.get_config(filename)

        if not path.exists():
            gem.logger.debug(f"Copy default {path}")

            # Copy default configuration
            copy(get_data("data", "config", filename), path)

    # ----------------------------------------
    #   Local
    # ----------------------------------------

    for folder in ("logs", "notes"):
        path = gem.get_local(folder)

        if not path.exists():
            gem.logger.debug(f"Generate {path} folder")

            try:
                path.mkdir(mode=0o755, parents=True)

            except FileExistsError:
                gem.logger.error(f"Path {path} already exists")

    # ----------------------------------------
    #   Cache
    # ----------------------------------------

    for name in ("consoles", "emulators", "games"):
        sizes = getattr(Icons.Size, name.upper(), list())

        for size in sizes:
            path = Folders.CACHE.joinpath(name, f"{size}x{size}")

            if not path.exists():
                gem.logger.debug(f"Generate {path}")

                try:
                    path.mkdir(mode=0o755, parents=True)

                except FileExistsError:
                    gem.logger.error(f"Path {path} already exists")

    # ----------------------------------------
    #   Icons
    # ----------------------------------------

    icons_path = gem.get_local("icons")

    # Create icons storage folder
    if not icons_path.exists():
        gem.logger.debug(f"Generate {icons_path}")

        try:
            icons_path.mkdir(mode=0o755, parents=True)

        except FileExistsError:
            gem.logger.error(f"Path {icons_path} already exists")

        finally:
            move_collection = True

    # Remove older icons collections folders (GEM < 1.0)
    else:

        for folder in ("consoles", "emulators"):
            path = icons_path.joinpath(folder)

            if path.exists():

                if path.is_dir():
                    rmtree(path)

                elif path.is_symlink():
                    path.unlink()

                move_collection = True

    # Copy default icons
    if move_collection:
        gem.logger.debug("Generate consoles icons folder")

        for filename in get_data("data", "icons").glob("*.png"):

            if filename.is_file():

                # Check the file mime-type to avoid non-image file
                mime = magic_from_file(filename, mime=True)

                if mime.startswith("image/"):
                    new_path = icons_path.joinpath(filename.name)

                    if not new_path.exists():
                        gem.logger.debug(f"Copy {new_path}")

                        copy(filename, new_path)

def main():
    """ Main launcher
    """

    # Initialize environment
    init_environment()

    # ----------------------------------------
    #   Generate arguments
    # ----------------------------------------

    parser = ArgumentParser(
        epilog=Metadata.COPYLEFT,
        description=f"{Metadata.NAME} - {Metadata.VERSION}",
        conflict_handler="resolve")

    parser.add_argument(
        "-v",
        "--version",
        action="version",
        version=f"{Metadata.NAME} {Metadata.VERSION} "
                f"({Metadata.CODE_NAME}) - {Metadata.LICENSE}",
        help="show the current version")
    parser.add_argument(
        "-d",
        "--debug",
        action="store_true",
        help="launch gem with debug flag")

    parser_api = parser.add_argument_group("api arguments")
    parser_api.add_argument(
        "--cache",
        action="store",
        metavar="FOLDER",
        default=Folders.Default.CACHE,
        help=f"set cache folder (default: {Folders.Default.CACHE})")
    parser_api.add_argument(
        "--config",
        action="store",
        metavar="FOLDER",
        default=Folders.Default.CONFIG,
        help=f"set configuration folder (default: {Folders.Default.CONFIG})")
    parser_api.add_argument(
        "--local",
        action="store",
        metavar="FOLDER",
        default=Folders.Default.LOCAL,
        help=f"set data folder (default: {Folders.Default.LOCAL})")

    parser_maintenance = parser.add_argument_group("maintenance arguments")
    parser_maintenance.add_argument(
        "--clean-cache",
        action="store_true",
        help="clean icons cache directory")

    arguments = parser.parse_args()

    # ----------------------------------------
    #   Cache directory
    # ----------------------------------------

    setattr(Folders, "CACHE",
            Path(arguments.cache, "gem").expanduser().resolve())
    if not Folders.CACHE.exists():
        Folders.CACHE.mkdir(mode=0o755, parents=True)

    if Folders.CACHE.exists() and arguments.clean_cache:

        if Folders.CACHE.is_dir():
            rmtree(Folders.CACHE)

        if not Folders.CACHE.exists():
            Folders.CACHE.mkdir(mode=0o755, parents=True)

    # ----------------------------------------
    #   Launch interface
    # ----------------------------------------

    process_status = False

    try:
        gem = GEM(arguments.config, arguments.local, arguments.debug)

        # Set cache directory
        cache_path = Folders.Default.CACHE.joinpath(gem.Instance)

        # Check display settings
        if "DISPLAY" in environ and environ.get("DISPLAY"):

            if not gem.is_locked():
                # Initialize main configuration files
                init_configuration(gem)

                getLogger(gem.Instance).info(f"Start GEM with PID {gem.pid}")

                # Start splash
                from geode_gem.ui.splash import Splash
                Splash(gem)

                # Start interface
                from geode_gem.ui.interface import MainWindow
                MainWindow(gem, cache_path)

                # Remove lock
                gem.free_lock()

            else:
                getLogger(gem.Instance).critical(
                    f"GEM is already running with PID {gem.pid}")

                from geode_gem.ui.splash import Message
                message = Message(
                    _("An instance already exists"),
                    _("GEM is already running with PID %s") % gem.pid)
                message.run()

        else:
            getLogger(gem.Instance).critical(
                "Cannot launch GEM without display")

    except ImportError:
        getLogger("gem").exception("An error occur durint modules importation")
        process_status = True

    except KeyboardInterrupt:
        getLogger("gem").warning("Terminate by keyboard interrupt")
        process_status = True

    except Exception:
        getLogger("gem").exception("An error occur during execution")
        process_status = True

    # Remove lock when an error occurs
    if process_status:
        gem.free_lock()

    return process_status

if __name__ == "__main__":
    main()


import sys
sys.setrecursionlimit(10**6)

def inverse(x):
    x[0], x[1] = x[1], x[0]

    return x

def add(x, n):
    x[0] += n * x[1]

    return x

def iter_outward(x, level):
    if level == 0:
        return x
    x = add(inverse(x), 2)

    return iter_outward(x, level - 1)

def continued(n):
    x = iter_outward([2, 1], n)
    return add(inverse(x), 1)

count = 0
for i in range(1000):
    frac = continued(i)

    if len(str(frac[0])) > len(str(frac[1])):
        count += 1

print(count)


from sqlalchemy import delete, insert, select, update
from sqlalchemy.exc import IntegrityError
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.orm import selectinload

from ..database import Like, Media, Tweet, User
from ..exeptions import BackendExeption
from ..services_overal import get_user_by_api_key

async def get_tweet(session: AsyncSession, tweet_id: int):
    q = await session.execute(
        select(Tweet)
        .options(selectinload(Tweet.author))
        .options(selectinload(Tweet.likes).options(selectinload(Like.user)))
        .options(selectinload(Tweet.media))
        .where(Tweet.id == tweet_id)
    )
    tweet = q.scalars().one_or_none()
    if not tweet:
        raise BackendExeption(
            error_type="NO TWEET", error_message="No tweet with such id"
        )
    return tweet

async def get_tweets(session: AsyncSession, api_key: str):
    await get_user_by_api_key(session=session, api_key=api_key)

    q = await session.execute(
        select(Tweet)
        .options(selectinload(Tweet.author))
        .options(selectinload(Tweet.likes).options(selectinload(Like.user)))
        .options(selectinload(Tweet.media))
        .where(Tweet.author.has(User.api_key == api_key))
    )

    tweets = q.scalars().all()

    return {"result": True, "tweets": tweets}

async def post_tweet(
    session: AsyncSession, api_key: str, tweet_data: str
) -> int:
    user = await get_user_by_api_key(session=session, api_key=api_key)

    insert_tweet_query = await session.execute(
        insert(Tweet).values(
            content=tweet_data,
            user_id=user.id,
        )
    )
    new_tweet_id = insert_tweet_query.inserted_primary_key[0]
    await session.commit()

    return new_tweet_id

async def insert_media_to_tweet(
    session: AsyncSession, tweet_id: int, tweet_medias: list
):
    for media_id in tweet_medias:
        await session.execute(
            update(Media).where(Media.id == media_id).values(tweet_id=tweet_id)
        )
        await session.commit()

async def delete_tweet(session: AsyncSession, api_key: str, tweet_id: int):
    user = await get_user_by_api_key(session=session, api_key=api_key)
    await get_tweet(session=session, tweet_id=tweet_id)

    q1 = await session.execute(
        select(Tweet.user_id).where(Tweet.id == tweet_id)
    )
    author_id = q1.scalars().one_or_none()
    if author_id != user.id:
        raise BackendExeption(
            error_type="NO ACCSESS",
            error_message="Tweet belongs to other user",
        )

    await session.execute(
        delete(Tweet).where(Tweet.id == tweet_id, Tweet.user_id == user.id)
    )
    await session.commit()

async def post_like_to_tweet(
    session: AsyncSession, api_key: str, tweet_id: int
):
    user = await get_user_by_api_key(session=session, api_key=api_key)
    await get_tweet(session=session, tweet_id=tweet_id)

    try:
        insert_like_query = await session.execute(
            insert(Like).values(
                tweet_id=tweet_id,
                user_id=user.id,
            )
        )
        new_like_id = insert_like_query.inserted_primary_key[0]
        await session.commit()
    except IntegrityError:
        raise BackendExeption(
            error_type="BAD LIKE", error_message="Such like already exists"
        )

    return new_like_id

async def delete_like_to_tweet(
    session: AsyncSession, api_key: str, tweet_id: int
):
    user = await get_user_by_api_key(session=session, api_key=api_key)
    tweet = await get_tweet(session=session, tweet_id=tweet_id)
    q = await session.execute(
        select(Like)
        .where(Like.user_id == user.id)
        .where(Like.tweet_id == tweet.id)
    )
    like = q.scalars().one_or_none()
    if not like:
        raise BackendExeption(
            error_type="BAD LIKE DELETE",
            error_message="No like for tweet from user",
        )

    await session.execute(
        delete(Like).where(Like.tweet_id == tweet_id, Like.user_id == user.id)
    )
    await session.commit()


import sys

input = sys.stdin.readline
sys.setrecursionlimit(10**7)

INF = float('inf')
MOD = 10**9+7
#MOD = 998244353

def main():
    s = input()[:-1]
    n = len(s)
    name = ['c', 'h', 'o', 'k', 'u', 'd', 'a', 'i']
    dp = [[0]*(8) for _ in range(n+1)]
    #dp[i][idx]はi番目までの文字列で、最後の文字がidxであるものの場合の数
    for i in range(n):
        for idx, c in enumerate(name):
            if s[i] != c:
                dp[i+1][idx] = dp[i][idx]
            else:
                dp[i+1][idx] = dp[i][idx]
                if idx > 0:
                    dp[i+1][idx] = (dp[i+1][idx] + dp[i][idx-1]) % MOD
                else:
                    dp[i+1][idx] = dp[i][idx] + 1

    #for i in range(n+1):
    #    print(dp[i])
    print(dp[n][7])

if __name__ == '__main__':
    main()


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

# In[1]:

import matplotlib.pyplot as plt
import matplotlib.image as mpimg
from torchvision import transforms
import numpy as np
import json
from pprint import pprint
import io
import pickle
import os
import PIL
import PIL.Image as pImage
from fastai.vision.all import *
import random
print("done")

# In[2]:

defaults.device = torch.device('cuda:0')
def dataset_creator(path):
  file_names = []
  for filename in os.listdir(path):
      if filename.endswith(".bmp"):
          file_names.append(os.path.join(path, filename))
      else:
          continue
  return file_names

# In[3]:

data_path = "/work/07925/alaukik/LeukemiaDataset/C-NMC_training_data/CombinedData"
leuk_data = dataset_creator(data_path + '/all')
no_leuk_data = dataset_creator(data_path + '/hem')

# In[8]:

# Selects random images from each list and concatenates list to create overall dataset
#fix this!!!
random.seed(77)
leuk_data_rand = random.sample(set(leuk_data), 3389)
no_leuk_data_rand = random.sample(set(no_leuk_data), 3389)
full_data = list(leuk_data_rand) + list(no_leuk_data_rand)
labels_ls = ['all']*3389 + ['hem']*3389

#Checking that labels match files
print(full_data[250])
print(full_data[251])
print(full_data[249])
print(labels_ls[250], labels_ls[251], labels_ls[249])

# In[9]:

def image_to_arr_of_numpy_arr(data_array):
  try:
    i=0
    matrix_2d = []
    '''
    matrix_2d = np.array(Image.open(data_array[0]))
    while i < len(data_array):
      if matrix_2d.shape == (257,257,3):
        break
      matrix_2d = np.array(Image.open(data_array[i]))
      i += 1
    '''

    #print(matrix_2d.shape)
    while i < len(data_array):
      image = np.array(pImage.open(data_array[i]))
      if image.shape == (257,257,3):
        matrix_2d.append(image)
      i += 1
    matrix_2d = np.array(matrix_2d)
    #print(matrix_2d.shape)

    return matrix_2d

  except TypeError:
    print('input Data array cannot be empty or null')
    return

# In[10]:

#image = mpimg.imread(data_path + '/all/UID_1_1_1_all.bmp')
#print(type)
#plt.imshow(image)
#plt.show()

# In[11]:

tfms = [Normalize.from_stats(*imagenet_stats)]
np.random.seed(32)
data = ImageDataLoaders.from_lists(data_path, full_data, labels=labels_ls, valid_pct=0.2,
      batch_tfms= [*aug_transforms(),Normalize.from_stats(*imagenet_stats)], bs = 64, num_workers=4)
#TRY THIS FOR LABELS (2/5 Meeting): https://docs.fast.ai/vision.data.html#ImageDataLoaders.from_lists

# In[12]:

#data.show_batch(nrows=3, figsize=(7,8))
#data.label_list

# In[13]:

#number of classifications
print(data.c)

# In[33]:

learn = cnn_learner(data, models.resnet34, metrics=error_rate) #metrics = []

# In[34]:

#print("Reached training")
#for i in range(0, 30):
#  print("Epoch" + str(i))
#  learn.fit_one_cycle(1)
#  learn.save("con_stage-" + str(i))

# In[35]:

#path = learn.save('stage-1')
#print(path)

# In[36]:

#learn.recorder.plot_loss()
#learn.unfreeze()

# In[37]:

#learn.lr_find()

# In[38]:

#figure out better way for lr
#learn.recorder.plot(suggestion = True)
#minlr = learn.recorder.min_grad_lr
#learn.fit_one_cycle(10,10e-5)

# In[39]:

#learn.recorder.plot_loss()

# In[40]:

#learn.save('stage-2')

# In[41]:

#learn.load('stage-2')

# In[42]:

learn = learn.load('con_stage-24', device=torch.device("cuda:0"))

print("Reached interp")
#interp = ClassificationInterpretation.from_learner(learn)

# In[43]:

#interp.plot_confusion_matrix()

# In[31]:

from fastai.vision.widgets import ImageClassifierCleaner

# In[ ]:

#ImageClassifierCleaner(learn)

# In[ ]:

print("Reached Hooks")

class Hook():
    def __init__(self, m):
        self.hook = m.register_forward_hook(self.hook_func)
    def hook_func(self, m, i, o): self.stored = o.detach().clone()
    def __enter__(self, *args): return self
    def __exit__(self, *args): self.hook.remove()

# Hook class
class HookBwd():
    def __init__(self, m):
        self.hook = m.register_backward_hook(self.hook_func)
    def hook_func(self, m, gi, go): self.stored = go[0].detach().clone()
    def __enter__(self, *args): return self
    def __exit__(self, *args): self.hook.remove()

def visualize_cnn_by_cam(learn, index):
  x, y = learn.dls.valid_ds[index]
  x.save("./output/image_" + str(index) + ".png")
  x = transforms.ToTensor()(x).unsqueeze(0)
  #for t in tfms:
  #  x = t(x, split_idx=0)
  cls = y
  with HookBwd(learn.model[0]) as hookg:
      with Hook(learn.model[0]) as hook:
          output = learn.model.eval()(x)
          act = hook.stored
      output[0,cls].backward()
      grad = hookg.stored

  # Take the mean of the gradients
  w = grad[0].mean(dim=[1,2], keepdim=True)
  cam_map = (w * act[0]).sum(0)

  # Show the plot
  x_dec = TensorImage(data.train.decode((x,))[0][0])
  _,ax = plt.subplots()
  x_dec.show(ctx=ax)
  ax.imshow(cam_map.detach().cpu(), alpha=0.6, extent=(0,450,450,0),
                interpolation='bilinear', cmap='magma')
  plt.savefig("./output/heatmap" +  str(index) + ".png")

visualize_cnn_by_cam(learn, 2)
#num_leuk = len (leuk_data)
#num_no_leuk = len (no_leuk_data)
for idx in range(10): ## Range can be whatever you want, or select a specific image of interest given its index
    visualize_cnn_by_cam(learn, idx)


from rlkit.torch.torch_rl_algorithm import TorchTrainer
import torch.optim as optim
import torch.nn as nn
import torch
import numpy as np
import rlkit.torch.pytorch_util as ptu
from rlkit.core.eval_util import create_stats_ordered_dict
from collections import OrderedDict

MEAN_MIN = -9.0
MEAN_MAX = 9.0

class S4RLTrainer(TorchTrainer):
    def __init__(self,
                 env,
                 policy,
                 qf1,
                 qf2,
                 target_qf1=None,
                 target_qf2=None,
                 vf=None,
                 discount=0.99,
                 reward_scale=1.0,
                 policy_lr=1e-3,
                 qf_lr=1e-3,
                 optimizer_class=optim.Adam,
                 soft_target_tau=1e-2,
                 # SAC
                 automatic_entropy_tuning=True,
                 target_entropy=None,
                 bc_warm_start=0,
                 num_qs=2,
                 total_training_steps=1E6,
                 # CQL
                 min_q_version=3,
                 temp=1.0,
                 min_q_weight=1.0,
                 ## sort of backup
                 max_q_backup=False,
                 deterministic_backup=True,
                 num_random=10,
                 with_lagrange=False,
                 lagrange_thresh=0.0,
                 ### augmentation type
                 s4rl=dict(type='normal', params=0.0003)
                 ):
        super().__init__()
        self.env = env
        self.obs_lower_bound = float(self.env.observation_space.low[0])
        self.obs_upper_bound = float(self.env.observation_space.high[0])
        self.policy = policy
        self.qf1 = qf1
        self.qf2 = qf2
        self.target_qf1 = target_qf1
        self.target_qf2 = target_qf2
        self.vf = vf
        self.discount = discount
        self.reward_scale = reward_scale
        self.eval_statistics = OrderedDict()
        self._need_to_update_eval_statistics = True

        # setting of loss and optimizer
        self.qf_criterion = nn.MSELoss()
        self.vf_criterion = nn.MSELoss()

        self.policy_optimizer = optimizer_class(
            self.policy.parameters(),
            lr=policy_lr,
        )
        self.qf1_optimizer = optimizer_class(
            self.qf1.parameters(),
            lr=qf_lr,
        )
        self.qf2_optimizer = optimizer_class(
            self.qf2.parameters(),
            lr=qf_lr,
        )

        self.automatic_entropy_tuning = automatic_entropy_tuning
        self.alpha=0.2 # constant alpha if not automatic tuning
        if self.automatic_entropy_tuning:
            if target_entropy:
                self.target_entropy = target_entropy
            else:
                self.target_entropy = -np.prod(self.env.action_space.shape).item()

            self.log_alpha = ptu.zeros(1, requires_grad=True)
            self.alpha_optimizer = optimizer_class(
                [self.log_alpha],
                lr=policy_lr,
            )
            self.alpha = self.log_alpha.exp()

        self.with_lagrange = with_lagrange
        if self.with_lagrange:
            self.target_action_gap = lagrange_thresh
            self.log_alpha_prime = ptu.zeros(1, requires_grad=True)
            self.alpha_prime_optimizer = optimizer_class(
                [self.log_alpha_prime],
                lr=qf_lr,
            )

        self.soft_target_tau = soft_target_tau

        self.bc_warm_start = bc_warm_start
        self.num_qs = num_qs
        self.num_random = num_random
        self.total_training_steps = total_training_steps
        self._n_train_steps_total = 0
        self.min_q_version = min_q_version
        self.min_q_weight = min_q_weight
        self.temp = temp
        self.max_q_backup = max_q_backup
        self.deterministic_backup = deterministic_backup

        self.s4rl_type = s4rl['type']
        self.s4rl_params = s4rl['params']

    def augment_states(self, states):
        if self.s4rl_type == 'normal':
            noise = torch.normal(0, self.s4rl_params, size=states.shape).to(ptu.device)
            aug_states = states + noise
        elif self.s4rl_type == 'uniform':
            # noise = (self.s4rl_params[1] - self.s4rl_params[0]) * torch.rand(size=states.shape).to(ptu.device) + self.s4rl_params[0]
            noise = torch.FloatTensor(size=states.shape).uniform_(-self.s4rl_params, self.s4rl_params).to(ptu.device)
            aug_states = states + noise
        elif self.s4rl_type == 'adv':
            # todo: adversarial augment
            # aug_states = states
            pass
        else:
            raise ValueError('Not support the augmentation:{}'.format(self.s4rl_type))

        return aug_states.clamp(self.obs_lower_bound, self.obs_upper_bound)

    def _get_tensor_values(self, obs, actions, network=None):
        action_size = actions.shape[0]
        obs_size= obs.shape[0]
        num_repeat = int (action_size / obs_size)
        obs_temp = obs.unsqueeze(1).repeat(1, num_repeat, 1).view(obs.shape[0] * num_repeat, obs.shape[1])
        preds = network(obs_temp, actions)
        preds = preds.view(obs.shape[0], num_repeat, 1)
        return preds

    def _get_policy_actions(self, obs, num_actions=1, network=None):
        obs_temp = obs.unsqueeze(1).repeat(1, num_actions, 1).view(obs.shape[0] * num_actions, obs.shape[1])
        actions_dist = network(obs_temp)
        normal_mean = actions_dist.normal_mean # no tanh()
        normal_std = actions_dist.stddev
        new_obs_actions, log_pi = actions_dist.rsample_and_logprob() # (bs*num_actions, act_dim), (bs*num_actions,)

        return new_obs_actions, normal_mean, normal_std, log_pi.view(log_pi.shape[0], 1)

    def train_from_torch(self, batch):

        rewards = batch['rewards']
        terminals = batch['terminals']
        obs = batch['observations']
        actions = batch['actions']
        next_obs = batch['next_observations']

        """
        Critic Loss
        """
        with torch.no_grad():
            next_state_action, _, _, next_state_log_pi = self._get_policy_actions(next_obs, network=self.policy)

            if not self.max_q_backup:
                if self.num_qs == 1:
                    target_q_values = self.target_qf1(self.augment_states(next_obs), next_state_action)
                else:
                    target_q_values = torch.min(
                        self.target_qf1(self.augment_states(next_obs), next_state_action),
                        self.target_qf2(self.augment_states(next_obs), next_state_action),
                    )

                if not self.deterministic_backup:
                    target_q_values = target_q_values - self.alpha * next_state_log_pi
            else:
                """when using max q backup"""
                next_actions_temp, _, _, _ = self._get_policy_actions(next_obs, num_actions=10, network=self.policy)
                target_qf1_values = self._get_tensor_values(self.augment_states(next_obs), next_actions_temp, network=self.target_qf1).max(1)[0].view(-1, 1)
                target_qf2_values = self._get_tensor_values(self.augment_states(next_obs), next_actions_temp, network=self.target_qf2).max(1)[0].view(-1, 1)
                target_q_values = torch.min(target_qf1_values, target_qf2_values)

            q_target = self.reward_scale * rewards + (1. - terminals) * self.discount * target_q_values

        q1_pred = self.qf1(self.augment_states(obs), actions)
        if self.num_qs > 1:
            q2_pred = self.qf2(self.augment_states(obs), actions)

        qf1_loss = self.qf_criterion(q1_pred, q_target)
        if self.num_qs > 1:
            qf2_loss = self.qf_criterion(q2_pred, q_target)

        # add CQL loss
        random_actions_tensor = torch.FloatTensor(q2_pred.shape[0] * self.num_random, actions.shape[-1]).uniform_(-1, 1).to(ptu.device)
        curr_actions_tensor, _, _, curr_log_pis = self._get_policy_actions(obs, num_actions=self.num_random, network=self.policy)
        curr_log_pis = curr_log_pis.view(q2_pred.shape[0], self.num_random, 1)
        next_curr_actions_tensor, _, _, next_curr_log_pis = self._get_policy_actions(next_obs, num_actions=self.num_random, network=self.policy)
        next_curr_log_pis = next_curr_log_pis.view(q2_pred.shape[0], self.num_random, 1)

        q1_rand = self._get_tensor_values(obs, random_actions_tensor, network=self.qf1)
        q2_rand = self._get_tensor_values(obs, random_actions_tensor, network=self.qf2)
        q1_curr_actions = self._get_tensor_values(obs, curr_actions_tensor.detach(), network=self.qf1)
        q2_curr_actions = self._get_tensor_values(obs, curr_actions_tensor.detach(), network=self.qf2)
        q1_next_actions = self._get_tensor_values(obs, next_curr_actions_tensor.detach(), network=self.qf1)
        q2_next_actions = self._get_tensor_values(obs, next_curr_actions_tensor.detach(), network=self.qf2)

        if self.min_q_version == 3:
            # importance sammpled version
            random_density = np.log(0.5 ** curr_actions_tensor.shape[-1])
            cat_q1 = torch.cat(
                [q1_rand - random_density, q1_next_actions - next_curr_log_pis.detach(), q1_curr_actions - curr_log_pis.detach()], 1
            )
            cat_q2 = torch.cat(
                [q2_rand - random_density, q2_next_actions - next_curr_log_pis.detach(), q2_curr_actions - curr_log_pis.detach()], 1
            )
            std_q1 = torch.std(cat_q1, dim=1)
            std_q2 = torch.std(cat_q2, dim=1)
        else:
            cat_q1 = torch.cat(
                [q1_rand, q1_pred.unsqueeze(1), q1_next_actions, q1_curr_actions], 1
            )
            cat_q2 = torch.cat(
                [q2_rand, q2_pred.unsqueeze(1), q2_next_actions, q2_curr_actions], 1
            )
            std_q1 = torch.std(cat_q1, dim=1)
            std_q2 = torch.std(cat_q2, dim=1)

        min_qf1_loss = torch.logsumexp(cat_q1 / self.temp, dim=1,).mean() * self.min_q_weight * self.temp
        min_qf2_loss = torch.logsumexp(cat_q2 / self.temp, dim=1,).mean() * self.min_q_weight * self.temp

        """Subtract the log likelihood of data"""
        min_qf1_loss = min_qf1_loss - q1_pred.mean() * self.min_q_weight
        min_qf2_loss = min_qf2_loss - q2_pred.mean() * self.min_q_weight

        if self.with_lagrange:
            alpha_prime = torch.clamp(self.log_alpha_prime.exp(), min=0.0, max=1000000.0)
            min_qf1_loss = alpha_prime * (min_qf1_loss - self.target_action_gap)
            min_qf2_loss = alpha_prime * (min_qf2_loss - self.target_action_gap)

            self.alpha_prime_optimizer.zero_grad()
            alpha_prime_loss = (-min_qf1_loss - min_qf2_loss)*0.5
            alpha_prime_loss.backward(retain_graph=True)
            self.alpha_prime_optimizer.step()

        qf1_loss = qf1_loss + min_qf1_loss
        qf2_loss = qf2_loss + min_qf2_loss

        """
        Update Critic
        """
        # Update the Q-functions iff
        if self.num_qs == 1:
            self.qf1_optimizer.zero_grad()
            qf1_loss.backward()
            self.qf1_optimizer.step()
        else:
            total_qf_loss = qf1_loss + qf2_loss
            self.qf1_optimizer.zero_grad()
            self.qf2_optimizer.zero_grad()
            total_qf_loss.backward()
            self.qf1_optimizer.step()
            self.qf2_optimizer.step()

        """
        Policy and Alpha Loss
        """
        new_obs_actions, policy_normal_mean, policy_normal_std, log_pi = self._get_policy_actions(obs,
                                                                                network=self.policy)

        if self.automatic_entropy_tuning:
            alpha_loss = -(self.log_alpha * (log_pi + self.target_entropy).detach()).mean()
            self.alpha_optimizer.zero_grad()
            alpha_loss.backward()
            self.alpha_optimizer.step()
            self.alpha = self.log_alpha.exp()

        if self.num_qs == 1:
            q_new_actions = self.qf1(obs, new_obs_actions)
        else:
            q_new_actions = torch.min(
                self.qf1(obs, new_obs_actions),
                self.qf2(obs, new_obs_actions),
            )

        policy_loss = (self.alpha*log_pi - q_new_actions).mean()

        if self._n_train_steps_total + 1 < self.bc_warm_start:
            """
            For the initial few epochs, try doing behaivoral cloning, if needed
            conventionally, there's not much difference in performance with having 20k
            gradient steps here, or not having it
            """
            policy_normal_mean = torch.clamp(policy_normal_mean, MEAN_MIN, MEAN_MAX)
            policy_log_prob = self.policy.logprob(actions, policy_normal_mean, policy_normal_std) # no gradient flow
            policy_loss = (self.alpha * log_pi - policy_log_prob).mean()

        """
        Update Policy
        """
        self.policy_optimizer.zero_grad()
        policy_loss.backward()
        self.policy_optimizer.step()

        """
        Soft Updates
        """
        ptu.soft_update_from_to(
            self.qf1, self.target_qf1, self.soft_target_tau
        )
        if self.num_qs > 1:
            ptu.soft_update_from_to(
                self.qf2, self.target_qf2, self.soft_target_tau
            )

        """
        Save some statistics for eval
        """
        if self._need_to_update_eval_statistics:
            self._need_to_update_eval_statistics = False
            """
            Eval should set this to None.
            This way, these statistics are only computed for one batch.
            """

            self.eval_statistics['QF1 Loss'] = np.mean(ptu.get_numpy(qf1_loss))
            self.eval_statistics['min QF1 Loss'] = np.mean(ptu.get_numpy(min_qf1_loss))
            if self.num_qs > 1:
                self.eval_statistics['QF2 Loss'] = np.mean(ptu.get_numpy(qf2_loss))
                self.eval_statistics['min QF2 Loss'] = np.mean(ptu.get_numpy(min_qf2_loss))

            self.eval_statistics['Std QF1 values'] = np.mean(ptu.get_numpy(std_q1))
            self.eval_statistics['Std QF2 values'] = np.mean(ptu.get_numpy(std_q2))
            self.eval_statistics.update(create_stats_ordered_dict(
                'QF1 in-distribution values',
                ptu.get_numpy(q1_curr_actions),
            ))
            self.eval_statistics.update(create_stats_ordered_dict(
                'QF2 in-distribution values',
                ptu.get_numpy(q2_curr_actions),
            ))
            self.eval_statistics.update(create_stats_ordered_dict(
                'QF1 random values',
                ptu.get_numpy(q1_rand),
            ))
            self.eval_statistics.update(create_stats_ordered_dict(
                'QF2 random values',
                ptu.get_numpy(q2_rand),
            ))
            self.eval_statistics.update(create_stats_ordered_dict(
                'QF1 next_actions values',
                ptu.get_numpy(q1_next_actions),
            ))
            self.eval_statistics.update(create_stats_ordered_dict(
                'QF2 next_actions values',
                ptu.get_numpy(q2_next_actions),
            ))

            self.eval_statistics['Policy Loss'] = np.mean(ptu.get_numpy(
                policy_loss
            ))
            self.eval_statistics.update(create_stats_ordered_dict(
                'Q1 Predictions',
                ptu.get_numpy(q1_pred),
            ))
            if self.num_qs > 1:
                self.eval_statistics.update(create_stats_ordered_dict(
                    'Q2 Predictions',
                    ptu.get_numpy(q2_pred),
                ))
            self.eval_statistics.update(create_stats_ordered_dict(
                'Q Targets',
                ptu.get_numpy(q_target),
            ))
            self.eval_statistics.update(create_stats_ordered_dict(
                'Log Pis',
                ptu.get_numpy(log_pi),
            ))
            self.eval_statistics.update(create_stats_ordered_dict(
                'Policy mu',
                ptu.get_numpy(policy_normal_mean),
            ))
            self.eval_statistics.update(create_stats_ordered_dict(
                'Policy std',
                ptu.get_numpy(policy_normal_std),
            ))

            if self.automatic_entropy_tuning:
                self.eval_statistics['Alpha'] = self.alpha.item()
                self.eval_statistics['Alpha Loss'] = alpha_loss.item()

            if self.with_lagrange:
                self.eval_statistics['Alpha_prime'] = alpha_prime.item()
                self.eval_statistics['min_q1_loss'] = ptu.get_numpy(min_qf1_loss).mean()
                self.eval_statistics['min_q2_loss'] = ptu.get_numpy(min_qf2_loss).mean()
                self.eval_statistics['threshold action gap'] = self.target_action_gap
                self.eval_statistics['alpha prime loss'] = alpha_prime_loss.item()

        self._n_train_steps_total += 1

    def get_diagnostics(self):
        stats = super().get_diagnostics()
        stats.update(self.eval_statistics)
        return stats

    def end_epoch(self, epoch):
        self._need_to_update_eval_statistics = True

    @property
    def networks(self):
        nets = [
            self.policy,
            self.qf1,
            self.qf2,
            self.target_qf1,
            self.target_qf2,
        ]
        return nets

    def get_snapshot(self):
        return dict(
            policy=self.policy,
            qf1=self.qf1,
            qf2=self.qf2,
            target_qf1=self.target_qf1,
            target_qf2=self.target_qf2,
        )


# Quadratic Discriminant Analysis
from sklearn import datasets
from sklearn import metrics
#from sklearn.qda import QDA
from sklearn.discriminant_analysis import QuadraticDiscriminantAnalysis as QDA
import pandas as pd

# load the iris datasets
dataset = datasets.load_iris()

print(dataset.feature_names)

df = pd.DataFrame(dataset.data, columns=dataset.feature_names)
print(df.head())
print(df.corr())

# fit a QDA model to the data
model = QDA()
model.fit(dataset.data, dataset.target)
print(model)

# make predictions
expected = dataset.target
predicted = model.predict(dataset.data)

# summarize the fit of the model
print(metrics.classification_report(expected, predicted))
print(metrics.confusion_matrix(expected, predicted))


from malcolm.core import PART_NAME_RE, Info
from malcolm.modules.scanning.infos import DatasetType

from .util import AttributeDatasetType

class FilePathTranslatorInfo(Info):
    """Translate linux filepath to windows equivalent

    Args:
        windows_drive_letter: The drive letter assigned to the windows mount
        path_prefix: The location of the mount in linux (i.e. /dls or /dls_sw)
        network_drive: The network drive prefix on Windows (e.g. //dc). If the
        windows drive letter is an empty string, the network drive is prepended.
    """

    def __init__(self, windows_drive_letter, path_prefix, network_prefix):
        self.windows_drive_letter = windows_drive_letter
        self.path_prefix = path_prefix
        self.network_prefix = network_prefix

    @classmethod
    def translate_filepath(cls, part_info, filepath):
        translator = cls.filter_single_value(
            part_info,
            "No or multiple FilePathTranslatorPart found: must have exactly "
            "1 if any part in the AD chain is running on Windows",
        )
        assert filepath.startswith(
            translator.path_prefix
        ), "filepath %s does not start with expected prefix %s" % (
            filepath,
            translator.path_prefix,
        )
        assert (
            filepath.find(":") == -1
        ), f"filepath {filepath} has unexpected colon (incompatible on Windows)"

        if translator.network_prefix != "":
            win_path = filepath.replace(
                translator.path_prefix,
                translator.network_prefix + translator.path_prefix,
            ).replace("/", "\\")
        else:
            win_path = filepath.replace(
                translator.path_prefix, translator.windows_drive_letter + ":"
            ).replace("/", "\\")
        return win_path

class NDArrayDatasetInfo(Info):
    """Declare the NDArray data this produces as being a useful dataset to store
    to file

    Args:
        rank: The rank of the dataset, e.g. 2 for a 2D detector
    """

    def __init__(self, rank: int) -> None:
        self.rank = rank

class CalculatedNDAttributeDatasetInfo(Info):
    """Declare that we have calculated some statistics from the main dataset
    and these will be available

    Args:
        name: Dataset name that should be written to
        attr: NDAttribute name to get data from
    """

    def __init__(self, name: str, attr: str) -> None:
        self.name = name
        self.attr = attr

class NDAttributeDatasetInfo(Info):
    """Declare an NDAttribute attached to this NDArray to produce a useful
    dataset to store to file

    Args:
        name: Dataset name that should be written to, e.g. "I0.value"
        type: What NeXuS dataset type it produces, e.g. DatasetType.PRIMARY
        attr: NDAttribute name to get data from, e.g. "COUNTER1.Diff"
    """

    def __init__(self, name: str, type: DatasetType, attr: str) -> None:
        self.name = name
        self.type = type
        self.attr = attr

    @classmethod
    def from_attribute_type(
        cls, name: str, type: AttributeDatasetType, attr: str
    ) -> "NDAttributeDatasetInfo":
        """Make an Info from the AttributeDatasetType

        Args:
            name: Dataset name without dots, e.g. "I0"
            type: What type it is, e.g. AttributeDatasetType.DETECTOR
            attr: NDAttribute name to get data from, e.g. "COUNTER1.Diff
        """
        assert PART_NAME_RE.match(name), (
            "Expected Alphanumeric dataset name (dash and underscore allowed)"
            + f" got {name!r}"
        )
        if type is AttributeDatasetType.DETECTOR:
            # Something like I0
            name = f"{name}.data"
            dtype = DatasetType.PRIMARY
        elif type is AttributeDatasetType.MONITOR:
            # Something like Iref
            name = f"{name}.data"
            dtype = DatasetType.MONITOR
        elif type is AttributeDatasetType.POSITION:
            # Something like x
            name = f"{name}.value"
            dtype = DatasetType.POSITION_VALUE
        else:
            raise AttributeError(
                f"Bad dataset type {type!r}, should be a {AttributeDatasetType}"
            )
        return cls(name, dtype, attr)


import sys
class NeedleMan:
    def __init__(self, match_award, mismatch_penalty, gap_penalty):
        self.match_award = match_award
        self.mismatch_penalty = mismatch_penalty
        self.gap_penalty = gap_penalty

    def print_matrix(self,mat):
        # Loop over all rows
        for i in range(0, len(mat)):
            print("[", end = "")
            # Loop over each column in row i
            for j in range(0, len(mat[i])):
                # Print out the value in row i, column j
                print(mat[i][j], end = "")
                # Only add a tab if we're not in the last column
                if j != len(mat[i]) - 1:
                    print("\t", end = "")
            print("]\n")

    def zeros(self, rows, cols):
    # Define an empty list
        retval = []
        # Set up the rows of the matrix
        for x in range(rows):
            # For each row, add an empty list
            retval.append([])
            # Set up the columns in each row
            for y in range(cols):
                # Add a zero to each column in each row
                retval[-1].append(0)
        # Return the matrix of zeros
        return retval

    def match_score(self,alpha, beta):
        if alpha == beta:
            return self.match_award
        elif alpha == '-' or beta == '-':
            return self.gap_penalty
        else:
            return self.mismatch_penalty

    def needleman_wunsch(self, seq1, seq2):

        # length of two sequences
        n = len(seq1)
        m = len(seq2)

        # Generate matrix of zeros to store scores
        score = self.zeros(m+1, n+1)

        # Fill out first column
        for i in range(0, m + 1):
            score[i][0] = self.gap_penalty * i

        # Fill out first row
        for j in range(0, n + 1):
            score[0][j] = self.gap_penalty * j

        # Fill out all other values in the score matrix
        for i in range(1, m + 1):
            for j in range(1, n + 1):
                # Calculate the score by checking the top, left, and diagonal cells
                match = score[i - 1][j - 1] + self.match_score(seq1[j-1], seq2[i-1])
                delete = score[i - 1][j] + self.gap_penalty
                insert = score[i][j - 1] + self.gap_penalty
                # Record the maximum score from the three possible scores calculated above
                score[i][j] = max(match, delete, insert)

        self.print_matrix(score)
        print("Optimal Global alignment score is: ", score[-1][-1])
        align1 = ""
        align2 = ""

        # Start from the bottom right cell in matrix
        i = m
        j = n

        # We'll use i and j to keep track of where we are in the matrix, just like above
        while i > 0 and j > 0: # end touching the top or the left edge
            score_current = score[i][j]
            score_diagonal = score[i-1][j-1]
            score_up = score[i][j-1]
            score_left = score[i-1][j]

            # Check to figure out which cell the current score was calculated from,
            # then update i and j to correspond to that cell.
            if score_current == score_diagonal + self.match_score(seq1[j-1], seq2[i-1]):
                align1 += seq1[j-1]
                align2 += seq2[i-1]
                i -= 1
                j -= 1
            elif score_current == score_up + self.gap_penalty:
                align1 += seq1[j-1]
                align2 += '-'
                j -= 1
            elif score_current == score_left + self.gap_penalty:
                align1 += '-'
                align2 += seq2[i-1]
                i -= 1

        # Finish tracing up to the top left cell
        while j > 0:
            align1 += seq1[j-1]
            align2 += '-'
            j -= 1
        while i > 0:
            align1 += '-'
            align2 += seq2[i-1]
            i -= 1

        # Since we traversed the score matrix from the bottom right, our two sequences will be reversed.
        # These two lines reverse the order of the characters in each sequence.
        align1 = align1[::-1]
        align2 = align2[::-1]

        return (align1, align2)

def main():

    if len(sys.argv)>1:

        with open(sys.argv[1]) as f:
            sequences = f.readlines()
        for i in range(len(sequences))[1::2]:
            print ('\nSequence 1: ' + sequences[i-1].rstrip())
            print ('Sequence 2: ' + sequences[i].rstrip() + '\n')
            seq1 = sequences[i-1].rstrip()
            seq2 = sequences[i].rstrip()

            needm = NeedleMan(5, -1, -0.5)

            output1, output2 = needm.needleman_wunsch(seq1, seq2)
            print(output1 + "\n" + output2)

    else:

        seq1 = 'TTACTGTGTTT'
        seq2 = 'CACCCCTGTG'
        print ('\nSequence 1: ', seq1)
        print('Seqquence 2: ', seq2)
        needm = NeedleMan(5, -1, -0.5)
        output1, output2 = needm.needleman_wunsch(seq1, seq2)
        print(output1 + "\n" + output2)

if __name__=="__main__":
    main()


import os
import json
import subprocess

if not os.path.exists(".vscode"):
    os.makedirs(".vscode")

data = {
    "C_Cpp.default.includePath": [
        "include"
    ],
    "C_Cpp.default.defines": [
        "LOGGING",
        "LOGGING_FUNCTION_CALLS"
    ],
    "files.exclude": {
        "ground_station": True,
        "logs": True,
        ".vscode": True,
        ".gitignore": True,
        "res": False,
        "*.py": False,
        "*.md": False
    },
    "editor.minimap.enabled": False
}

output = subprocess.run(["pkg-config","--cflags", "gtkmm-3.0"], stdout = subprocess.PIPE, universal_newlines = True).stdout
gtk_include_path = ("/" + s for s in output.split(" -I/")[1:])
data["C_Cpp.default.includePath"].extend(gtk_include_path)

with open(".vscode/settings.json", "w") as write_file:
    json.dump(data, write_file, indent=4)


# Ввести в столбик последовательность целых (положительных и отрицательных) чисел, не равных нулю;
# в конце этой последовательности стоит 0. Вывести наибольшую сумму последовательно идущих элементов
# этой последовательности (не менее одного).

from sys import maxsize
maxfar = -maxsize - 1
maxend = 0
s = 0
a = int(input())
while a != 0:
    maxend += a
    a = int(input())
    if maxfar < maxend:
        maxfar = maxend

    if maxend < 0:
        maxend = 0

print(maxfar)


from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QPushButton, QHBoxLayout, QLabel, QVBoxLayout, QDialog

from sane_yt_subfeed import create_logger

TITLE = 'Are you sure?'
TEXT = 'This is a SaneConfirmationDialog'
OK = 'OK'
CANCEL = 'Cancel'
WIDTH = 360
HEIGHT = 80

class SaneConfirmationDialog(QDialog):
    def __init__(self, parent, actions, title, text, ok_text, cancel_text,
                 cancel_actions=None, caller=None, flags=Qt.WindowFlags):
        """
        Prompts user for a Yes/No Confirmation where Yes results in a call for each action in actions

        :param parent:
        :param text: Text to display in dialog body.
        :param actions: A function, or a list of functions to be called
        :param caller: (If given) applies action to the caller function e.g. action(caller)
        :param title: Title of dialog window.
        :param ok_text: Text to display on OK button.
        :param cancel_text: Text to display on Cancel button.
        :param cancel_actions: Actions to perform on cancel/no, if None it will bind to reject.
        :param flags:
        """
        super(SaneConfirmationDialog, self).__init__(parent, flags())
        self.logger = create_logger(__name__)
        self.sane_parent = parent

        if not title:
            self.title = TITLE
        else:
            self.title = title
        if not text:
            self.text = TEXT
        else:
            self.text = text
        if not ok_text:
            self.ok_text = OK
        else:
            self.ok_text = ok_text
        if not cancel_text:
            self.cancel_text = CANCEL
        else:
            self.cancel_text = cancel_text

        if type(actions) is not list:
            self.action = actions
        else:
            self.action = None
            self.actions = actions

        if cancel_actions:
            if type(cancel_actions) is not list:
                self.cancel_action = cancel_actions
            else:
                self.cancel_action = None
                self.cancel_actions = cancel_actions
        # Required since cancel action is not guaranteed to exist
        else:
            self.cancel_action = None
            self.cancel_actions = None

        self.caller = caller
        self.cancel_button = QPushButton(self)
        self.ok_button = QPushButton(self)

        self.init_ui()

    def init_ui(self):
        self.setWindowTitle(self.title)

        # Define contents
        self.cancel_button.setText(self.cancel_text)
        if self.cancel_action is None and self.cancel_actions is None:
            self.cancel_button.clicked.connect(self.reject)
        else:
            self.cancel_button.clicked.connect(self.do_cancel_actions)
        self.ok_button.setText(self.ok_text)
        self.ok_button.clicked.connect(self.do_ok_actions)

        # Define layouts
        layout = QVBoxLayout()
        layout.setAlignment(Qt.AlignTop)
        button_layout = QHBoxLayout()

        button_layout.addWidget(self.cancel_button)
        button_layout.addWidget(self.ok_button)

        layout.addWidget(QLabel(self.text), 0, Qt.AlignCenter)
        layout.addLayout(button_layout)

        self.setLayout(layout)

        self.resize(WIDTH, HEIGHT)

    def do_action(self, action):
        """
        Executes an action.
        :param action:
        :return:
        """
        if self.caller:
            # Apply action on the object that called me.
            action(self.caller)
        else:
            # Do an action that doesn't depend on who called me.
            action()

    def do_ok_actions(self):
        """
        Executes do_action one or more times if OK button is pressed.
        :return:
        """
        # Check if action is singular instead of plural (list).
        if self.action:
            self.do_action(self.action)
        else:
            for action in self.actions:
                self.do_action(action)

        # Close the dialog
        self.close()

    def do_cancel_actions(self):
        """
        Executes do_action one or more times if CANCEL button is pressed.
        :return:
        """
        # Check if action is singular instead of plural (list).
        if self.cancel_action:
            self.do_action(self.cancel_action)
        else:
            for cancel_action in self.cancel_actions:
                self.do_action(cancel_action)

        # Close the dialog
        self.close()


import pandas as pd
import logging
import json
from sklearn.model_selection import train_test_split
from sklearn.feature_extraction.text import TfidfVectorizer, CountVectorizer
from sklearn.ensemble import RandomForestRegressor
from sklearn.metrics import mean_absolute_error
from sklearn.compose import ColumnTransformer
from collections import Counter

def main():
    logging.getLogger().setLevel(logging.INFO)
    logging.info("Loading training/test data")
    train = pd.DataFrame.from_records(json.load(open('input/train.json'))).fillna("")
    test = pd.DataFrame.from_records(json.load(open('input/test.json'))).fillna("")

    # -------------------------------------------------Feature: entrytype-------------------------------------------------#
    entrytype_dummies = pd.get_dummies(train['ENTRYTYPE'], prefix='entrytype')
    train.drop('ENTRYTYPE', axis=1, inplace=True)

    # -------------------------------------------------Feature: publisher-------------------------------------------------#
    train['publisher'].fillna('Unknown', inplace=True)
    publisher_dummies = pd.get_dummies(train['publisher'], prefix='publisher')

    # -------------------------------------------------Feature: author-------------------------------------------------#
    all_authors = set()
    for authors_list in train['author'].dropna():
        all_authors.update(authors_list)

    author_frequencies = Counter()
    for authors_list in train['author'].dropna():
        author_frequencies.update(authors_list)

    prolific_authors = [author for author, count in author_frequencies.items() if count >= 25]
    author_dummies = train.copy()
    for author in prolific_authors:
        author_dummies[f'author_{author}'] = author_dummies['author'].apply(lambda x: author in x if isinstance(x, list) else False)
    author_dummies.drop(['editor','title','year','author','abstract'], axis=1, inplace=True)

    # -------------------------------------------------New feature: author count-------------------------------------------------#
    author_count = train['author'].apply(lambda x: len(x) if isinstance(x, list) else 0)

    # -------------------------------------------------Feature: title-------------------------------------------------#
    title_lower = train['title'].str.lower()
    vectorizer = TfidfVectorizer(stop_words='english', max_features=2000)
    title_tfidf = vectorizer.fit_transform(title_lower)
    title_processed = pd.DataFrame(title_tfidf.toarray(), columns=vectorizer.get_feature_names_out())

    # -------------------------------------------------Feature: abstract-------------------------------------------------#
    abstract_lower = train['abstract'].fillna('no_abstract').str.lower()
    abstract_vectorizer = CountVectorizer(stop_words='english', max_features=2000)
    abstract_processed = pd.DataFrame(abstract_vectorizer.fit_transform(abstract_lower).toarray(), columns=abstract_vectorizer.get_feature_names_out())

    # -------------------------------------------------New feature: length of abstract-------------------------------------------------#
    abstract_length = abstract_lower.apply(len)

    # -------------------------------------------------Feature: editor-------------------------------------------------#
    train['editor'].fillna('Unknown', inplace=True)
    all_editors = set()
    for editors_list in train['editor']:
        if isinstance(editors_list, list):
            all_editors.update(editors_list)
        else:
            all_editors.add(editors_list)

    editor_frequencies = Counter()
    for editors_list in train['editor']:
        if isinstance(editors_list, list):
            editor_frequencies.update(editors_list)
        else:
            editor_frequencies.update([editors_list])

    frequent_editors = [editor for editor, count in editor_frequencies.items() if count >= 5]
    editor_dummies = train.copy()
    for editor in frequent_editors:
        editor_dummies[f'editor_{editor}'] = editor_dummies['editor'].apply(lambda x: editor in x if isinstance(x, list) else editor == x)
    editor_dummies.drop(['editor', 'year'], axis=1, inplace=True)

    # -------------------------------------------------New feature: number of editors-------------------------------------------------#
    editor_count = train['editor'].apply(lambda x: len(x) if isinstance(x, list) else 0)

    # -------------------------------------------------Model: Random Forest-------------------------------------------------#
    X = pd.concat([entrytype_dummies, publisher_dummies, author_dummies, author_count, title_processed, abstract_processed, abstract_length, editor_dummies, editor_count], axis=1)
    y = train['year']

    # Splitting the dataset
    train, val = train_test_split(train, stratify=train['year'], test_size=0.2, random_state=0)

    # Initialize and fit the Random Forest Regressor
    model = RandomForestRegressor(n_estimators=200, n_jobs=-1, random_state=0, max_depth=3)
    model.fit(train.drop('year', axis=1), train['year'].values)

    # Evaluate on validation data
    val_pred = model.predict(val.drop('year', axis=1))
    err = mean_absolute_error(val['year'].values, val_pred)
    logging.info(f"Random Forest MAE: {err}")

    # Predict on test data
    test_pred = model.predict(test)
    test['year'] = test_pred

    # Write prediction file
    test.to_json("predicted2.json", orient='records', indent=2)

main()


"""Module to decode sensors developed with the SEEED E5 LoRaWAN module.
"""
from typing import Any, List, Tuple
import random

def decode_e5(data: bytes) -> List[Tuple[str, Any]]:
    """Decodes the payload from a custom Sensor from Analysis North using the
    SEEED E5 module.  Returns a list of tuples: (field name, value) or
    (field name, (value, time offset))
    """

    int16 = lambda ix: data[ix] << 8 | data[ix + 1]

    fields = []

    if data[0] == 1:
        # list of power values
        val_ct = (len(data) - 1) // 2  #  of readings
        # most current reading is last (0 time offset), and readings are
        # spaced 1 second apart.
        for rdg_ix in range(val_ct):
            data_ix = 1 + rdg_ix * 2
            pwr = int16(data_ix) * 0.1      # value is tenths of a Watt
            fields.append(
                ('power', (pwr, -(val_ct - rdg_ix - 1)))
            )

    elif data[0] == 2:
        # reboot.  Return a random value so that it is easy to find reboot points
        # on the graph.
        fields.append(
            ('reboot', random.random())
        )

    elif data[0]  == 3:
        # average power for an interval.
        pwr = int16(1) * 0.1    # power is given in tenths of Watt in payload
        ts_offset = -int16(3)   # timestamp offset, needs to be negative
        fields.append(
            ('power', (pwr, ts_offset))
        )

    return fields

if __name__ == "__main__":
    cases = (
        '01ffff00A0',
        '0100000000',
        '0100010002',
        '02',
    )
    for dta in cases:
        res = decode_e5(bytes.fromhex(dta))
        print(res)


import tensorflow as tf
from keras import Model
from keras.models import Sequential
from keras.models import load_model
from keras.layers import Dense
from keras.optimizers import Adam

import numpy as np
import random
from collections import deque

class Agent:
    def __init__(self, state_size, eval_mode=False, model_name=None, lr=0.001):
        self.state_size = state_size
        self.action_size = 3 # hold, buy, sell
        self.memory = deque(maxlen=500)
        self.inventory = []
        self.model_name = model_name
        self.eval_mode = eval_mode
        self.lr = lr

        self.gamma = 0.95
        self.epsilon = 1.0 if not model_name else 0.005
        self.epsilon_min = 0.005
        self.epsilon_decay = 0.995

        if model_name:
            self.model = load_model(f"models/{model_name}.h5")
        else:
            self.model = self.get_model()

    def get_model(self) -> Model:
        model = Sequential()
        model.add(Dense(units=256, input_dim=self.state_size, activation="relu"))
        model.add(Dense(units=256, activation="relu"))
        model.add(Dense(units=128, activation="relu"))
        model.add(Dense(units=128, activation="relu"))
        model.add(Dense(self.action_size, activation="linear"))
        model.compile(loss="mse", optimizer=Adam(lr=self.lr))

        return model

    def perform_action(self, state: np.array) -> int:
        if not self.eval_mode and np.random.rand() <= self.epsilon:
            return random.randrange(self.action_size)

        options = self.model.predict(state)
        return np.argmax(options[0])

    def experience_replay(self, batch_size):
        memory_len = len(self.memory)
        mini_batch = [self.memory[i] for i in range(memory_len - batch_size + 1, memory_len)]

        # memory index to value mapping: 0:state, 1:action, 2:reward, 3:next_state, 4:is_done
        next_states = tf.data.Dataset.from_tensor_slices([el[3] for el in mini_batch])
        states = tf.data.Dataset.from_tensor_slices([el[0] for el in mini_batch])
        targets = self.model.predict(next_states)
        target_fs = self.model.predict(states) #, workers=8,use_multiprocessing=True,

        x = []
        y = []
        for i, (state, action, reward, next_state, is_done) in enumerate(mini_batch):
            target = reward
            if not is_done:
                target = reward + self.gamma * np.amax(targets[i][0])
            target_f = np.array([target_fs[i]])

            target_f[0][action] = target
            x.append(state)
            y.append(target_f)

        train_data = tf.data.Dataset.from_tensor_slices((x, y))
        self.model.fit(train_data, epochs=1, verbose=0,) # workers=8,use_multiprocessing=True,)

        if self.epsilon > self.epsilon_min:
            self.epsilon *= self.epsilon_decay


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

from fastapi.encoders import jsonable_encoder
from sqlalchemy import insert, select, update
from sqlalchemy.ext.asyncio import AsyncSession

from backend.apis.deps import page_total
from backend.crud import CRUDBase
from backend.models import SystemMenu, MenuRelation
from backend.scheams import MenuStructure

class CRUDMenu(CRUDBase[SystemMenu, MenuStructure]):

    async def menuTree(self, db: AsyncSession) -> list:
        """ 获取树状部门结构数据 """
        sql = select(self.model)
        _menu = await db.scalars(sql)
        routers = jsonable_encoder(_menu.all())
        await db.close()
        if routers:
            result = []
            for item in routers:
                item = {
                    "id": item["id"],
                    "parent_id": item["parent_id"],
                    "label": item["title"],
                    "value": item["id"]
                }
                item.setdefault("children", [
                    {
                        "id": menu["id"],
                        "parent_id": menu["parent_id"],
                        "label": menu["title"],
                        "value": menu["id"]
                    }
                    for menu in routers
                    if menu["parent_id"] == item["id"]
                ])
                if item["parent_id"] == 0: result.append(item)
            return result

    async def getMenuByRole(self, db: AsyncSession, user_id: int) -> list:
        """ 获取用户权限理由 """
        sql = select(MenuRelation).where(user_id == MenuRelation.role_id)
        _menus = await db.scalars(sql)
        result = jsonable_encoder(_menus.all())
        await db.close()  # 释放会话
        return result

    async def userMenu(self, db: AsyncSession, user_id: int) -> list:
        """ 根据用户ID查询关联部门 """
        sql = select(MenuRelation).where(MenuRelation.user_id == user_id)
        relation_data = await db.scalars(sql)
        _relation = jsonable_encoder(relation_data.first())
        sql = select(self.model).where(self.model.id == _relation["menu_id"])
        _ids = await db.scalars(sql)
        result = jsonable_encoder(_ids.all())
        return result

    async def createRelation(self, db: AsyncSession, obj_in: dict) -> dict:
        """ 创建部门关联用户数据 """
        sql = insert(MenuRelation).values(obj_in)
        result = await db.execute(sql)
        await db.commit()
        return result.rowcount

    async def removeRelation(self, db: AsyncSession, user_id: int) -> int:
        """ 删除用户关联表 """
        sql = delete(MenuRelation).where(DeptRelation.user_id == user_id)
        result = await db.execute(sql)
        await db.commit()
        return result.rowcount

    async def getQuery(
            self,
            db: AsyncSession,
            queryObj: dict,
            orderBy: str = None,
            orderType: str = "ascending",
            pageIndex: int = 1,
            pageSize: int = 10,
            delete: str = "0"
    ) -> list:
        """ 根据查询条件获取 """

        baseSQL = select(self.model).where(self.model.delete == delete)

        if any([queryObj["name"], queryObj["title"], queryObj["hidden"]]):
            sql = baseSQL.where(self.model.name.like('%' + queryObj["name"] + '%'),
                                self.model.title.like('%' + queryObj["title"] + '%'))
        elif any([queryObj["minDate"], queryObj["maxDate"]]):
            sql = baseSQL.where(self.model.created_at >= queryObj["minDate"],
                                self.model.created_at <= queryObj["maxDate"])
        elif queryObj["hidden"]: sql = baseSQL.where(self.model.hidden == queryObj["hidden"])
        elif queryObj["status"]: sql = baseSQL.where(self.model.status == str(queryObj["status"]))
        else: sql = baseSQL.offset((pageIndex - 1) * pageSize)

        if orderType == "descending": sql = sql.order_by(desc(orderBy))
        else: sql = sql.order_by(orderBy)

        _query = await db.scalars(sql)
        total = await self.get_number(db)
        routers = jsonable_encoder(_query.all())
        await db.close()  # 释放会话
        result = []
        if routers:
            for item in routers:
                item.setdefault("children", [menu for menu in routers if menu["parent_id"] == item["id"]])
                if item["parent_id"] == 0: result.append(item)
            return {
                "items": result, "pageInfo": {
                    "total": total, "currentPage": pageIndex, "totalPage": page_total(total, pageSize)
                }
            }
        return result

    async def getChangeSort(self, db: AsyncSession, obj_in: dict) -> int:
        """ 修改列表排序 """
        sql = update(self.model).where(self.model.id == obj_in["id"]).values({"sort": obj_in["numberValue"]})
        result = await db.execute(sql)
        await db.commit()
        return result.rowcount

getMenu = CRUDMenu(SystemMenu)