import os
import numpy as np
import pandas as pd
import pyodbc as db
import matplotlib.pyplot as plt
from sklearn.externals import joblib
from sklearn.metrics import auc
from sklearn.metrics import roc_auc_score
from sklearn.metrics import confusion_matrix
from sklearn.metrics import roc_curve
from sklearn.metrics import precision_recall_curve
import sklearn

os.chdir(r'C:\Users\Darth\Desktop\Thesis\Code\Evaluating Trained Algorithms\final_2000-2014no(hb,wbc)')

def information(ds):
    features = ['Age', 'Albumin', 'ALP', 'ALT', 'AST', 'Bilirubin', 'Creatinine', 'INR', 'Platelets', 'BMI']
    for feat in features:
        print('Feature: ' + feat)
        print('Mean:    ' + str(np.mean(ds[feat].dropna())))
        print('2.5th:   ' + str(np.percentile(ds[feat].dropna(), 2.5)))
        print('97.5th:   ' + str(np.percentile(ds[feat].dropna(), 97.5)))
        print('')

def area_by_shoelace(x,y):
    return abs(sum(i*j for i, j in zip(x,y[1:])) + x[-1]*y[0] - sum(i*j for i,j in zip(x[1:],y)) - x[0]*y[-1])/2

def show(text):
	print(text)
	pause()

def pause():
	input('Press enter to continue!')

def APRI_class(Xp_test, Yp_test):
	indet_count = 0
	Yp_pred_new = []
	Yp_prob_new = []
	Yp_test_new = []
	det_indices = []
	apri_values = []

	for i in range(0, len(Xp_test)):
		AST_upper = 35 #31 if Xp_test[i,0] == 0 else 19
		AST = Xp_test[i,1]
		Plt = Xp_test[i,2]
		APRI = (100*AST/AST_upper)/(Plt)

#		print('AST: ' + str(AST))
#		print('AST_Upper: ' + str(AST_upper))
#		print('PLT: ' + str(Plt))
#		print('APRI: ' + str(APRI))
#		input('Press enter to continue')

		if (APRI >= 2):
			apri_values.append(APRI)
			Yp_pred_new.append(4)
			Yp_test_new.append(Yp_test[i])
			Yp_prob_new.append(1)
			det_indices.append([i])
		elif (APRI <=1):
			apri_values.append(APRI)
			Yp_pred_new.append(0)
			Yp_test_new.append(Yp_test[i])
			Yp_prob_new.append(0)
			det_indices.append([i])
		else:
			indet_count += 1
			Yp_prob_new.append(0.5)
	return Yp_pred_new, Yp_prob_new, Yp_test_new, indet_count, apri_values

def FIB4_class(Xp_test, Yp_test):
	indet_count = 0
	Yp_pred_new = []
	Yp_prob_new = []
	Yp_test_new = []
	det_indices = []
	fib4_values = []

	for i in range(0, len(Xp_test)):
		age = Xp_test[i,0]
		ALT = Xp_test[i,1]
		AST = Xp_test[i,2]
		Plt = Xp_test[i,3]

		FIB4 = age*AST/(Plt*(ALT)**0.5)
		if (FIB4 >= 3.25):
			fib4_values.append(FIB4)
			Yp_pred_new.append(4)
			Yp_prob_new.append(1)
			Yp_test_new.append(Yp_test[i])
			det_indices.append([i])
		elif (FIB4 <=1.45):
			fib4_values.append(FIB4)
			Yp_pred_new.append(0)
			Yp_prob_new.append(0)
			Yp_test_new.append(Yp_test[i])
			det_indices.append([i])
		else:
			indet_count += 1
			Yp_prob_new.append(0.5)
	return Yp_pred_new, Yp_prob_new, Yp_test_new, indet_count, fib4_values

def NAFLD_class(Xp_test, Yp_test):
	indet_count = 0
	Yp_pred_new = []
	Yp_prob_new = []
	Yp_test_new = []
	det_indices = []
	nafld_values = []

	for i in range(0, len(Xp_test)):
		age = Xp_test[i,0]
		albumin = Xp_test[i,1]
		ALT = Xp_test[i,2]
		AST = Xp_test[i,3]
		Plt = Xp_test[i,4]
		BMI = Xp_test[i,5]
		Diab = Xp_test[i,6]

#		print('Age: ' + str(age))
#		print('Alb: ' + str(albumin))
#		print('ALT: ' + str(ALT))
#		print('AST: ' + str(AST))
#		print('Plt: ' + str(Plt))
#		print('BMI: ' + str(BMI))
#		print('Diab: ' + str(Diab))

		NAFLD = -1.675 + 0.037*age + 0.094*BMI + 1.13*Diab + 0.99*(AST/ALT) - 0.013*Plt - 0.66*albumin/10
#		input('NAFLD index was : ' + str(NAFLD))
		if (NAFLD >= 0.676):
			nafld_values.append(NAFLD)
			Yp_pred_new.append(4)
			Yp_prob_new.append(1)
			Yp_test_new.append(Yp_test[i])
			det_indices.append([i])
		elif (NAFLD <=-1.455):
			nafld_values.append(NAFLD)
			Yp_pred_new.append(0)
			Yp_prob_new.append(0)
			Yp_test_new.append(Yp_test[i])
			det_indices.append([i])
		else:
			indet_count += 1
			Yp_prob_new.append(0.5)
	return Yp_pred_new, Yp_prob_new, Yp_test_new, indet_count, nafld_values

def ENS_class(s,r,g,l,k,m, ap, fb, Xp_test, Yp_test, params, excluded_algs):
	indet_count = 0
	Yp_pred_new = []
	Yp_prob_new = []
	Yp_test_new = []
	det_indices = []
	probabilities = []
	#algs = [s,r,g,l,k,m,]
	algs = []

	if ('SVM' not in excluded_algs):
		algs.append(s)
	if ('RFC' not in excluded_algs):
		algs.append(r)
	if ('GBC' not in excluded_algs):
		algs.append(g)
	if ('LOG' not in excluded_algs):
		algs.append(l)
	if ('KNN' not in excluded_algs):
		algs.append(k)
	if ('MLP' not in excluded_algs):
		algs.append(m)

	indet_f4 = 0
	indet_f0 = 0

	for i in range(0, len(Xp_test)):
		prob_sum = 0
		terms = 0
		weight_sum = 0
		f4_votes = 0
		f0_votes = 0

		for alg in algs:
			prob_sum += alg[i]
			terms += 1
		probabilities.append(prob_sum/terms)
#		if ((ap[i] == 0.5 and params['indets'] == 'APRI') or (fb[i] == 0.5 and params['indets'] == 'FIB4')):
#				indet_count += 1
#				continue
		p=('%.2f' %  (probabilities[i]))
		if (probabilities[i] >= (params['threshold'] + params['indet_range_high'])):
			#print('Guessed 4 for probability: ' + str(probabilities[i]) + ' at threshold ' + str(params['threshold'] + params['indet_range_high']))
			Yp_pred_new.append(4)
			Yp_test_new.append(Yp_test[i])
			Yp_prob_new.append(probabilities[i])
			det_indices.append(i)
			print(p + ' guessed F4')
		elif (probabilities[i] < (params['threshold'] - params['indet_range_low'])):
			Yp_pred_new.append(0)
			Yp_test_new.append(Yp_test[i])
			Yp_prob_new.append(probabilities[i])
			#print('Guessed 0 for probability: ' + str(probabilities[i]) + ' at threshold ' + str(params['threshold'] - params['indet_range_low']))
			det_indices.append(i)
			print(p + ' guessed F01')
		else:
			if(params['indet_guess_mode'] == 'none'):
				indet_count += 1
			elif(params['indet_guess_mode'] == 'aprifib4'):
				if(ap[i] == 1 and fb[i] == 1):
					#print('Guessed indeterminate, but APRI and FIB4 both said 4')
					Yp_pred_new.append(4)
					Yp_test_new.append(Yp_test[i])
					Yp_prob_new.append(probabilities[i])
					det_indices.append(i)
					print(p + ' guessed F4 w/ AF')
				elif(ap[i] == 0 and fb[i] == 0):
					#print('Guessed indeterminate, but APRI and FIB4 both said 0')
					Yp_pred_new.append(0)
					Yp_test_new.append(Yp_test[i])
					Yp_prob_new.append(probabilities[i])
					det_indices.append(i)
					print(p + ' guessed F01 w/ AF')
				else:
					print('Guessed indeterminate on an ' + str(Yp_test[i]))
					indet_count += 1
#					if (Yp_test[i] == 4):
#					   indet_f4 += 1
#					else:
#					   indet_f0 += 1
#
#	print('ENS3 # of indet F4s: ' + str(indet_f4))
#	print('ENS3 # of indet F01s: ' + str(indet_f0))
	print(Yp_pred_new)
	return Yp_pred_new, Yp_prob_new, Yp_test_new, indet_count, det_indices

def write_performance_metrics(cms, names, aurocs, man_aurocs, auprcs, man_auprcs, indet_array, threshold_array, excluded_algs, noshow):
	from beautifultable import BeautifulTable
	table = BeautifulTable(max_width=300)
	table.append_column(' ', ['sensitivity', 'specificity', 'PPV', 'NPV', 'accuracy', 'Manual AUROC', 'Manual AUPRC', '% indet', 'Dec. Thresh. (%)'])
	count = 0
	for cm in cms:
		if (names[count] in excluded_algs):
			print('Did not include ' + str(names[count]) + 'results!')
			count += 1
			continue
		if (names[count] in noshow):
			#print('Did not show ' + str(names[count]) + 'results!')
			count += 1
			continue
