### fit and plot curves for IC50s ########################################
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import os
import math
from scipy.optimize import curve_fit
import warnings
###################################################################################################
colors=[(0.212395, 0.359683, 0.55171), (0.153364, 0.497, 0.557724), (0.122312, 0.633153, 0.530398), (0.288921, 0.758394, 0.428426), (0.626579, 0.854645, 0.223353),(0.275191, 0.194905, 0.496005)]
sns.set_palette(colors)
pal=sns.color_palette(colors)

def plot_pct_inhib_curves(compound, raw, curve, targs=['PARP1','PARP2'], save_fig=False, graphcol='intensity_inhibition', fitcrit='R^2', sharey=False, save_lab='HiTS', save_dir='./curve_fits'):
    ''' Plot and save IC50 curves on top of raw data for visualization across various targets.
    Raw data frame should at minimum have columns
    [Compound, Target, <response column graphcol>, logconc, Plate, Well_Type]. 'solubility' optional.
    Curve data frame should have columns
    [Compound, Target, 'bottom','top','LogIC50','hill','RMSE',<fitcrit col>,'IC50','relation','pIC50','hitc','coff','notes']
    '''
    curvecols=['bottom','top','LogIC50','hill','RMSE',fitcrit,'IC50','pIC50','hitc','coff']
    sns.set_context('poster')
    rows=int(np.ceil(len(targs)/4))
    cols=int(np.ceil(len(targs)*2/rows))
    realcurvecols=['Compound']
    for col in curvecols:
        if col in curve.columns:
            curve.loc[:,col]=curve[col].astype(float)
            realcurvecols.append(col)
        # except:
        #     # warnings.warn(f'{col} column does not exist or was unable to be cast as float')
        #     pass

    fig, ax = plt.subplots(rows,cols,figsize=(cols*6,rows*10),sharey=sharey,gridspec_kw={'width_ratios': [5,1]*int(np.ceil(cols/2))})
    ax=ax.ravel()
    i=0
    minmin=0
    maxmax=0
    for targ in targs:
        # get curve data
        ppc=curve[(curve.Compound==compound) & (curve.Target==targ)].copy()
        note=ppc[['notes']]
        ppc=ppc[realcurvecols]
        if len(ppc)>1:
            ppc.IC50=ppc.IC50.astype(float)
            ppc=ppc.groupby('Compound').mean()
        if len(ppc)>0:
            for col in ['top','bottom','hill','pIC50',fitcrit,'IC50',]:
                ppc[col]=ppc[col].astype(float)
            if 'relation' in ppc.columns:
                ppc.relation=ppc.relation.replace(np.nan,'=')
            else:
                ppc['relation']='='
            if 'coff' in ppc.columns:
                coff = ppc.iloc[0].coff
            else:
                coff=None
        else:
            coff=None
        note=list(set(note.notes.dropna()))
        ppc['notes']='\n'.join(note)

        # get raw data
        ppr=raw[(raw.Compound==compound) & (raw.Target==targ)].copy()
        if len(ppr)==0:
            continue
        if 'RealPlate' in ppr.columns:
            plateNegCtrl=raw[(raw.RealPlate.isin(ppr.RealPlate.unique()))&(raw.Well_Type=='negativeControl')&(raw.Target==targ)]
        else:
            plateNegCtrl=raw[(raw.Plate.isin(ppr.Plate.unique()))&(raw.Well_Type=='negativeControl')&(raw.Target==targ)]
        if coff is None:
            vals=plateNegCtrl[graphcol].values
            coff=3*np.median(np.absolute(vals - np.median(vals))) # 3*BMAD

        # get axes bounds
        logconcmin=ppr.logconc.min()-0.5
        logconcmax=ppr.logconc.max()+0.5
        pctmin = min(ppr[graphcol].min(), plateNegCtrl[graphcol].min(), coff)
        pctmax = max(ppr[graphcol].max(), plateNegCtrl[graphcol].max(), coff)
        pctmin = pctmin-0.05*pctmax
        pctmax = pctmax+0.05*pctmax

        # create curve if it's a hit and curve fit succeeded
        if len(ppc)>0:
            if (ppc.hitc.iloc[0]==1) and ('succeeded' in ppc.notes.iloc[0]):
                # try:
                x = np.linspace(logconcmin, logconcmax, 1000)
                y = ppc.bottom.iloc[0] + ((ppc.top.iloc[0] - ppc.bottom.iloc[0])/(1+10**((-ppc.pIC50.iloc[0] - x)*float(ppc.hill.iloc[0]))))
                ax[i].plot(x,y,c=pal[-1])
                # except:
                #     pass
                pctmin=min(pctmin, ppc.bottom.iloc[0])
                pctmax=max(pctmax, ppc.top.iloc[0])
                pctmin = pctmin-0.05*pctmax
                pctmax = pctmax+0.05*pctmax

        # create scatterplot whether it's a hit or not
        if 'RealPlate' in ppr.columns:
            sns.scatterplot(data=ppr, x='logconc', y=graphcol, hue='RealPlate', ax=ax[i], legend=False)
        else:
            ax[i].scatter(x=ppr.logconc.values, y=ppr[graphcol].values, s=50)
        if not isinstance(compound,str):
            try:
                compound=int(compound)
            except:
                pass
        if 'solubility' in ppc.columns:
            ax[i].set_title(f"{compound} {targ} IC50{ppc.relation.iloc[0]}{round(ppc.IC50.iloc[0], 4)} uM\n{ppc.notes.iloc[0]}\nSoluble: {ppc['solubility'].iloc[0]}; \nHITC: {int(ppc.hitc.iloc[0])};{fitcrit}={round(ppc[fitcrit].iloc[0], 4)}")
        elif len(ppc)==0:
            ax[i].set_title(f"{compound} {targ}\n No Fits")
        else:
            ax[i].set_title(f"{compound} {targ} IC50{ppc.relation.iloc[0]}{round(ppc.IC50.iloc[0], 4)} uM\n{ppc.notes.iloc[0]}\nHITC: {int(ppc.hitc.iloc[0])}; {fitcrit}={round(ppc[fitcrit].iloc[0], 4)}")
        ax[i].set_xlabel('log(Concentration in M)')
        ax[i].set_xlim(logconcmin, logconcmax)
        ax[i].set_ylim(pctmin, pctmax)
        ax[i].hlines(coff, xmin=logconcmin, xmax=logconcmax, color=pal[-2], zorder=0)

        if 'RealPlate' in plateNegCtrl.columns:
            sns.histplot(y=graphcol, data=plateNegCtrl, bins=np.arange(pctmin,pctmax,((pctmax-pctmin)/22)), hue='RealPlate', ax=ax[i+1], legend=False)
        else:
            ax[i+1].hist(plateNegCtrl[graphcol], orientation='horizontal', range=(pctmin,pctmax), bins=22)
        ax[i+1].set_ylim(pctmin, pctmax)
        ax[i+1].set_xlabel('negCtrlDist')
        i+=2

        # if sharey is true, use maxmax
        if pctmin < minmin:
            minmin=pctmin
        if pctmax > maxmax:
            maxmax=pctmax

    # finish creating plot
    if sharey:
        ax[0].set_ylim(minmin, maxmax)
    ax[0].set_ylabel(graphcol)
    fig.patch.set_facecolor('white')
    fig.tight_layout()

    # save plot if save
    if save_fig:
        if not os.path.exists(save_dir):
            os.makedirs(save_dir)
        plt.savefig(os.path.join(save_dir, f'{compound}_{save_lab}_curvefit.png'))
        plt.close()

def plot_sc_data(compound, raw, curve, targs=['PARP1','PARP2'], save_fig=False, graphcol='intensity_inhibition', save_lab='HiTS', save_dir='./curve_fits'):
    ''' Plot and save IC50 curves on top of raw data for visualization across various targets.
    Raw data frame should at minimum have columns
    [Compound, Target, <response column graphcol>, logconc, Plate, Well_Type]. 'solubility' optional.
    Curve data frame should have columns
    [Compound, Target, 'bottom','top','LogIC50','hill','RMSE',<fitcrit col>,'IC50','pIC50','hitc','coff','notes']
    '''
    sns.set_context('poster')
    rows=int(np.ceil(len(targs)/4))
    cols=int(np.ceil(len(targs)*2/rows))
    fig, ax = plt.subplots(rows,cols,figsize=(cols*6,rows*10),sharey=True,gridspec_kw={'width_ratios': [5,1]*int(np.ceil(cols/2))})
    ax=ax.ravel()
    i=0

    # minmax=raw[raw.Compound==compound]
    # if graphcol!='fold_change':
    #     pctmin = minmax[graphcol].min()-5
    #     pctmax = minmax[graphcol].max()+5
    #     pctmin = min(pctmin, -105)
    #     pctmax = max(pctmax, 105)
    # else:
    #     pctmin = minmax[graphcol].min()-0.5
    #     pctmax = minmax[graphcol].max()+0.5

    for targ in targs:
        # get curve data
        ppc=curve[(curve.Compound==compound) & (curve.Target==targ)].copy()
        # ppc=ppc[['Compound', 'Target', 'bottom','top','LogIC50','hill','RMSE',<fitcrit col>,'IC50','pIC50','hitc','coff','notes'
        if len(ppc)>1:
            note=list(set(ppc.notes.tolist()))[0]
            ppc.IC50=ppc.IC50.astype(float)
            note=set(ppc.notes.tolist())
            ppc=ppc.groupby('Compound').mean()
            ppc['notes']=str(note)
        coff = ppc.coff.iloc[0]

        # get raw data
        ppr=raw[(raw.Compound==compound) & (raw.Target==targ)].copy()
        if len(ppr)==0:
            continue
        plateNegCtrl=raw[(raw.Plate.isin(ppr.Plate.unique()))&(raw.Well_Type=='negativeControl')&(raw.Target==targ)]

        # get axes bounds
        logconcmin=ppr.logconc.min()-0.5
        logconcmax=ppr.logconc.max()+0.5

        pctmin = min(ppr[graphcol].min(), plateNegCtrl[graphcol].min())
        pctmax = max(ppr[graphcol].max(), plateNegCtrl[graphcol].max())
        pctmin = pctmin-0.05*pctmax
        pctmax = pctmax+0.05*pctmax

        # create curve if it's a hit and curve fit succeeded
        if (ppc.hitc.iloc[0]==1) and ('succeeded' in ppc.notes.iloc[0]):
            try:
                x = np.linspace(logconcmin, logconcmax, 1000)
                y = ppc.bottom.iloc[0] + ((ppc.top.iloc[0] - ppc.bottom.iloc[0])/(1+10**((-ppc.pIC50.iloc[0] - x)*float(ppc.hill.iloc[0]))))
                ax[i].plot(x,y,c='cornflowerblue')
            except:
                pass

        # create scatterplot whether it's a hit or not
        ax[i].scatter(x=ppr.logconc.values, y=ppr[graphcol].values, s=50)
        if 'solubility' in ppc.columns:
            ax[i].set_title(f"{int(compound)} {targ}\nIC50={round(ppc.IC50.iloc[0], 4)} uM HITC: {int(ppc.hitc.iloc[0])}; {ppc.notes.iloc[0]}\nSoluble: {ppc['solubility'].iloc[0]}; RMSE={round(ppc['RMSE'].iloc[0], 4)}")
        else:
            ax[i].set_title(f"{int(compound)} {targ}\nIC50={round(ppc.IC50.iloc[0], 4)} uM HITC: {int(ppc.hitc.iloc[0])}; {ppc.notes.iloc[0]}\nRMSE={round(ppc['RMSE'].iloc[0], 4)}")
        ax[i].set_xlabel('log(Concentration in M)')
        ax[i].set_xlim(logconcmin, logconcmax)

        ax[i].hlines(coff, xmin=logconcmin, xmax=logconcmax, color='orange', zorder=0)
        ax[i+1].hist(plateNegCtrl[graphcol], orientation='horizontal', range=(pctmin,pctmax), bins=22)
        ax[i+1].set_xlabel('negCtrlDist')
        i+=2

    # finish creating plot
    ax[0].set_ylim(pctmin, pctmax)
    ax[0].set_ylabel(graphcol)
    fig.patch.set_facecolor('white')
    fig.tight_layout()

    # save plot if save
    if save_fig:
        if not os.path.exists(save_dir):
            os.makedirs(save_dir)
        plt.savefig(os.path.join(save_dir, f'{compound}_{save_lab}_curvefit.png'))
        plt.close()

