import torch
import torch.nn as nn
import torch.nn.functional as F
from torch.nn.modules.batchnorm import _BatchNorm
import numpy as np
import math
import torch.utils.model_zoo as model_zoo
import time

from util import som
from . import operations
from .layers import *

import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

import index_max

class Transformer(nn.Module):
    def __init__(self, opt):
        super(Transformer, self).__init__()
        self.opt = opt

        self.first_pointnet = PointNet(3, (32, 64, 128), activation=self.opt.activation, normalization=self.opt.normalization,
                                       momentum=opt.bn_momentum, bn_momentum_decay_step=opt.bn_momentum_decay_step, bn_momentum_decay=opt.bn_momentum_decay)

        self.second_pointnet = PointNet(128+128, (256, 256), activation=self.opt.activation, normalization=self.opt.normalization,
                                        momentum=opt.bn_momentum, bn_momentum_decay_step=opt.bn_momentum_decay_step, bn_momentum_decay=opt.bn_momentum_decay)

        # regressor to get a sin(theta)
        self.fc1 = MyLinear(256, 128, activation=self.opt.activation, normalization=self.opt.normalization,
                            momentum=opt.bn_momentum, bn_momentum_decay_step=opt.bn_momentum_decay_step,
                            bn_momentum_decay=opt.bn_momentum_decay)
        self.fc2 = MyLinear(128, 64, activation=self.opt.activation, normalization=self.opt.normalization,
                            momentum=opt.bn_momentum, bn_momentum_decay_step=opt.bn_momentum_decay_step,
                            bn_momentum_decay=opt.bn_momentum_decay)
        self.fc3 = MyLinear(64, 1, activation=None, normalization=None)

        self.dropout1 = nn.Dropout(p=self.opt.dropout)
        self.dropout2 = nn.Dropout(p=self.opt.dropout)

    def forward(self, x, sn=None, epoch=None):
        '''

        :param x: BxMx3 som nodes / Bx3xN points
        :param sn: Bx3xN surface normal
        :return:
        '''

        first_pn_out = self.first_pointnet(x, epoch)  # BxCxN
        feature_1, _ = torch.max(first_pn_out, dim=2, keepdim=False)  # BxC

        second_pn_out = self.second_pointnet(torch.cat((first_pn_out, feature_1.unsqueeze(2).expand_as(first_pn_out)), dim=1), epoch)
        feature_2, _ = torch.max(second_pn_out, dim=2, keepdim=False)

        # get sin(theta)
        fc1_out = self.fc1(feature_2, epoch)
        if self.opt.dropout > 0.1:
            fc1_out = self.dropout1(fc1_out)
        self.fc2_out = self.fc2(fc1_out, epoch)
        if self.opt.dropout > 0.1:
            self.fc2_out = self.dropout2(self.fc2_out)

        sin_theta = torch.tanh(self.fc3(self.fc2_out, epoch))  # Bx1

        return sin_theta

class Encoder(nn.Module):
    def __init__(self, opt):
        super(Encoder, self).__init__()
        self.opt = opt
        self.feature_num = opt.feature_num

        # transformer
        self.transformer = Transformer(opt)

        # first PointNet
        if self.opt.surface_normal == True:
            self.first_pointnet = PointResNet(6, [64, 128, 256, 384], activation=self.opt.activation, normalization=self.opt.normalization,
                                              momentum=opt.bn_momentum, bn_momentum_decay_step=opt.bn_momentum_decay_step, bn_momentum_decay=opt.bn_momentum_decay)
        else:
            self.first_pointnet = PointResNet(3, [64, 128, 256, 384], activation=self.opt.activation, normalization=self.opt.normalization,
                                              momentum=opt.bn_momentum, bn_momentum_decay_step=opt.bn_momentum_decay_step, bn_momentum_decay=opt.bn_momentum_decay)

        if self.opt.som_k >= 2:
            # second PointNet
            self.knnlayer = KNNModule(3+384, (512, 512), activation=self.opt.activation, normalization=self.opt.normalization,
                                      momentum=opt.bn_momentum, bn_momentum_decay_step=opt.bn_momentum_decay_step, bn_momentum_decay=opt.bn_momentum_decay)

            # final PointNet
            self.final_pointnet = PointNet(3+512, (768, self.feature_num), activation=self.opt.activation, normalization=self.opt.normalization,
                                           momentum=opt.bn_momentum, bn_momentum_decay_step=opt.bn_momentum_decay_step, bn_momentum_decay=opt.bn_momentum_decay)
        else:
            # final PointNet
            self.final_pointnet = PointResNet(3+384, (512, 512, 768, self.feature_num), activation=self.opt.activation, normalization=self.opt.normalization,
                                              momentum=opt.bn_momentum, bn_momentum_decay_step=opt.bn_momentum_decay_step, bn_momentum_decay=opt.bn_momentum_decay)

        # build som for clustering, node initalization is done in __init__
        rows = int(math.sqrt(self.opt.node_num))
        cols = rows
        self.som_builder = som.BatchSOM(rows, cols, 3, self.opt.gpu_id, self.opt.batch_size)

        # padding
        self.zero_pad = torch.nn.ZeroPad2d(padding=1)

    def forward(self, x, sn, node, node_knn_I, is_train=False, epoch=None):
        '''

        :param x: Bx3xN Tensor
        :param sn: Bx3xN Tensor
        :param node: Bx3xM FloatTensor
        :param node_knn_I: BxMxk_som LongTensor
        :param is_train: determine whether to add noise in KNNModule
        :return:
        '''

        # optimize the som, access the Tensor's tensor, the optimize function should not modify the tensor
        # self.som_builder.optimize(x.data)
        self.som_builder.node.resize_(node.size()).copy_(node)

        # modify the x according to the nodes, minus the center
        self.mask, mask_row_max, min_idx = self.som_builder.query_topk(x.data, k=self.opt.k)  # BxkNxnode_num, Bxnode_num
        mask_row_sum = torch.sum(self.mask, dim=1)  # Bxnode_num
        mask = self.mask.unsqueeze(1)  # Bx1xkNxnode_num

        # if necessary, stack the x
        x_list, sn_list = [], []
        for i in range(self.opt.k):
            x_list.append(x)
            sn_list.append(sn)
        x_stack = torch.cat(tuple(x_list), dim=2)
        sn_stack = torch.cat(tuple(sn_list), dim=2)

        # re-compute center, instead of using som.node
        x_stack_data_unsqueeze = x_stack.data.unsqueeze(3)  # BxCxkNx1
        x_stack_data_masked = x_stack_data_unsqueeze * mask.float()  # BxCxkNxnode_num
        cluster_mean = torch.sum(x_stack_data_masked, dim=2) / (mask_row_sum.unsqueeze(1).float()+1e-5)  # BxCxnode_num
        self.som_builder.node = cluster_mean
        self.som_node = self.som_builder.node

        # ====== apply transformer to rotate x_stack, sn_stack, som_node ======
        # sin_theta = self.transformer(x=self.som_node, sn=None, epoch=epoch)  # Bx1
        # # sin_theta = self.transformer(x=torch.cat((x_stack, sn_stack), dim=1), sn=None, epoch=epoch)  # Bx1
        # cos_theta = torch.sqrt(1 + 1e-5 - sin_theta*sin_theta)  # Bx1
        # B = x.size()[0]
        # rotation_matrix = torch.Tensor(B, 3, 3).zero_().to(self.opt.device)  # Bx3x3
        # rotation_matrix[:, 0, 0] = cos_theta[:, 0]
        # rotation_matrix[:, 0, 2] = sin_theta[:, 0]
        # rotation_matrix[:, 1, 1] = 1
        # rotation_matrix[:, 2, 0] = -1 * sin_theta[:, 0]
        # rotation_matrix[:, 2, 2] = cos_theta[:, 0]
        # # print(rotation_matrix)

        # x_stack = torch.matmul(rotation_matrix, x_stack)
        # sn_stack = torch.matmul(rotation_matrix, sn_stack)
        # self.som_node = torch.matmul(rotation_matrix, self.som_node)
        # self.som_builder.node = torch.matmul(rotation_matrix.data, self.som_builder.node)
        # ====== apply transformer to rotate x_stack, sn_stack, som_node ======

        # assign each point with a center
        node_expanded = self.som_node.data.unsqueeze(2)  # BxCx1xnode_num, som.node is BxCxnode_num
        self.centers = torch.sum(mask.float() * node_expanded, dim=3).detach()  # BxCxkN

        self.x_decentered = (x_stack - self.centers).detach()  # Bx3xkN
        x_augmented = torch.cat((self.x_decentered, sn_stack), dim=1)  # Bx6xkN

        # go through the first PointNet
        if self.opt.surface_normal == True:
            self.first_pn_out = self.first_pointnet(x_augmented, epoch)
        else:
            self.first_pn_out = self.first_pointnet(self.x_decentered, epoch)

        M = node.size()[2]
        with torch.cuda.device(self.first_pn_out.get_device()):
            gather_index = index_max.forward_cuda(self.first_pn_out.detach(),
                                                  min_idx.int(),
                                                  M).detach().long()
        self.first_pn_out_masked_max = self.first_pn_out.gather(dim=2, index=gather_index * mask_row_max.unsqueeze(1).long())  # BxCxM

        if self.opt.som_k >= 2:
            # second pointnet, knn search on SOM nodes: ----------------------------------
            self.knn_center_1, self.knn_feature_1 = self.knnlayer(self.som_node, self.first_pn_out_masked_max, node_knn_I, self.opt.som_k, self.opt.som_k_type, epoch)

            # final pointnet --------------------------------------------------------------
            self.final_pn_out = self.final_pointnet(torch.cat((self.knn_center_1, self.knn_feature_1), dim=1), epoch)  # Bx1024xM
        else:
            # final pointnet --------------------------------------------------------------
            self.final_pn_out = self.final_pointnet(torch.cat((self.som_node, self.first_pn_out_masked_max), dim=1), epoch)  # Bx1024xM

        self.feature, _ = torch.max(self.final_pn_out, dim=2, keepdim=False)

        return self.feature

class Classifier(nn.Module):
    def __init__(self, opt):
        super(Classifier, self).__init__()
        self.opt = opt
        self.feature_num = opt.feature_num

        # classifier
        self.fc1 = MyLinear(self.feature_num, 512, activation=self.opt.activation, normalization=self.opt.normalization,
                            momentum=opt.bn_momentum, bn_momentum_decay_step=opt.bn_momentum_decay_step, bn_momentum_decay=opt.bn_momentum_decay)
        self.fc2 = MyLinear(512, 256, activation=self.opt.activation, normalization=self.opt.normalization,
                            momentum=opt.bn_momentum, bn_momentum_decay_step=opt.bn_momentum_decay_step, bn_momentum_decay=opt.bn_momentum_decay)
        self.fc3 = MyLinear(256, self.opt.classes, activation=None, normalization=None)

        self.dropout1 = nn.Dropout(p=self.opt.dropout)
        self.dropout2 = nn.Dropout(p=self.opt.dropout)

    def forward(self, feature, epoch=None):
        fc1_out = self.fc1(feature, epoch)
        if self.opt.dropout > 0.1:
            fc1_out = self.dropout1(fc1_out)
        self.fc2_out = self.fc2(fc1_out, epoch)
        if self.opt.dropout > 0.1:
            self.fc2_out = self.dropout2(self.fc2_out)
        score = self.fc3(self.fc2_out, epoch)

        return score