#		if (names[count] == 'APRI' or names[count] == 'FIB4'):
#        		count += 1
#        		continue
		#if (names[count] != 'ENS1' and names[count] != 'ENS2' and names[count] != 'ENS3'):
        #		count += 1
        #		continue
		tot = cm[0,0] + cm[0,1] + cm[1,0] + cm[1,1]
		tp = cm[1,1]
		fp = cm[0,1]
		tn = cm[0,0]
		fn = cm[1,0]

		accuracy = 100*(tp + tn)/(tot)
		precision = 100*tp/(tp + fp)
		negPredVal = 100*tn/(tn + fn)
		sensitivity = 100*tp/(tp + fn)
		falseNegRate = 100*fn/(fn + tp)
		specificity = 100*tn/(tn + fp)
		falsePosRate = 100*fp/(fp + tn)
		f1 = 100*2*precision*sensitivity/(precision + sensitivity)
		auc = aurocs[count]
		man_aucs = man_aurocs[count]
		prc = auprcs[count]
		man_prcs = man_auprcs[count]
		indt = indet_array[count]
		thresh = threshold_array[count]
		table.append_column(names[count], [(' %0.1f' % sensitivity), (' %0.1f' % specificity), (' %0.1f' % precision), (' %0.1f' % negPredVal), (' %0.1f' % accuracy), (' %0.1f' % (100*man_aucs)), (' %0.1f' % (100*man_prcs)), (' %0.1f' % (100*indt)), thresh])
		count += 1
	print(table)

def my_auprc_non_prob(test_values, Yp_test):
    thresholds = np.linspace(0, np.max(test_values)+0.5, 1000)

    tprs = []
    precs = []

    for t in thresholds:
        Yp_pred = (test_values >= t)*4

        cm = my_confusion_matrix(Yp_test, Yp_pred)

        tp = cm[1,1]
        fp = cm[0,1]
        fn = cm[1,0]

        if (tp + fn == 0):
            tprs.append(np.nan)
        else:
            tprs.append(tp/(tp+fn))

        if (tp + fp == 0):
            precs.append(np.nan)
        else:
            precs.append(tp/(tp+fp))

#        print('Threshold: ' + str(t))
#        print(Yp_pred)
#        print(Yp_test)
#        print('TPRS: ' + str(tprs[len(tprs)-1]))
#        print('PRECS: ' + str(precs[len(precs)-1]))
#        print('Threshold: ' + str(t))
#        print('TPRS:')
#        print(tprs)
#        print('PRECS:')
#        print(precs)
#        print('')
#        input('Press enter to continue!')

    prc_curve = []
    prc_tprs = np.array([])
    prc_prcs = np.array([])

    for i in range(0, len(tprs) - 1):
        tpr = tprs[i]
        pre = precs[i]

        if (np.isnan(tpr) == True or np.isnan(pre) == True):
            continue
        if (np.isnan(tpr) == False and np.isnan(pre) == False):
            prc_tprs = np.append(prc_tprs, tpr)
            prc_prcs = np.append(prc_prcs, pre)

    if (prc_tprs[-1] == 0 and prc_prcs[-1] == 0):
        prc_tprs = np.append(prc_tprs, np.array([1]))
        prc_prcs = np.append(prc_prcs, np.array([0]))
    else:
        prc_tprs = np.append(prc_tprs, np.array([0,0,1]))
        prc_prcs = np.append(prc_prcs, np.array([1,0,0]))

    auprc1 = area_by_shoelace(prc_tprs, prc_prcs)

    for i in range(0, len(tprs) - 1):
        if (np.isnan(tprs[i]) == False and np.isnan(precs[i]) == False):
            prc_curve.append((tprs[i], precs[i]))
    #prc_curve = np.sort(prc_curve, axis=0)
    sorted_tprs = []
    sorted_precs = []

    for i in range(0,len(prc_curve)-1):
        sorted_tprs.append(prc_curve[i][0])
        sorted_precs.append(prc_curve[i][1])
    auprc = auc(sorted_tprs, sorted_precs, reorder=True)
#    print('Original method: ' + str(auprc))
#    print('Shoelace method: ' + str(auprc1))
#    input('Press enter to continue!')

    return auprc1, sorted_tprs, sorted_precs, prc_curve

def my_auroc_non_prob(test_values, Yp_test):
	thresholds = np.linspace(np.min(test_values),np.max(test_values),1000)

	fprs = []
	tprs = []

	for t in thresholds:
		Yp_pred = (test_values >= t)*4
		cm = my_confusion_matrix(Yp_test, Yp_pred)

		tp = cm[1,1]
		fp = cm[0,1]
		tn = cm[0,0]
		fn = cm[1,0]

		if (fp + tn == 0):
			fprs.append(np.nan)
		else:
			fprs.append(fp/(fp+tn))

		if (tp + fn == 0):
			tprs.append(np.nan)
		else:
			tprs.append(tp/(tp+fn))

	roc_curve = [(0,0),(1,1)]

	for i in range(0,len(fprs)-1):
		if (np.isnan(fprs[i]) == False and np.isnan(tprs[i]) == False):
			roc_curve.append((fprs[i], tprs[i]))

	roc_curve = np.sort(roc_curve, axis=0)
	sorted_fprs = []
	sorted_tprs = []

	for i in range(0,len(roc_curve)-1):
		sorted_fprs.append(roc_curve[i][0])
		sorted_tprs.append(roc_curve[i][1])
	auroc = auc(sorted_fprs, sorted_tprs)

	return auroc, sorted_fprs, sorted_tprs

def my_auprc_prob(probs, Yp_test):
	from sklearn.metrics import auc
	from numpy import trapz
	tprs = []
	precs = []
	threshs = []

	for i in range(0,250):
		thresh = i/250
		Yp_pred = (np.asarray(probs) > np.asarray(thresh))*4
		cm = my_confusion_matrix(Yp_test, Yp_pred)

		tp = cm[1,1]
		fp = cm[0,1]
		fn = cm[1,0]

		if (tp + fn == 0 or tp + fp == 0):
				tprs.append(np.nan)
				precs.append(np.nan)
				threshs.append(np.nan)
		else:
				precs.append(tp/(tp+fp))
				tprs.append(tp/(tp+fn))
				threshs.append(thresh)

	tprs.append(1)
	precs.append(0)
	threshs.append(np.nan)

	tprs.append(0)
	precs.append(1)
	threshs.append(np.nan)

	prc_curve = []
	prc_tprs = np.array([])
	prc_prcs = np.array([])

	for i in range(0, len(tprs) - 1):
		tpr = tprs[i]
		pre = precs[i]

		if (np.isnan(tpr) == True or np.isnan(pre) == True):
			continue
		if (np.isnan(tpr) == False and np.isnan(pre) == False):
			if (tpr == 1 and pre == 0):
				continue
			prc_tprs = np.append(prc_tprs, tpr)
			prc_prcs = np.append(prc_prcs, pre)

	if (prc_tprs[-1] == 0 and prc_prcs[-1] == 0):
		prc_tprs = np.append(prc_tprs, np.array([1]))
		prc_prcs = np.append(prc_prcs, np.array([0]))
	else:
		prc_tprs = np.append(prc_tprs, np.array([0,0,1]))
		prc_prcs = np.append(prc_prcs, np.array([1,0,0]))

#	for i in range(0, len(prc_tprs)):
#		print('(%0.3f, %0.3f)' % (prc_tprs[i], prc_prcs[i]))

	auprc1 = area_by_shoelace(prc_tprs, prc_prcs)

	for i in range(0,max(len(tprs), len(precs))):
		if (np.isnan(tprs[i]) == False and np.isnan(precs[i]) == False):
			prc_curve.append([tprs[i],  precs[i]])
	sorted_tprs = []
	sorted_precs = []

	for i in range(0,len(prc_curve)):
		sorted_tprs.append(prc_curve[i][0])
		sorted_precs.append(prc_curve[i][1])
	auprc = auc(sorted_tprs, sorted_precs, reorder=True)

	#temp = pd.DataFrame(data=[tprs, precs])
	#temp = temp.transpose()
	#temp.to_csv('temp_AUPRC_check.csv')

#	print('Old method AUPRC: ' + str(auprc))
#	print('Shoelace method AURPC: ' + str(auprc1))
#	input('Batman')

	#return auprc, sorted_tprs, sorted_precs
	return auprc1, tprs, precs

def my_auroc_prob(probs, Yp_test):
	from sklearn.metrics import auc
	fprs = []
	tprs = []

	for i in range(0,3001):
		thresh = i/3000
		Yp_pred = (np.asarray(probs) > np.asarray(thresh))*4
		cm = my_confusion_matrix(Yp_test, Yp_pred)

		tp = cm[1,1]
		fp = cm[0,1]
		tn = cm[0,0]
		fn = cm[1,0]

		if (fp + tn == 0):
			fprs.append(np.nan)
		else:
			fprs.append(fp/(fp+tn))

		if (tp + fn == 0):
			tprs.append(np.nan)
		else:
			tprs.append(tp/(tp+fn))

	roc_curve = [(0,0),(1,1)]

	for i in range(0,len(fprs)-1):
		if (np.isnan(fprs[i]) == False and np.isnan(tprs[i]) == False):
			roc_curve.append((fprs[i],  tprs[i]))

	roc_curve = np.sort(roc_curve, axis=0)
	sorted_fprs = []
	sorted_tprs = []
	for i in range(0,len(roc_curve)-1):
		sorted_fprs.append(roc_curve[i][0])
		sorted_tprs.append(roc_curve[i][1])
	auroc = auc(sorted_fprs, sorted_tprs)
	return auroc, sorted_fprs, sorted_tprs