###################################################################################################
# from stack overflow
def ModelAndScatterPlot(xData, yData, color='blue', ax=None, label=None, init=[100, 0, -5.5, 1],
                       bounds=([80,-20,-np.inf,-np.inf], [120, 20, np.inf,np.inf])):
    if ax is None:
        f = plt.figure(figsize=(5,5))
        ax = f.add_subplot(111)

    # first the raw data as a scatter plot
    ax.plot(xData, yData,  'D', color=colors[1])

    fittedParameters, pcov = curve_fit(hillfunc, xData, yData, init, bounds=bounds)

    # create data for the fitted equation plot
    xModel = np.linspace(min(xData), max(xData), num=100)
    yModel = hillfunc(xModel, *fittedParameters)

    # now the model as a line plot
    ax.plot(xModel, yModel, color=colors[1], label=label)

    # ax.set_xlabel('X Data') # X axis data label
    # ax.set_ylabel('Y Data') # Y axis data label
    # axes.set_ylim(-20,105)
    return ax

###################################################################################################

def hillfunc(x, Bottom, Top, LogIC50, HillSlope):
    return (Bottom + (Top-Bottom)/(1+10**((LogIC50-x)*HillSlope)))

def fit_scipy_curves(cmpds, raw, graphcol, targs=['PARP1','PARP2'], init=np.array([100, -20, -5.5, 1]),
                          bounds=([80,-20,-np.inf,-np.inf], [120, 20, np.inf,np.inf]), bcomm=''):
    ''' fit IC50 curves to raw concentration-response data. Raw data frame should at minimum have columns
    [Compound, Target, <response column graphcol>, logconc]
    '''
    allparams = {}

    for cmpd in cmpds:
        for i, targ in enumerate(targs):
            ppr=raw[(raw.Compound==cmpd) & (raw.Target==targ)].copy()
            xData=ppr.logconc
            yData = ppr[graphcol].values

            # these are the same as the scipy defaults
            # initialParameters = np.array([init[top], init[bottom], np.log10(float(init[ic50])/1000000), init[hill]])
            initialParameters = init

            # do not print unnecessary warnings during curve_fit()
            warnings.filterwarnings("ignore")

            try:
                # curve fit the test data
                fittedParameters, pcov = curve_fit(hillfunc, xData, yData, initialParameters, bounds=bounds)

                modelPredictions = hillfunc(xData, *fittedParameters)

                absError = modelPredictions - yData

                SE = np.square(absError) # squared errors
                MSE = np.mean(SE) # mean squared errors
                RMSE = np.sqrt(MSE) # Root Mean Squared Error, RMSE
                Rsquared = 1.0 - (np.var(absError) / np.var(yData))
                IC50 = 10**fittedParameters[2]*1000000
                pIC50= -np.log10(IC50/1000000)

                fittedParameters=list(fittedParameters)
                fittedParameters.extend([RMSE, Rsquared, IC50, pIC50])
                fittedParameters.append(f'Fit succeeded with SciPy{bcomm}')
                allparams[targ+"_"+str(cmpd)]=fittedParameters

            except:
                # print(f'{targ} {cmpd} fit failed')
                allparams[targ+"_"+str(cmpd)]=[np.nan]*8+[f'Fit FAILED with SciPy{bcomm}']

    df=pd.DataFrame.from_dict(allparams).T
    df.columns=['top','bottom','LogIC50','hill','RMSE','R^2','IC50','pIC50','notes']
    # df.columns=['SciPy_'+col for col in df.columns]
    df.hill=df.hill*-1
    df=df.reset_index()
    df=df.rename(columns={'index':'Compound'})
    df[['Target','Compound']]=df.Compound.str.split('_', expand=True)
    # df.Compound=df.Compound.astype(int)
    df['relation']=np.nan
    df['hitc']=[1 if 'succeeded' in x else 0 for x in df.notes]

    return df

###################################################################################################

def tcpl_mc3_to_raw(mc3, graphcol='percent_inhibition', fix_raw=False):
    """Prep TCPL output to be used in plotting functions.

    Args:
        mc3: tcpl MC3 df to be prepped

    Returns:
        raw: modified df
    """
    raw=mc3.copy()
    raw.columns=['Compound', 'chid', 'casn', 'chnm', 'dsstox_substance_id', 'code', 'aeid',
       'Target', 'm0id', 'm1id', 'm2id', 'm3id', 'logc', graphcol, 'cndx', 'Well_Type',
       'Plate', 'rowi', 'coli', 'repi', 'resp_unit', 'conc_unit']
    raw['Conc_uM']=10**raw.logc
    raw['logconc']=np.log10(raw.Conc_uM/1000000)
    raw.Well_Type=raw.Well_Type.str.replace('n','negativeControl')
    nconcdict={}
    for plate in raw.Plate.unique():
        nconcdict[plate]=raw[raw.Plate==plate].cndx.max()
    raw['nconc']=raw.Plate.map(nconcdict)
    nplatedict={}
    for compound in raw.Compound.unique():
        nplatedict[compound]=raw[raw.Compound==compound].Plate.nunique()
    raw['nplate']=raw.Compound.map(nplatedict)
    raw['RealPlate']=raw.Plate
    raw.Plate = raw.Target
    if fix_raw:
        for targ in raw.Target.unique():
            for compound in raw.Compound.unique():
                if compound in [207,210]:
                    continue
            # print(compound, raw[raw.Compound==compound].nconc.unique().tolist())
                if (raw[(raw.Compound==compound)&(raw.Target==targ)].nconc.unique().tolist()==[3,9]):
                    raw=raw.drop(raw[(raw.Compound==compound)&(raw.Target==targ)&(raw.nconc==3)].index)
    return raw

def tcpl_mc5_to_curve(mc5):
    """Prep TCPL output to be used in plotting functions.

    Args:
        mc5: tcpl MC5 df to be prepped

    Returns:
        curve: modified df
    """
    curve=mc5.copy()
    curve['AC50_uM']=10**curve.modl_ga
    curve['pIC50']=-np.log10(curve.AC50_uM/1000000)
    curve=curve[['m5id', 'flag', 'spid', 'chid', 'casn', 'aenm', 'm4id', 'bmad', 'resp_max', 'resp_min',
       'max_mean', 'max_mean_conc', 'max_med', 'max_med_conc', 'logc_max',
       'logc_min', 'nconc', 'npts', 'nrep', 'nmed_gtbl', 'hitc', 'modl', 'fitc', 'coff', 'actp', 'modl_er',
       'modl_tp', 'modl_ga', 'modl_gw', 'modl_la', 'modl_lw', 'modl_rmse',
       'modl_prob', 'modl_acc', 'modl_acb', 'modl_ac10', 'resp_unit',
       'conc_unit', 'AC50_uM', 'pIC50']]
    curve.columns=['m5id', 'flag', 'Compound', 'chid', 'casn', 'Target', 'm4id', 'bmad', 'resp_max', 'resp_min',
           'max_mean', 'max_mean_conc', 'max_med', 'max_med_conc', 'logc_max',
           'logc_min', 'nconc', 'npts', 'nrep', 'nmed_gtbl', 'hitc', 'modl', 'fitc', 'coff', 'actp', 'modl_er',
           'top', 'modl_ga', 'hill', 'modl_la', 'modl_lw', 'RMSE',
           'modl_prob', 'modl_acc', 'modl_acb', 'modl_ac10', 'resp_unit',
           'conc_unit', 'IC50', 'pIC50']
    curve['bottom']=0
    curve['notes']=['TCPL fit succeeded' if x==1 else np.nan for x in curve.hitc]
    return curve


import mysql.connector
import self_library as lib

print("WELCOME TO SAARTHI, INDIA'S NUMBER ONE ONLINE CAB SERVICE")

while (1):
    fname = "'" + input("Please enter your first name  :    ") + "'"
    lname = "'" + input("Please enter your last name  :     ") + "'"
    lib.login(fname,lname)

    i = int(input("Press 1 to book a cab or 0 to exit:      "))
    if(i==1):
        r = int(input("Press 1 to reserve or 0 to book now:     "))
        if(r==1):

            lib.reserve_ride()
            lib.payment()
            lib.show_price()
            lib.leave_rating()
            print("****************************************************************")

            print("Thank you for using Saarthi!")

            exit(0)
        else:
            lib.book_ride()
            lib.payment()
            lib.show_price()
            lib.leave_rating()
            print("****************************************************************")

            print("Thank you for using Saarthi!")

            exit(0)
    else:
        print("****************************************************************")
        print("Thank you for using Saarthi!")
        exit(0)


import fiftyone as fo
import fiftyone.utils.image

def load_dataset_from_local_path(dataset_local_dir: str, dataset_name: str,
                                 force_reload_dataset_if_exists: bool = False):
    if dataset_name in fo.list_datasets() and force_reload_dataset_if_exists:
        exists_dataset = fo.load_dataset(dataset_name)
        print("dataset: {} already exists, will delete it...".format(dataset_name))
        exists_dataset.delete()
        print("     deleted with result: {}".format(exists_dataset.deleted))
    elif dataset_name in fo.list_datasets() and not force_reload_dataset_if_exists:
        return fo.load_dataset(dataset_name)
    dataset = fo.Dataset.from_dir(
        dataset_dir=dataset_local_dir,
        dataset_type=fo.types.KITTIDetectionDataset,
        name=dataset_name,
    )
    dataset.persistent = True
    return dataset

def reencode_to_png_in_place(dataset):
    # fiftyone.utils.image.reencode_images(
    #     dataset, ext='.png', force_reencode=True, delete_originals=True, num_workers=None, skip_failures=False)
    # size (width, height) for each image. One dimension can be -1, in which case the aspect ratio is preserved
    fiftyone.utils.image.transform_images(dataset, size=(960, 1280), min_size=None, max_size=None, ext='.png',
                                          force_reencode=True, delete_originals=True, num_workers=None, skip_failures=False)

if __name__ == '__main__':
    src_dataset_local_path = "test/my_kitti_dataset_dir"
    dataset_name = "first_time1"
    dataset = load_dataset_from_local_path(
        src_dataset_local_path, dataset_name, True)
    # View summary info about the dataset
    print(dataset)

    # Print the first few samples in the dataset
    # print(dataset.head())
    reencode_to_png_in_place(dataset)


import numpy as np
import scipy.stats as stats

# создание двух массивов данных
group1 = [1000,1380,1200]
group2 = [1400,1600,1180,1220]

# объединение двух массивов
all_values = np.concatenate((group1, group2))

# ранжирование значений
ranked_values = np.argsort(all_values)
# print(all_values)
# print(np.sort(all_values))
# print(ranked_values)

# расчет суммы рангов для каждой из групп
ranks_group1 = ranked_values[:len(group1)].sum()
ranks_group2 = ranked_values[len(group1):].sum()
R = max(ranks_group1, ranks_group2)
print(R)

# расчет U-статистики
n1 = len(group1)
n2 = len(group2)
if R == ranks_group1:
    nt = (n1*(n1+1)) / 2
else:
    nt = (n2*(n2+1)) / 2

print(nt)
U1 = n1 * n2 + n1 * (n1 + 1) / 2 - ranks_group1
U2 = n1 * n2 + n2 * (n2 + 1) / 2 - ranks_group2
print(n1*n2)
print(n1 * (n1 + 1) / 2)
print(n1 / (n1 + n2))
print (U1, U2)
U = max(U1, U2)

# U = R - nt
# print(U)

# определение p-value
p = 2 * (1 - (U / (n1 * n2)))

print("Статистика U = %.2f, p-value = %.3f" % (U, p))

print(stats.mannwhitneyu(group1, group2))


import cv2

image = cv2.imread("two_people.jpg")
eye_cascade = cv2.CascadeClassifier('haarcascade_eye.xml')
eyes = eye_cascade.detectMultiScale(image, scaleFactor=1.1, minNeighbors=5)

for (ex, ey, ew, eh) in eyes:
    cv2.rectangle(image, (ex, ey), (ex + ew, ey + eh), (255, 0, 0), 2)

cv2.imshow("Eye Detected", image)

cv2.waitKey(0)
cv2.destroyAllWindows()


__author__ = 'jonathan'

#############
#  imports  #
#############

from functools import wraps
from flask import Flask, flash, redirect, render_template, \
    request, session, url_for, Blueprint

from .forms import AddTaskForm
from datetime import datetime
from project import db
from project.models import Task

##############
#   config   #
##############

tasks_blueprint = Blueprint('tasks', __name__)

#######################
#   helper functions  #
#######################

def login_required(test):
    @wraps(test)
    def wrap(*args, **kwargs):
        if 'logged_in' in session:
            return test(*args, **kwargs)
        else:
            flash('You must log in to view this page')
            return redirect(url_for('users.login'))
    return wrap

def open_tasks():
    return db.session.query(Task).filter_by(
        status='1').order_by(Task.due_date.asc())

def closed_tasks():
    return db.session.query(Task).filter_by(
        status='0').order_by(Task.due_date.asc())