class Segmenter(nn.Module):
    def __init__(self, opt):
        super(Segmenter, self).__init__()
        self.opt = opt
        self.feature_num = opt.feature_num

        # segmenter
        if self.opt.surface_normal == True:
            if self.opt.som_k >= 2:
                in_channels = 3 + 3 + 3 + 3 + 16 + 384 + 384 + 512 + self.feature_num * 2
            else:
                in_channels = 3 + 3 + 3 + 3 + 16 + 384 + 384 + self.feature_num * 2
        else:
            if self.opt.som_k >= 2:
                in_channels = 3 + 3 + 3 + 16 + 384 + 384 + 512 + self.feature_num * 2
            else:
                in_channels = 3 + 3 + 3 + 16 + 384 + 384 + self.feature_num * 2

        self.layer1 = EquivariantLayer(in_channels,
                                       1024,
                                       activation=self.opt.activation,
                                       normalization=self.opt.normalization)
        self.layer2 = EquivariantLayer(1024, 512, activation=self.opt.activation, normalization=self.opt.normalization)
        self.layer3 = EquivariantLayer(512, 256, activation=self.opt.activation, normalization=self.opt.normalization)
        self.drop3 = nn.Dropout(p=self.opt.dropout)
        self.layer4 = EquivariantLayer(256, 128, activation=self.opt.activation, normalization=self.opt.normalization)
        self.drop4 = nn.Dropout(p=self.opt.dropout)
        self.layer5 = EquivariantLayer(128, self.opt.classes, activation=None, normalization=None)

    def forward(self, x_decentered, x, centers, sn, label,
                first_pn_out,
                feature_max_first_pn_out,
                feature_max_knn_feature_1,
                feature_max_final_pn_out,
                feature):
        '''
        :param x_decentered: Bx3xkN
        :param x: Bx3xN
        :param centers: Bx3xkN
        :param sn: Bx3xkN
        :param label: B, tensor
        :param first_pn_out: Bx384xkN
        :param feature_max_first_pn_out: Bx384xM
        :param feature_max_knn_feature_1: Bx512xM
        :param feature_max_final_pn_out: Bx1024xM
        :param feature: Bx1024
        :return:
        '''

        B = x.size()[0]
        N = x.size()[2]
        k = self.opt.k
        kN= round(k*N)

        # if necessary, stack the x
        x_list, sn_list = [], []
        for i in range(self.opt.k):
            x_list.append(x)
            sn_list.append(sn)
        x = torch.cat(tuple(x_list), dim=2)
        sn = torch.cat(tuple(sn_list), dim=2)

        label_onehot = torch.FloatTensor(B, 16).zero_().to(self.opt.device)  # Bx16
        label_onehot.scatter_(1, label.unsqueeze(1), 1)  # Bx16
        label_onehot = label_onehot.unsqueeze(2).expand(B, 16, kN).detach()  # Bx16xkN

        feature_expanded = feature.unsqueeze(2).expand(B, self.feature_num, kN)

        if self.opt.surface_normal == True:
            if self.opt.som_k >= 2:
                layer1_in = torch.cat((x_decentered, x, centers, sn, label_onehot,
                                       first_pn_out,
                                       feature_max_first_pn_out,
                                       feature_max_knn_feature_1,
                                       feature_max_final_pn_out,
                                       feature_expanded), dim=1)
            else:
                layer1_in = torch.cat((x_decentered, x, centers, sn, label_onehot,
                                       first_pn_out,
                                       feature_max_first_pn_out,
                                       feature_max_final_pn_out,
                                       feature_expanded), dim=1)
        else:
            if self.opt.som_k >= 2:
                layer1_in = torch.cat((x_decentered, x, centers, label_onehot,
                                       first_pn_out,
                                       feature_max_first_pn_out,
                                       feature_max_knn_feature_1,
                                       feature_max_final_pn_out,
                                       feature_expanded), dim=1)
            else:
                layer1_in = torch.cat((x_decentered, x, centers, label_onehot,
                                       first_pn_out,
                                       feature_max_first_pn_out,
                                       feature_max_final_pn_out,
                                       feature_expanded), dim=1)
        layer1_out = self.layer1(layer1_in)
        layer2_out = self.layer2(layer1_out)
        layer3_out = self.layer3(layer2_out)

        # split into k * BxN
        splited_list = torch.split(layer3_out, self.opt.input_pc_num, dim=2)  # BxCxkN -> k * BxCxN
        assert (len(splited_list) == k)
        if k==2:
            layer3_avg_out = 0.5 * (splited_list[0] + splited_list[1])  # BxCxN
        elif k==3:
            layer3_avg_out = (1.0/3.0) * (splited_list[0] + splited_list[1] + splited_list[2])  # BxCxN

        layer4_out = self.layer4(layer3_avg_out)
        if self.opt.dropout > 0.1:
            layer4_out = self.drop4(layer4_out)
        layer5_out = self.layer5(layer4_out)  # Bx50xN

        return layer5_out

class DecoderLinear(nn.Module):
    def __init__(self, opt):
        super(DecoderLinear, self).__init__()
        self.opt = opt
        self.feature_num = opt.feature_num
        self.output_point_number = opt.output_fc_pc_num

        self.linear1 = MyLinear(self.feature_num, self.output_point_number*2, activation=self.opt.activation, normalization=self.opt.normalization)
        self.linear2 = MyLinear(self.output_point_number*2, self.output_point_number*3, activation=self.opt.activation, normalization=self.opt.normalization)
        self.linear3 = MyLinear(self.output_point_number*3, self.output_point_number*4, activation=self.opt.activation, normalization=self.opt.normalization)
        self.linear_out = MyLinear(self.output_point_number*4, self.output_point_number*3, activation=None, normalization=None)

        # special initialization for linear_out, to get uniform distribution over the space
        self.linear_out.linear.bias.data.uniform_(-1, 1)

    def forward(self, x):
        # reshape from feature vector NxC, to NxC
        x = self.linear1(x)
        x = self.linear2(x)
        x = self.linear3(x)
        x = self.linear_out(x)

        return x.view(-1, 3, self.output_point_number)

class ConvToPC(nn.Module):
    def __init__(self, in_channels, opt):
        super(ConvToPC, self).__init__()
        self.in_channels = in_channels
        self.opt = opt

        self.conv1 = MyConv2d(self.in_channels, int(self.in_channels), kernel_size=1, stride=1, padding=0, bias=True, activation=opt.activation, normalization=opt.normalization)
        self.conv2 = MyConv2d(int(self.in_channels), 3, kernel_size=1, stride=1, padding=0, bias=True, activation=None, normalization=None)

        # special initialization for conv2, to get uniform distribution over the space
        # self.conv2.conv.bias.data.normal_(0, 0.3)
        self.conv2.conv.bias.data.uniform_(-1, 1)

        # self.conv2.conv.weight.data.normal_(0, 0.01)
        # self.conv2.conv.bias.data.uniform_(-3, 3)

    def forward(self, x):
        x = self.conv1(x)
        return self.conv2(x)

class DecoderConv(nn.Module):
    def __init__(self, opt):
        super(DecoderConv, self).__init__()
        self.opt = opt
        self.feature_num = opt.feature_num
        self.output_point_num = opt.output_conv_pc_num

        # __init__(self, in_channels, out_channels, kernel_size=3, stride=1, padding=0, output_padding=0, bias=True, activation=None, normalization=None)
        # 1x1 -> 2x2
        self.deconv1 = UpConv(self.feature_num, int(self.feature_num), activation=self.opt.activation, normalization=self.opt.normalization)
        # 2x2 -> 4x4
        self.deconv2 = UpConv(int(self.feature_num), int(self.feature_num/2), activation=self.opt.activation, normalization=self.opt.normalization)
        # 4x4 -> 8x8
        self.deconv3 = UpConv(int(self.feature_num/2), int(self.feature_num/4), activation=self.opt.activation, normalization=self.opt.normalization)
        # 8x8 -> 16x16
        self.deconv4 = UpConv(int(self.feature_num/4), int(self.feature_num/8), activation=self.opt.activation, normalization=self.opt.normalization)
        self.conv2pc4 = ConvToPC(int(self.feature_num/8), opt)
        # 16x16 -> 32x32
        self.deconv5 = UpConv(int(self.feature_num/8), int(self.feature_num/8), activation=self.opt.activation, normalization=self.opt.normalization)
        self.conv2pc5 = ConvToPC(int(self.feature_num/8), opt)
        # 32x32 -> 64x64
        self.deconv6 = UpConv(int(self.feature_num/8), int(self.feature_num/8), activation=self.opt.activation, normalization=self.opt.normalization)
        self.conv2pc6 = ConvToPC(int(self.feature_num/8), opt)

    def forward(self, x):
        # reshape from feature vector NxC, to NxCx1x1
        x = x.view(-1, self.feature_num, 1, 1)
        x = self.deconv1(x)
        x = self.deconv2(x)
        x = self.deconv3(x)
        x = self.deconv4(x)
        self.pc4 = self.conv2pc4(x)
        x = self.deconv5(x)
        self.pc5 = self.conv2pc5(x)
        x = self.deconv6(x)
        self.pc6 = self.conv2pc6(x)

        return self.pc6

class Decoder(nn.Module):
    def __init__(self, opt):
        super(Decoder, self).__init__()
        self.opt = opt
        if self.opt.output_fc_pc_num > 0:
            self.fc_decoder = DecoderLinear(opt)
        self.conv_decoder = DecoderConv(opt)

    def forward(self, x):
        if self.opt.output_fc_pc_num > 0:
            self.linear_pc = self.fc_decoder(x)

        if self.opt.output_conv_pc_num > 0:
            self.conv_pc6 = self.conv_decoder(x).view(-1, 3, 4096)
            self.conv_pc4 = self.conv_decoder.pc4.view(-1, 3, 256)
            self.conv_pc5 = self.conv_decoder.pc5.view(-1, 3, 1024)

        if self.opt.output_fc_pc_num == 0:
            if self.opt.output_conv_pc_num == 4096:
                return self.conv_pc6
            elif self.opt.output_conv_pc_num == 1024:
                return self.conv_pc5
        else:
            if self.opt.output_conv_pc_num == 4096:
                return torch.cat([self.linear_pc, self.conv_pc6], 2)
            elif self.opt.output_conv_pc_num == 1024:
                return torch.cat([self.linear_pc, self.conv_pc5], 2)
            else:
                return self.linear_pc


import torch
import os
import model
import cv2
import collections
import speech_recognition as sr
import os
from tqdm import tqdm
from pydub import AudioSegment
from pydub.silence import split_on_silence
import warnings
import argparse
import librosa.display
import librosa.feature
import matplotlib.pyplot as plt
import numpy as np

warnings.filterwarnings("ignore")

PATH = 'pretrained_model/speech_net_aug.pth.tar'
# device = torch.device("cuda")

def silence_based_conversion(path, n, sil_thresh):
    print([path, n])
    song = AudioSegment.from_wav(path)

    chunks = split_on_silence(song,

        min_silence_len = 300,
        silence_thresh = sil_thresh
    )

    try:
        os.system('rm -rf data/audio/' + n)
    except:
        pass

    try:
        os.mkdir('data/audio/'+ n)
    except(FileExistsError):
        pass

    os.chdir('data/audio/' + n)
    i = 0
    for chunk in chunks:

        chunk_silent = AudioSegment.silent(duration = 10)
        audio_chunk = chunk_silent + chunk + chunk_silent
        audio_chunk.export("./chunk_{0}.wav".format(i), bitrate ='192k', format ="wav")
        filename = 'chunk_'+str(i)+'.wav'
        i+=1
    os.chdir('..')

def extract_mfcc(in_path, file, fmax, nMel, n):
    y, sr = librosa.load(in_path + file)
    S = librosa.feature.melspectrogram(y=y, sr=sr, n_mels=nMel, fmax=fmax)

    plt.figure(figsize=(3, 3), dpi=100)
    librosa.display.specshow(librosa.amplitude_to_db(S, ref=np.max), fmax=fmax)

    plt.xticks([])
    plt.yticks([])
    plt.tight_layout()

    try:
        os.system('rm -rf data/images/' + n)
    except:
        pass

    try:
        os.mkdir('data/images/'+ n)
    except(FileExistsError):
        pass
    plt.savefig('data/images/' + n + '/' + file[:-3] + 'png', bbox_inches='tight', pad_inches=-0.1)

    plt.close()
    return

def print_number(folder, model):

    phone_number = {}
    for file in os.listdir(folder):
        img = cv2.imread(folder + '/' + file)
        img = torch.from_numpy(img)
        img = torch.unsqueeze(img, 0)
        # img = img.to(device)
        outputs = model(img)
        _, predicted = torch.max(torch.unsqueeze(outputs.data,0), 1)
        phone_number[int(file.split("_")[1].split(".")[0])] =predicted.item()

    return phone_number

if __name__ == '__main__':

    parser=argparse.ArgumentParser()
    parser.add_argument('-pn','--phone_number',type=str,required=False,default='pn1',help='audio file name')
    parser.add_argument('-st','--sil_thresh',type=int,required=False,default='25',help='silence threshold')

    args=parser.parse_args()
    phone_number=args.phone_number
    sil_thresh=args.sil_thresh

    ## FROM WEB APP
    path_wav = './data/audio/' + phone_number + '.wav'

    silence_based_conversion(path_wav, phone_number, -1*sil_thresh)
    print('Audio split successful...')

    chunks_path = '/home/mohiitaa/ufonia/phone_number_identification_from_speech/data/audio/' + phone_number + '/'
    # import pdb; pdb.set_trace()
    print(os.listdir(chunks_path))
    for wavfile in os.listdir(chunks_path):
        S = extract_mfcc(chunks_path, wavfile, 8000, 256, phone_number)

    print('MFCC extracted...')
    spec_path = '/home/mohiitaa/ufonia/phone_number_identification_from_speech/data/images/' + phone_number
    speech_model = model.SpeechConv()
    # speech_model.to(device)
    speech_model.load_state_dict(torch.load(PATH))
    print_number = print_number(spec_path, speech_model)
    print('Pretrained speech model loaded...')
    print('Loading predictions...')
    od = collections.OrderedDict(sorted(print_number.items()))
    output = []
    output2 = ''
    for k, v in od.items():
        output.append(v)
        output2 += str(v)
    print(output2)


