import tensorflow as tf
import math
import time
from datetime import datetime
import os
from PIL import Image, ImageDraw, ImageFont
import numpy as np
from tqdm import tqdm
import matplotlib.pyplot as plt

class Data:
    def __init__(self, batch_size, num_classes, data_path, val_data):
        """
        :param batch_size: batch size
        :param num_classes: number of classes for datasets
        :param data_path: training set path
        :param val_data: validation set path
        """
        self.batch_size = batch_size
        self.num_classes = num_classes
        self.data_path = data_path
        self.labels_name = []
        self.val_data = val_data
        self.image_names = os.listdir(self.data_path)
        for name in tqdm(self.image_names):
            class_name = name.split('.')[0].split('_')[-1]
            self.labels_name.append(class_name)
        class_set = set(self.labels_name)
        self.labels_dict = {}
        for v, k in enumerate(class_set):
            self.labels_dict[k] = v
        print("Data Loading finished!")
        print("Label dict: ", self.labels_dict)
        self.labels = [self.labels_dict.get(k) for k in self.labels_name]
        self.inverse_dict = dict((val, key) for key, val in self.labels_dict.items())

    # convert label to one hot form
    def getOneHotLabel(self, labels, depth):
        label = np.zeros([len(labels), depth])
        for i in range(len(labels)):
            label[i][labels[i]] = 1
        return label

    def get_batch(self, count):
        start = count * self.batch_size
        end = (count + 1) * self.batch_size
        start_pos = max(0, start)
        end_pos = min(end, len(self.labels))
        images_name_batch = self.image_names[start_pos: end_pos]
        images = []
        for images_name in images_name_batch:
            image_path = os.path.join(self.data_path, images_name)
            image = Image.open(image_path)
            image = np.array(image) / 255.0
            images.append(image)
        labels = self.labels[start_pos: end_pos]
        datas = np.array(images)
        labels = np.array(labels)
        labels = self.getOneHotLabel(labels, self.num_classes)
        return datas, labels

    def get_batch_num(self):
        return len(self.labels) // self.batch_size

    def get_batch_size(self):
        return self.batch_size

    def get_val_data(self):
        val_names = os.listdir(self.val_data)
        val_images = []
        val_labels = []
        for name in val_names:
            image_path = os.path.join(self.val_data, name)
            image = Image.open(image_path)
            image = np.array(image) / 255.0
            val_images.append(image)
            class_name_val = name.split('.')[0].split('_')[-1]
            val_labels.append(class_name_val)
        val_images = np.array(val_images)
        val_labels = [self.labels_dict.get(k) for k in val_labels]
        val_labels = np.array(val_labels)
        val_labels = self.getOneHotLabel(val_labels, self.num_classes)
        return val_images, val_labels

    def get_label_dict(self):
        return self.labels_dict


import numpy as np
import pandas as pd
import math
import sys
import csv
import matplotlib
import matplotlib.pyplot as plt

PM2_5=[]
normalization=[]
for i in range(18):
    normalization.append([])

def main():
    train_x, train_y = load_train()
    print(PM2_5)
    linear_regression(train_x, train_y)

def linear_regression(train_x, train_y):
    train_x = np.concatenate((np.ones((train_x.shape[0],1)),train_x), axis=1)
    #cross validation
    print(train_x.shape[0], train_x.shape[1])
    batchs=36
    batch_size = int(train_x.shape[0]/batchs)
    batch_paras = [13]
    feature_paras = [0.24]
    final_RMSEloss = []
    final_batch_RMSEloss = []
    for feature_para in feature_paras:
        feature_threshold = feature_para
        #generate feature-selected train_x
        pollution = 0
        fs_train_x = train_x[:, :1]
        for term in PM2_5:
            #print(term)
            if pollution ==9:
                fs_train_x = np.concatenate((fs_train_x, train_x[:, pollution*4+1:pollution*4+10]), axis=1)
                print(fs_train_x.shape[0], fs_train_x.shape[1])
                #print(np.sum(train_x[:, :pollution*4+10]-fs_train_x))
            elif term >= feature_threshold and pollution < 9:
                fs_train_x = np.concatenate((fs_train_x, train_x[:, pollution*4+1:(pollution+1)*4+1]), axis=1)
                print(fs_train_x.shape[0], fs_train_x.shape[1])
                #print(np.sum(train_x[:, :(pollution+1)*4+1]-fs_train_x))
            elif term >= feature_threshold and pollution > 9:
                fs_train_x = np.concatenate((fs_train_x, train_x[:, pollution*4+6:(pollution+1)*4+6]), axis=1)
                print(fs_train_x.shape[0], fs_train_x.shape[1])
                #print(np.sum(train_x[:, :(pollution+1)*4+6]-fs_train_x))
            pollution+=1
        #print(np.sum(train_x-fs_train_x))
        train_x = fs_train_x

        batch_RMSEloss = []
        for batch in range(batchs):
            if batch == 0:
                train1_x = train_x[batch_size:]
                train1_y = train_y[batch_size:]
                val_x = train_x[:batch_size]
                val_y = train_y[:batch_size]
            elif batch == batchs-1:
                train1_x = train_x[:batch*batch_size]
                train1_y = train_y[:batch*batch_size]
                val_x = train_x[batch*batch_size:]
                val_y = train_y[batch*batch_size:]
            else:
                train1_x = train_x[:batch*batch_size]
                val_x = train_x[batch*batch_size:(batch+1)*batch_size]
                train2_x = train_x[(batch+1)*batch_size:]
                train1_x = np.concatenate((train1_x, train2_x), axis=0)
                train1_y = train_y[:batch*batch_size]
                val_y = train_y[batch*batch_size:(batch+1)*batch_size]
                train2_y = train_y[(batch+1)*batch_size:]
                train1_y = np.concatenate((train1_y, train2_y), axis=0)
                #testt = np.concatenate((val_x,train1_x), axis=0)
                #print(train1_x.shape[0])
                #print(val_x.shape[0])
                #print(np.sum(train_x-testt))
            RMSEloss = gradient_descend(train1_x, train1_y, val_x, val_y, 10000, 0.1, batch)
            batch_RMSEloss.append(RMSEloss)
        batch_RMSEloss = np.array(batch_RMSEloss)
        final_batch_RMSEloss.append(np.mean(batch_RMSEloss))
        #print(np.mean(batch_RMSEloss))

            #print(batch_RMSEloss)
        for batch_para in batch_paras:
            print("model : %f , %f " % (feature_para, batch_para))
            val_threshold = batch_para
            train_final_x=[]
            train_final_y=[]
            train_final_val_x=[]
            train_final_val_y=[]
            for term in range(len(batch_RMSEloss)):
                if batch_RMSEloss[term] <= val_threshold:
                    if train_final_x == []:
                        train_final_x = train_x[term*batch_size:(term+1)*batch_size]
                    else:
                        train_final_x = np.concatenate((train_final_x, train_x[term*batch_size:(term+1)*batch_size]), axis=0)
                    if train_final_y == []:
                        train_final_y = train_y[term*batch_size:(term+1)*batch_size]
                    else:
                        train_final_y = np.concatenate((train_final_y, train_y[term*batch_size:(term+1)*batch_size]), axis=0)
                    print(train_final_x.shape[0], train_final_x.shape[1])
                    print(train_final_y.shape[0])
            RMSEloss = gradient_descend(train_final_x, train_final_y, train_final_val_x, train_final_val_y, 10000, 0.1, -1)
            final_RMSEloss.append([RMSEloss, feature_threshold, val_threshold])
    print(final_RMSEloss)
    print(final_batch_RMSEloss)
def gradient_descend(train_x, train_y, val_x, val_y, epochs, l_rate, batch):
    w = np.zeros(len(train_x[0]))
    #print(train_x)
    train_x_t = train_x.transpose()
    prev_gra = np.zeros(len(train_x[0]))
    for i in range(epochs):
        predict = np.dot(train_x,w)
        gra = -np.dot(train_x_t, (train_y - predict))
        prev_gra += gra**2
        ada = np.sqrt(prev_gra)
        w = w - l_rate * gra/ada
    #np.save("model_%d" % (batch), w)
    RMSEloss = np.sqrt(np.mean((de_normalization(train_y) - de_normalization(predict))** 2) )
    #RMSEloss = np.sqrt(np.mean((train_y - predict)** 2) )
    # save model
    if batch == -1:
        np.save('model.npy',w)
        print("batch: %d | train error rate: %f " % (batch+1, RMSEloss))
        val_RMSEloss = RMSEloss
    else:
        val_predict = np.dot(val_x, w)
        val_RMSEloss = np.sqrt(np.mean((de_normalization(val_y) - de_normalization(val_predict))** 2) )
        #val_RMSEloss = np.sqrt(np.mean(val_y - val_predict)** 2 )
        print("batch: %d | train error rate: %f | val error rate: %f" % (batch+1, RMSEloss, val_RMSEloss))
    return val_RMSEloss

def load_train():
    global PM2_5
    data = []
    for i in range(18):
        data.append([])
    pollution = 0
    train = open('data/train.csv', 'r', encoding = 'big5')
    rows = csv.reader(train, delimiter = ",")
    for row in rows:
        if pollution != 0:
            for i in range(3,27):
                if row[i] != "NR":
                    data[(pollution-1)%18].append(float(row[i]))
                else:
                    data[(pollution-1)%18].append(float(0))
        pollution+=1
    train.close()

    df = pd.DataFrame()
    for pollution in range(18):
        df[pollution] = data[pollution]
    PM2_5 = df.corrwith(df[9])
    np.save("PM2_5.npy", PM2_5)
    '''
    plt.matshow(df.corr())
    plt.xticks(range(len(df.columns)), df.columns)
    plt.yticks(range(len(df.columns)), df.columns)
    plt.colorbar()
    plt.show()
    '''
    #print(data[0][0])
    data = data_normalization(data, 1)
    #print(data[0][0])
    #print(data[0][0]*(normalization[0][1]-normalization[0][0])+normalization[0][0])
    train_x = []
    train_y = []
    for month in range(12):
        for n in range(471):
            train_x.append([])
            for p in range(18):
                for hr in range(9):
                    if data[p][480*month+n+hr] == 0:
                        correct_0 = 0
                        for index in range(1,4):
                            correct_hr = (hr + index) % 9
                            correct_0+=data[p][480*month+n+correct_hr]
                        data[p][480*month+n+hr] = correct_0/3
                        if data[p][480*month+n+hr] == 0:
                            data[p][480*month+n+hr] = 0.5
                    if p != 9:
                        if hr >= 5:
                            train_x[471*month+n].append(data[p][480*month+n+hr] )
                    else:
                        train_x[471*month+n].append(data[p][480*month+n+hr] )
            train_y.append(data[9][480*month+n+9])
    train_x = np.array(train_x)
    train_y = np.array(train_y)
    return train_x, train_y

