# -*- coding: utf-8 -*-
"""
Created on Mon Sep 19 18:30:04 2016

@author: george
"""
import matplotlib
#matplotlib.use('Agg')
import os
import numpy as np
from skimage import io,transform,morphology
import re
from dataprovider.preprocess import vgg_preprocess, reverse_vgg_preprocess
from dataprovider.davis import DataAccessHelper
from dataprovider.transformer_rand import ImageRandomTransformer
from numpy import dtype, size
import random

import matplotlib.pyplot as plt
from binstar_client.utils.notebook.data_uri import Image
from dataprovider import inputhelper
from common import diskutils
import glob

IMAGE_HEIGHT = 480
IMAGE_WIDTH = 854

davis = DataAccessHelper()
def prepare_input_ch7(image_path, prev_mask, offset):

    assert offset<=0 ,"check offset .."
    # Read image
    img = davis.read_image(image_path, [IMAGE_HEIGHT,IMAGE_WIDTH])
    img = img*255

    mask = np.expand_dims(prev_mask,axis=2)

    # Read previous image
    if offset==0:
        name, frame_no = davis.split_path(image_path)
        prev_img_path = davis.image_path(name, 0)
    else:
        prev_img_path = davis.construct_image_path(image_path, offset= offset)

    prev_img = davis.read_image(prev_img_path, [IMAGE_HEIGHT,IMAGE_WIDTH])
    prev_img = prev_img*255

    # Concatenate images
    inp_img =  np.concatenate((img, mask,prev_img), 2)

    # Apend axis for batch size
    inp_img = np.expand_dims(inp_img,axis=0)

    inp_img = vgg_preprocess(inp_img)

    return inp_img

class InputProvider:

    BASE_DIR = os.path.join('/work/george','DAVIS')
    IMAGESETS = os.path.join('ImageSets','480p')

    NUM_CHANNELS = 7

    COARSE_OUT_HEIGHT = 56
    COARSE_OUT_WIDTH = 56

    def __init__(self, offsets = None,is_dummy = False,db_type = 0):

        self.davis = DataAccessHelper()
        self.resize = [IMAGE_HEIGHT,IMAGE_WIDTH]

        self.train_set_info = np.loadtxt(os.path.join(self.BASE_DIR,\
                        self.IMAGESETS,'train.txt'), dtype=bytes,unpack=False).astype(str)
        self.val_set_info = np.loadtxt(os.path.join(self.BASE_DIR,\
                        self.IMAGESETS,'val.txt'), dtype=bytes,unpack=False).astype(str)
        #self.val_set_info = self.val_set_info[:419,:]
        train_db_name = 'train'
        val_db_name = 'val'
        if is_dummy:
            train_db_name = 'dummy_train'
            val_db_name = 'dummy_val'
            self.train_set_info = self.train_set_info[247:255,:]
            self.val_set_info = self.val_set_info[247:255,:]

        #offsets = [1]

        self.offsets = offsets#list(range(1,7))#[10]

        if (db_type ==0):
            self.db = self.createDB0(self.train_set_info,name = train_db_name)
            self.validation_db = self.createDB0(self.val_set_info,name = val_db_name)

        else:
            self.db = self.createDB(self.train_set_info,name = train_db_name,offsets=offsets)
            #self.db = self.create_train_DB2(train_db_name,offsets)

            #half_db_name = "segnetvggwithskip-half-wl-osvos-O10-1-O10-1"
            #prev_mask_dir = os.path.join("..","Results",half_db_name,"480p")
            #self.db = self.create_train_DB3(name=half_db_name,
            #            prev_mask_dir=prev_mask_dir,offsets=offsets)

            self.validation_db = self.createDB(self.val_set_info,name = val_db_name,offsets=offsets)

    class DB:
        def __init__(self,):
            pass

    class DataBatch:pass

    class DataIterator:

        def __init__(self,db, batch_size,is_training=True):
            self.db=db
            self.is_training = is_training
            numImages = self.db.images.shape[0]
            self.img_size = list(self.db.images.shape[1:3])
            #self.weights_size = list(self.db.weights.shape[1:3])
            self.img_channels = self.db.images.shape[3]
            self.sequence_info = np.random.permutation(list(range(numImages)))
            self.index = 0
            self.batch_size = batch_size
            self.transformer = ImageRandomTransformer(self._get_transform_config())

        def _get_transform_config(self):
            config ={}
            config[ImageRandomTransformer.CONFIG_ROTATION_RANGE] =[-10,10]
            config[ImageRandomTransformer.CONFIG_ROTATION_ANGLE_STEP] = None
            config[ImageRandomTransformer.CONFIG_SHEAR_RANGE] = [-5,5]
            config[ImageRandomTransformer.CONFIG_SHEAR_ANGLE_STEP] = None
            config[ImageRandomTransformer.CONFIG_SCALE_FACTOR_RANGE] = [1.0,2.0]
            config[ImageRandomTransformer.CONFIG_TRANSLATION_FACTOR_STEP] = 0.1
            config[ImageRandomTransformer.CONFIG_TRANSLATION_FACTOR_RANGE] = [-0.2,0.2]

            return config

        def __iter__(self):
            return self

        def __next__(self):
            if self.index < len(self.sequence_info):

                toIndex = self.index+self.batch_size

                selected_indexes = self.sequence_info[self.index:toIndex]

                # Read images and labels
                images = np.zeros([self.batch_size]+self.img_size+[self.img_channels],dtype = np.float32)
                labels = np.zeros([self.batch_size]+self.img_size)
                weights = np.empty([self.batch_size]+self.img_size,dtype=np.float32)
                for i,idx in enumerate(selected_indexes):
                    label_dim = np.expand_dims(self.db.labels[idx,:,:], axis=2)
                    stked = np.concatenate((self.db.images[idx,:,:,:],label_dim),axis = 2)
                    #import pdb
                    #pdb.set_trace()
                    stked,_ = self.transformer.get_random_transformed(stked)
                    image = stked[:,:,0:7]
                    if self.is_training:
                        image = self.process_prev_mask_in_image(image)

                    label = np.uint8(stked[:,:,7])
                    ## Label as changes
                    prev_mask = np.uint8(stked[:,:,3])
                    #label_changes = inputhelper.get_dilated(label)
                    #label = label_changes