from card_dealer import *
import itertools

def allCombinations() :
    list = []

    for i in range(52) :
        list.append(Card(i))

    return itertools.combinations(list, 5)

def containsSeries(tuple):
    checkSeries = [0]*13

    for c in tuple :
        checkSeries[c.get_rank()] += 1

    seriesLen = 0
    for i in checkSeries :
        if (i > 0) :
            seriesLen += 1
            if (seriesLen >= 3) :
                return True
        else :
            seriesLen = 0

    return False

all = list(allCombinations())

print("5 cards combinations = " + str(len(all)))

count = 0
for t in all :
    if (containsSeries(t)) :
        count += 1

print("5 card combinations containing a series of at least 3 consecutive ranks = " + str(count))

print("percentage -> = " + str(100.*count/len(all)) + " %")


try:
    from typing import Iterable, BinaryIO, Type, ClassVar
    from pathlib import Path
    from fs.base import FS
    from roughrider.storage.meta import FileInfo, Storage, ChecksumAlgorithm

    class PyFSStorage(Storage):

        fs: FS
        checksum_algorithm: ChecksumAlgorithm

        def __init__(self, name: str, fs: FS, algorithm='md5'):
            self.name = name
            self.fs = fs
            try:
                self.checksum_algorithm = ChecksumAlgorithm[algorithm]
            except KeyError:
                raise LookupError(f'Unknown algorithm: `{algorithm}`.')

        def retrieve(self, ticket: str) -> Iterable[bytes]:
            path = self.ticket_to_uri(ticket)
            if not self.fs.exists(str(path)):
                raise FileNotFoundError(path)

            def file_iterator(path: Path, chunk=4096):
                with self.fs.openbin(str(path)) as reader:
                    while True:
                        data = reader.read(chunk)
                        if not data:
                            break
                        yield data

            return file_iterator(path)

        def delete(self, ticket: str) -> Iterable[bytes]:
            path = self.ticket_to_uri(ticket)
            try:
                self.fs.remove(str(path))
                return True
            except FileNotFoundError:
                raise  # we need to propagate.
            return False

        def store(self, data: BinaryIO, **metadata) -> FileInfo:
            ticket = self.generate_ticket()
            path = self.ticket_to_uri(ticket)
            self.fs.makedirs(str(path.parent), recreate=True)
            size = 0
            fhash = self.checksum_algorithm.value()
            with self.fs.openbin(str(path), mode='w+') as target:
                for block in iter(lambda: data.read(4096), b""):
                    size += target.write(block)
                    fhash.update(block)

            return FileInfo(
                namespace=self.name,
                ticket=ticket,
                size=size,
                checksum=(fhash.name, fhash.hexdigest()),
                metadata=metadata
            )
except ImportError:
    pass


from kafka import KafkaConsumer, TopicPartition
from struct import unpack_from
import threading
import logging

logger = logging.getLogger(__name__)

class KafkaOffsetReader():
  def __init__(self, config):
    logger.info("Config: %s", config)
    self.offsets = dict()
    self.commits = dict()
    self.exporter_offsets = dict()
    self.topics = set()
    self.bootstrap_servers = config["bootstrap_servers"]

    consumer_config = {
      'bootstrap_servers': config["bootstrap_servers"],
      'group_id': None,
      'auto_offset_reset': 'earliest',
      'consumer_timeout_ms': 500,
      'security_protocol': 'PLAINTEXT'
    }

    self.consumer = KafkaConsumer(
        '__consumer_offsets',
        **consumer_config
    )

    thread = threading.Thread(target=self.run, args=())
    thread.daemon = True                            # Daemonize thread
    thread.start()                                  # Start the execution

  def run(self):
    while True:
      for message in self.consumer:
        exporter_partition = message.partition
        exporter_offset = message.offset

        self.exporter_offsets = ensure_dict_key(self.exporter_offsets, exporter_partition, exporter_offset)
        self.exporter_offsets[exporter_partition] = exporter_offset

        if message.key and message.value:
          key = parse_key(message.key)
          if key:
            value = parse_value(message.value)
            group = key[1]
            topic = key[2]
            partition = key[3]
            offset = value[1]

            self.topics.add(topic)

            self.offsets = ensure_dict_key(self.offsets, topic, {})
            self.offsets[topic] = ensure_dict_key(self.offsets[topic], group, {})
            self.offsets[topic][group] = ensure_dict_key(self.offsets[topic][group], partition, offset)
            self.offsets[topic][group][partition] = offset

            self.commits = ensure_dict_key(self.commits, topic, {})
            self.commits[topic] = ensure_dict_key(self.commits[topic], partition, {})
            self.commits[topic][partition] = ensure_dict_key(self.commits[topic][partition], group, 0)
            self.commits[topic][partition][group] += 1

  def get_offsets(self):
    return self.offsets

  def get_highwater(self):
    con = KafkaConsumer(bootstrap_servers = self.bootstrap_servers)

    highwaters = dict()
    for topic in list(self.topics):
      ps = [TopicPartition(topic, p) for p in con.partitions_for_topic(topic)]
      highwaters[topic] = con.end_offsets(ps)

    con.close()

    return highwaters

def read_short(bytes):
  num = unpack_from('>h', bytes)[0]
  remaining = bytes[2:]
  return (num, remaining)

def read_int(bytes):
  num = unpack_from('>i', bytes)[0]
  remaining = bytes[4:]
  return (num, remaining)

def read_long_long(bytes):
  num = unpack_from('>q', bytes)[0]
  remaining = bytes[8:]
  return (num, remaining)

def read_string(bytes):
  length, remaining = read_short(bytes)
  string = remaining[:length].decode('utf-8')
  remaining = remaining[length:]
  return (string, remaining)

def parse_key(bytes):
  (version, remaining_key) = read_short(bytes)
  if version == 1 or version == 0:
    (group, remaining_key) = read_string(remaining_key)
    (topic, remaining_key) = read_string(remaining_key)
    (partition, remaining_key) = read_int(remaining_key)
    return (version, group, topic, partition)

def parse_value(bytes):
  (version, remaining_key) = read_short(bytes)
  if version == 0:
    (offset, remaining_key) = read_long_long(remaining_key)
    (metadata, remaining_key) = read_string(remaining_key)
    (timestamp, remaining_key) = read_long_long(remaining_key)
    return (version, offset, metadata, timestamp)
  elif version == 1:
    (offset, remaining_key) = read_long_long(remaining_key)
    (metadata, remaining_key) = read_string(remaining_key)
    (commit_timestamp, remaining_key) = read_long_long(remaining_key)
    (expire_timestamp, remaining_key) = read_long_long(remaining_key)
    return (version, offset, metadata, commit_timestamp, expire_timestamp)
  elif version == 3:
    (offset, remaining_key) = read_long_long(remaining_key)
    (leader_epoch, remaining_key) = read_int(remaining_key)
    (metadata, remaining_key) = read_string(remaining_key)
    (timestamp, remaining_key) = read_long_long(remaining_key)
    return (version, offset, leader_epoch, metadata, timestamp)

def ensure_dict_key(curr_dict, key, new_value):
  if key in curr_dict:
    return curr_dict

  new_dict = curr_dict.copy()
  new_dict[key] = new_value
  return new_dict


import sys
from collections import deque

def input(): return sys.stdin.readline().rstrip()

moves = ((0, 1), (1, 0), (0, -1), (-1, 0))

for _ in range(int(input())):
    commands = deque(input())

    turtle = [0, 0]
    turtle_top, turtle_bottom, turtle_left, turtle_right = 0, 0, 0, 0
    direction = 0 # 0부터 북 동 남 서

    while commands:
        command = commands.popleft()

        # F: 한 눈금 앞으로
        if command == 'F':
            turtle[0] += moves[direction][0]
            turtle[1] += moves[direction][1]
        # B: 한 눈금 뒤로
        elif command == 'B':
            turtle[0] += moves[(direction + 2) % 4][0]
            turtle[1] += moves[(direction + 2) % 4][1]
        # L: 왼쪽으로 90도 회전
        elif command == 'L':
            direction = (direction + 3) % 4
        # R: 오른쪽으로 90도 회전
        elif command == 'R':
            direction = (direction + 1) % 4

        turtle_top = max(turtle_top, turtle[1])
        turtle_bottom = min(turtle_bottom, turtle[1])
        turtle_right = max(turtle_right, turtle[0])
        turtle_left = min(turtle_left, turtle[0])

    print(abs(turtle_right - turtle_left) * abs(turtle_top - turtle_bottom))


mylist=[]

while True:
    mysublist=[]
    mysublist = list(map(int,input('>>').split()))
    if mysublist[0] ==-1:
        break
    else:
        mylist.append(mysublist)

print(mylist)

for sublist in list:
    for value in sublist:
        for i in value:
            for i in range(0, value):
                if value%2 == 1:
                    print(" ■ ", end="1")

for sublist in list:
    for value in sublist:
        for i in value:
            for i in range(0, value):
                if value%2==0:
                    print(" □ ", end="0")


class GameStats:
    """此类用于游戏的统计"""
    def __init__(self, ai_game):
        self.setting = ai_game.setting
        self.reset_stats()
        #游戏开始的标志
        self.game_active=False
        #记录分数
        self.score=0
        #展示最高分
        self.heigh_score=0
        #显示等级
        self.level=1
    def reset_stats(self):
        """"初始化在游戏运行期间可能变化的统计信息"""
        self.ships_left = self.setting.ship_limit
        self.score=0


import streamlit as st
# from PIL import Image
import streamlit.components.v1 as components
from streamlit_chat import message as st_message
from datetime import datetime
import hashlib
import random
import time

st.set_page_config(
    page_title="AlanIA",
    page_icon="👩🏻🦰",
)

if "session_unique_key" not in st.session_state:
    st.session_state.session_unique_key = f"{hashlib.sha256(('unique-key-'+str(random.random())).encode()).hexdigest()}-{datetime.now()}"
if "history" not in st.session_state:
    st.session_state.history = []

# logo = Image.open('./images/logo.png')

def random_key_gen():
    return f"{hashlib.sha256(('unique-key-'+str(random.random())).encode()).hexdigest()}-{datetime.now()}"

def conversational_bot(user_message):
     return "ainda to burra calma"

def generate_answer():
    user_message = st.session_state.input_text
    st.session_state.input_text = ""

    response = conversational_bot(user_message)

    st.session_state.history.append({"message": user_message, "is_user": True})
    st.session_state.history.append({"message": response, "is_user": False})

def gpt3_app():

    # st.image(logo)

    st.title("AlanIA")

    for chat in st.session_state.history:
        st_message(**chat, key=random_key_gen())  # unpacking

    st.text_input("Fale com o robo", key="input_text", on_change=generate_answer)

    if st.button("LIMPAR"):

            st.session_state.history = []
            st.session_state.pdf_source = "Vazio"
            st.session_state.session_unique_key = f"{hashlib.sha256(('unique-key-'+str(random.random())).encode()).hexdigest()}-{datetime.now()}"

            st.experimental_rerun()

    time.sleep(0.15)
    components.html(
        f"""
            <!--{len(st.session_state.history)}-->
            <script>
                var objDiv = window.parent.document.querySelector('section.main');
                objDiv.scrollTop = objDiv.scrollHeight;
            </script>
        """,
        height=0
    )

gpt3_app()


from __future__ import print_function
from bcc import BPF
from time import sleep, strftime
import errno
from cStringIO import StringIO

debug = 0