# route to display tasks
@tasks_blueprint.route('/tasks/')
@login_required
def tasks():
    return render_template(
        'tasks.html',
        form=AddTaskForm(request.form),
        open_tasks=open_tasks(),
        closed_tasks=closed_tasks()
    )

# Add new task
@tasks_blueprint.route('/add/', methods=['GET', 'POST'])
@login_required
def new_task():
    error = None
    form = AddTaskForm(request.form)
    if request.method == 'POST':
        if form.validate_on_submit():
            task_to_add = Task(
                form.name.data,
                form.due_date.data,
                form.priority.data,
                datetime.utcnow(),
                '1',
                session['user_id']
            )
            db.session.add(task_to_add)
            db.session.commit()
            flash('New entry was successfully posted.')
            return redirect(url_for('tasks.tasks'))

    return render_template(url_for('tasks.tasks'), form=form, error=error, open_tasks=open_tasks(),
                           closed_tasks=closed_tasks())

# Mark task as complete, using dynamic routing
@tasks_blueprint.route('/complete/<int:task_id>/')
@login_required
def complete(task_id):
    db.session.query(Task) \
        .filter_by(task_id=task_id).update({"status": "0"})
    db.session.commit()
    flash('The task with id = ' + str(task_id) + ' was marked as complete')
    return redirect(url_for('tasks.tasks'))

# Delete task, using dynamic routing
@tasks_blueprint.route('/delete/<int:task_id>/')
@login_required
def delete_entry(task_id):
    db.session.query(Task) \
        .filter_by(task_id=task_id).delete()
    db.session.commit()
    flash('Deleted task with id = ' + str(task_id))
    return redirect(url_for('tasks.tasks'))


import re

class ApplicationConfig(object):
    def __init__(self, header_path=("../../../examples/serial/include/"
                                    + "nrf_mesh_config_app.h")):

        self.data = {}

        # Regular expression that finds all #define pairs
        # NOTE: This will not work for bitfield types, e.g., (1 << 3)
        r = re.compile("#define\s+([A-Za-z0-9_]+)[\s(]+([A-Za-z0-9_]+)")
        fdata = ""

        # Read the header into a string
        with open(header_path, "r") as f:
            fdata = f.read()

        matches = r.findall(fdata)
        for match in matches:
            self.data[match[0]] = self.define_parse(match[1])

        # Setting this allows the user to access the configuration data
        # as, e.g., ApplicationConfig.DEVICE_ID
        self.__dict__ = self.data

    def define_parse(self, define):
        DEFINE_LUT = {"ACCESS_COMPANY_ID_NONE": 0xFFFF,
                      "ACCESS_COMPANY_ID_NORDIC": 0x0059,
                      "ACCESS_TTL_USE_DEFAULT": 0xFF,
                      "CONFIG_FEATURE_RELAY_BIT": 1}

        if define.lower().startswith("0x"):
            return int(define, 16)
        elif define.isdigit():
            return int(define, 10)
        elif define in DEFINE_LUT.keys():
            return DEFINE_LUT[define]
        elif define in self.data.keys():
            return self.data[define]
        else:
            return None


from collections import defaultdict, Counter
from os import listdir

import torch
import torch.optim as optim
from aalpy.utils import load_automaton_from_file
from sklearn.cluster import estimate_bandwidth

from RNN import get_model, Optimization
from automata_data_generation import get_tomita, get_mqtt_mealy, generate_data_from_automaton, AutomatonDataset
from clustering import compute_linear_separability_classifier, \
    compute_clusters_and_map_to_states, compute_linear_separability_and_map_to_states
from dim_reduction import reduce_dimensions
from methods import extract_hidden_states, compute_lda_separation
from util import compute_ambiguity

# Unused function
def compute_lda_and_separation(automaton, model, validation_data):
    hs_processing_fun = 'flatten' if model.model_type != 'lstm' else 'flatten_lstm'

    import time
    before_extract = time.time()
    hidden_states = extract_hidden_states(model, validation_data, process_hs_fun=hs_processing_fun,
                                          save=False, load=False)

    before_lda = time.time()
    lda = compute_linear_separability_classifier(automaton, hidden_states, validation_data)
    before_separation = time.time()
    separation_values = compute_lda_separation(lda, automaton, hidden_states, validation_data)
    end = time.time()

    print(f"Separation: {separation_values}")
    print(f"Times: {before_lda - before_extract}, {before_separation - before_lda}, {end - before_separation}")
    return separation_values

# Unused function
def map_clusters_to_lda(automaton, model, validation_data):
    clustering_functions = ['k_means', 'mean_shift', 'spectral', 'DBSCAN', 'OPTICS']

    hs_processing_fun = 'flatten' if model.model_type != 'lstm' else 'flatten_lstm'
    hidden_states = extract_hidden_states(model, validation_data, process_hs_fun=hs_processing_fun,
                                          save=False, load=False)

    cluster_to_lda_maps = []
    lda = compute_linear_separability_classifier(automaton, hidden_states, validation_data)
    lda_predictions = [lda.predict(x.reshape(1, -1)) for x in hidden_states.copy()]
    for cf in clustering_functions:
        cf_predictions = compute_clusters_and_map_to_states(automaton, validation_data, hidden_states, cf,
                                                            return_fit_predict=True)
        lda_to_cf_map = defaultdict(Counter)
        for l, c in zip(lda_predictions, cf_predictions):
            lda_to_cf_map[f'l{l}'][f'c{c}'] += 1
            cluster_to_lda_maps.append(('cf', lda_to_cf_map))

    ambiguity_results = []
    for cf, lda_cluster_map in cluster_to_lda_maps:
        ambiguity_results.append((cf, compute_ambiguity(lda_cluster_map)))

    print(ambiguity_results)

def compare_clustering_methods(automaton, model, validation_data):
    clustering_functions = ['DBSCAN_half', 'DBSCAN', 'DBSCAN_double', 'DBSCAN_triple', 'DBSCAN_quad', 'k_means',
                            'k_means_dec', 'k_means_inc', 'k_means_double', 'k_means_4', 'k_means_6', 'k_means_8',
                            'OPTICS', 'mean_shift', 'mean_shift_2', 'mean_shift_4', 'mean_shift_8']

    model.eval()

    hs_processing_fun = 'flatten' if model.model_type != 'lstm' else 'flatten_lstm'
    hidden_states = extract_hidden_states(model, validation_data, process_hs_fun=hs_processing_fun,
                                          save=False, load=False)

    cluster_to_state_maps = []
    lda_state_map = compute_linear_separability_and_map_to_states(automaton, hidden_states, validation_data,
                                                                  method='lda')
    cluster_to_state_maps.append(('lda', lda_state_map, automaton.size))
    lr_state_map = compute_linear_separability_and_map_to_states(automaton, hidden_states, validation_data, method='lr')
    cluster_to_state_maps.append(('lr', lr_state_map, automaton.size))

    mean_shift_default_bandwidth = estimate_bandwidth(hidden_states)

    for cf in clustering_functions:
        cf_state_map, nr_clusters = compute_clusters_and_map_to_states(automaton, validation_data, hidden_states,
                                                                       cf, mean_shift_default_bandwidth)
        cluster_to_state_maps.append((cf, cf_state_map, nr_clusters))

    ambiguity_results = []
    for cf, state_cluster_map, nr_clusters in cluster_to_state_maps:
        ambiguity_results.append((cf, compute_ambiguity(state_cluster_map, weighted=True), nr_clusters))

    print(ambiguity_results)
    return ambiguity_results

if __name__ == '__main__':

    save_dir = 'rnn_data'

    device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
    device_type = 'gpu' if device != 'cpu' else 'cpu'

    experiments = [(get_tomita(3), 'tomita3'),
                   (get_tomita(5), 'tomita5'),
                   (get_tomita(7), 'tomita7'),
                   (get_mqtt_mealy(), 'mqtt'),
                   (load_automaton_from_file('automata_models/regex_paper.dot', automaton_type='dfa'), 'regex')]

    randomly_generated_dfa = [f for f in listdir('automata_models/') if f[:3] == 'dfa']
    randomly_generated_moore_machines = [f for f in listdir('automata_models/') if f[:5] == 'moore']

    for aut in randomly_generated_dfa:
        experiments.append((load_automaton_from_file(f'automata_models/{aut}', automaton_type='dfa'), aut))

    for aut in randomly_generated_moore_machines:
        experiments.append((load_automaton_from_file(f'automata_models/{aut}', automaton_type='moore'), aut))

    rnn_types = ['tanh', 'relu', 'gru', 'lstm']
    num_repeats_per_config = 2

    num_training_samples = 50 * 1000
    num_validation_samples = 4 * 1000

    total_exp_configs = len(experiments) * len(rnn_types) * 3 * num_repeats_per_config
    print(f'Total number of trainings: {total_exp_configs}')

    current_iteration = 0
    with open('experiment_results/stats_mean_shift_lr.txt', 'a') as stats_file:
        for automaton, exp_name in experiments:
            for rnn in rnn_types:
                optimal_size = len(automaton.get_input_alphabet()) * automaton.size
                sizes = ((1, optimal_size), (1, int(optimal_size * 1.5)), (2, optimal_size))
                for layers, nodes in sizes:
                    for i in range(num_repeats_per_config):
                        current_iteration += 1
                        print(f'Automated driver progress: {round((current_iteration / total_exp_configs) * 100, 2)}%')

                        exp_rnn_config = f'{exp_name}_{rnn}_{layers}_{nodes}_{i + 1}_{device_type}'
                        model_weights_name = f'{save_dir}/models/exp_models/{exp_rnn_config}.pt'
                        print(exp_rnn_config)

                        training_data, input_al, output_al = generate_data_from_automaton(automaton,
                                                                                num_examples=num_training_samples)
                        validation_data, _, _ = generate_data_from_automaton(automaton,
                                                                             num_examples=num_validation_samples)

                        model_type = rnn if rnn in {'gru', 'lstm'} else 'rnn'
                        activation_fun = rnn
                        input_dim = len(input_al)
                        output_dim = len(output_al)
                        layer_dim = layers
                        hidden_dim = nodes
                        batch_size = 128
                        dropout = 0.1 if layer_dim > 1 else 0
                        n_epochs = 200
                        learning_rate = 0.0005
                        weight_decay = 1e-6

                        data_handler = AutomatonDataset(input_al, output_al, batch_size)

                        train, val = data_handler.create_dataset(training_data), data_handler.create_dataset(
                            validation_data)

                        model_params = {'input_dim': input_dim,
                                        'hidden_dim': hidden_dim,
                                        'layer_dim': layer_dim,
                                        'output_dim': output_dim,
                                        'nonlinearity': activation_fun,
                                        'dropout_prob': dropout,
                                        'data_handler': data_handler, }

                        model = get_model(model_type, model_params)
                        model.model_name = model_weights_name

                        optimizer = optim.Adam(model.parameters(), lr=learning_rate, weight_decay=weight_decay)
                        opt = Optimization(model=model, optimizer=optimizer)
                        # opt.train(train, val, n_epochs=n_epochs, exp_name=model_weights_name, early_stop=True, verbose=True,
                        #          save=False, load=True)

                        load_status = opt.load(model_weights_name)
                        if not load_status:
                            print(f'Can not find weights file of: {model_weights_name}')
                            continue

                        validation_data, _, _ = generate_data_from_automaton(automaton, num_examples=1000)

                        res = compare_clustering_methods(automaton, model, validation_data)
                        # res = compute_lda_and_separation(automaton, model, validation_data)
                        from methods import conformance_test

                        conf_test_res = conformance_test(model, automaton, min_test_len=5, max_test_len=13)
                        res.append(('conf_test', conf_test_res))
                        stats_file.write(
                            f'Automated driver progress: iteration {current_iteration} of {total_exp_configs}\n')
                        stats_file.write(f'{exp_rnn_config}\n')
                        stats_file.write(f'{res}\n')
                        stats_file.flush()


# Functions go here
import pandas

# checks that questions are not left blank and repeat question
def not_blank(question, error):

    valid = False
    while not valid:
        response = input(question)

        if response == "":
            print("{}.  \nPlease try again.\n".format(error))
            continue

        return response

# checks that the budget is 5 or more
def get_budget(question, error, num_type):
    valid = False
    while not valid:

        try:
            response = num_type(input(question))

            if response < 5:
                print(error)
            else:
                return response

        except ValueError:
            print(error)

# checks that number is more than or equal to 1
def price_check(question, error, num_type):
    valid = False
    while not valid:

        try:
            response = num_type(input(question))

            if response < 1:
                print(error)
            else:
                return response

        except ValueError:
            print(error)

