import wx
import files

class Toolbar(wx.ToolBar):
  def __init__(self,Frame,Panel):
    self.ASH_Frame = Frame
    wx.ToolBar.__init__(self,Panel, id=-1, style = wx.TB_HORIZONTAL | wx.TB_TEXT)
    (ID_NEW,ID_OPEN,ID_SAVE,ID_PLAY,ID_STOP,ID_RECORD,ID_DOWNLOAD) = (1,2,3,4,5,6,7)
    self.AddLabelTool(ID_NEW,'New', wx.Bitmap('icons/new.png'))
    self.AddLabelTool(ID_OPEN, 'Open', wx.Bitmap('icons/open.png'))
    self.AddLabelTool(ID_SAVE, 'Save', wx.Bitmap('icons/save.png'))
    self.AddSeparator()
    self.AddLabelTool(ID_PLAY, 'Play', wx.Bitmap('icons/play.png'))
    self.AddLabelTool(ID_STOP, 'Stop', wx.Bitmap('icons/stop.png'))
    self.AddLabelTool(ID_RECORD, 'Record', wx.Bitmap('icons/record.png'))
    self.AddSeparator()
    self.AddLabelTool(ID_DOWNLOAD, 'Save Song', wx.Bitmap('icons/download.jpeg'))
    self.AddSeparator()
    Frame.Bind(wx.EVT_TOOL, self.OnNew, id=ID_NEW)
    Frame.Bind(wx.EVT_TOOL, self.OnOpen, id=ID_OPEN)
    Frame.Bind(wx.EVT_TOOL, self.OnSave, id=ID_SAVE)
    Frame.Bind(wx.EVT_TOOL, self.OnPlay, id=ID_PLAY)
    Frame.Bind(wx.EVT_TOOL, self.OnStop, id=ID_STOP)
    Frame.Bind(wx.EVT_TOOL, self.OnRecord, id=ID_RECORD)
    Frame.Bind(wx.EVT_TOOL, self.OnSaveSong, id=ID_DOWNLOAD)
    self.Realize()
    self.Player = None

  def OnNew(self,event):
    files.OnNew(self.ASH_Frame)

  def OnOpen(self,event):
    files.OpenFile(self.ASH_Frame)

  def OnSave(self,event):
    files.SaveFile(self.ASH_Frame)

  def OnPlay(self,event):
    if self.ASH_Frame.Tune.TuneName != None:
      self.Player = wx.Sound(self.ASH_Frame.Tune.TuneName)
      self.Player.Play()

  def OnStop(self,event):
    if self.Player != None:
      self.Player.Stop()
      self.Player = None

  def OnRecord(self,event):
    import tune, Tkinter, tkSnack
    tune.recorder(self.ASH_Frame)
    self.ASH_Frame.Tune.TkRoot = Tkinter.Tk()
    tkSnack.initializeSnack(self.ASH_Frame.Tune.TkRoot)
    self.ASH_Frame.Tune.SnackSound.write(".tempfile.wav")
    self.ASH_Frame.Tune.SnackSound = tkSnack.Sound(load=".tempfile.wav")
    if tune.IS_RECORDED:
      self.ASH_Frame.Tune.TuneName = "saves/.temp.wav"
      self.ASH_Frame.Tune.SnackSound.read("saves/.temp.wav")
      T = self.ASH_Frame.Tune.SnackSound.length(unit="SECONDS")
      if T < 10 :
        Time = "Tune too short!"
      elif T > 20 :
        Time = "Tune too long!"
      else:
        Time = "Time : " + str() + "Sec"
      self.ASH_Frame.Tune.Time.SetLabel(Time)
      self.ASH_Frame.Tune.DrawGraph()

  def OnSaveSong(self, event):
    S = self.ASH_Frame.Song.SongList.GetSelections()
    if self.ASH_Frame.Song.Songs == None or S == ():
      Dialog = wx.MessageDialog(None, "No Song Selected.", 'Error!', wx.OK | wx.ICON_ERROR)
      Dialog.ShowModal()
    else:
      files.SaveSong(self.ASH_Frame)


# -*- coding: utf-8 -*-
"""
Spyder Editor

Author: Sudipan Saha
"""
import os
import sys
import torch
import torch.nn as nn
from torch.nn import init
import functools
from torch.optim import lr_scheduler
import numpy as np
import scipy.io as sio
from PIL import Image

import matplotlib.pyplot as plt
import h5py
import math
import matplotlib.gridspec as gridspec
import pickle as pickle
from networksForFeatureExtraction import ResnetFeatureExtractor9FeatureFromLayer23
from networksForFeatureExtraction import ResnetFeatureExtractor9FeatureFromLayer8
from networksForFeatureExtraction import ResnetFeatureExtractor9FeatureFromLayer10
from networksForFeatureExtraction import ResnetFeatureExtractor9FeatureFromLayer11
from networksForFeatureExtraction import ResnetFeatureExtractor9FeatureFromLayer5
from networksForFeatureExtraction import ResnetFeatureExtractor9FeatureFromLayer2
from skimage.transform import resize
from skimage import filters
from skimage import morphology
import cv2 as cv
from kmodes.kmodes import KModes
import PIL
import cv2
from scipy.spatial.distance import cdist
import scipy.stats as sistats
from saturateSomePercentile import saturateImage
from options import optionsDCVA
import sklearn.metrics as mt

##Parsing options
opt = optionsDCVA().parseOptions()
dataPath = opt.dataPath
inputChannels = opt.inputChannels
outputLayerNumbers = np.array(opt.layersToProcess.split(','),dtype=np.int)
thresholdingStrategy = opt.thresholding
otsuScalingFactor = opt.otsuScalingFactor
objectMinSize = opt.objectMinSize
topPercentSaturationOfImageOk=opt.topPercentSaturationOfImageOk
topPercentToSaturate=opt.topPercentToSaturate
multipleCDBool=opt.multipleCDBool
changeVectorBinarizationStrategy=opt.changeVectorBinarizationStrategy
clusteringStrategy=opt.clusteringStrategy
clusterNumber=opt.clusterNumber
hierarchicalDistanceStrategy=opt.hierarchicalDistanceStrategy

nanVar=float('nan')

#Defining parameters related to the CNN
sizeReductionTable=[nanVar,nanVar,1,nanVar,nanVar,2,nanVar,nanVar,4,nanVar,\
                            4,4,4,4,4,4,4,4,4,
                            nanVar,2,nanVar,nanVar,1,nanVar,nanVar,1,1]
featurePercentileToDiscardTable=[nanVar,nanVar,90,nanVar,nanVar,90,nanVar,nanVar,95,nanVar,\
                            95,95,95,95,95,95,95,95,95,nanVar,95,nanVar,nanVar,95
                            ,nanVar,nanVar,0,0]
filterNumberTable=[nanVar,nanVar,64,nanVar,nanVar,128,nanVar,nanVar,256,nanVar,\
                            256,256,256,256,256,256,256,256,256,nanVar,128,nanVar,nanVar,64,nanVar,nanVar,1,1]