def init_bpf():
  # define BPF program
  bpf_text = """
#include <uapi/linux/ptrace.h>
#include <linux/sched.h>

#define MINBLOCK_US    MINBLOCK_US_VALUEULL
#define MAXBLOCK_US    MAXBLOCK_US_VALUEULL

struct key_t {
    u32 pid;
    u32 tgid;
    int user_stack_id;
    int kernel_stack_id;
    char name[TASK_COMM_LEN];
};
BPF_HASH(counts, struct key_t);
BPF_HASH(start, u32);
BPF_STACK_TRACE(stack_traces, STACK_STORAGE_SIZE)

int oncpu(struct pt_regs *ctx, struct task_struct *prev) {
    u32 pid = prev->pid;
    u32 tgid = prev->tgid;
    u64 ts, *tsp;

    // record previous thread sleep time
    if ((THREAD_FILTER) && (STATE_FILTER)) {
        ts = bpf_ktime_get_ns();
        start.update(&pid, &ts);
    }

    // get the current thread's start time
    pid = bpf_get_current_pid_tgid();
    tgid = bpf_get_current_pid_tgid() >> 32;
    tsp = start.lookup(&pid);
    if (tsp == 0) {
        return 0;        // missed start or filtered
    }

    // calculate current thread's delta time
    u64 delta = bpf_ktime_get_ns() - *tsp;
    start.delete(&pid);
    delta = delta / 1000;
    if ((delta < MINBLOCK_US) || (delta > MAXBLOCK_US)) {
        return 0;
    }

    // create map key
    u64 zero = 0, *val;
    struct key_t key = {};

    key.pid = pid;
    key.tgid = tgid;
    key.user_stack_id = USER_STACK_GET;
    key.kernel_stack_id = KERNEL_STACK_GET;
    bpf_get_current_comm(&key.name, sizeof(key.name));

    val = counts.lookup_or_init(&key, &zero);
    (*val) += delta;
    return 0;
}
  """

  return bpf_text

def offcputimenewUtil(folded, duration, in_user_threads_only, in_kernel_threads_only, in_user_stacks_only, in_kernel_stacks_only, in_tgid, in_pid, in_state, in_stack_storage_size, in_min_block_time, in_max_block_time):
  output = StringIO()

  bpf_text = init_bpf()

  # set thread filter
  thread_context = ""
  if in_tgid is not None:
    thread_context = "PID %d" % in_tgid
    thread_filter = 'tgid == %d' % in_tgid
  elif in_pid is not None:
    thread_context = "TID %d" % in_pid
    thread_filter = 'pid == %d' % in_pid
  elif in_user_threads_only:
    thread_context = "user threads"
    thread_filter = '!(prev->flags & PF_KTHREAD)'
  elif in_kernel_threads_only:
    thread_context = "kernel threads"
    thread_filter = 'prev->flags & PF_KTHREAD'
  else:
    thread_context = "all threads"
    thread_filter = '1'
  if in_state == 0:
    state_filter = 'prev->state == 0'
  elif in_state:
    # these states are sometimes bitmask checked
    state_filter = 'prev->state & %d' % in_state
  else:
    state_filter = '1'
  bpf_text = bpf_text.replace('THREAD_FILTER', thread_filter)
  bpf_text = bpf_text.replace('STATE_FILTER', state_filter)

  # set stack storage size
  bpf_text = bpf_text.replace('STACK_STORAGE_SIZE', str(in_stack_storage_size))
  bpf_text = bpf_text.replace('MINBLOCK_US_VALUE', str(in_min_block_time))
  bpf_text = bpf_text.replace('MAXBLOCK_US_VALUE', str(in_max_block_time))

  # handle stack args
  kernel_stack_get = "stack_traces.get_stackid(ctx, BPF_F_REUSE_STACKID)"
  user_stack_get = \
    "stack_traces.get_stackid(ctx, BPF_F_REUSE_STACKID | BPF_F_USER_STACK)"
  stack_context = ""
  if in_user_stacks_only:
    stack_context = "user"
    kernel_stack_get = "-1"
  elif in_kernel_stacks_only:
    stack_context = "kernel"
    user_stack_get = "-1"
  else:
    stack_context = "user + kernel"
  bpf_text = bpf_text.replace('USER_STACK_GET', user_stack_get)
  bpf_text = bpf_text.replace('KERNEL_STACK_GET', kernel_stack_get)

# check for an edge case; the code below will handle this case correctly
# but ultimately nothing will be displayed
  if in_kernel_threads_only and in_user_stacks_only:
    print("ERROR: Displaying user stacks for kernel threads " +
          "doesn't make sense.", file=output)
    exit(1)

  if (debug):
    print(bpf_text)

# initialize BPF
  b = BPF(text=bpf_text)
  b.attach_kprobe(event="finish_task_switch", fn_name="oncpu")

  # header
  if not folded:
    print("Tracing off-CPU time (us) of %s by %s stack" %
        (thread_context, stack_context), end="", file=output)
    print(" for %d secs." % duration, file=output)

  sleep(duration)

  if not folded:
    print(file=output)

  need_delimiter = not (in_kernel_stacks_only or
                                         in_user_stacks_only)

  missing_stacks = 0
  has_enomem = False
  counts = b.get_table("counts")
  stack_traces = b.get_table("stack_traces")
  for k, v in sorted(counts.items(), key=lambda counts: counts[1].value):
    # handle get_stackid erorrs
    if (not in_user_stacks_only and k.kernel_stack_id < 0) or \
            (not in_kernel_stacks_only and k.user_stack_id < 0 and
                 k.user_stack_id != -errno.EFAULT):
        missing_stacks += 1
        # check for an ENOMEM error
        if k.kernel_stack_id == -errno.ENOMEM or \
           k.user_stack_id == -errno.ENOMEM:
            has_enomem = True
        continue

    # user stacks will be symbolized by tgid, not pid, to avoid the overhead
    # of one symbol resolver per thread
    user_stack = [] if k.user_stack_id < 0 else \
        stack_traces.walk(k.user_stack_id)
    kernel_stack = [] if k.kernel_stack_id < 0 else \
        stack_traces.walk(k.kernel_stack_id)

    if folded:
        # print folded stack output
        user_stack = list(user_stack)
        kernel_stack = list(kernel_stack)
        line = [k.name.decode()] + \
            [b.sym(addr, k.tgid) for addr in reversed(user_stack)] + \
            (need_delimiter and ["-"] or []) + \
            [b.ksym(addr) for addr in reversed(kernel_stack)]
        print("%s %d" % (";".join(line), v.value), file=output)
    else:
        # print default multi-line stack output
        for addr in kernel_stack:
            print("    %s" % b.ksym(addr), file=output)
        if need_delimiter:
            print("    --", file=output)
        for addr in user_stack:
            print("    %s" % b.sym(addr, k.tgid), file=output)
        print("    %-16s %s (%d)" % ("-", k.name.decode(), k.pid), file=output)
        print("        %d\n" % v.value, file=output)

  if missing_stacks > 0:
    enomem_str = "" if not has_enomem else \
        " Consider increasing --stack-storage-size."
    print("WARNING: %d stack traces could not be displayed.%s" %
        (missing_stacks, enomem_str),
        file=output)

  b.detach_kprobe(event="finish_task_switch")
  return output.getvalue()


def is_ascending(numbers):
    for i in range(len(numbers) - 1):
        if numbers[i] > numbers[i+1]:
            return False
    return True

n = int(input("Enter number of elements in list: "))
numbers = []
for i in range(n):
    num = int(input("Enter the value: "))
    numbers.append(num)

print("Original list:", numbers)

if is_ascending(numbers):
    print("Yes, the list is in ascending order.")
else:
    print("No, the list is not in ascending order.")


#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import pickle
import numpy as np
import pandas as pd
from geopy.distance import vincenty
import xml.etree.ElementTree as ET
from itertools import product
from unidecode import unidecode

MAX_TRAVEL_TIME = 5
NUM_LOCATIONS = 30
# One time slot every 50 kilometers seems fair; it also means that a budget of
# 10 time slots equates to 500 kilometers, which also seems fair.
KM_THRESHOLD = 50
# The cost goes up by 1 every 100k tourists; threshold taken by manual
# inspection of a histogram
TOURIST_THRESHOLD = 100000

np.random.seed(0)

def sanitize(name):
    sanitized_name = unidecode(name.strip()).replace("'", "").upper()
    return sanitized_name

# Read the hotel data provided by:
#   http://dati.trentino.it/dataset/esercizi-alberghieri
ent_with_no_1_2_star_hotel = set()
ent_with_3_4_star_hotel = set()
ent_with_5_star_hotel = set()
root = ET.parse("datasets/tndata/EserciziAlberghieri.xml").getroot()
for child in root.findall("prezzi-localita-turistica"):
    ent = sanitize(child.attrib["denominazione"])
    for subchild in child.iter("prezzi-saa"):
        level = subchild.attrib["livello-classifica"]
        if level in ("nessuna-stella", "1-stella", "2-stelle"):
            ent_with_no_1_2_star_hotel.add(ent)
        elif level in ("3-stelle", "3-stelle-s", "4-stelle", "4-stelle-s"):
            ent_with_3_4_star_hotel.add(ent)
        elif level == "5-stelle":
            ent_with_5_star_hotel.add(ent)
        else:
            raise ValueError()

# Read the bus stop data provided by:
#   http://dati.trentino.it/dataset/trasporti-pubblici-del-trentino-formato-gtfs
df = pd.read_csv("datasets/tndata/bus_stops.csv", sep=",")
ent_with_bus_stop = set(map(sanitize,
                            [s.split("-")[0] for s in df.stop_name.unique()]))

# Read the agritur data provide by:
#   http://dati.trentino.it/dataset/agriturismi-del-trentino
df = pd.read_csv("datasets/tndata/elenco_agritur_attivi.csv", sep=";", engine="python")
ent_with_agritur = set(map(sanitize, df.sede_impresa_agricola.unique()))

# Read the museum data provided by:
#   https://it.wikipedia.org/wiki/Musei_del_Trentino-Alto_Adige
df = pd.read_csv("datasets/tndata/musei.csv", sep=",")
ent_with_museum = set(map(sanitize, df.ent.unique()))

# Read the osterie data provided by:
#   http://dati.trentino.it/dataset/osterie-tipiche-trentine
df = pd.read_csv("datasets/tndata/osterietipiche2013.csv", sep=";")
ent_with_osteria = set(map(sanitize,
                           [s.split("-")[0] for s in df.Comune.unique()]))

# Read the botteghe data provided by:
#   http://dati.trentino.it/dataset/botteghe-storiche-del-trentino
df = pd.read_csv("datasets/tndata/albobotteghestorichetrentinoluglio2016.csv", sep=",", engine="python")
ent_with_bottega = set(map(sanitize, df.Comune.unique()))

# Read the hospital data provided by:
#   http://dati.trentino.it/dataset/strutture-di-ricovero-e-cura
df = pd.read_csv("datasets/tndata/ospedali.csv", sep=",")
ent_with_ospedale = set(map(sanitize, df.COMUNE.unique()))

# Read the pharmacy data provided by:
#   http://dati.trentino.it/dataset/farmacie-pat
df = pd.read_csv("datasets/tndata/farmacie.csv", sep=",")
ent_with_farmacia = set(map(sanitize, df.COMUNE.unique()))

# Read the para-pharmacy data provided by:
#   http://dati.trentino.it/dataset/parafarmacie-pat
df = pd.read_csv("datasets/tndata/parafarmacie.csv", sep=",")
ent_with_parafarmacia = set(map(sanitize, df.COMUNE.unique()))

# Read the strutture sanitarie data provided by:
#   http://dati.trentino.it/dataset/strutture-sanitarie-dell-azienda-sanitaria-e-convenzionate
df = pd.read_csv("datasets/tndata/strutture_sanitarie.csv", sep=",")
ent_with_strutsan = set(map(sanitize, df.COMUNE.unique()))

# Read the strutture riabilitazione data provided by:
#   http://dati.trentino.it/dataset/strutture-di-riabilitazione
df = pd.read_csv("datasets/tndata/strutture_riabilitazione.csv", sep=",")
ent_with_strutriab = set(map(sanitize, df.COMUNE.unique()))

# Read the guardia medica data provided by:
#   http://dati.trentino.it/dataset/continuita-assitenziale-ex-gm
df = pd.read_csv("datasets/tndata/continuita_assistenziale.csv", sep=",")
ent_with_contassist = set(map(sanitize, df.COMUNE.unique()))

# Read the library data provided by:
#   http://dati.trentino.it/dataset/biblioteche-ai-censimenti
ent_with_library = set()
for line in open("datasets/tndata/biblioteche.xml", "rb"):
    line = line.decode().strip()
    if "<comune>" in line:
        ent = line.split(">")[1].split("<")[0]
        ent_with_library.add(sanitize(ent))

# Read the code->entity map provided by:
#   http://dati.trentino.it/dataset/elenco-codici-ente
df = pd.read_csv("datasets/tndata/codente50.csv", sep=";", comment="#")
ents = sorted(map(sanitize, df.descriz.unique()))
regs = sorted(map(sanitize, df.comvall.unique()))