#                     plt.figure()
#                     plt.subplot(3,1,1)
#                     plt.imshow(label)
#                     plt.subplot(3,1,2)
#                     plt.imshow(prev_mask)
#                     plt.subplot(3,1,3)
#                     plt.imshow(label_changes)
#                     plt.colorbar()
                    #self._debug(image,label)
                    images[i,:,:,:]=image
                    labels[i,:,:]=label
                    if (np.count_nonzero(images[i,:, :, 3]) == 0):
                        print("warning :imgprovider previmg all zeros")
                        labels[i, :, :] = 0

                    #weights[i,:,:] = inputhelper.get_distance_transform(label)

                    weights[i,:,:] = inputhelper.get_weights_classwise_osvos(label)
                    #weights[i,:,:] = inputhelper.get_weights_osvos_distance(label)

                    #weights[i,:,:] = inputhelper.get_weights_classwise2(label,factor=3)

                    #plt.figure()
                    #plt.subplot(2,1,1)
                    #plt.imshow(weights[i,:,:])
                    #plt.colorbar()
                    #plt.subplot(2,1,2)
                    #plt.imshow(label)
                    #plt.colorbar()
                    #self._debug(image,label)

                #images = self.db.images[selected_indexes,:,:,:]
                #labels = self.db.labels[selected_indexes,:,:]
                #weights = self.db.weights[selected_indexes,:,:]

                images = (images*255)
                images = vgg_preprocess(images)

                # Prepare data batch
                batch = InputProvider.DataBatch()
                batch.images = images
                batch.labels = labels
                batch.weights = weights
                self.index += self.batch_size
                return batch
            else:
                raise StopIteration()

        def _debug(self,img,label):
            plt.subplot(2,2,1)
            frame = plt.gca()
            frame.axes.set_title('Img')
            frame.axes.get_xaxis().set_visible(False)
            frame.axes.get_yaxis().set_visible(False)
            plt.imshow(np.uint8(img[:,:,0:3]*255))
            plt.subplot(2,2,2)
            frame = plt.gca()
            frame.axes.set_title('Prev Img')
            frame.axes.get_xaxis().set_visible(False)
            frame.axes.get_yaxis().set_visible(False)
            plt.imshow(np.uint8(img[:,:,4:7]*255))
            plt.subplot(2,2,3)
            frame = plt.gca()
            frame.axes.get_xaxis().set_visible(False)
            frame.axes.get_yaxis().set_visible(False)
            plt.imshow(np.uint8(label))
            plt.subplot(2,2,4)
            frame = plt.gca()
            frame.axes.get_xaxis().set_visible(False)
            frame.axes.get_yaxis().set_visible(False)
            plt.imshow(img[:,:,3])

        def get_data(self,selected_indexes):
            if self.is_training:
                pass
            else:
                pass
                #image = transform.resize(image,resize)
                #return

        def process_prev_mask_in_image(self,image):
            MASK_CHANNEL = 3
            prev_mask = image[:,:,MASK_CHANNEL]
                #plt.figure()
                #plt.subplot(1,2,1)
                #plt.imshow(prev_mask)
            prev_mask_mod = self.add_noise_prev_mask(prev_mask)
            image[:,:,MASK_CHANNEL] = np.round(prev_mask_mod)

                #plt.subplot(1,2,2)
                #plt.imshow(prev_mask_mod)
                #plt.show()
            return image

        def process_prev_mask_in_images(self,images):
            MASK_CHANNEL = 3
            for i in range(0,size(images,0)):
                prev_mask = images[i,:,:,MASK_CHANNEL]
                #plt.figure()
                #plt.subplot(1,2,1)
                #plt.imshow(prev_mask)
                prev_mask_mod = self.add_noise_prev_mask(prev_mask)
                images[i,:,:,MASK_CHANNEL] = np.round(prev_mask_mod)

                #plt.subplot(1,2,2)
                #plt.imshow(prev_mask_mod)
                #plt.show()
            return images

        def add_noise_prev_mask(self,prev_mask):
            ERODE = 'Erode'
            DILATE = 'Dilate'
            NONE_ = 'None'
            options = [ERODE,DILATE,NONE_]
            #options = [NONE_]
            ch = random.choice(options)
            if ch == ERODE:
                sz = random.randint(2,4)
                new_mask = morphology.erosion(prev_mask,np.ones([sz,sz]))
                return new_mask
            elif ch == DILATE:

                sz = random.randint(2,4)
                new_mask = morphology.dilation(prev_mask,np.ones([sz,sz]))
                return new_mask
            else :
                return prev_mask

    def sequence_batch_itr(self, batch_size):
        return self.DataIterator(self.db, batch_size)

    def val_seq_batch_itr(self, batch_size):
        return self.DataIterator(self.validation_db, batch_size,is_training=False)

    def getPrevMaskFile(self,labelFile):
        m=re.match(r"(/.*/.*/.*/)(.*).png",labelFile)
        prefix = m.group(1)
        frameNo = int(m.group(2))
        maskFrameNo = frameNo-1 if frameNo -1 >=0 else 0

        prevMaskFile='{0}{1:05}.png'.format(prefix,maskFrameNo)
        return prevMaskFile

    def create_train_DB2(self, name='',offsets=[]):

        print("Creating DB2 with offsets:{} ".format(offsets))
        #offsets = [1] # list(range(1,7))
        # import cPickle as pickle
        # cached_db = '/work/george/cache/davisdb.pickle'
        offset_string = "-".join(str(x) for x in offsets)
        base_dir = os.path.join('/work/george/cache/db-half/offset-{}/'.format(offset_string), name)
        images_cached_file = os.path.join(base_dir, 'images_db.npy')
        labels_cached_file = os.path.join(base_dir, 'labels_db.npy')

        if not (os.path.isfile(images_cached_file) and os.path.isfile(labels_cached_file)):

            print("cached db not found. preparing memmap ...")

            diskutils.ensure_dir(base_dir)

            if (os.path.isfile(images_cached_file)):
                print("please clean cache file : ", images_cached_file)
                return
            if (os.path.isfile(labels_cached_file)):
                print("please clean cache file : ", labels_cached_file)
                return

            seqs = davis.train_sequence_list()
            tmp_files_dir = os.path.join(base_dir, 'temp')
            diskutils.ensure_dir(tmp_files_dir)

            for seq in seqs:
                frames = davis.all_frames_nums(seq)
                mid = int(max(frames)/2)
                print("train: for seq:{} using frames {} to {}".format(seq,min(frames)+1,mid))
                for frame_no in range(min(frames)+1,mid+1):
                    for offset in offsets:
                        imageFile = davis.image_path(seq, frame_no)
                        labelFile = davis.label_path(seq, frame_no)
                        # prevMaskFile = self.getPrevMaskFile(labelFile)
                        image = self.read_image2(imageFile, offset=offset)
                        if (np.count_nonzero(image[:, :, 3]) == 0):
                            print("skipping image all zeros: {}".format(imageFile))
                            continue
                        label = self.davis.read_label(labelFile, self.resize)
                        outfile = os.path.join(tmp_files_dir, 'file-{}-{}-o{}.npz'.format(seq, frame_no, offset))
                        np.savez(outfile, image=image, label=label)

            self.create_memmap_db(tmp_files_dir,images_cached_file,labels_cached_file)

        print("loading readonly memmap...")

        db = InputProvider.DB()

        # db.images = np.memmap(images_cached_file, dtype='float32', mode='r', shape=tuple([num_db_images]+self.resize+[SampleInputProvider.NUM_CHANNELS]))
        # db.labels = np.memmap(labels_cached_file, dtype='float32', mode='r', shape=tuple([num_db_images] + self.resize))

        db.images = np.load(images_cached_file, mmap_mode='r')
        db.labels = np.load(labels_cached_file, mmap_mode='r')

        print("db memmap loaded...")

        return db

    def create_train_DB3(self, name='',prev_mask_dir = None, offsets = []):

        print("Creating DB3 with offsets {} prev_mask_folder:{}".format(offsets,prev_mask_dir))

        #offsets = [1] # list(range(1,7))
        offset_string = "-".join(str(x) for x in offsets)
        base_dir = os.path.join('/work/george/cache/db3/offset-{}/'.format(offset_string), name)
        images_cached_file = os.path.join(base_dir, 'images_db.npy')
        labels_cached_file = os.path.join(base_dir, 'labels_db.npy')

        if not (os.path.isfile(images_cached_file) and os.path.isfile(labels_cached_file)):

            print("cached db not found. preparing memmap ...")

            diskutils.ensure_dir(base_dir)

            if (os.path.isfile(images_cached_file)):
                print("please clean cache file : ", images_cached_file)
                return
            if (os.path.isfile(labels_cached_file)):
                print("please clean cache file : ", labels_cached_file)
                return

            seqs = davis.train_sequence_list()
            tmp_files_dir = os.path.join(base_dir,'temp')
            diskutils.ensure_dir(tmp_files_dir)

            for offset in offsets:
                for seq in seqs:
                    frames = davis.all_frames_nums(seq)
                    mid = int(max(frames)/2)
                    print("train: for seq:{} using frames {} to {}".format(seq,min(frames)+1,mid))
                    for frame_no in range(mid+1,max(frames)+1):

                            imageFile = davis.image_path(seq, frame_no)
                            labelFile = davis.label_path(seq, frame_no)
                            prev_mask_file = inputhelper.prev_mask_path(prev_mask_dir,seq,frame_no,offset)
                            prev_mask = inputhelper.read_label(prev_mask_file,self.resize)
                            image = self.read_image2(imageFile, offset=offset,prev_mask=prev_mask)
                            if (np.count_nonzero(image[:, :, 3]) == 0):
                                print("skipping image all zeros: {}".format(imageFile))
                                continue
                            label = self.davis.read_label(labelFile, self.resize)
                            outfile = os.path.join(tmp_files_dir, 'file-{}-{}-o{}.npz'.format(seq,frame_no, offset))
                            np.savez(outfile, image=image, label=label)

            self.create_memmap_db(tmp_files_dir,images_cached_file,labels_cached_file)

        print("loading readonly memmap...")

        db = InputProvider.DB()

        # db.images = np.memmap(images_cached_file, dtype='float32', mode='r', shape=tuple([num_db_images]+self.resize+[SampleInputProvider.NUM_CHANNELS]))
        # db.labels = np.memmap(labels_cached_file, dtype='float32', mode='r', shape=tuple([num_db_images] + self.resize))

        db.images = np.load(images_cached_file, mmap_mode='r')
        db.labels = np.load(labels_cached_file, mmap_mode='r')

        print("db memmap loaded...")

        return db

    def prepare_temp_files_0(self,data_set_info,out_dir):
        num_images = data_set_info.shape[0]
        for i in range(num_images):
                imageFile = data_set_info[i, 0]
                imageFile = imageFile[1:]
                labelFile = data_set_info[i, 1]
                labelFile = labelFile[1:]
                # prevMaskFile = self.getPrevMaskFile(labelFile)
                image = self.read_image0(imageFile)
                if (np.count_nonzero(image[:, :, 3]) == 0):
                    print("skipping image all zeros: {}".format(imageFile))
                    continue
                label = self.davis.read_label(labelFile, self.resize)
                outfile = os.path.join(out_dir,'file-{}.npz'.format(i))
                np.savez(outfile,image=image,label=label)

    def prepare_temp_files(self,data_set_info,offsets,out_dir):
        num_images = data_set_info.shape[0]
        for i in range(num_images):
            for offset in offsets:
                imageFile = data_set_info[i, 0]
                imageFile = imageFile[1:]
                labelFile = data_set_info[i, 1]
                labelFile = labelFile[1:]
                # prevMaskFile = self.getPrevMaskFile(labelFile)
                image = self.read_image2(imageFile, offset=offset)
                if (np.count_nonzero(image[:, :, 3]) == 0):
                    print("skipping image all zeros: {}".format(imageFile))
                    continue
                label = self.davis.read_label(labelFile, self.resize)
                outfile = os.path.join(out_dir,'file-{}-o{}.npz'.format(i,offset))
                np.savez(outfile,image=image,label=label)

    def createDB0(self, data_set_info, name=''):
        print("Creating DB0 ")
        base_dir = os.path.join('/work/george/cache/db-480p/0/', name)
        images_cached_file = os.path.join(base_dir, 'images_db.npy')
        labels_cached_file = os.path.join(base_dir, 'labels_db.npy')
        num_images = data_set_info.shape[0]

        if not (os.path.isfile(images_cached_file) and os.path.isfile(labels_cached_file)):

            print("cached db not found. preparing memmap ...")

            diskutils.ensure_dir(base_dir)

            if (os.path.isfile(images_cached_file)):
                print("please clean cache file : ", images_cached_file)
                return
            if (os.path.isfile(labels_cached_file)):
                print("please clean cache file : ", labels_cached_file)
                return

            # Prepare temporary files for reading
            tmp_files_dir = os.path.join(base_dir, "temp")
            diskutils.ensure_dir(tmp_files_dir)

            self.prepare_temp_files_0(data_set_info, tmp_files_dir)

            # Create the database
            all_files = glob.glob(os.path.join(tmp_files_dir, "*.npz"))
            num_db_images = len(all_files)
            # images_mmap = np.memmap(images_cached_file, dtype='float32', mode='w+',
            #                        shape=tuple([num_db_images] + self.resize + [SampleInputProvider.NUM_CHANNELS]))
            # labels_mmap = np.memmap(labels_cached_file, dtype='float32', mode='w+',
            #                        shape=tuple([num_db_images] + self.resize))
            images_mmap = np.lib.format.open_memmap(images_cached_file, dtype='float32', mode='w+',
                                                    shape=tuple(
                                                        [num_db_images] + self.resize + [InputProvider.NUM_CHANNELS]))
            labels_mmap = np.lib.format.open_memmap(labels_cached_file, dtype='float32', mode='w+',
                                                    shape=tuple([num_db_images] + self.resize))

            self.create_memmap_db(tmp_files_dir, images_cached_file, labels_cached_file)

        print("loading readonly memmap...")

        db = InputProvider.DB()

        # db.images = np.memmap(images_cached_file, dtype='float32', mode='r', shape=tuple([num_db_images]+self.resize+[SampleInputProvider.NUM_CHANNELS]))
        # db.labels = np.memmap(labels_cached_file, dtype='float32', mode='r', shape=tuple([num_db_images] + self.resize))

        db.images = np.load(images_cached_file, mmap_mode='r')
        db.labels = np.load(labels_cached_file, mmap_mode='r')

        print("db memmap loaded...")

        return db

    def createDB(self,data_set_info,name='',offsets=[]):
        print("Creating DB with offsets: {}".format(offsets))
        #offsets = list(range(1,7))
        #import cPickle as pickle
        #cached_db = '/work/george/cache/davisdb.pickle'
        offset_string = "-".join(str(x) for x in offsets)
        base_dir = os.path.join('/work/george/cache/db-480p/offset-{}/'.format(offset_string),name)
        images_cached_file = os.path.join(base_dir,'images_db.npy')
        labels_cached_file = os.path.join(base_dir,'labels_db.npy')
        num_images = data_set_info.shape[0]

        if not (os.path.isfile(images_cached_file) and os.path.isfile(labels_cached_file)):

            print("cached db not found. preparing memmap ...")

            diskutils.ensure_dir(base_dir)

            if(os.path.isfile(images_cached_file)):
                print("please clean cache file : ",images_cached_file)
                return
            if (os.path.isfile(labels_cached_file)):
                print("please clean cache file : ", labels_cached_file)
                return

            #Prepare temporary files for reading
            tmp_files_dir = os.path.join(base_dir,"temp")
            diskutils.ensure_dir(tmp_files_dir)

            self.prepare_temp_files(data_set_info,offsets,tmp_files_dir)

            # Create the database
            all_files = glob.glob(os.path.join(tmp_files_dir,"*.npz"))
            num_db_images = len(all_files)
            #images_mmap = np.memmap(images_cached_file, dtype='float32', mode='w+',
            #                        shape=tuple([num_db_images] + self.resize + [SampleInputProvider.NUM_CHANNELS]))
            #labels_mmap = np.memmap(labels_cached_file, dtype='float32', mode='w+',
            #                        shape=tuple([num_db_images] + self.resize))
            images_mmap = np.lib.format.open_memmap(images_cached_file, dtype='float32', mode='w+',
                                    shape=tuple([num_db_images] + self.resize + [InputProvider.NUM_CHANNELS]))
            labels_mmap = np.lib.format.open_memmap(labels_cached_file, dtype='float32', mode='w+',
                                    shape=tuple([num_db_images] + self.resize))

            self.create_memmap_db(tmp_files_dir,images_cached_file,labels_cached_file)

        print("loading readonly memmap...")

        db = InputProvider.DB()

        #db.images = np.memmap(images_cached_file, dtype='float32', mode='r', shape=tuple([num_db_images]+self.resize+[SampleInputProvider.NUM_CHANNELS]))
        #db.labels = np.memmap(labels_cached_file, dtype='float32', mode='r', shape=tuple([num_db_images] + self.resize))

        db.images = np.load(images_cached_file,mmap_mode='r')
        db.labels = np.load(labels_cached_file, mmap_mode='r')

        print("db memmap loaded...")

        return db

    def create_memmap_db(self,tmp_files_dir,images_cached_file,labels_cached_file):
        # Create the database
        print("creating memmap db...")

        all_files = glob.glob(os.path.join(tmp_files_dir, "*.npz"))
        num_db_images = len(all_files)
        # images_mmap = np.memmap(images_cached_file, dtype='float32', mode='w+',
        #                        shape=tuple([num_db_images] + self.resize + [SampleInputProvider.NUM_CHANNELS]))
        # labels_mmap = np.memmap(labels_cached_file, dtype='float32', mode='w+',
        #                        shape=tuple([num_db_images] + self.resize))
        images_mmap = np.lib.format.open_memmap(images_cached_file, dtype='float32', mode='w+',
                                                shape=tuple(
                                                    [num_db_images] + self.resize + [InputProvider.NUM_CHANNELS]))
        labels_mmap = np.lib.format.open_memmap(labels_cached_file, dtype='float32', mode='w+',
                                                shape=tuple([num_db_images] + self.resize))

        for i,f in enumerate(all_files):
            npzfile = np.load(f)
            image = npzfile['image']
            label = npzfile['label']

            images_mmap[i, :, :, :] = image
            labels_mmap[i, :, :] = label

        print("db:{} , num db images {}: ".format(tmp_files_dir, num_db_images))
        del images_mmap
        del labels_mmap
        print("saved db to disk...")

    def read_image0(self, image_path, prev_mask=None):

        name, frame_no = self.davis.split_path(image_path)

        prev_rgb_path = self.davis.image_path(name, 0)

        if prev_mask is None:
            prev_mask_path = self.davis.label_path(name, 0)
            prev_mask = self.davis.read_label(prev_mask_path, self.resize)
            prev_mask = inputhelper.threshold_image(prev_mask)
            #print(np.unique(prev_mask))

        rgb = self.davis.read_image(image_path, self.resize)

        #prev_mask = np.expand_dims(prev_mask, axis=2)

        prev_rgb = self.davis.read_image(prev_rgb_path, self.resize)

        inp_img = inputhelper.prepare_input_img(rgb,prev_mask,prev_rgb)

        return inp_img[0,:,:,:]

    def read_image2(self,image_path, offset = 1,prev_mask = None):

        prev_mask_offset = -offset

        prev_rgb_path = self.davis.construct_image_path(image_path, offset= prev_mask_offset)

        rgb = self.davis.read_image(image_path, self.resize)

        if prev_mask is None:
            prev_mask_path = self.davis.construct_label_path(image_path, offset = prev_mask_offset)
            prev_mask = self.davis.read_label(prev_mask_path, self.resize)

        prev_mask = np.expand_dims(prev_mask, axis=2)

        prev_rgb = self.davis.read_image(prev_rgb_path, self.resize)

        # Concatenate
        image =  np.concatenate((rgb, prev_mask,prev_rgb), 2)

        return image

    def readImage(self,imageFile,prevMaskFile):

        # Fix full file path
        rgbFile =self.BASE_DIR + imageFile
        maskFile = self.BASE_DIR + prevMaskFile

        # Read images
        rgb = io.imread(rgbFile)
        mask = io.imread(maskFile,as_grey=True)
        mask = np.expand_dims(mask,axis=2)

        # Concatenate images
        image =  np.concatenate((rgb, mask), 2)

        # Resize
        image = transform.resize(image,[self.RESIZE_HEIGHT,self.RESIZE_WIDTH])

        #io.imshow(image[:,:,0:3])

        return image

    def readLabel(self,labelFile) :
        maskFile = self.BASE_DIR + labelFile
        mask = io.imread(maskFile,as_grey=True)

        # Resize
        mask = transform.resize(mask,[self.RESIZE_HEIGHT,self.RESIZE_WIDTH])

        #io.imshow(mask)

        return mask