def my_confusion_matrix(truth, pred):
    TN_count = 0
    TP_count = 0
    FP_count = 0
    FN_count = 0

    for i in range(0,len(truth)):
        if(pred[i] == 0 and truth[i] == 0):
            TN_count += 1
        elif(pred[i] == 4 and truth[i] == 4):
            TP_count += 1
        elif(pred[i] == 4 and truth[i] == 0):
            FP_count += 1
        elif(pred[i] == 0 and truth[i] == 4):
            FN_count += 1

    cm = np.ndarray(shape=(2,2))
    cm[1,1] = TP_count
    cm[0,1] = FP_count
    cm[0,0] = TN_count
    cm[1,0] = FN_count
    return cm
# Testing with ICES data to make sure the rest of the code works. This code is only loaded at runtime, and is not saved anywhere in the directories being extracted.
#dataset = pd.read_csv('/dshroot/projects/hspe/dsh0990.111.003/user_data/ssabetsarvestany/dataset_assembly/dataset_bx_30.csv')
#dataset['sex'] = np.where(dataset['sex'] == 'Male', 0, 1)
#dataset['reckey_enc'] = dataset['reckey_enc'].astype(str)
#dataset['patientID'] = dataset['reckey_enc'] + '|' + dataset['bx_date']
#dataset = dataset.sort_values(by='bx_date', ascending=False)
#dataset = dataset.reset_index(drop=True)
#dataset = dataset.loc[dataset['bx_date'] >= '2012-01-01']
#dataset = dataset.loc[dataset['with_olis_missingness'] <= 3]
#dataset = dataset.rename(columns={'calc_bmi': 'bmi'})
#features = ['sex', 'age', 'albumin', 'alp', 'alt', 'ast', 'tot_bil', 'creatinine', 'inr', 'platelets', 'bmi', 'diabetes', 'hb', 'wbc', 'fibrosis', 'patientID', 'bx_date', 'reckey_enc']
#dataset = dataset[features]

desc_string = ''
data = 'McGill'
missThresh = 3
exc = []

no_show = []# ['SVM', 'RFC', 'GBC', 'LOG', 'MLP']
exc_alg = ['KNN']

desc_string += data + ' holdout set, missingness <=' + str(missThresh)

if ('Age' in exc):
    desc_string += ', Age <= 60'
if ('Albumin' in exc):
    desc_string += ', Albumin >= 30'

#Code to import Toronto 2015-2016 and Mcgill datasets once everything has been extracted
conn_str = (r'DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};'r'DBQ=C:\Users\Darth\Desktop\Thesis\Data\Fibrosis.accdb;')
cnxn = db.connect(conn_str)
cursor = cnxn.cursor()

if (data == 'Toronto'):
    sql = "SELECT * FROM _TorontoHoldOut30"
if (data == 'McGill'):
    sql = "SELECT * FROM _McGillData WHERE Neoplasm=0 AND FIBROSIS IS NOT NULl"
if (data == 'Expert'):
    sql = "SELECT * FROM _ExpertPredsCombined WHERE bx_date IS NOT NULL"#_ExpertPredsCombined"

dataset = pd.read_sql(sql, cnxn)

#ds1 = pd.read_sql("SELECT * FROM _TorontoHoldOut30 WHERE [WilsonsDisease]=1 OR OTHER=1", cnxn)
#ds2 = pd.read_sql("SELECT * FROM _McGillData WHERE NEOPLASM=0 AND ([WilsonsDisease]=1 OR OTHER=1)", cnxn)
#dataset = ds1.append(ds2)
#print(dataset.columns.tolist())
#dataset = dataset.loc[dataset['Other'] == 1]
#dataset = dataset.loc[dataset['AST'] < 1000]
dataset = dataset.reset_index(drop=True)
dataset = dataset.loc[dataset['missingness'] <= missThresh]
#dataset = dataset.loc[(dataset['Fibrosis'] == 0) | (dataset['Fibrosis'] == 1) | (dataset['Fibrosis'] == 4)]
#dataset['Fibrosis'] = np.where(dataset['Fibrosis'] == 2, 4, dataset['Fibrosis'])
#dataset['Fibrosis'] = np.where(dataset['Fibrosis'] == 3, 4, dataset['Fibrosis'])
dataset['Fibrosis'] = np.where(dataset['Fibrosis'] >= 4, 4, 0)

if ('Age' in exc):
    dataset = dataset.loc[dataset['Age'] <= 60]

if ('Albumin' in exc):
    dataset = dataset.loc[dataset['Albumin'] >= 30]

#exp_data = pd.read_sql("SELECT * FROM _ExpertPreds", cnxn)
#exp_data = exp_data.reset_index(drop=True)
#exp_data['Fibrosis'] = np.where(exp_data['Fibrosis'] == 'F 4', 4, 0)

#F01s = dataset.loc[dataset['Fibrosis'] == 0]
#F4s = dataset.loc[dataset['Fibrosis'] == 4]
#F01s = F01s.sample(len(F4s), random_state=20)
#dataset = F01s.append(F4s, ignore_index=False, verify_integrity=True)
#dataset = dataset.sample(frac=1, random_state=0)

#print('Number of records: ' + str(len(dataset)))
#print('Number of NAFL records: ' + str(num_nafl))
#print('% NAFL: ' + str(100*num_nafl/len(dataset)))
#print(dataset.columns.tolist())
features = ['Sex', 'Age', 'Albumin', 'ALP', 'ALT', 'AST', 'Bilirubin', 'Creatinine', 'INR', 'Platelets', 'BMI', 'Diabetes', 'Hb', 'WBC', 'Fibrosis', 'patientID', 'bx_date', 'reckey_enc']
dataset = dataset[features]

F0 = dataset.loc[dataset['Fibrosis'] == 0]
F4 = dataset.loc[dataset['Fibrosis'] == 4]

#information(F0)
#show('Enter to continue')
#information(F4)

#exp_data = exp_data[features]
#dataset['Sex'] = dataset['Sex'].astype(int)

#exp_data = exp_data.loc[exp_data['Age'] < 60]
#exp_data = exp_data.loc[exp_data['Albumin'] >= 30]
#exp_data = exp_data.reset_index(drop=True)

imputer = joblib.load('imputer.joblib')
scaler = joblib.load('scaler.joblib')

# Predicting on Toronto and McGill datasets
X_test_unimp = dataset.iloc[:,0:len(features) - 4].values
X_test_imp = imputer.transform(X_test_unimp)
X_test_imp_scl = scaler.transform(X_test_imp)
Y_test = dataset.iloc[:,len(features)-4].values

# Predicting on Expert Cases
#X_test_unimp = exp_data.iloc[:,0:len(features)-4].values
#X_test_imp = imputer.transform(X_test_unimp)
#X_test_imp_scl = scaler.transform(X_test_imp)
#Y_test = exp_data.iloc[:,len(features)-4].values

cm_array = []
name_array = []
auroc_array = []
my_auroc_array = []
auprc_array = []
my_auprc_array = []
indet_array = []
threshold_array = []

#Loading the algorithms used in the ensemble model
print('Now making predictions for SVM')
SVM_model = joblib.load('SVM.joblib')
SVM_probs = SVM_model.predict_proba(X_test_imp_scl[:,[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11]])
SVM_probs = SVM_probs[:,1]
SVM_fprs_py, SVM_tprs_py, threshold = roc_curve(Y_test/4, SVM_probs)
SVM_precs_py, SVM_recs_py, thresholds = precision_recall_curve(Y_test/4, SVM_probs)
SVM_preds = (SVM_probs > 0.4)*4
SVM_cm = my_confusion_matrix(Y_test,SVM_preds)
cm_array.append(SVM_cm)
name_array.append('SVM')
try:
    auroc_array.append(roc_auc_score(Y_test/4, SVM_probs)) # Python calculated AUROC
except ValueError:
    auroc_array.append(np.nan)
try:
    SVM_AUROC, SVM_fprs, SVM_tprs = my_auroc_prob(SVM_probs, Y_test) # Manually calculated AUROC
    my_auroc_array.append(SVM_AUROC)
except ValueError:
    my_auroc_array.append(np.nan)
try:
    auprc_array.append(auc(SVM_recs_py, SVM_precs_py))
except ValueError:
    auprc_array.append(np.nan)
try:
    SVM_AUPRC, SVM_recs, SVM_precs = my_auprc_prob(SVM_probs, Y_test)
    my_auprc_array.append(SVM_AUPRC)
except ValueError:
    my_auprc_array.append(np.nan)
except IndexError:
    my_auprc_array.append(np.nan)

indet_array.append(0)
threshold_array.append(0.4)

print('Now making predictions for RFC')
RFC_model = joblib.load('RFC.joblib')
RFC_probs = RFC_model.predict_proba(X_test_imp_scl[:,[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]])
RFC_probs = RFC_probs[:,1]
RFC_fprs_py, RFC_tprs_py, threshold = roc_curve(Y_test/4, RFC_probs)
RFC_precs_py, RFC_recs_py, thresholds = precision_recall_curve(Y_test/4, RFC_probs)
RFC_preds = (RFC_probs > 0.4)*4
RFC_cm = my_confusion_matrix(Y_test,RFC_preds)
cm_array.append(RFC_cm)
name_array.append('RFC')
try:
    auroc_array.append(roc_auc_score(Y_test/4, RFC_probs)) # Python calculated AUROC
except ValueError:
    auroc_array.append(np.nan)

try:
    RFC_AUROC, RFC_fprs, RFC_tprs = my_auroc_prob(RFC_probs, Y_test) # Manually calculated AUROC
    my_auroc_array.append(RFC_AUROC)
except ValueError:
    my_auroc_array.append(np.nan)

try:
    auprc_array.append(auc(RFC_recs_py, RFC_precs_py))
except ValueError:
    auprc_array.append(np.nan)