ent_to_reg = {}
for ent, reg in zip(df.descriz, df.comvall):
    ent_to_reg[sanitize(ent)] = sanitize(reg)

ent_to_cost = {}
for ent, tou in zip(df.descriz, df.presenze):
    ent_to_cost[sanitize(ent)] = 1 + int(tou) // TOURIST_THRESHOLD

ent_to_i = {ent: i for i, ent in enumerate(ents)}
reg_to_i = {reg: i for i, reg in enumerate(regs)}

# Read the entity->(lat,lon) map
df = pd.read_csv("datasets/tndata/coords.csv", sep=",")

ent_to_coords = {}
for ent, lat, lon in zip(df.ent, df.lat, df.lon):
    ent_to_coords[sanitize(ent)] = (lat, lon)
assert all(ent in ent_to_coords for ent in ents)

# Build the location-activity array
ENT_WITH_ACTIVITIES = [
    ent_with_no_1_2_star_hotel,
    ent_with_3_4_star_hotel,
    ent_with_5_star_hotel,
    ent_with_agritur,
    ent_with_osteria,
    ent_with_bottega,
    ent_with_bus_stop,
    ent_with_library,
    ent_with_museum,
    ent_with_ospedale,
    ent_with_farmacia,
    ent_with_parafarmacia,
    ent_with_strutsan,
    ent_with_strutriab,
    ent_with_contassist,
]

num_locations = len(ents)
num_activities = len(ENT_WITH_ACTIVITIES)

location_activities = np.zeros((num_locations + 1, num_activities), dtype=int)
for i, ent in enumerate(ents):
    for j, ent_with_activity in enumerate(ENT_WITH_ACTIVITIES):
        if ent in ent_with_activity:
            location_activities[i, j] = 1

# Compute the location costs; we have no better way to do it
location_cost = np.zeros(num_locations + 1, dtype=int)
for i, ent in enumerate(ents):
    location_cost[i] = ent_to_cost[ent]

# Compute an approximate travel time based on geospatial distance in KM
travel_time = np.zeros((num_locations, num_locations), dtype=int)
for ent1, ent2 in product(ents, ents):
    i1, coords1 = ent_to_i[ent1], ent_to_coords[ent1]
    i2, coords2 = ent_to_i[ent2], ent_to_coords[ent2]
    km = vincenty(coords1, coords2).km
    travel_time[i1, i2] = 1 + km // KM_THRESHOLD
np.fill_diagonal(travel_time, 0)

# Compute the entity->region map
indices, location_regions = [], []
for ent in ents:
    index = reg_to_i[ent_to_reg[ent]]
    if not index in indices:
        indices.append(index)
    new_index = indices.index(index) + 1
    location_regions.append(new_index)
num_regions = len(set(indices))

print("""\
location activities =
{location_activities}

location costs =
{location_cost}

travel time =
{travel_time}

regions =
{location_regions} / {num_regions}
""".format(**locals()))

dataset = {
    "location_activities": location_activities,
    "location_cost": location_cost,
    "travel_time": travel_time,
    "num_regions": num_regions,
    "regions": location_regions,
}
with open("datasets/travel_tn.pickle", "wb") as fp:
    pickle.dump(dataset, fp)


import os
import sys
import logging
if getattr(sys,'frozen', False): #frozen exe
    PATH = os.path.dirname(sys.argv[0]) + '\\'
    logging.basicConfig(filename= os.path.dirname(sys.argv[0]) + '\concerto.log', level=logging.DEBUG)
else: #not frozen
    PATH = os.path.dirname(os.path.abspath(__file__)) + '\\'
    logging.basicConfig(filename= os.path.dirname(os.path.abspath(__file__)) + '\concerto.log', level=logging.DEBUG)
import configparser
from kivy.config import Config
from kivy.resources import resource_add_path
if hasattr(sys, '_MEIPASS'):
    resource_add_path(os.path.join(sys._MEIPASS))
os.environ["KIVY_AUDIO"] = "sdl2"
# Kivy app configs
Config.set('graphics', 'width', '600')
Config.set('graphics', 'height', '400')
Config.set('graphics', 'resizable', False)
Config.set('graphics', 'multisamples', 0)
Config.set('graphics', 'fullscreen', 0)
Config.set('kivy', 'desktop', 1)
Config.set('input', 'mouse', 'mouse,multitouch_on_demand')
Config.set('kivy', 'window_icon', 'concertoicon.ico')
Config.set(
    "kivy",
    "default_font",
    [
        "Roboto",
        'data/fonts/Roboto-Regular.ttf',
        'data/fonts/Roboto-Italic.ttf',
        'data/fonts/Roboto-Bold.ttf',
        'data/fonts/Roboto-BoldItalic.ttf'
    ],
)
Config.write()
#CCCaster ini default settings
caster_config = None
caster_opt = {
        'alertOnConnect' : '3',
        'alertWavFile' : 'SystemDefault',
        'autoCheckUpdates' : '1',
        'defaultRollback' : '4',
        'displayName' : 'Concerto Player',
        'fullCharacterName' : '0',
        'heldStartDuration' : '1.5',
        'highCpuPriority' : '0',
        'lastMainMenuPosition' : '-1',
        'lastOfflineMenuPosition' : '-1',
        'lastUsedPort' : '-1',
        'maxRealDelay' : '254',
        'replayRollbackOn' : '1',
        'updateChannel' : '1',
        'versusWinCount' : '2',
        'autoReplaySave' : '1',
        'matchmakingRegion': 'NA West'
}
if os.path.exists(PATH + 'cccaster\config.ini'):
    clean = []
    with open(PATH + 'cccaster\config.ini') as f:
        for i in f.readlines():
            for x in caster_opt:
                if x in i:
                    clean.append(x)
    for i in clean:
        try:
            del caster_opt[i]
        except KeyError:
            pass
    if len(caster_opt) != 0:
        with open(PATH + 'cccaster\config.ini','a') as f:
            for k,v in caster_opt.items():
                f.write('\n%s=%s' % (k,v))
            f.close()
    with open(PATH + 'cccaster\config.ini', 'r') as f:
            config_string = f.read()
    caster_config = configparser.ConfigParser()
    caster_config.read_string('[settings]\n' + config_string)
else:
    if os.path.isdir(PATH + 'cccaster'):
        with open(PATH + 'cccaster\config.ini', 'w') as f:
            for k,v in caster_opt.items():
                    f.write('\n%s=%s' % (k,v))
            f.close()
        with open(PATH + 'cccaster\config.ini', 'r') as f:
            config_string = f.read()
        caster_config = configparser.ConfigParser()
        caster_config.read_string('[settings]\n' + config_string)

#Concerto ini default settings
opt = [
        'netplay_port',
        'mute_alerts',
        'mute_bgm',
        'discord',
        'write_scores',
        'caster_exe',
        'bgm_track'
]
if os.path.exists(PATH + 'concerto.ini'):
    with open(PATH + 'concerto.ini') as f:
        for i in f.readlines():
            for x in opt:
                if x in i:
                    opt.remove(x)
    if len(opt) != 0:
        with open(PATH + 'concerto.ini','a') as f:
            for i in opt:
                if i == 'caster_exe':
                    f.write('\ncaster_exe=cccaster.v3.1.exe\n')
                elif i == 'bgm_track':
                    f.write('\nbgm_track=walkway\n')
                else:
                    f.write('\n%s=0\n' % i)
            f.close()
else:
    with open(PATH + 'concerto.ini', 'w') as f:
        f.write('[settings]')
        for i in opt:
            if i == 'caster_exe':
                f.write('\ncaster_exe=cccaster.v3.1.exe\n')
            elif i == 'bgm_track':
                f.write('\nbgm_track=walkway\n')
            else:
                f.write('\n%s=0\n' % i)
        f.close()
with open(PATH + 'concerto.ini','r') as f:
    config_string = f.read()
app_config = configparser.ConfigParser()
app_config.read_string(config_string)

LOBBYURL = "https://concerto-mbaacc.shib.live/l"
VERSIONURL = "https://concerto-mbaacc.shib.live/v"
CURRENT_VERSION = '1.04'
DEBUG_VERSION = 'lang-beta-1' # set to '' if not in use. This string is printed to logging to track specific test builds.
def find_img(file):
    if os.path.exists(file):
        return PATH + file
    else:
        return 'res/%s' % file

def img_credit(file,txt):
    if os.path.exists(file):
        return ''
    else:
        return txt


import sys
import pygame
import json
import time
from question import Question

def check_events(vw_settings, vw_stats, screen, question):
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_q:
                sys.exit()
            elif vw_stats.answer_en and event.key == vw_stats.cur_answer:
                print("Well done!")
                vw_stats.game_active = False
            elif vw_stats.answer_en and event.key != vw_stats.cur_answer:
                print("Failed...")
                vw_stats.info_print_en = True
                update_screen(vw_settings, vw_stats, screen, question)
                time.sleep(5)
                vw_stats.game_active = False

def update_screen(vw_settings, vw_stats, screen, question):
    screen.fill(vw_settings.bg_color)
    if not vw_stats.info_print_en:
        question.ask_question()
    else:
        question.give_tips()
    pygame.display.flip()

def get_question(file_path, vw_settings, screen, vw_stats):
    try:
        f_obj = open(file_path, encoding='utf-8')
    except FileNotFoundError:
        print("test file not found, please check.")
        vw_stats.game_active = False
    else:
        question = json.load(f_obj)
        cur_question = Question(question, vw_settings, screen, vw_stats)
        # vw_stats.game_active = False
        vw_stats.answer_en = True
        return cur_question


from PyQt5.Qt import *
import sys

class Window(QWidget):
    def __init__(self):
        super(Window, self).__init__()
        self.setGeometry(1400, 600, 600, 600)
        self.setWindowTitle('')
        self.setup_ui()

    def setup_ui(self):
        text_area = QTextEdit(self)
        text_area.setHtml('*' * 200 + '''这是内容''' + '+' * 200)

        button = QPushButton('转到锚点', self)
        button.move(20, 300)
        button.clicked.connect(self.to_anchor_1)

    def to_anchor_1(self):
        text_area = self.findChild(QTextEdit)
        text_area.scrollToAnchor('anchor_1')

if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = Window()
    window.show()
    sys.exit(app.exec())


import torch
import torch.nn as nn

class SnakeLoss(nn.Module):
    """
    Sum the the scores weighted by the probabilities assigned to the action chosen"""

    def __init__(self, weihgts: torch.Tensor = 0) -> None:
        super().__init__()
        self.weights = weihgts

    def forward(
        self, direction_pred: torch.Tensor, direction: torch.Tensor, score: torch.Tensor
    ) -> float:
        """Return loss

        Parameters
        ----------
        direction_pred : torch.Tensor
            Shape (B, N, 4)
        direction : torch.Tensor
            Shape (B, N, 1) dtype torch.long
        score : torch.Tensor
            Shape (B, N, 1)

        Returns
        -------
        torch.float
            _description_
        """

        proba_of_chosen_direction = torch.gather(
            direction_pred, dim=-1, index=direction
        )

        predicted_reward = torch.mul(proba_of_chosen_direction, score)

        return torch.sum(predicted_reward)

if __name__ == "__main__":

    # Test loss
    direction_pred = torch.Tensor(
        [
            [
                [0.5, 0.3, 0.2],
                [0.3, 0.5, 0.2],
            ]
        ]
    )

    direction = torch.Tensor(
        [
            [
                [0],
                [2],
            ]
        ],
    ).to(torch.int64)

    score = torch.Tensor(
        [
            [
                [1],
                [2],
            ]
        ]
    )

    loss = SnakeLoss()

    output = loss.forward(direction_pred, direction, score)

    print(output)

    assert output == torch.Tensor([-0.9])


from datetime import datetime
import telebot
from telebot import types
from resources.Data import Dicts
from resources.electricity import *
from resources.TOKEN import token, chatId
from clients.telegram_client import TelegramClient
from clients.sqlclient import SQLiteClient, UserActioner
# from logger_main import *

TOKEN = token
ADMIN_CHAT_ID = chatId

class MyBot(telebot.TeleBot):
    def __init__(self, telegram_client: TelegramClient, user_actioner: UserActioner, *args, **kwargs):
        super(self.__class__, self).__init__(*args, **kwargs)
        self.telegram_client = telegram_client
        self.user_actioner = user_actioner

    def setup_resources(self):
        self.user_actioner.setup()

    def shutdown_resources(self):
        self.user_actioner.shutdown()

    def shutdown(self):
        self.shutdown_resources()