def CVA(preChangeImage, postChangeImage):
    preChangeImageOriginalShape = preChangeImage.shape
    if preChangeImageOriginalShape[0]<preChangeImageOriginalShape[1]: ##code is written in a way s.t. it expects row>col
        preChangeImage = np.swapaxes(preChangeImage,0,1)
        postChangeImage = np.swapaxes(postChangeImage,0,1)

    #Pre-change and post-change image normalization
    if topPercentSaturationOfImageOk:
        axis = preChangeImage.shape[2]
        preChangeImageNormalized=saturateImage().saturateSomePercentileMultispectral(preChangeImage, topPercentToSaturate, axis)
        postChangeImageNormalized=saturateImage().saturateSomePercentileMultispectral(postChangeImage, topPercentToSaturate, axis)

    #Reassigning pre-change and post-change image to normalized values
    data1=np.copy(preChangeImageNormalized)
    data2=np.copy(postChangeImageNormalized)

    #Checking image dimension
    imageSize=data1.shape
    imageSizeRow=imageSize[0]
    imageSizeCol=imageSize[1]
    imageNumberOfChannel=imageSize[2]

    #Initilizing net / model (G_B: acts as feature extractor here)
    input_nc=imageNumberOfChannel #input number of channels
    output_nc=6 #from Potsdam dataset number of classes
    ngf=64 # number of gen filters in first conv layer
    norm_layer = nn.BatchNorm2d
    use_dropout=False

    netForFeatureExtractionLayer23=ResnetFeatureExtractor9FeatureFromLayer23(input_nc, output_nc, ngf, norm_layer, use_dropout, 9)
    netForFeatureExtractionLayer11=ResnetFeatureExtractor9FeatureFromLayer11(input_nc, output_nc, ngf, norm_layer, use_dropout, 9)
    netForFeatureExtractionLayer10=ResnetFeatureExtractor9FeatureFromLayer10(input_nc, output_nc, ngf, norm_layer, use_dropout, 9)
    netForFeatureExtractionLayer8=ResnetFeatureExtractor9FeatureFromLayer8(input_nc, output_nc, ngf, norm_layer, use_dropout, 9)
    netForFeatureExtractionLayer5=ResnetFeatureExtractor9FeatureFromLayer5(input_nc, output_nc, ngf, norm_layer, use_dropout, 9)
    netForFeatureExtractionLayer2=ResnetFeatureExtractor9FeatureFromLayer2(input_nc, output_nc, ngf, norm_layer, use_dropout, 9)
    if inputChannels=='RGB':
        state_dict=torch.load('/data/xuqs/Change_detection/Change_detection_1222/Baselines/PytorchStyleFormer-main/PytorchStyleFormer-main/trainedNet/RGB/trainedModelFinal')
        if imageNumberOfChannel!=3:
            sys.exit('Input images do not have 3 channels while loaded model is for R-G-B input')
    elif inputChannels=='RGBNIR':
        state_dict=torch.load('/data/xuqs/Change_detection/Change_detection_1222/Baselines/PytorchStyleFormer-main/PytorchStyleFormer-main/trainedNet/RGBIR/trainedModelFinal')
        if imageNumberOfChannel!=4:
            sys.exit('Input images do not have 4 channels while loaded model is for R-G-B-NIR input')
    else:
        sys.exit('Image channels not valid - valid arguments RGB or RGBNIR')
    # state_dict=torch.load('./trainedNet/RGBIR/trainedModelFinal')

    #for name, param in state_dict.items():
    #    print(name)

    netForFeatureExtractionLayer23Dict=netForFeatureExtractionLayer23.state_dict()
    state_dictForLayer23=state_dict
    state_dictForLayer23={k: v for k, v in netForFeatureExtractionLayer23Dict.items() if k in state_dictForLayer23}

    netForFeatureExtractionLayer11Dict=netForFeatureExtractionLayer11.state_dict()
    state_dictForLayer11=state_dict
    state_dictForLayer11={k: v for k, v in netForFeatureExtractionLayer11Dict.items() if k in state_dictForLayer11}

    netForFeatureExtractionLayer10Dict=netForFeatureExtractionLayer10.state_dict()
    state_dictForLayer10=state_dict
    state_dictForLayer10={k: v for k, v in netForFeatureExtractionLayer10Dict.items() if k in state_dictForLayer10}

    netForFeatureExtractionLayer8Dict=netForFeatureExtractionLayer8.state_dict()
    state_dictForLayer8=state_dict
    state_dictForLayer8={k: v for k, v in netForFeatureExtractionLayer8Dict.items() if k in state_dictForLayer8}

    netForFeatureExtractionLayer5Dict=netForFeatureExtractionLayer5.state_dict()
    state_dictForLayer5=state_dict
    state_dictForLayer5={k: v for k, v in netForFeatureExtractionLayer5Dict.items() if k in state_dictForLayer5}

    netForFeatureExtractionLayer2Dict=netForFeatureExtractionLayer2.state_dict()
    state_dictForLayer2=state_dict
    state_dictForLayer2={k: v for k, v in netForFeatureExtractionLayer2Dict.items() if k in state_dictForLayer2}

    netForFeatureExtractionLayer23.load_state_dict(state_dictForLayer23)
    netForFeatureExtractionLayer11.load_state_dict(state_dictForLayer11)
    netForFeatureExtractionLayer10.load_state_dict(state_dictForLayer10)
    netForFeatureExtractionLayer8.load_state_dict(state_dictForLayer8)
    netForFeatureExtractionLayer5.load_state_dict(state_dictForLayer5)
    netForFeatureExtractionLayer2.load_state_dict(state_dictForLayer2)

    input_nc=imageNumberOfChannel #input number of channels
    output_nc=imageNumberOfChannel #output number of channels
    ngf=64 # number of gen filters in first conv layer
    norm_layer = functools.partial(nn.InstanceNorm2d, affine=False, track_running_stats=True)
    use_dropout=False

    ##changing all nets to eval mode
    netForFeatureExtractionLayer23.eval()
    netForFeatureExtractionLayer23.requires_grad=False

    netForFeatureExtractionLayer11.eval()
    netForFeatureExtractionLayer11.requires_grad=False

    netForFeatureExtractionLayer10.eval()
    netForFeatureExtractionLayer10.requires_grad=False

    netForFeatureExtractionLayer8.eval()
    netForFeatureExtractionLayer8.requires_grad=False

    netForFeatureExtractionLayer5.eval()
    netForFeatureExtractionLayer5.requires_grad=False

    netForFeatureExtractionLayer2.eval()
    netForFeatureExtractionLayer2.requires_grad=False

    torch.no_grad()

    eachPatch=imageSizeRow
    numImageSplitRow=imageSizeRow/eachPatch
    numImageSplitCol=imageSizeCol/eachPatch
    cutY=list(range(0,imageSizeRow,eachPatch))
    cutX=list(range(0,imageSizeCol,eachPatch))
    additionalPatchPixel=64

    layerWiseFeatureExtractorFunction=[nanVar,nanVar,netForFeatureExtractionLayer2,nanVar,nanVar,netForFeatureExtractionLayer5,nanVar,nanVar,netForFeatureExtractionLayer8,nanVar,\
                                netForFeatureExtractionLayer10,netForFeatureExtractionLayer11,nanVar,nanVar,nanVar,nanVar,nanVar,nanVar,nanVar,nanVar,\
                                nanVar,nanVar,nanVar,netForFeatureExtractionLayer23,nanVar,nanVar,nanVar,nanVar]

    ##Checking validity of feature extraction layers
    validFeatureExtractionLayers=[2,5,8,10,11,23] ##Feature extraction from only these layers have been defined here
    for outputLayer in outputLayerNumbers:
        if outputLayer not in validFeatureExtractionLayers:
            sys.exit('Feature extraction layer is not valid, valid values are 2,5,8,10,11,23')

    ##Extracting bi-temporal features
    modelInputMean=0.406

    for outputLayerIter in range(0,len(outputLayerNumbers)):
            outputLayerNumber=outputLayerNumbers[outputLayerIter]
            filterNumberForOutputLayer=filterNumberTable[outputLayerNumber]
            featurePercentileToDiscard=featurePercentileToDiscardTable[outputLayerNumber]
            featureNumberToRetain=int(np.floor(filterNumberForOutputLayer*((100-featurePercentileToDiscard)/100)))
            sizeReductionForOutputLayer=sizeReductionTable[outputLayerNumber]
            patchOffsetFactor=int(additionalPatchPixel/sizeReductionForOutputLayer)
            print('Processing layer number:'+str(outputLayerNumber))

            timeVector1Feature=np.zeros([imageSizeRow,imageSizeCol,filterNumberForOutputLayer])
            timeVector2Feature=np.zeros([imageSizeRow,imageSizeCol,filterNumberForOutputLayer])

            if ((imageSizeRow<eachPatch) | (imageSizeCol<eachPatch)):
                if imageSizeRow>imageSizeCol:
                    patchToProcessDate1=np.pad(data1,[(0,0),(0,imageSizeRow-imageSizeCol),(0,0)],'symmetric')
                    patchToProcessDate2=np.pad(data2,[(0,0),(0,imageSizeRow-imageSizeCol),(0,0)],'symmetric')
                if imageSizeCol>imageSizeRow:
                    patchToProcessDate1=np.pad(data1,[(0,imageSizeCol-imageSizeRow),(0,0),(0,0)],'symmetric')
                    patchToProcessDate2=np.pad(data2,[(0,imageSizeCol-imageSizeRow),(0,0),(0,0)],'symmetric')
                if imageSizeRow==imageSizeCol:
                    patchToProcessDate1=data1
                    patchToProcessDate2=data2
                #print('This image (or this subpatch) is small and hence processing in 1 step')
                 #converting to pytorch varibales and changing dimension for input to net
                patchToProcessDate1=patchToProcessDate1-modelInputMean
                inputToNetDate1=torch.from_numpy(patchToProcessDate1)
                inputToNetDate1=inputToNetDate1.float()
                inputToNetDate1=np.swapaxes(inputToNetDate1,0,2)
                inputToNetDate1=np.swapaxes(inputToNetDate1,1,2)
                inputToNetDate1=inputToNetDate1.unsqueeze(0)
                del patchToProcessDate1

                patchToProcessDate2=patchToProcessDate2-modelInputMean
                inputToNetDate2=torch.from_numpy(patchToProcessDate2)
                inputToNetDate2=inputToNetDate2.float()
                inputToNetDate2=np.swapaxes(inputToNetDate2,0,2)
                inputToNetDate2=np.swapaxes(inputToNetDate2,1,2)
                inputToNetDate2=inputToNetDate2.unsqueeze(0)
                del patchToProcessDate2

                #running model on image 1 and converting features to numpy format
                with torch.no_grad():
                    obtainedFeatureVals1=layerWiseFeatureExtractorFunction[outputLayerNumber](inputToNetDate1)
                obtainedFeatureVals1=obtainedFeatureVals1.squeeze()
                obtainedFeatureVals1=obtainedFeatureVals1.data.numpy()
                del inputToNetDate1

                #running model on image 2 and converting features to numpy format
                with torch.no_grad():
                    obtainedFeatureVals2=layerWiseFeatureExtractorFunction[outputLayerNumber](inputToNetDate2)
                obtainedFeatureVals2=obtainedFeatureVals2.squeeze()
                obtainedFeatureVals2=obtainedFeatureVals2.data.numpy()
                del inputToNetDate2

                for processingFeatureIter in range(0,filterNumberForOutputLayer):
                                timeVector1Feature[0:imageSizeRow,\
                                               0:imageSizeCol,processingFeatureIter]=\
                                               resize(obtainedFeatureVals1[processingFeatureIter,\
                                                                           0:int(imageSizeRow/sizeReductionForOutputLayer),\
                                                                           0:int(imageSizeCol/sizeReductionForOutputLayer)],\
                                                                           (imageSizeRow,imageSizeCol))
                for processingFeatureIter in range(0,filterNumberForOutputLayer):
                                timeVector2Feature[0:imageSizeRow,\
                                               0:imageSizeCol,processingFeatureIter]=\
                                               resize(obtainedFeatureVals2[processingFeatureIter,\
                                                                           0:int(imageSizeRow/sizeReductionForOutputLayer),\
                                                                           0:int(imageSizeCol/sizeReductionForOutputLayer)],\
                                                                           (imageSizeRow,imageSizeCol))

            if not((imageSizeRow<eachPatch) | (imageSizeCol<eachPatch)):
                for kY in range(0,len(cutY)):
                    for kX in range(0,len(cutX)):

                        #extracting subset of image 1
                        if (kY==0 and kX==0):
                            patchToProcessDate1=data1[cutY[kY]:(cutY[kY]+eachPatch+additionalPatchPixel),\
                                                           cutX[kX]:(cutX[kX]+eachPatch+additionalPatchPixel),:]
                        elif (kY==0 and kX!=(len(cutX)-1)):
                            patchToProcessDate1=data1[cutY[kY]:(cutY[kY]+eachPatch+additionalPatchPixel),\
                                                           (cutX[kX]-additionalPatchPixel):(cutX[kX]+eachPatch),:]
                        elif (kY!=(len(cutY)-1) and kX==(len(cutX)-1)):
                            patchToProcessDate1=data1[cutY[kY]:(cutY[kY]+eachPatch+additionalPatchPixel),\
                                                           (imageSizeCol-eachPatch-additionalPatchPixel):(imageSizeCol),:]
                        elif (kX==0 and kY!=(len(cutY)-1)):
                            patchToProcessDate1=data1[(cutY[kY]-additionalPatchPixel):\
                                                      (cutY[kY]+eachPatch),\
                                                           cutX[kX]:(cutX[kX]+eachPatch+additionalPatchPixel),:]
                        elif (kX!=(len(cutX)-1) and kY==(len(cutY)-1)):
                            patchToProcessDate1=data1[(imageSizeRow-eachPatch-additionalPatchPixel):\
                                                      (imageSizeRow),\
                                                           cutX[kX]:(cutX[kX]+eachPatch+additionalPatchPixel),:]
                        elif (kY==(len(cutY)-1) and kX==(len(cutX)-1)):
                            patchToProcessDate1=data1[(imageSizeRow-eachPatch-additionalPatchPixel):\
                                                      (imageSizeRow),\
                                                           (imageSizeCol-eachPatch-additionalPatchPixel):(imageSizeCol),:]
                        else:
                            patchToProcessDate1=data1[(cutY[kY]-additionalPatchPixel):\
                                                      (cutY[kY]+eachPatch),\
                                                      (cutX[kX]-additionalPatchPixel):(cutX[kX]+eachPatch),:]
                        #extracting subset of image 2
                        if (kY==0 and kX==0):
                            patchToProcessDate2=data2[cutY[kY]:(cutY[kY]+eachPatch+additionalPatchPixel),\
                                                           cutX[kX]:(cutX[kX]+eachPatch+additionalPatchPixel),:]
                        elif (kY==0 and kX!=(len(cutX)-1)):
                            patchToProcessDate2=data2[cutY[kY]:(cutY[kY]+eachPatch+additionalPatchPixel),\
                                                           (cutX[kX]-additionalPatchPixel):(cutX[kX]+eachPatch),:]
                        elif (kY!=(len(cutY)-1) and kX==(len(cutX)-1)):
                            patchToProcessDate2=data2[cutY[kY]:(cutY[kY]+eachPatch+additionalPatchPixel),\
                                                           (imageSizeCol-eachPatch-additionalPatchPixel):(imageSizeCol),:]
                        elif (kX==0 and kY!=(len(cutY)-1)):
                            patchToProcessDate2=data2[(cutY[kY]-additionalPatchPixel):\
                                                      (cutY[kY]+eachPatch),\
                                                          cutX[kX]:(cutX[kX]+eachPatch+additionalPatchPixel),:]
                        elif (kX!=(len(cutX)-1) and kY==(len(cutY)-1)):
                            patchToProcessDate2=data2[(imageSizeRow-eachPatch-additionalPatchPixel):\
                                                      (imageSizeRow),\
                                                           cutX[kX]:(cutX[kX]+eachPatch+additionalPatchPixel),:]
                        elif (kY==(len(cutY)-1) and kX==(len(cutX)-1)):
                            patchToProcessDate2=data2[(imageSizeRow-eachPatch-additionalPatchPixel):\
                                                      (imageSizeRow),\
                                                           (imageSizeCol-eachPatch-additionalPatchPixel):(imageSizeCol),:]
                        else:
                            patchToProcessDate2=data2[(cutY[kY]-additionalPatchPixel):\
                                                      (cutY[kY]+eachPatch),\
                                                      (cutX[kX]-additionalPatchPixel):(cutX[kX]+eachPatch),:]
                        print(kY)
                        print(kX)
                        print(patchToProcessDate1.shape)
                        print(patchToProcessDate2.shape)

                        #converting to pytorch varibales and changing dimension for input to net
                        patchToProcessDate1=patchToProcessDate1-modelInputMean

                        inputToNetDate1=torch.from_numpy(patchToProcessDate1)
                        del patchToProcessDate1
                        inputToNetDate1=inputToNetDate1.float()
                        inputToNetDate1=np.swapaxes(inputToNetDate1,0,2)
                        inputToNetDate1=np.swapaxes(inputToNetDate1,1,2)
                        inputToNetDate1=inputToNetDate1.unsqueeze(0)

                        patchToProcessDate2=patchToProcessDate2-modelInputMean

                        inputToNetDate2=torch.from_numpy(patchToProcessDate2)
                        del patchToProcessDate2
                        inputToNetDate2=inputToNetDate2.float()
                        inputToNetDate2=np.swapaxes(inputToNetDate2,0,2)
                        inputToNetDate2=np.swapaxes(inputToNetDate2,1,2)
                        inputToNetDate2=inputToNetDate2.unsqueeze(0)

                        #running model on image 1 and converting features to numpy format
                        with torch.no_grad():
                            obtainedFeatureVals1=layerWiseFeatureExtractorFunction[outputLayerNumber](inputToNetDate1)
                        obtainedFeatureVals1=obtainedFeatureVals1.squeeze()
                        obtainedFeatureVals1=obtainedFeatureVals1.data.numpy()
                        del inputToNetDate1

                        #running model on image 2 and converting features to numpy format
                        with torch.no_grad():
                            obtainedFeatureVals2=layerWiseFeatureExtractorFunction[outputLayerNumber](inputToNetDate2)
                        obtainedFeatureVals2=obtainedFeatureVals2.squeeze()
                        obtainedFeatureVals2=obtainedFeatureVals2.data.numpy()
                        del inputToNetDate2
                        #this features are in format (filterNumber, sizeRow, sizeCol)

                        ##clipping values to +1 to -1 range, be careful, if network is changed, maybe we need to modify this
                        obtainedFeatureVals1=np.clip(obtainedFeatureVals1,-1,+1)
                        obtainedFeatureVals2=np.clip(obtainedFeatureVals2,-1,+1)

                        #obtaining features from image 1: resizing and truncating additionalPatchPixel
                        if (kY==0 and kX==0):
                            for processingFeatureIter in range(0,filterNumberForOutputLayer):
                                timeVector1Feature[cutY[kY]:(cutY[kY]+eachPatch),\
                                               cutX[kX]:(cutX[kX]+eachPatch),processingFeatureIter]=\
                                               resize(obtainedFeatureVals1[processingFeatureIter,\
                                                                           0:int(eachPatch/sizeReductionForOutputLayer),\
                                                                           0:int(eachPatch/sizeReductionForOutputLayer)],\
                                                                           (eachPatch,eachPatch))

                        elif (kY==0 and kX!=(len(cutX)-1)):
                            for processingFeatureIter in range(0,filterNumberForOutputLayer):
                                timeVector1Feature[cutY[kY]:(cutY[kY]+eachPatch),\
                                               cutX[kX]:(cutX[kX]+eachPatch),processingFeatureIter]=\
                                               resize(obtainedFeatureVals1[processingFeatureIter,\
                                                                           0:int(eachPatch/sizeReductionForOutputLayer),\
                                                                           (patchOffsetFactor+1):\
                                                                           (int(eachPatch/sizeReductionForOutputLayer)+patchOffsetFactor+1)],\
                                                                           (eachPatch,eachPatch))
                        elif (kY!=(len(cutY)-1) and kX==(len(cutX)-1)):
                            for processingFeatureIter in range(0,filterNumberForOutputLayer):
                                timeVector1Feature[cutY[kY]:(cutY[kY]+eachPatch),\
                                               cutX[kX]:imageSizeCol,processingFeatureIter]=\
                                               resize(obtainedFeatureVals1[processingFeatureIter,\
                                                                           0:int(eachPatch/sizeReductionForOutputLayer),\
                                                                           (obtainedFeatureVals1.shape[2]-1-int((imageSizeCol-cutX[kX])/sizeReductionForOutputLayer)):\
                                                                           (obtainedFeatureVals1.shape[2])],\
                                                                           (eachPatch,(imageSizeCol-cutX[kX])))
                        elif (kX==0 and kY!=(len(cutY)-1)):
                            for processingFeatureIter in range(0,filterNumberForOutputLayer):
                                timeVector1Feature[cutY[kY]:(cutY[kY]+eachPatch),\
                                               cutX[kX]:(cutX[kX]+eachPatch),processingFeatureIter]=\
                                               resize(obtainedFeatureVals1[processingFeatureIter,\
                                                                           (patchOffsetFactor+1):\
                                                                           (int(eachPatch/sizeReductionForOutputLayer)+patchOffsetFactor+1),\
                                                                           0:int(eachPatch/sizeReductionForOutputLayer)],\
                                                                           (eachPatch,eachPatch))
                        elif (kX!=(len(cutX)-1) and kY==(len(cutY)-1)):
                            for processingFeatureIter in range(0,filterNumberForOutputLayer):
                                timeVector1Feature[cutY[kY]:imageSizeRow,\
                                               cutX[kX]:(cutX[kX]+eachPatch),processingFeatureIter]=\
                                               resize(obtainedFeatureVals1[processingFeatureIter,\
                                                                           (obtainedFeatureVals1.shape[1]-1-int((imageSizeRow-cutY[kY])/sizeReductionForOutputLayer)):\
                                                                           (obtainedFeatureVals1.shape[1]),\
                                                                           0:int(eachPatch/sizeReductionForOutputLayer)],\
                                                                           ((imageSizeRow-cutY[kY]),eachPatch))
                        elif (kX==(len(cutX)-1) and kY==(len(cutY)-1)):
                            for processingFeatureIter in range(0,filterNumberForOutputLayer):
                                timeVector1Feature[cutY[kY]:(cutY[kY]+eachPatch),\
                                               cutX[kX]:(cutX[kX]+eachPatch),processingFeatureIter]=\
                                               resize(obtainedFeatureVals1[processingFeatureIter,\
                                                                           (obtainedFeatureVals1.shape[1]-1-int((imageSizeRow-cutY[kY])/sizeReductionForOutputLayer)):\
                                                                           (obtainedFeatureVals1.shape[1]),\
                                                                           (obtainedFeatureVals1.shape[2]-1-int((imageSizeCol-cutX[kX])/sizeReductionForOutputLayer)):\
                                                                           (obtainedFeatureVals1.shape[2])],\
                                                                           ((imageSizeRow-cutY[kY]),(imageSizeCol-cutX[kX])))
                        else:
                            for processingFeatureIter in range(0,filterNumberForOutputLayer):
                                timeVector1Feature[cutY[kY]:(cutY[kY]+eachPatch),\
                                               cutX[kX]:(cutX[kX]+eachPatch),processingFeatureIter]=\
                                               resize(obtainedFeatureVals1[processingFeatureIter,\
                                                                           (patchOffsetFactor+1):\
                                                                           (int(eachPatch/sizeReductionForOutputLayer)+patchOffsetFactor+1),\
                                                                           (patchOffsetFactor+1):\
                                                                           (int(eachPatch/sizeReductionForOutputLayer)+patchOffsetFactor+1)],\
                                                                           (eachPatch,eachPatch))
                        #obtaining features from image 2: resizing and truncating additionalPatchPixel
                        if (kY==0 and kX==0):
                            for processingFeatureIter in range(0,filterNumberForOutputLayer):
                                timeVector2Feature[cutY[kY]:(cutY[kY]+eachPatch),\
                                               cutX[kX]:(cutX[kX]+eachPatch),processingFeatureIter]=\
                                               resize(obtainedFeatureVals2[processingFeatureIter,\
                                                                           0:int(eachPatch/sizeReductionForOutputLayer),\
                                                                           0:int(eachPatch/sizeReductionForOutputLayer)],\
                                                                           (eachPatch,eachPatch))

                        elif (kY==0 and kX!=(len(cutX)-1)):
                            for processingFeatureIter in range(0,filterNumberForOutputLayer):
                                timeVector2Feature[cutY[kY]:(cutY[kY]+eachPatch),\
                                               cutX[kX]:(cutX[kX]+eachPatch),processingFeatureIter]=\
                                               resize(obtainedFeatureVals2[processingFeatureIter,\
                                                                           0:int(eachPatch/sizeReductionForOutputLayer),\
                                                                           (patchOffsetFactor+1):\
                                                                           (int(eachPatch/sizeReductionForOutputLayer)+patchOffsetFactor+1)],\
                                                                           (eachPatch,eachPatch))
                        elif (kY!=(len(cutY)-1) and kX==(len(cutX)-1)):
                            for processingFeatureIter in range(0,filterNumberForOutputLayer):
                                timeVector2Feature[cutY[kY]:(cutY[kY]+eachPatch),\
                                               cutX[kX]:imageSizeCol,processingFeatureIter]=\
                                               resize(obtainedFeatureVals2[processingFeatureIter,\
                                                                           0:int(eachPatch/sizeReductionForOutputLayer),\
                                                                           (obtainedFeatureVals2.shape[2]-1-int((imageSizeCol-cutX[kX])/sizeReductionForOutputLayer)):\
                                                                           (obtainedFeatureVals2.shape[2])],\
                                                                           (eachPatch,(imageSizeCol-cutX[kX])))
                        elif (kX==0 and kY!=(len(cutY)-1)):
                            for processingFeatureIter in range(0,filterNumberForOutputLayer):
                                timeVector2Feature[cutY[kY]:(cutY[kY]+eachPatch),\
                                               cutX[kX]:(cutX[kX]+eachPatch),processingFeatureIter]=\
                                               resize(obtainedFeatureVals2[processingFeatureIter,\
                                                                           (patchOffsetFactor+1):\
                                                                           (int(eachPatch/sizeReductionForOutputLayer)+patchOffsetFactor+1),\
                                                                           0:int(eachPatch/sizeReductionForOutputLayer)],\
                                                                           (eachPatch,eachPatch))
                        elif (kX!=(len(cutX)-1) and kY==(len(cutY)-1)):
                            for processingFeatureIter in range(0,filterNumberForOutputLayer):
                                timeVector2Feature[cutY[kY]:imageSizeRow,\
                                               cutX[kX]:(cutX[kX]+eachPatch),processingFeatureIter]=\
                                               resize(obtainedFeatureVals2[processingFeatureIter,\
                                                                           (obtainedFeatureVals2.shape[1]-1-int((imageSizeRow-cutY[kY])/sizeReductionForOutputLayer)):\
                                                                           (obtainedFeatureVals2.shape[1]),\
                                                                           0:int(eachPatch/sizeReductionForOutputLayer)],\
                                                                           ((imageSizeRow-cutY[kY]),eachPatch))
                        elif (kX==(len(cutX)-1) and kY==(len(cutY)-1)):
                            for processingFeatureIter in range(0,filterNumberForOutputLayer):
                                timeVector2Feature[cutY[kY]:(cutY[kY]+eachPatch),\
                                               cutX[kX]:(cutX[kX]+eachPatch),processingFeatureIter]=\
                                               resize(obtainedFeatureVals2[processingFeatureIter,\
                                                                           (obtainedFeatureVals2.shape[1]-1-int((imageSizeRow-cutY[kY])/sizeReductionForOutputLayer)):\
                                                                           (obtainedFeatureVals2.shape[1]),\
                                                                           (obtainedFeatureVals2.shape[2]-1-int((imageSizeCol-cutX[kX])/sizeReductionForOutputLayer)):\
                                                                           (obtainedFeatureVals2.shape[2])],\
                                                                           ((imageSizeRow-cutY[kY]),(imageSizeCol-cutX[kX])))
                        else:
                            for processingFeatureIter in range(0,filterNumberForOutputLayer):
                                timeVector2Feature[cutY[kY]:(cutY[kY]+eachPatch),\
                                               cutX[kX]:(cutX[kX]+eachPatch),processingFeatureIter]=\
                                               resize(obtainedFeatureVals2[processingFeatureIter,\
                                                                           (patchOffsetFactor+1):\
                                                                           (int(eachPatch/sizeReductionForOutputLayer)+patchOffsetFactor+1),\
                                                                           (patchOffsetFactor+1):\
                                                                           (int(eachPatch/sizeReductionForOutputLayer)+patchOffsetFactor+1)],\
                                                                           (eachPatch,eachPatch))

            del  obtainedFeatureVals1,obtainedFeatureVals2
            timeVectorDifferenceMatrix=timeVector1Feature-timeVector2Feature
            print(timeVectorDifferenceMatrix.shape)

            nonZeroVector=[]
            stepSizeForStdCalculation=int(imageSizeRow/2)
            for featureSelectionIter1 in range(0,imageSizeRow,stepSizeForStdCalculation):
                for featureSelectionIter2 in range(0,imageSizeCol,stepSizeForStdCalculation):
                    timeVectorDifferenceSelectedRegion=timeVectorDifferenceMatrix\
                                                       [featureSelectionIter1:(featureSelectionIter1+stepSizeForStdCalculation),\
                                                        featureSelectionIter2:(featureSelectionIter2+stepSizeForStdCalculation),
                                                        0:filterNumberForOutputLayer]
                    stdVectorDifferenceSelectedRegion=np.std(timeVectorDifferenceSelectedRegion,axis=(0,1))
                    featuresOrderedPerStd=np.argsort(-stdVectorDifferenceSelectedRegion)   #negated array to get argsort result in descending order
                    nonZeroVectorSelectedRegion=featuresOrderedPerStd[0:featureNumberToRetain]
                    nonZeroVector=np.union1d(nonZeroVector,nonZeroVectorSelectedRegion)

            modifiedTimeVector1=timeVector1Feature[:,:,nonZeroVector.astype(int)]
            modifiedTimeVector2=timeVector2Feature[:,:,nonZeroVector.astype(int)]
            del timeVector1Feature,timeVector2Feature

            ##Normalize the features (separate for both images)
            meanVectorsTime1Image=np.mean(modifiedTimeVector1,axis=(0,1))
            stdVectorsTime1Image=np.std(modifiedTimeVector1,axis=(0,1))
            normalizedModifiedTimeVector1=(modifiedTimeVector1-meanVectorsTime1Image)/stdVectorsTime1Image

            meanVectorsTime2Image=np.mean(modifiedTimeVector2,axis=(0,1))
            stdVectorsTime2Image=np.std(modifiedTimeVector2,axis=(0,1))
            normalizedModifiedTimeVector2=(modifiedTimeVector2-meanVectorsTime2Image)/stdVectorsTime2Image

            ##feature aggregation across channels
            if outputLayerIter==0:
                timeVector1FeatureAggregated=np.copy(normalizedModifiedTimeVector1)
                timeVector2FeatureAggregated=np.copy(normalizedModifiedTimeVector2)
            else:
                timeVector1FeatureAggregated=np.concatenate((timeVector1FeatureAggregated,normalizedModifiedTimeVector1),axis=2)
                timeVector2FeatureAggregated=np.concatenate((timeVector2FeatureAggregated,normalizedModifiedTimeVector2),axis=2)

    del netForFeatureExtractionLayer5, netForFeatureExtractionLayer8, netForFeatureExtractionLayer10, netForFeatureExtractionLayer11,netForFeatureExtractionLayer23

    axis = timeVector1FeatureAggregated.shape[2]
    absoluteModifiedTimeVectorDifference=np.absolute(saturateImage().saturateSomePercentileMultispectral(timeVector1FeatureAggregated,5,axis)-\
    saturateImage().saturateSomePercentileMultispectral(timeVector2FeatureAggregated,5,axis))

    #take absolute value for binary CD
    detectedChangeMap=np.linalg.norm(absoluteModifiedTimeVectorDifference,axis=(2))
    detectedChangeMapNormalized=(detectedChangeMap-np.amin(detectedChangeMap))/(np.amax(detectedChangeMap)-np.amin(detectedChangeMap))
    # detectedChangeMapNormalized = np.swapaxes(detectedChangeMapNormalized, 0, 1)
    return detectedChangeMapNormalized