try:
    RFC_AUPRC, RFC_recs, RFC_precs = my_auprc_prob(RFC_probs, Y_test)
    my_auprc_array.append(RFC_AUPRC)
except ValueError:
    my_auprc_array.append(np.nan)
except IndexError:
    my_auprc_array.append(np.nan)
indet_array.append(0)
threshold_array.append(0.4)

print('Now making predictions for GBC')
GBC_model = joblib.load('GBC.joblib')
GBC_probs = GBC_model.predict_proba(X_test_imp_scl[:,[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11]])
GBC_probs = GBC_probs[:,1]
GBC_fprs_py, GBC_tprs_py, threshold = roc_curve(Y_test/4, GBC_probs)
GBC_precs_py, GBC_recs_py, thresholds = precision_recall_curve(Y_test/4, GBC_probs)
GBC_preds = (GBC_probs > 0.4)*4
GBC_cm = my_confusion_matrix(Y_test,GBC_preds)
cm_array.append(GBC_cm)
name_array.append('GBC')
try:
    auroc_array.append(roc_auc_score(Y_test/4, GBC_probs)) # Python calculated AUROC
except ValueError:
    auroc_array.append(np.nan)

try:
    GBC_AUROC, GBC_fprs, GBC_tprs = my_auroc_prob(GBC_probs, Y_test) # Manually calculated AUROC
    my_auroc_array.append(GBC_AUROC)
except ValueError:
    my_auroc_array.append(np.nan)

try:
    auprc_array.append(auc(GBC_recs_py, GBC_precs_py))
except ValueError:
    auprc_array.append(np.nan)

try:
    GBC_AUPRC, GBC_recs, GBC_precs = my_auprc_prob(GBC_probs, Y_test)
    my_auprc_array.append(GBC_AUPRC)
except ValueError:
    my_auprc_array.append(np.nan)
except IndexError:
    my_auprc_array.append(np.nan)
indet_array.append(0)
threshold_array.append(0.4)

#print('Feature ranking for GBC')
#for i in range(0,11):
#    key = feats[i][0]
#    val = feats[i][1]
#    print('%10s:    %0.2f' % (key, val))
#
#for key in feats:
#    print('%5s %0.2f'%(key, feats[0](key)))

print('Now making predictions for LOG')
LOG_model = joblib.load('LOG.joblib')
LOG_probs = LOG_model.predict_proba(X_test_imp_scl[:,[0, 1, 2, 4, 5, 6, 7, 8, 9, 10, 11]])
LOG_probs = LOG_probs[:,1]
LOG_fprs_py, LOG_tprs_py, threshold = roc_curve(Y_test/4, LOG_probs)
LOG_precs_py, LOG_recs_py, thresholds = precision_recall_curve(Y_test/4, LOG_probs)
LOG_preds = (LOG_probs > 0.4)*4
LOG_cm = my_confusion_matrix(Y_test,LOG_preds)
cm_array.append(LOG_cm)
name_array.append('LOG')
try:
    auroc_array.append(roc_auc_score(Y_test/4, LOG_probs)) # Python calculated AUROC
except ValueError:
    auroc_array.append(np.nan)

try:
    LOG_AUROC, LOG_fprs, LOG_tprs = my_auroc_prob(LOG_probs, Y_test) # Manually calculated AUROC
    my_auroc_array.append(LOG_AUROC)
except ValueError:
    my_auroc_array.append(np.nan)

try:
    auprc_array.append(auc(LOG_recs_py, LOG_precs_py))
except ValueError:
    auprc_array.append(np.nan)

try:
    LOG_AUPRC, LOG_recs, LOG_precs = my_auprc_prob(LOG_probs, Y_test)
    my_auprc_array.append(LOG_AUPRC)
except ValueError:
    my_auprc_array.append(np.nan)
except IndexError:
    my_auprc_array.append(np.nan)
indet_array.append(0)
threshold_array.append(0.4)

print('Now making predictions for KNN')
KNN_model = joblib.load('KNN.joblib')
KNN_probs = KNN_model.predict_proba(X_test_imp_scl[:,[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]])
KNN_probs = KNN_probs[:,1]
KNN_fprs_py, KNN_tprs_py, threshold = roc_curve(Y_test/4, KNN_probs)
KNN_precs_py, KNN_recs_py, thresholds = precision_recall_curve(Y_test/4, KNN_probs)
KNN_preds = (KNN_probs > 0.4)*4
KNN_cm = my_confusion_matrix(Y_test,KNN_preds)
cm_array.append(KNN_cm)
name_array.append('KNN')
try:
    auroc_array.append(roc_auc_score(Y_test/4, KNN_probs)) # Python calculated AUROC
except ValueError:
    auroc_array.append(np.nan)

try:
    KNN_AUROC, KNN_fprs, KNN_tprs = my_auroc_prob(KNN_probs, Y_test) # Manually calculated AUROC
    my_auroc_array.append(KNN_AUROC)
except ValueError:
    my_auroc_array.append(np.nan)

try:
    auprc_array.append(auc(KNN_recs_py, KNN_precs_py))
except ValueError:
    auprc_array.append(np.nan)

try:
    KNN_AUPRC, KNN_recs, KNN_precs = my_auprc_prob(KNN_probs, Y_test)
    my_auprc_array.append(KNN_AUPRC)
except ValueError:
    my_auprc_array.append(np.nan)
except IndexError:
    my_auprc_array.append(np.nan)
indet_array.append(0)
threshold_array.append(0.4)

print('Now making predictions for MLP')
MLP_model = joblib.load('MLP.joblib')
MLP_probs = MLP_model.predict_proba(X_test_imp_scl[:,[0, 1, 2, 3, 4, 5, 8, 9, 10, 11]])
MLP_probs = MLP_probs[:,1]
MLP_fprs_py, MLP_tprs_py, threshold = roc_curve(Y_test/4, MLP_probs)
MLP_precs_py, MLP_recs_py, thresholds = precision_recall_curve(Y_test/4, MLP_probs)
MLP_preds = (MLP_probs > 0.4)*4
MLP_cm = my_confusion_matrix(Y_test,MLP_preds)
cm_array.append(MLP_cm)
name_array.append('MLP')
try:
    auroc_array.append(roc_auc_score(Y_test/4, MLP_probs)) # Python calculated AUROC
except ValueError:
    auroc_array.append(np.nan)
try:
    MLP_AUROC, MLP_fprs, MLP_tprs = my_auroc_prob(MLP_probs, Y_test) # Manually calculated AUROC
    my_auroc_array.append(MLP_AUROC)
except ValueError:
    my_auroc_array.append(np.nan)
try:
    auprc_array.append(auc(MLP_recs_py, MLP_precs_py))
except ValueError:
    auprc_array.append(np.nan)
try:
    MLP_AUPRC, MLP_recs, MLP_precs = my_auprc_prob(MLP_probs, Y_test)
    my_auprc_array.append(MLP_AUPRC)
except ValueError:
    my_auprc_array.append(np.nan)
except IndexError:
    my_auprc_array.append(np.nan)

indet_array.append(0)
threshold_array.append(0.4)

print('Now making predictions for APRI')
APRI_preds, APRI_probs, APRI_test, APRI_indet_count, APRI_values = APRI_class(X_test_imp[:,[0, 5, 9]], Y_test)
APRI_precs_py, APRI_recs_py, thresholds = precision_recall_curve(Y_test/4, APRI_probs)
APRI_cm = my_confusion_matrix(APRI_test,APRI_preds)
cm_array.append(APRI_cm)
name_array.append('APRI')
try:
    auroc_array.append(roc_auc_score(Y_test/4, APRI_probs))
except ValueError:
    auroc_array.append(np.nan)
try:
    APRI_AUROC, APRI_fprs, APRI_tprs = my_auroc_non_prob(APRI_values, APRI_test)
    my_auroc_array.append(APRI_AUROC)
except ValueError:
    my_auroc_array.append(np.nan)
try:
    auprc_array.append(auc(APRI_recs_py, APRI_precs_py))
except ValueError:
    auprc_array.append(np.nan)
try:
    APRI_AUPRC, APRI_recs, APRI_precs, APRI_prc_curve = my_auprc_non_prob(APRI_values, APRI_test)
    my_auprc_array.append(APRI_AUPRC)
except ValueError:
    my_auprc_array.append(np.nan)
except IndexError:
    my_auprc_array.append(np.nan)

indet_array.append(APRI_indet_count/len(Y_test))
threshold_array.append('n/a')

print('Now making predictions for FIB4')
FIB4_preds, FIB4_probs, FIB4_test, FIB4_indet_count, FIB4_values = FIB4_class(X_test_imp[:,[1, 4, 5, 9]], Y_test)
FIB4_precs_py, FIB4_recs_py, thresholds = precision_recall_curve(Y_test/4, FIB4_probs)
FIB4_cm = my_confusion_matrix(FIB4_test,FIB4_preds)
cm_array.append(FIB4_cm)
name_array.append('FIB4')
try:
    auroc_array.append(roc_auc_score(Y_test/4, FIB4_probs))
except ValueError:
    auroc_array.append(np.nan)
try:
    FIB4_AUROC, FIB4_fprs, FIB4_tprs = my_auroc_non_prob(FIB4_values, FIB4_test)
    my_auroc_array.append(FIB4_AUROC)
except ValueError:
    my_auroc_array.append(np.nan)
try:
    auprc_array.append(auc(FIB4_recs_py, FIB4_precs_py))
except ValueError:
    auprc_array.append(np.nan)
try:
    FIB4_AUPRC, FIB4_recs, FIB4_precs, FIB4_prc_curve = my_auprc_non_prob(FIB4_values, FIB4_test)
    my_auprc_array.append(FIB4_AUPRC)