user_actioner = UserActioner(SQLiteClient(r"../resources/users.db"))
telegram_client = TelegramClient(token=TOKEN, base_url="https://api.telegram.org")
bot = MyBot(token=TOKEN, telegram_client=telegram_client, user_actioner=user_actioner)

@bot.message_handler(commands=['start'])
def start_message(message):
    img = open(Dicts.PICTURE_1, 'rb')
    msg = bot.send_photo(message.chat.id, img, caption="Привіт!\nЦей бот послуговується графіками планових відключень від "
                                                 "Львівобленерго. Інформація про аварійні відключення не надається. "
                                    "Щоб продовжити натисніть /putin_huilo", parse_mode='HTML')
    bot.register_next_step_handler(msg, reply_to_start)

def reply_to_start(message):
    if message.text != "/putin_huilo":
        bot.reply_to(message, "Для початку роботи із ботом необхідно ідентифікувати ваші політичні погляди, тому щоб продовжити, "
                          "слідуйте інструкціям, що вказані нижче 👇🏻", parse_mode='HTML')
        start_message(message)
    else:
        choose_group(message)

# @bot.message_handler(commands=['putin_huilo'])
def choose_group(message):
    markup_inline = types.InlineKeyboardMarkup()
    group_1 = types.InlineKeyboardButton(text='I група', callback_data=1)
    group_2 = types.InlineKeyboardButton(text='II група', callback_data=2)
    group_3 = types.InlineKeyboardButton(text='III група', callback_data=3)
    markup_inline.add(group_1, group_2, group_3)
    bot.send_message(message.chat.id, 'Оберіть номер вашої групи:', reply_markup=markup_inline, parse_mode='HTML')
    markup_inline_2 = types.InlineKeyboardMarkup()
    url = types.InlineKeyboardButton(text='Дізнатись групу', url='https://poweroff.loe.lviv.ua/gav_city3')
    markup_inline_2.add(url)
    bot.send_message(message.chat.id, 'Не знаєте в якій ви групі?', reply_markup=markup_inline_2,
                     parse_mode='HTML')

@bot.message_handler(content_types=["text"])
def reply(message):
    bot.reply_to(message, "Спершу оберіть групу! ☝🏻\nДля взаємодії з ботом використовуйте клавіші, що з'являються у чаті та "
                          "у нижній частині екрану.", parse_mode='HTML')

@bot.callback_query_handler(func=lambda callback: callback.data)
def to_json(callback):

    tg_name = callback.from_user.username
    user_id = callback.from_user.id
    user_name = callback.from_user.first_name
    chat_id = callback.message.chat.id
    group_id = callback.data
    bot.delete_message(callback.message.chat.id, callback.message.id)

    user = bot.user_actioner.get_user(user_id=str(user_id))

    if not user:
        bot.user_actioner.create_user(user_id=str(user_id), username=user_name, chat_id=chat_id, tg_name=tg_name)
        bot.user_actioner.set_group(user_id=str(user_id), group_id=group_id)
    else:
        bot.user_actioner.set_group(user_id=str(user_id), group_id=group_id)

    bot.send_message(callback.message.chat.id, text=f'Вітаю, {user_name}. Вас зареєстровано.\n'
                                                    f'Ваша група: №{group_id}')
    choose_option(callback.message)

def choose_option(message):
    kb = types.ReplyKeyboardMarkup(resize_keyboard=True, row_width=5)
    btn1 = types.KeyboardButton(text='1 💡')
    btn2 = types.KeyboardButton(text='2 🕯')
    btn3 = types.KeyboardButton(text='3 📅')
    btn4 = types.KeyboardButton(text='4 ⏰')
    btn5 = types.KeyboardButton(text='5 🔁')
    kb.add(btn1, btn2, btn3, btn4, btn5)
    msg = bot.send_message(message.chat.id, text='Оберіть опцію:', reply_markup=kb, parse_mode='HTML')

    bot.send_message(message.chat.id, text='1. Дізнатись про наявність електроенергії у цю мить.\n'
                                           '2. Отримати графік відключення на поточний день.\n'
                                           '3. Отримати графік відключення на тиждень.\n'
                                           '4. Налаштувати сповіщення щодо відключення.\n'
                                           '5. Змінити групу.')
    bot.register_next_step_handler(msg, option)

def on_off(message):
    if message.text == "Підключити сповіщення":
        bot.send_message(message.chat.id, text=f'Вітаю, {user_actioner.get_user(user_id=str(message.from_user.id))[1]}. '
                                               f'Ви підключили сповіщення!\n'
                                               'Кожного разу за годину перед можливим відключенням '
                                               'Вам надходитиме попереджувальне повідомлення.')

        bot.user_actioner.set_notify(user_id=str(message.from_user.id), notifications=1)
        choose_option(message)
    elif message.text == "Відключити сповіщення":
        bot.send_message(message.chat.id,
                         text="Сповіщення про відключення електроенергії вимкнено !")
        bot.user_actioner.set_notify(user_id=str(message.from_user.id), notifications=0)
        choose_option(message)
    else:
        bot.reply_to(message, text="Для взаємодії з ботом використовуйте клавіші, що з'являються у "
                          "нижній частині екрану. Спробуйте підключити або відключити сповіщення ще раз, "
                                   "використовуючи одну із запропонованих опцій.")
        choose_option(message)

def option(message):
    group = bot.user_actioner.get_group(user_id=str(message.from_user.id))
    if message.text == '1 💡':
        condition = get_condition(int(group))
        if condition == 'Є Енергія':
            img = open(Dicts.PICTURE_2, 'rb')
            bot.send_photo(message.chat.id, img, caption=f'Згідно графіку відключень від Львівобленерго у вашому будинку'
                                                         f' на цей момент імовірно:\n'
                                                         f'✅ {condition} ✅',
                           parse_mode='HTML')
        elif condition == 'Немає Енергії':
            img = open(Dicts.PICTURE_3, 'rb')
            bot.send_photo(message.chat.id, img, caption=f'Згідно графіку відключень від Львівобленерго у вашому будинку'
                                                         f' на цей момент імовірно:\n'
                                                         f'❌ {condition} ❌',
                           parse_mode='HTML')
        else:
            img = open(Dicts.PICTURE_4, 'rb')
            bot.send_photo(message.chat.id, img,
                           caption=f'Згідно графіку відключень від Львівобленерго у вашому будинку'
                                   f' на цей момент імовірно:\n'
                                   f'⚠ {condition} ⚠',
                           parse_mode='HTML')
        choose_option(message)
    elif message.text == '2 🕯':
        bot.send_message(message.chat.id, text=f'{Dicts.WEEK_DAY[choose_day()]}, Група №{group}',
                         parse_mode='HTML')
        condition = get_day_sсhedule(int(group))
        for k, v in condition.items():
            bot.send_message(message.chat.id, text=f'{k} : {v}', parse_mode='HTML')
        choose_option(message)
    elif message.text == '3 📅':
        if group == 1:
            img = open(Dicts.SCHEDULE_1, 'rb')
            bot.send_photo(message.chat.id, img)
        elif group == 2:
            img = open(Dicts.SCHEDULE_2, 'rb')
            bot.send_photo(message.chat.id, img)
        else:
            img = open(Dicts.SCHEDULE_3, 'rb')
            bot.send_photo(message.chat.id, img)
        choose_option(message)
    elif message.text == '4 ⏰':
        kb = types.ReplyKeyboardMarkup(resize_keyboard=True, row_width=2)
        btn1 = types.KeyboardButton(text='Підключити сповіщення')
        btn2 = types.KeyboardButton(text='Відключити сповіщення')
        kb.add(btn1, btn2)
        msg = bot.send_message(message.chat.id, text='Оберіть опцію:', reply_markup=kb, parse_mode='HTML')
        bot.register_next_step_handler(msg, on_off)

    elif message.text == '5 🔁':
        choose_group(message)

    else:
        bot.reply_to(message, text="Для взаємодії з ботом використовуйте клавіатуру у нижній частині екрану! "
                                               "Вдалого користування.", parse_mode='HTML')
        choose_option(message)

def create_err_message(err: Exception) -> str:
    return f"{datetime.now} ::: {err.__class__} ::: {err}"

if __name__ == "__main__":
    while True:
        try:
            bot.setup_resources()
            bot.polling()
        except Exception as err:
            error_message = create_err_message(err)
            bot.telegram_client.post(method='sendMessage', params={"text": error_message,
                                                                   "chat_id": ADMIN_CHAT_ID})

            send_log(error_message)
            bot.shutdown()


'''
Least Squares Fit
'''
import numpy as np
import matplotlib.pyplot as plt

def visualize(X, Y, W, title, labels):
    '''
    Draw graphs
    :param X: list of x
    :param Y: list of y
    :param W: (w0, w1)
    :param title: title
    :param labels: (xlabel, ylabel)
    :return: None
    '''
    axes = plt.gca()
    plt.title(title)
    plt.xlabel(labels[0])
    plt.ylabel(labels[1])
    axes.scatter(X, Y)
    Y_fit = get_line(W, X)
    axes.plot(X, Y_fit)
    plt.show()

def get_line(W, X):
    '''
    Calculate Y = WX
    :param W: (w0, w1)
    :param X: list of x
    :return: Y
    '''
    X = np.vstack([[1] * len(X), X])
    return W @ X

def linear_regression(X, Y):
    '''
    Exact solution for W = YX_pseudo_inv
    :param X: array of x
    :param Y: array of y
    :return: W
    '''
    X = np.vstack([[1] * len(X), X])
    return Y @ (np.transpose(X) @ np.linalg.inv(X @ np.transpose(X)))

def calc_gradient(X, Y, W):
    '''
    Calculate gradient
    :param X: array of x
    :param Y: array of y
    :param W: (w0, w1)
    :return: gradient
    '''
    gradient = np.empty(2)
    for i in range(0, len(Y)):
        gradient = gradient + (Y[i] - (W[0] + W[1] * X[i])) * np.array([1, X[i]])
    return - 2 * gradient

def gradient_descent(X, Y):
    '''
    Gradient Descent algorithm
    :param X: array of x
    :param Y: array of y
    :return: W
    '''
    W = np.array([0.15, 1])
    eta = 0.001/len(Y)
    epochs = 0
    while True:
        W_prev = W
        gradient = calc_gradient(X, Y, W)
        W = W - eta * gradient
        epochs += 1
        if np.array(abs(W - W_prev) < 10**-4).all():
            break
    print(epochs)
    return W

def main():
    '''
    Main
    :return: None
    '''
    X = np.arange(1, 51, 1)
    Y = np.array([X[i] + np.random.uniform(-1, 1) for i in range(0, len(X))])
    W_lr = linear_regression(X, Y)
    W_gd = gradient_descent(X, Y)
    print(W_lr)
    visualize(X, Y, W_lr, 'Linear Regression', ('x', 'y'))
    visualize(X, Y, W_gd, 'Gradient Descent', ('x', 'y'))

if __name__ == '__main__':
    main()


import matplotlib
matplotlib.use('agg')
import matplotlib.pyplot as plt

import pandas as pd
import numpy as np
from scipy.stats import hypergeom
import random
import sys

from scipy.integrate import simpson

plt.rcParams.update({'font.size': 24})