# checks that grams is at least 100
def get_grams(question, error, num_type):
    valid = False
    while not valid:

        try:
            response = num_type(input(question))

            if response < 100:
                print(error)
            else:
                return response

        except ValueError:
            print(error)

def currency(x):
    return "${:.2f}".format(x)

# Main routine goes here
budget = get_budget("What is your budget in dollars? ",
                    "Please enter a number that is 5 or more\n", float)
print("Your budget is", "${:.2f}".format(budget))

# set up lists
item_list = []
weight_list = []
cost_list = []
unitprice_list = []

variable_dict = {
        'Item': item_list,
        'Weight (g)': weight_list,
        'Cost': cost_list,
        'Unit Price': unitprice_list,
    }

item = ""

while item != "xxx":

    # ask user for item name
    item = not_blank("Item: ",
                     "This can't be blank")

    # End the loop if the exit code is entered
    if item == "xxx":
        break

    # get weight in grams
    weight_grams = get_grams("What is the weight in grams / milliliters? ",
                             "Please enter a number that is 100 or more\n", int)

    # get cost in dollars
    get_cost = price_check("What is the price in dollars? ",
                           "Please enter a number that is 1 or more\n", float)

    # test unit price calculation
    unit_price = get_cost / (weight_grams / 1000)
    print("The unit price is", "${:.2f}".format(unit_price))

    # add item name, weight, price, and unit price to lists
    item_list.append(item)
    weight_list.append(weight_grams)
    cost_list.append(get_cost)
    unitprice_list.append(unit_price)

price_frame = pandas.DataFrame(variable_dict)
price_frame = price_frame.set_index('Item')

price_frame = price_frame.rename(columns={'Unit Price': 'U.P',
                                          'Weight (g)': 'grams'})

price_frame = price_frame.sort_values(by=['U.P'])

pandas.set_option('display.max_columns', None)

add_dollars = ['Cost', 'U.P']
for item in add_dollars:
    price_frame[item] = price_frame[item].apply(currency)

best_value = price_frame.head(1).item('U.P')

print()
print(price_frame)
print()
print(best_value)
print()
print("The items are listed in ascending order by unit price.",
      "\nThe ones at the top are the best value")


# from pudb import set_trace; set_trace()
from typing import List

class Solution:
    def numIslands(self, grid: List[List[str]]) -> int:
        """DFS. Since we only need to return the total number of islands, the
        problem is actually simplied.

        O(MN), 336 ms, 49% ranking.
        """
        m, n = len(grid), len(grid[0])

        def dfs(i: int, j: int) -> int:
            if 0 <= i < m and 0 <= j < n and grid[i][j] == '1':
                grid[i][j] = '0'
                # courtesy of Mr. Pochmann
                # https://leetcode.com/problems/number-of-islands/discuss/56349/7-lines-Python-~14-lines-Java
                list(map(dfs, [i + 1, i - 1, i, i], [j, j, j + 1, j - 1]))
                return 1
            return 0

        return sum(dfs(i, j) for i in range(m) for j in range(n))

sol = Solution()
tests = [
    (
        [
          ["1","1","1","1","0"],
          ["1","1","0","1","0"],
          ["1","1","0","0","0"],
          ["0","0","0","0","0"]
        ],
        1,
    ),
    (
        [
          ["1","1","0","0","0"],
          ["1","1","0","0","0"],
          ["0","0","1","0","0"],
          ["0","0","0","1","1"]
        ],
        3,
    )
]

for i, (grid, ans) in enumerate(tests):
    res = sol.numIslands(grid)
    if res == ans:
        print(f'Test {i}: PASS')
    else:
        print(f'Test {i}; Fail. Ans: {ans}, Res: {res}')


import django
django.setup()
from ..models import PublicKey, PrivateKey, Member
import  random
from ..Utils import NumberUtil, KeyUtil
import hashlib
import pathlib

def Hash(m):
    a=str(m)
    result=hashlib.sha512(a.encode('utf-8')).digest()
    return int.from_bytes(result, 'little')

def ChooseG(n, upperBlock):
    while True:
        number = NumberUtil.GetPrime(NumberUtil.lower(n), upperBlock)
        if number < upperBlock:
            return number
        else:
            continue

def Setup(lg=1200,ep=9/8,l=1200,l1=860,l2=600):
    PublicKey.objects.all().delete()
    PrivateKey.objects.all().delete()

    p = NumberUtil.GetPrime(NumberUtil.lower(lg / 2), NumberUtil.upper(lg / 2))
    q = NumberUtil.GetPrime(NumberUtil.lower(lg / 2), NumberUtil.upper(lg / 2))
    k = 256
    n = p * q
    g = ChooseG(lg - 1, n)

    hatZ = NumberUtil.nBitRandom(NumberUtil.lower(lg), NumberUtil.upper(lg))
    z = pow(g, hatZ, n)
    hatH = NumberUtil.nBitRandom(NumberUtil.lower(lg), NumberUtil.upper(lg))
    h = pow(g, hatH, n)

    x = random.randrange(0, NumberUtil.upper(lg))
    y = pow(g, x, n)

    KeyUtil.SavePublicKey(KeyUtil.Public(n,g,h,z,l,l1,l2,lg,k,ep,y))
    KeyUtil.SavePrivate(KeyUtil.Private(p,q,x))

def Registration():
    public= KeyUtil.GetPublicKey()

    hatE = NumberUtil.GetPrime(NumberUtil.lower(int(public.L)), NumberUtil.upper(int(public.L)))
    e = NumberUtil.GetPrime(2**int(public.L1)+1, 2**int(public.L1)+2**int(public.L2) - 1)
    tempE = hatE*e
    tempZ = pow(int(public.Z), hatE, int(public.N))

    return (e,tempE, tempZ)

def Hash(m):
    a=str(m)
    result=hashlib.sha512(a.encode('utf-8')).digest()
    return int.from_bytes(result, 'little')

def CheckMemberKey(u, e):
    publickey = KeyUtil.GetPublicKey()
    z= int(publickey.Z)
    n = int(publickey.N)
    temp = pow(u,e,n)
    z= z % n
    return (temp==(z % n))

def GenerateSignature(u, e, message):
    publickey = KeyUtil.GetPublicKey()
    lg =int(publickey.LG)
    g = int(publickey.G)
    n = int(publickey.N)
    y= int(publickey.Y)
    h = int(publickey.H)
    z= int(publickey.Z)
    ep = float(publickey.ESP)
    l2= int(publickey.L2)
    l1= int(publickey.L1)
    k= int(publickey.K)

    m = Hash(message)
    w = random.randrange(0, 2 ** lg)

    a = pow(g, w, n)
    b = (u * pow(y, w, n)) % n
    d = (pow(g, e, n) * pow(h, w, n)) % n
    r1 = random.randrange(0, pow(2, int(ep * (l2 + k))))
    r2 = random.randrange(0, pow(2, int(ep * (lg + l1 + k))))
    r3 = random.randrange(0, pow(2, int(ep * (lg + k))))
    t1 = (pow(b, r1, n) * pow(pow(y, r2, n), -1, n)) % n
    t2 = (pow(a, r1, n) * pow(pow(g, r2, n), -1, n)) % n
    t3 = pow(g, r3, n)
    t4 = (pow(g, r1, n) * pow(h, r3, n)) % n
    c = Hash(str(g) + str(h) + str(y) + str(z) + str(a) + str(b) + str(d) + str(t1) + str(t2) + str(t3) + str(t4) + str(m))
    s1 = r1 - c * (e - 2 ** l1)
    s2 = r2 - c * e * w
    s3 = r3 - c * w

    return c, s1, s2, s3, a, b, d

def Verifying(c,s1,s2,s3,a,b,d, message):
    publickey = KeyUtil.GetPublicKey()
    lg = int(publickey.LG)
    g = int(publickey.G)
    n = int(publickey.N)
    y = int(publickey.Y)
    h = int(publickey.H)
    z = int(publickey.Z)
    ep = float(publickey.ESP)
    l2 = int(publickey.L2)
    l1 = int(publickey.L1)
    k = int(publickey.K)

    m = Hash(message)
    tempHat = int(s1 - c * 2 ** l1)
    t1 = pow(z, c, n) * pow(b, tempHat, n) * pow(pow(y, s2, n), -1, n)
    t2 = pow(a, tempHat, n) * pow(pow(g, s2, n), -1, n)
    t3 = pow(a, c, n) * pow(g, s3, n)
    t4 = pow(d, c, n) * pow(g, tempHat, n) * pow(h, s3, n)

    t1 = t1 % n
    t2 = t2 % n
    t3 = t3 % n
    t4 = t4 % n

    tempC = Hash(str(g) + str(h) + str(y) + str(z) + str(a) + str(b) + str(d) + str(t1) + str(t2) + str(t3) + str(t4) + str(m))

    return tempC == c

def tracing(c,s1,s2,s3,a,b,d):
    publickey = KeyUtil.GetPublicKey()
    n = int(publickey.N)

    privatekey = KeyUtil.GetPrivate()
    x= int(privatekey.X)
    result = b * pow(pow(a, x, n), -1, n)
    result = result % n

    return result


class node:
  def __init__(self,data=0):
    self.data=data
    self.left=None
    self.right=None

def identical(root,r):
  if root==None and r==None:
    return True
  elif root==None or r==None:
    return False
  elif root.data==r.data :
    return(True and identical(root.left,r.left) and identical(root.right,r.right))
  else:
    return False

#tree 1
root=node(1)
root.left=node(2)
root.right=node(3)
root.left.left=node(4)

#tree 2
root1=node(1)
root1.left=node(2)
root1.right=node(5)
root1.left.left=node(4)

print(identical(root,root1))


from typing import List

class Solution:
    def kidsWithCandies(self, candies: List[int], extraCandies: int) -> List[bool]:
        max = -1
        isGreatest = []

        for each in candies:
            if each > max:
                max = each

        for each in candies:
            isGreater = False
            if (extraCandies + each >= max):
                isGreater = True
            isGreatest.append(isGreater)
        return isGreatest

if __name__ == "__main__":
    sol = Solution()
    print(f'The output is : {sol.kidsWithCandies([2,3,5,1,3], 3)}')

Data Structures and Algorithms/Python/LeetCode/Kids With the Greatest Number of Candies.py


from Dealer import *

# -*- coding: utf-8 -*-
"""
Created on Sat May 14 10:09:15 2022

@author: Mark D. Yarnell
"""

def play_hand(player, dealer):
    """
    player : a member of Player Class
    dealer : a special member of Player Class
    """
    player.reset()                          # reset variables
    player.deal()                           # first 2 cards
    player.print_score()
    while player.total <= 21:               # still in play
        decision = input("0 = STICK, 1 = TWIST ")
        if decision == "1":
            player.twist()                  # 1 more card
            player.print_score()
        else:
            break
    if player.total > 21:                   # dealer auto wins
        player.lost()
        return
    if player.aces > 0 and player.total <= 11:
        player.total += 10                  # score an ace as 11
    dealer.reset()
    dealer.deal()
    dealer.print_score()
    """" awkward condition to account for various scenarios incl aces"""
    while dealer.total < player.total and dealer.total + 10*dealer.aces > 21 or dealer.total + 10*dealer.aces < player.total:
        dealer.twist()
        dealer.print_score()
    if dealer.total <= 21 and dealer.total >= player.total:
        player.lost()
    else:
        player.won()
    new_hand()
def new_hand():                             # leave a gap between hands
    print("---")
    print()

# def computer_player_hand():
#     #When this function is called, the dealer's score is reset for another round, a credit is paid, the dealer's turn is
#     #taken and the process is displayed as text. The dealer's score remains
#     dealer.reset() #resets the score
#     if dealer.credits == 0:
#         print("Congratulations! The dealer ran out of credits! You won!")
#         # game_complete()
#     dealer.credits -= 1
#     print("Dealer's turn... Dealer paid 1 credit to play. Dealer currently has ", dealer.credits, " credits.")
#     while dealer.total < 22:
#         if 15 < dealer.total < 22:
#             print("Dealer has chosen to STICK with", dealer.total)
#             break
#         print("Dealer takes a card...")
#         time.sleep(2)
#         card = deck.deal()
#         print("Dealer drew ", card.value)
#         time.sleep(2)
#         dealer.total += card.value
#         print("Dealer's total is currently ", dealer.total)
#         time.sleep(2)
#     if dealer.total > 21:
#         print("Dealer went bust! Dealer scored 0. Your turn!")
#         dealer.reset()
    # play_hand()


#Project Euler question 9

#There exists exactly one Pythagorean triplet for which a + b + c = 1000.
#Find the product abc.

#brute force
def pEQuestion9():
   for a in range(1,1000):
       for b in range(a,1000 - a):
         c = 1000 - a - b
         if a*a + b*b == c*c:
            return a*b*c