except ValueError:
    my_auprc_array.append(np.nan)
except IndexError:
    my_auprc_array.append(np.nan)

indet_array.append(FIB4_indet_count/len(Y_test))
threshold_array.append('n/a')

print('Now making predictions for NAFLD')
NAFLD_preds, NAFLD_probs, NAFLD_test, NAFLD_indet_count, NAFLD_values = NAFLD_class(X_test_imp[:,[1, 2, 4, 5, 9, 10, 11]], Y_test)
NAFLD_precs_py, NAFLD_recs_py, thresholds = precision_recall_curve(Y_test/4, NAFLD_probs)
NAFLD_cm = my_confusion_matrix(NAFLD_test,NAFLD_preds)
cm_array.append(NAFLD_cm)
name_array.append('NAFLD')
try:
    auroc_array.append(roc_auc_score(Y_test/4, NAFLD_probs))
except ValueError:
    auroc_array.append(np.nan)
try:
    NAFLD_AUROC, NAFLD_fprs, NAFLD_tprs = my_auroc_non_prob(NAFLD_values, NAFLD_test)
    my_auroc_array.append(NAFLD_AUROC)
except ValueError:
    my_auroc_array.append(np.nan)
try:
    auprc_array.append(auc(NAFLD_recs_py, NAFLD_precs_py))
except ValueError:
    auprc_array.append(np.nan)
try:
    NAFLD_AUPRC, NAFLD_recs, NAFLD_precs, NAFLD_prc_curve = my_auprc_non_prob(NAFLD_values, NAFLD_test)
    my_auprc_array.append(NAFLD_AUPRC)
except ValueError:
    my_auprc_array.append(np.nan)
except IndexError:
    my_auprc_array.append(np.nan)

indet_array.append(NAFLD_indet_count/len(Y_test))
threshold_array.append('n/a')

#NAFLD_cm = confusion_matrix(NAFLD_test,NAFLD_preds)
#cm_array.append(NAFLD_cm)
#name_array.append('NAFLD')
#auroc_array.append(roc_auc_score(Y_test/4, NAFLD_probs))
#my_auroc_array.append(my_auroc_non_prob(NAFLD_values, NAFLD_test))
#indet_array.append(NAFLD_indet_count/len(Y_test))
#threshold_array.append('n/a')

thresh = 0.45
low_indet_range = 0.2
high_indet_range = 0.0

ENS1_params = joblib.load('ENS1.joblib')
ENS1_params['threshold'] = thresh
ENS1_params['indets'] = 'None'
ENS1_preds, ENS1_probs, ENS1_test, ENS1_indet_count, ENS1_det_indices = ENS_class(SVM_probs, RFC_probs, GBC_probs, LOG_probs, KNN_probs, MLP_probs, APRI_probs, FIB4_probs, X_test_imp_scl, Y_test, ENS1_params, exc_alg)
ENS1_test = np.array(ENS1_test)
ENS1_fprs_py, ENS1_tprs_py, threshold = roc_curve(ENS1_test/4, ENS1_probs)
ENS1_precs_py, ENS1_recs_py, thresholds = precision_recall_curve(ENS1_test/4, ENS1_probs)
ENS1_cm = my_confusion_matrix(ENS1_test, ENS1_preds)
cm_array.append(ENS1_cm)
name_array.append('ENS1')

try:
    auroc_array.append(roc_auc_score(np.asarray(ENS1_test)/4, ENS1_probs))
except ValueError:
    auroc_array.append(np.nan)
try:
    ENS1_AUROC, ENS1_fprs, ENS1_tprs = my_auroc_prob(ENS1_probs, ENS1_test)
    my_auroc_array.append(ENS1_AUROC)
except ValueError:
    my_auroc_array.append(np.nan)
try:
    auprc_array.append(auc(ENS1_recs_py, ENS1_precs_py))
except ValueError:
    auprc_array.append(np.nan)
try:
    ENS1_AUPRC, ENS1_recs, ENS1_precs = my_auprc_prob(ENS1_probs, ENS1_test)
    my_auprc_array.append(ENS1_AUPRC)
except ValueError:
    my_auprc_array.append(np.nan)
except IndexError:
    my_auprc_array.append(np.nan)

indet_array.append(ENS1_indet_count/len(Y_test))
threshold_array.append(ENS1_params['threshold'])

#ENS2_params = joblib.load('ENS2.joblib')
#ENS2_params['threshold'] = thresh
#ENS2_params['indet_range_low'] = low_indet_range
#ENS2_preds, ENS2_probs, ENS2_test, ENS2_indet_count, ENS2_det_indices = ENS_class(SVM_probs, RFC_probs, GBC_probs, LOG_probs, KNN_probs, MLP_probs, APRI_probs, FIB4_probs,  X_test_imp_scl, Y_test, ENS2_params, exc_alg)
#ENS2_cm = confusion_matrix(ENS2_test, ENS2_preds)
#cm_array.append(ENS2_cm)
#name_array.append('ENS2')
#auroc_array.append(roc_auc_score(np.asarray(ENS2_test)/4, ENS2_probs))
#my_auroc_array.append(my_auroc_prob(ENS2_probs, ENS2_test))50.0
#indet_array.append(ENS2_indet_count/len(Y_test))
#threshold_array.append(ENS2_params['threshold'])

print('Now making predictions for ENS3')
ENS3_params = joblib.load('ENS3.joblib')
ENS3_params['threshold'] = thresh
ENS3_params['indet_range_low'] = low_indet_range
ENS3_params['indet_range_high'] = high_indet_range
ENS3_params['indets'] = 'aprifib4'
ENS3_preds, ENS3_probs, ENS3_test, ENS3_indet_count, ENS3_det_indices = ENS_class(SVM_probs, RFC_probs, GBC_probs, LOG_probs, KNN_probs, MLP_probs, APRI_probs, FIB4_probs,  X_test_imp_scl, Y_test, ENS3_params, exc_alg)
ENS3_test = np.array(ENS3_test)
ENS3_fprs_py, ENS3_tprs_py, threshold = roc_curve(ENS3_test/4, ENS3_probs)
ENS3_precs_py, ENS3_recs_py, thresholds = precision_recall_curve(ENS3_test/4, ENS3_probs)
ENS3_cm = my_confusion_matrix(ENS3_test, ENS3_preds)
cm_array.append(ENS3_cm)
name_array.append('ENS3')
try:
    auroc_array.append(roc_auc_score(np.asarray(ENS3_test)/4, ENS3_probs))
except ValueError:
    auroc_array.append(np.nan)
try:
    ENS3_AUROC, ENS3_fprs, ENS3_tprs = my_auroc_prob(ENS3_probs, ENS3_test)
    my_auroc_array.append(ENS3_AUROC)
except ValueError:
    my_auroc_array.append(np.nan)
try:
    auprc_array.append(auc(ENS3_recs_py, ENS3_precs_py))
except ValueError:
    auprc_array.append(np.nan)
try:
    ENS3_AUPRC, ENS3_recs, ENS3_precs = my_auprc_prob(ENS3_probs, ENS3_test)
    my_auprc_array.append(ENS3_AUPRC)
except ValueError:
    my_auprc_array.append(np.nan)
except IndexError:
    my_auprc_array.append(np.nan)

indet_array.append(ENS3_indet_count/len(Y_test))
threshold_array.append(ENS3_params['threshold'])

print(desc_string)
print('Number of records in dataset: ' + str(len(dataset)))
print('F01/F4: ' + str(len(dataset.loc[dataset['Fibrosis'] == 0])) + '/' + str(len(dataset.loc[dataset['Fibrosis'] == 4])))
write_performance_metrics(cm_array, name_array, auroc_array, my_auroc_array, auprc_array, my_auprc_array, indet_array, threshold_array, exc_alg, no_show)

#  Adding point (1,0) to PRC curves
SVM_recs_py = np.insert(SVM_recs_py, 0, np.array([1]))
SVM_precs_py = np.insert(SVM_precs_py, 0, np.array([0]))

RFC_recs_py = np.insert(RFC_recs_py, 0, np.array([1]))
RFC_precs_py = np.insert(RFC_precs_py, 0, np.array([0]))

GBC_recs_py = np.insert(GBC_recs_py, 0, np.array([1]))
GBC_precs_py = np.insert(GBC_precs_py, 0, np.array([0]))

LOG_recs_py = np.insert(LOG_recs_py, 0, np.array([1]))
LOG_precs_py = np.insert(LOG_precs_py, 0, np.array([0]))

KNN_recs_py = np.insert(KNN_recs_py, 0, np.array([1]))
KNN_precs_py = np.insert(KNN_precs_py, 0, np.array([0]))

MLP_recs_py = np.insert(MLP_recs_py, 0, np.array([1]))
MLP_precs_py = np.insert(MLP_precs_py, 0, np.array([0]))
#
plt.rcParams['figure.figsize'] = (4,3.5)