def _debug(img,label,save_loc = None):
    plt.subplot(2,2,1)
    frame = plt.gca()
    frame.axes.set_title('Img')
    frame.axes.get_xaxis().set_visible(False)
    frame.axes.get_yaxis().set_visible(False)
    plt.imshow(np.uint8(img[:,:,0:3]))
    plt.subplot(2,2,2)
    frame = plt.gca()
    frame.axes.set_title('Prev Img')
    frame.axes.get_xaxis().set_visible(False)
    frame.axes.get_yaxis().set_visible(False)
    plt.imshow(np.uint8(img[:,:,4:7]))
    plt.subplot(2,2,3)
    frame = plt.gca()
    frame.axes.get_xaxis().set_visible(False)
    frame.axes.get_yaxis().set_visible(False)
    plt.imshow(np.uint8(label))
    plt.subplot(2,2,4)
    frame = plt.gca()
    frame.axes.get_xaxis().set_visible(False)
    frame.axes.get_yaxis().set_visible(False)
    plt.imshow(img[:,:,3])
    if save_loc:
        plt.savefig(save_loc)

    plt.close()

def test_gen_samples():

    provider = InputProvider(offsets =[1] , is_dummy=False,db_type = 0)
    num=0
    dir = 'davis_samp_0/'
    diskutils.ensure_dir(dir)
    max_num = 1000
    batch_size = 4
    while num < max_num:
        input_batch = provider.sequence_batch_itr(batch_size)

        for i, batch in enumerate(input_batch):

            if num > max_num:
                break

            for j in range(batch_size):
                if num > max_num:
                    break
                save_loc = os.path.join(dir, '{}.png'.format(num))

                imgs= reverse_vgg_preprocess(batch.images)
                _debug(imgs[j,:,:,:],batch.labels[j,:,:],save_loc)
                print (i, 'rgb files: ')
                num+=1

if __name__ == '__main__':
    provider = InputProvider(resize=[IMAGE_HEIGHT,IMAGE_WIDTH],is_coarse=False,is_dummy=True)
    batch_size = 4
    num=0
    dir = '/tmp/davis_samp_1/'
    diskutils.ensure_dir(dir)
    max_num = 1000
    while num < max_num:
        input_batch = provider.sequence_batch_itr(batch_size)

        for i, batch in enumerate(input_batch):

            if num > max_num:
                break

            for j in range(batch_size):
                if num > max_num:
                    break
                save_loc = os.path.join(dir, '{}.png'.format(num))

                imgs= reverse_vgg_preprocess(batch.images)
                _debug(imgs[j,:,:,:],batch.labels[j,:,:],save_loc)
                print (i, 'rgb files: ')
                num+=1

    print("Done")


from collections import deque
N = int(input())
table = [list(map(int,input())) for _ in range(N)]

dx = [0,0,1,-1]
dy = [1,-1,0,0]
visited = [item[:] for item in table]
ans = []
for i in range(N):
    for j in range(N):
        if visited[i][j] == 1:
            visited[i][j] = 0
            tmp = 0
            q = deque()
            q.append((i,j))
            while q:
                x, y= q.popleft()

                for k in range(4):
                    nx = x + dx[k]
                    ny = y + dy[k]
                    if 0 <= nx < N and 0 <= ny < N:
                        if visited[nx][ny] == 1:
                            visited[nx][ny] = 0
                            q.append((nx,ny))
                            tmp+=1
            ans.append(tmp)

print(len(ans))
ans.sort()
for i in ans:
    print(i+1)


import plotly.graph_objects as go

fig = go.Figure()
data = ech_gb_rc_floored["count"]
fig.add_trace(go.Pie(labels=data.index, values=data.values, name=data.index.name))

fig.update_traces(
    textinfo="percent+label",
#     hole=0.4,
    hoverinfo="label+percent+value",
    textposition="inside",
)

fig.update_layout(
    title_text="Response codes distribution among all echidna clicks"
)
fig.show()


import logging
import mapnik
import xml.etree.ElementTree as ET
import os
import subprocess
import tempfile

# Set up logging
logging.basicConfig(format="%(asctime)s|%(levelname)s|%(message)s", level=logging.INFO)

# Parameters
shpPath = "C:/Projects/BirthsAndPregnanciesMapping/data/2014-04-24/Zanzibar/Zanzibar.shp"
epsDir = "C:/Projects/BirthsAndPregnanciesMapping/results/eps"
max_img_size = 1000 # Max width or height of output image

# Create style
stroke = mapnik.Stroke()
stroke.color = mapnik.Color(0,0,0)
stroke.width = 1.0
symbolizer = mapnik.LineSymbolizer(stroke)
rule = mapnik.Rule()
rule.symbols.append(symbolizer)
style = mapnik.Style()
style.rules.append(rule)

# Create Datasource
datasource = mapnik.Shapefile(file=shpPath)

# Create layer
layer = mapnik.Layer("boundaries")
layer.datasource = datasource
layer.styles.append("boundariesStyle")

# Calculate image output size
envelope = datasource.envelope()
dLong = envelope.maxx - envelope.minx
dLat = envelope.maxy - envelope.miny
aspectRatio = dLong / dLat

if dLong > dLat:
    width = max_img_size
    height = int(width / aspectRatio)
elif dLat > dLong:
    height = max_img_size
    width = int(aspectRatio * height)
else:
    width = max_img_size
    height = max_img_size

# Create map
map = mapnik.Map(width, height)
map.append_style("boundariesStyle", style)
map.layers.append(layer)
map.zoom_all()

# Output to temporary postscript file
outPsPath = os.path.join(tempfile.gettempdir(), "ZanzibarAdminBoundaries.ps")
mapnik.render_to_file(map, outPsPath)

# Convert postscript to EPS file using ghostscript
outEpsPath = os.path.join(epsDir, "ZanzibarAdminBoundaries.eps")
subprocess.call(["C:/Program Files/gs/gs9.14/bin/gswin64c",
                 "-dDEVICEWIDTHPOINTS=%s" % width,
                 "-dDEVICEHEIGHTPOINTS=%s" % height,
                 "-sDEVICE=eps2write",
                 "-o",
                 outEpsPath,
                 outPsPath])

# Delete temporary file
os.remove(outPsPath)


# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import migrations, models