print(pEQuestion9())

#I tried implementing a solution with find the tripplet
#tripplets can be found with when
#m>n ,so a = m*m - n*n , b = 2(m*n), c = m*m + n*n
#I was having trouble generateing n and ms but figure Id just loop until 1000

def mnTriplet():
    for m in range(1,1000):
        for n in range(1,m):
            a = m*m - n*n
            b = 2*(m*n)
            c = m*m + n*n

            if a+b+c == 1000:
                return a*b*c

print(mnTriplet())


# A robot moves in a plane starting from the original point (0,0).
# The robot can move toward UP, DOWN, LEFT and RIGHT with a given steps.
# The trace of robot movement is shown as the following:
'''
UP 5
DOWN 3
LEFT 3
RIGHT 2
'''
# The numbers after the direction are steps. Please write a program to compute
# the distance from current position after a sequence of movement and original point.
# If the distance is a float, then just print the nearest integer.
# Example: If the following tuples are given as input to the program:
'''
UP 5
DOWN 3
LEFT 3
RIGHT 2
'''
# Then, the output of the program should be: 2

import math

up_down, left_right = 0, 0

while True:
    user_input = input().split(' ')
    if not user_input[0]:
        break
    else:
        if user_input[0].lower() == 'up':
            up_down -= int(user_input[1])
            print(up_down)
        elif user_input[0].lower() == 'down':
            up_down += int(user_input[1])
            print(up_down)
        elif user_input[0].lower() == 'left':
            left_right -= int(user_input[1])
            print(left_right)
        elif user_input[0].lower() == 'right':
            left_right += int(user_input[1])
            print(left_right)

total_distance = round(math.sqrt(up_down**2 + left_right**2))
print(total_distance)


from ast import Try

hrs = input('Enter Hours:')
h = float(hrs)
rate = input('Enter Rate per hours:')
r = float(rate)
if h <= 40:
    print(h * r)
else:
    print((h - 40) * r * 1.5 + 40 * r)


# Copied from fab.sampling.rejection_sampling_test.
import torch
from fab.sampling_methods.rejection_sampling import rejection_sampling
import matplotlib.pyplot as plt
from matplotlib import rc
import matplotlib as mpl

# Define target.
def target_log_prob(x):
    return -x**4 + 6 * x**2 + 1/2 * x

TARGET_Z = 11784.50927

# Define proposal
mix = torch.distributions.Categorical(torch.tensor([0.2, 0.8]))
com = torch.distributions.Normal(torch.tensor([-1.7, 1.7]), torch.tensor([0.5, 0.5]))

proposal = torch.distributions.MixtureSameFamily(mixture_distribution=mix,
                                             component_distribution=com)

k = TARGET_Z * 3

if __name__ == '__main__':
    mpl.rcParams['figure.dpi'] = 300
    rc('font', **{'family': 'serif', 'serif': ['Times']})
    rc('text', usetex=True)
    rc('figure', titlesize=15)
    rc('axes', titlesize=13, labelsize=13)  # fontsize of the axes title and labels
    #rc('legend', fontsize=6)
    rc('xtick', labelsize=11)
    rc('ytick', labelsize=11)

    # First plot contours so make sure that our rejection sampling meets condition that kq > p.
    fig, axs = plt.subplots(1, 2, figsize=(6, 3))
    x = torch.linspace(-4, 4, 200)
    p = torch.exp(target_log_prob(x))
    kq = k*torch.exp(proposal.log_prob(x))
    axs[0].plot(x, p, label="p")
    axs[0].plot(x, kq, label="kq")
    axs[0].set_xlabel(r"$x_1$")
    axs[0].set_ylabel(r"$f(x_1)$")
    axs[0].legend()

    n_samples = 10000
    samples = rejection_sampling(n_samples, proposal, target_log_prob, k)
    axs[1].plot(x, p/TARGET_Z, label="p (normalised)")
    axs[1].hist(samples, density=True, bins=100, label="sample density")
    axs[1].legend()
    axs[1].set_xlabel(r"$x_1$")
    axs[1].set_ylabel("PDF")
    plt.tight_layout()

    fig.savefig("plots/rejection_sampling.png", bbox_inches="tight")
    plt.show()


import extract_data as dd

import os, sys
sys.path.append(os.getcwd())
import time

import numpy as np
import tensorflow as tf

import tflib as lib
import tflib.ops.linear
import tflib.ops.conv2d
import tflib.ops.batchnorm
import tflib.ops.deconv2d
import tflib.save_images
import tflib.plot

DIM = 64
LAMBDA = 10  # Gradient penalty lambda hyperparameter
CRITIC_ITERS = 5  # How many critic iterations per generator iteration
BATCH_SIZE = 64  # Batch size
ITERS = 200000  # How many generator iterations to train for
OUTPUT_DIM = 12288  # Number of pixels (3*64*64)

lib.print_model_settings(locals().copy())

def LeakyReLU(x, alpha=0.2):
    return tf.maximum(alpha*x, x)

def ReLULayer(name, n_in, n_out, inputs):
    output = lib.ops.linear.Linear(name+'.Linear', n_in, n_out, inputs)
    return tf.nn.relu(output)

def LeakyReLULayer(name, n_in, n_out, inputs):
    output = lib.ops.linear.Linear(name+'.Linear', n_in, n_out, inputs)
    return LeakyReLU(output)

def Generator(n_samples, noise=None):
    if noise is None:
        noise = tf.random_normal([n_samples, 128])

    output = lib.ops.linear.Linear('Generator.Input', 128, 4*4*8*DIM, noise)
    output = lib.ops.batchnorm.Batchnorm('Generator.BN1', [0], output)
    output = tf.nn.relu(output)
    output = tf.reshape(output, [-1, 8*DIM, 4, 4])

    output = lib.ops.deconv2d.Deconv2D('Generator.2', 8*DIM, 4*DIM, 5, output)
    output = lib.ops.batchnorm.Batchnorm('Generator.BN2', [0,2,3], output)
    output = tf.nn.relu(output)

    output = lib.ops.deconv2d.Deconv2D('Generator.3', 4*DIM, 2*DIM, 5, output)
    output = lib.ops.batchnorm.Batchnorm('Generator.BN3', [0,2,3], output)
    output = tf.nn.relu(output)

    output = lib.ops.deconv2d.Deconv2D('Generator.4', 2*DIM, DIM, 5, output)
    output = lib.ops.batchnorm.Batchnorm('Generator.BN4', [0, 2, 3], output)
    output = tf.nn.relu(output)

    output = lib.ops.deconv2d.Deconv2D('Generator.5', DIM, 3, 5, output)

    output = tf.tanh(output)

    return tf.reshape(output, [-1, OUTPUT_DIM])

def Discriminator(inputs):

    #output = tf.reshape(inputs, [-1, 64, 64, 3])
    output = tf.reshape(inputs, [-1, 3, 64, 64])

    output = lib.ops.conv2d.Conv2D('Discriminator.1', 3, DIM, 5, output, stride=2)
    output = LeakyReLU(output)

    output = lib.ops.conv2d.Conv2D('Discriminator.2', DIM, 2*DIM, 5, output, stride=2)
    output = LeakyReLU(output)

    output = lib.ops.conv2d.Conv2D('Discriminator.3', 2*DIM, 4*DIM, 5, output, stride=2)
    output = LeakyReLU(output)

    output = lib.ops.conv2d.Conv2D('Discriminator.4', 4*DIM, 8*DIM, 5, output, stride=2)
    output = LeakyReLU(output)

    output = tf.reshape(output, [-1, 4*4*8*DIM])
    output = lib.ops.linear.Linear('Discriminator.Output', 4*4*8*DIM, 1, output)

    return tf.reshape(output, [-1])

real_data_in = tf.placeholder(tf.float32, shape=[None, OUTPUT_DIM])
real_data = 2*(real_data_in-.5)
fake_data = Generator(BATCH_SIZE)

disc_real = Discriminator(real_data)
disc_fake = Discriminator(fake_data)

gen_params = lib.params_with_name('Generator')
disc_params = lib.params_with_name('Discriminator')

# Standard WGAN loss
gen_cost = -tf.reduce_mean(disc_fake)
disc_cost = tf.reduce_mean(disc_fake) - tf.reduce_mean(disc_real)

# Gradient penalty
alpha = tf.random_uniform(
    shape=[BATCH_SIZE,1],
    minval=0.,
    maxval=1.
)
differences = fake_data - real_data
interpolates = real_data + (alpha*differences)
gradients = tf.gradients(Discriminator(interpolates), [interpolates])[0]
slopes = tf.sqrt(tf.reduce_sum(tf.square(gradients), reduction_indices=[1]))
gradient_penalty = tf.reduce_mean((slopes-1.)**2)
disc_cost += LAMBDA*gradient_penalty

gen_train_op = tf.train.AdamOptimizer(learning_rate=1e-4, beta1=0.5, beta2=0.9).minimize(gen_cost, var_list=gen_params)
disc_train_op = tf.train.AdamOptimizer(learning_rate=1e-4, beta1=0.5, beta2=0.9).minimize(disc_cost, var_list=disc_params)

# For generating samples
fixed_noise_128 = tf.constant(np.random.normal(size=(128, 128)).astype('float32'))
fixed_noise_samples_128 = Generator(128, noise=fixed_noise_128)
def generate_image(frame):
    samples = session.run(fixed_noise_samples_128)
    samples = ((samples+1.)*(255./2)).astype('int32')
    lib.save_images.save_images(samples.reshape((128, 3, 64, 64)), './out/samples_{}.jpg'.format(frame))

# Dataset iterators
def random_train_batch(dataset):
    idx = np.random.choice(_num_images_train, size=BATCH_SIZE, replace=False)
    train_img = dataset[idx, :, :, :]
    train_img = np.reshape(train_img, newshape=[BATCH_SIZE, OUTPUT_DIM])
    return train_img

# Train loop
with tf.Session() as session:
    start = 0
    if not os.path.exists('./out/'):
        os.makedirs('./out/')

    # Directory where data is present
    data_path = 'uc_data/'

    # filename
    filename = 'uc_data.tar.gz'

    dd._extract(data_path, filename)

    images_train = np.load(os.path.join(data_path, 'images_train_batch_1.npy'))
    _num_images_train = len(images_train)

    session.run(tf.global_variables_initializer())

    for iteration in xrange(ITERS):
        start_time = time.time()
        # Train generator
        if iteration > 0:
            _ = session.run(gen_train_op)
        # Train critic
        disc_iters = CRITIC_ITERS
        for i in xrange(disc_iters):
            train_imgs = random_train_batch(images_train)
            _disc_cost, _ = session.run([disc_cost, disc_train_op], feed_dict={real_data_in: train_imgs})

        lib.plot.plot('train disc cost', _disc_cost)
        lib.plot.plot('time', time.time() - start_time)

        # Calculate dev loss and generate samples every 100 iters
        if iteration % 100 == 99:
            generate_image(iteration)

        # Save logs every 100 iters
        if (iteration < 5) or (iteration % 100 == 99):
            lib.plot.flush()

        lib.plot.tick()


from guizero import App, Text, PushButton, TextBox

daApp = App("Aplicación", 500, 200, 'auto')

def guiveResult():
    result.value = (f"El cuadrado es: {str(int(numero.value)**2)}")

message = Text(daApp,text="Dame un numero")
numero = TextBox(daApp, width=50, text="")
result = Text(daApp, text="")

btnn = PushButton(daApp, command=guiveResult, text="Calcular")

daApp.display()


"""API endpoints for dealing with borrowable items."""

from typing import Any, Dict, Tuple, cast
from flask import Blueprint, request
from sqlalchemy.exc import IntegrityError  # type: ignore

from inventorymgr.accesscontrol import requires_permissions
from inventorymgr.api import APIError
from inventorymgr.api.models import BorrowableItemSchema
from inventorymgr.auth import authentication_required
from inventorymgr.db import db
from inventorymgr.db.models import BorrowableItem, Qualification

bp = Blueprint("items", __name__, url_prefix="/api/v1/items")

@bp.route("", methods=("POST",))
@authentication_required
@requires_permissions("create_items")
def create_item() -> Tuple[Dict[str, Any], int]:
    """JSON endpoint for creating borrowable items."""
    received_item = BorrowableItemSchema(
            only=(
                "name",
                "quantity_total",
                "quantity_in_stock",
                "unmatched_returns",
                "description",
                "required_qualifications",
            )
    ).load(request.json)
    try:
        qual_ids = [q["id"] for q in received_item["required_qualifications"]]
        qualifications = [Qualification.query.get(q_id) for q_id in qual_ids]
        if any(q is None for q in qualifications):
            raise APIError(reason="unknown_qualification", status_code=400)
        item = BorrowableItem(
            name=received_item["name"],
            quantity_total=received_item["quantity_total"],
            quantity_in_stock=received_item["quantity_in_stock"],
            unmatched_returns=received_item["unmatched_returns"],
            description=received_item["description"],
            required_qualifications=qualifications,
        )
        db.session.add(item)
        db.session.commit()
        return BorrowableItemSchema().dump(item), 200
    except IntegrityError as exc:
        raise APIError(reason="item_exists", status_code=400) from exc