# Plotting ROC and PRC curves - Python Calculations
#plt.title('ROC curve for Toronto dataset')
#plt.title('Figure 1 c) ROC curve for ' + data + ' dataset')
plt.xlabel('1 - Specificity')
plt.ylabel('Sensitivity')
#plt.plot(SVM_fprs_py, SVM_tprs_py, label=('SVM, auc=%0.2f'% (SVM_AUROC)))
#plt.plot(RFC_fprs_py, RFC_tprs_py, label=('RFC, auc=%0.2f'% (RFC_AUROC)))
#plt.plot(GBC_fprs_py, GBC_tprs_py, label=('GBC, auc=%0.2f'% (GBC_AUROC)))
#plt.plot(LOG_fprs_py, LOG_tprs_py, label=('LOG, auc=%0.2f'% (LOG_AUROC)))
#plt.plot(MLP_fprs_py, MLP_tprs_py, label=('MLP, auc=%0.2f'% (MLP_AUROC)))
plt.plot(APRI_fprs, APRI_tprs, color='cyan', label=('APRI\n0.741' % (APRI_AUROC)))
plt.plot(FIB4_fprs, FIB4_tprs, color='lightblue', label=('FIB-4\n0.712'  % (FIB4_AUROC)))
#plt.plot(ENS1_fprs_py, ENS1_tprs_py, color='orange', linewidth=2, label=(('ENS1'.center(20,' ') + '\nAUROC=%0.3f'.rjust(10, ' ')) % (ENS1_AUROC)))
plt.plot(ENS3_fprs_py, ENS3_tprs_py, color='red', linewidth=2, label=('ENS2\n0.762' % (ENS3_AUROC)))
plt.plot([0,1],[0,1], 'k--', linewidth=1)
plt.legend(loc='upper center', bbox_to_anchor=(0.5,-0.2), ncol=4)
plt.grid(True, axis='both', color='gray', linestyle='--')
plt.xlim([-0.01,1.01])
plt.ylim([-0.01,1.01])
frame1 = plt.gca()
frame1.set_facecolor('white')
plt.show()

#plt.title('PRC curve for ' + data + ' dataset')
#plt.title('Figure 1 d) PRC curve for ' + data + ' dataset')
plt.xlabel('Recall (Sensitivity)')
plt.ylabel('Precision (PPV)')
#plt.plot(SVM_recs_py, SVM_precs_py, label=('SVM, auc=%0.2f'% (auc(SVM_recs_py, SVM_precs_py, reorder=True))))
#plt.plot(RFC_recs_py, RFC_precs_py, label=('RFC, auc=%0.2f'% (auc(RFC_recs_py, RFC_precs_py    ))))
#plt.plot(GBC_recs_py, GBC_precs_py, label=('GBC, auc=%0.2f'% (auc(GBC_recs_py, GBC_precs_py))))
#plt.plot(LOG_recs_py, LOG_precs_py, label=('LOG, auc=%0.2f'% (auc(LOG_recs_py, LOG_precs_py))))
#plt.plot(MLP_recs_py, MLP_precs_py, label=('MLP, auc=%0.2f'% (auc(MLP_recs_py, MLP_precs_py))))

plt.plot(APRI_recs, APRI_precs, color='cyan', label=('APRI\n0.324' % (APRI_AUPRC)))
plt.plot(FIB4_recs, FIB4_precs, color='lightblue', label=('FIB-4\n0.597' % (FIB4_AUPRC)))
#plt.plot(ENS1_recs_py, ENS1_precs_py, color = 'orange', linewidth=2, label=(('ENS1'.center(20,' ') + '\nAUPRC=%0.3f'.rjust(10, ' ')) % (auc(ENS1_recs_py, ENS1_precs_py))))
plt.plot(ENS3_recs_py, ENS3_precs_py, color = 'red', linewidth=2, label=('ENS2\n0.629' % (auc(ENS3_recs_py, ENS3_precs_py))))
plt.plot([0,1],[1,0], 'k--', linewidth=1)
plt.legend(loc='upper center', bbox_to_anchor=(0.5,-0.2), ncol=4)
plt.grid(True, axis='both', color='gray', linestyle='--')
plt.xlim([-0.01,1.01])
plt.ylim([-0.01,1.01])
frame1 = plt.gca()
frame1.set_facecolor('white')
plt.show()


import pandas as pd # Biblioteca usada para criação de dataframe

quakes = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/earthquakes-23k.csv') # Cria o dataframe com dados do arquivo

import plotly.graph_objects as go # Chama o módulo go

# Cria a figura e suas configurações
fig = go.Figure(go.Densitymapbox(lat=quakes.Latitude, lon=quakes.Longitude, z=quakes.Magnitude, # Chama os dados de lat/long
                                 radius=10))
fig.update_layout(mapbox_style="stamen-terrain", mapbox_center_lon=180) # Adiciona no layout o estilo do mapa
fig.update_layout(margin={"r":0,"t":0,"l":0,"b":0}) # Configura no layout as proporções
fig.show() # Plota o gráfico

Plotly/Mapa de Calor no Globo Terrestre/Exemplo 2/MAPA DE CALOR COM MAPAS ex.2.py


import logging

class SimpleStateMachine():
    def __init__(self, starting_state):
        self.state = []
        self.state.append(starting_state)

    def change(self, new_state):
        self.state.append(new_state)

    def back(self):
        self.state.pop()

    def get_state(self):
        if self.state:
            return self.state[-1]
        return None

    def clear(self):
        self.state.clear()

class StateMachine():
    def __init__(self):
        self.state = []
        self.temp_state = []
        self.prev_state = None

    def load_states(self, starting_states=None, temp_state=None):
        from app.engine import title_screen, transitions, general_states, level_up, \
            turnwheel, game_over, settings, info_menu, prep, base, trade, promotion, \
            status_upkeep, debug_mode, chapter_title, player_choice, feat_choice, \
            victory_screen, objective_menu, minimap, roam_state
        from app.events import event_state
        self.all_states = \
            {'title_start': title_screen.TitleStartState,
             'title_main': title_screen.TitleMainState,
             'title_load': title_screen.TitleLoadState,
             'title_restart': title_screen.TitleRestartState,
             'title_mode': title_screen.TitleModeState,
             'title_new': title_screen.TitleNewState,
             'title_new_child': title_screen.TitleNewChildState,
             'title_extras': title_screen.TitleExtrasState,
             'title_all_saves': title_screen.TitleAllSavesState,
             'title_wait': title_screen.TitleWaitState,
             'title_save': title_screen.TitleSaveState,
             'in_chapter_save': title_screen.TitleSaveState,
             'transition_in': transitions.TransitionInState,
             'transition_out': transitions.TransitionOutState,
             'transition_pop': transitions.TransitionPopState,
             'transition_double_pop': transitions.TransitionDoublePopState,
             'transition_to': transitions.TransitionToState,
             'turn_change': general_states.TurnChangeState,
             'initiative_upkeep': general_states.InitiativeUpkeep,
             'free': general_states.FreeState,
             'option_menu': general_states.OptionMenuState,
             'option_child': general_states.OptionChildState,
             'settings_menu': settings.SettingsMenuState,
             'objective_menu': objective_menu.ObjectiveMenuState,
             'info_menu': info_menu.InfoMenuState,
             'phase_change': general_states.PhaseChangeState,
             'move': general_states.MoveState,
             'movement': general_states.MovementState,
             'wait': general_states.WaitState,
             'canto_wait': general_states.CantoWaitState,
             'move_camera': general_states.MoveCameraState,
             'dying': general_states.DyingState,
             'menu': general_states.MenuState,
             'item': general_states.ItemState,
             'item_child': general_states.ItemChildState,
             'item_discard': general_states.ItemDiscardState,
             'targeting': general_states.TargetingState,
             'trade': trade.TradeState,
             'combat_trade': trade.CombatTradeState,
             'weapon_choice': general_states.WeaponChoiceState,
             'spell_choice': general_states.SpellChoiceState,
             'combat_targeting': general_states.CombatTargetingState,
             'item_targeting': general_states.ItemTargetingState,
             'combat': general_states.CombatState,
             'alert': general_states.AlertState,
             'ai': general_states.AIState,
             'shop': general_states.ShopState,
             'unlock_select': general_states.UnlockSelectState,
             'exp': level_up.ExpState,
             'promotion_choice': promotion.PromotionChoiceState,
             'class_change_choice': promotion.ClassChangeChoiceState,
             'promotion': promotion.PromotionState,
             'class_change': promotion.ClassChangeState,
             'feat_choice': feat_choice.FeatChoiceState,
             'turnwheel': turnwheel.TurnwheelState,
             'game_over': game_over.GameOverState,
             'chapter_title': chapter_title.ChapterTitleState,
             'event': event_state.EventState,
             'player_choice': player_choice.PlayerChoiceState,
             'victory': victory_screen.VictoryState,
             'minimap': minimap.MinimapState,
             'status_upkeep': status_upkeep.StatusUpkeepState,
             'status_endstep': status_upkeep.StatusUpkeepState,
             'prep_main': prep.PrepMainState,
             'prep_pick_units': prep.PrepPickUnitsState,
             'prep_formation': prep.PrepFormationState,
             'prep_formation_select': prep.PrepFormationSelectState,
             'prep_manage': prep.PrepManageState,
             'prep_manage_select': prep.PrepManageSelectState,
             'base_manage': prep.PrepManageState,
             'base_manage_select': prep.PrepManageSelectState,
             'prep_trade_select': prep.PrepTradeSelectState,
             'prep_trade': trade.PrepTradeState,
             'prep_items': prep.PrepItemsState,
             'supply_items': prep.PrepItemsState,
             'prep_restock': prep.PrepRestockState,
             'prep_market': prep.PrepMarketState,
             'base_main': base.BaseMainState,
             'base_market_select': base.BaseMarketSelectState,
             'base_bexp_select': base.BaseBEXPSelectState,
             'base_bexp_allocate': base.BaseBEXPAllocateState,
             'base_convos_child': base.BaseConvosChildState,
             'base_supports': base.BaseSupportsState,
             'base_codex_child': base.BaseCodexChildState,
             'base_library': base.BaseLibraryState,
             'base_guide': base.BaseGuideState,
             'base_records': base.BaseRecordsState,
             'free_roam': roam_state.FreeRoamState,
             'debug': debug_mode.DebugState,
             }

        if starting_states:
            for state_name in starting_states:
                self.state.append(self.all_states[state_name](state_name))
        if temp_state:
            self.temp_state = temp_state

    def state_names(self):
        return [s.name for s in self.state]

    def change(self, new_state):
        self.temp_state.append(new_state)

    def back(self):
        self.temp_state.append('pop')

    def clear(self):
        self.temp_state.append('clear')

    def refresh(self):
        # Clears all states except the top one
        self.state = self.state[-1:]

    def current(self):
        if self.state:
            return self.state[-1].name

    def exit_state(self, state):
        if state.processed:
            state.processed = False
            state.end()
        state.finish()

    def from_transition(self):
        return self.prev_state in ('transition_out', 'transition_to', 'transition_pop', 'transition_double_pop')

    def process_temp_state(self):
        if self.temp_state:
            logging.debug("Temp State: %s", self.temp_state)
        for transition in self.temp_state:
            if transition == 'pop':
                if self.state:
                    state = self.state[-1]
                    self.exit_state(state)
                    self.state.pop()
            elif transition == 'clear':
                for state in reversed(self.state):
                    self.exit_state(state)
                self.state.clear()
            else:
                new_state = self.all_states[transition](transition)
                self.state.append(new_state)
        if self.temp_state:
            logging.debug("State: %s", self.state_names())
        self.temp_state.clear()

    def update(self, event, surf):
        if not self.state:
            return None, False
        state = self.state[-1]
        repeat_flag = False  # Whether we run the state machine again in the same frame
        # Start
        if not state.started:
            state.started = True
            start_output = state.start()
            if start_output == 'repeat':
                repeat_flag = True
            self.prev_state = state.name
        # Begin
        if not repeat_flag and not state.processed:
            state.processed = True
            begin_output = state.begin()
            if begin_output == 'repeat':
                repeat_flag = True
        # Take Input
        if not repeat_flag:
            input_output = state.take_input(event)
            if input_output == 'repeat':
                repeat_flag = True
        # Update
        if not repeat_flag:
            update_output = state.update()
            if update_output == 'repeat':
                repeat_flag = True
        # Draw
        if not repeat_flag:
            # Handles transparency of states
            idx = -1
            while True:
                if self.state[idx].transparent and len(self.state) >= (abs(idx) + 1):
                    idx -= 1
                else:
                    break
            while idx <= -1:
                surf = self.state[idx].draw(surf)
                idx += 1
        # End
        if self.temp_state and state.processed:
            state.processed = False
            state.end()
        # Finish
        self.process_temp_state()  # This is where FINISH is taken care of
        return surf, repeat_flag

    def save(self):
        return [state.name for state in self.state], self.temp_state[:]  # Needs to be a copy!!!