class StepwiseHypergeom:

    def __init__(self, full_ranking_files, external_successes_file, bucket_size, bucket='', mol_type='', full_ranking_top_perc=-1, successes_top_perc=-1, max_x_lim=-1, max_y_lim=-1):

        """
            This class calculates the stepwise hypergeometric enrichment between a full ranked list of genes and a set of external files containing ranked 'successes'.

            - full_ranking_file:
                full reference gene ranking; file should be provided as a single-column ranked list of genes (withouth column header)

            - external_successes_files:
                list of external files containing the 'successes'; each file should be provided as a single-column ranked list of genes (withouth column header)

            - full_ranking_top_perc:
                top percentage of full_ranking_file's hits to restrict the enrichment analysis into (e.g 0.05); if -1, the full list is used

            - successes_top_perc:
                top percentage of each of external_successes_files' hits to restrict the enrichment analysis into (e.g 0.05); if -1, the full list is used

            - max_x_lim:
                x-axis limit for the hypergeometric enrichment plots

            - max_y_lim:
                y-axis limit for the hypergeometric enrichment plots
        """

        #self.full_ranking_df = self.read_full_ranking(full_ranking_file)
        self.full_ranking_files = full_ranking_files

        self.external_successes = pd.read_csv(external_successes_file, header=None)

        self.full_ranking_top_perc = full_ranking_top_perc
        self.successes_top_perc = successes_top_perc

        self.bucket_size = bucket_size
        self.bucket = bucket
        self.mol_type = mol_type

        # plotting parameters
        self.figure_name = 'both'
        self.max_x_lim = max_x_lim
        self.max_y_lim = max_y_lim

    def calc_phred_score(self, pval):
        phred = None

        # Set an upper cap of 500 for all Phred scores
        if pval == 0:
            phred = 500
        else:
            phred = -10 * np.log10(pval)
            if phred > 500:
                phred = 500

        return phred

    def read_full_ranking(self, full_ranking_file):

        full_ranking_df = pd.read_csv(full_ranking_file, header=None)
        full_ranking_df.columns = ['Gene_Name']
        full_ranking_df['full_ranking'] = range(1, full_ranking_df.shape[0]+1)

        return full_ranking_df

    def calc_hypergeom_pvals(self, full_ranking_df):

        external_successes = self.external_successes.copy()
        # external top predictions
        external_successes.columns = ['Gene_Name']
        #print("\n external ranking:", external_successes.head())
        #print(external_successes.shape)

        # Subset top external hits to then overlap with the full rankings df
        if self.successes_top_perc != -1:
            #external_successes = external_successes.iloc[:int(external_successes.shape[0] * self.successes_top_perc), :]
            external_successes = external_successes.iloc[:self.bucket_size, :]
        external_top_genes = external_successes['Gene_Name'].tolist()
        print('- Total number of Successes:', len(external_top_genes))

        # Restrict full ranking to top perc results if 'full_ranking_top_perc' is specified
        if self.full_ranking_top_perc != -1:
            #print(full_ranking_df.shape)
            #full_ranking_df = full_ranking_df.loc[:int(full_ranking_df.shape[0] * self.full_ranking_top_perc)]
            full_ranking_df = full_ranking_df.iloc[:992]
            #print(full_ranking_df.shape)
            print('- Restrict full ranking to top % results: ' + str(int(self.full_ranking_top_perc*100)) + '% (' + str(full_ranking_df.shape[0]) + ')' )

        M = full_ranking_df.shape[0]
        print('- Population Size:', M)
        #print('\n Full ranking:\n', full_ranking_df.head())

        full_ranking_df = full_ranking_df.loc[full_ranking_df['Gene_Name'].isin(external_top_genes)]
        full_ranking_df.reset_index(drop=True, inplace=True)
        #print('\n', full_ranking_df.head())
        #print('\n', full_ranking_df.tail())

        n = full_ranking_df.shape[0]
        print('\nTotal number of Successes in Full ranking (overlap):', n)

        # ************* Hypergeometric Test *************
        hypergeom_pvals = []
        hypergeom_ordered_genes = []

        for x in range(full_ranking_df.shape[0]):

            #print(full_ranking_df.iloc[x, 0])

            N = full_ranking_df.iloc[x, full_ranking_df.shape[1]-1]
            #print(x, N)

            cur_pval = hypergeom.sf(x - 1, M, n, N)
            #print(cur_pval)

            hypergeom_pvals = hypergeom_pvals + [cur_pval]

            cur_gene = full_ranking_df.loc[x, 'Gene_Name']
            hypergeom_ordered_genes = hypergeom_ordered_genes + [cur_gene]
        # ***********************************************

        #min_pval = min(hypergeom_pvals)
        hypergeom_pvals = [self.calc_phred_score(pval) for pval in hypergeom_pvals]
        print('\nMax phred:', max(hypergeom_pvals))
        print('Avg phred:', np.mean(hypergeom_pvals))

        return hypergeom_pvals

    def plot_hypergeom_stepwise(self, hypergeom_pvals, ax, label, color='#33a02c', signif_thres=0.05, plot_pval_thres=True):

        if plot_pval_thres:
            signif_thres = self.calc_phred_score(signif_thres)
            ax.axhline(y=signif_thres, linestyle='--', color='red', label='p-val: 0.05')

        ax.plot(hypergeom_pvals, color=color,
                label=label,
                linewidth=1)

        ax.set_xlim(left=-0.5)

        y_label = 'Phred score from hypergeometric test\n(significance increasing in positive direction)'
        ax.set_ylabel(y_label, fontsize=14)

        ax.legend(bbox_to_anchor=(1.32, 1), fontsize=12, loc='upper right', framealpha =0.6)
        for line in ax.legend().get_lines():
            line.set_linewidth(2.0)

    def get_area_under_curve(self,yvals):
        # - Calc. AUC based on Simpson's area / trapezoid area
        # - Restrict area above the line: y=phred(0.05)

        phred = self.calc_phred_score(0.05)
        yvals = np.array(yvals)

        diff = yvals - phred
        curve_values = np.maximum(diff, 0) #negative values are replaced with 0
        curve_auc = simpson(curve_values, dx=1)

        return curve_auc

    def main(self):
        print("hello")
        hypergeom_results = {}

        # Calculate hypergeometric enrichments for each external successes file
        for f in self.full_ranking_files:
            #print(f)
            full_ranking_df = self.read_full_ranking(f)
            ranking_file = f.split('/')[-1]
            print('\n\n\n> ', ranking_file + ':', full_ranking_df.shape)

            hypergeom_results[ranking_file] = self.calc_hypergeom_pvals(full_ranking_df)

        # # Calculate hypergeometric enrichments against a random gene ranking
        random_full_ranking = full_ranking_df.sample(frac=1, random_state=0)
        random_full_ranking.reset_index(drop=True, inplace=True)
        random_full_ranking['full_ranking'] = range(1, full_ranking_df.shape[0]+1)
        #print(random_full_ranking.head())
        print('\n\n\n> Random:', random_full_ranking.shape)
        random_hypergeom_pvals = self.calc_hypergeom_pvals(random_full_ranking)

        print(sorted(hypergeom_results, key=lambda k: len(hypergeom_results[k]), reverse=True))

        # ------------------------- Start plotting ----------------------------
        print('\n> Plotting hypergeom. enrichment plots...')
        fig, ax = plt.subplots(figsize=(12, 8))

        colors = ['#2171b5', '#238b45', '#fe9929', '#fff7bc']
        cnt = 0
        for external_dataset in sorted(hypergeom_results, key=lambda k: len(hypergeom_results[k]), reverse=True):  #hypergeom_results.items():

            hypergeom_pvals = hypergeom_results[external_dataset]

            #calculate area under curve
            auc = self.get_area_under_curve(hypergeom_pvals)
            print(external_dataset+" auc= ",auc)

            self.plot_hypergeom_stepwise(hypergeom_pvals, ax, label=external_dataset.split('.')[0], color=colors[cnt], plot_pval_thres=False)
            cnt += 1

        self.plot_hypergeom_stepwise(random_hypergeom_pvals, ax, label='random', color='black')

        # Set axis limits
        if self.max_x_lim != -1:
            ax.set_xlim(0, self.max_x_lim)
        else:
            ax.set_xlim(0, max(len(l) for k, l in hypergeom_results.items()))
        if self.max_y_lim != -1:
            ax.set_ylim(0, self.max_y_lim)

        # Define filename top perc. identifiers
        if self.successes_top_perc == -1:
            success_top_str = 'all'
        else:
            success_top_str = 'top' + str(int(self.successes_top_perc * 100)) + 'perc'

        if self.full_ranking_top_perc == -1:
            full_top_str = 'all'
        else:
            full_top_str = 'top' + str(int(self.full_ranking_top_perc * 100)) + 'perc'

        if self.mol_type == 'Kings':
            plt.title('Kings et al')
        else:
            plt.title(self.mol_type + ' ' + self.bucket)

        # Save fig to pdf
        fig.savefig(self.mol_type+'_External_' + self.bucket + '-vs-Full_ranking_' + self.figure_name + '_' + full_top_str + '.pdf', bbox_inches='tight')
        fig.savefig(self.mol_type+'_External_' + self.bucket + '-vs-Full_ranking_' + self.figure_name + '_' + full_top_str + '.png', bbox_inches='tight')
        plt.close()

        print('\n> Done.')


# -*- coding: utf-8 -*-
"""
Created on Thu Dec 30 16:20:13 2021

@author: doudou
"""

import torch
import torch.nn as nn
import torch.nn.functional as F

import time # record the time record
import matplotlib.pyplot as plt #draw the diagram

import numpy as np #linear algebra
import datetime
import random
from DSL import *

from math import *
from Boomsday.omegas.dataloader import *
from config import *
import config as config

data = Mathloader(path,trainNum)

symbol_id_collection = []
# gain symbol id from tokenizer
for i in range(10):
    st = "the value symbol" + str(i) + " and what is that "
    idx = data.tokenize_data(st)[0][2]
    symbol_id_collection.append(idx)

def attention(q,words):
    att = torch.softmax(torch.matmul(words,q.permute(1,0)),-2)
    return torch.matmul(att.permute(1,0),words)

def del_tensor_ele(arr,index):
    arr1 = arr[0:index]
    arr2 = arr[index+1:]
    return torch.cat((arr1,arr2),dim=0)

class SymbolNet(nn.Module):
    def __init__(self,name):
        super().__init__()
        self.id = name
        self.wordvecs = nn.Embedding(10000, 232)

        self.pfc1 = nn.Linear(232,100)
        self.pfc2 = nn.Linear(100,64)
        #self.pfca = nn.Linear(64,100)
        self.pfc3 = nn.Linear(64,232)

    def forward(self,x):
        # shape : [1,n]

        symbolCount = 0
        # 1.step:
        X = torch.tensor(x)
        wvectors = self.wordvecs(X)[0]

        q = self.pfc3(self.pfc2(self.pfc1(wvectors)))
        embeds =attention(q,wvectors)
        embeds = torch.reshape(embeds,[1,-1,232])
        reserves = []
        # 2.step:
        for i in range(len(x[0])):
            item = x[0][i]
            word = data.tokenizer_en.sequences_to_texts([[item]])
            if ("symbol" in word[0]):
                reserves.append(i)

        # 3.step:
        symbols = embeds[0][idx]
        symbols = torch.reshape(symbols,[1,-1])
        for i in range(len(reserves)-1):
            symbols = torch.cat([symbols,torch.reshape(embeds[0][i+1],[1,-1])],0)

        return torch.tensor(symbols)