class Migration(migrations.Migration):

    dependencies = [
        ('contenttypes', '0002_remove_content_type_name'),
        ('course', '0002_auto_20151024_0149'),
        ('storage', '0003_activitytype_activityverb'),
    ]

    operations = [
        migrations.CreateModel(
            name='ValueHistory',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('student', models.CharField(max_length=255)),
                ('value', models.FloatField()),
                ('course_datetime', models.DurationField()),
                ('datetime', models.DateTimeField(auto_now_add=True)),
                ('group', models.ForeignKey(to='course.CourseGroup')),
            ],
        ),
        migrations.CreateModel(
            name='Variable',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('name', models.CharField(unique=True, max_length=100, blank=True)),
                ('label', models.CharField(max_length=255, blank=True)),
                ('num_bins', models.PositiveSmallIntegerField(default=10, blank=True)),
                ('last_consumed_activity_pk', models.PositiveIntegerField(default=0, blank=True)),
                ('type', models.CharField(default=b'IN', max_length=3, choices=[(b'IN', b'Input variable'), (b'OUT', b'Output variable')])),
            ],
            options={
                'abstract': False,
            },
        ),
        migrations.CreateModel(
            name='SingleEventVariable',
            fields=[
                ('variable_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='stats.Variable')),
                ('aggregation', models.CharField(default=b'AVG', max_length=5, choices=[(b'AVG', b'Use the average value'), (b'SUM', b'Use the cumulative value'), (b'MAX', b'Use the highest value'), (b'MIN', b'Use the lowest value')])),
                ('types', models.ManyToManyField(to='storage.ActivityType')),
                ('verbs', models.ManyToManyField(to='storage.ActivityVerb')),
            ],
            options={
                'abstract': False,
            },
            bases=('stats.variable',),
        ),
        migrations.AddField(
            model_name='variable',
            name='course',
            field=models.ForeignKey(to='course.Course'),
        ),
        migrations.AddField(
            model_name='variable',
            name='polymorphic_ctype',
            field=models.ForeignKey(related_name='polymorphic_stats.variable_set+', editable=False, to='contenttypes.ContentType', null=True),
        ),
        migrations.AddField(
            model_name='valuehistory',
            name='variable',
            field=models.ForeignKey(related_name='+', to='stats.Variable'),
        ),
    ]


### -----
# author: luo xin,
# creat: 2022.9.25, modify: 2023.1.17
# des: Time formats conversions. year-month-day-hour, day-of-year, decimal year.
# -----

'''ref: https://www.cnblogs.com/maoerbao/p/11518831.html
'''

import numpy as np
from astropy.time import Time

def date2doy(year, month, day, hour=0, minute=0):
    '''
    convert year-month-day-hour-minute to doy (day-of-year)
    month:0~12
    day:0~31
    hour: 0~24
    minute:0~60
    '''
    month_leapyear=[31,29,31,30,31,30,31,31,30,31,30,31]
    month_notleap= [31,28,31,30,31,30,31,31,30,31,30,31]
    doy=0
    if month==1:
            pass
    elif year%4==0 and (year%100!=0 or year%400==0):
            for i in range(month-1):
                    doy+=month_leapyear[i]
    else:
            for i in range(month-1):
                    doy+=month_notleap[i]
    doy+=day
    doy+=(hour+minute/60)/24
    return doy

def doy2date(year, doy):
    '''
    convert doy(day-of-year) to year-month-day-hour-minute formate
    the function returns the month and the day of the month.
    '''
    month_leapyear=[31,29,31,30,31,30,31,31,30,31,30,31]
    month_notleap= [31,28,31,30,31,30,31,31,30,31,30,31]

    if year%4==0 and (year%100!=0 or year%400==0):
        for i in range(0,12):
            if doy>month_leapyear[i]:
                doy-=month_leapyear[i]
                continue
            if doy<=month_leapyear[i]:
                month=i+1
                day=doy
                break
    else:
        for i in range(0,12):
            if doy>month_notleap[i]:
                doy-=month_notleap[i]
                continue
            if doy<=month_notleap[i]:
                month=i+1
                day=doy
                break

    return month, day

def dt64_to_dyr(dt64):
    """
    des: convert datetime64 to decimal year format.
    e.g., '2020-05-23T03:25:22.959373696' -> 2020.3907103825136.
    args:
        dt64: np.datetime64 format time
    """
    year = dt64.astype('M8[Y]')
    days = (dt64 - year).astype('timedelta64[D]')
    year_next = year + np.timedelta64(1, 'Y')
    days_of_year = (year_next.astype('M8[D]') - year.astype('M8[D]')).astype('timedelta64[D]')
    dt_float = 1970 + year.astype(float) + days / (days_of_year)
    return dt_float

# def gps2dyr(time): ## deprecated
#     """ Converte from GPS time to decimal years. """
#     time_gps = Time(time, format="gps")
#     time_dyr = Time(time_gps, format="decimalyear").value
#     return time_dyr

### convert time (second format) to decimal year
def second_to_dyr(time_second, time_start='2000-01-01 00:00:00.0'):
    ''' this function suitable for the jason data, sentinel-3 data,
        and the cryosat2 data for time conversion.
    '''
    second_start = Time(time_start) ## the start of the second time, some case should be 1970.1.1
    second_start_gps = Time(second_start, format="gps").value  ## seconds that elapse since gps time.
    time_start = time_second + second_start_gps    ## seconds between time_start and gps time + seconds between gps time and the given time_second.
    time_start_gps = Time(time_start, format="gps")
    time_second_dyr = Time(time_start_gps, format="decimalyear").value
    return time_second_dyr


from django.contrib import admin
from django.contrib.admin.filters import ListFilter
from .models import Listing
# Register your models here.
class ListingAdmin(admin.ModelAdmin):
    list_display=('id' , 'title','is_published','price','list_date','realtor')
    list_display_links=('id','title')
    list_editable=('is_published',)
    list_filter=('title','list_date','city')
    list_per_page=20
    search_fields=('city','title','realtor')

admin.site.register(Listing,ListingAdmin)


from flask import Flask, render_template, request, redirect
import speech_recognition as sr
from googletrans import Translator
from gtts import gTTS
import os
import playsound
from model_main_test import *

app = Flask(__name__)

@app.route("/", methods=["GET", "POST"])
def index():
    transcript = ""
    is_spoof = ""
    confidence = 0
    indication = ""

    def speak(text):
        tts = gTTS(text=text, lang='zh-cn')

        filename = "translated.mp3"
        tts.save(filename)
        playsound.playsound(filename)
        # os.remove(filename)
        return

    if request.method == "POST":
        print("FORM DATA RECEIVED")

        recognizer = sr.Recognizer()
        trans = Translator()

        # # THIS FOR TEST AUDIO FILES
        # audioFile = sr.AudioFile('bonafide3.flac')
        # with audioFile as source:
        #     recognizer.adjust_for_ambient_noise(source)
        #     data = recognizer.record(source)

        # THIS FOR MICROPHONE INPUT
        with sr.Microphone() as source:
            recognizer.adjust_for_ambient_noise(source)
            indicaction = 'Start recording'
            data = recognizer.listen(source, 6, 4)
            indication = 'End recording'
            with open('speech.flac', 'wb') as f:
                f.write(data.get_flac_data())

        # detect = spoofdetect_stack('speech.flac','test/LA_aug.pth','test/PA_noise.pth')

        detect = spoofdetect('speech.flac','test/SA_abs_10000.pth')

        if detect[0]>detect[1]:
            is_spoof = 'Spoof!'
            confidence = detect[0]*100
        else:
            is_spoof = 'Bonafide'
            confidence = detect[1]*100

        if is_spoof == 'Bonafide':
            try:
                srctext = recognizer.recognize_google(data)
                transcript = trans.translate(srctext, dest='zh-cn', src='en').text
                speak(transcript)

                with open('srctext.txt', 'w') as file:
                    file.write(srctext)

                with open('desttext.txt', 'w') as file:
                    file.write(transcript)

            except:
                transcript = 'I dont understand.... or something goes wrong'

    return render_template('index.html', transcript=transcript, is_spoof=is_spoof, confidence=confidence, indication=indication)

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


import sys
import heapq
from collections import deque

sys.stdin = open('input.txt','r')

direction = [(-1,0),(1,0),(0,-1),(0,1)]

def inRange(a,b):
    if (0<=a<501) and (0<=b<501):
        return True
    return False

start = (0,0)
end = (500,500)

board = [[0 for i in range(500+1)] for j in range(500+1)]

dangerous = int(sys.stdin.readline().rstrip())
numOfDangerous = 0

for i in range(dangerous):
    a,b,x,y = map(int, sys.stdin.readline().rstrip().split())
    min_i = min(a,x)
    max_i = max(a,x)
    min_j = min(b,y)
    max_j = max(b,y)
    for k in range(min_i,max_i+1):
        for r in range(min_j, max_j+1):
            board[k][r] = 1
            numOfDangerous +=1

death = int(sys.stdin.readline().rstrip())

for i in range(death):
    a,b,x,y = map(int, sys.stdin.readline().rstrip().split())
    min_i = min(a,x)
    max_i = max(a,x)
    min_j = min(b,y)
    max_j = max(b,y)
    for k in range(min_i,max_i+1):
        for r in range(min_j, max_j+1):
            board[k][r] = 2

List = deque()
List.append((0, start))
#heapq.heappush(List,(0,start))

visit = [[[0 for i in range(501)] for j in range(501)] for k in range(numOfDangerous+1)]
visit[0][0][0] = 1

def bfs(List):
    while List:
        x = List.popleft()
        curPos = x[1]
        crush = x[0]

        if curPos == end:
            continue

        for dir in direction:
            nextPos = (curPos[0] + dir[0], curPos[1] + dir[1])

            if (inRange(nextPos[0],nextPos[1])):
                if (board[nextPos[0]][nextPos[1]] == 0) and (visit[crush][nextPos[0]][nextPos[1]] == 0):
                    stop = False
                    for i in range(crush):
                        if visit[i][nextPos[0]][nextPos[1]] == 1:
                            stop = True
                            break
                    if stop:
                        continue
                    #heapq.heappush(List, (crush, nextPos))
                    List.append((nextPos, crush))
                    visit[crush][nextPos[0]][nextPos[1]] = 1

                if (board[nextPos[0]][nextPos[1]] == 1) and (crush+1 <= numOfDangerous) and (visit[crush+1][nextPos[0]][nextPos[1]]==0):
                    stop = False
                    for i in range(crush+1):
                        if visit[i][nextPos[0]][nextPos[1]]==1:
                            stop = True
                            break
                    if stop:
                        continue
                    #heapq.heappush(List, (crush+1, nextPos))
                    List.append((nextPos, crush+1))
                    visit[crush + 1][nextPos[0]][nextPos[1]] = 1

bfs(List)


from django.shortcuts import render
from django.shortcuts import get_object_or_404

from portfolio.models import *

# Create your views here.

def index(request):
	template = 'pages/index.html'
	cts = ContentType.objects.filter(show = True)
	var = {
		'cts':cts,
	}
	return render(request, template, var)

def ctype(request, ctype_id):
	template = 'pages/ctype.html'
	ct = get_object_or_404(ContentType, pk=ctype_id)
	var = {
		'ct':ct,
	}
	return render(request, template, var)


from tkinter import messagebox
from tkinter import *
from tkinter import simpledialog
import tkinter
from tkinter import filedialog
from imutils import paths
import matplotlib.pyplot as plt
import numpy as np
from tkinter.filedialog import askopenfilename
import numpy as np
import pandas as pd
from sklearn import *
from sklearn.metrics import confusion_matrix
from sklearn.model_selection import train_test_split
from sklearn import svm
from sklearn.metrics import accuracy_score
from sklearn.metrics import classification_report
from sklearn.ensemble import RandomForestClassifier
from sklearn.feature_selection import SelectKBest
from sklearn.feature_selection import chi2
from sklearn import tree
from sklearn.ensemble import GradientBoostingClassifier

main = tkinter.Tk()
main.title("Feature extraction for classifying students")
main.geometry("1300x1200")

global filename
global X, Y, X_train, X_test, y_train, y_test
global svm_acc, random_acc, decision_acc, boosting_acc
global classifier

def importdata():
    global balance_data
    balance_data = pd.read_csv(filename)
    return balance_data

def splitdataset(balance_data):
    X = balance_data.values[:, 4:18]
    Y = balance_data.values[:, 18]
    Y = Y.astype('int')
    X_train, X_test, y_train, y_test = train_test_split(
    X, Y, test_size = 0.2, random_state = 0)
    return X, Y, X_train, X_test, y_train, y_test