def load_test():
    data = []
    for i in range(18):
        data.append([])
    pollution = 0
    test = open('data/test.csv' ,"r", encoding = 'big5')
    rows = csv.reader(test , delimiter= ",")
    for row in rows:
        #if pollution %18 == 0:
            #test_x.append([])
        for i in range(2,11):
            if row[i] !="NR":
                data[pollution%18].append(float(row[i]))
                #test_x[pollution//18].append(float(row[i]))
            else:
                data[pollution%18].append(float(0))
                #test_x[pollution//18].append(0)
        pollution+=1
    test.close()

    data = data_normalization(data, 0)
    data = np.array(data)

    test_x = []
    for n in range(data.shape[1]//9):
        test_x.append([])
        for p in range(18):
            for hr in range(9):
                if data[p][n*9+hr] == 0:
                    correct_0 = 0
                    for index in range(1,4):
                        correct_hr = (hr + index) % 9
                        correct_0+=data[p][n*9+correct_hr]
                    data[p][n*9+hr] = correct_0/3
                    if data[p][n*9+hr] == 0:
                        data[p][n*9+hr] = 0.5
                if p != 9:
                    if hr >= 5:
                        test_x[n].append(data[p][n*9+hr])
                else:
                    test_x[n].append(data[p][n*9+hr])
    test_x = np.array(test_x)
    #add square term
    #test_x = np.concatenate((test_x,test_x**2), axis=1)
    return test_x

def data_normalization(data, train):
    global normalization
    #improvable
    for pollution in range(18):
        if train:
            p_min = np.min(data[pollution], axis=0)
            p_max = np.max(data[pollution], axis=0)
            normalization[pollution].append(p_min)
            normalization[pollution].append(p_max)
        #print(normalization)
        for i in range(len(data[pollution])):
            data[pollution][i] = (data[pollution][i] - normalization[pollution][0]) / (normalization[pollution][1] - normalization[pollution][0])
    np.save("normalization.npy",normalization)
    return data

def de_normalization(predict):
    return predict*(normalization[9][1]-normalization[9][0])+normalization[9][0]

def output_answer(test_x, w):
    test_x = np.concatenate((np.ones((test_x.shape[0],1)),test_x), axis=1)
    #print(test_x[0])
    feature_threshold = 0.246
    #generate feature-selected train_x
    pollution = 0
    fs_test_x = test_x[:, :1]
    for term in PM2_5:
        #print(term)
        if pollution == 9:
            fs_test_x = np.concatenate((fs_test_x, test_x[:, pollution*4+1:pollution*4+10]), axis=1)
            print(fs_test_x.shape[0], fs_test_x.shape[1])
        elif term >= feature_threshold and pollution < 9:
            fs_test_x = np.concatenate((fs_test_x, test_x[:, pollution*4+1:(pollution+1)*4+1]), axis=1)
            print(fs_test_x.shape[0], fs_test_x.shape[1])
            #print(np.sum(test_x-fs_test_x))
        elif term >= feature_threshold and pollution > 9:
            fs_test_x = np.concatenate((fs_test_x, test_x[:, pollution*4+6:(pollution+1)*4+6]), axis=1)
            print(fs_test_x.shape[0], fs_test_x.shape[1])
            #print(np.sum(test_x-fs_test_x))
        pollution+=1
    #print(np.sum(test_x-fs_test_x))
    test_x = fs_test_x
    #print(test_x.shape[1])
    ans = []
    for i in range(len(test_x)):
        ans.append([])
        ans[i].append("id_" + str(i))
        predict = np.dot(w,test_x[i])
        #print(w[1], test_x[i][1], predict, de_normalization(predict))
        ans[i].append(de_normalization(predict))
        #ans[i].append(predict)

    filename = "result/predict.csv"
    answer = open(filename, "w+")
    output = csv.writer(answer,delimiter=',',lineterminator='\n')
    output.writerow(["id","value"])
    for i in range(len(ans)):
        output.writerow(ans[i])
    answer.close()

main()
'''
[5.847131595951411, 6.467332472049556, 6.720242637910978, 7.052816733040604, 5.693279501203789, 6.310390018176018, 6.565079655596946, 6.909165893721935, 5.676831987208386, 6.298728067285582, 6.553633047239661, 6.891906437410382, 5.5885753495456845, 6.287201409833578, 6.542705228282351, 6.879488811638106]
'''


import os

class ATM:
    def __init__(self, accountListFile, transactionSummary):
        self.accountList = []
        self.transactionList = []
        self.depositRecord = {}                                                 # key: account, value: depositted amount
        self.withdrawRecord = {}                                                # key: account, value: withdrawn amount
        self.transferRecord = {}                                                # key: account, value: transferred amount
        self.readList(accountListFile)                                          # read account list to accountList
        self.writeTarget = transactionSummary
        self.interface()

    # read account list and append it to accountList
    def readList(self,fileName):
        with open(fileName, 'r') as f:
            line = f.readline()
            while line:
                self.accountList.append(line.strip())
                line = f.readline()

    # takes amount in cent such as "001"
    # convert it to float, such as 0.01
    def inputConvert(self, amount):
        return float(amount[:-2] + "." + amount[-2:])

    # main interface
    def interface(self):
        while True:                                                             # loop until accept 'logout' command
            self.greeting()
            function = input()
            if function == "deposit":
                signal = self.functionDeposit()
                if signal == 0: break
            elif function == "withdraw":
                signal = self.functionWithdraw()
                if signal == 0: break
            elif function == "transfer":
                signal = self.functionTransfer()
                if signal == 0: break
            elif function == "createacct":
                signal = self.functionCreateAccount()
                if signal == 0: break
            elif function == "deleteacct":
                signal = self.functionDeleteAccount()
                if signal == 0: break
            elif function == "logout":
                break
            else:
                print("Check your input, and try again!")
        self.functionLogout()

    # print greeting when login to ATM mode
    # overriden in agent.py
    def greeting(self):
        print("Hello, welcome to the ATM mode, please type the transaction you want to make: ")

    # deposit logic frame
    # get valid toAccount and amount,
    # then append the transaction to transactionList
    def functionDeposit(self):
        toAccount = input("Enter your account please: ")
        if toAccount == "logout":
            return 0
        while (not self.verifyAccount(toAccount) or not self.existAccount(toAccount)):          # invalid format or non-exist
            toAccount = input("--> ")
            if toAccount == "logout":
                return 0
        amount = input("Enter the amount of money you want to deposit: ")
        if amount == "logout":
            return 0
        while not self.verifyDepositAmount(toAccount,amount):                                   # invalid amount
            amount = input("--> ")
            if amount == "logout":
                return 0
        transaction = "DEP {} {} 0000000 ***\n".format(toAccount, amount)
        self.transactionList.append(transaction)                                                # append transaction info to the transactionList
        self.recordTransaction("deposit", toAccount, self.inputConvert(amount))                 # record transaction
        print("<--  Your transaction has been successfully made!  -->")
        print("=="*34)
        return 1

    # withdraw logic frame
    # get valid fromAccount and amount,
    # then append the transaction to the transactionList.
    def functionWithdraw(self):
        fromAccount = input("Enter your account please: ")
        if fromAccount == "logout":
            return 0
        while (not self.verifyAccount(fromAccount) or not self.existAccount(fromAccount)):      # invalid format or non-exist
            fromAccount = input("--> ")
            if fromAccount == "logout":
                return 0
        amount = input("Enter the amount of money you want to withdraw: ")
        if amount == "logout":
            return 0
        while not self.verifyWithdrawAmount(fromAccount, amount):                               # invalid amount
            amount = input("--> ")
            if amount == "logout":
                return 0
        transaction = "WDR 0000000 {} {} ***\n".format(amount, fromAccount)
        self.transactionList.append(transaction)                                                # append transaction info to the transactionList
        self.recordTransaction("withdraw", fromAccount, self.inputConvert(amount))              # record transaction
        print("<--  Your transaction has been successfully made!  -->")
        print("=="*34)
        return 1

    # transfer logic frame
    # get valid fromAccount, toAccount, and amount,
    # then append the transaction to the transactionList.
    def functionTransfer(self):
        fromAccount = input("Enter your account please: ")
        if fromAccount == "logout":
            return 0
        while (not self.verifyAccount(fromAccount) or not self.existAccount(fromAccount)):      # invalid format or non-exist
            fromAccount = input("--> ")
            if fromAccount == "logout":
                return 0
        toAccount = input("Enter the payee account please: ")
        if toAccount == "logout":
            return 0
        while (not self.verifyAccount(toAccount) or not self.existAccount(toAccount)):          # invalid format or non-exist
            toAccount = input("--> ")
            if toAccount == "logout":
                return 0
        amount = input("Enter the amount of money you want to transfer: ")
        if amount == "logout":
            return 0
        while not self.verifyTransferAmount(fromAccount, amount):                               # invalid amount
            amount = input("--> ")
            if amount == "logout":
                return 0
        transaction = "XFR {} {} {} ***\n".format(toAccount, amount, fromAccount )
        self.transactionList.append(transaction)                                                # append transaction info to transactionList
        self.recordTransaction("transfer", fromAccount, self.inputConvert(amount))              # record transaction
        print("<--  Your transaction has been successfully made!  -->")
        print("==" * 34)
        return 1

    # createacct (not supported in ATM mode)
    # overriden in agent.py
    def functionCreateAccount(self):
        print("The operation is not supported in ATM mode")
        return 1

    # deleteacct (not supported in ATM mode)
    # overriden in agent.py
    def functionDeleteAccount(self):
        print("The operation is not supported in ATM mode")
        return 1

    # logout
    # write transaction summary file here
    def functionLogout(self):
        writeDir = os.path.dirname(self.writeTarget)
        if not os.path.exists(writeDir):
            os.makedirs(writeDir)
        try:
            f = open(self.writeTarget, "w")
            self.transactionList.append("EOS")                                              # transaction summary file end with "EOS"
            f.writelines(self.transactionList)                                              # write transaction summary file
            f.close()
        except:
            print("file cannot found")
        return 0

    # record transaction in corresponding dict
    # @transaction: type of transaction
    # @account:     account number
    # @amount:      the amount of the type of transaction
    def recordTransaction(self, transaction, account, amount):
        if transaction == "deposit":
            currentAmount = self.depositRecord.get(account)
            if currentAmount is None:                                                  # uninitialized amount will be None
                currentAmount = 0
            updatedAmount = currentAmount + amount
            self.depositRecord[account] = updatedAmount
        elif transaction == "withdraw":
            currentAmount = self.withdrawRecord.get(account)
            if currentAmount is None:                                                  # uninitialized amount will be None
                currentAmount = 0
            updatedAmount = currentAmount + amount
            self.withdrawRecord[account] = updatedAmount
        elif transaction == "transfer":
            currentAmount = self.transferRecord.get(account)
            if currentAmount is None:                                                  # uninitialized amount will be None
                currentAmount = 0
            updatedAmount = currentAmount + amount
            self.transferRecord[account] = updatedAmount

    # verify the account if is valid or not
    # length exactly 7 digits and can not start with '0'
    def verifyAccount(self,account):
        if len(account) != 7:
            print("The account has to be exactly 7 digits")
            return False
        elif account[0] == '0':
            # change from the to The
            print("The account cannot start with '0'")
            return False
        elif not account.isdigit():
            print("The account cannot contain other characters")
            return False
        return True

    # verify the amount is valid
    # length is valid and only contain number
    def verifyAmount(self, amount):
        if len(amount) < 3 or len(amount) > 8:
            print("Invalid amount, please try again!")
            return False
        elif not amount.isdigit():
            print("Invalid amount, please try again!")
            return False
        elif amount[0] == '0' and len(amount) > 3:                                      # such as "0111"
            print("Invalid amount, please try again!")
            return False
        else:
            return True

    # further verfiy the deposit amount
    # each deposit within $2,000
    # daily deposit limit is $5,000
    def verifyDepositAmount(self, account, amount):
        if self.verifyAmount(amount):
            if self.inputConvert(amount) > 2000:                                                            # each time deposit should <= $2,000
                print("The limit of each deposit is $2,000, please retype: ")
                return False
            currentAmount = self.depositRecord.get(account)
            if currentAmount is None or 5000 >= currentAmount + self.inputConvert(amount):                  # total deposit should <= $5,000
                return True
            else:
                print("The daily limit of deposit is $5,000, ", end="")
                print(f"you have used ${self.depositRecord.get(account):.2f}, please try again.")
                return False
        return False

    # further verify the withdraw amount
    # each withdraw within $1,000
    # daily withdraw limit is $5,000
    def verifyWithdrawAmount(self, account, amount):
        if self.verifyAmount(amount):
            if self.inputConvert(amount) > 1000:                                                            # each time withdraw should <= $1,000
                print("The limit of each withdraw is $1,000, please retype: ")
                return False
            currentAmount = self.withdrawRecord.get(account)
            if currentAmount is None or 5000 >= currentAmount + self.inputConvert(amount):                  # total withdraw amount should <= $5,000
                return True
            else:
                print("The daliy limit of withdraw is $5,000, ", end="")
                print(f"you have withdrawn ${self.withdrawRecord.get(account):.2f}, please try again.")
                return False
        return False

    # further verify the transfer amount
    # each transfer within $10,000
    # daily transfer limit is $10,000
    def verifyTransferAmount(self, fromAccount, amount):
        if self.verifyAmount(amount):
            if self.inputConvert(amount) > 10000:                                                       # each transfer should <= $10,000
                print("The limit of each transfer is $10,000, please retype: ")
                return False
            currentAmount = self.transferRecord.get(fromAccount)
            if currentAmount is None or 10000 >= currentAmount + self.inputConvert(amount):             # total transfer should <= $10,000
                return True
            else:
                print("The daliy limit of transfer is $10,000, ", end="")
                print(f"you have transferred ${self.transferRecord.get(fromAccount):.2f}, please try again.")
        return False

    # binary search see if a account in the account list
    def existAccount(self,account):
        start = 0
        end = len(self.accountList) - 2
        while start <= end:
            middle = (start + end) // 2
            if self.accountList[middle] > account:
                start = middle + 1
            elif self.accountList[middle] < account:
                end = middle - 1
            else:
                return True
        print("No matching account found!")
        return False


from mcpi.minecraft import Minecraft
import time
mc=Minecraft.create()
pos=mc.player.getTilePos()
f=open("block.csv",'w')
L=20
W=20
H=15
for y in range (H):
    for x in range (L):
        for z in range (W):
            block=mc.getBlockWithData(pos.x+x+1,pos.y+y,pos.z+z+1)
            f.write(str(block.id))
            f.write('|')
            f.write(str(block.data))
            if z < W-1:
                f.write(',')

        f.write('\n')
        print(x,y)
f.close()


# Replace Description:
# Given a string, character to replace, and character to sub
# Return a new string which subbed in characters

def sub_letter(a_str, to_r, to_s):
    arr = list(a_str)
    for i in range(len(arr)):
        if arr[i] == to_r:
            arr[i] = to_s
    return "".join(arr)

if __name__ == "__main__":
    a_string = "brady"
    b_string = sub_letter(a_string, "b", "g")
    print(a_string)
    print(b_string)


#pip install flask
from flask import Flask, render_template

edad = 45

aplicacion = Flask(__name__)

@aplicacion.route('/')
def hello_world():
    return render_template("index.html")

@aplicacion.route('/envia')
def envia():
    print("alguien me esta intentando enviar algo")
    return "ok"

if __name__ == '__main__':
    aplicacion.run(host="192.168.1.215")


import numpy as np
from numpy.linalg import inv
from numpy import genfromtxt
from tabulate import tabulate

def header_names(tableau):
    m,n = np.shape(tableau)
    n = n-1
    headers = {}
    for i in range(n):
        headers[ "x" + str( i+1 ) ] = i
        i+=1
    headers["BFS"] = n
    return headers

def standard_input():
    A = genfromtxt('/Users/kaustubhrajimwale/Desktop/Fall 21/IE535/Computing Project/Model12/A.csv', delimiter=',')
    A = np.delete(A, 0, 1)

    b = genfromtxt('/Users/kaustubhrajimwale/Desktop/Fall 21/IE535/Computing Project/Model12/b.csv', delimiter=',')
    b = np.delete(b, 0, 1)

    C = genfromtxt('/Users/kaustubhrajimwale/Desktop/Fall 21/IE535/Computing Project/Model12/C.csv', delimiter=',')
    C = np.delete(C, 0, 1)

    z = input("\nMaximize(1) or Minimize(0): ")
    z = int(z)

    if z != 0:
        C = C * (-1)

    return(A,b,C,z)

def add_artifical_variables(A):
    m,n = np.shape(A)
    C_phase1 = np.zeros(((n+m),1))
    for i in range(m):
        x_a = np.zeros((m,1))
        x_a[i,0] = 1
        A = np.concatenate((A, x_a), 1)
        C_phase1[n+i,0] = 1
    return A, C_phase1

def initial_basic_variables(A):
    m,n = np.shape(A)
    l = 0
    k = 0
    Xb = np.zeros((m))

    for l in range(m):
        for k in range(n):
            if A[l,n-k-1]==1:
                Xb[l] = n-k
                break
            k+=1
        l+=1
    return Xb

def basic_matrix(A,Xb):
    m,n = np.shape(A)
    B = np.zeros((m, m))
    i = 0
    j = 0
    for i in range(m):
        for j in range(m):
            B[i,j] = A[i, int(Xb[j])-1]
    return B

def BFS(B,b):
    Binv = inv(B)
    Binv_b = Binv @ b
    return Binv_b, Binv

def find_Cb(C, Xb,A):
    m,n = np.shape(A)
    Cb = np.zeros((m,1))
    i = 0
    for i in range(m):
        Cb[i] = int(C[int(Xb[i]-1)])
    return Cb

def initiate_tableau(A, Binv_b):
    m,n = np.shape(A)
    tableau = np.zeros((m+1,n+1))
    tableau[1:m+1, 0:n] = A
    tableau[1:m+1, n] = np.asarray(Binv_b[:,0])
    return tableau

def reduced_cost(Cb,A,C,tableau):
    m,n = np.shape(A)
    tableau[0,0:n] = np.subtract((np.transpose(Cb) @ A), np.transpose(C))
    return tableau

def obj(tableau,Cb,A):
    m,n = np.shape(A)
    tableau[0,n] = (np.transpose(Cb) @ tableau[1:m+1, n])
    return tableau

def initiate():
    A,b, C, z = standard_input()
    m,n = np.shape(A)
    A, C_phase1 = add_artifical_variables(A)
    Xb = initial_basic_variables(A)
    B = basic_matrix(A,Xb)
    Binv_b, Binv = BFS(B, b)
    Cb = find_Cb(C_phase1,Xb,A)
    tableau = initiate_tableau(A, Binv_b)
    tableau = reduced_cost(Cb,A,C_phase1,tableau)
    tableau = obj(tableau,Cb,A)
    return (tableau,Xb,C,z)

def simplex_iterations(tableau,Xb):

    ### PRINTER
    print("\n===============================")
    print("STARTING TABLEAU")
    print("===============================\n")
    print(tabulate(np.round(tableau,10), tablefmt="github", headers=header_names(tableau), numalign="right"))
    #PRINTER

    m,n = np.shape(tableau)
    m = m-1
    n = n-1
    iter = 0
    flag = 1
    optimal = 0
    unbdd = 0
    pivot_col = int(0)

    while(flag != 0):

        iter += 1
        print("\n===============================")
        print("ITERATION ",iter)
        print("===============================\n")
        print(tabulate(np.round(tableau,10), tablefmt="github", headers=header_names(tableau),numalign="right"),"\n\nBasic Variables:",Xb)

        if (np.all(np.round(tableau[0,0:n],10)<=0)):
            flag = 0
            flag = int(flag)
            optimal = 1
            break

        else:
            maxRC = 0
            i=0
            for i in range(n):
                if tableau[0,i]>=maxRC:
                    maxRC = tableau[0,i]
                    pivot_col = i
                i+=1

            y = (tableau[1:m+1,pivot_col]<=0)
            if (sum(y)==m):
                flag = 0
                flag = int(flag)
                unbdd = 1
                break

            #ratio_test
            ratio = 10000000001
            i=0
            for i in range(m):
                if (tableau[i+1,pivot_col]>0) and ((tableau[i+1,n]/tableau[i+1,pivot_col])<=ratio):
                    if (tableau[i+1,n]/tableau[i+1,pivot_col]) < ratio:
                        ratio = (tableau[i+1,n]/tableau[i+1,pivot_col])
                        pivot_row = i+1

                    else:
                        lexicographic = tableau[i+1,:] - tableau[pivot_row,:]
                        j=0
                        while(i>=0):
                            if lexicographic[j]>0:
                                ratio = (tableau[i+1,n]/tableau[i+1,pivot_col])
                                pivot_row = i+1
                                break
                            else:
                                if lexicographic[j]<0:
                                    break
                                else:
                                    j+=1
                i+=1
            print("\nPivot Element:",tableau[pivot_row,pivot_col],"\n")
            print("Entering Variable: x",pivot_col+1)
            print("Leaving Variable: x",int(Xb[pivot_row-1]),"\n")
            Xb[pivot_row-1] = pivot_col+1

            #Row Transformations
            i=0
            tableau[pivot_row,:] = tableau[pivot_row,:]/tableau[pivot_row,pivot_col]
            for i in range(m+1):
                if i!=pivot_row:
                    tableau[i,:] = tableau[i,:] - (tableau[pivot_row,:]*(tableau[i,pivot_col]))
                i+=1

    return(tableau,unbdd,optimal,pivot_col, Xb)

def result_phase1(unbdd, optimal, tableau, Xb, C):
    m,n = np.shape(tableau)
    m = m-1
    n = n-1
    phase2 = 1

    logic = Xb > n-m

    if(sum(logic)!=0):
        count = 0
        i = 0
        artificial_variables_in_basis =  np.zeros((0))
        temp = np.zeros((1))
        temp_row = np.zeros((1))
        rows_to_remove = np.zeros((0))
        val = np.zeros((0))

        for i in range(m):
            if Xb[i] > n-m:
                temp[0] = Xb[i]
                artificial_variables_in_basis = np.append(artificial_variables_in_basis,temp,axis= 0)
                temp[0] = round((tableau[i+1,n]),10)
                val = np.append(val,temp,axis= 0)
                if temp == 0:
                    temp_row[0] = i+1
                    rows_to_remove = np.append(rows_to_remove,temp_row,axis= 0)
            i+=1

        if (sum(val == 0)!=0):
            print("\nRedundancy Exists! Removing the redundant constraint.\n")
            l, = np.shape(rows_to_remove)
            i = 0
            print("...")
            for i in range(l):
                tableau = np.delete(tableau, int(rows_to_remove[i]), 0)
                Xb = np.delete(Xb, int(rows_to_remove[i]-1), 0)
                print("...")
                i+=1
            print("\nRedundant Row Deleted\n")

        else:
            print("\nThe linear program is infeasible, as the basic variables of the final tableau consists of one or more artificial variables with non-zero value.\nBasic Variables:")
            for i in range(m):
                print("X",int(Xb[i]),"=",(tableau[i+1,n]))
            print(" ")
            phase2 = 0
            return 0,0,0

    else:
        print("\nThe given LP is feasible. Starting Phase II now.\n")

    if phase2 == 1:
        i = 0
        for i in range(m):
            tableau = np.delete(tableau, n-i-1, 1)
            i+=1

        m,n = np.shape(tableau)
        m = m-1
        n = n-1
        A = np.zeros((m,n))
        Cb = find_Cb(C,Xb,A)
        zero_col = np.array([[0]])
        temp = np.append(np.transpose(C), zero_col, 1)
        tableau[0,0:n+1] = np.subtract((np.transpose(Cb) @ tableau[1:m+1,:]), temp)
        print("Updated Tableau:\n")
        print(tabulate(np.round(tableau,10), tablefmt="github", headers=header_names(tableau), numalign="right"),"\n\nBasic Variables:",Xb)
        print(" ")
        print("\n End of Phase I. \n Phase II:\n")
        return tableau, Xb, 1

def result_phase2(unbdd,optimal,tableau,Xb,z):
    m,n = np.shape(tableau)
    m = m-1
    n = n-1
    if optimal == 1:
        print(" ")
        print("ITERATIONS STOPPED\n")
        print("The current BFS is optimal:\n")
        if z != 0:
            print("Objective Function =",(tableau[0,n]*(-1)))
        else:
            print("Objective Function =",(tableau[0,n]*(1)))
        j=0
        for j in range(m):
            print("X",int(Xb[j]),"=",(tableau[j+1,n]))
        print(" ")
        print("All other variables are non-basic and are equal to 0.")
        print(" ")
        print(" ")

    if unbdd == 1:
        print("THE LP IS UNBOUNDED ALONG THE DIRECTION:")
        dir = np.zeros((n,1))
        x_unbdd = np.zeros((n,1))
        i = 0
        for i in range(m):
            x_unbdd[int(Xb[i]-1),0] = tableau[i+1,n]
            dir[int(Xb[i]-1),0] = -1*tableau[i+1,pivot_col]
        dir[pivot_col,0] = 1
        i = 0
        print(" ")
        for i in range(n):
            print('x',i+1,' = ',x_unbdd[i,0],"+",dir[i,0],'T')
        print(" ")

tableau,Xb,C, z = initiate()
tableau,unbdd,optimal,pivot_col, Xb = simplex_iterations(tableau,Xb)
tableau, Xb, next_phase = result_phase1(unbdd, optimal, tableau, Xb,C)
if next_phase == 1:
    tableau,unbdd,optimal,pivot_col, Xb = simplex_iterations(tableau,Xb)
    result_phase2(unbdd, optimal, tableau, Xb, z)


import os
import cv2

import torch

class ShopeeDataset(torch.utils.data.Dataset):
    '''
    Define Shopee Dataset
    '''
    def __init__(self, df, transform=None):
        self.df = df
        self.root_dir = 'train_images'
        self.transform = transform

    def __len__(self):
        return len(self.df)

    def __getitem__(self, idx):

        row = self.df.iloc[idx]
        # define image path
        image_path = os.path.join(self.root_dir, row.image)
        # read input image and transform
        transformed_image = cv2.imread(image_path)
        transformed_image = cv2.cvtColor(transformed_image, cv2.COLOR_BGR2RGB)
        label = row.label_group

        augmented_image = self.transform(image=transformed_image)
        transformed_image = augmented_image['image']

        return {
            'image': transformed_image,
            'label': torch.tensor(label).long()
        }


from django.conf import settings
from django.conf.urls import include, url
from django.contrib import admin
from django.contrib.auth.views import logout as django_logout
from django.http import HttpResponse
from django.views.generic.base import RedirectView

handler404 = 'myapp.views.my_custom_page_not_found_view'
handler500 = 'myapp.views.my_custom_error_view'

urlpatterns = [
    url(r'^{}/'.format(settings.ADMIN_URL), admin.site.urls),
    url(r'^health$', lambda request:HttpResponse(status=200)),

    url(r'^logout/$', django_logout,
         {'next_page': '/'},
         name='myproject_logout'),

    url(r'openid/', include('djangooidc.urls')),

    url(r'^myapp/', include('myapp.urls', namespace='myapp')),

    url(r'^$',
        RedirectView.as_view(pattern_name='myapp:public', permanent=False),
       name='home'),
]

if settings.DEBUG:
    import debug_toolbar
    urlpatterns += [
        url(r'^__debug__/', include(debug_toolbar.urls)),
    ]

# vim: ai et ts=4 sw=4 sts=4


import time

file = open('bank_input.txt', 'r')
file.readline()
tg = (file.readline())
mytable = tg.maketrans(",", ".")
target = float(tg.translate(mytable))
file.readline()
terms = [float(line.strip().translate(mytable)) for line in file]
file.close()

class SetWithSum:
    def __init__(self, terms):
        self._items = list(terms)
        self._sum = sum(terms)

    def add(self, num):
        self._items.append(num)
        self._sum += num
        return self

    def clone(self):
        return SetWithSum(self.items())

    def items(self):
        return self._items

    def sum(self):
        return self._sum

    def __repr__(self):
        return f"<{self._sum},{self._items}>"

def find_sum(terms, target, eps):
    terms = list(sorted(terms))
    result = [SetWithSum([terms[0]])]
    delta = eps * target / len(terms)
    for digit in terms[1:]:
        twin = result
        twin.extend([i.clone().add(digit) for i in result])
        twin = sorted(twin, key=SetWithSum.sum)
        term = twin[0]
        result = [term]
        for num in twin:
            if (term.sum() + delta) < num.sum() and num.sum() <= target:
                term = num
                result.append(term)
    return max(result, key=SetWithSum.sum)

start = time.time()
print(find_sum(terms, target, eps=0))
print(round((time.time() - start) // 60), 'minutes', round((time.time() - start) % 60), 'seconds')


# -*- coding: utf-8 -*-
from odoo import http
from odoo.http import content_disposition, request

import binascii

from odoo import fields, http, SUPERUSER_ID, _
from odoo.exceptions import AccessError, MissingError, ValidationError
from odoo.fields import Command
from odoo.http import request

from odoo.addons.payment.controllers import portal as payment_portal
from odoo.addons.payment import utils as payment_utils
from odoo.addons.portal.controllers.mail import _message_post_helper
from odoo.addons.portal.controllers import portal
from odoo.addons.portal.controllers.portal import pager as portal_pager

class CustomerPortal(portal.CustomerPortal):

    @http.route(['/my/orders/<int:order_id>/<int:picking_id>'], type='http', auth="public", website=True)
    def portal_order_page(self, order_id,picking_id, report_type=None, access_token=None, message=False, download=False, **kw):
        try:
            order_sudo = self._document_check_access('sale.order', order_id, access_token=access_token)
        except (AccessError, MissingError):
            return request.redirect('/my')

        if report_type in ('html', 'pdf', 'text'):
            return self._show_report(model=order_sudo, report_type=report_type,
                                     report_ref='sale.action_report_saleorder', download=download)

        if request.env.user.share and access_token:
            # If a public/portal user accesses the order with the access token
            # Log a note on the chatter.
            today = fields.Date.today().isoformat()
            session_obj_date = request.session.get('view_quote_%s' % order_sudo.id)
            if session_obj_date != today:
                # store the date as a string in the session to allow serialization
                request.session['view_quote_%s' % order_sudo.id] = today
                # The "Quotation viewed by customer" log note is an information
                # dedicated to the salesman and shouldn't be translated in the customer/website lgg
                context = {'lang': order_sudo.user_id.partner_id.lang or order_sudo.company_id.partner_id.lang}
                msg = _('Quotation viewed by customer %s', order_sudo.partner_id.name)
                del context
                _message_post_helper(
                    "sale.order",
                    order_sudo.id,
                    message=msg,
                    token=order_sudo.access_token,
                    message_type="notification",
                    subtype_xmlid="mail.mt_note",
                    partner_ids=order_sudo.user_id.sudo().partner_id.ids,
                )

        backend_url = f'/web#model={order_sudo._name}' \
                      f'&id={order_sudo.id}' \
                      f'&action={order_sudo._get_portal_return_action().id}' \
                      f'&view_type=form'
        values = {
            'sale_order': order_sudo,
            'message': message,
            'report_type': 'html',
            'backend_url': backend_url,
            'picking_id': picking_id,
            'res_company': order_sudo.company_id,  # Used to display correct company logo
        }

        # Payment values
        if order_sudo._has_to_be_paid():
            logged_in = not request.env.user._is_public()

            providers_sudo = request.env['payment.provider'].sudo()._get_compatible_providers(
                order_sudo.company_id.id,
                order_sudo.partner_id.id,
                order_sudo.amount_total,
                currency_id=order_sudo.currency_id.id,
                sale_order_id=order_sudo.id,
            )  # In sudo mode to read the fields of providers and partner (if not logged in)
            tokens = request.env['payment.token'].search([
                ('provider_id', 'in', providers_sudo.ids),
                ('partner_id', '=', order_sudo.partner_id.id)
            ]) if logged_in else request.env['payment.token']

            # Make sure that the partner's company matches the order's company.
            if not payment_portal.PaymentPortal._can_partner_pay_in_company(
                    order_sudo.partner_id, order_sudo.company_id
            ):
                providers_sudo = request.env['payment.provider'].sudo()
                tokens = request.env['payment.token']

            fees_by_provider = {
                provider: provider._compute_fees(
                    order_sudo.amount_total,
                    order_sudo.currency_id,
                    order_sudo.partner_id.country_id,
                ) for provider in providers_sudo.filtered('fees_active')
            }
            values.update({
                'providers': providers_sudo,
                'tokens': tokens,
                'fees_by_provider': fees_by_provider,
                'show_tokenize_input': payment_portal.PaymentPortal._compute_show_tokenize_input_mapping(
                    providers_sudo, logged_in=logged_in, sale_order_id=order_sudo.id
                ),
                'amount': order_sudo.amount_total,
                'currency': order_sudo.pricelist_id.currency_id,
                'partner_id': order_sudo.partner_id.id,
                'access_token': order_sudo.access_token,
                'transaction_route': order_sudo.get_portal_url(suffix='/transaction'),
                'landing_route': order_sudo.get_portal_url(),
                'picking_id': picking_id,
            })

        if order_sudo.state in ('draft', 'sent', 'cancel'):
            history_session_key = 'my_quotations_history'
        else:
            history_session_key = 'my_orders_history'

        values = self._get_page_view_values(
            order_sudo, access_token, values, history_session_key, False)

        return request.render('sale.sale_order_portal_template', values)

class ProjectsImport(http.Controller):

    @http.route('/mail/delivery/date', type='http', methods=['POST'], auth="public", website=True, csrf=False)
    def update_sale_delivery(self, **kw):
        delivery_id = kw['delivery_id']
        delivery_date = kw['delivery_date']
        stock_picking = request.env['stock.picking'].sudo().search([('id', '=', delivery_id)])
        order_id = stock_picking.sale_id.id
        stock_pickings_related = request.env['stock.picking'].sudo().search(
            [('sale_id', '=', order_id), ('partner_id', '=', stock_picking.partner_id.id)])
        sale_order = request.env['sale.order'].sudo().search([('id', '=', order_id)])
        if stock_pickings_related:
            for picking in stock_pickings_related:
                picking.update(
                    {'expected_delivery_date': delivery_date}
                )
                picking.delivery_date_confirmed_first = True
                picking.submit_date_count = +1
                for rec in picking.move_ids:
                    rec.update(
                        {'expected_delivery_date': delivery_date}
                    )
                    for sale_line in sale_order.order_line:
                        if sale_line.product_id.id == rec.product_id.id:
                            sale_line.update(
                                {'expected_delivery_date': delivery_date}
                            )
            template_id = request.env.ref('projects_import.delivery_date_confirm_mail_to_admin_template_first')
            request.env['mail.template'].browse(template_id.id).with_context(email_to=picking.user_id.email).send_mail(
                picking.id, force_send=True)
        # return request.redirect('/my/orders/%s/%s' % (order_id, delivery_id))
    @http.route('/mail/delivery/date/second-confirm', type='http', methods=['POST'], auth="public", website=True, csrf=False)
    def update_sale_delivery_second(self, **kw):
        delivery_id = kw['delivery_id']
        delivery_date = kw['delivery_date']
        stock_picking = request.env['stock.picking'].sudo().search([('id', '=', delivery_id)])
        order_id = stock_picking.sale_id.id
        stock_pickings_related = request.env['stock.picking'].sudo().search(
            [('sale_id', '=', order_id), ('partner_id', '=', stock_picking.partner_id.id)])
        sale_order = request.env['sale.order'].sudo().search([('id', '=', order_id)])
        if stock_pickings_related:
            for picking in stock_pickings_related:
                if delivery_date != str(picking.expected_delivery_date):
                    picking.update(
                        {'expected_delivery_date': delivery_date}
                    )
                    picking.confirm_date_count = +1
                    for rec in picking.move_ids:
                        rec.update(
                            {'expected_delivery_date': delivery_date}
                        )
                        for sale_line in sale_order.order_line:
                            if sale_line.product_id.id == rec.product_id.id:
                                sale_line.update(
                                    {'expected_delivery_date': delivery_date}
                                )
                else:
                    picking.delivery_date_confirmed_second = True
                    picking.confirm_date_count = +1
        # return request.redirect('/my/orders/%s/%s' % (order_id, delivery_id))

    @http.route('/my/delivery/<int:order_id>/<int:picking_id>/confirm_date', type='http', auth='user')
    def set_value(self, order_id,picking_id, **kwargs):
        current_picking = request.env['stock.picking'].sudo().search([('id', '=', picking_id)])
        stock_picking = request.env['stock.picking'].sudo().search([('sale_id', '=', order_id),('partner_id', '=', current_picking.partner_id.id)])
        if stock_picking:
            for rec in stock_picking:
                if rec.delivery_date_confirmed_first is True:
                    rec.delivery_date_confirmed_second = True
                else:
                    rec.delivery_date_confirmed_first = True
                # return request.redirect('/my/form/view/%d' % order_id)


import requests
from bs4 import BeautifulSoup

def scrape_cyberpuerta():
    url = "https://www.cyberpuerta.mx/Computo-Hardware/Componentes/Tarjetas-de-Video/"
    response = requests.get(url)
    if response.status_code != 200:
        raise Exception("No se pudo acceder a la página.")

    soup = BeautifulSoup(response.text, 'html.parser')
    products = soup.find_all('a', class_='emproduct_right_title')

    data = []
    for product in products:
        name = product.text.strip()
        price = product.find_next('span', class_='price').text.strip()
        data.append((name, price))

    return data

if __name__ == "__main__":
    scraped_data = scrape_cyberpuerta()

    # Imprime la información en la terminal
    for name, price in scraped_data:
        print(f"Nombre: {name}")
        print(f"Precio: {price}")
        print("=" * 30)


# from ctypes.wintypes import WORD
# from tracemalloc import stop
import sys
import os
import spacy
import numpy as np
from numpy.linalg import norm
import math
import pandas as pd
import collections
from spacy.tokenizer import Tokenizer
from spacy import displacy
from spacy import tokens
from spacy.tokens import DocBin
import random
import re
nlp = spacy.load("en_core_web_sm")
from spacy.lang.en.stop_words import STOP_WORDS
from time import time
import nltk
from sklearn.datasets import load_files
# nltk.download('stopwords')
import pickle
# from nltk.corpus import stopwords
from sklearn.model_selection import train_test_split
from scipy.stats import chi2_contingency

def get_sentens(doc, sent_number):
	d = nlp(doc)
	index=1
	for s in d.sents:
		if index == int(sent_number) + 1:
			return s
		else:
			index += 1

def bow_cosine(d1,sent_list):
	bow_list=[]
	list_one=[]
	list_two=[]
	vector_s1=[]
	vector_s2=[]
	# s1=nlp(d1)
	# for i in s1.sents:
	for tok in d1:
		if tok.lemma_.lower() not in list_one:
			list_one.append(tok.lemma_.lower())
	# print(list_one)
	for j in sent_list:
		# m=nlp(j)
		# for k in m.sents:
		for n in j:
			if n.lemma_.lower() not in list_two:
				list_two.append(n.lemma_.lower())
	# print(list_two)
	for l in list_one:
		if l not in bow_list:
			bow_list.append(l)
	# print(bow_list)
	for o in list_two:
		if o not in bow_list:
			bow_list.append(o)
	# print(bow_list)
	#create vector
	for word in bow_list:
		if word in list_one:
			vector_s1.append(1)
		else:
			vector_s1.append(0)
	for wd in bow_list:
		if wd in list_two:
			vector_s2.append(1)
		else:
			vector_s2.append(0)
	# print(vector_s1)
	# print(vector_s2)
	#nominator
	cosine_numinator=0
	for m in range(0,len(vector_s1)):
		cosine_numinator+=vector_s1[m]*vector_s2[m]
	# print(cosine_numinator)
	#denominator
	power1_r1=0
	r1_denom=0
	for p in range(0,len(vector_s1)):
		power1_r1+=vector_s1[p]**2
		r1_denom=math.sqrt(power1_r1)
	# print(r1_denom)
	power2_r2=0
	r2_denom=0
	for q in range(0,len(vector_s2)):
		power2_r2+=vector_s2[q]**2
		r2_denom=math.sqrt(power2_r2)
	# print(r2_denom)
	cosine_denominator=r1_denom*r2_denom
	# print(cosine_denominator)
	#cosine_fraction
	if cosine_denominator != 0:
		cosine_fraction= cosine_numinator/float(cosine_denominator)
	else:
		cosine_fraction=0
	# print(cosine_fraction)
	return cosine_fraction

def jaccard_similarity(list1, list2):
	s1 = set(list1)
	s2 = set(list2)
	if len(s1.union(s2)):
		return float(len(s1.intersection(s2)) / len(s1.union(s2)))
	else:
		return 0

def okapi_bm25(s1,s2,k1=1.2,b=0.75):
	# calculate average document length
	avgdl = (len(s1) + len(s2)) / 2
	# calculate IDF for each term
	idfs = {}
	for term in set(s1 + s2):
		df = sum(1 for doc in [s1, s2] if term in doc)
		idf = math.log((len([s1, s2]) - df + 0.5) / (df + 0.5))
		idfs[term] = abs(idf)
	# calculate score for each sentence
	scores = []
	for i, terms in enumerate([s1, s2]):
		score = 0
		for term in terms:
			tf = terms.count(term)
			score += idfs[term] * (tf * (k1 + 1)) / (tf + k1 * (1 - b + b * (len(terms) / avgdl)))
		scores.append(score)
	return(scores[1])

def cosine_similarity(s1, s2, d1, d2):
	tf_s1 = {}
	tf_s2 = {}
	for w in s1:
		if w in tf_s1:
			tf_s1[w] += 1
		else:
			tf_s1[w] = 1
	for w in s2:
	    if w in tf_s2:
	        tf_s2[w] += 1
	    else:
		    tf_s2[w] = 1
	tf_idf_s1 = {}
	tf_idf_s2 = {}
	for w in tf_s2:
		tf_idf_s2[w] = tf_s2[w]/float(d2[w])
	for w in tf_s1:
		tf_idf_s1[w] = tf_s1[w]/float(d1[w])
	zigma = 0
	for i in tf_s1:
		if i in tf_s2:
			zigma += tf_idf_s1[i]*tf_idf_s2[i]
	r1 = 0
	r2 = 0
	for w in tf_s1:
		r1 += (tf_s1[w]/float(d1[w])) ** 2
	for w in tf_s2:
		r2 += (tf_s2[w]/float(d2[w])) ** 2
	if r1 != 0 and r2 !=0:
		cosine_sim = zigma/float(math.sqrt(r1) * math.sqrt(r2))
	else:
		cosine_sim = 0
	return cosine_sim
def identitysimilarity(s1, s2):
	tfs1={}
	tfs2={}
	for i in s1:
		if i in tfs1:
			tfs1[i]+=1
		else:
			tfs1[i]=1
	for i in s2:
		if i in tfs2:
			tfs2[i]+=1
		else:
			tfs2[i]=1
	l_s1=len(s1)
	l_s2=len(s2)
	absolute_value=abs(l_s1-l_s2)
	idf={}
	for k in tfs1:
		if k in tfs2:
			idf[k]=tfs1[k]+tfs2[k]
		else:
			idf[k]=tfs1[k]
	for k in tfs2:
		if k not in idf:
			idf[k]=tfs2[k]
	zigma=0
	for i in tfs1:
		if i in tfs2:
			zigma+=idf[i]+absolute_value
	if zigma==0:
		fraction_1=0
	else:
		fraction_1=1/float(zigma)
	sec_fraction=0
	for i in tfs1:
		if i in tfs2:
			sec_fraction+=idf[i]/float(1+abs(tfs1[i]-tfs2[i]))
	prod_ident=fraction_1*sec_fraction
	return prod_ident

def similarity(doc1, doc2, topics):
	doc_bin = DocBin(attrs=["LEMMA", "ENT_IOB", "ENT_TYPE"], store_user_data=True)
	d1 = nlp(doc1)
	d2 = nlp(doc2)
	idf_d1 = {}
	idf_d2 = {}
	norm_list=[]
	okapi_score = []
	cosine_score = []
	jaccard_score = []
	identity_score=[]
	topic_score = []
	word_str=""
	for tok in d1:
		if tok.is_stop == False and tok.text.isalpha() == True :
			t = tok.lemma_.lower()
			word_str+=t
			if t in idf_d1:
				idf_d1 [t] += 1
			else:
				idf_d1 [t] = 1
	for tok in d2:
		if tok.is_stop == False and tok.text.isalpha() == True :
			t = tok.lemma_.lower()
			if t in idf_d2:
				idf_d2 [t] += 1
			else:
				idf_d2 [t] = 1
	# print(idf_d1)
	jacard_time = 0.0
	identity_time = 0.0
	for sentence1 in d1.sents:
		score_list1 = []
		score_list2 = []
		score_list3 = []
		score_list4 = []
		score_list5 = []
		s1 = [token.lemma_.lower() for token in sentence1 if token.is_stop == False and token.text.isalpha() == True]
		for sentence2 in d2.sents:
			s2 = [token.lemma_.lower() for token in sentence2 if token.is_stop == False and token.text.isalpha() == True]
			score_list1.append(jaccard_similarity(s1, s2))
			score_list2.append(okapi_bm25(s1,s2,k1=1.2,b=0.75))
			score_list3.append(identitysimilarity(s1, s2))
			score_list4.append(topic_signature_similarity(topics, s1, s2, idf_d1, idf_d2))
			score_list5.append(cosine_similarity(s1, s2, idf_d1, idf_d2))
		jaccard_score.append(score_list1)
		sumu=sum(score_list2)
		l_t=[]
		for sc in score_list2:
			if sumu==0:
				l_t.append(0)
			else:
				frac=sc/sumu
				l_t.append(frac)
		okapi_score.append(l_t)
		identity_score.append(score_list3)
		topic_score.append(score_list4)
		cosine_score.append(score_list5)
		# print(okapi_score)
	return jaccard_score ,okapi_score, identity_score, topic_score , cosine_score

def hits (harmunic_dict):
	neighbors = {}
	hits = {}
	for k, d in harmunic_dict.items():
		doc1 = k[0:int(k.find("_"))]
		doc2 = k[int(k.find("_"))+1:len(k)+1]
		for index,data in enumerate(d):
			vertex = doc1 + '_S' + str(index)
			neighbor_list = []
			if vertex not in hits:
				hits[vertex] = 1
			else:
				neighbor_list = neighbors[vertex]
			for ind , data2 in enumerate(data):
				tmp = {}
				if data2 != 0 :
					tmp[doc2 + '_S' + str(ind)] = data2
					neighbor_list.append(tmp)
			neighbors[vertex] = neighbor_list
	replit = 10
	epsilon = 0.0000008
	new_hits = {}
	for r in range(replit):
		# print('hits repets : %d' % r , end='\r')
		convergence = 0
		for vi , hits_vi in hits.items():
			sum_vi = 0
			for n_vi in neighbors[vi]:
				vj = list(n_vi.keys())[0]
				dj = list(n_vi.values())[0]
				sum_vi += dj * hits[vj]
			new_hits[vi] = sum_vi
		#normalize and convergence
		norm = sum (new_hits.values())
		for vi , hits_vi in new_hits.items():
			new_hits[vi] = hits_vi / norm
			convergence += ( new_hits[vi] - hits[vi] ) **2
		if convergence <= epsilon:
			break
		else:
			hits = new_hits.copy()
	# print()
	return new_hits

def pageRank (harmunic_dict):
	page_rank = {}
	neighbors = {}
	#initialaze PageRank and find neighbors
	for k, d in harmunic_dict.items():
		doc1 = k[0:int(k.find("_"))]
		doc2 = k[int(k.find("_"))+1:len(k)+1]
		for index,data in enumerate(d):
			vertex = doc1 + '_S' + str(index)
			neighbor_list = []
			if vertex not in page_rank:
				page_rank[vertex] = random.uniform(0,0.5)
			else:
				neighbor_list = neighbors[vertex]
			for ind , data2 in enumerate(data):
				tmp = {}
				if data2 != 0 :
					tmp[doc2 + '_S' + str(ind)] = data2
					neighbor_list.append(tmp)
			neighbors[vertex] = neighbor_list
	#calculate Page Rank

	n = len(neighbors.keys())
	# print(n)
	d = 0.85
	epsilon = 0.0000008
	replit = 10
	new_page_rank = {}
	for r in range(replit):
		# print('Page rank repets : %d' % r , end='\r')
		convergence = 0
		for vi , pr_vi in page_rank.items():
			# print("Vi", vi, pr_vi)
			sum_vi = 0
			for n_vi in neighbors[vi]:
				# print("n_vi", n_vi)
				if bool(n_vi):
					vj = list(n_vi.keys())[0]
					dj = list(n_vi.values())[0]
					sim_vj_vz = 0.0
					for n_vj in neighbors[vj]:
						# print("n_vj", n_vj)
						if bool(n_vj):
							vz = list(n_vj.keys())[0]
							dz = list(n_vj.values())[0]
							sim_vj_vz += dz
							# print(vi,vj,dj,vz,dz, sim_vj_vz)
					sum_vi += (dj / sim_vj_vz) * page_rank[vj]
					# print(sum_vi)
			# print("*******************************")
			new_page_rank[vi] = (1 - d) / n + d * sum_vi
		norm = sum(new_page_rank.values())
		for vi , PR_vi in new_page_rank.items():
			new_page_rank[vi] = PR_vi / norm
			convergence += (page_rank[vi] - new_page_rank[vi]) **2
		if convergence <= epsilon:
			break
		else:
			page_rank = new_page_rank.copy()
	# print()
	return page_rank

basePath = os.getcwd()
path = sys.argv[1]
# nonRePath = os.path.join(basePath, sys.argv[2])
nonRePath = sys.argv[2]
os.chdir(path)
path = os.getcwd()
doc_list = []

topics = topic_signature(path, nonRePath)

os.chdir(path)
for file in os.listdir():
	if os.path.isfile(file):
		doc_list.append(file)
x=0
sumup=0
summ_doc={}
summ_dict={}
harmunic_dict={}
doc_list_size = len(doc_list)
for file1 in doc_list:
	f1 = open(f"{path}/{file1}")
	fr1 = f1.read()
	for file2 in doc_list:
		f2 = open(f"{path}/{file2}")
		fr2 = f2.read()
		l1, l2, l3, l4 ,l5 = similarity(fr1,fr2, topics)
		# print("similarity time : {}".format(time() - ts2))
		list_array=[]
		list_h=[]
		for i in range(0 , len(l1)):
			harmunic_list=[]
			a=0
			b=0
			c=0
			d=0
			f=0
			h=0
			for j in range(0, len(l1[i])):
				if (l1[i][j]==0):
					a=0
				else:
					a=1/l1[i][j]
				if (l2[i][j]==0):
					b=0
				else:
					b=1/l2[i][j]
				if (l3[i][j]==0):
					c=0
				else:
					c=1/l3[i][j]
				if (l4[i][j]==0):
					d=0
				else:
					d=1/l4[i][j]
				if (l5[i][j]==0):
					f=0
				else:
					f=1/l5[i][j]
				if (a+b+c+d+f==0):
					h=0
				else:
					h=5/(a+b+c+d+f)
				harmunic_list.append(h)
			list_h.append(harmunic_list)
		name= file1+"_"+file2
		harmunic_dict[name]=list_h
Harmonic_between_2_algo={}
PR_final_list=pageRank(harmunic_dict)
new_HITS_normalize=hits(harmunic_dict)
for i, j in PR_final_list.items():
	l = new_HITS_normalize[i]
	if j == 0 :
		n = 0.0 + (1/float(l))
	elif l == 0 :
		n=(1/float(j)) + 0.0
	else :
		n=(1/float(j))+(1/float(l))
	Harmonic_between_2_algo[i]=2/n

n_sentns = 15
harmonic_sorted = sorted(Harmonic_between_2_algo.items(), key=lambda x: x[1], reverse=True)
# print(harmonic_sorted)
list_summary=[]
for i in range(0, n_sentns):
	k,d = harmonic_sorted[i]
	doc_name = k[0:int(k.find("_"))]
	sent_numb = k[int(k.find("_"))+2:len(k)]
	f1 = open(f"{path}/{doc_name}").read()
	# print (doc_name , sent_numb , d)
	s=get_sentens(f1,sent_numb)
	# print("sentence:",s)
	if (len(list_summary)==0):
		list_summary.append(s)
		# print("list:",list_summary)
	elif (bow_cosine(s,list_summary) < 0.7):
		list_summary.append(s)
print(list_summary)


microbit_selected = "NONE"
player_selected = "NONE"
player_select = randint(0,2)
win=1
drawed = False
error = images.create_image("""
	0 0 1 1 1
	0 0 1 0 0
	0 0 1 1 1
	0 0 1 0 0
	0 0 1 0 0
""")
rock = images.create_image("""
	0 0 1 0 0
	0 1 1 1 0
	1 1 1 1 1
	1 1 1 1 0
	0 1 1 0 0
""")
paper = images.create_image("""
	1 1 1 1 1
	1 1 1 1 1
	1 1 1 1 1
	1 1 1 1 1
	1 1 1 1 1
""")
scissors = images.create_image("""
	1 0 0 0 1
	0 1 0 1 0
	0 1 1 1 0
	1 0 1 0 1
	0 1 0 1 0
""")
Xcon = images.create_image("""
	1 0 0 0 1
	0 1 0 1 0
	0 0 1 0 0
	0 1 0 1 0
	1 0 0 0 1
""")
wincon = images.create_image("""
	0 1 1 1 0
	0 1 1 1 1
	0 1 1 1 1
	0 1 0 0 0
	0 1 0 0 0
""")
lose = images.create_image("""
	0 1 1 1 0
	1 0 1 0 1
	1 1 0 1 1
	0 1 1 1 0
	0 1 0 1 0
""")
draw = images.create_image("""
	0 0 0 0 0
	1 1 1 1 1
	0 0 0 0 0
	1 1 1 1 1
	0 0 0 0 0
""")

def restart():
	global microbit_selected, player_selected, player_select, win, drawed
	microbit_selected = "NONE"
	player_selected = "NONE"
	player_select = randint(0,2)
	win=1
	drawed = False

input.on_gesture(Gesture.SHAKE, restart)

def on_button_pressed_a():
	global player_select
	if player_selected == "NONE":
		player_select -= 1
		if player_select <= -1:
			player_select = 2
input.on_button_pressed(Button.A, on_button_pressed_a)

def on_button_pressed_b():
	global player_select
	if player_selected == "NONE":
		player_select += 1
		if player_select >= 3:
			player_select = 0
input.on_button_pressed(Button.B, on_button_pressed_b)

def select(rps: number):
	if rps == 0:
		rock.show_image(0)
		returnning = "rock"
	elif rps == 1:
		paper.show_image(0)
		returnning = "paper"
	elif rps == 2:
		scissors.show_image(0)
		returnning = "scissors"
	else:
		error.show_image(0)
		returnning = "ERR"
	return returnning

def microbit():
	global microbit_selected
	microbit_selected = select(randint(0, 2))

def on_button_pressed_ab():
	global player_selected, player_select
	if player_selected == "NONE":
		player_selected = select(player_select)
input.on_button_pressed(Button.AB, on_button_pressed_ab)

def fight(first_player: str, second_player: str):
	global win, drawed

	if not first_player in " rock paper scissors " or not second_player in " rock paper scissors ":
		error.show_image(0)
		win = -120

	#win
	if (first_player == "paper" and second_player == "rock") or (first_player == "rock" and second_player == "scissors") or (first_player == "scissors" and second_player == "paper"):win= 0
	#lose
	if (second_player == "paper" and first_player == "rock") or (second_player == "rock" and first_player == "scissors") or (second_player == "scissors" and first_player == "paper"):win=-1
	#draw
	if first_player == second_player: drawed = True

def on_forever():
	global microbit_selected, player_selected, player_select, win
	for _ in range(1):
		if player_selected == "NONE":
			select(player_select)
			continue
		elif win==1:
			Xcon.show_image(0)
			basic.pause(50)
			microbit()
			fight(player_selected, microbit_selected)
			basic.pause(50)
		elif drawed:
			draw.show_image(0)
			restart()
		elif win==0:
			wincon.show_image(0)
		elif win==-1:
			lose.show_image(0)
		else:
			error.show_image(0)
			print("ERROR: player_selected or microbit_selected is not rock, paper or scissors!")
	pass

basic.forever(on_forever)


import win32com.client as win32
import time

def combine_documents(output_path, *input_paths):
    word_app = win32.gencache.EnsureDispatch('Word.Application')
    word_app.Visible = False

    # Create a new Word document to combine the input documents
    new_doc = word_app.Documents.Add()

    for input_path in input_paths:
        if input_path.lower().endswith('.doc') or input_path.lower().endswith('.docx'):
            input_doc = word_app.Documents.Open(input_path)
            input_doc.Content.Copy()
            new_doc.Content.Paste()
            input_doc.Close()

            # Introduce a delay to prevent the com_error
            time.sleep(1)

    new_doc.SaveAs(output_path)
    new_doc.Close()

    word_app.Quit()
# Example usage
input_files = ["E:\Project\Job\GQ\Python\Baidu_downlaod_upload\Baidu_Pyqt5_Threading\document_merger\CCTV.doc",
               "E:\Project\Job\GQ\Python\Baidu_downlaod_upload\Baidu_Pyqt5_Threading\document_merger\老师协议.docx"]
output_file = "E:\Project\Job\GQ\Python\Baidu_downlaod_upload\Baidu_Pyqt5_Threading\document_merger\combined_output.docx"

combine_documents(output_file, *input_files)


"""Module for handling automatic unbanishments."""
import asyncio
import datetime
from logging import Logger

from discord import Guild

from mrfreeze.bot import MrFreeze
from mrfreeze.cogs.coginfo import CogInfo
from mrfreeze.lib import default
from mrfreeze.lib.banish import mute_db
from mrfreeze.lib.colors import CYAN
from mrfreeze.lib.colors import CYAN_B
from mrfreeze.lib.colors import MAGENTA
from mrfreeze.lib.colors import RED
from mrfreeze.lib.colors import RESET
from mrfreeze.lib.colors import YELLOW

async def unbanish_loop(server: Guild, coginfo: CogInfo) -> None:
    """Check for people to unbanish every self.banish_interval seconds."""
    if coginfo.bot and coginfo.logger and coginfo.default_mute_interval:
        bot: MrFreeze = coginfo.bot
        logger: Logger = coginfo.logger
        default_mute_interval: int = coginfo.default_mute_interval
    else:
        raise Exception("Failed to create unbanish loop, insufficient cog info.")

    while not bot.is_closed():
        # Wait the time specified by the server (or the default time) before running
        interval = bot.settings.get_mute_interval(server) or default_mute_interval
        logger.debug(f"Running unbanish loop for {server.name} in {interval}.")
        await asyncio.sleep(interval)
        logger.debug(f"Running unbanish loop for {server.name}.")

        # Fetch mute role/channel, which might fail.
        try:
            mute_role = await bot.get_mute_role(server)
            mute_channel = await bot.get_mute_channel(server, silent=True)
        except Exception:
            logger.warning(f"{server.name} Unbanish loop failed to fetch mute role or channel.")
            continue
        unmuted = list()

        # Create a list of mutes which are due for unmuting
        current_time = datetime.datetime.now()
        mutes = mute_db.mdb_fetch(bot, server)
        timed_mutes = [ i for i in mutes if i.until is not None ]
        due_mutes = [ i for i in timed_mutes if i.until < current_time ]
        logger.debug(f"{server.name} mutes: {len(mutes)}/{len(timed_mutes)}/{len(due_mutes)}")

        for mute in due_mutes:
            logger.debug(f"{mute} is due for unbanish!")

            # Refresh member to make sure we have their latest roles.
            try:
                member = await server.fetch_member(mute.member.id)
                logger.debug(f"Refreshed {member}, they have {len(member.roles)} roles.")
            except Exception as e:
                logger.error(f"Failed to refresh muted member: {e}")
                continue  # Will try again next unbanish loop

            # Calculate how late we were in unbanishing
            diff = bot.parse_timedelta(current_time - mute.until)
            if diff == "":
                diff = "now"
            else:
                diff = f"{diff} ago"

            # Remove from database
            mute_db.mdb_del(bot, member, logger)

            if mute_role in member.roles:
                logger.debug(f"{member} has the mute role! Removing it.")
                try:
                    await member.remove_roles(mute_role)
                    logger.debug(f"{member} should no longer have the mute role.")
                    # Members are only considered unmuted if they had the antarctica role
                    unmuted.append(member)

                    log = f"Auto-unmuted {CYAN_B}{member.name}#"
                    log += f"{member.discriminator} @ {server.name}."
                    log += f"{YELLOW} (due {diff}){RESET}"
                    logger.info(log)

                except Exception as e:
                    log = f"Failed to remove mute role of {YELLOW}"
                    log += f"{member.name}#{member.discriminator}"
                    log += f"{CYAN_B} @ {MAGENTA} {server.name}:"
                    log += f"\n{RED}==> {RESET}{e}"
                    logger.error(log)
            else:
                log = f"User {YELLOW}{member.name}#{member.discriminator}"
                log += f"{CYAN_B} @ {MAGENTA} {server.name}{CYAN} "
                log += f"due for unmute but does not have a mute role!{RESET}"
                logger.warning(log)

        # Time for some great regrets
        if len(unmuted) > 0:
            unmuted_str = default.mentions_list(unmuted)

            if len(unmuted_str) == 1:
                msg = "It's with great regret that I must inform you all that "
                msg += f"{unmuted_str}'s exile has come to an end."
            else:
                msg = "It's with great regret that I must inform you all that the exile of "
                msg += f"{unmuted_str} has come to an end."

            await mute_channel.send(msg)


# Sprite class

import pygame as pg

# Custom files
from settings import *

# Function assignments
vec = pg.math.Vector2

class Player(pg.sprite.Sprite):
	def __init__(self):
		pg.sprite.Sprite.__init__(self)
		self.image = pg.Surface((30, 40))
		self.image.fill(BLUE)
		self.rect = self.image.get_rect()
		self.rect.center = (WIDTH/2, HEIGHT/2)

		self.pos = vec(WIDTH/2,HEIGHT/2)
		self.vel = vec(0,0)
		self.acc = vec(0,0)

	def update(self):
		# Initialize acceleration
		self.acc = vec(0,0)

		keys = pg.key.get_pressed()
		if keys[pg.K_LEFT]:
			self.acc.x = -PLAYER_ACC
		if keys[pg.K_RIGHT]:
			self.acc.x = PLAYER_ACC
		if keys[pg.K_UP]:
			self.acc.y = -PLAYER_ACC
		if keys[pg.K_DOWN]:
			self.acc.y = PLAYER_ACC

		self.acc.x += self.vel.x * PLAYER_FRICTION # Friction for x
		self.acc.y += self.vel.y * PLAYER_FRICTION # Friction for y
		self.vel += self.acc # Acceleration adds to velocity
		self.pos += self.vel + 0.5 * self.acc

		self.rect.center = self.pos

		# Collision with wall - Wrap around
		#if self.pos.x > WIDTH:
		#	self.pos.x = 0
		#if self.pos.x < 0:
		#	self.pos.x = WIDTH
		#if self.pos.y > HEIGHT:
		#	self.pos.y = 0
		#if self.pos.y < 0:
		#	self.pos.y = HEIGHT

		# Collision with wall - Stop
		if self.pos.x > WIDTH:
			self.pos.x = WIDTH
		if self.pos.x < 0:
			self.pos.x = 0
		if self.pos.y > HEIGHT:
			self.pos.y = HEIGHT
		if self.pos.y < 0:
			self.pos.y = 0

class Platform(pg.sprite.Sprite):
	def __init__(self, x, y, w, h):
		pg.sprite.Sprite.__init__(self)
		self.image = pg.Surface((w,h))
		self.image.fill(GREEN)
		self.rect = self.image.get_rect()
		self.rect.x = x
		self.rect.y = y


import requests
import os
import re
from datetime import timezone, timedelta
import datetime
import time
import mojimoji
import pandas as pd

# To set your environment variables in your terminal run the following line:
# export 'BEARER_TOKEN'='<your_bearer_token>'
bearer_token = os.environ.get('BEARER_TOKEN')

search_url = 'https://api.twitter.com/2/tweets/search/all'

def create_query(nextToken):

    # Zeitangabe in JST
    jst_st = datetime.datetime(2021, 4, 1, 0, 0, 0, 0, datetime.timezone(timedelta(hours=+9)))
    jst_et = datetime.datetime(2021, 5, 1, 0, 0, 0, 0, datetime.timezone(timedelta(hours=+9)))
    # Zeitangabe nach UTC umschreiben
    utc_st = jst_st.astimezone(timezone.utc)
    utc_st = utc_st.isoformat()
    utc_et = jst_et.astimezone(timezone.utc)
    utc_et =utc_et.isoformat()

    if not nextToken:
        # Optionale params: start_time,end_time,since_id,until_id,max_results,next_token,
        # expansions,tweet.fields,media.fields,poll.fields,place.fields,user.fields
        query_params = {'query': '(オリンピック lang:ja -is:retweet) OR (五輪 lang:ja -is:retweet)',
                    'tweet.fields': 'created_at,id,text,public_metrics',
                    'start_time': utc_st,
                    'end_time': utc_et,
                    'max_results': 500}
    else:
        query_params = {'query': '(オリンピック lang:ja -is:retweet) OR (五輪 lang:ja -is:retweet)',
                    'tweet.fields': 'created_at,id,text,public_metrics',
                    'start_time': utc_st,
                    'end_time': utc_et,
                    'max_results': 500,
                    'next_token': nextToken}

    return query_params

def create_headers(bearer_token):
    headers = {'Authorization': 'Bearer {}'.format(bearer_token)}
    return headers

def connect_to_endpoint(url, headers, params):

    # für 3 sec warten wegen rate limit "App rate limit: 1 request per second"
    time.sleep(3)

    response = requests.request('GET', url, headers=headers, params=params)
    # print(response.status_code)
    if response.status_code != 200:
        raise Exception(response.status_code, response.text)
    return response.json()

def throw_q(nextToken):
    headers = create_headers(bearer_token)
    query_params = create_query(nextToken)
    json_response = connect_to_endpoint(search_url, headers, query_params)

    if json_response['meta'].get('next_token') is None:
        nextToken = False
    else:
        nextToken = json_response['meta']['next_token']

    tw_daten = json_response['data']
    tw_list = []
    for i in tw_daten:
        # id als Str
        ident = str(i['id'])
        # user-id, url, hash-tag, Zeilenumbruch und Spatien aus dem Tweets entfernen
        tw_text = re.sub(r'@\w+','', i['text'])
        tw_text = re.sub(r'https://t\.co/[0-9a-zA-Z]+','', tw_text)
        tw_text = re.sub(r'(http|https)://[0-9a-zA-Z\./]+','', tw_text)
        tw_text = re.sub(r'#.+?(\s|$)', '', tw_text)
        tw_text = re.sub(r'\n','', tw_text)
        # tw_text = re.sub(r'\s','', tw_text)
        # Kana soll immer in Fullwidth-Zeichen dargestellt werden
        tw_text = mojimoji.han_to_zen(tw_text, kana=True, digit=False, ascii=False)
        # Digit und Ascii sollen immer in Halfwidth-Zeichen dargestellt werden
        tw_text = mojimoji.zen_to_han(tw_text, kana=False, digit=True, ascii=True)

        # Wenn die Text-Länge kurzer als 3 Zeichen ist, soll das Tweet ignoriert werden
        if len(tw_text) < 3:
            continue

        # Zahl von retweet und like
        retw = i['public_metrics']['retweet_count']
        like_count = i['public_metrics']['like_count']

        tw_list.append([ident, i['created_at'], tw_text, retw, like_count])

    return nextToken, tw_list

if __name__ == "__main__":
    start_time = time.time()
    nextToken = ''
    tweets = []
    nt, l = throw_q(nextToken)
    nextToken = nt
    tweets += l

    itr_num = 1
    while nextToken:
        t1 = time.time()
        if itr_num == 1:
            t0 = t1

        # Wenn das ganze Verfahren länger als 2 Stunde dauert, soll das aktuelle nextToken gespeichert werden. while-loop wird auch unterbrochen
        ft = t1 - start_time
        if ft >= 7200:
            dt_now = datetime.datetime.now()
            dt_now = dt_now.isoformat()
            s = 'Verfahren unterbrochen: ' + dt_now + ' Das aktuelle nextToken: ' + nextToken
            with open('./nextToken.txt', mode='w') as f:
                f.write(s)
            break

        # Query werfen und tweets & nextToken erhalten
        nt, l = throw_q(nextToken)
        nextToken = nt
        tweets += l
        itr_num += 1

        # wegen rate limit Pause einlegen "App rate limit: 300 requests per 15-minute window"
        if itr_num == 299:
            t2 = time.time()
            t = 1200 - (t2 - t0)
            if t > 0:
                print('sleep ' + str(t) + ' sec. wegen rate limit')
                time.sleep(t)
            itr_num = 1

    tweetsDf = pd.DataFrame(tweets, columns=['id', 'time', 'text', 'retweets', 'likes'])
    tweetsDf.to_csv('tweetsdata.csv', encoding='utf_8')


import random
import numpy as np
import math
import torch.utils.data as data
import utils.utils_image as util
import torch
from data.degradations import circular_lowpass_kernel, random_mixed_kernels

class DatasetDegradation(data.Dataset):
    '''
    # -----------------------------------------
    # Get L/H for SISR.
    # If only "paths_H" is provided, sythesize bicubicly downsampled L on-the-fly.
    # -----------------------------------------
    # e.g., train denoiser with L and H
    # -----------------------------------------
    '''

    def __init__(self, opt):
        super(DatasetDegradation, self).__init__()
        print('Get L/H for image-to-image mapping. Both "paths_L" and "paths_H" are needed.')
        self.opt = opt
        self.n_channels = opt['n_channels'] if opt['n_channels'] else 3
        self.patch_size = self.opt['H_size'] if self.opt['H_size'] else 512

        # ------------------------------------
        # get the path of H
        # ------------------------------------
        self.paths_H = util.get_image_paths(opt['dataroot_H'])
        self.paths_L = None

        assert self.paths_H, 'Error: H path is empty.'

        # blur settings for the first degradation
        self.blur_kernel_size = opt['blur_kernel_size'] # 21
        self.kernel_list = opt['kernel_list']   # ['iso', 'aniso', 'generalized_iso', 'generalized_aniso', 'plateau_iso', 'plateau_aniso' ]
        self.kernel_prob = opt['kernel_prob']   # [ 0.45, 0.25, 0.12, 0.03, 0.12, 0.03 ]
        self.blur_sigma = opt['blur_sigma']     # 0.1
        self.betag_range = opt['betag_range']   # [ 0.2, 3 ]
        self.betap_range = opt['betap_range']   # [ 0.5, 4 ]
        self.sinc_prob = opt['sinc_prob']       # [ 1, 2 ]

        # blur settings for the second degradation
        self.blur_kernel_size2 = opt['blur_kernel_size2']
        self.kernel_list2 = opt['kernel_list2']
        self.kernel_prob2 = opt['kernel_prob2']
        self.blur_sigma2 = opt['blur_sigma2']
        self.betag_range2 = opt['betag_range2']
        self.betap_range2 = opt['betap_range2']
        self.sinc_prob2 = opt['sinc_prob2']

        # a final sinc filter
        self.final_sinc_prob = opt['final_sinc_prob'] # 0.8

        self.kernel_range = [2 * v + 1 for v in range(3, 11)]  # kernel size ranges from 7 to 21
        self.pulse_tensor = torch.zeros(21, 21).float()  # convolving with pulse tensor brings no blurry effect
        self.pulse_tensor[10, 10] = 1

    def __getitem__(self, index):

        # ------------------------------------
        # get H image
        # ------------------------------------
        H_path = self.paths_H[index]
        img_H = util.imread_uint(H_path, self.n_channels)

        H, W, _ = img_H.shape

        # --------------------------------
        # randomly crop the patch
        # --------------------------------
        rnd_h = random.randint(0, max(0, H - self.patch_size))
        rnd_w = random.randint(0, max(0, W - self.patch_size))
        patch_H = img_H[rnd_h:rnd_h + self.patch_size, rnd_w:rnd_w + self.patch_size, :]

        # --------------------------------
        # pad
        # --------------------------------
        if H < self.patch_size or W < self.patch_size:
            patch_H = util.img_pad(patch_H, self.patch_size)

        # --------------------------------
        # augmentation - flip and/or rotate
        # --------------------------------
        mode = random.randint(0, 7)
        patch_H =  util.augment_img(patch_H, mode=mode)

        # ------------------------ Generate kernels (used in the first degradation) ------------------------ #
        kernel_size = random.choice(self.kernel_range)
        if np.random.uniform() < self.opt['sinc_prob']:
            # this sinc filter setting is for kernels ranging from [7, 21]
            if kernel_size < 13:
                omega_c = np.random.uniform(np.pi / 3, np.pi)
            else:
                omega_c = np.random.uniform(np.pi / 5, np.pi)
            kernel = circular_lowpass_kernel(omega_c, kernel_size, pad_to=False)
        else:
            kernel = random_mixed_kernels(
                self.kernel_list,
                self.kernel_prob,
                kernel_size,
                self.blur_sigma,
                self.blur_sigma, [-math.pi, math.pi],
                self.betag_range,
                self.betap_range,
                noise_range=None)
        # pad kernel
        pad_size = (21 - kernel_size) // 2
        kernel = np.pad(kernel, ((pad_size, pad_size), (pad_size, pad_size)))

        # ------------------------ Generate kernels (used in the second degradation) ------------------------ #
        kernel_size = random.choice(self.kernel_range)
        if np.random.uniform() < self.opt['sinc_prob2']:
            if kernel_size < 13:
                omega_c = np.random.uniform(np.pi / 3, np.pi)
            else:
                omega_c = np.random.uniform(np.pi / 5, np.pi)
            kernel2 = circular_lowpass_kernel(omega_c, kernel_size, pad_to=False)
        else:
            kernel2 = random_mixed_kernels(
                self.kernel_list2,
                self.kernel_prob2,
                kernel_size,
                self.blur_sigma2,
                self.blur_sigma2, [-math.pi, math.pi],
                self.betag_range2,
                self.betap_range2,
                noise_range=None)

        # pad kernel
        pad_size = (21 - kernel_size) // 2
        kernel2 = np.pad(kernel2, ((pad_size, pad_size), (pad_size, pad_size)))

        # ------------------------------------- sinc kernel ------------------------------------- #
        if np.random.uniform() < self.opt['final_sinc_prob']:
            kernel_size = random.choice(self.kernel_range)
            omega_c = np.random.uniform(np.pi / 3, np.pi)
            sinc_kernel = circular_lowpass_kernel(omega_c, kernel_size, pad_to=21)
            sinc_kernel = torch.FloatTensor(sinc_kernel)
        else:
            sinc_kernel = self.pulse_tensor

        # --------------------------------
        # HWC to CHW, numpy(uint) to tensor
        # --------------------------------
        img_H = util.uint2tensor3(patch_H)
        kernel = torch.FloatTensor(kernel)
        kernel2 = torch.FloatTensor(kernel2)

        return {'H': img_H, 'H_path': H_path, 'kernel1': kernel, 'kernel2':kernel2, 'sinc_kernel':sinc_kernel}

    def __len__(self):
        return len(self.paths_H)


import math
import pandas as pd
from pandas import ExcelFile
from collections import namedtuple
import pprint
import json
pp = pprint.PrettyPrinter(indent=4)
df = pd.read_excel(
    'Section IV - Piping Materials - Revison to EDB.xlsx', sheet_name="Pipe-Tube Data")

Entry = namedtuple(
    'Entry', 'type material nominal_size nominal_od schedule id epsilon')

r = 0
entries = []
for row in df.itertuples():
    # Piping:
      # material (F)
      # nominal size (G)
      # nominal outside diameter (H)
      # schedule (N)
      # inside diameter
      # (AB) epsilon
    # Tubing

    if r > 1 and not math.isnan(float(row[28])) and not math.isnan(float(row[23])) and str(row[14]) != "nan":
        entries.append(Entry('Piping', row[6], row[7], row[8],
                             row[14], row[23], row[28]))
    # elif r > 1 and not math.isnan(float(row[28])) and not math.isnan(float(row[23])):
    #    entries.append(Entry('Tubing', row[6], row[7], row[8],
    #                         None, row[23], row[28]))

    r = r + 1

# print(entries)
materials = dict()
for entry in entries:
    if entry.material in materials:
        materials[entry.material]['entries'].append(entry)
    else:
        materials[entry.material] = {"entries": [entry]}

# print(materials)

for material in materials:
    m = materials[material]
    m['nominal_sizes'] = dict()
    for entry in m['entries']:
        if entry.nominal_size in m['nominal_sizes']:
            m['nominal_sizes'][entry.nominal_size]['entries'].append(entry)
        else:
            m['nominal_sizes'][entry.nominal_size] = {"entries": [entry]}
    del m['entries']
for material in materials:
    m = materials[material]
    print(material, len(m['nominal_sizes']))
    for size in m['nominal_sizes']:
        s = m['nominal_sizes'][size]
        s['schedules'] = dict()
        for entry in s['entries']:
            s['schedules'][entry.schedule] = entry

        del s['entries']

with open('../../generate/static/friction-loss-materials.json', 'w') as fp:
    json.dump(materials, fp)


from fredapi import Fred
from api_etl.etl import ETL

class Fredapi(ETL):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.indices = ["PAYEMS", "FEDFUNDS", "UNRATE", "PPIACO", "CPIAUCSL",
                        "PCE", "INDPRO", "UMCSENT", "RSAFS", "HOUST", "CSUSHPINSA"],

    def fetch_macro_data(self):
        fred = Fred(api_key=self.api_keys["Fred"])
        dfs = []

        # Mapping of series IDs to their actual names
        names = {
            "PAYEMS": "NFP", # Non-Farm Payrolls
            "CPIAUCSL": "CPI", # Consumer Price Index
            "FEDFUNDS": "InterestRate", # Effective Federal Funds Rate
            "UNRATE": "UnemploymentRate",
            "PPIACO": "PPI", # Producer Price Index
            "PCE": "PCE", # Personal Consumption Expenditures
            "INDPRO": "IPI", # Industrial Production Index
            "UMCSENT": "ConsumerSentiment",
            "RSAFS": "RetailSales",
            "HOUST": "HousingStarts",
            "CSUSHPINSA": "HPI", # S&P/Case-Shiller U.S. National Home Price Index
        }

        for index in self.indices[0]: # Note: self.indices is a tuple with a single list
            series = fred.get_series(index, self.start_day, self.end_day)
            series = series.resample("D").ffill().reset_index()
            series.columns = ["date", index]
            dfs.append(series)

        # Merge all dataframes on 'date'
        macro_df = dfs[0]
        for df in dfs[1:]:
            macro_df = macro_df.merge(df, on='date', how='outer')

        # Rename the columns
        macro_df.rename(columns=names, inplace=True)

        macro_df = macro_df.round(4)
        macro_df.to_csv('../data/macro.csv', index=False)
        print('macro.csv created')
        return macro_df


import datetime
import gzip
import io
import json
import logging
import zipfile
from typing import IO, Any, Iterable, List, Mapping, MutableMapping, Optional

import pendulum
import requests
from airbyte_cdk.models import SyncMode
from airbyte_cdk.sources.streams.http import HttpStream

LOGGER = logging.getLogger("airbyte")

HTTP_ERROR_CODES = {
    400: {
        "msg": "The file size of the exported data is too large. Shorten the time ranges and try again. The limit size is 4GB.",
        "lvl": "ERROR",
    },
    404: {
        "msg": "No data collected",
        "lvl": "WARN",
    },
    504: {
        "msg": "The amount of data is large causing a timeout. For large amounts of data, the Amazon S3 destination is recommended.",
        "lvl": "ERROR",
    },
}

def error_msg_from_status(status: int = None):
    if status:
        level = HTTP_ERROR_CODES[status]["lvl"]
        message = HTTP_ERROR_CODES[status]["msg"]
        if level == "ERROR":
            LOGGER.error(message)
        elif level == "WARN":
            LOGGER.warning(message)
        else:
            LOGGER.error(f"Unknown error occured: code {status}")

class Events(HttpStream):
    api_version = 2
    base_params = {}
    cursor_field = "server_upload_time"
    date_template = "%Y%m%dT%H"
    compare_date_template = "%Y-%m-%d %H:%M:%S.%f"
    primary_key = "uuid"
    state_checkpoint_interval = 1000

    def __init__(self, data_region: str, start_date: str, event_time_interval: dict = None, **kwargs):
        if event_time_interval is None:
            event_time_interval = {"size_unit": "hours", "size": 24}
        self.data_region = data_region
        self.event_time_interval = event_time_interval
        self._start_date = pendulum.parse(start_date) if isinstance(start_date, str) else start_date
        self.date_time_fields = self._get_date_time_items_from_schema()
        super().__init__(**kwargs)

    @property
    def url_base(self) -> str:
        subdomain = "analytics.eu." if self.data_region == "EU Residency Server" else ""
        return f"https://{subdomain}amplitude.com/api/"

    @property
    def time_interval(self) -> dict:
        return {self.event_time_interval.get("size_unit"): self.event_time_interval.get("size")}

    def get_updated_state(self, current_stream_state: MutableMapping[str, Any], latest_record: Mapping[str, Any]) -> Mapping[str, Any]:
        # save state value in source native format
        if self.compare_date_template:
            latest_state = pendulum.parse(latest_record[self.cursor_field]).strftime(self.compare_date_template)
        else:
            latest_state = latest_record.get(self.cursor_field, "")
        return {self.cursor_field: max(latest_state, current_stream_state.get(self.cursor_field, ""))}

    def _get_date_time_items_from_schema(self):
        """
        Get all properties from schema with format: 'date-time'
        """
        result = []
        schema = self.get_json_schema()
        for key, value in schema["properties"].items():
            if value.get("format") == "date-time":
                result.append(key)
        return result

    def _date_time_to_rfc3339(self, record: MutableMapping[str, Any]) -> MutableMapping[str, Any]:
        """
        Transform 'date-time' items to RFC3339 format
        """
        for item in record:
            if item in self.date_time_fields and record[item]:
                record[item] = pendulum.parse(record[item]).to_rfc3339_string()
        return record

    def get_most_recent_cursor(self, stream_state: Mapping[str, Any] = None) -> datetime.datetime:
        """
        Use `start_time` instead of `cursor` in the case of more recent.
        This can happen whenever a user simply finds that they are syncing to much data and would like to change `start_time` to be more recent.
        See: https://github.com/airbytehq/airbyte/issues/25367 for more details
        """
        cursor_date = (
            pendulum.parse(stream_state[self.cursor_field])
            if stream_state and self.cursor_field in stream_state
            else datetime.datetime.min.replace(tzinfo=datetime.timezone.utc)
        )
        return max(self._start_date, cursor_date)

    def parse_response(self, response: requests.Response, stream_state: Mapping[str, Any] = None, **kwargs) -> Iterable[Mapping]:
        most_recent_cursor = self.get_most_recent_cursor(stream_state).strftime(self.compare_date_template)
        try:
            zip_file = zipfile.ZipFile(io.BytesIO(response.content))
        except zipfile.BadZipFile as e:
            self.logger.exception(e)
            self.logger.error(
                f"Received an invalid zip file in response to URL: {response.request.url}."
                f"The size of the response body is: {len(response.content)}"
            )
            return []

        for gzip_filename in zip_file.namelist():
            with zip_file.open(gzip_filename) as file:
                for record in self._parse_zip_file(file):
                    if record[self.cursor_field] >= most_recent_cursor:
                        yield self._date_time_to_rfc3339(record)  # transform all `date-time` to RFC3339

    def _parse_zip_file(self, zip_file: IO[bytes]) -> Iterable[MutableMapping]:
        with gzip.open(zip_file) as file:
            for record in file:
                yield json.loads(record)

    def stream_slices(self, stream_state: Mapping[str, Any] = None, **kwargs) -> Iterable[Optional[Mapping[str, Any]]]:
        slices = []
        start = self.get_most_recent_cursor(stream_state=stream_state)
        end = pendulum.now()
        if start > end:
            self.logger.info("The data cannot be requested in the future. Skipping stream.")
            return []

        while start <= end:
            slices.append(
                {
                    "start": start.strftime(self.date_template),
                    "end": start.add(**self.time_interval).subtract(hours=1).strftime(self.date_template),
                }
            )
            start = start.add(**self.time_interval)

        return slices

    def read_records(
        self,
        sync_mode: SyncMode,
        cursor_field: List[str] = None,
        stream_slice: Mapping[str, Any] = None,
        stream_state: Mapping[str, Any] = None,
    ) -> Iterable[Mapping[str, Any]]:
        stream_state = stream_state or {}
        start = pendulum.parse(stream_slice["start"])
        end = pendulum.parse(stream_slice["end"])
        if start > end:
            yield from []
        # sometimes the API throws a 404 error for not obvious reasons, we have to handle it and log it.
        # for example, if there is no data from the specified time period, a 404 exception is thrown
        # https://developers.amplitude.com/docs/export-api#status-codes
        try:
            self.logger.info(f"Fetching {self.name} time range: {start.strftime('%Y-%m-%dT%H')} - {end.strftime('%Y-%m-%dT%H')}")
            records = super().read_records(sync_mode, cursor_field, stream_slice, stream_state)
            yield from records
        except requests.exceptions.HTTPError as error:
            status = error.response.status_code
            if status in HTTP_ERROR_CODES.keys():
                error_msg_from_status(status)
                yield from []
            else:
                self.logger.error(f"Error during syncing {self.name} stream - {error}")
                raise

    def request_params(self, stream_slice: Mapping[str, Any], **kwargs) -> MutableMapping[str, Any]:
        params = self.base_params
        params["start"] = pendulum.parse(stream_slice["start"]).strftime(self.date_template)
        params["end"] = pendulum.parse(stream_slice["end"]).strftime(self.date_template)
        return params

    def next_page_token(self, response: requests.Response) -> Optional[Mapping[str, Any]]:
        return None

    def path(self, **kwargs) -> str:
        return f"{self.api_version}/export"