import json
from typing import Any, Dict, Tuple

import factory
import httpx
from pytest_httpx import HTTPXMock

import assemblyai as aai
from assemblyai.api import ENDPOINT_TRANSCRIPT
from tests.unit import factories

aai.settings.api_key = "test"

class AutohighlightResultFactory(factory.Factory):
    class Meta:
        model = aai.types.AutohighlightResult

    count = factory.Faker("pyint")
    rank = factory.Faker("pyfloat")
    text = factory.Faker("sentence")
    timestamps = factory.List([factory.SubFactory(factories.TimestampFactory)])

class AutohighlightResponseFactory(factory.Factory):
    class Meta:
        model = aai.types.AutohighlightResponse

    status = aai.types.StatusResult.success
    results = factory.List([factory.SubFactory(AutohighlightResultFactory)])

class AutohighlightTranscriptResponseFactory(
    factories.TranscriptCompletedResponseFactory
):
    auto_highlights_result = factory.SubFactory(AutohighlightResponseFactory)

def __submit_mock_request(
    httpx_mock: HTTPXMock,
    mock_response: Dict[str, Any],
    config: aai.TranscriptionConfig,
) -> Tuple[Dict[str, Any], aai.Transcript]:
    """
    Helper function to abstract mock transcriber calls with given `TranscriptionConfig`,
    and perform some common assertions.
    """

    mock_transcript_id = mock_response.get("id", "mock_id")

    # Mock initial submission response (transcript is processing)
    mock_processing_response = factories.generate_dict_factory(
        factories.TranscriptProcessingResponseFactory
    )()

    httpx_mock.add_response(
        url=f"{aai.settings.base_url}{ENDPOINT_TRANSCRIPT}",
        status_code=httpx.codes.OK,
        method="POST",
        json={
            **mock_processing_response,
            "id": mock_transcript_id,  # inject ID from main mock response
        },
    )

    # Mock polling-for-completeness response, with completed transcript
    httpx_mock.add_response(
        url=f"{aai.settings.base_url}{ENDPOINT_TRANSCRIPT}/{mock_transcript_id}",
        status_code=httpx.codes.OK,
        method="GET",
        json=mock_response,
    )

    # == Make API request via SDK ==
    transcript = aai.Transcriber().transcribe(
        data="https://example.org/audio.wav",
        config=config,
    )

    # Check that submission and polling requests were made
    assert len(httpx_mock.get_requests()) == 2

    # Extract body of initial submission request
    request = httpx_mock.get_requests()[0]
    request_body = json.loads(request.content.decode())

    return request_body, transcript