from uuid import uuid4

from sanic import Blueprint
from sanic.response import json

from rbac.common.task import Task
from rbac.server.api.auth import authorized
from rbac.server.api import utils
from rbac.server.db import tasks_query
from rbac.server.db.relationships_query import fetch_relationships

TASKS_BP = Blueprint("tasks")

@TASKS_BP.get("api/tasks")
@authorized()
async def get_all_tasks(request):
    """Get all tasks."""
    head_block = await utils.get_request_block(request)
    start, limit = utils.get_request_paging_info(request)
    task_resources = await tasks_query.fetch_all_task_resources(
        request.app.config.DB_CONN, start, limit
    )
    return await utils.create_response(
        request.app.config.DB_CONN,
        request.url,
        task_resources,
        head_block,
        start=start,
        limit=limit,
    )

@TASKS_BP.post("api/tasks")
@authorized()
async def create_new_task(request):
    """Create a new task."""
    required_fields = ["name", "administrators", "owners"]
    utils.validate_fields(required_fields, request.json)

    txn_key, txn_user_id = await utils.get_transactor_key(request)
    task_id = str(uuid4())
    batch_list = Task().batch_list(
        signer_keypair=txn_key,
        signer_user_id=txn_user_id,
        task_id=task_id,
        name=request.json.get("name"),
        admins=request.json.get("administrators"),
        owners=request.json.get("owners"),
        metdata=request.json.get("metadata"),
    )
    await utils.send(
        request.app.config.VAL_CONN, batch_list, request.app.config.TIMEOUT
    )
    return create_task_response(request, task_id)

@TASKS_BP.get("api/tasks/<task_id>")
@authorized()
async def get_task(request, task_id):
    """Get a specific task by task_id."""
    head_block = await utils.get_request_block(request)
    task_resource = await tasks_query.fetch_task_resource(
        request.app.config.DB_CONN, task_id
    )
    return await utils.create_response(
        request.app.config.DB_CONN, request.url, task_resource, head_block
    )

@TASKS_BP.post("api/tasks/<task_id>/admins")
@authorized()
async def add_task_admin(request, task_id):
    """Propose add a task admin."""
    required_fields = ["id"]
    utils.validate_fields(required_fields, request.json)

    txn_key, txn_user_id = await utils.get_transactor_key(request)
    proposal_id = str(uuid4())
    approver = await fetch_relationships("task_admins", "task_id", task_id).run(
        request.app.config.DB_CONN
    )
    batch_list = Task().admin.propose.batch_list(
        signer_keypair=txn_key,
        signer_user_id=txn_user_id,
        proposal_id=proposal_id,
        task_id=task_id,
        next_id=request.json.get("id"),
        reason=request.json.get("reason"),
        metadata=request.json.get("metadata"),
        assigned_approver=approver,
    )
    await utils.send(
        request.app.config.VAL_CONN, batch_list, request.app.config.TIMEOUT
    )
    return json({"proposal_id": proposal_id})

@TASKS_BP.post("api/tasks/<task_id>/owners")
@authorized()
async def add_task_owner(request, task_id):
    """Propose add a task owner."""
    required_fields = ["id"]
    utils.validate_fields(required_fields, request.json)

    txn_key, txn_user_id = await utils.get_transactor_key(request)
    proposal_id = str(uuid4())
    approver = await fetch_relationships("task_admins", "task_id", task_id).run(
        request.app.config.DB_CONN
    )
    batch_list = Task().owner.propose.batch_list(
        signer_keypair=txn_key,
        signer_user_id=txn_user_id,
        proposal_id=proposal_id,
        task_id=task_id,
        next_id=request.json.get("id"),
        reason=request.json.get("reason"),
        metadata=request.json.get("metadata"),
        assigned_approver=approver,
    )
    await utils.send(
        request.app.config.VAL_CONN, batch_list, request.app.config.TIMEOUT
    )
    return json({"proposal_id": proposal_id})

def create_task_response(request, task_id):
    """Prepare the json response for create new task."""
    task_resource = {
        "id": task_id,
        "name": request.json.get("name"),
        "owners": request.json.get("owners"),
        "administrators": request.json.get("administrators"),
        "roles": [],
        "proposals": [],
    }

    if request.json.get("metadata"):
        task_resource["metadata"] = request.json.get("metadata")

    return json({"data": task_resource})


from re import A
from android import python_act
from android.runnable import run_on_ui_thread
from jnius import autoclass, cast

from android_api import activity, SDK_INT

AndroidString = autoclass('java.lang.String')
Context = autoclass('android.content.Context')
NotificationBuilder = autoclass('android.app.Notification$Builder')
NotificationManager = autoclass('android.app.NotificationManager')
Drawable = autoclass("{}.R$mipmap".format(activity.getPackageName()))
PendingIntent = autoclass('android.app.PendingIntent')
Intent = autoclass('android.content.Intent')
Toast = autoclass('android.widget.Toast')
BitmapFactory = autoclass('android.graphics.BitmapFactory')

class AndroidNotification():

	def __init__(self):
		self._ns = None
		self._channel_id = activity.getPackageName()

	def _get_notification_service(self):
		if not self._ns:
			self._ns = cast(NotificationManager, activity.getSystemService(
				Context.NOTIFICATION_SERVICE
			))
		return self._ns

	def _build_notification_channel(self, name):

		if SDK_INT < 26:
			return
		channel = autoclass('android.app.NotificationChannel')
		app_channel = channel(
			self._channel_id, name, NotificationManager.IMPORTANCE_DEFAULT
		)
		self._get_notification_service().createNotificationChannel(
			app_channel
		)
		return app_channel

	@run_on_ui_thread
	def _toast(self, message):
		Toast.makeText(
			activity,
			cast('java.lang.CharSequence', AndroidString(message)),
			Toast.LENGTH_LONG
		).show()

	@staticmethod
	def _set_icons(notification, icon=None):
		app_icon = Drawable.icon
		notification.setSmallIcon(app_icon)

		bitmap_icon = app_icon
		if icon is not None:
			bitmap_icon = BitmapFactory.decodeFile(icon)
			notification.setLargeIcon(bitmap_icon)
		elif icon == '':
			# we don't want the big icon set,
			# only the small one in the top panel
			pass
		else:
			bitmap_icon = BitmapFactory.decodeResource(
				python_act.getResources(), app_icon
			)
			notification.setLargeIcon(bitmap_icon)

	def _build_notification(self, title):
		if SDK_INT < 26:
			noti = NotificationBuilder(activity)
		else:
			self._channel = self._build_notification_channel(title)
			noti = NotificationBuilder(activity, self._channel_id)
		return noti

	@staticmethod
	def _set_open_behavior(notification):
		app_context = activity.getApplication().getApplicationContext()
		notification_intent = Intent(app_context, python_act)
		notification_intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP)
		notification_intent.setAction(Intent.ACTION_MAIN)
		notification_intent.addCategory(Intent.CATEGORY_LAUNCHER)

		pending_intent = PendingIntent.getActivity(
			app_context, 0, notification_intent, 0
		)
		notification.setContentIntent(pending_intent)
		notification.setAutoCancel(True)

	def _open_notification(self, notification):
		if SDK_INT >= 16:
			notification = notification.build()
		else:
			notification = notification.getNotification()

		self._get_notification_service().notify(0, notification)

	def _notify(self, **kwargs):
		noti = None
		message = kwargs.get('message').encode('utf-8')
		ticker = kwargs.get('ticker').encode('utf-8')
		title = AndroidString(
			kwargs.get('title', '').encode('utf-8')
		)
		icon = kwargs.get('app_icon')
		if kwargs.get('toast'):
			self._toast(message)
			return
		else:
			noti = self._build_notification(title)

		noti.setContentTitle(title)
		noti.setContentText(AndroidString(message))
		noti.setTicker(AndroidString(ticker))
		self._set_icons(noti, icon=icon)
		self._set_open_behavior(noti)

		self._open_notification(noti)