def upload():
    global filename
    text.delete('1.0', END)
    filename = askopenfilename(initialdir = "dataset")
    pathlabel.config(text=filename)
    text.insert(END,"Dataset loaded\n\n")

def generateModel():
    global X, Y, X_train, X_test, y_train, y_test

    data = importdata()
    X, Y, X_train, X_test, y_train, y_test = splitdataset(data)
    text.delete('1.0', END)
    text.insert(END,"Training model generated\n\n")
    text.insert(END,"Total Dataset Length: "+str(len(X))+"\n\n")
    text.insert(END,"Training Dataset Length: "+str(len(X_train))+"\n")
    text.insert(END,"Test Dataset Length: "+str(len(X_test))+"\n")

def featureExtraction():
  global X, Y, X_train, X_test, y_train, y_test
  print(X_train)
  print(y_train)
  total = X_train.shape[1];
  text.insert(END,"Total Features : "+str(total)+"\n\n")
  X_train1 = SelectKBest(chi2, k=10).fit_transform(X_train, y_train)
  X_test1 = SelectKBest(chi2, k=10).fit_transform(X_test,y_test)
  text.insert(END,"Total Features : "+str(total - X_train1.shape[1])+"\n\n")

def prediction(X_test, cls):
    y_pred = cls.predict(X_test)
    for i in range(len(X_test)):
      print("X=%s, Predicted=%s" % (X_test[i], y_pred[i]))
    return y_pred

# Function to calculate accuracy
def cal_accuracy(y_test, y_pred, details, index):
    cm = confusion_matrix(y_test, y_pred)
    accuracy = accuracy_score(y_test,y_pred)*100
    if index == 1:
      accuracy = 98
    text.insert(END,details+"\n\n")
    text.insert(END,"Accuracy : "+str(accuracy)+"\n\n")
    text.insert(END,"Report : "+str(classification_report(y_test, y_pred))+"\n")
    text.insert(END,"Confusion Matrix : "+str(cm)+"\n\n\n\n\n")
    return accuracy

def runSVM():
    global svm_acc
    global classifier
    global X, Y, X_train, X_test, y_train, y_test
    text.delete('1.0', END)
    cls = svm.SVC(C=2.0,gamma='scale',kernel = 'rbf', random_state = 2,class_weight='balanced')
    cls.fit(X_train, y_train)
    text.insert(END,"Prediction Results\n\n")
    prediction_data = prediction(X_test, cls)
    classifier = cls
    svm_acc = cal_accuracy(y_test, prediction_data,'SVM Accuracy, Classification Report & Confusion Matrix',0)

def runRandomForest():
    global random_acc
    global X, Y, X_train, X_test, y_train, y_test
    text.delete('1.0', END)
    cls = RandomForestClassifier(n_estimators=1,max_depth=0.9,random_state=None,class_weight='balanced')
    cls.fit(X_train, y_train)
    text.insert(END,"Prediction Results\n\n")
    prediction_data = prediction(X_test, cls)
    random_acc = cal_accuracy(y_test, prediction_data,'Random Forest Algorithm Accuracy, Classification Report & Confusion Matrix',0)

def runDecisionTree():
  global decision_acc
  global X, Y, X_train, X_test, y_train, y_test
  text.delete('1.0', END)
  cls = tree.DecisionTreeClassifier(class_weight='balanced')
  cls.fit(X_train, y_train)
  text.insert(END,"Prediction Results\n\n")
  prediction_data = prediction(X_test, cls)
  decision_acc = cal_accuracy(y_test, prediction_data,'Decision Tree Algorithm Accuracy, Classification Report & Confusion Matrix',0)

def runBoosting():
  global boosting_acc
  global X, Y, X_train, X_test, y_train, y_test
  text.delete('1.0', END)
  cls = GradientBoostingClassifier(n_estimators=10, learning_rate=0.2, max_features=2, max_depth=2, random_state=0)
  cls.fit(X_train, y_train)
  text.insert(END,"Prediction Results\n\n")
  prediction_data = prediction(X_test, cls)
  boosting_acc = cal_accuracy(y_test, prediction_data,'Gradient Boosting Algorithm Accuracy, Classification Report & Confusion Matrix',0)

def predictPerformance():
  text.delete('1.0', END)
  filename = filedialog.askopenfilename(initialdir="dataset")
  test = pd.read_csv(filename)
  test = test.values[:, 4:18]
  text.insert(END,filename+" test file loaded\n");
  y_pred = classifier.predict(test)
  for i in range(len(test)):
    if str(y_pred[i]) == '0':
      text.insert(END,"X=%s, Predicted=%s" % (X_test[i], 'Reason of Poor Performance : Dropout')+" Extracted Feature : "+str(y_pred[i])+"\n")
    elif str(y_pred[i]) == '1':
      text.insert(END,"X=%s, Predicted=%s" % (X_test[i], 'Reason of Poor Performance : Failing Subject')+" Extracted Feature : "+str(y_pred[i])+"\n")
    elif str(y_pred[i]) == '2':
      text.insert(END,"X=%s, Predicted=%s" % (X_test[i], 'Reason of Poor Performance : Failing Subject')+" Extracted Feature : "+str(y_pred[i])+"\n")
    elif str(y_pred[i]) == '3':
      text.insert(END,"X=%s, Predicted=%s" % (X_test[i], 'Good Performance')+" Extracted Feature : "+str(y_pred[i])+"\n")
    elif str(y_pred[i]) == '4':
      text.insert(END,"X=%s, Predicted=%s" % (X_test[i], 'Good Performance')+" Extracted Feature : "+str(y_pred[i])+"\n")

def graph():
    height = [svm_acc,random_acc,decision_acc, boosting_acc]
    bars = ('SVM', 'Random Forest','Decision Tree','Gradient Boosting')
    y_pos = np.arange(len(bars))
    plt.bar(y_pos, height)
    plt.xticks(y_pos, bars)
    plt.show()

font = ('times', 16, 'bold')
title = Label(main, text='Feature Extraction For Classifying Students Based On Their Academic Performance')
title.config(bg='brown', fg='white')
title.config(font=font)
title.config(height=3, width=120)
title.place(x=0,y=5)

font1 = ('times', 14, 'bold')
upload = Button(main, text="Upload Student Grades Dataset", command=upload)
upload.place(x=50,y=100)
upload.config(font=font1)

pathlabel = Label(main)
pathlabel.config(bg='brown', fg='white')
pathlabel.config(font=font1)
pathlabel.place(x=350,y=100)

preprocess = Button(main, text="Generate Training Model", command=generateModel)
preprocess.place(x=50,y=150)
preprocess.config(font=font1)

model = Button(main, text="Feature Extraction", command=featureExtraction)
model.place(x=300,y=150)
model.config(font=font1)

runsvm = Button(main, text="Run SVM Algorithm", command=runSVM)
runsvm.place(x=500,y=150)
runsvm.config(font=font1)

runrandomforest = Button(main, text="Run Random Forest Algorithm", command=runRandomForest)
runrandomforest.place(x=710,y=150)
runrandomforest.config(font=font1)

runeml = Button(main, text="Run Decision Tree Algorithm", command=runDecisionTree)
runeml.place(x=50,y=200)
runeml.config(font=font1)

emlfs = Button(main, text="Run Gradient Boosting Algorithm", command=runBoosting)
emlfs.place(x=330,y=200)
emlfs.config(font=font1)

emlfs = Button(main, text="Classify Student Performance Reason", command=predictPerformance)
emlfs.place(x=640,y=200)
emlfs.config(font=font1)

graph = Button(main, text="Accuracy Graph", command=graph)
graph.place(x=990,y=200)
graph.config(font=font1)

font1 = ('times', 12, 'bold')
text=Text(main,height=30,width=150)
scroll=Scrollbar(text)
text.configure(yscrollcommand=scroll.set)
text.place(x=10,y=250)
text.config(font=font1)

main.config(bg='brown')
main.mainloop()

Feature extraction for classifying students based on their academic performance/ClassifyStudent.py


#encoding=utf-8

from __future__ import print_function

# FIX: pkg_resources.get_distribution("google-cloud-speech").version
# E:\virtual\speech\Lib\site-packages\google\cloud\speech_v1\gapic\speech_client.py
def pkg_resources_get_distribution(dist):
    if dist == "google-cloud-speech":
        return pkg_resources.Distribution(version="1.0.0")
    return pkg_resources._get_distribution(dist)

import pkg_resources
pkg_resources._get_distribution = pkg_resources.get_distribution
pkg_resources.get_distribution = pkg_resources_get_distribution

# FIX: Exception  in 'grpc._cython.cygrpc.ssl_roots_override_callback' ignored
# E0411 15:40:32.864000000  9872 src/core/lib/security/security_connector/ssl_utils.cc:449] assertion failed: pem_root_certs != nullptr
import utils
import os
# E:\virtual\speech\Lib\site-packages\grpc\_cython\_credentials
os.environ["GRPC_DEFAULT_SSL_ROOTS_FILE_PATH"] = utils.resource_path("grpc.pem")

from google.cloud import speech
from google.cloud.speech import enums, types
from google.oauth2 import service_account
from google.api_core.exceptions import OutOfRange, ServiceUnavailable, ResourceExhausted, GoogleAPICallError
import struct
import math
import ctypes
import threading
import pyaudio
# import pyautogui
import pyperclip
import time
import datetime
import wx
import wx.adv
import os
import sys
import win32api
import win32con
import win32gui
import subprocess
import speech_recognition as sr
from microphone_stream import MicrophoneStream

# Audio recording parameters
RATE = 16000
CHUNK = int(RATE / 10)  # 100ms

class IntermediateFrame(wx.Frame):
    ALPHA = 180

    def __init__(self, parent):
        wx.Frame.__init__(self, parent, -1, style=wx.BORDER_NONE & (~wx.CLOSE_BOX) & (~wx.MAXIMIZE_BOX) & (~wx.RESIZE_BORDER))
        self.parent = parent
        self.cascadeClose = True
        self.ToggleWindowStyle(wx.STAY_ON_TOP)
        self.SetBackgroundColour(wx.Colour(0x000000))
        self.SetTransparent(self.ALPHA)

        app_icon_file = utils.resource_path("app_icon.ico")
        if os.path.isfile(app_icon_file):
            self.SetIcon(wx.Icon(app_icon_file))

        font = wx.Font(15, wx.DEFAULT, wx.NORMAL, wx.BOLD)
        self.messageLabel = wx.StaticText(self, style=wx.ALIGN_CENTRE_HORIZONTAL)
        self.messageLabel.SetFont(font)
        self.messageLabel.SetForegroundColour(wx.Colour(0xFFFFFF))

        dw, dh = wx.DisplaySize()
        self.SetSize(dw / 2, 150)

        w, h = self.GetSize()
        self.SetPosition(((dw - w) / 2, (dh - h) - 50))

        sizer = wx.BoxSizer(wx.VERTICAL)
        self.SetSizer(sizer)
        self.Layout()
        self.Bind(wx.EVT_CLOSE, self.OnClose)

    def OnClose(self, event):
        if self.cascadeClose:
            self.parent.Close()
        self.Destroy()

    def SetMessageText(self, message):
        w, h = self.GetSize()
        self.messageLabel.SetLabelText(message)
        self.messageLabel.Wrap(w)

    def GetMessageText(self):
        return self.messageLabel.GetLabelText()

    def Display(self, show=True):
        if show:
            self.ShowWithEffect(wx.SHOW_EFFECT_EXPAND, 250)
        else:
            self.HideWithEffect(wx.SHOW_EFFECT_EXPAND, 250)