def test_auto_highlights_disabled_by_default(httpx_mock: HTTPXMock):
    """
    Tests that excluding `auto_highlights` from the `TranscriptionConfig` will
    result in the default behavior of it being excluded from the request body
    """
    request_body, transcript = __submit_mock_request(
        httpx_mock,
        mock_response=factories.generate_dict_factory(
            factories.TranscriptCompletedResponseFactory
        )(),
        config=aai.TranscriptionConfig(),
    )
    assert request_body.get("auto_highlights") is None
    assert transcript.auto_highlights is None

def test_auto_highlights_enabled(httpx_mock: HTTPXMock):
    """
    Tests that including `auto_highlights=True` in the `TranscriptionConfig`
    will result in `auto_highlights=True` in the request body, and that the
    response is properly parsed into a `Transcript` object
    """
    mock_response = factories.generate_dict_factory(
        AutohighlightTranscriptResponseFactory
    )()
    request_body, transcript = __submit_mock_request(
        httpx_mock,
        mock_response=mock_response,
        config=aai.TranscriptionConfig(auto_highlights=True),
    )

    # Check that request body was properly defined
    assert request_body.get("auto_highlights") == True

    # Check that transcript was properly parsed from JSON response
    assert transcript.error is None
    assert transcript.auto_highlights is not None
    assert (
        transcript.auto_highlights.status
        == mock_response["auto_highlights_result"]["status"]
    )

    assert transcript.auto_highlights.results is not None
    assert len(transcript.auto_highlights.results) > 0
    assert len(transcript.auto_highlights.results) == len(
        mock_response["auto_highlights_result"]["results"]
    )

    for response_result, transcript_result in zip(
        mock_response["auto_highlights_result"]["results"],
        transcript.auto_highlights.results,
    ):
        assert transcript_result.count == response_result["count"]
        assert transcript_result.rank == response_result["rank"]
        assert transcript_result.text == response_result["text"]

        for response_timestamp, transcript_timestamp in zip(
            response_result["timestamps"], transcript_result.timestamps
        ):
            assert transcript_timestamp.start == response_timestamp["start"]
            assert transcript_timestamp.end == response_timestamp["end"]


from typing import List

import cv2
import numpy as np

def unnormalize(img: np.ndarray, to_colormap: bool = True) -> np.ndarray:
    c, h, w = img.shape
    unnormalized_img = img.transpose([1, 2, 0]) * 0.5 + 0.5
    if c == 1 and to_colormap:
        unnormalized_img = (
            cv2.applyColorMap(
                np.array((1-unnormalized_img) * 255, dtype=np.uint8), cv2.COLORMAP_JET
            )
            / 255
        )
    return unnormalized_img

def make_grid(images: List[List[np.ndarray]], pad: int = 3) -> np.ndarray:
    for k in range(len(images)):
        c, h, w = images[k][0].shape
        dtype = images[k][0].dtype
        row_image = np.array(unnormalize(images[k][0]), dtype=dtype)
        for i in range(1, len(images[k])):
            add_image = cv2.hconcat(
                [
                    np.zeros([h, pad, 3], dtype=dtype),
                    np.array(unnormalize(images[k][i]), dtype=dtype),
                ]
            )
            row_image = cv2.hconcat([row_image, add_image])

        if k == 0:
            grid_image = row_image
        else:
            h, w, c = row_image.shape
            add_image = cv2.vconcat([np.zeros([pad, w, c], dtype=dtype), row_image])
            grid_image = cv2.vconcat([grid_image, add_image])

    return grid_image

def make_grid_gray(images: List[List[np.ndarray]], pad: int = 3) -> np.ndarray:
    for k in range(len(images)):
        _, h, w = images[k][0].shape
        dtype = images[k][0].dtype
        row_image = images[k][0].transpose([1, 2, 0]) * 0.5 + 0.5
        for i in range(1, len(images[k])):
            add_image = cv2.hconcat(
                [
                    np.zeros([h, pad, 1], dtype=dtype),
                    images[k][i].transpose([1, 2, 0]) * 0.5 + 0.5,
                ]
            )
            row_image = cv2.hconcat([row_image, add_image])

        if k == 0:
            grid_image = row_image
        else:
            h, w = row_image.shape
            add_image = cv2.vconcat([np.zeros([pad, w], dtype=dtype), row_image])
            grid_image = cv2.vconcat([grid_image, add_image])

    return grid_image[:, :, np.newaxis]


import slo
import cursor
import keyboard
import root
from rootobject import rootobject
from rootobject import textformat
from rootobject import alert
from rootobject import pointer
from rootobject.buckerwindow import text
from rootobject.buckerwindow import textarea

import pygame
import math

resize_d = 'R_D'
resize_s = 'R_S'