@bp.route("", methods=("GET",))
@authentication_required
def list_items() -> Dict[str, Any]:
    """JSON endpoint for getting all borrowable items."""
    items = BorrowableItemSchema(many=True).dump(BorrowableItem.query.all())
    return {"items": items}

@bp.route("/<int:item_id>", methods=("PUT",))
@authentication_required
@requires_permissions("create_items")
def update_item(item_id: int) -> Dict[str, Any]:
    """JSON endpoint for updating borrowable item."""
    schema = BorrowableItemSchema()
    received_item = schema.load(request.json)

    if received_item["id"] != item_id:
        raise APIError(reason="id_mismatch", status_code=400)

    item = BorrowableItem.query.get(item_id)
    if item is None:
        raise APIError(reason="nonexistent_item", status_code=400)

    qual_ids = [q["id"] for q in received_item["required_qualifications"]]
    qualifications = [Qualification.query.get(q_id) for q_id in qual_ids]
    if any(q is None for q in qualifications):
        raise APIError(reason="unknown_qualification", status_code=400)

    try:
        item.name = received_item["name"]
        item.quantity_total = received_item["quantity_total"]
        item.quantity_in_stock = received_item["quantity_in_stock"]
        item.unmatched_returns = received_item["unmatched_returns"]
        item.description = received_item["description"]
        item.required_qualifications = qualifications
        db.session.commit()
    except IntegrityError as exc:
        db.session.rollback()
        raise APIError(reason="item_exists", status_code=400) from exc

    return cast(Dict[str, Any], schema.dump(item))

@bp.route("/<int:item_id>", methods=("DELETE",))
@authentication_required
@requires_permissions("create_items")
def delete_item(item_id: int) -> Dict[str, Any]:
    """API endpoint for deleting borrowable items."""
    item = BorrowableItem.query.get(item_id)
    if item is not None:
        db.session.delete(item)
        db.session.commit()
    return {"success": True}

@bp.route("/<int:item_id>", methods=("GET",))
@authentication_required
def get_item(item_id: int) -> Any:
    """API endpoint for getting a single borrowable item."""
    item = BorrowableItem.query.get(item_id)
    if item is None:
        raise APIError(reason="nonexistent_item", status_code=400)
    return BorrowableItemSchema().dump(item)


import heapq
input = __import__('sys').stdin.readline
n = int(input())
a,b,c = map(int, input().split())
m = int(input())
graph = [[] for _ in range(n+1)]
for _ in range(m):
    d,e,l = map(int, input().split())
    graph[d].append((e,l))
    graph[e].append((d,l))
INF = float('inf')

def dijkstra(start):
    distance = [INF]*(n+1)
    q = []
    heapq.heappush(q, (0, start))
    distance[start] = 0
    while q:
        dist, node = heapq.heappop(q)
        if dist>distance[node]:continue
        for nextNode, nextDist in graph[node]:
            cost = nextDist + dist
            if cost<distance[nextNode]:
                distance[nextNode] = cost
                heapq.heappush(q,(cost,nextNode))
    return distance

a_dist = dijkstra(a)
b_dist = dijkstra(b)
c_dist = dijkstra(c)
result = []
for i in range(1, n+1):
    m = min(a_dist[i], b_dist[i], c_dist[i])
    result.append(m)
idx = max(result)
print(result.index(idx) + 1)


"""
A very simple web server for managing the stock levels of a company's products

"""
import sys
from uuid import uuid4

import lightbus
from flask import Flask, request, redirect
from flask.templating import render_template

from . import db

# Create a flask webserver
web = Flask(__name__, static_folder='../../../static')

@web.route('/set-stock/<product_uuid>', methods=['POST'])
def set_stock(product_uuid):
    # Insert/update the stock level in the database
    db['stock'].upsert(dict(
        uuid=product_uuid,
        quantity=int(request.form.get('quantity') or 0)
    ), keys=['uuid'])
    return redirect('/')

@web.route('/', methods=['GET'])
def list_stock():
    return render_template('list.html',
                    products=db['products'],
                    stock=db['stock'],
    )


from django.contrib.auth.models import User
from django.views.generic import CreateView
from django.urls import reverse_lazy
from .forms import UserForm
from django.core import serializers
from django.http import HttpResponse, HttpResponseRedirect
from rest_framework.views import APIView
from .serializers import UserSerializer
import json
from django.shortcuts import render
from django.urls import reverse_lazy
from django.contrib.auth.views import LoginView
from .models import UserWebSocketSession
from .message import publish
from django.contrib.auth.views import logout
from django.contrib.auth.decorators import login_required
from django.http import JsonResponse

def customlogout(request):
    token = request.session.get('session_user_token', None)
    if token:
        session_user = UserWebSocketSession.objects.get(token=token)
        session_user.session_two_steps = False
        session_user.active_websocket = False
        session_user.save()

    return logout(request)

class CustomLoginView(LoginView):
    template_name = 'index.html'
    success_url = reverse_lazy("refuge:index")

    def dispatch(self, request, *args, **kwargs):
        response = super().dispatch(request, *args, **kwargs)
        valid = True

        if (request.method == 'POST' and request.POST['username'] and
                request.POST['password']):

            if request.session.get('session_user_token') is None:
                session_user = UserWebSocketSession.create_session_user(
                    user=request.user)
                request.session['session_user_token'] = session_user.token
                two_step = session_user.session_two_steps
                port = session_user.port
                request.session['session_user_two_steps'] = two_step
                request.session['session_user_port'] = port
                if not two_step:  # notifica al usuario que se ha iniciado otra sesion
                    publish(f'question_the_user.{session_user.user.id}',
                            {'user_id': session_user.user.id,
                             'token': session_user.token})
            else:
                token = request.session.get('session_user_token')
                session_user = UserWebSocketSession.objects.get(token=token)
                success = UserWebSocketSession.objects.filter(
                    user=session_user.user, session_two_steps=True).count() == 0
                if session_user.locked:
                    valid = False
                elif success:
                    valid = True
                    session_user.session_two_steps = True
                    session_user.save()
                session_user.session_two_steps = True
                session_user.save()
            two_step = session_user.session_two_steps
        else:  # metodo GET
            two_step = True

        if True:
            return response
        elif not valid:  # usuario bloqueado no acceso al sistema
            return HttpResponseRedirect(reverse_lazy('logout'))
        return HttpResponseRedirect(reverse_lazy('user:waiting_page'))

def user(request):
    return render(request, 'people/user_list.html')

def list(request):
    user = serializers.serialize('json', User.objects.all())
    return HttpResponse(user, content_type='application/json')

class UserRegistry(CreateView):
    model = User
    template_name = 'user/user_registry.html'
    form_class = UserForm
    success_url = reverse_lazy("login")

    def post(self, request, *arg, **kwargs):

        form = self.get_form()

        if form.is_valid():
            user = form.save()
            self.object = user
            return HttpResponseRedirect(self.get_success_url())
        else:
            kwargs['form'] = form

            return self.render_to_response(kwargs)

def user_session_token_authentication(request):
    first = False
    response = {'valid': False, 'first': first}
    token = request.GET.get('token', None)
    session_user = UserWebSocketSession.objects.filter(token=token)
    confirmation = session_user.exists()
    if confirmation:
        session_user = session_user.first()
        if not session_user.active_websocket and not session_user.locked:
            first = UserWebSocketSession.objects.filter(user=session_user.user,
                                                        active_websocket=True).count() == 0
            session_user.active_websocket = True
            session_user.save()
        response = {'valid': confirmation, 'first': first}

    return JsonResponse(response)

# confimacion de el usuario a una nueva session True o False

def user_session_confirm_token(request):
    response = {'valid': False}
    token = request.GET.get('token', None)
    campaign_id = request.GET.get('campaign_id', None)
    # si exite campaign id evaluar que esa campaña pertenesca a el usuario
    session_user = UserWebSocketSession.objects.filter(token=token)
    token_origin = request.GET.get('token_origin', None)
    valid_token_origin = UserWebSocketSession.objects.filter(
        token=token_origin).exists()
    valid_token_new = session_user.exists()
    session_user = session_user.get()

    if (not session_user.locked and not session_user.session_two_steps and
            valid_token_origin and valid_token_new):
        confirm = response_user = request.GET.get('confirm', None)
        if confirm == 'YES':
            session_user.session_two_steps = True
            response = {'valid': True}
        else:
            session_user.locked = True
        session_user.save()
        publish(f"session_confirm.{session_user.user.id}", {})
        publish(f'success_session_redirect.{session_user.token}',
                {'success': response["valid"]})

    return JsonResponse(response)

@login_required
def view_waiting_page(request):
    return render(request, 'user/waiting_page.html')

@login_required
def view_has_not_permits(request):
    return render(request, 'user/has_not_permits.html')

class UserAPI(APIView):
    serializers = UserSerializer

    def get(seft, request, format=None):
        list = User.objects.all()
        response = seft.serializers(list, many=True)

        return HttpResponse(json.dumps(response.data), content_type='application/json')


import numpy as np
import numpy.random as npr
from math import pi
from hypothesis.strategies import integers, floats, composite, tuples, lists

# In this file we define a number of strategies representing
# particular data types. Defining them here in one place will
# help keep ourselves consistent.

# A "real" number in the range of +- 1 million
real = floats(min_value=-1e6, max_value=1e6)

# A "radial" number - the R in polar coordinates
R = floats(min_value=0.1, max_value=1e6)

# An angle, the T in polar coordinates
T = floats(min_value=0, max_value=(2*pi - 0.0001))

# A cylindrical coordinate - for mesh gen reasons we represent them as (T, Z, R)
cylin = tuples(T, real, R)
cylindrical = lists(cylin, min_size=4, max_size=512)

cart = tuples(real, real, real)
cartesian = lists(cart, min_size=4, max_size=512)

# A "size" a non negative integer representing the length of arrays etc.
size = integers(min_value=1, max_value=512)

# A strategy representing an arbitrary array of faces
@composite
def faces(draw):
    num = draw(size)
    return npr.randint(1, 256, size=(num, 4))


from django.urls import path, include

from .views import (
                    CompanyListView,
                    CompanyView,
                    CompanyEmployeeListView,
                    CompanyEmployeeView,
                    EmployeeAssetView,
                    CompanyAssetListView,
                    CompanyAssetView,
                    )

urlpatterns = [
    #All companies name
    path('', CompanyListView.as_view(), name= "company_list"),
    #Input exact company name in url and see individual company information
    path('<company_name>/', CompanyView.as_view(), name= "company_view"),
    #Companies assets
    path('<int:company_id>/asset/', CompanyAssetListView.as_view(), name= "company_assets"),
    #Individual companies asset
    path('<int:company_id>/asset/<int:pk>', CompanyAssetView.as_view(), name= "company_assets"),
    #Individual companies all employees
    path('<int:company_id>/employee/', CompanyEmployeeListView.as_view(), name= "employee_list"),
    #Individual companies individual employee details
    path('<int:company_id>/employee/<int:pk>/', CompanyEmployeeView.as_view(), name= "employee_view"),
    #asset assigned to the employee through company
    path('<int:company_id>/asset-assign/', EmployeeAssetView.as_view(), name= "asset-assign"),

]

#for login
urlpatterns += [
    path('api-auth/', include('rest_framework.urls')),
]


from typing import Union, List

from Helper import SYMBOLS, formatDateGerman, CouponType, formatPrice
from UtilsCouponsDB import Coupon, CouponSortMode, CouponSortModes