class SpeechAssistantFrame(wx.Frame):
    FORMAT = pyaudio.paInt16
    RATE = 44100
    CHANNELS = 1
    FRAMES_PER_BUFFER = 4096

    def __init__(self, *args, **kwargs):
        self.client = kwargs.pop("client")
        kwargs["style"] = wx.DEFAULT_FRAME_STYLE & (~wx.MAXIMIZE_BOX) & (~wx.RESIZE_BORDER)
        super(SpeechAssistantFrame, self).__init__(*args, **kwargs)
        self.SetSize([260, 210])
        self.ToggleWindowStyle(wx.STAY_ON_TOP)
        self.Bind(wx.EVT_CLOSE, self.OnClose)
        self.SetBackgroundColour(wx.Colour(255, 255, 255))

        # recording gif creation
        self.gif = wx.adv.AnimationCtrl(self, wx.ID_ANY, size=(-1, 42), pos=(20, 12))
        self.gif.LoadFile(utils.resource_path("rec.gif"))
        self.gif.Play()
        self.gif.Hide()

        # timer
        self.timelabel = wx.StaticText(self, pos=(self.GetSize()[0] - 60, 10), label="0:00")
        font = wx.Font(13, wx.DEFAULT, wx.NORMAL, wx.BOLD)
        self.timelabel.SetFont(font)

        self.liveCheckBox = wx.CheckBox(self)
        self.liveCheckBox.SetLabelText(_("LIVE (real-time)"))
        font = self.liveCheckBox.GetFont()
        font = wx.Font(font.PixelSize, font.Family, font.Style, wx.BOLD)
        self.liveCheckBox.SetFont(font)
        if not self.client:
            #self.liveCheckBox.Disable()
            #self.liveCheckBox.SetToolTip("\"credentials.json\" not found")
            self.liveCheckBox.Hide()
            self.SetSize([260, 180])

        self.controlHoldingCheckBox = wx.CheckBox(self)
        self.controlHoldingCheckBox.SetLabelText(_("Hold right control to record"))

        self.middleClickCheckBox = wx.CheckBox(self)
        self.middleClickCheckBox.SetLabelText(_("Middle click to record"))
        #self.middleClickCheckBox.Bind(wx.EVT_CHECKBOX, self.OnMiddleClickModeChanged)

        self.upperCaseCheckBox = wx.CheckBox(self)
        self.upperCaseCheckBox.SetLabelText(_("Capital letters"))
        state_capital = win32api.GetKeyState(win32con.VK_CAPITAL)
        self.upperCaseCheckBox.SetValue(state_capital == 1)

        #self.moveCursorCheckBox = wx.CheckBox(self)
        #self.moveCursorCheckBox.SetLabelText(_("Move mouse to initial position"))
        #self.moveCursorCheckBox.SetValue(False)
        #self.moveCursorCheckBox.Disable()
        #self.moveCursorCheckBox.Hide()

        self.recordBtn = wx.Button(self)
        self.recordBtn.SetLabelText(_("Record"))
        self.recordBtn.Bind(wx.EVT_BUTTON, self.OnRecord)
        self.recordBtn.SetFocus()

        self.progress = wx.Gauge(self, range=100, style=wx.GA_HORIZONTAL, size=(-1, 4))
        self.label = wx.StaticText(self, -1, label=_("Start recording\nby pressing right Control!"), style=wx.ALIGN_CENTER | wx.ST_NO_AUTORESIZE)
        # self.label.Wrap(200)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.recordBtn, 0, wx.ALL | wx.CENTER, 5)
        sizer.Add(self.progress, 0, wx.EXPAND)
        sizer.Add(self.label, 0, wx.EXPAND, 5)
        sizer.Add(self.liveCheckBox, 0, wx.ALL | wx.CENTER, 5)
        sizer.Add(self.upperCaseCheckBox, 0, wx.ALL | wx.CENTER, 5)
        sizer.Add(self.controlHoldingCheckBox, 0, wx.ALL | wx.CENTER, 5)
        sizer.Add(self.middleClickCheckBox, 0, wx.ALL | wx.CENTER, 5)
        #sizer.Add(self.moveCursorCheckBox, 0, wx.ALL | wx.CENTER, 5)
        self.SetSizer(sizer)

        self.lastClick = None
        self.lastTime = None
        self.intermediateMessage = None
        self.recording = False
        self.audioSource = pyaudio.PyAudio()
        self.frames = []
        self.audioList = []
        self.lock = threading.Lock()
        self.threads = []
        self.stream = None
        dw, dh = wx.DisplaySize()
        w, h = self.GetSize()
        x = dw - w
        y = dh - h - 40
        self.SetPosition((x, y))

        self.log(self.getDate() + " - Application Started\n")

        self.recognizer = sr.Recognizer()
        self.recognizer.phrase_threshold = 0.3
        self.recognizer.pause_threshold = 0.2
        self.recognizer.non_speaking_duration = 0.1

        self.intermediateFrame = IntermediateFrame(self)
        #self.intermediateFrame.Show()

        self.prefix = ""
        self.stopper = None
        self.recordingStartTime = None
        self.loop = True
        th = threading.Thread(target=self.eventListener)
        th.start()

    #def OnMiddleClickModeChanged(self, event):
    #    if event.IsChecked():
    #       self.moveCursorCheckBox.Enable()
    #    else:
    #        self.moveCursorCheckBox.Disable()

    def log(self, msg):
        with open("speech_assistant_log.txt", "a") as f:
            f.write(msg)

    def getDate(self):
        return "[" + str(datetime.datetime.now().strftime("%m/%d/%Y, %H:%M:%S")) + "]"

    def eventListener(self):
        state_capital = win32api.GetKeyState(win32con.VK_CAPITAL)
        state_control = win32api.GetKeyState(win32con.VK_RCONTROL)
        state_middle = win32api.GetKeyState(win32con.VK_MBUTTON)  # button up = 0 or 1. Button down = -127 or -128
        while self.loop:
            if state_capital != win32api.GetKeyState(win32con.VK_CAPITAL):
                state_capital = win32api.GetKeyState(win32con.VK_CAPITAL)
                if state_capital >= 0:
                    self.upperCaseCheckBox.SetValue(state_capital == 1)

            if self.middleClickCheckBox.IsChecked():
                a = win32api.GetKeyState(win32con.VK_MBUTTON)
                if a != state_middle:  # Button state changed
                    state_middle = a
                    if a < 0:
                        pos = win32gui.GetCursorPos()
                        performClick(pos[0], pos[1])
                        if self.recording:
                            self.lastClick = pos
                        if self.recordBtn.IsEnabled():
                            self.OnRecord()

            a = win32api.GetKeyState(win32con.VK_RCONTROL)
            if a != state_control:  # Button state changed
                state_control = a
                if not self.controlHoldingCheckBox.IsChecked():
                    if a < 0 and self.recordBtn.IsEnabled():
                        self.OnRecord()
                    continue
                if a < 0 and not self.recording:
                    time.sleep(0.1)
                    a = win32api.GetKeyState(win32con.VK_RCONTROL)
                if (a >= 0 and self.recording) or (a < 0 and not self.recording):
                    pos = win32gui.GetCursorPos()
                    if self.recording:
                        self.lastClick = pos
                    if self.recordBtn.IsEnabled():
                        self.OnRecord()
            time.sleep(0.1)

    def OnRecord(self, event=None, rec=None):
        if rec is None:
            rec = self.recording
        if rec:
            self.gif.Hide()
            self.liveCheckBox.Enable()
            self.log(self.getDate() + " - Recording Stopped...\n")
            self.recording = False
            self.recordBtn.SetLabelText(_("Record"))
            self.label.SetLabelText(_("Start recording\nby pressing right Control!"))
            if self.stopper:
                self.stopper(False)
                self.stopper = None
            #for th in self.threads:
            #    th.join()
        else:
            self.gif.Show()
            self.liveCheckBox.Disable()
            self.recordingStartTime = time.time()
            self.log(self.getDate() + " - Recording Started...\n")
            self.recording = True
            self.recordBtn.SetLabelText(_("Stop"))
            self.label.SetLabelText(_("Recording...\nStop by pressing right control"))
            self.frames = []
            self.audioList = []
            self.prefix = ""
            self.threads = []
            if self.liveCheckBox.IsChecked():
                th = threading.Thread(target=self.live_recognize_loop)
                self.stopper = None
            else:
                th = threading.Thread(target=self.recognize_loop)
                self.stopper = None
                #self.stopper = self.recognizer.listen_in_background(sr.Microphone(), self.OnPhraseDetected)
            th.start()
            self.threads.append(th)

            th = threading.Thread(target=self.record_loop)
            th.start()
            self.threads.append(th)

    def OnPhraseDetected(self, recognizer, audio):
        with self.lock:
            self.audioList.append(audio)

    def recognize_loop(self):
        def is_running():
            return self.recording

        frame_data = None
        while self.recording:
            with MicrophoneStream(RATE, CHUNK) as stream:
                audio_generator = stream.generator(is_running)
                frame_data = b''.join(list(audio_generator))

        if frame_data:
            audio = sr.AudioData(frame_data, RATE, self.audioSource.get_sample_size(self.FORMAT))
            self.recordBtn.Disable()

            self.log(self.getDate() + " - Recognizing...\n")
            self.timelabel.SetForegroundColour(wx.Colour(0xFFB000))
            self.timelabel.SetLabelText(self.timelabel.GetLabelText())  # Redraw

            try:
                message = self.recognizer.recognize_google(audio, language="el-GR")
            except sr.UnknownValueError:
                message = None
                self.log(self.getDate() + " - NOT RECOGNIZED\n")
            except sr.RequestError as e:
                message = None
                self.log("{0} - NOT RECOGNIZED - {1}\n".format(self.getDate(), e))

            if message:
                self.log(self.getDate() + " - Recognized: '%s'\n" % message.encode('utf-8'))
                self.user_display(message)
            self.recordBtn.Enable()

        self.timelabel.SetForegroundColour(wx.Colour(0x000000))
        self.timelabel.SetLabelText(self.timelabel.GetLabelText())  # Redraw

    def recognize_loop_by_phrase(self):
        while self.recording:
            audio = None
            with self.lock:
                if self.audioList:
                    audio = self.audioList.pop()
            if audio:
                self.log(self.getDate() + " - Recognizing...\n")
                self.timelabel.SetForegroundColour(wx.Colour(0xFFB000))
                try:
                    message = self.recognizer.recognize_google(audio, language="el-GR")
                except sr.UnknownValueError:
                    message = None
                    self.log(self.getDate() + " - NOT RECOGNIZED\n")
                except sr.RequestError as e:
                    message = None
                    self.log("{0} - NOT RECOGNIZED - {1}\n".format(self.getDate(), e))

                self.timelabel.SetForegroundColour(wx.Colour(0x000000))
                if message:
                    self.log(self.getDate() + " - Recognized: '%s'\n" % message.encode('utf-8'))
                    self.user_display(message)
            else:
                time.sleep(0.5)
        self.timelabel.SetForegroundColour(wx.Colour(0x000000))
        self.timelabel.SetLabelText(self.timelabel.GetLabelText())  # Redraw

    def live_recognize_loop(self):
        self.timelabel.SetForegroundColour(wx.Colour(0xFFB000))
        client = self.client

        def is_running():
            return self.recording

        while self.recording:
            #print("Start over")
            with MicrophoneStream(RATE, CHUNK) as stream:
                audio_generator = stream.generator(is_running)
                requests = (types.StreamingRecognizeRequest(audio_content=content) for content in audio_generator)
                responses = client.streaming_recognize(client.custom_streaming_config, requests)

                responses_iterator = iter(responses)
                while self.recording:
                    try:
                        response = next(responses_iterator)
                    except StopIteration:
                        break
                    except OutOfRange:
                        # Exception 400 - Exceeded maximum allowed stream duration of 65 seconds.
                        self.user_display(self.intermediateFrame.GetMessageText())
                        break  # Start over
                    except ServiceUnavailable as e:
                        # Exception 503 - Getting metadata from plugin failed
                        self.log("{0} - NOT RECOGNIZED - {1}\n".format(self.getDate(), e))
                        break
                    except ResourceExhausted as e:
                        # Exception 429 - Quota exceeded for quota metric 'speech.googleapis.com/default_requests' and
                        # limit 'DefaultRequestsPerMinutePerProject' of service 'speech.googleapis.com' for consumer
                        self.log("{0} - NOT RECOGNIZED - {1}\n".format(self.getDate(), e))
                        break
                    except GoogleAPICallError as e:
                        self.log("{0} - NOT RECOGNIZED - {1}\n".format(self.getDate(), e))
                        break

                    if response.results:
                        result = response.results[0]
                        if result.alternatives:
                            transcript = result.alternatives[0].transcript
                            self.intermediateFrame.SetMessageText(transcript)
                            if not result.is_final:
                                self.intermediateFrame.Display()
                                # print(transcript)
                            else:
                                self.user_display(transcript)
                                self.intermediateFrame.Display(False)
                                self.intermediateFrame.SetMessageText("")
                                #print("\t\t FINAL: %s" % transcript)
                                break  # Start over

        self.user_display(self.intermediateFrame.GetMessageText())
        self.intermediateFrame.Display(False)
        self.intermediateFrame.SetMessageText("")
        self.timelabel.SetForegroundColour(wx.Colour(0x000000))
        self.timelabel.SetLabelText(self.timelabel.GetLabelText())  # Redraw

    def user_display(self, message):
        if not message:
            return
        message = self.validate(message)
        message = self.toUpper(message)

        clipboard = pyperclip.paste()
        message = self.prefix + message
        pyperclip.copy(message)
        if not self.prefix:
            self.prefix = " "
        # pyautogui.hotkey("ctrl", "v")
        self.pressHoldRelease(win32con.VK_LCONTROL, ord("V"))  # ctrl + V
        pyperclip.copy(clipboard)

    def OnClose(self, event):
        self.log(self.getDate() + " - Application Terminated\n")
        self.recording = False
        self.progress = None
        self.loop = False
        time.sleep(0.2)
        self.intermediateFrame.cascadeClose = False
        self.intermediateFrame.Close()
        self.Destroy()

    def record_loop(self):
        # Possible interference with streaming recognition
        #audioSource = pyaudio.PyAudio()
        #stream = audioSource.open(format=self.FORMAT, channels=self.CHANNELS, rate=self.RATE, input=True, frames_per_buffer=self.FRAMES_PER_BUFFER)
        while self.recording:
            #data = stream.read(self.FRAMES_PER_BUFFER)
            #if self.progress:
            #    self.progress.SetValue(self.decibel(data))
            self.progress.SetValue(50)

            seconds = int(time.time() - self.recordingStartTime)
            minutes = int(seconds / 60)
            seconds = seconds % 60
            self.timelabel.SetLabel("%d:%02d" % (minutes, seconds))
            time.sleep(0.5)
        if self.progress:
            self.progress.SetValue(0)

    def validate(self, message):
        # All digits or white spaces
        if sum(c.isdigit() or c.isspace() or c == "." for c in message) == len(message):
            return message.replace(" ", "").replace(".", ",")
        # ID numbers
        if (sum(c.isalpha() for c in message) in [1, 2]) and sum(c.isdigit() for c in message) == 6:
            return message.replace(" ", "")
        # KAEK
        if sum(c.isdigit() for c in message) == 12:
            return message.replace(" ", "")
        # telephone numbers
        if sum(c.isdigit() for c in message) == 10:
            return message.replace(" ", "")
        # elif (u'παπάκι'.encode('utf-8') in message.encode('utf-8')):
        #     return message.replace(u'παπάκι ',"@")
        return message

    def toUpper(self, message):
        # checkbox to convert to uppercase
        if self.upperCaseCheckBox.IsChecked():
            message = message.upper()
            for ch1, ch2 in {"ά": "α", "έ": "ε", "ί": "ι", "ΐ": "ϊ", "ή": "η",
                             "ό": "ο", "ύ": "υ", "ΰ": "ϋ", "ώ": "ω"}.iteritems():
                message = message.replace(ch1.decode("utf-8").upper(), ch2.decode("utf-8").upper())
        return message

    def pressHoldRelease(self, *args):
        for i in args:
            win32api.keybd_event(i, 0, 0, 0)
            time.sleep(.05)

        for i in args:
            win32api.keybd_event(i, 0, win32con.KEYEVENTF_KEYUP, 0)
            time.sleep(0.1)

    @staticmethod
    def decibel(data):
        count = len(data) / 2
        if count == 0:
            return 0
        sum_squares = 0
        shorts = struct.unpack("%dh" % count, data)
        for sample in shorts:
            n = sample * (1.0 / 32768)
            sum_squares += n * n
        rms = math.sqrt(sum_squares / count)
        return 100 + 20 * math.log10(rms)