# V 모든 윈도우(창) 오브젝트
class BuckerWindow(rootobject.RootObject):
    close = pygame.transform.scale(pygame.image.load('./res/image/icon/close.png'), (20, 20)).convert_alpha()
    text_format = rootobject.default_text_format

    def __init__(self, program: str):
        self.program = program

        self.x = 0
        self.y = 0
        self.title_height = 24
        self.width = 150
        self.height = 150
        self.title = 'BuckerWindow'
        self.normal_border_color = slo.bucker['window']['normal_border_color']
        self.highlighted_border_color = slo.bucker['window']['highlighted_border_color']
        self.background_color = slo.bucker['window']['background_color']

        self.exit = False

        if self.title == 'BuckerWindow':
            self.title = self.program.split('/')[-1]
            if '\\' in self.title:
                self.title = self.program.split('//')[-1]

        self.directory = self.program[:-len(self.title) - 1]

        self.elements = []
        try:
            self.build_program(self.program)
        except SyntaxError:
            self.exit = True

        self.highlighted_object = None

        self.width += 2
        self.height += self.title_height + 1

        self.target_x = self.x
        self.target_y = self.y

        self.x_moving = True
        self.y_moving = True

        self.x = cursor.position[0] - self.width / 2
        self.y = cursor.position[1] - self.height / 2

        self.text_format.color = self.background_color

        self.moving = False
        self.original_x = None
        self.original_y = None
        self.start_moving_x = None
        self.start_moving_y = None

        self.window = pygame.Surface((0, 0))
        self.surface = pygame.Surface((self.width - 2, self.height - self.title_height - 1))
        self.surface.fill(self.background_color)

        self.resize_mode = None
        self.original_width = self.width
        self.original_height = self.height
        self.width_target = self.width
        self.height_target = self.height
        self.width_move = False
        self.height_move = False

        self.minimum_width = 100
        self.minimum_height = 100

        self.build_surface()

    def tick(self):
        if self.x_moving:
            self.x += (self.target_x - self.x) / (root.display.display_fps / slo.slo['appearance']['motion_speed'])
            if math.fabs(self.x - self.target_x) < 1:
                self.x = self.target_x
                self.x_moving = False

        if self.y_moving:
            self.y += (self.target_y - self.y) / (root.display.display_fps / slo.slo['appearance']['motion_speed'])
            if math.fabs(self.y - self.target_y) < 1:
                self.y = self.target_y
                self.y_moving = False

        if self.exit:
            self.y_moving = True
            self.target_y = root.display.size[1] + 1

            if root.display.size[1] <= self.y:
                self.destroy()

        if self.moving:
            self.target_x = cursor.position[0] - self.start_moving_x + self.original_x
            self.target_y = cursor.position[1] - self.start_moving_y + self.original_y

            self.x_moving = True
            self.y_moving = True

        if keyboard.keydown_key == pygame.K_q and (keyboard.lctrl or keyboard.rctrl) and rootobject.highlighted_object == self:
            self.exit = True

        if cursor.fpressed[0]:
            if self.x <= cursor.position[0] <= self.x + self.width:
                if self.y <= cursor.position[1] <= self.y + self.title_height and rootobject.get_on_cursor_window() == self:
                    self.moving = True
                    self.original_x = self.x
                    self.original_y = self.y
                    self.start_moving_x = cursor.position[0]
                    self.start_moving_y = cursor.position[1]

            if rootobject.get_on_cursor_window() == self:
                self.ahead()

            self.highlighted_object = None

        if cursor.epressed[0]:
            self.moving = False

            if self.x + self.width - self.title_height <= cursor.position[0] <= self.x + self.width and self.y <= cursor.position[1] <= self.y + self.title_height and rootobject.get_on_cursor_window() == self:
                self.exit = True

            self.resize_mode = None

        if rootobject.get_on_cursor_window() == self:
            if self.x + self.width - 6 <= cursor.position[0] and self.y < cursor.position[1] < self.y + self.height:
                pointer.pointer.mode = pointer.resize_width
                if cursor.fpressed[0]:
                    self.resize_mode = resize_d
                    self.original_width = self.width
            elif self.y + self.height - 6 <= cursor.position[1] and self.x < cursor.position[0] < self.x + self.width:
                pointer.pointer.mode = pointer.resize_height
                if cursor.fpressed[0]:
                    self.resize_mode = resize_s
                    self.original_height = self.height
            else:
                pointer.pointer.mode = pointer.normal
        else:
            pointer.pointer.mode = pointer.normal

        if self.resize_mode is not None:
            if self.resize_mode == resize_d:
                self.width_target = self.original_width + (cursor.position[0] - cursor.sposition[0])
                self.width_move = True
                if self.width_target < self.minimum_width:
                    self.width_target = self.minimum_width
            elif self.resize_mode == resize_s:
                self.height_target = self.original_height + (cursor.position[1] - cursor.sposition[1])
                self.height_move = True
                if self.height_target < self.minimum_height:
                    self.height_target = self.minimum_height

        if self.width_move:
            self.width += (self.width_target - self.width) / (root.display.display_fps / slo.slo['appearance']['motion_speed'])
            if math.fabs(self.width_target - self.width) < 1:
                self.width = self.width_target
                self.width_move = False
                self.build_surface()

        if self.height_move:
            self.height += (self.height_target - self.height) / (root.display.display_fps / slo.slo['appearance']['motion_speed'])
            if math.fabs(self.height_target - self.height) < 1:
                self.height = self.height_target
                self.height_move = False
                self.build_surface()

        if self.resize_mode is not None or self.width_move or self.height_move:
            self.build_surface()

        for element in self.elements:
            element.tick()

    def render(self):
        root.window.blit(self.window, (self.x, self.y))

        self.surface.fill(self.background_color)

        for element in self.elements:
            element.render()

        root.window.blit(self.surface, (1 + self.x, self.title_height + self.y))

    def build_surface(self):
        title_surface = self.text_format.render(self.title)

        border_color = self.highlighted_border_color if rootobject.highlighted_object == self else self.normal_border_color

        self.surface = pygame.Surface((round(self.width - 2), round(self.height - 1 - self.title_height)))

        self.window = pygame.Surface((self.width, self.height))
        self.window.fill(self.background_color)
        pygame.draw.rect(self.window, border_color, ((0, 0), (self.width, self.title_height)))
        pygame.draw.line(self.window, border_color, (0, 0), (0, self.height), 1)
        pygame.draw.line(self.window, border_color, (0, self.height), (self.width, self.height), 3)
        pygame.draw.line(self.window, border_color, (self.width, 0), (self.width, self.height), 3)
        self.window.blit(self.close, (self.width - self.close.get_width() - 2, 2))
        self.window.blit(title_surface, (rootobject.center(self.width, title_surface.get_width()), 0))

    def build_program(self, path):
        def exception(message):
            rootobject.add_object(alert.Alert(self.title, f'현재 실행하고 있는 프로그램의 {line_number + 1}번째 줄에 다음과 같은 오류가 발견되었습니다: \n' + str(message)))
            raise SyntaxError(message)

        try:
            code = open(path, 'r').read().split('\n')
        except UnicodeDecodeError:
            code = open(path, 'r', encoding='utf-8').read().split('\n')

        variables = {}

        for line_number in range(len(code)):
            line = code[line_number]

            if '?' in line: line = line[:line.index('?')]
            if len(line) <= 0: continue
            while line[-1] == ' ': line = line[:-1]

            sline = line.split()
            if sline[0] == 'set-raw':
                if len(sline) < 3:
                    exception('set-raw 구문의 변수 이름 또는 변수 값이 지정되어 있지 않습니다.')

                try:
                    variables[sline[1]] = eval(' '.join(sline[2:]))
                except Exception as e:
                    exception(str(e))

            elif sline[0] == 'set':
                if len(sline) < 3:
                    exception('set 구문의 변수 이름 또는 변수 값이 지정되어 있지 않습니다.')

                if sline[1] == 'TextFormat':
                    keys = ('font', 'size', 'color')

                    arguments = {}
                    for key in keys:
                        arguments[key] = None

                    for _i in range(len(sline)):
                        _i += 3
                        try:
                            word = sline[_i]
                        except IndexError:
                            break

                        if _i % 2 == 0:
                            if '_' in word: word = word.replace('_', ' ')
                            if '\\ ' in word: word = word.replace('\\ ', '_')

                            if last_key in keys:
                                if word[0] == '$':
                                    arguments[last_key] = variables[word]
                                else:
                                    arguments[last_key] = eval(word)
                        else:
                            last_key = word

                    arguments['font'] = arguments['font'].replace('|', '/')

                    if arguments['font'][0] == '%':
                        arguments['font'] = self.directory + arguments['font'][1:]

                    variables[sline[2]] = textformat.TextFormat(font=arguments['font'], size=arguments['size'], colour=arguments['color'])

            elif sline[0] == 'window-set':
                # noinspection PyBroadException
                try:
                    if sline[1] == 'x': self.x = eval(' '.join(sline[2:]))
                    elif sline[1] == 'y': self.y = eval(' '.join(sline[2:]))
                    elif sline[1] == 'title_height': self.title_height = eval(' '.join(sline[2:]))
                    elif sline[1] == 'width': self.width = eval(' '.join(sline[2:]))
                    elif sline[1] == 'height': self.height = eval(' '.join(sline[2:]))
                    elif sline[1] == 'title': self.title = eval(' '.join(sline[2:]))
                    elif sline[1] == 'border_color': self.normal_border_color = eval(' '.join(sline[2:]))
                    elif sline[1] == 'background_color': self.background_color = eval(' '.join(sline[2:]))
                    elif sline[1] == 'highlighted_background_color': self.highlighted_border_color = eval(' '.join(sline[2:]))
                except Exception as e:
                    exception(e)

            elif sline[0] == 'window-add':
                if len(sline) < 2:
                    exception('window-add 구문의 변수형이 지정되어 있지 않습니다.')

                arguments = {}
                last_key = ''

                if sline[1] == 'TextArea':
                    keys = ('x', 'y', 'width', 'height', 'value', 'text_format', 'background_color', 'writable')

                    for key in keys:
                        arguments[key] = None

                    for _i in range(len(sline)):
                        _i += 2
                        try:
                            word = sline[_i]
                        except IndexError:
                            break

                        if _i % 2 == 1:
                            if '_' in word: word = word.replace('_', ' ')
                            if '\\ ' in word: word = word.replace('\\ ', '_')

                            if last_key in keys:
                                if word[0] == '$':
                                    arguments[last_key] = variables[word]
                                else:
                                    arguments[last_key] = eval(word)
                        else:
                            last_key = word

                    self.elements.append(textarea.TextArea(x=arguments['x'], y=arguments['y'], width=arguments['width'], height=arguments['height'], value=arguments['value'], text_format=arguments['text_format'], background_color=arguments['background_color'], writable=arguments['writable'], window=self))
                elif sline[1] == 'Text':
                    keys = ('x', 'y', 'text', 'text_format')

                    for key in keys:
                        arguments[key] = None

                    for _i in range(len(sline)):
                        _i += 2
                        try:
                            word = sline[_i]
                        except IndexError:
                            break

                        if _i % 2 == 1:
                            if '_' in word: word = word.replace('_', ' ')
                            if '\\ ' in word: word = word.replace('\\ ', '_')

                            if last_key in keys:
                                if word[0] == '$':
                                    if word not in variables.keys():
                                        exception(f'{word}라는 변수는 지정되지 않았습니다.\n변수 형에 언더바(_)를 사용했을 가능성이 있습니다.')
                                    arguments[last_key] = variables[word]
                                else:
                                    try:
                                        arguments[last_key] = eval(word)
                                    except NameError as e:
                                        exception(f'{e}')
                        else:
                            last_key = word

                    self.elements.append(text.Text(x=arguments['x'], y=arguments['y'], text=arguments['text'], text_format=arguments['text_format'], window=self))
                else:
                    exception(f'변수형 {sline[1]}을(를) 알 수 없습니다.')

            else:
                exception(f'명령어 {sline[0]}을(를) 알 수 없습니다.')

        return False


from gi.repository import Gtk

#------------------------------------------------------------------------
#
# Indicator class
#
#------------------------------------------------------------------------
class Indicator(Gtk.DrawingArea):

    def __init__(self):
        Gtk.DrawingArea.__init__(self)
        self.connect('draw', self._draw)
        self.active = False
        self.set_size_request(5, -1)

    def set_active(self, value):
        self.active = value
        self.queue_draw()

    def _draw(self, widget, cr):

        # clip area to avoid extra work
        #cr.rectangle(event.area.x, event.area.y,
                     #event.area.width, event.area.height)
        #cr.clip()

        alloc = self.get_allocation()
        if self.active:
            cr.set_source_rgba(1, 0, 0, 1)
        else:
            cr.set_source_rgba(1, 0, 0, 0)
        cr.rectangle(0, 3, alloc.width, alloc.height-6)
        cr.fill()