class CouponCategory:
    """ Takes a list/dict of given coupons and creates a 'category' container of it containing easily accessible fields with useful information about it. """

    def __init__(self, coupons: Union[CouponType, int, dict, List], title: Union[str, None] = None):
        self.titleOverride = title
        self.coupons = None
        self.mainCouponType = None
        self.couponTypes = set()
        self.displayDescription = False  # Display description for this category in bot menu?
        self.expireDatetimeLowest = None
        self.expireDatetimeHighest = None
        self.numberofCouponsTotal = 0
        self.numberofCouponsHidden = 0
        self.numberofCouponsEatable = 0
        self.numberofCouponsEatableWithPrice = 0
        self.numberofCouponsNew = 0
        self.numberofCouponsWithFriesAndDrink = 0
        self.numberofVeggieCoupons = 0
        self.totalPrice = 0
        if isinstance(coupons, dict):
            self.coupons = list(coupons.values())
        elif isinstance(coupons, list):
            self.coupons = coupons
        if self.coupons is not None:
            for coupon in self.coupons:
                self.updateWithCouponInfo(coupon)
            if len(self.couponTypes) == 1:
                for first_item in self.couponTypes:
                    self.mainCouponType = first_item
                    break
            else:
                self.mainCouponType = None
        else:
            self.mainCouponType = coupons
        if self.mainCouponType is None:
            self.nameSingular = "Coupon"
            self.namePlural = "Alle Coupons"
            self.namePluralWithoutSymbol = "Alle Coupons"
            self.description = "Coupons mehrerer Kategorien"
        elif self.mainCouponType == CouponType.APP:
            self.nameSingular = "App Coupon"
            self.namePlural = "App Coupons"
            self.namePluralWithoutSymbol = "App Coupons"
            self.description = "Coupons aus der BK App"
        elif self.mainCouponType == CouponType.PAPER:
            self.nameSingular = "Papiercoupon"
            self.namePlural = SYMBOLS.NEWSPAPER + "Papiercoupons"
            self.namePluralWithoutSymbol = "Papiercoupons"
            self.description = "Coupons der Papier Couponbögen"
        elif self.mainCouponType == CouponType.PAPER_UNSAFE:
            self.nameSingular = "Papiercoupon (unsafe)"
            self.namePlural = SYMBOLS.NEWSPAPER + "Papiercoupons (unsafe)"
            self.namePluralWithoutSymbol = "Papiercoupons (unsafe)"
            self.description = "Coupons aus der \"Coupons2\" API, die keinem anderen Coupon-Typen zugewiesen werden konnten."
        elif self.mainCouponType == CouponType.ONLINE_ONLY:
            self.nameSingular = "Online Only"
            self.namePlural = "Online only"
            self.namePluralWithoutSymbol = "Online Only"
            self.description = "Coupons, die mit hoher Wahrscheinlichkeit nur online oder am Terminal bestellbar sind"
        elif self.mainCouponType == CouponType.ONLINE_ONLY_STORE_SPECIFIC:
            self.nameSingular = "Online only (store specific)"
            self.namePlural = "Online only (store specific)"
            self.namePluralWithoutSymbol = "Online only (store specific)"
            self.description = "Coupons, die nur in bestimmten# Filialen gültig sind"
        elif self.mainCouponType == CouponType.SPECIAL:
            self.nameSingular = "Special Coupon"
            self.namePlural = SYMBOLS.GIFT + "Special Coupons"
            self.namePluralWithoutSymbol = "Special Coupons"
            self.description = "Diese Coupons sind evtl. nicht in allen Filialen einlösbar!"
        elif self.mainCouponType == CouponType.PAYBACK:
            self.nameSingular = "Payback Coupon"
            self.namePlural = SYMBOLS.PARK + "ayback Coupons"
            self.namePluralWithoutSymbol = "Payback Coupons"
            self.description = "Payback Papiercoupons"
        else:
            self.nameSingular = "Unbekannt"
            self.namePlural = "Unbekannt"
            self.namePluralWithoutSymbol = "Unbekannt"

    def getTotalPrice(self) -> float:
        return self.totalPrice

    def getNumberofCouponsEatableWithPrice(self) -> int:
        return self.numberofCouponsEatableWithPrice

    def getNumberofCouponsEatableWithoutPrice(self) -> int:
        return self.numberofCouponsEatable - self.numberofCouponsEatableWithPrice

    def setNumberofCouponsEatableWithPrice(self, newNumber: int):
        self.numberofCouponsEatableWithPrice = newNumber

    def setTotalPrice(self, newPrice: float):
        self.totalPrice = newPrice

    def isEatable(self) -> bool:
        """ Typically all coupon categories except Payback coupons will return True here as they do contain at least one item that is considered 'eatable'. """
        if self.numberofCouponsEatable > 0:
            return True
        else:
            return False

    def isVeggie(self):
        """ Returns True if all coupons in this categorie are veggie. """
        if len(self.couponTypes) == 1 and self.mainCouponType == CouponType.PAYBACK:
            # Only Payback coupons in this category -> Technically veggie but logically not ;)
            return False
        elif self.numberofCouponsTotal > 0 and self.numberofCouponsTotal == self.numberofVeggieCoupons:
            return True
        else:
            return False

    def isEligibleForDuplicateRemoval(self):
        if self.mainCouponType == CouponType.PAYBACK:
            return False
        else:
            return True

    def isEligableForSort(self):
        if len(self.getSortModes()) > 1:
            return True
        else:
            return False

    def getSortModes(self) -> List:
        """ Returns all SortModes which make sense for this set of coupons. """
        if self.coupons is None:
            return []
        sortModes = []
        if self.totalPrice > 0:
            sortModes.append(CouponSortModes.PRICE)
            sortModes.append(CouponSortModes.PRICE_DESCENDING)
        if self.numberofCouponsTotal != self.numberofCouponsWithFriesAndDrink:
            sortModes.append(CouponSortModes.MENU_PRICE)
        if len(self.couponTypes) > 1:
            sortModes.append(CouponSortModes.TYPE_MENU_PRICE)
        return sortModes

    def allowsSortMode(self, sortModeToCheckFor: CouponSortMode) -> bool:
        """ Checks if desired sortMode is currently allowed. """
        sortModes = self.getSortModes()
        for possibleSortMode in sortModes:
            if possibleSortMode == sortModeToCheckFor:
                return True
        return False

    def getNextPossibleSortMode(self, sortMode: CouponSortMode) -> CouponSortMode:
        possibleSortModes = self.getSortModes()
        for possibleSortMode in possibleSortModes:
            if possibleSortMode.getSortCode() > sortMode.getSortCode():
                return possibleSortMode
        # Fallback/Rollover to first sort
        return possibleSortModes[0]

    def getSortModeCode(self, desiredSortMode: CouponSortMode, fallbackSortMode: CouponSortMode) -> CouponSortMode:
        if self.allowsSortMode(desiredSortMode):
            return desiredSortMode
        else:
            return fallbackSortMode

    def getCategoryInfoText(self) -> str:
        if self.titleOverride is not None:
            text = '[{couponCount} Stück] {couponCategoryName}'
            couponCategoryName = self.titleOverride
        else:
            # Auto determine result
            if self.mainCouponType == CouponType.APP and self.numberofCouponsTotal == self.numberofCouponsHidden:
                # Only hidden App-coupons
                text = '[{couponCount} Stück] {couponCategoryName} versteckte'
            elif self.numberofCouponsWithFriesAndDrink == 0 and self.numberofCouponsEatable > 0:
                text = '[{couponCount} Stück] {couponCategoryName} ohne Menü'
            else:
                text = '[{couponCount} Stück] {couponCategoryName}'
            if self.numberofCouponsTotal == 1:
                couponCategoryName = self.nameSingular
            else:
                couponCategoryName = self.namePluralWithoutSymbol
        text = text.format(couponCount=self.numberofCouponsTotal, couponCategoryName=couponCategoryName)
        if self.displayDescription and self.description is not None:
            text += '\n' + self.description
        text += '\n' + self.getExpireDateInfoText()
        return text

    def getExpireDateInfoText(self) -> str:
        if self.expireDatetimeLowest is None or self.expireDatetimeHighest is None:
            return "Gültig bis ??"
        elif self.expireDatetimeLowest == self.expireDatetimeHighest:
            return "Gültig bis " + formatDateGerman(self.expireDatetimeLowest)
        else:
            return "Gültig bis min " + formatDateGerman(self.expireDatetimeLowest) + " max " + formatDateGerman(self.expireDatetimeHighest)

    def getPriceInfoText(self) -> Union[str, None]:
        if self.getNumberofCouponsEatableWithPrice() == 0:
            return None
        text = "Gesamtwert: " + formatPrice(self.getTotalPrice())
        if self.getNumberofCouponsEatableWithoutPrice() > 0:
            text += "*\n* außer " + str(
                self.getNumberofCouponsEatableWithoutPrice()) + " Coupons, deren Preis nicht bekannt ist."
        return text

    def updateWithCouponInfo(self, couponOrCouponList: Union[Coupon, List[Coupon]]):
        """ Updates category with information of given Coupon(s). """
        if isinstance(couponOrCouponList, Coupon):
            couponList = [couponOrCouponList]
        else:
            couponList = couponOrCouponList
        for coupon in couponList:
            self.couponTypes.add(coupon.type)
            self.numberofCouponsTotal += 1
            if coupon.isHidden:
                self.numberofCouponsHidden += 1
            if coupon.isEatable():
                self.numberofCouponsEatable += 1
            if coupon.isNewCoupon():
                self.numberofCouponsNew += 1
            if coupon.isContainsFriesAndDrink():
                self.numberofCouponsWithFriesAndDrink += 1
            if coupon.isVeggie():
                self.numberofVeggieCoupons += 1
            # Update expire-date info
            date = coupon.getExpireDatetime()
            if self.expireDatetimeLowest is None and self.expireDatetimeHighest is None:
                self.expireDatetimeLowest = date
                self.expireDatetimeHighest = date
            else:
                if date < self.expireDatetimeLowest:
                    self.expireDatetimeLowest = date
                elif date > self.expireDatetimeHighest:
                    self.expireDatetimeHighest = date
            if coupon.getPrice() is not None:
                self.setTotalPrice(self.getTotalPrice() + coupon.getPrice())
                self.setNumberofCouponsEatableWithPrice(self.getNumberofCouponsEatableWithPrice() + 1)
        # End of function
        return


# LCM
def lcm(n, m):
    rem = n % m
    if rem == 0:
        return n
    return int(n * lcm(m, rem) / rem)

n = int(input("Enter: "))
m = int(input("Enter: "))

print(lcm(n, m))


import os
import typing

__all__ = ['split_all', 'join_all', 'normpath', 'join', 'sys2vfs']

def split_all(path: str) -> typing.List[str]:
    comps = path.split('/')
    new_comps = []
    for comp in comps:
        if comp in ('', '.'):
            continue

        if comp != '..' or not new_comps or new_comps and new_comps[-1] == '..':
            new_comps.append(comp)
        else:
            if new_comps:
                new_comps.pop()

    return new_comps

def join_all(*parts: str) -> str:
    return '/' + '/'.join(parts)

def sys2vfs(*paths: str) -> str:
    paths = os.path.normpath(os.path.join(*paths)).split(os.path.sep)
    return join_all(*paths)

def normpath(path: str) -> str:
    return join_all(*split_all(path))

def join(a: str, b: str) -> str:
    if a == '/':
        return b
    return a + b


# Import your solution function
from IBMsrc.challenge_submission import compiler_function

# Import submission evaluation and scoring functions
from IBMsrc.challenge_evaluation import evaluate, score

# Possibly useful other helper function
from IBMsrc.challenge_evaluation import qasm_to_dag_circuit, load_coupling, get_layout

# Select the simulation backend to calculate the quantum states resulting from the circuits
# On Windows platform the C++ Simulator is not yet available with pip install
backend = 'local_qiskit_simulator'
#backend = 'local_qasm_simulator'     # uncomment this line if you are a Windows user

# Load example circuits and coupling maps

ex_nr = 5 # examples to add per qubit number. maximum is 10 with the provided circuits
test_circuit_filenames = {}

for i in range(ex_nr):
    test_circuit_filenames['IBMsrc/circuits/random%d_n5_d5.qasm' % i] = get_layout(5)
# for i in range(ex_nr):
#     test_circuit_filenames['IBMsrc/circuits/random%d_n16_d16.qasm' % i] = get_layout(16)
# for i in range(ex_nr):
#     test_circuit_filenames['IBMsrc/circuits/random%d_n20_d20.qasm' % i] = get_layout(20)

# store circuit, coupling map pairs in test_circuits. Circuits are in qasm form.
test_circuits = {}
for filename, cmap in test_circuit_filenames.items():
    with open(filename, 'r') as infile:
        qasm = infile.read()
        test_circuits[filename] = {"qasm": qasm, "coupling_map": cmap}

# result = evaluate(compiler_function, test_circuits, verbose=True, backend = backend)
# print(result)

myres = score(compiler_function, backend = backend)
print("Your compiler scored %6.5f x better \
and was %6.5f x faster than the QISKit reference compiler." % myres)


# This script is used for populating google sheets with
# anomalies list for user input
# Author: atediarjo@gmail.com

import pygsheets as pg
import pandas as pd

gc = pg.authorize(service_file='key/key.json')