class Parser(nn.Module):
    def __init__(self,op_dim = 232, args_dim = 64,state_dim = 256,word_dim = 232, vocab = 10000):
        super(Parser, self).__init__()

        # create a list of vectors representing operators and words
        self.wordvecs = nn.Embedding(vocab, word_dim)
        self.op_vecs = nn.Embedding(vocab, op_dim)
        self.arg_vecs = nn.Embedding(vocab, args_dim)

        # Input of this model will be a set of embeddings of the operator

        # Recreate operators using pytorch
        self.state_dim = state_dim
        self.args_dim = args_dim
        self.op_dim = op_dim
        self.word_dim = word_dim

        # Synthesis methods required
        self.log_p = 0
        self.count = 0
        self.program = ""

        # to create the probability analyzer unit
        self.pfc1 = nn.Linear(state_dim,100)
        self.pfc2 = nn.Linear(100,64)
        #self.pfca = nn.Linear(64,100)
        self.pfc3 = nn.Linear(64,word_dim)
        # to create the repeater unit
        self.rfc1 = nn.Linear(args_dim+state_dim,200)
        self.rfc2 = nn.Linear(200,100)
        self.rfc3 = nn.Linear(100,state_dim)
        # Gated recurrential unit
        self.fGRU = torch.nn.GRU(word_dim,state_dim,1)
        self.bGRU = torch.nn.GRU(state_dim,state_dim,1)
        self.namo = "Math-Reaver"

        self.words = None
        self.attention_data = []
        self.DSL =MathDSL

        self.STCM = []
        self.sn = SymbolNet("LilRag")

    def attention(self,q,words):
        att = torch.softmax(torch.matmul(words,q.permute(1,0)),-2)
        self.attention_data.append(att)
        return torch.matmul(att.permute(1,0),words)

    def pdf_ops(self,opp,order_state):
        # shape of input variables are [num, embed_dim]
        # output will be the pdf tensor and the argmax position

        query = F.tanh(self.pfc1(order_state))
        query = F.softplus(self.pfc2(query))
        query = F.softplus(self.pfc3(query))

        fused = self.attention(query,self.words)

        #create pdf tensor

        pdf = torch.matmul(fused,opp.permute(1,0))

        pdf = torch.softmax(pdf,-1)[0]

        #index of the maximum operator is
        index = np.argmax(pdf.detach().numpy())
        return pdf, index

    def repeat_vector(self,semantics,arg):
        # Create next semantics vector for the argument
        r = torch.cat([semantics,arg],-1)
        r = F.tanh(self.rfc1(r))
        r = F.softplus(self.rfc2(r))
        r = F.tanh(self.rfc3(r))

        return r

    def convert(self,x,words):
        self.attention_data = []
        self.words = words
        # Start the parsing process
        self.log_p = 0
        self.program = ""
        self.count = 0
        def parse(s,arg,ops,ops_dict):
            # analogue goal-based policy in multi-goal RL
            # estimate the action to take when given the state (s) and the goal (arg)
            parse_state = self.repeat_vector(s,arg)
            # 1. create a state given the current state and the goal given
            pdf,index = self.pdf_ops(ops,parse_state)
            #index = ops_dict.index(ops_sequence[self.count])

            self.log_p  = self.log_p - torch.log(pdf[index])

            operator = ops_dict[index+1]
            self.program += str(operator)
            self.count += 1
            #print(ops_dict,index)
            # 2. pass the semantics down to next level if required

            if operator in self.DSL.arged_ops:
                self.program +=  "("

                args = self.DSL.arg_dict[operator]
                args_paramed = self.arg_vecs(torch.tensor(args))

                for i in range(len(args)):

                    if self.count < 35:
                        parse(parse_state,torch.reshape(args_paramed[i],[1,self.args_dim]),ops,ops_dict)
                    else:
                        self.program+="RandO"
                    if i != (len(args)-1):
                        self.program += ","
                self.program += ")"

        root = self.arg_vecs(torch.tensor([0]))
        ops = self.op_vecs(torch.tensor(self.DSL.ops))
        ops= torch.cat([ops,self.STCM],0)

        # TODO: dynamic library useage during the parsing
        operators = []
        operators.extend(self.DSL.operators)
        operators.extend(self.STOP)
        # TODO: dynamic library useage during the parsing
        parse(x,root,ops,operators)
        return self.program,self.log_p

    def program_prob(self,x,ops_sequence,words):
        self.attention_data = []
        self.words = words
        # Start the parsing process
        self.log_p = 0
        self.count = 0
        self.program = ""

        def parse(s,arg,ops,ops_dict,ops_sequence):
            # analogue goal-based policy in multi-goal RL
            # estimate the action to take when given the state (s) and the goal (arg)
            parse_state = self.repeat_vector(s,arg)
            # 1. create a state given the current state and the goal given

            pdf,index = self.pdf_ops(ops,parse_state)
            index = ops_dict.index(ops_sequence[self.count])

            self.log_p  = self.log_p - torch.log(pdf[index-1])
            operator = ops_dict[index]

            self.program += str(operator)

            # 2. pass the semantics down to next level if required
            self.count += 1

            if operator in self.DSL.arged_ops:
                self.program +=  "("

                args = self.DSL.arg_dict[operator]
                args_paramed = self.arg_vecs(torch.tensor(args))

                for i in range(len(args)):

                    if self.count < 35:
                        parse(parse_state,torch.reshape(args_paramed[i],[1,self.args_dim]),ops,ops_dict,ops_sequence)
                    else:
                        self.program+="RandO"
                    if i != (len(args)-1):
                        self.program += ","
                self.program += ")"

        root = self.arg_vecs(torch.tensor([0]))
        ops = self.op_vecs(torch.tensor(self.DSL.ops))
        ops= torch.cat([ops,self.STCM],0)

        # TODO: dynamic library useage during the parsing
        operators = []
        operators.extend(self.DSL.operators)
        operators.extend(self.STOP)

        parse(x,root,ops,operators,ops_sequence)
        return self.program,self.log_p

    def save_model(self):
        dirc = "D:/Omegas/" + str(self.namo) + "/"
        torch.save(self, dirc+self.namo + '.pth')

    def load_model(self):
        dirc = "D:/Omegas/" + str(self.namo) + "/"
        try:
            self = torch.load(dirc+self.namo + '.pth')
        except:
            print("Failed")

    def run(self,x,symbols,seq = None):
        self.STCM = self.sn(x)
        self.STOP = symbols
        sequence = self.wordvecs(torch.tensor(x))

        results,hidden  = self.fGRU(sequence)
        final_r,final_h = self.bGRU(hidden)

        hidden = torch.reshape(final_h,[final_h.shape[1],self.state_dim])
        semantics = torch.reshape(hidden[hidden.shape[0]-1],[1,self.state_dim])
        if seq != None:
            program,loss  = self.program_prob(semantics,seq,sequence[0])
        else:
            program,loss = self.convert(semantics,sequence[0])
        return program, loss

    def train(self,tasks,EPOCH,rate = 8e-5):
       optimizer =torch. optim.Adam(psr.parameters(), lr=rate)
       for epoch in range(EPOCH):
           Loss = 0.0
           for i in range(len(tasks)):
               seq = tasks[i][0]
               #print(tasks[i][1])
               #print(tasks[i][2])
               print(data.tokenizer_en.sequences_to_texts(tasks[i][0]))

               pro,loss = psr.run(seq,tasks[i][3],tasks[i][1])
               print("Program:",pro)
               print("Loss:",loss.detach().numpy())
               Loss += loss/10
               print(" ")
           optimizer.zero_grad()
           Loss.backward()
           optimizer.step()
           if epoch%100 == 0:
               print("EPOCH:",epoch,"Loss is ",Loss.detach().numpy())

def visualize_masks(masks):
    try:
        img = torch.cat([masks[0],masks[1]],-1)

        for i in range(len(masks)-2):
            img = torch.cat([img,masks[i+2]],-1)
    except:
        img = masks[0]
    img = img.permute(1,0)
    plt.cla()
    plt.imshow((img.view(1,masks.shape[0])).detach().numpy(),'bone')
    plt.pause(0.01)

def visualize_attention(att):
    plt.cla()
    try:
        img = torch.cat([att[0],att[1]],-1)
        for i in range(len(att)-2):
            img = torch.cat([img,att[i+2]],-1)
    except:
        img = att[0]

    plt.imshow(img.detach().numpy())
    plt.pause(1)

psr = Parser()
tasks = data.train_set[:10]
from karazhan.curator import *

tasks = data.make_tasks(ArithMatics)
psr.train(tasks,3000, 1e-4)

psr.run(tasks[0][0],tasks[0][3])
psr.run(data.convert_to_data(p),extract_symbols(p))

from sklearn.manifold import TSNE

tsne = TSNE(n_components=2)


'''
Given a binary tree, find the largest subtree which is a Binary Search Tree (BST), where largest means subtree with largest number of nodes in it.

Note:
A subtree must include all of its descendants.

Example:

Input: [10,5,15,1,8,null,7]

   10
   / \
  5  15
 / \   \
1   8   7

Output: 3
Explanation: The Largest BST Subtree in this case is the highlighted one.
             The return value is the subtree's size, which is 3.

来源：力扣（LeetCode）
链接：https://leetcode-cn.com/problems/largest-bst-subtree
著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。
'''

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

'''
For each subtree, we return 4 elements.

the status of this subtree, 1 means it's empty, 2 means it's a BST, 0 means it's not a BST
size of this subtree (we only care about size of BST though)
the minimal value in this subtree
the maximal value in this subtree
'''
class Solution:
    def largestBSTSubtree(self, root: TreeNode) -> int:
        res = 0
        def helper(node): # return status of bst, size of bst, left bound and right bound
            nonlocal res
            if not node:
                return 1, 0, None, None
            ls, l, ll, lr = helper(node.left)
            rs, r, rl, rr = helper(node.right)
            if (ls == 2 and node.val > lr or ls == 1) and (rs == 2 and node.val < rl or rs == 1):
                res = max(res, l + r + 1)
                return 2, l + r + 1, ll if ll else node.val, rr if rr else node.val
            return 0, 0, None, None
        helper(root)
        return res


#Please write a function named range_of_list, which takes a list of integers as an argument. The function
#  returns the difference between the smallest and the largest value in the list.

# Write your solution here
def range_of_list(lst: list):
    smallest = min(lst)
    largest = max(lst)
    difference = largest - smallest
    return difference
# You can test your function by calling it within the following block
if __name__ == "__main__":
    my_list = [3, 6, -4]
    result = range_of_list(my_list)
    print(result)
    my_list2 = [1, 2, 3, 4, 5]
    result2 = range_of_list(my_list2)
    print(f"The range of the list is {result2}")

#examples of output
# 10
# The range of the list is 4

University Of Helsinki/Python Course/Introduction to Programming/Part 4/4.19 range_of_list/src/range_of_list.py


import numpy as np # linear algebra
import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)
import matplotlib.pyplot as plt
import seaborn as sns
import matplotlib.ticker as ticker
import os
import json
from itertools import chain

def read_data_without_genre():
    return pd.read_csv('data/data.csv')

def read_data_with_genre():
    return pd.read_csv('data/spotify_data_by_genres.csv')

def get_top_ten_artists():
    data_without_genre = read_data_without_genre()
    del data_without_genre['Unnamed: 0']

    # get data of year 2020
    data_of_year_2020 = data_without_genre[data_without_genre['year'] == 2020]

    # cleaning the memory
    del data_without_genre

    # data cleaning
    data_of_year_2020['artists'] = data_of_year_2020.artists.str.replace('[', '').str.replace(
        ']', '').str.replace('\'', '').str.replace('"', '').str.strip()

    # data conversion to required format and conversion into new dataframe
    artists_popularity_of_year_2020 = pd.concat([pd.Series(row['popularity'], row['artists'].split(','))
                    for _, row in data_of_year_2020.iterrows()]).reset_index()

    del data_of_year_2020
    artists_popularity_of_year_2020.columns = ['Artists', 'Popularity']

    # data cleaning
    artists_popularity_of_year_2020['Artists'] = artists_popularity_of_year_2020['Artists'].str.title().str.strip()

    # calculation of popularity and sorting in required format
    top_ten_artists_df = artists_popularity_of_year_2020.groupby('Artists').mean().reset_index().sort_values(['Popularity'],
                         ascending=[0]).head(10)

    # cleaning the memory
    del top_ten_artists_df['Popularity'], artists_popularity_of_year_2020
    return list(chain.from_iterable(json.loads(top_ten_artists_df.to_json(orient='values'))))

def get_average_duration_of_songs(number_of_popular_songs=10):
    data_without_genre = read_data_without_genre()
    del data_without_genre['Unnamed: 0']

    # get data of year 2020
    data_of_year_2020 = data_without_genre[data_without_genre['year'] == 2020]
    del data_without_genre
    # data cleaning
    name_popularity_duration_of_year_2020 = pd.concat([data_of_year_2020['name'], data_of_year_2020['popularity'],
                                                      data_of_year_2020['duration_ms']], axis=1)
    del data_of_year_2020
    name_popularity_duration_of_year_2020['name'] = name_popularity_duration_of_year_2020['name'].str.title().str.strip()
    top_songs_df = name_popularity_duration_of_year_2020.groupby('name').mean().reset_index().sort_values(['popularity'],
                                                                ascending=[0])
    del top_songs_df['name'], top_songs_df['popularity'], name_popularity_duration_of_year_2020
    return (sum(list(chain.from_iterable(json.loads(top_songs_df.to_json(orient='values'))))[0: number_of_popular_songs])
                    / number_of_popular_songs)


to_cryp=open("tj.txt","r").read().split("\n")
key= open("klucze1.txt","r").read().split("\n")
key_cryp={}
result=open("wynik4a.txt","w+")
alphabet = "abcdefghijklmnopqrstuvwxyz".upper()

for i in range(0,120):
    key_cryp[key[i]]=to_cryp[i]

for combination in key_cryp:
    word =key_cryp[combination]
    key = combination
    if(len(word)>len(key)):
        key+=key*(len(word)-len(key))
    word_to_save=""
    for i in range(0,len(word)):
        new=ord(word[i])+alphabet.find(key[i])+1
        if(new > 90):
            new-=26
        word_to_save+=chr(new)
    result.write(word_to_save+"\n")
# b
to_encryp=open("sz.txt","r").read().split("\n")
key= open("klucze2.txt","r").read().split("\n")
result=open("wynik4b.txt","w+")
key_encryp={}
for i in range(0,120):
    key_encryp[key[i]]=to_encryp[i]

for combination in  key_encryp:
    word = key_encryp[combination]
    key = combination
    word_to_save = ""
    if (len(word) > len(key)):
        key += key * (len(word) - len(key))
    for i in range(0, len(word)):
        new = ord(word[i]) - (alphabet.find(key[i]) + 1)
        if (new < 65 ):
            new += 26
        print(new)
        word_to_save += chr(new)
    result.write(word_to_save + "\n")