#------------------------------------------------------------------------
#
# EntryGrid class
#
#------------------------------------------------------------------------
class EntryGrid(Gtk.Grid):

    def __init__(self, headings=None, tooltips=None, model=None, callback=None):
        Gtk.Grid.__init__(self)

        self.headings = headings
        self.tooltips = tooltips
        self.model = model
        self.widgets = []
        self.indicators = []
        self.selected = None
        self.callback = callback

    def set_model(self, model):
        self.model = model

        model.connect('row-inserted', self.row_inserted)
        model.connect('row-deleted', self.row_deleted)
        model.connect('rows-reordered', self.rows_reordered)
        self.sig_id = model.connect('row-changed', self.row_changed)

        if len(self.model) > 0:
            self.selected = model.get_iter((0,))

    def set_columns(self, columns, tooltips):
        self.headings = columns
        self.tooltips = tooltips

    def build(self):

        for child in self.get_children():
            self.remove(child)
            child.destroy()

        self.indicators = []
        self.widgets = []

        for column, heading in enumerate(self.headings):
            label = Gtk.Label(label=heading)
            label.set_halign(Gtk.Align.START)
            label.set_valign(Gtk.Align.CENTER)
            label.set_margin_right(8)
            label.show()
            self.attach(label, column + 2, 0, 1, 1)

        for row in range(len(self.model)):
            image = Gtk.Image()
            image.set_from_icon_name('gtk-index', Gtk.IconSize.BUTTON)
            button = Gtk.Button()
            button.set_relief(Gtk.ReliefStyle.NONE)
            button.add(image)
            button.connect('clicked', self.clicked, row)
            button.set_can_focus(False)
            button.show_all()
            self.attach(button, 0, row + 1, 1, 1)
            box = Indicator()
            box.show()
            if self.model.get_path(self.selected)[0] == row:
                box.set_active(True)
            self.attach(box, 1, row + 1, 1, 1)
            self.indicators.append(box)
            entry_row = []
            for column, value in enumerate(self.model[row]):
                if column == 0:
                    continue
                entry = Gtk.Entry()
                entry.set_width_chars(5)
                if value is not None:
                    entry.set_text(value)
                    set_size(entry)
                entry.set_tooltip_text(self.tooltips[column - 1])
                entry.connect('changed', self.changed, row, column)
                entry.connect('focus-in-event', self.got_focus, row)
                entry.show()
                self.attach(entry, column + 1, row + 1, 1, 1)
                entry_row.append(entry)
            self.widgets.append(entry_row)

    def get_selected(self):
        return self.selected

    def clicked(self, button, row):
        iter_ = self.model.get_iter((row,))
        self.callback(self.model, iter_)

    def got_focus(self, entry, event, row):
        for indicator in self.indicators:
            indicator.set_active(False)
        self.selected = self.model.get_iter((row,))
        self.indicators[row].set_active(True)

    def changed(self, entry, row, column):
        set_size(entry)
        self.model.handler_block(self.sig_id)
        self.model[row][column] = entry.get_text()
        self.model.handler_unblock(self.sig_id)

    def row_inserted(self, model, path, iter_):
        self.selected = model.get_iter((len(model) - 1,))
        self.build()

    def row_changed(self, model, path, iter_):
        for column in range(1, len(self.headings) + 1):
            value = model.get_value(iter_, column)
            if value is not None:
                self.widgets[path[0]][column - 1].set_text(value)

    def row_deleted(self, model, path):
        if len(model) > 0:
            self.selected = model.get_iter((0,))
        else:
            self.selected = None
        self.build()

    def rows_reordered(self, model, path, iter_, new_order):
        self.build()

    def clean_up(self):
        self.headings = None
        self.tooltips = None
        self.model = None
        self.widgets = None
        self.indicators = None
        self.selected = None
        self.callback = None

def set_size(entry):
    layout = entry.get_layout()
    width, height = layout.get_pixel_size()
    entry.set_size_request(width + 18, -1)


'''
test api server
'''

from flask import Flask, request
from flask_restful import Resource, Api
from flask.views import MethodView

import logging
import json,base64

import os, sys
import datetime
import threading, time

app = Flask(__name__)
api = Api(app)

log = logging.basicConfig(filename='testsvr.log', level=logging.INFO)

# 로깅을 전부 끄기
# logging.getLogger('werkzeug')
# log = logging.get
# log.disabled = True
# app.logger.disabled = True

'''
/apitest1
'''
class apitest1(MethodView):
    def get(self):
        print('header:', request.headers)
        # print(request.headers['pwd'])
        data = request.args
        print('recv:', data)  # dictionary
        abc = data.get('abc')
        if abc :
            result = 'This is GET method!'+str(abc)
        else:
            result = 'Hello World! input abc'
        return result

    def post(self):
        print('header:', request.headers)
        # get과 동일하게 작동
        # return self.get()

        # curl http://localhost:18899/apitest1 -d "name=jane"
        # receive form data
        # result = request.form["name"]
        result = request.form.get('name')
        if not result :
            result = 'name required(FORM)'
        else:
            print("name=", result)
        return result

'''
/sum
'''
class sum(MethodView):
    def get(self):
        data = request.args
        print('recv:', data)  # dictionary
        return 'Hello.'

    def post(self):
        '''
        JSON으로 받아서 작업 후 JSON으로 결과 반환
curl -H "Content-Type: application/json" http://localhost:18899/sum -d "{\"a\":10,\"b\":20}"
        '''
        print('header:', request.headers)
        logging.info('sum test')
        # print('request.data=', request.data)  # binary data read all
        data=request.get_json(force=True) # parse json string
        print('request.json=', data)
        a = data['a']
        b = data['b']
        now = datetime.datetime.now()
        print(now)
        timestr = now.strftime('%Y%m%d %H:%M:%S')
        result = {
            'sum':int(a+b),
            'time':timestr
        }
        logging.info('result='+json.dumps(result))
        return result

api.add_resource(apitest1, '/apitest1')
api.add_resource(sum, '/sum')

port = 18899

if __name__=='__main__':
    print('Start Server... port=', port)
    logging.info('start server')
    app.run(host='0.0.0.0', port=port, debug=True)
    # 디버그 모드로 하면 소스 수정시 자동으로 서버 재시작이 된다.


from tkinter import Tk, Canvas, BOTH, Entry
from tktable.table import *
import sqlite3

class TestForm(Tk):

    def __init__(self):
        super().__init__()

        self.title('Test Table')
        self.test_frame = Canvas(self, width=400, height=400)
        self.test_frame.pack_propagate(0)
        self.test_frame.pack(fill=BOTH, expand=1)
        self.conn = sqlite3.connect('local.db')
        self.create_table()

        tab = Table(self.test_frame, 'SELECT * FROM test', self.conn)

        # Tab = Table(self.test_frame, 10, 5, header=['ID', 'First Name', 'Last Name', 'Phone', 'Email'])
        # Tab.update_cell_in_row(1, ['ID', 'First Name', 'Last Name', 'Phone', 'Email'])
        # print(Tab.get_children())
    def create_table(self):
        cursor = self.conn.cursor()
        create_version_sql = """ CREATE TABLE IF NOT EXISTS test (
                                        test_id integer PRIMARY KEY,
                                        test_name TEXT NOT NULL,
                                        test_location TEXT NOT NULL
                                        ); """
        cursor.execute(create_version_sql)
        cursor.close()

if __name__ == '__main__':
    test_app = TestForm()
    test_app.mainloop()


import pandas as pd
import streamlit as st
import pickle
import sklearn
import numpy as np
import datetime

df=pd.read_csv('car_data.xls')
forest = open('Car_Price_prediction_model.pkl','rb')
model = pickle.load(forest)
st.title(':violet[VEHICLE PRICE PREDICTION APP]')
dict={'ritz': 90.0, 'sx4': 93.0, 'ciaz': 68.0, 'wagon_r': 96.0, 'swift': 92.0,'vitara_brezza': 95.0, 's_cross': 91.0, 'alto_800': 62.0, 'ertiga': 76.0, 'dzire': 73.0, 'alto_k10': 63.0,
      'ignis': 85.0, '800': 0.0, 'baleno': 65.0, 'omni': 89.0, 'fortuner': 81.0, 'innova': 86.0, 'corolla_altis': 71.0, 'etios_cross': 77.0, 'etios_g': 78.0, 'etios_liva': 80.0,
      'corolla': 70.0, 'etios_gd': 79.0, 'camry': 67.0, 'land_cruiser': 88.0, 'Royal_Enfield_Thunder_500': 49.0, 'UM_Renegade_Mojave': 56.0, 'KTM_RC200': 42.0, 'Bajaj_Dominar_400': 11.0,
      'Royal_Enfield_Classic_350': 46.0, 'KTM_RC390': 43.0, 'Hyosung_GT250R': 40.0, 'Royal_Enfield_Thunder_350': 48.0, 'KTM_390_Duke_': 41.0, 'Mahindra_Mojo_XT300': 44.0,
      'Bajaj_Pulsar_RS200': 17.0, 'Royal_Enfield_Bullet_350': 45.0, 'Royal_Enfield_Classic_500': 47.0, 'Bajaj_Avenger_220': 6.0, 'Bajaj_Avenger_150': 4.0, 'Honda_CB_Hornet_160R': 32.0,
      'Yamaha_FZ_S_V_2.0': 60.0, 'Yamaha_FZ_16': 58.0, 'TVS_Apache_RTR_160': 51.0, 'Bajaj_Pulsar_150': 14.0, 'Honda_CBR_150': 37.0, 'Hero_Extreme': 20.0, 'Bajaj_Avenger_220_dtsi': 7.0,
      'Bajaj_Avenger_150_street': 5.0, 'Yamaha_FZ__v_2.0': 57.0, 'Bajaj_Pulsar__NS_200': 12.0, 'Bajaj_Pulsar_220_F': 15.0, 'TVS_Apache_RTR_180': 52.0, 'Hero_Passion_X_pro': 26.0,
      'Bajaj_Pulsar_NS_200': 16.0, 'Yamaha_Fazer_': 61.0, 'Honda_Activa_4G': 31.0, 'TVS_Sport_': 54.0, 'Honda_Dream_Yuga_': 38.0, 'Bajaj_Avenger_Street_220': 8.0, 'Hero_Splender_iSmart': 28.0,
      'Activa_3g': 1.0, 'Hero_Passion_Pro': 25.0, 'Honda_CB_Trigger': 34.0, 'Yamaha_FZ_S_': 59.0, 'Bajaj_Pulsar_135_LS': 13.0, 'Activa_4g': 2.0, 'Honda_CB_Unicorn': 35.0, 'Hero_Honda_CBZ_extreme': 22.0,
      'Honda_Karizma': 39.0, 'Honda_Activa_125': 30.0, 'TVS_Jupyter': 53.0, 'Hero_Honda_Passion_Pro': 23.0, 'Hero_Splender_Plus': 27.0, 'Honda_CB_Shine': 33.0, 'Bajaj_Discover_100': 9.0,
      'Suzuki_Access_125': 50.0, 'TVS_Wego': 55.0, 'Honda_CB_twister': 36.0, 'Hero_Glamour': 21.0, 'Hero_Super_Splendor': 29.0, 'Bajaj_Discover_125': 10.0, 'Hero_Hunk': 24.0,
      'Hero__Ignitor_Disc': 19.0, 'Hero__CBZ_Xtreme': 18.0, 'Bajaj__ct_100': 3.0, 'i20': 84.0, 'grand_i10': 82.0, 'i10': 83.0, 'eon': 75.0, 'xcent': 97.0, 'elantra': 74.0, 'creta': 72.0,
      'verna': 94.0, 'city': 69.0, 'brio': 66.0, 'amaze': 64.0, 'jazz': 87.0}

#code to remove whitespace
def remove(string):
    return string.replace(" ", "_")

col1,col2=st.columns(2)
with col1:
    # For vehicle Type
    vehicle=st.selectbox(':blue[Select Vehicle]',df['Car_Name'].unique())
    if vehicle:
        veh=remove(vehicle)
        vehicle=dict[veh]
    #st.write(vehicle)

    # For price column
    price=st.text_input(':blue[Enter The Present Price of Vehicle in Lacks]')
    if price:
        present_price=int(price)

    # Seller Type
    seller = st.selectbox(':blue[Select Seller Type]', ['Dealer', 'Individual'])
    if seller == 'Dealer':
        Seller_Type = 0
    else:
        Seller_Type = 1
    # st.write(Seller_Type)

    # For Kilometers driven
    kilometers_driven = st.text_input(':blue[Enter the Number of Kilometers Driven]')
    if kilometers_driven:
        kilometers_driven = int(kilometers_driven)
    #st.write(kilometers_driven)