anomalies_list = pd.read_csv('input/anomalies_detection.csv')
ever_resolved = pd.read_csv('input/ever_resolved.csv')

# only output confirmed correct as ever resolved, if manual resolution is done but anomalies is still there, then populate google sheets
ever_resolved = ever_resolved[ever_resolved['resolution_status'] == 'confirmed_correct']

other_status = pd.read_csv('input/resolution_other_status.csv')[['resolution_id', 'resolution_status', 'resolver']]

data_for_spreadsheet = anomalies_list[~anomalies_list['resolution_id'].isin(ever_resolved['resolution_id'].unique())]
data_for_spreadsheet = pd.merge(data_for_spreadsheet, other_status, how='left', on = 'resolution_id')
data_for_spreadsheet['resolution_status'] = data_for_spreadsheet['resolution_status_y'].fillna('to_do')
data_for_spreadsheet.drop(['resolution_status_x', 'resolution_status_y'], inplace=True, axis = 1)
data_for_spreadsheet = data_for_spreadsheet[['resolution_id',
                                             'KEY',
                                             'form_id',
                                             'anomalies_id',
                                             'anomalies_description',
                                             'anomalies_reports_to_wid',
                                             'resolver',
                                             'resolution_status']].fillna('')

sh = gc.open('odk_form_anomalies')
wks = sh.worksheet_by_title('anomalies_resolution_tracker')
wks.clear(start='A1', end = 'Y20000')
wks.set_dataframe(data_for_spreadsheet, (0,0))


'''
Segments audio and extracts feature vectors for each segement
Returns a list of those segment objects
Use by calling Segement(filePath)
'''

import numpy as np
import scipy.io.wavfile as sciowav
from pylab import specgram
import sys
import converter
import sh
import os

class Segment(object):
	def __init__(self,seg,timbre,pitches,loudness):
		self.start = seg[0]
		self.end = seg[1]
		self.duration = seg[1]-seg[0]
		self.loudness = loudness
		self.timbre = timbre
		self.pitches = pitches

	def __str__(self):
		return str(self.__dict__)

class Loudness(object):
	def __init__(self,DBSegLoudness,binTime):
		self.start = DBSegLoudness[0]
		self.end = DBSegLoudness[-1]
		self.max = np.max(DBSegLoudness)
		self.max_time = np.argmax(DBSegLoudness)*binTime

	def __str__(self):
		return str(self.__dict__)

# Normalize a convolution kernel to sum to 1
# Prevents scaling of data
def normKernel(kernel):
	total = np.sum(kernel)
	kernel = kernel*(1/total)
	return kernel

# Convert array from decibels to power spectrum
def DBToPow(db):
	db = np.array(db)
	return np.power(10,(db/20))*60

# Convert array from power spectrum to decibels
def powToDB(powData):
	powData = np.array(powData)
	DB = 20*np.log10(powData/60)
	return np.clip(DB,-60,sys.float_info.max)

# Return a slice of power spectrum data for a segment
def getSegData(data,seg,bins):
	start = np.where(bins==seg[0])[0]
	end = np.where(bins==seg[1])[0]
	return data[:,start:end]

# Calculate bark values for frequency bands
def barkScale(f):
	a = 13*np.arctan(0.00076*f)
	b = 3.5*np.arctan(np.power((f/7500),2))
	return np.floor(a+b)

# Calculate the normalization values to mimic human perception of spectrogram frequencies
def DBNorm(f):
	f = f/1000;
	a = -3.64*np.power(f,-0.8)
	b = 6.5*np.exp(-0.6*np.power((f-3.3),2))
	c = np.power(f,4)/1000
	result = a+b-c
	result[0] = -150
	return result

# Normalizes specGram output for human frequency preception
def specGramAdjust(data,freqs):
	DBNorms = DBNorm(freqs)
	DBNorms = np.clip(np.array(DBNorm(freqs).reshape(-1,1)),-60,sys.float_info.max)
	data = powToDB(data)
	return DBToPow(data+DBNorms)

# Normalizes an FFT spectrum for human frequency preception
def FFTAdjust(data,freqs):
	DBNorms = DBNorm(freqs)
	DBNorms = np.clip(np.array(DBNorm(freqs)),-60,sys.float_info.max)
	data = powToDB(data)
	return data+DBNorms

# Evaluates guassian function to find weightings for points
def evalGaussian(vals,sigma):
	num = np.exp(-(np.power(vals,2)/(2*sigma*sigma)))
	denom = np.sqrt(2*np.pi)*sigma
	return num/denom

# If input is not a .wav convert to .wav
# Returns tuple of filePath to analyze and whether or not it converted
def handleConversion(filePath):
	converted = False
	if os.path.splitext(filePath)[-1] != '.wav':
		filePath = converter.Convert(filePath,'.wav')
		converted = True
	return filePath,converted

# Create list of loudness objects for each segment
def loudnessSegments(powerData,bins,length,segments):
	loudnessFeats = []
	binTime = length/bins.size
	for seg in segments:
		segPowerData = getSegData(powerData,seg,bins)
		segLoudness = []
		for i in xrange(segPowerData.shape[1]):
			segLoudness.append(np.mean(segPowerData[:,i]))
		DBSegLoudness = powToDB(segLoudness)
		loudness = Loudness(DBSegLoudness,binTime)
		loudnessFeats.append(loudness)
	return loudnessFeats

# Get timbre vectors for each segment
def timbreSegments(powerData,bins,segments,freqs):
	barks = barkScale(freqs)
	uniqueBarks = np.unique(barks)
	timbreVecs = []
	for seg in segments:
		segPowerData = getSegData(powerData,seg,bins)
		segTimbreVecs = []
		for i in xrange(segPowerData.shape[1]):
			timbreVec = []
			for bark in uniqueBarks:
			    timbreVec.append(segPowerData[:,i][barks == bark].mean())
			segTimbreVecs.append(timbreVec)
		timbreVecs.append(np.mean(segTimbreVecs,0))
	return powToDB(timbreVecs)

# Temporal masking of the audio spectrogram to mimic human perception
# Convolves with a 0.2 sec half-hann window
def tempMask(data,freqs,length,bins):
	dataMasked = np.zeros(data.shape)
	for i in xrange(freqs.size):
		winSize = round(0.4/(length/bins.size))
		hann = np.hanning(winSize)
		halfPoint = np.argmax(hann)
		hann = hann[halfPoint:]
		hann = normKernel(hann)
		dataMasked[i,:] = np.convolve(data[i,:],hann,mode='same')
	return dataMasked

# Segments the audio into subsections for each note or spectral change
# Calculates spectral varience and smooths result with hann win
# Detects peaks in spectral varience as segments
def getSegments(data,freqs,length,bins):
	specVar = np.zeros(data[0,:].shape)
	for i in xrange(freqs.size):
		specVar += np.abs(np.gradient(data[i,:]))
	winSize = round(0.15/(length/bins.size))
	hannWin = np.hanning(winSize)
	specVar = np.convolve(specVar,hannWin,mode='same')
	specVarGrad = np.gradient(specVar)
	onsets = [bins[i] for i in xrange(len(specVarGrad)-1) if specVarGrad[i] > 0 and specVarGrad[i+1] < 0]
	segments = []
	for i,onset in enumerate(onsets):
		if i == 0:
			segments.append([bins[0],onset])
		elif i == len(onsets)-1:
			segments.append([onset,bins[-1]])
		else:
			segments.append([onset,onsets[i+1]])
	return np.array(segments)

# Computes FFT of each segment
def FFTSegment(audio,Fs,seg):
	audioSeg = audio[seg[0]:seg[1]]
	n = len(audioSeg)+8096
	FFTSeg = 2*np.abs(np.fft.rfft(audioSeg,n))
	freqs = np.fft.fftfreq(n,float(1)/Fs)
	halfPoint = np.argmin(freqs)
	freqs = freqs[:halfPoint+1]
	FFTSeg = FFTAdjust(FFTSeg,freqs)
	FFTSeg = DBToPow(FFTSeg)
	FFTSeg = FFTSeg[1:-1]
	return FFTSeg,freqs

# Gets FFT of segment
# Shifts to equal tempermant (piano key) scale
# For every key on scale, computes intensity using
# Guassian windows of the power spectrum of key width
# Folds keys down to 12 note pitch scale
# Normalizes pitch scale to 0 to 1
def pitchSegments(audio,Fs,segments):
	segments = np.round(segments*44100) # Convert to array indices
	pitchScales = []
	avgs = []
	for seg in segments:
		FFTSeg, freqs = FFTSegment(audio,Fs,seg)
		keys = 12*np.log2(freqs/440)+49
		keys = keys[1:-1]
		pitchScale = np.zeros(12)
		for key in xrange(16,100):
			positions = keys[(keys > key-0.5) & (keys < key+0.5)]-key
			FFTVals = FFTSeg[(keys > key-0.5) & (keys < key+0.5)]
			weights = evalGaussian(positions,0.2)
			weights = normKernel(weights)
			index = (key-16)%12
			pitchScale[index] += np.sum(FFTVals*weights)
		pitchScale = pitchScale/np.max(pitchScale)
		pitchScales.append(pitchScale)
	return pitchScales

# Putting everything together
def merge(segs,timbres,pitches,loudness):
	segments = []
	for i in xrange(len(segs)):
		seg = Segment(segs[i],timbres[i],pitches[i],loudness[i])
		segments.append(seg)
	return segments

# Main function gets specgram data, process it for human perception
# Then does feature vector extraction.
def segmentData(filePath):
	filePath,converted = handleConversion(filePath)
	audio = sciowav.read(filePath)
	Fs = audio[0]
	npA = audio[1][:,0]
	length = float(npA.shape[0])/Fs
	powerData, freqs, bins, im = specgram(npA, NFFT=2048, Fs=Fs, noverlap=1536)
	powerData = specGramAdjust(powerData,freqs)
	maskedData = tempMask(powerData,freqs,length,bins)
	segments = getSegments(maskedData,freqs,length,bins)
	timbreSegs = timbreSegments(maskedData,bins,segments,freqs)
	pitchSegs = pitchSegments(npA,Fs,segments)
	loudSegs = loudnessSegments(maskedData,bins,length,segments)
	segments = merge(segments,timbreSegs,pitchSegs,loudSegs)
	if converted:
		converter.Delete(filePath)
	return segments


# -*- coding: utf-8 -*-
# --------------------------------- #
#       Author: Anemily Machina     #
#       Python Version: 3.10.4       #
#       Created on: 2022-01-31      #
# --------------------------------- #

"""
This class builds a word2vec NN object.10

It loads vectors from a given pkl file.

"""

from .context import definition
from definition.sentence_aggregation import SentenceAggregationBlock

import sys

class SentenceAggregationBuilder():

	def __init__(self, *args, **kwargs):

		self.configured = False

	"""
	kwargs
	vector_pkl_file - file where the matrix of vectors is stored
	word2vec_config - parameter dictionary provided for the word2vec NN object from configuration
	"""
	def configure(self, *args, **kwargs):

		#update configuration
		agregation_type = kwargs.pop("aggregation_type")

		if agregation_type not in SentenceAggregationBlock.STRATEGY:
			print(f"Aggregation type not found {agregation_type}")
			sts.exit()

		self.configured = True

		self.SA_params = kwargs
		self.aggregation_function = SentenceAggregationBlock.STRATEGY[agregation_type]

	def build(self):

		if not self.configured:
			print()
			print(f'Builder not configured')
			sys.exit()

		sentence_aggregation_block = SentenceAggregationBlock(**self.SA_params)
		sentence_aggregation_block.set_sentence_aggregation_strategy(self.aggregation_function)

		return sentence_aggregation_block


# x + y + z = 9
# 6x -y + z = 13
# 10x + y -z = 19
def gausseJordan() :
    import numpy
    n = int(input("Enter The Number of varibale: "))
    #print(n)
    A = numpy.zeros((n,n+1))
    X = numpy.zeros(n)
    print("Enter the coefficients of matrix : ")
    for i in range(n):
        for j in range(n+1):
            A[i][j] = float(input('A[' + str(i) + '][' + str(j) + ']' + ' = ') )
    # print("The augumented matrix is : ")
    print(A)
    for i in range(n):
        if A[0][0] == 0.0 :
            print("No solution available Cause Divide by Zero detected.")
            break
        for j in range(n) :
            if i != j :
                ratio = A[j][i] / A[i][i]
                for k in range(n+1) :
                    A[j][k] = A[j][k] - ratio*A[i][k]

    print("The diagonal matrix is : ")
    print(A)
    print("The value of variables are :")
    for i in range(n):
        X[i] = A[i][n] / A[i][i]
    for i in range(n) :
        print('X%d =%0.2f' %(i, X[i]), end='\n')

    # print(X)
gausseJordan()