def instance():
	return AndroidNotification()

def notify(title='', message='', app_icon='', app_name='', timeout=10, ticker='', toast=False):
	my_notification = AndroidNotification()
	my_notification._notify(title=title, message=message,
		app_icon=app_icon, app_name=app_name,
		timeout=timeout, ticker=ticker, toast=toast)


import os
from pydub import AudioSegment
import threading

genres = 'blues classical country disco hiphop metal pop reggae rock'
genres = genres.split()

class myThread(threading.Thread):
    def __init__(self, genre):
        threading.Thread.__init__(self)
        self.genre = genre

    def run(self):
        print("Started " + self.genre)
        split_files(self.genre)
        print("Finished " + self.genre)

def split_files(g):
    j = 0
    for filename in os.listdir(os.path.join('Z:/Egyetem/önlab2_msc/raw_audio/yt_dataset_2', f"{g}")):
        song = os.path.join(f'Z:/Egyetem/önlab2_msc/raw_audio/yt_dataset_2/{g}', f'{filename}')
        j = j + 1
        for w in range(0, 1000):
            t1 = 3 * (w) * 1000
            t2 = t1 + 6000
            new_audio = AudioSegment.from_wav(song)
            new = new_audio[t1:t2]
            new.export(f'Z:/Egyetem/önlab2_msc/splitted_audiofiles/audio6sec_overlap3s_yt_dataset2/{g}/{g + str(j) + str(w)}.wav',
                       format="wav")

threads = []
for g in genres:
    threads.append(myThread(g))

for t in threads:
    t.start()


import numpy as np
import qoplots.qoplots as qoplots
qoplots.init("rose_pine", doc_type = "presentation")
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
import time
from fractions import Fraction as Frac

def wave(idx, w, x_max, x):
    x_local = x + x_max * idx
    if idx % 2 == 1:
        x_local = x_local[::-1]
    y = np.sin(2 * np.pi * x_local / w) * (-1) ** (idx)
    return y

color = qoplots.Scheme.accents[0].base.css
fig = plt.figure()
fig.set_size_inches(8, 4.5)
ax = plt.Axes(fig, [0., 0., 1., 1.])
ax.set_axis_off()
fig.add_axes(ax)
ax.set_xlim(0, 1)
ax.set_ylim(-4, 4)

N_data = 2
N_show = 2
max_frames = 2000

plt.axhline(1, color = qoplots.Scheme.foreground[3].css, ls = "--")
plt.axhline(-1, color = qoplots.Scheme.foreground[3].css, ls = "--")

lines = [None] * N_show
total = None
x_max = 1
x = np.linspace(0, x_max, 300)
a = 1 / (8 * np.pi)
f = 20 * np.pi
t = np.linspace(0, 1, max_frames // 2)
ws = 1/(a * (t * f - np.sin(t * f)) + 0.5)
ws = np.concatenate((ws, ws[::-1]))
y = np.zeros((N_data, len(x)))
for i in range(N_data):
    y[i] = wave(i, ws[0], x_max, x)
    if i < N_show:
        lines[i], = plt.plot(x, y[i] + 1, color = color, lw = 1, alpha = (1-i/N_show), ls = "solid" if i == 0 else ":")

y_total = np.sum(y, axis = 0)
# normalise
y_total = y_total / N_data
total, = plt.plot(x, y_total - 1, lw = 2, alpha = 1, ls = "solid", color = qoplots.Scheme.accents[1].base.css)

textlambda = plt.text(0.825, 2.5, "$\lambda =$", color = qoplots.Scheme.accents[4].base.css, ha = "right", va = "center", fontsize = 20)
text = plt.text(0.9, 2.5, "$2L$", color = qoplots.Scheme.accents[4].base.css, ha = "right", va = "center", fontsize = 20)

def update(frame):

    # return to the start of the line after printing
    def bar(f, max_f, width = 50):
        completed = int(f / max_f * width)
        return f"[{'=' * completed}{' ' * (width - completed)}]"
    def format_time(remaining):
        if remaining < 60:
            return f"{remaining:.2f}s"
        elif remaining < 3600:
            return f"{remaining / 60:.0f}:{remaining % 60:0>2.0f}"
        else:
            return f"{remaining / 3600:.2f}h"

    current_time = time.time()
    elapsed_time = current_time - start_time
    remaining_time = elapsed_time / (frame + 1) * (max_frames - frame - 1)
    print(f"Frame: {frame: >3d} / {max_frames} {bar(frame, max_frames)} ({frame / max_frames * 100:.2f}%, {format_time(remaining_time)})", end = "\x1b[0G", flush = True)

    w = ws[frame]
    frac = Frac(w).limit_denominator(300)
    if frac.denominator == 1:
        text.set_text(f"${frac.numerator if frac.numerator != 1 else ''}L$")
    else:
        text.set_text(f"$\\frac{{{frac.numerator}}}{{{frac.denominator}}}L$")

    y = np.zeros((N_data, len(x)))
    for i in range(N_data):
        y[i] = wave(i, w, x_max, x)
        if i < N_show:
            lines[i].set_data(x, y[i] + 1)

    y_total = np.sum(y, axis = 0)
    # normalise
    y_total = y_total / N_data
    total.set_data(x, y_total - 1)

start_time = time.time()
anim = FuncAnimation(fig, update, frames=np.arange(0, max_frames), interval=20)
anim.save('animation.mp4', fps=30, dpi = 400)


"""
Author: Rambod Azimi
This Python code will make use of numpy and scikit-learn libraries to implement and utilize the Logistic Regression
machine learning algorithm.
"""

import numpy as np
from sklearn.linear_model import LogisticRegression

# defining our training set examples
X_train = np.array([[0.5, 1.5], [1, 1], [1.5, 0.5], [3, 0.5], [2, 2], [1, 2.5]]) # 6 training examples with 2 features
y_train = np.array([0, 0, 0, 1, 1, 1]) # targets

logistic_regression_model = LogisticRegression()
logistic_regression_model.fit(X_train, y_train) # fit the model on the training data by caliing fit function

prediction = logistic_regression_model.predict(X_train)

for i in range(X_train.shape[0]):
    print(f"Prediction value: {prediction[i]} \t Actual value: {y_train[i]}")

print(f"Accuracy of the model: {logistic_regression_model.score(X_train, y_train)* 100}%")


from flask import request
from flask_restful import Resource
from app.models import db, Customers, CustomersSchema

customers_schema = CustomersSchema(many=True)
customer_schema = CustomersSchema()

class CustomersResource(Resource):
    def get(self):
        key = request.args.get('key')

        if key:
            customers = Customers.query.filter(Customers.type==key).all()
        else:
            customers = Customers.query.all()

        customers = customers_schema.dump(customers).data
        return {'status': 'success', 'message': customers[0]['values']}, 200


# Construct a Trie from a Collection of Patterns
import itertools as it
import sys

from collections import defaultdict

class Trie:
    def __init__(self, patterns):
        self._node_id_generator = it.count()
        self._root = next(self._node_id_generator)
        self._adjacency_list = self._build_trie_from_patterns(patterns)

    def edges(self):
        for node, neighbours in self._adjacency_list.items():
            for neighbour, label in neighbours:
                yield f'{node}->{neighbour}:{label}'

    def _build_trie_from_patterns(self, patterns):
        adjacency_list = defaultdict(list)
        for pattern in patterns:
            self._add_pattern_to_trie(adjacency_list, pattern)
        return dict(adjacency_list)

    def _add_pattern_to_trie(self, adjacency_list, pattern):
        current_node = self._root
        for letter in pattern:
            node = _get_neighbour_with_given_label(adjacency_list, current_node, letter)
            if node is None:
                next_node = next(self._node_id_generator)
                adjacency_list[current_node].append((next_node, letter))
                current_node = next_node
            else:
                current_node = node

def _get_neighbour_with_given_label(adjacency_list, current_node, letter):
    neighbours = adjacency_list.get(current_node, [])
    for node, label in neighbours:
        if label == letter:
            return node
    return None

def main():
    patterns = sys.stdin.read().splitlines()
    trie = Trie(patterns)
    for edge in trie.edges():
        print(edge)

if __name__ == '__main__':
    main()


import logging
import pandas as pd

from django.core.management.base import BaseCommand

from stk.models import Station

logger = logging.getLogger(__name__)

class Command(BaseCommand):

    def add_arguments(self, parser):
        parser.add_argument('input_path', type=str, nargs=1)

    def handle(self, *args, **options):
        df = pd.read_excel(options['input_path'][0])
        for col in df.columns:
            df[col] = df[col].astype(str)

        for i, row in df.iterrows():
            Station.objects.create(
                stk_id=row['STK č.'].replace('.', '').strip(),
                authorization=row['Opravnenia'].strip(),
                zip_code=row['PSČ'].strip(),
                city=row['Město'].strip(),
                address=row['Ulice'].strip(),
                operator=row['Provozovatel STK'].strip(),
                tel_number=row['Telefon'].strip(),
                email=row['E-mail'].strip(),
                region=row['Kraj'].strip()
            )