with col2:
    # For Transmission Type
    trans=st.selectbox(':blue[Select Transmission Type]',['Manual', 'Automatic'])
    if trans == 'Manual':
        Transmission=0
    else:
        Transmission = 1
    #st.write(Transmission)

    # For owner
    owner=st.text_input(':blue[Enter The Number Of Owners]')
    if owner:
        owner=int(owner)
    #st.write(owner)

     # For fuel column
    fuel = st.selectbox(':blue[Select Fuel Type]', ['Petrol', 'Diesel', 'CNG'])
    if fuel == 'Petrol':
        fuel_type = 0
    elif fuel == 'Diesel':
        fuel_type = 1
    else:
        fuel_type = 2
    # st.write(fuel_type)

    # For age column
    age=st.text_input(':blue[Enter The Registered Year of Vehicle]')
    if age:
        date_time = datetime.datetime.now()
        age= date_time.year-int(age)

    #st.write(age)

predict=st.button('predict')
if predict:
    prediction=model.predict([[vehicle,present_price, kilometers_driven, fuel_type, Seller_Type, Transmission, owner, age]])
    st.write("### :green[The predicted price of vehicle is]",int(prediction[0]))

st.write( f'<h5 style="color:rgb(0, 153, 153,0.35);">App Created by RAVI CHANDRA PALEM </h5>', unsafe_allow_html=True )


from bin import sentinel
from lib import config
from lib import sucr_config
import time
import datetime
import sys
import os
import shutil
import string
import random
import math
import logging
import traceback

from builtins import input

try:
    from colorama import init
    from termcolor import colored
    from pynput import keyboard

    DISPLAY_AVAILABLE = True
except:
    DISPLAY_AVAILABLE = False

def random_string(n):
    rnd = random.SystemRandom()
    pool = string.ascii_lowercase + string.ascii_uppercase + string.digits
    m = len(pool) - 1

    return ''.join(pool[rnd.randint(0, m)] for _ in range(n))

def run_sentinel():
    logger = logging.getLogger('sentinel')
    print(colored('Sentinel runs every 1 minute', 'green'))

    while True:
        now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M")

        print(colored('{} Running sentinel'.format(now), 'green'))
        try:
            sentinel.entrypoint()
        except Exception as e:
            print(colored('Error: {}'.format(e), 'red'))

            logger.error(str(e))
            logger.error(traceback.format_exc())
            logger.error('--------------------')

        time.sleep(60) # Wait for a minute

def fix_masternode(data_folder):
    try:
        wallet_file = os.path.join(data_folder, 'wallet.dat')

        if not os.path.isfile(wallet_file):
            print('It seems like the data folder (the one containing wallet.dat) is not the same as the folder where sucr.conf is')
            data_folder = input('Please, write the data folder path: ')
            return fix_masternode(data_folder)

        print(colored('Make a copy of "wallet.dat" and "sucr.conf" before continuing.\nThis program will try it best not to touch them, but just in case!', attrs=['bold']))
        confirm = input('Once done, press [ENTER], or write cancel + [ENTER] to exit\n')
        if confirm.lower() == "cancel":
            return

        print(colored('Removing conflicting files', 'green'))
        for filename in os.listdir(data_folder):
            if filename in ('wallet.dat', 'sucr.conf'):
                continue

            realpath = os.path.join(data_folder, filename)
            if os.path.isfile(realpath):
                os.remove(realpath)
            elif os.path.isdir(realpath):
                shutil.rmtree(realpath)

            print('\t{}'.format(filename))

        print(colored('Done removing', 'green'))
        print('')

        print(colored('Checking sucr.conf contents', 'green'))
        tokens = sucr_config.SucreConfig.tokenize(config.sucr_conf)

        # Check if needed tokens are there, set them if not
        tokens['rpcuser'] = tokens.get('rpcuser', random_string(18))
        tokens['rpcpassword'] = tokens.get('rpcpassword', random_string(18))
        tokens['rpcconnect'] = tokens.get('rpcconnect', '127.0.0.1')
        tokens['rpcport'] = tokens.get('rpcport', 9335)
        tokens['server'] = 1

        # It must have a masternode=1
        try:
            if int(tokens['masternode']) != 1:
                raise Exception
        except:
            r = None
            while r not in ('y', 'n'):
                print(colored('It seems like your sucr.conf is not setting the wallet as masternode!', 'red'))
                print(colored('If your are running a COLD wallet, this must be executed on the MN wallet, not the collateral', 'red'))
                print(colored('If you are using MNs hosts like HostMNs DO NOT continue, this should be done by them, not you!', 'red'))
                r = input(colored('Continuing will set masternode=1, don\'t do it if this is a collateral wallet, [y/n]: ', 'red', attrs=['bold']))

                if r == 'n':
                    rewrite = False
                elif r != 'y':
                    print('Please write y or n')

            if r == 'y':
                tokens['masternode'] = 1
            else:
                sys.exit(1)

        # It must have a masternodeprivkey
        if 'masternodeprivkey' not in tokens:
            print(colored('Your sucr.conf does not contain a \'masternodeprivkey\' entry, please set it up before opening your wallet', 'red'))

        # Rewrite config
        with open(config.sucr_conf, 'w') as fp:
            for k, v in tokens.items():
                fp.write('{}={}\n'.format(k, v))

        print(colored('Done checking\n', 'green'))
        print(colored('Please open your wallet (sucrd on linux) and wait for it completely load/open before continuing', attrs=['bold']))
        input('Press [ENTER] to continue')
        print('')

        print(colored('Sentinel will automatically start in 15s', 'green', attrs=['bold']))
        print(colored('Until the wallet is fully synced, sentinel will show errors related to sync status, that\'s fine!', 'green'))
        print(colored('If it says it can not connect, check your sucr.conf settings', 'yellow'))

        r = 15
        while r > 0:
            sys.stdout.write('Starting in {}s \r'.format(r))
            sys.stdout.flush()
            r -= 1
            time.sleep(1)

        print('\n')
        run_sentinel()
    except Exception as e:
        print(colored('Error: {}'.format(e), 'red'))

        logger.error(str(e))
        logger.error(traceback.format_exc())
        logger.error('--------------------')

# @https://stackoverflow.com/questions/24582233/python-flush-input-before-raw-input
def flush_input():
    try:
        import sys, termios
        termios.tcflush(sys.stdin, termios.TCIOFLUSH)
    except ImportError:
        import msvcrt
        while msvcrt.kbhit():
            msvcrt.getch()

def menu():
    args = config.get_args()

    if args.repair and args.sentinel:
        print(colored('Do not specify --repair and --sentinel at the same time', 'red'))
        sys.exit(1)
    elif args.sentinel:
        return 1
    elif args.repair:
        return 2

    print('Select an option:')
    print('\t1. Start sentinel')
    print('\t2. Fix wallet and masternode')

    global menu_option
    menu_option = 0

    # No PyInput means no auto-start if no command line option was given, sry!
    if not DISPLAY_AVAILABLE:
        while menu_option not in (1, 2):
            try:
                menu_option = int(input('Please write 1 or 2 and press [ENTER]: '))
            except:
                pass

        return menu_option

    print('')

    def on_release(key):
        global menu_option

        try:
            if key.char in ('1', '2'):
                menu_option = int(key.char)
                return False
            else:
                print(colored('Option not valid', 'red'))
        except:
            pass

    # Collect events until released
    with keyboard.Listener(on_release=on_release) as listener:
        r = 30
        while menu_option == 0 and r > 0:
            sys.stdout.write('\rPress 1 or 2. Sentinel will automatically start in {}s  '.format(int(math.ceil(r))))
            sys.stdout.flush()

            r -= 0.1
            time.sleep(0.1)

        listener.stop()

    if menu_option == 0:
        menu_option = 1

    flush_input()

    print('\n')
    return menu_option

if __name__ == '__main__':
    init()

    # Setup logging
    logger = logging.getLogger('sentinel')
    hdlr = logging.FileHandler('sentinel.log')
    formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
    hdlr.setFormatter(formatter)
    logger.addHandler(hdlr)
    logger.setLevel(logging.INFO)

    if os.path.isfile(config.sentinel_config_file):
        print(colored('Using sentinel.conf: {}'.format(config.sentinel_config_file), 'green'))

    print(colored('Using sucr.conf: {}'.format(config.sucr_conf), 'green'))

    option = menu()
    if option == 1:
        run_sentinel()
    elif option == 2:
        # Use default data folder
        data_folder = os.path.dirname(config.sucr_conf)
        fix_masternode(data_folder)


# -*- coding: utf-8 -*-
"""
Created on Tue Aug  8 17:52:10 2017

@author: acbart
"""

import json
import os
import pandas as pd
import codecs
from unidecode import unidecode
from datetime import timedelta, datetime
from datetime import date as datetime_date
from dateutil.parser import parse
import matplotlib.pyplot as plt
from matplotlib.ticker import FuncFormatter
import matplotlib
import re
import math
from collections import Counter
import numpy as np
from textblob import TextBlob
from wordcloud import WordCloud, STOPWORDS
from nltk.corpus import stopwords
from nltk import word_tokenize
from itertools import tee, islice, combinations
import string
from textstat.textstat import textstat
from stepwise import forward_selected
from states import state_names
import scipy.stats as stats
import sklearn.metrics as metrics

#%%

wordcounts = []
y_wordcounts = []
ym_words = []
indexes = []
overall = Counter()
ym_words_bigrams = []
wordcounts_bigrams = []
overall_bigrams= Counter()
for filename in os.listdir('monthly_bodies'):
    _, year, month = filename.split('_')
    month = int(month[:-4])
    year = int(year)
    if year in (1996, 2017):
        continue
    with codecs.open('monthly_bodies/'+filename, encoding='utf-8') as inp:
        stripped_words = [w.strip() for w in inp.readlines()]
        words = Counter(stripped_words)
        ym_words.append(stripped_words)
        wordcounts.append(words)
        indexes.append((year, month))
        overall.update(stripped_words)
        # Bigrams
        stripped_bigrams = [l+' '+r for l, r in
                            zip(stripped_words[:-1], stripped_words[1:])]
        words_bigrams = Counter(stripped_bigrams)
        ym_words_bigrams.append(stripped_bigrams)
        wordcounts_bigrams.append(words_bigrams)
        overall_bigrams.update(stripped_bigrams)

index = pd.MultiIndex.from_tuples(indexes, names=('Year', "Month"))
lengths = pd.Series(data=[len(w) for w in ym_words],
                    index=index)
y_lengths = lengths.sum(level=0)
lengths_bigrams = pd.Series(data=[len(w) for w in ym_words_bigrams],
                    index=index)
y_lengths_bigrams = lengths_bigrams.sum(level=0)
def counts(word):
    return pd.Series(data=[w[word] for w in wordcounts],
                     index=index)
def counts_bi(phrase):
    return pd.Series(data=[p[phrase] for p in wordcounts_bigrams],
                     index=index)
#%%
BORING_PHRASES = ('computer science', 'software engineering',
                  'assistant professor', 'computer engineering',
                  'department computer', 'invites applications',
                  'professor computer', 'state university')
pd.Series(data=[[(phrase, count)
                 for phrase, count in p.most_common(100)
                 if phrase not in BORING_PHRASES]
                for p in wordcounts_bigrams],
          index=index)
#%%
def standardize_and_show_plot(ylim):
    plt.legend(loc=(1.04,.28), framealpha=0.2)
    plt.gcf().set_size_inches(4, 2)
    plt.xlim(1997, 2016)
    #plt.yticks(np.arange(0, ylim, .001))
    plt.yticks(np.arange(max(0, round(plt.gca().get_ylim()[0], 4)-.001),
                         round(plt.gca().get_ylim()[1], 4)+.001, .001))
    plt.ylabel("Proportion")
    #plt.xlabel("Year")
    plt.show()
#%%
## Programming Languages
for keyword, language in [('java', 'Java'),
                           ('python', 'Python'),
                           ('c', 'C'),
                           ('cpp', 'C++')]:
    plt.plot((counts(keyword).sum(level=0))/y_lengths,
             label=language)
standardize_and_show_plot(.005)
#%%
## Gendered words
FEMALE_TERMS = ("women", "woman", "she", "her", "herself",
              "females", "girls", "gals",
              "lady", "ladies",
               "female", "girl", "gal")
MALE_TERMS = ("men", "man", "he", "his", "him", "himself",
                 "males", "boys", "guys",
                 "gentleman", "gentlemen",
                "male", "boy", "guy")