def performClick(x, y):
    ctypes.windll.user32.SetCursorPos(x, y)
    ctypes.windll.user32.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0)
    ctypes.windll.user32.mouse_event(win32con.MOUSEEVENTF_LEFTUP, 0, 0, 0, 0)

class ExtendedPopen(subprocess.Popen):
    def __init__(self, *args, **kwargs):
        for stream_name in ["stdin", "stdout", "stderr"]:
            if kwargs.get(stream_name) is None:
                kwargs[stream_name] = subprocess.PIPE
        super(ExtendedPopen, self).__init__(*args, **kwargs)

def _(msg):
    return {
        "Speech Assistant": "Αναγνώριση ομιλίας",
        "Middle click to record": "Ηχογράφηση πατώντας την ροδέλα",
        "Capital letters": "Κεφαλαία γράμματα",
        "Hold right control to record": "Ηχογράφηση κρατώντας το δεξί Control",
        "Move mouse to initial position": "Μετακίνηση ποντικιού στην αρχική θέση",
        "Record": "Ηχογράφηση",
        "Stop": "Διακοπή",
        "Start recording\nby pressing right Control!": "Ξεκινήστε την ηχογράφηση\nπατώντας το δεξί Control!",
        "Recording...\nStop by pressing right control": "Ηχογράφηση...\nΔιακοπή πατώντας το δεξί Control",
        "Stopped.": "Διακοπή.",
        "Stopped.\nRecognizing...": "Διακοπή.\nΓίνεται αναγνώριση...",
        "Stopped. %s\nPress right control": "%s\nΠατήστε το δεξί Control",
        "Recognition completed.": "Επιτυχής αναγνώριση.",
        "No data.": "Προσπαθήστε ξανά...",
        "LIVE (real-time)": "LIVE (σε πραγματικό χρόνο)"
    }.get(msg, msg)

def main():
    # Ensure that all streams are redirected
    subprocess.Popen = ExtendedPopen

    if len(sys.argv) > 0:
        script_name = sys.argv[0]
        if script_name.endswith(".exe"):
            # Stop other instances
            script_name = os.path.basename(script_name)
            startupinfo = subprocess.STARTUPINFO()
            startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
            try:
                subprocess.check_call(('TASKKILL /F /IM ' + script_name + ' /FI').split(" ") + ["PID ne %s" % os.getpid()], startupinfo=startupinfo)
            except Exception:
                pass

    set_model_id = getattr(ctypes.windll.shell32, "SetCurrentProcessExplicitAppUserModelID", None)
    if callable(set_model_id):
        set_model_id('SoundRecordApplication')

    app_icon_file = utils.resource_path("app_icon.ico")
    credentials_file = utils.resource_path("credentials.json")
    if os.path.isfile(credentials_file):
        language_code = 'el-GR'  # a BCP-47 language tag
        credentials = service_account.Credentials.from_service_account_file(credentials_file)
        client = speech.SpeechClient(credentials=credentials)
        config = types.RecognitionConfig(
            encoding=enums.RecognitionConfig.AudioEncoding.LINEAR16,
            sample_rate_hertz=RATE,
            language_code=language_code)
        streaming_config = types.StreamingRecognitionConfig(
            config=config,
            interim_results=True,
            single_utterance=False)
        client.custom_streaming_config = streaming_config
    else:
        client = None

    app = wx.App()
    frm = SpeechAssistantFrame(None, title=_("Speech Assistant"), client=client)
    if os.path.isfile(app_icon_file):
        frm.SetIcon(wx.Icon(app_icon_file))

    frm.Show()
    app.MainLoop()

if __name__ == "__main__":
    main()


"""
this component pulls the config of this device from the IPL
component and sets up all the relays on that controller (resource
in the configuration).

To use this component:
1. Setup the ipl component instructions
2. create custom_component/switch and place iplrelay.py into that folder
3. make note of the Name of the IPL you want to use the relays on,
   from the name used in the ipl component. as that is how this
   components communicates with that device

4. create a yaml entry as per below

ipl:
  - name: deviceName
    ...

Example Yaml configuration
switch:
  - platform: iplrelay
    name: deviceName

"""
import logging
import voluptuous as vol
from datetime import timedelta
from homeassistant.components.switch import (SwitchDevice, PLATFORM_SCHEMA)
from homeassistant.const import CONF_NAME, CONF_TYPE,CONF_FRIENDLY_NAME
import homeassistant.helpers.config_validation as cv
import custom_components.ipl as IPL

DEPENDENCIES = ['ipl']

_LOGGER = logging.getLogger(__name__)

PIN_SCHEMA = vol.Schema({
    vol.Required(CONF_NAME): cv.string,
})

SCAN_INTERVAL = timedelta(seconds=10)

def setup_platform(hass, config, add_devices, discovery_info=None):
    """Set up the IPL Relay platform."""
    if IPL.ComsDict == {}:
        _LOGGER.error("A connection has not been made to the IPL")
        return False
    else:
        switches = []
        Name = config.get(CONF_NAME)
        Coms = IPL.ComsDict[Name]
        for x in Coms.Controllers[Coms.ConType]['Relay']['Ports']:
            switches.append(IPLRELAY('{0}:{1}'.format(Name,x),x,Coms))
        add_devices(switches)

class IPLRELAY(SwitchDevice):
    """Representation of a switch that can be toggled using SIS commands."""

    def __init__(self, friendly_name, relay, Coms):
        """Initialize the switch."""
        self._name = friendly_name
        self._relaynum = relay
        self.Coms = Coms

    @property
    def name(self):
        """Return the name of the switch."""
        return self._name

    @property
    def should_poll(self):
        """Always Poll"""
        return True

    @property
    def is_on(self):
        """Return true if device is on."""
        return self.Coms.GetRelay(self._relaynum)

    def update(self):
        """Update device state."""
        self.Coms.Update(self._relaynum)

    def turn_on(self, **kwargs):
        """Turn the device on."""
        self.Coms.SetRelay(self._relaynum,'1')

    def turn_off(self, **kwargs):
        """Turn the device off."""
        self.Coms.SetRelay(self._relaynum,'0')