(sum(counts(w) for w in MALE_TERMS).sum(level=0)/len(overall)).plot(label="Male")
(sum(counts(w) for w in FEMALE_TERMS).sum(level=0)/len(overall)).plot(label="Female")
plt.xlabel("")
standardize_and_show_plot(.03)
#%%
for buzzword in ["ethics", "cheating", "cheat"]:
    counts(buzzword).sum(level=0).plot(label=buzzword)
plt.legend(loc='best', framealpha=0.2)
plt.gcf().set_size_inches(4, 3)
plt.show()
#%%
for buzzword in [":)", ":-)", ":(", ":-("]:
    counts(buzzword).sum(level=0).plot(label=buzzword)
plt.legend(loc='best', framealpha=0.2)
plt.gcf().set_size_inches(4, 3)
plt.title("Smiley Faces")
plt.show()
#%%
for buzzword in ["teaching", "research"]:
    counts(buzzword).sum(level=0).plot(label=buzzword)
    #(counts(buzzword).sum(level=0)/y_lengths).plot(label=buzzword)
plt.legend(loc='best', framealpha=0.2)
plt.gcf().set_size_inches(4, 3)
plt.title("Teaching vs. Research")
plt.show()
#%%
## PL Styles
for keyword, language in [('object-oriented', 'Object-Oriented'),
                           ('functional', 'Functional'),
                           ('imperative', 'Imperative')]:
    plt.plot((counts(keyword).sum(level=0))/y_lengths,
             label=language)
standardize_and_show_plot(.03)
#%%
for buzzword in ["graduate", "undergraduate"]:
    counts(buzzword).sum(level=0).plot(label=buzzword)
    #(counts(buzzword).sum(level=0)/y_lengths).plot(label=buzzword)
plt.legend(loc='best', framealpha=0.2)
plt.gcf().set_size_inches(4, 3)
plt.title("Graduate vs. Undergraduate")
plt.show()
#print(stats.pearsonr(*[(counts(buzzword).sum(level=0)/y_lengths)
#        for buzzword in ["graduate", "undergraduate"]]))
#%%
## pd.DataFrame(overall.most_common(500), columns=["Word", "Frequency"]).to_csv("top_words.csv", index=False)
#%%
for buzzword in ["acm", "ieee"]:
    counts(buzzword).sum(level=0).plot(label=buzzword)
    #(counts(buzzword).sum(level=0)/y_lengths).plot(label=buzzword)
plt.legend(loc='best', framealpha=0.2)
plt.gcf().set_size_inches(4, 3)
plt.title("Professional Organizations")
plt.show()
#%%
for buzzword in ["fall", "spring", "winter", "summer"]:
    counts(buzzword).sum(level=0).plot(label=buzzword)
    #(counts(buzzword).sum(level=0)/y_lengths).plot(label=buzzword)
plt.legend(loc='best', framealpha=0.2)
plt.gcf().set_size_inches(4, 3)
plt.title("Semesters")
plt.show()
#%%
for buzzword in ["hci", "ai", "gui"]:
    counts(buzzword).sum(level=0).plot(label=buzzword)
    #(counts(buzzword).sum(level=0)/y_lengths).plot(label=buzzword)
plt.legend(loc='best', framealpha=0.2)
plt.gcf().set_size_inches(4, 3)
plt.title("Topics")
plt.show()
#%%
for phrase in ["computational thinking", "data structures", "k 12"]:
    counts_bi(phrase).sum(level=0).plot(label=phrase)
    #(counts(buzzword).sum(level=0)/y_lengths).plot(label=buzzword)
plt.legend(loc='best', framealpha=0.2)
plt.gcf().set_size_inches(4, 3)
plt.title("Subjects")
plt.show()
#%% CS Levels
for keyword, language in [('cs0', 'CS0'),
                           ('cs1', 'CS1'),
                           ('cs2', 'CS2'),
                           ('cs3', 'CS3')]:
    plt.plot((counts(keyword).sum(level=0))/y_lengths,
             label=language)
standardize_and_show_plot(.03)
#%%
for phrase in ["operating systems", "artificial intelligence",
               "human-computer interaction", "computer vision",
               "game development", "data mining",
               "discrete math", "machine learning",
               "computer graphics", "parallel distributed",
               "computer architecture", "software engineering"]:
    counts_bi(phrase).sum(level=0).plot(label=phrase)
    #(counts(buzzword).sum(level=0)/y_lengths).plot(label=buzzword)
plt.legend(loc='best', framealpha=0.2)
plt.gcf().set_size_inches(6, 6)
plt.title("Subjects")
plt.show()

#%%
for phrase in ["active learning", "paired programming", "distance education",
               "peer instruction"
               ]:
    counts_bi(phrase).sum(level=0).plot(label=phrase)
    #(counts(buzzword).sum(level=0)/y_lengths).plot(label=buzzword)
plt.legend(loc='best', framealpha=0.2)
plt.gcf().set_size_inches(4, 3)
plt.title("Subjects")
plt.show()
#%%
for phrase in ["functional programming", "object-oriented programming"]:
    counts_bi(phrase).sum(level=0).plot(label=phrase)
    #(counts(buzzword).sum(level=0)/y_lengths).plot(label=buzzword)
plt.legend(loc='best', framealpha=0.2)
plt.gcf().set_size_inches(4, 3)
plt.title("Subjects")
plt.show()
#%%
for phrase in ["women computing"]:
    counts_bi(phrase).sum(level=0).plot(label=phrase)
    #(counts(buzzword).sum(level=0)/y_lengths).plot(label=buzzword)
plt.legend(loc='best', framealpha=0.2)
plt.gcf().set_size_inches(4, 3)
plt.title("Subjects")
plt.show()
#%%
for phrase in ["computer science", "software engineering"]:
    counts_bi(phrase).sum(level=0).plot(label=phrase)
    #(counts(buzzword).sum(level=0)/y_lengths).plot(label=buzzword)
plt.legend(loc='best', framealpha=0.2)
plt.gcf().set_size_inches(4, 3)
plt.title("Subjects")
plt.show()
#%%
for keyword, language in [('middle school', 'Middle School'),
                           ('high school', 'High School'),
                           ('k 12', 'K-12')]:
    plt.plot((counts_bi(keyword).sum(level=0))/y_lengths_bigrams,
             label=language)
standardize_and_show_plot(.001)
#%%

s_wordcounts = []
s_y_wordcounts = []
s_ym_words = []
s_indexes = []
s_overall = Counter()
for filename in os.listdir('monthly_subjects'):
    _, year, month = filename.split('_')
    month = int(month[:-4])
    year = int(year)
    if year in (1996, 2017):
        continue
    with codecs.open('monthly_subjects/'+filename, encoding='utf-8') as inp:
        stripped_words = [w.strip() for w in inp.readlines()]
        words = Counter(stripped_words)
        s_ym_words.append(stripped_words)
        s_wordcounts.append(words)
        s_indexes.append((year, month))
        s_overall.update(stripped_words)

s_index = pd.MultiIndex.from_tuples(s_indexes, names=('Year', "Month"))
s_lengths = pd.Series(data=[len(w) for w in s_ym_words],
                    index=s_index)
s_y_lengths = s_lengths.sum(level=0)
def s_counts(word):
    return pd.Series(data=[w[word] for w in s_wordcounts],
                     index=s_index)
#%%
BORING_PHRASES = ['faculty', 'position', 'cs', 'workshop',
                  'science', 'university', 'tenuretrack', 'sigcse']
pd.Series(data=[[(phrase, count)
                 for phrase, count in p.most_common(100)
                 if phrase not in BORING_PHRASES]
                for p in s_wordcounts],
          index=s_index).map(lambda x: ', '.join([y[0] for y in x][:10]))


from pynput import keyboard
from pynput.keyboard import Key

class Vim:
    def __init__(self, filepath):
        self.idx = 0
        self.lines = []
        self.filepath = filepath
        self.is_running = True

    def exec(self):
        listener = keyboard.Listener(on_press=self.on_press)
        listener.start()
        with open(self.filepath, 'r') as f:
            for line in f:
                line = line.strip('\n')
                self.lines.append(line)
            if len(self.lines) == 0:
                self.lines.append('')

        print(f'{self.idx + 1}. {self.lines[self.idx]}')
        while self.is_running:
            pass
        listener.stop()

    def on_press(self, key):
        if (key == Key.shift_l):
            if self.idx > 0:
                self.idx -= 1
                print(f'{self.idx + 1}. {self.lines[self.idx]}')
        elif (key == Key.shift_r):
            if self.idx < len(self.lines) - 1:
                self.idx += 1
                print(f'{self.idx + 1}. {self.lines[self.idx]}')
        elif (key == Key.alt_l):
            self.lines[self.idx] = input(f'{self.idx + 1}. ')
        elif (key == Key.alt_r):
            self.idx += 1
            self.lines.insert(self.idx, '')
            print(f'{self.idx + 1}. {self.lines[self.idx]}')
        elif (key == Key.ctrl_l):
            if len(self.lines) == 1:
                self.lines[0] = ''
            else:
                self.lines.pop(self.idx)
            if self.idx != 0:
                self.idx -= 1
            print(f'{self.idx + 1}. {self.lines[self.idx]}')
        elif (key == Key.ctrl_r):
            with open(self.filepath, 'w') as f:
                f.write('\n'.join(self.lines))
            self.is_running = False


from scipy import stats
import numpy as np
import matplotlib.pyplot as plt
z=0.325
def f(t):
    return stats.norm.pdf(t)
plt.ylim(0,0.45)
x=np.arange(-3,3,.1)
y1=f(x)
x2=np.arange(-4,z,1/40)
sum_=0
delta=.05
s=np.arange(-10,z,delta)
for i in s:
    sum_+=f(i)*delta
cdf=stats.norm.cdf(z)
print('sum');print(sum_)
print('ppf');print(cdf)
plt.plot(x,f(x))
plt.fill_between(x2,f(x2))
plt.annotate('z='+str(z),xy=(z,0))
plt.annotate('area is'+str(round(sum_,4))+'cdf is'+str(round(cdf,4)),xy=(-1,0.25),xytext=(-3.8,0.4),arrowprops=dict(facecolor='red',shrink=.01))


import setuptools

with open("README.md", "r") as f:
    long_description = f.read()

setuptools.setup(
    name="genealogy",
    version="0.0.3",
    author="Robert Williams",
    author_email="robertedwardwilliams@me.com",
    description="A package for recording Genealogy.",
    long_description=long_description,
    long_description_content_type="text/markdown",
    url="https://github.com/kibaffo33/genealogy",
    packages=setuptools.find_packages(),
    classifiers=[
        "Programming Language :: Python :: 3",
        "License :: OSI Approved :: MIT License",
        "Operating System :: OS Independent",
    ],
)


import numpy as np
import cv2
import imutils

img = cv2.imread('example.jpg', cv2.COLOR_BGR2GRAY)
template = cv2.imread('template.jpg', cv2.COLOR_BGR2GRAY)
threshold = 0.5
found = None

for scale in np.linspace(0.1, 10, 100)[::-1]:
    resized = imutils.resize(template, width=int(template.shape[1] * scale))
    ratio = template.shape[1] / resized.shape[1]
    th, tw = resized.shape[:2]

    if resized.shape[0] < img.shape[0] and resized.shape[0] < img.shape[1]:
        res = cv2.matchTemplate(img, resized, cv2.TM_CCOEFF_NORMED)
        _, maxVal, _, maxLoc = cv2.minMaxLoc(res)

        if maxVal > 0.5:
            print(maxVal)
            clone = img.copy()
            cv2.rectangle(clone, (maxLoc[0], maxLoc[1]), (maxLoc[0]+tw, maxLoc[1]+th), (0, 255, 0), 2)
            cv2.imshow('Multi-scale matching', clone)
            cv2.waitKey(0)

            if found is None or maxVal > found[0]:
                found = (maxVal, maxLoc, ratio)
        else:
            print('Nothing has been found.')

_, maxLoc, ratio = found
startX, startY = (maxLoc[0]*ratio, maxLoc[1]*ratio)
endX, endY = ((maxLoc[0]+tw)*ratio, (maxLoc[1]+th)*ratio)

cv2.rectangle(img, (startX, startY), (endX, endY), (0, 0, 255), 2)
cv2.imshow('', img)
cv2.waitKey(0)