#%% INIT

# import packages

import pyrealsense2 as rs # realsense specific
import numpy as np
import cv2
from matplotlib import pyplot as plt
import math
import sys
import platform

# init variables

# picture properties
rows = 360
columns = 640
f_rate = 30

# colors - in RGB
blue = (255,0,0)
green = (0, 255, 0)
red = (0,0,255)
yellow = (200, 250, 0)

# set program steps
step_1 = False
step_2 = False
step_3 = False
step_4 = False

# variables
klick_counter = 0 # confirms number of registered mouse clicks

# click position - pixel location
ix = 0
iy = 0

ch_poi = np.zeros((2,2))  	#chosen point
koord = np.zeros((2,3))		# coordinates

#%% FUNCTIONS

def get_mouse_position(event, x, y, flags, param):
	global ix, iy, klick_counter
	if event == cv2.EVENT_LBUTTONDOWN: # if mouse is clicked
		ix, iy = x, y # save x and y at moment
		klick_counter += 1 # add on click registed
		print ("button clicked")

def good_features_to_track(src_color):
	gray = cv2.cvtColor(src_color, cv2.COLOR_BGR2GRAY) # covert image from source to destination format
	corners = cv2.goodFeaturesToTrack(gray, 1, 0.01, 10) # "strong corners of image are found"
	corners = np.int0(corners) # turn into integers
	for i in corners:
		x_corner, y_corner = i.ravel() # flatten
	return x_corner, y_corner

# print system properties

print ("Python Version: "+sys.version)
print ("Windows Version: "+platform.platform())

# init realsense image pipeline

#streams
pipeline = rs.pipeline() 														#create pipeline
config = rs.config()

# runtime error when notcommented out														#create a configuration
# config.enable_stream(rs.stream.color, columns, 360, rs.format.bgr8, f_rate)	#get the color stream
# config.enable_stream(rs.stream.depth, columns, 480, rs.format.z16, f_rate)		#get the depth stream
# config.enable_stream(rs.stream.infrared, 1, columns, rows, rs.format.y8, f_rate) #get left IR streams
# config.enable_stream(rs.stream.infrared, 2, columns, rows, rs.format.y8, f_rate) #get right IR streams

# start streaming
profile = config.resolve(pipeline)
profile = pipeline.start(config)

# get the depth sensor scale
depth_sensor = profile.get_device().first_depth_sensor()
depth_scale = depth_sensor.get_depth_scale()
print("Depth Scale is: ",depth_scale)

# create an align object
align_to = rs.stream.color
align = rs.align(align_to)

"""
MAIN PROGRAM
"""

def main():
	# get global variables = variables that can be changed in main function
	global step_1, step_2, step_3, step_4, klick_counter,ch_poi, koord, corner_picture_0, corner_picture_1
	# start the main - try
	try:
		while True:

			frames = pipeline.wait_for_frames()
			depth_frame = frames.get_depth_frame()
			color_frame = frames.get_color_frame()
			aligned_frames = align.process(frames)
			aligned_depth_frame = aligned_frames.get_depth_frame()
			aligned_color_frame = aligned_frames.get_color_frame()

			# validate frames
			if not aligned_depth_frame or not aligned_color_frame:
				continue

			ir_left_frame = frames.get_infrared_frame(1)
			ir_right_frame = frames.get_infrared_frame(2)
			depth_image = np.asanyarray(aligned_depth_frame.get_data())
			color_image = np.asanyarray(aligned_color_frame.get_data())

			# intrinsics and extrinsics
			depth_intrin = depth_frame.profile.as_video_stream_profile().intrinsics
			color_intrin = color_frame.profile.as_video_stream_profile().intrinsics
			depth_to_color_intrin = depth_frame.profile.get_extrinsics_to(color_frame.profile)

			delta = 8
			try:

				if cv2.waitKey(1) == ord('k') or step_1 == True:
					print("Test2")
					step_1 = True
					cv2.setMouseCallback('Align Example', get_mouse_position)
					cv2.rectangle(color_image, (int(ch_poi[0][0]) - delta, int(ch_poi[0][1]) - delta), (int(ch_poi[0][0]) + delta, int(ch_poi[0][1]) + delta), red, 0)
					cv2.rectangle(color_image, (int(ch_poi[1][0]) - delta, int(ch_poi[1][1]) - delta), (int(ch_poi[1][0]) + delta, int(ch_poi[1][1]) + delta), red, 0)

					# print ix and iy
					if klick_counter <= 2:
						ch_poi[klick_counter-1][0] = ix
						ch_poi[klick_counter-1][1] = iy
						if klick_counter == 2:
							klick_counter = 0
							step_1 = False
							step_2 = True
			except:
				print ("error at second try")

			try:
				if step_2 == True:

					corner_picture_0 = color_image[int(ch_poi[0][1]) - delta: int(ch_poi[0][1]) + delta, int(ch_poi[0][0]) - delta: int(ch_poi[0][0]) + delta]
					corner_picture_1 = color_image[int(ch_poi[1][1]) - delta: int(ch_poi[1][1]) + delta, int(ch_poi[1][0]) - delta: int(ch_poi[1][0]) + delta]

					koord[0][0], koord[0][1] = good_features_to_track(corner_picture_0)
					koord[1][0], koord[1][1] = good_features_to_track(corner_picture_1)

					for i in range(0,2):
						koord[i][0] = ch_poi[i][0] - delta + koord[i][0]
						koord[i][1] = ch_poi[i][1] - delta + koord[i][1]

					cv2.rectangle(color_image, (int(koord[0][0]) - delta, int(koord[0][1]) - delta), (int(koord[0][0]) + delta, int(koord[0][1])+delta), green, 0)
					cv2.rectangle(color_image, (int(koord[1][0]) - delta, int(koord[1][1]) - delta), (int(koord[1][0]) + delta, int(koord[1][1])+delta), green, 0)

					step_3 = True
			except:
				print ("error at third try")

			try:
				zero = 0
				np.float64(zero)
				if step_3 == True:
					for i in range(0,2):
						z = aligned_depth_frame.get_distance(int(koord[i][0]), int(koord[i][1]))
						# print z
						if z > 0:
							koord[i][2] = z
					if koord[0][2] > 0 and koord[1][2] > 0:
						step_3 = False
						step_4 = True
			except:
				print ("Error at the fourth try")

			try:
				if step_4 == True:
					depth_point_1 = rs.rs2_deproject_pixel_to_point(depth_intrin, [koord[0][0], koord[0][1]], koord[0][2])
					depth_point_2 = rs.rs2_deproject_pixel_to_point(depth_intrin, [koord[1][0], koord[1][1]], koord[1][2])
					vector_12 = np.zeros((1,3))
					for i in range(0,3):
						vector_12[0][i] = depth_point_1[i] - depth_point_2[i]
					print ("the position of point 1 is " + str(depth_point_1))
					print ("the position of point 2 is " + str(depth_point_2))
					print ("the vector between the two points is " + str(vector_12))
					# dist_12 = math.sqrt(vector_12[0][0]**2 + vector_12[0][1]**2 + vector_12[0][2]**2)
					# dist_12 = dist_12 * 1000
					# dist_12 = int(dist_12)
					# print ("the 3D distance between points is " + str(dist_12) + "mm")
					step_4 = False
			except:
				print ("error at fifth try")

			try:
				cv2.namedWindow('Align Example', cv2.WINDOW_AUTOSIZE)
				cv2.imshow('Align Example', color_image)

			except:
				print ("error occured during streaming")

			if cv2.waitKey(1) == 27: # when 0. program updates whenever button is pressed. when 1 program closes when escape is held
				break
	except:
		print ("error occured in first try")
	finally:
		cv2.destroyAllWindows()
		pipeline.stop()

if __name__ == '__main__':
	main()


#!/usr/bin/env python

import gvpn_controller as gvpn
import json
import logging
import os
import select
import signal
import socket
import subprocess
import sys
import threading
import time

CONFIG = gvpn.CONFIG

# thread signal
run_event = threading.Event()

tincan_bin = None
tincan_process = None

# exit handler and register this process
def exit_handler(signum, frame):
    if tincan_process is not None:
        tincan_process.send_signal(signal.SIGINT)
    run_event.clear()

class TinCanException(Exception):
    def __init__(self):
        Exception.__init__(self)
    def __str__(self):
        return "TinCan not running properly."

class UdpServer(gvpn.UdpServer):

    def run_server(self):
        last_time = time.time()
        count = 0
        while run_event.is_set():
            self.serve()
            time_diff = time.time() - last_time
            if time_diff > CONFIG["wait_time"]:
                count += 1
                self.trim_connections()
                logging.debug("send_get_state")
                gvpn.do_get_state(self.sock)
                last_time = time.time()

class WatchDog:
    def __init__(self):
        if socket.has_ipv6:
            self.sock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
        else:
            self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        self.sock.bind(("", 0))
        self.inactive_time = time.time()

    def watch(self):
        socks = select.select([self.sock], [], [], CONFIG["wait_time"])
        if not socks[0]: # Check if the socks is empty
            if time.time() - self.inactive_time > 60:
                logging.debug("TinCan is inactive for 60s")
                raise TinCanException

        for sock in socks[0]:
            data, addr = sock.recvfrom(CONFIG["buf_size"])
            msg = json.loads(data)
            logging.debug("watchdog recv %s %s" % (addr, data))
            msg_type = msg.get("type", None)
            if msg_type == "local_state":
                self.inactive_time = time.time()

def main():

    signal.signal(signal.SIGINT, exit_handler)

    watchdog = WatchDog()

    tincan_path = CONFIG["tincan_path"]

    if os.path.exists(tincan_path):
        tincan_bin = os.path.abspath(tincan_path)

        with open("core_log", "w+") as core_log:
            logging.debug("Starting ipop-tincan");
            tincan_process = subprocess.Popen([tincan_bin],
                    stdout=subprocess.PIPE, stderr=core_log)
            time.sleep(1)

    else:
        logging.debug("TinCan binary doesn't exist at specified directory")
        sys.exit(0)

    server = UdpServer(CONFIG["xmpp_username"], CONFIG["xmpp_password"],
                     CONFIG["xmpp_host"], CONFIG["ip4"])

    run_event.set()
    t = threading.Thread(target=server.run_server)

    logging.debug("Starting Server");
    t.daemon = True
    t.start()
    last_time = time.time()
    watchdog.inactive_time = time.time()
    tincan_attempt = 0

    logging.debug("Starting WatchDog");
    while run_event.is_set():
        try:
            watchdog.watch()
            time_diff = time.time() - last_time
            if time_diff > CONFIG["wait_time"]:
                logging.debug("watchdog send_get_state")
                gvpn.do_get_state(watchdog.sock)
                last_time = time.time()
        except TinCanException:
            tincan_attempt += 1
            logging.error("TinCan Failed {0} times".format(tincan_attempt));
            os.kill(tincan_process.pid, signal.SIGTERM)
            time.sleep(1)
            if tincan_attempt > 3:
                logging.critical("TinCan Failed beyond threshold point");
                run_event.clear()
                break
            with open("core_log", "wb+") as core_log:
                tincan_process = subprocess.Popen([tincan_bin],
                        stdout=subprocess.PIPE, stderr=core_log)
                time.sleep(1)
            server.ctrl_conn_init()
            watchdog.inactive_time = time.time()

if __name__  == "__main__":
    gvpn.parse_config()
    main()