# -*- coding: utf-8 -*-
"""
Created on Fri May  8 14:17:46 2020

@author: Caterina Brighi
"""

import pandas as pd
import numpy as np
import scipy.stats as stats
import matplotlib.patches as ptch
import matplotlib.pyplot as plt
import os
from pylab import plot, xlim, legend, setp

#%%Functions

# function for setting the colors of the box plots pairs
def setBoxColors(bp):

    '''This function sets the colors of the box plot pairs as blue and red.'''

    setp(bp['boxes'][0], color='blue')
    setp(bp['caps'][0], color='blue')
    setp(bp['caps'][1], color='blue')
    setp(bp['whiskers'][0], color='blue')
    setp(bp['whiskers'][1], color='blue')
    setp(bp['medians'][0], color='blue')

    setp(bp['boxes'][1], color='red')
    setp(bp['caps'][2], color='red')
    setp(bp['caps'][3], color='red')
    setp(bp['whiskers'][2], color='red')
    setp(bp['whiskers'][3], color='red')
    setp(bp['medians'][1], color='red')

def box_plot(dataframe, column_list, ylabel, color, ymin='Auto', ymax='Auto', tick_min='Auto', tick_max='Auto'):

    '''This function generates a box plot of the column_list of the dataframe specified.
    You need to provide ylabel as a string, y_min, y_max, tick_min, tick_max as floats and color as a list of strings.
    The default ymin, ymax, tick_min and tick_max is 'Auto'. '''

    ax.set_ylabel(ylabel, fontsize=15, wrap=True)
    if ymin == 'Auto' and ymax == 'Auto':
        ax.set_ylim(auto=True)
    else:
        ax.set_ylim(bottom=ymin, top=ymax)

    if tick_min == 'Auto' and tick_max == 'Auto':
        bp = dataframe.boxplot(column=column_list, fontsize=15, return_type='both', patch_artist=True, grid=False)
        for i, f in zip(range(len(column_list)), color):
            bp[0].findobj(ptch.Patch)[i].set_facecolor(f)
            bp[0].findobj(ptch.Patch)[i].set_edgecolor("black")
            bp[0].findobj(ptch.Patch)[i].set_linewidth(1.0)
    else:
        ax.yaxis.set_major_locator(plt.MultipleLocator(tick_max))
        ax.yaxis.set_minor_locator(plt.MultipleLocator(tick_min))
        bp = dataframe.boxplot(column=column_list, fontsize=15, return_type='both', patch_artist=True, grid=False)
        for i, f in zip(range(len(column_list)), color):
            bp[0].findobj(ptch.Patch)[i].set_facecolor(f)
            bp[0].findobj(ptch.Patch)[i].set_edgecolor("black")
            bp[0].findobj(ptch.Patch)[i].set_linewidth(1.0)

#%%Statistical analysis

data_supradir = 'Path to data directory' #Set working directory
fileDir = data_supradir

Trial_stats_results = pd.ExcelWriter(fileDir +'Trial_statAnalysis_results.xlsx')

#Calculate volumes ratio statistics
volumes_ratio = pd.read_excel(fileDir + 'Group_stats_results.xlsx', sheet_name='Volumes ratio', index_col='Subject_ID')

#Calculate FET roi on FETPET in FETCT stats
FETroionFETPET = pd.read_excel(fileDir + 'Group_stats_results.xlsx', sheet_name='FETroi_onFETPET', index_col='Subject_ID')

FETroiSUVmean = FETroionFETPET["Mean intensity [SUV]"]
FETroiSUVmean = pd.DataFrame(FETroiSUVmean)
FETroiSUVmean.rename({'Mean intensity [SUV]': 'FET roi on FETPET SUVmean'}, axis=1, inplace=True)

FETroiSUVmax = FETroionFETPET["Max intensity [SUV]"]
FETroiSUVmax = pd.DataFrame(FETroiSUVmax)
FETroiSUVmax.rename({'Max intensity [SUV]': 'FET roi on FETPET SUVmax'}, axis=1, inplace=True)

#Calculate TER roi on TERPET in FETCT stats
TERroionTERPET = pd.read_excel(fileDir + 'Group_stats_results.xlsx', sheet_name='TERroi_onTERPET', index_col='Subject_ID')

TERroiSUVmean = TERroionTERPET["Mean intensity [SUV]"]
TERroiSUVmean = pd.DataFrame(TERroiSUVmean)
TERroiSUVmean.rename({'Mean intensity [SUV]': 'TER roi on TERPET SUVmean'}, axis=1, inplace=True)

TERroiSUVmax = TERroionTERPET["Max intensity [SUV]"]
TERroiSUVmax = pd.DataFrame(TERroiSUVmax)
TERroiSUVmax.rename({'Max intensity [SUV]': 'TER roi on TERPET SUVmax'}, axis=1, inplace=True)

#Calculate TER roi on TERPET in TERCT stats
TERroionTERPETorig = pd.read_excel(fileDir + 'Group_stats_results.xlsx', sheet_name='TERroi_onTERPETorig', index_col='Subject_ID')

TERroiSUVmeanOrig = TERroionTERPETorig["Mean intensity [SUV]"]
TERroiSUVmeanOrig = pd.DataFrame(TERroiSUVmeanOrig)
TERroiSUVmeanOrig.rename({'Mean intensity [SUV]': 'TER roi on TERPETorig SUVmean'}, axis=1, inplace=True)

TERroiSUVmaxOrig = TERroionTERPETorig["Max intensity [SUV]"]
TERroiSUVmaxOrig = pd.DataFrame(TERroiSUVmaxOrig)
TERroiSUVmaxOrig.rename({'Max intensity [SUV]': 'TER roi on TERPETorig SUVmax'}, axis=1, inplace=True)

#Calculate rois TBR stats
TBRval = pd.read_excel(fileDir + 'Group_stats_results.xlsx', sheet_name='TBR', index_col='Subject_ID')
# TBRval = TBRval.drop(columns=['FET stdTBRmean MI', 'FET stdTBRmean CS', 'TER stdTBRmean MI', 'TER stdTBRmean CS'])

#Group patients in PsP group (FET<2) and Recurrent tumour group (FET>2)

def PsP_vs_RT_classification(name_FET_TBRmean_col, name_FET_TBRmeanSTD_col, method):

    '''This function classifies subjects into two groups based on their FET TBRmean value: PsP with FET<2.0 and RT with FET>2.0.
   Generates two dataframes, PsP_df and RT_df, including Subject_ID as index and values of PSMA SUVmean and PSMA SUVmax.'''

    FETTBRmean = TBRval.loc[:,name_FET_TBRmean_col]
    FETTBRmeanSTD = TBRval.loc[:,name_FET_TBRmeanSTD_col]
    x=FETTBRmean+FETTBRmeanSTD
    maskMin = x<2.0
    PsP_group = FETTBRmean[maskMin]
    PsP_array = []
    for i in PsP_group.index:
        PsP_array.append([i, TERroiSUVmean.loc[i,'TER roi on TERPET SUVmean'], TERroiSUVmax.loc[i, 'TER roi on TERPET SUVmax']])
    PsP_array = np.array(PsP_array)
    PsP_df = pd.DataFrame(PsP_array, columns=['Subject_ID', 'PsP PSMA SUVmean '+method, 'PsP PSMA SUVmax '+method])
    PsP_df = PsP_df.set_index('Subject_ID')

    maskMax = x>2.0
    RT_group = FETTBRmean[maskMax]
    RT_array = []
    for i in RT_group.index:
        RT_array.append([i, TERroiSUVmean.loc[i,'TER roi on TERPET SUVmean'], TERroiSUVmax.loc[i, 'TER roi on TERPET SUVmax']])
    RT_array = np.array(RT_array)
    RT_df = pd.DataFrame(RT_array, columns=['Subject_ID', 'RT PSMA SUVmean '+method, 'RT PSMA SUVmax '+method])
    RT_df = RT_df.set_index('Subject_ID')

    return PsP_df, RT_df

PsP_df_MI, RT_df_MI = PsP_vs_RT_classification('FET TBRmean MI', 'FET stdTBRmean MI', 'MI')
PsP_df_CS, RT_df_CS = PsP_vs_RT_classification('FET TBRmean CS', 'FET stdTBRmean CS', 'CS')

PsPRT_dfs = pd.ExcelWriter(fileDir +'PsPvsRT_results.xlsx')
PsP_df_MI.to_excel(PsPRT_dfs, sheet_name='PsP_df_MI', index=True)
RT_df_MI.to_excel(PsPRT_dfs, sheet_name='RT_df_MI', index=True)
PsP_df_CS.to_excel(PsPRT_dfs, sheet_name='PsP_df_CS', index=True)
RT_df_CS.to_excel(PsPRT_dfs, sheet_name='RT_df_CS', index=True)
PsPRT_dfs.save()

PsP_df_MI=pd.read_excel(fileDir + 'PsPvsRT_results.xlsx', sheet_name='PsP_df_MI', index_col='Subject_ID')
RT_df_MI=pd.read_excel(fileDir + 'PsPvsRT_results.xlsx', sheet_name='RT_df_MI', index_col='Subject_ID')
PsP_df_CS=pd.read_excel(fileDir + 'PsPvsRT_results.xlsx', sheet_name='PsP_df_CS', index_col='Subject_ID')
RT_df_CS=pd.read_excel(fileDir + 'PsPvsRT_results.xlsx', sheet_name='RT_df_CS', index_col='Subject_ID')

#Calculate FETminCE roi on TERPET in FETCT stats
FETminCEonTERPET = pd.read_excel(fileDir + 'Group_stats_results.xlsx', sheet_name='FETminCE_onTERPET', index_col='Subject_ID')

FETminCESUVmean = FETminCEonTERPET["Mean intensity [SUV]"]
FETminCESUVmean = pd.DataFrame(FETminCESUVmean)
FETminCESUVmean.rename({'Mean intensity [SUV]': 'FETminCE on TERPET SUVmean'}, axis=1, inplace=True)

FETminCESUVmax = FETminCEonTERPET["Max intensity [SUV]"]
FETminCESUVmax = pd.DataFrame(FETminCESUVmax)
FETminCESUVmax.rename({'Max intensity [SUV]': 'FETminCE on TERPET SUVmax'}, axis=1, inplace=True)

#Calculate FETmaxCE roi on TERPET in FETCT stats
FETmaxCEonTERPET = pd.read_excel(fileDir + 'Group_stats_results.xlsx', sheet_name='FETmaxCE_onTERPET', index_col='Subject_ID')

FETmaxCESUVmean = FETmaxCEonTERPET["Mean intensity [SUV]"]
FETmaxCESUVmean = pd.DataFrame(FETmaxCESUVmean)
FETmaxCESUVmean.rename({'Mean intensity [SUV]': 'FETmaxCE on TERPET SUVmean'}, axis=1, inplace=True)

FETmaxCESUVmax = FETmaxCEonTERPET["Max intensity [SUV]"]
FETmaxCESUVmax = pd.DataFrame(FETmaxCESUVmax)
FETmaxCESUVmax.rename({'Max intensity [SUV]': 'FETmaxCE on TERPET SUVmax'}, axis=1, inplace=True)

#Put all rois stats together into a final df
final = pd.concat([volumes_ratio, FETroiSUVmean, FETroiSUVmax, TERroiSUVmean, TERroiSUVmax, TERroiSUVmeanOrig, TERroiSUVmaxOrig, TBRval,
                   PsP_df_MI, RT_df_MI, PsP_df_CS, RT_df_CS, FETminCESUVmean, FETminCESUVmax, FETmaxCESUVmean, FETmaxCESUVmax], axis=1)
final_stats = final.describe()
final_stats.to_excel(Trial_stats_results, sheet_name='Trial stats', index=True)

#Perform statistical tests

storage = []
listnames = [['FET TBRmean MI', 'TER TBRmean MI'], ['FET TBRmax MI', 'TER TBRmax MI'],['FET TBRmean CS', 'TER TBRmean CS'],
             ['FET TBRmax CS', 'TER TBRmax CS'],['FET TBRmean MI', 'FET TBRmean CS'],['FET TBRmax MI', 'FET TBRmax CS'],
             ['TER TBRmean MI', 'TER TBRmean CS'],['TER TBRmax MI', 'TER TBRmax CS'],
             ['PsP PSMA SUVmean MI', 'RT PSMA SUVmean MI'],
             ['PsP PSMA SUVmax MI', 'RT PSMA SUVmax MI'],
             ['PsP PSMA SUVmean CS', 'RT PSMA SUVmean CS'],
             ['PsP PSMA SUVmax CS', 'RT PSMA SUVmax CS'],
             ['FETminCE on TERPET SUVmean', 'FETmaxCE on TERPET SUVmean'],
             ['FETminCE on TERPET SUVmax', 'FETmaxCE on TERPET SUVmax']]

for i in listnames:
    if i in listnames[8:]:
        t, p = stats.mannwhitneyu(final[i[0]].dropna(), final[i[1]].dropna())
    elif i in listnames[:8]:
        t, p = stats.wilcoxon(final[i[0]], final[i[1]])

    if p < 0.0001:
        ast = '****'
    elif p < 0.001:
        ast = '***'
    elif p < 0.01:
        ast = '**'
    elif p < 0.05:
        ast = '*'
    else:
        ast = 'ns'

    storage.append([t,p,ast])

storage = np.array(storage)

statistical_tests = pd.DataFrame(storage, index=['FET vs TER TBRmean MI', 'FET vs TER TBRmax MI', 'FET vs TER TBRmean CS', 'FET vs TER TBRmax CS',
                                                 'FET TBRmean MI vs CS', 'FET TBRmax MI vs CS', 'TER TBRmean MI vs CS', 'TER TBRmax MI vs CS',
                                                 'PSMA SUVmean PsP vs RT MI', 'PSMA SUVmax PsP vs RT MI',
                                                 'PSMA SUVmean PsP vs RT CS', 'PSMA SUVmax PsP vs RT CS',
                                                 'FETmaxCE vs FETminCE TER SUVmean', 'FETmaxCE vs FETminCE TER SUVmax'],
                                 columns=['test stats', 'p value', 'significance'])

statistical_tests.to_excel(Trial_stats_results, sheet_name='Statistical tests', index=True)

Trial_stats_results.save()

#%%Plotting graphs analysis

#Make a directory for the plots
os.mkdir(fileDir +'/Analysis Results Plots')

#Set paths to plot dir
plot_dir = fileDir +'/Analysis Results Plots'

#Box plot tumour volume ratios
fig, ax = plt.subplots()
box_plot(final, ['TER tum volume/FET tum volume'], 'PSMA/FET tumour volumes [a.u.]', 'cyan', ymin=0.0, ymax=1.5, tick_min=0.1, tick_max=0.5)
plt.savefig(plot_dir + '/VolumesRatio.png')
plt.close()

#Box plot SUVmean of FET and TER rois
xtick_labels = ['FET', 'PSMA']
fig, ax = plt.subplots()
box_plot(final, ['FET roi on FETPET SUVmean', 'TER roi on TERPET SUVmean'], 'SUVmean [g mL\u207b\u00b9]', ['magenta','magenta'], ymin=0.0, ymax=6.0, tick_min=0.5, tick_max=1.0)
ax.set_xticklabels(xtick_labels, rotation=0, fontsize=15)
plt.savefig(plot_dir + '/SUVmeanFETTERrois.png')
plt.close()

#Box plot SUVmax of FET and TER rois
fig, ax = plt.subplots()
box_plot(final, ['FET roi on FETPET SUVmax', 'TER roi on TERPET SUVmax'], 'SUVmax [g mL\u207b\u00b9]', ['lightgreen','lightgreen'], ymin=0.0, ymax=12.0, tick_min=0.5, tick_max=1.0)
ax.set_xticklabels(xtick_labels, rotation=0, fontsize=15)
plt.savefig(plot_dir + '/SUVmaxFETTERrois.png')
plt.close()

#Box plot TBRmean MI
fig, ax = plt.subplots()
box_plot(final, ['FET TBRmean MI', 'TER TBRmean MI'], 'TBRmean MI [a.u.]', ['orange','orange'], tick_min=1.0, tick_max=5.0)
ax.set_xticklabels(xtick_labels, rotation=0, fontsize=15)
plt.savefig(plot_dir + '/TBRmeanMI.png')
plt.close()

#Box plot TBRmax MI
fig, ax = plt.subplots()
box_plot(final, ['FET TBRmax MI', 'TER TBRmax MI'], 'TBRmax MI [a.u.]', ['blue','blue'], tick_min=1.0, tick_max=5.0)
ax.set_xticklabels(xtick_labels, rotation=0, fontsize=15)
plt.savefig(plot_dir + '/TBRmaxMI.png')
plt.close()

#Box plot TBRmean CS
fig, ax = plt.subplots()
box_plot(final, ['FET TBRmean CS', 'TER TBRmean CS'], 'TBRmean CS [a.u.]', ['orange','orange'], tick_min=5.0, tick_max=10.0)
ax.set_xticklabels(xtick_labels, rotation=0, fontsize=15)
plt.savefig(plot_dir + '/TBRmeanCS.png')
plt.close()

#Box plot TBRmax CS
fig, ax = plt.subplots()
box_plot(final, ['FET TBRmax CS', 'TER TBRmax CS'], 'TBRmax CS [a.u.]', ['blue','blue'], tick_min=1.0, tick_max=5.0)
ax.set_xticklabels(xtick_labels, rotation=0, fontsize=15)
plt.savefig(plot_dir + '/TBRmaxCS.png')
plt.close()

#Box plot PSMA SUVmean PsP vs RT MI
xtick_labels = ['PsP', 'RT']
fig, ax = plt.subplots()
box_plot(final, ['PsP PSMA SUVmean MI', 'RT PSMA SUVmean MI'], 'PSMA SUVmean [g mL\u207b\u00b9]',['yellow','yellow'], tick_min=0.1, tick_max=0.5)
ax.set_xticklabels(xtick_labels, rotation=0, fontsize=15)
plt.savefig(plot_dir + '/SUVmean_PsPvsRT_MI.png')
plt.close()

#Box plot PSMA SUVmax PsP vs RT MI
xtick_labels = ['PsP', 'RT']
fig, ax = plt.subplots()
box_plot(final, ['PsP PSMA SUVmax MI', 'RT PSMA SUVmax MI'], 'PSMA SUVmax [g mL\u207b\u00b9]',['green','green'], tick_min=0.5, tick_max=1.0)
ax.set_xticklabels(xtick_labels, rotation=0, fontsize=15)
plt.savefig(plot_dir + '/SUVmax_PsPvsRT_MI.png')
plt.close()

#Box plot PSMA SUVmean PsP vs RT CS
xtick_labels = ['PsP', 'RT']
fig, ax = plt.subplots()
box_plot(final, ['PsP PSMA SUVmean CS', 'RT PSMA SUVmean CS'], 'PSMA SUVmean [g mL\u207b\u00b9]',['yellow','yellow'], tick_min=0.1, tick_max=0.5)
ax.set_xticklabels(xtick_labels, rotation=0, fontsize=15)
plt.savefig(plot_dir + '/SUVmean_PsPvsRT_CS.png')
plt.close()

#Box plot PSMA SUVmax PsP vs RT CS
xtick_labels = ['PsP', 'RT']
fig, ax = plt.subplots()
box_plot(final, ['PsP PSMA SUVmax CS', 'RT PSMA SUVmax CS'], 'PSMA SUVmax [g mL\u207b\u00b9]',['green','green'], tick_min=0.5, tick_max=1.0)
ax.set_xticklabels(xtick_labels, rotation=0, fontsize=15)
plt.savefig(plot_dir + '/SUVmax_PsPvsRT_CS.png')
plt.close()

#Box plot PSMA SUVmean CE recurrent tum vs CE CR changes
xtick_labels = ['CE recurrent tumour', 'CE CR changes']
fig, ax = plt.subplots()
box_plot(final, ['FETmaxCE on TERPET SUVmean', 'FETminCE on TERPET SUVmean'], 'PSMA SUVmean [g mL\u207b\u00b9]', ['red','red'], tick_min=0.1, tick_max=0.5)
ax.set_xticklabels(xtick_labels, rotation=0, fontsize=15)
plt.savefig(plot_dir + '/SUVmean_CEtest.png')
plt.close()

#Box plot PSMA SUVmax CE recurrent tum vs CE CR changes
xtick_labels = ['CE recurrent tumour', 'CE CR changes']
fig, ax = plt.subplots()
box_plot(final, ['FETmaxCE on TERPET SUVmax', 'FETminCE on TERPET SUVmax'], 'PSMA SUVmax [g mL\u207b\u00b9]', ['violet','violet'], tick_min=0.5, tick_max=1.0)
ax.set_xticklabels(xtick_labels, rotation=0, fontsize=15)
plt.savefig(plot_dir + '/SUVmax_CEtest.png')
plt.close()

#TBRmean MI vs CS comparison
FET = [final['FET TBRmean MI'].tolist(), final['FET TBRmean CS'].tolist()]
PSMA = [final['TER TBRmean MI'].tolist(), final['TER TBRmean CS'].tolist()]

fig, (ax, ax2) = plt.subplots(2, 1, sharex=True)
#ax.set_ylabel('TBRmean [a.u.]', fontsize=12, wrap=True)
# first boxplot pair
bp = ax2.boxplot(FET, positions = [1, 2], widths = 0.6)
setBoxColors(bp)
# second boxplot pair
bp1 = ax.boxplot(PSMA, positions = [4, 5], widths = 0.6)
setBoxColors(bp1)

# zoom-in / limit the view to different portions of the data
ax2.set_ylim(1.0, 4.0)  # outliers only
ax.set_ylim(5, 85)  # most of the data

# hide the spines between ax and ax2
ax.spines['bottom'].set_visible(False)
ax2.spines['top'].set_visible(False)
ax.xaxis.tick_top()
ax.tick_params(labeltop=False)  # don't put tick labels at the top
ax2.xaxis.tick_bottom()

ax2.set_ylabel('TBRmean [a.u.]', fontsize=12)
ax2.yaxis.set_label_coords(0.05, 0.5, transform=fig.transFigure)

## set axes limits and labels
xlim(0,6)
#ylim(0,80)
ax2.set_xticklabels(['FET', 'PSMA'], fontsize=12)
ax2.set_xticks([1.5, 4.5])
#ax.yaxis.set_major_locator(plt.MultipleLocator(10.0))
#ax.yaxis.set_minor_locator(plt.MultipleLocator(5.0))

d = .015  # how big to make the diagonal lines in axes coordinates
# arguments to pass to plot, just so we don't keep repeating them
kwargs = dict(transform=ax.transAxes, color='k', clip_on=False)
ax.plot((-d, +d), (-d, +d), **kwargs)        # bottom-left diagonal
ax.plot((1 - d, 1 + d), (-d, +d), **kwargs)  # bottom-right diagonal

kwargs.update(transform=ax2.transAxes)  # switch to the top axes
ax2.plot((-d, +d), (1 - d, 1 + d), **kwargs)  # top-left diagonal
ax2.plot((1 - d, 1 + d), (1 - d, 1 + d), **kwargs)  # top-rig

# draw temporary red and blue lines and use them to create a legend
hB, = plot([1,1],'b-')
hR, = plot([1,1],'r-')
legend((hB, hR),('MI', 'CS'), loc='lower right')
hB.set_visible(False)
hR.set_visible(False)

plt.savefig(plot_dir + '/TBRmeanMIvsCS.png')
plt.close()

#TBRmax MI vs CS comparison
FET = [final['FET TBRmax MI'].tolist(), final['FET TBRmax CS'].tolist()]
PSMA = [final['TER TBRmax MI'].tolist(), final['TER TBRmax CS'].tolist()]

fig, (ax, ax2) = plt.subplots(2, 1, sharex=True)
#ax.set_ylabel('TBRmean [a.u.]', fontsize=12, wrap=True)
# first boxplot pair
bp = ax2.boxplot(FET, positions = [1, 2], widths = 0.6)
setBoxColors(bp)
# second boxplot pair
bp1 = ax2.boxplot(PSMA, positions = [4, 5], widths = 0.6)
setBoxColors(bp1)

bp1 = ax.boxplot(PSMA, positions = [4, 5], widths = 0.6)
setBoxColors(bp1)

# zoom-in / limit the view to different portions of the data
ax2.set_ylim(1.0, 5.0)  # outliers only
ax.set_ylim(5, 50)  # most of the data

# hide the spines between ax and ax2
ax.spines['bottom'].set_visible(False)
ax2.spines['top'].set_visible(False)
ax.xaxis.tick_top()
ax.tick_params(labeltop=False)  # don't put tick labels at the top
ax2.xaxis.tick_bottom()

ax2.set_ylabel('TBRmax [a.u.]', fontsize=12)
ax2.yaxis.set_label_coords(0.05, 0.5, transform=fig.transFigure)

## set axes limits and labels
xlim(0,6)
#ylim(0,80)
ax2.set_xticklabels(['FET', 'PSMA'], fontsize=12)
ax2.set_xticks([1.5, 4.5])
#ax.yaxis.set_major_locator(plt.MultipleLocator(10.0))
#ax.yaxis.set_minor_locator(plt.MultipleLocator(5.0))

d = .015  # how big to make the diagonal lines in axes coordinates
# arguments to pass to plot, just so we don't keep repeating them
kwargs = dict(transform=ax.transAxes, color='k', clip_on=False)
ax.plot((-d, +d), (-d, +d), **kwargs)        # bottom-left diagonal
ax.plot((1 - d, 1 + d), (-d, +d), **kwargs)  # bottom-right diagonal

kwargs.update(transform=ax2.transAxes)  # switch to the top axes
ax2.plot((-d, +d), (1 - d, 1 + d), **kwargs)  # top-left diagonal
ax2.plot((1 - d, 1 + d), (1 - d, 1 + d), **kwargs)  # top-rig

# draw temporary red and blue lines and use them to create a legend
hB, = plot([1,1],'b-')
hR, = plot([1,1],'r-')
legend((hB, hR),('MI', 'CS'), loc='lower right')
hB.set_visible(False)
hR.set_visible(False)

plt.savefig(plot_dir + '/TBRmaxMIvsCS.png')
plt.close()


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

import torch
from torch.utils.data import Dataset, DataLoader
import h5py
import numpy as np
import json

class VideoData(Dataset):
    def __init__(self, mode, split_index):
        self.mode = mode
        self.name = 'tvsum'
        self.datasets = ['../data/SumMe/eccv16_dataset_summe_google_pool5.h5',
                         '../data/TVSum/eccv16_dataset_tvsum_google_pool5.h5']
        self.splits_filename = ['../data/splits/' + self.name + '_splits.json']
        self.splits = []
        self.split_index = split_index # it represents the current split (varies from 0 to 4)
        temp = {}

        if 'summe' in self.splits_filename[0]:
            self.filename = self.datasets[0]
        elif 'tvsum' in self.splits_filename[0]:
            self.filename = self.datasets[1]
        self.video_data = h5py.File(self.filename, 'r')

        with open(self.splits_filename[0]) as f:
            data = json.loads(f.read())
            for split in data:
                temp['train_keys'] = split['train_keys']
                temp['test_keys'] = split['test_keys']
                self.splits.append(temp.copy())

    def __len__(self):
        self.len = len(self.splits[0][self.mode+'_keys'])
        return self.len

    # In "train" mode it returns the features; in "test" mode it also returns the video_name
    def __getitem__(self, index):
        video_name = self.splits[self.split_index][self.mode + '_keys'][index]
        frame_features = torch.Tensor(np.array(self.video_data[video_name + '/features']))
        if self.mode == 'test':
            return frame_features, video_name
        else:
            return frame_features

def get_loader(mode, split_index):
    if mode.lower() == 'train':
        vd = VideoData(mode, split_index)
        return DataLoader(vd, batch_size=1)
    else:
        return VideoData(mode, split_index)

if __name__ == '__main__':
    pass


# class object

import pyclass
import message
user1 = pyclass.User("vinod", "vinod@.com", "vinod", "DevOps Engineer")
user1.get_user_info()

user2 = pyclass.User("albert", "albert.com", "albertpwd", "scientist")
user2.get_user_info()

user3 = pyclass.User("mail.com", "mail", "mail-pwd", "mail-work")
user3.get_user_info()

user_message = message.Post("author message", user1.user_name)
user_message.get_post_message()

albert_user = message.Post("I am albert User", user2.user_name)
albert_user.get_post_message()


from ruamel.yaml import YAML
from ruamel.yaml.scalarstring import PreservedScalarString as pss
from ruamel.yaml.scalarstring import SingleQuotedScalarString

yaml = YAML()
yaml.preserve_quotes = True
with open(
    r'/root/buildfarm_deployment_config/hiera/hieradata/common.yaml', 'r'
) as yfile:
    config = yaml.load(yfile)

config['master::ip'] = '192.168.50.10'
config['repo::ip'] = '192.168.50.11'

with open(
    r'/root/buildfarm_deployment_config/hiera/hieradata/common.yaml', 'w'
) as yfile:
    yaml.dump(config, yfile)


import requests
import base64
import pandas as pd
from core.banner import banner
from core.log import logger
from core.cmdline import args
from core.conf import email,key
from  core.colors import red
from core.lib import ip2cidr,saveContext,readFile
import json
logger=logger()
num = 0
class FofaAPI(object):
    def __init__(self, email, key):
        self.email = email
        self.key = key
        self.base_url = 'https://fofa.so'
        self.search_api_url = '/api/v1/search/all'
        self.login_api_url = '/api/v1/info/my'
        self.get_userinfo()

    def get_userinfo(self):
        try:
            url = '{url}{api}'.format(url=self.base_url, api=self.login_api_url)
            data = {"email": self.email, 'key': self.key}
            req = requests.get(url, params=data)
            return req.json()
        except requests.exceptions.ConnectionError:
            error_msg = {"error": True, "errmsg": "Connect error"}
            return error_msg

    def get_data(self, query_str,size=1000, fields='host,ip,title'):
        try:
            url = '{url}{api}'.format(url=self.base_url, api=self.search_api_url)
            query_str =query_str.encode(encoding="utf-8")
            base64_str=base64.b64encode(query_str)
            data = {'qbase64': base64_str, 'email': self.email, 'key': self.key, 'size': size,
                    'fields': fields}
            req = requests.get(url, params=data, timeout=10)
            return req.json()
        except requests.exceptions.ConnectionError:
            error_msg = {"error": True, "errmsg": "Connect error"}
            return error_msg

if __name__ == '__main__':
    banner()
    ips=[]
    fofa = FofaAPI(email,key)
    if args.cert:
        f = readFile(args.cert)
        domains = f.readlines()
        for domain in domains:
            domain = domain.strip()
            if args.status_code:
                query = 'cert="{}" && type="subdomain" && country="CN" && status_code="{}"'.format(domain,args.status_code)
            else:
                query='cert="{}" && type="subdomain" && country="CN"'.format(domain)
            logger.INFO(red+"Finding.....................................[{}]!".format(domain))
            try:
                result = fofa.get_data(query,args.size, "host,ip,title")
            except:
                logger.INFO("search error!!")
            try:
                for host, ip, title in result['results']:
                    if args.cidr:
                        ips.append(ip2cidr(ip))
                    logger.INFO("Host: {0} IP: {1} Title: [{2}]".format(host, ip, title) + "  is FOUND!")
                    num = num + 1

                if args.cidr:
                    cips = saveContext(ips, domain+"_cidr"+".csv")
                    logger.INFO("C段为: {}".format(cips[1]))
                    logger.INFO("一共查询出{}个C段 ".format(cips[0]) + ",保存为{}......".format(domain+"_cidr"+".csv"))
                logger.INFO("一共导出{0}条数据，保存为{1}........................".format(num,"{}_{}.csv".format(args.status_code,domain) ))
                logger.INFO("保存中.....")
                num=0
                df = pd.DataFrame(columns=['host', 'ip', 'title'], data=result['results'])
                df.to_csv("./{}".format("{}_{}.csv".format(args.status_code,domain)), encoding='utf-8', index=False)
                logger.INFO("保存完毕......")
            except:
                logger.INFO("search [{}] error!! please check your query words!!".format(domain))
    else:
        try:
            result=fofa.get_data(args.query,args.size,"host,ip,title")
        except:
            logger.INFO("search error!!")
        try:
            for host,ip,title in result['results']:
                if args.cidr:
                    ips.append(ip2cidr(ip))
                logger.INFO("Host: {0} IP: {1} Title: [{2}]".format(host,ip,title)+"  is FOUND!")
                num=num+1

            if args.cidr:
                cips=saveContext(ips,args.cidr)
                logger.INFO("C段为: {}".format(cips[1]))
                logger.INFO("一共查询出{}个C段 ".format(cips[0])+",保存为{}......".format(args.cidr))
            logger.INFO("一共导出{0}条数据，保存为{1}.........".format(num,args.report_name))
            logger.INFO("保存中.....")
            df = pd.DataFrame(columns=['host', 'ip','title'], data=result['results'])
            df.to_csv("./{}".format(args.report_name), encoding='utf-8', index=False)
            logger.INFO("保存完毕......")
        except:
            logger.INFO("search [{}] error!! please check your query words!!".format(args.query))


# We're gonna need a helper class that is a bingo board
# it should store an array of numbers, then check if there is a bingo or not

import bingo as bingo
all_lines = []
bingo_boards = []

with open("day4.txt") as file:
    all_lines = file.readlines()

bingo_input = all_lines[0]
print(bingo_input)
input_count = 0
board_input = ""
for i in range(1, len(all_lines)):
    if all_lines[i] == "":
        continue
    else:
        board_input += all_lines[i].rstrip("\n") + " "
        input_count +=1

    if input_count == 6 :
        bingo_boards.append(bingo.Bingo())
        bingo_boards[-1].createBoard(board_input)
        input_count = 0
        board_input = ""

winning_board = -1
winning_number = -1
for number in bingo_input.split(","):
    if(winning_board != -1):
        break
    for i in range(len(bingo_boards)):
        bingo_boards[i].numberCheck(int(number))
        if (bingo_boards[i].checkBingo()):
            print("winner!!")
            winning_board = i
            winning_number = number
            break

# We want to know the final score, so after all numbers called?
if (winning_board ==-1):
    print("No one won")
else:
    print("Winning board: " + str(winning_board))
    print(bingo_boards[winning_board].board[:])
    print("Winning number: " + str(winning_number))
    print("Sum of board:" + str(bingo_boards[winning_board].sumUnmarked()))
    total = int(winning_number) * bingo_boards[winning_board].sumUnmarked()
    print(total)

# Go again but find the last board to win
for i in range(len(bingo_boards)):
    bingo_boards[i].resetMarkers()

boards_won = [0] * len(bingo_boards)
last_board = -1
last_number = -1
winning_total = -1
for number in bingo_input.split(","):
    for i in range(len(bingo_boards)):
        # we skip any board that's already won
        if boards_won[i] == 0:
            bingo_boards[i].numberCheck(int(number))
            if (bingo_boards[i].checkBingo()):
                print("winner!! " + str(i))
                boards_won[i] = 1 # Mark it as won
                last_board = i
                last_number = number
                winning_total = int(last_number) * bingo_boards[last_board].sumUnmarked()

print("Last board: " + str(last_board))
print(bingo_boards[last_board].board[:])
print("Last number: " + str(last_number))
print("Sum of board:" + str(bingo_boards[last_board].sumUnmarked()))
total = int(last_number) * bingo_boards[last_board].sumUnmarked()
print(total)
print(winning_total)


import os
import sys
from pathlib import Path

import matplotlib
import matplotlib.pyplot as plt

import QPOEstimation
from QPOEstimation.get_data import *
from QPOEstimation.likelihood import get_kernel, get_mean_model, get_gp_likelihood
from QPOEstimation.parse import parse_args
from QPOEstimation.prior import get_priors
from QPOEstimation.prior.gp import *
from QPOEstimation.stabilisation import bar_lev
from QPOEstimation.utils import *

if len(sys.argv) > 1:
    parser = parse_args()
    args = parser.parse_args()

    data_source = args.data_source
    run_mode = args.run_mode
    sampling_frequency = args.sampling_frequency
    variance_stabilisation = boolean_string(args.variance_stabilisation)

    hares_and_hounds_id = args.hares_and_hounds_id
    hares_and_hounds_round = args.hares_and_hounds_round

    solar_flare_folder = args.solar_flare_folder
    solar_flare_id = args.solar_flare_id
    grb_id = args.grb_id
    grb_label = args.grb_label
    grb_binning = args.grb_binning
    grb_detector = args.grb_detector
    grb_energy_band = args.grb_energy_band
    magnetar_label = args.magnetar_label
    magnetar_tag = args.magnetar_tag
    bin_size = args.bin_size
    magnetar_subtract_t0 = boolean_string(args.magnetar_subtract_t0)
    magnetar_unbarycentred_time = boolean_string(args.magnetar_unbarycentred_time)

    rebin_factor = args.rebin_factor

    start_time = args.start_time
    end_time = args.end_time

    period_number = args.period_number
    run_id = args.run_id

    candidate_id = args.candidate_id

    polynomial_max = args.polynomial_max
    amplitude_min = args.amplitude_min
    amplitude_max = args.amplitude_max
    offset_min = args.offset_min
    offset_max = args.offset_max
    sigma_min = args.sigma_min
    sigma_max = args.sigma_max
    t_0_min = args.t_0_min
    t_0_max = args.t_0_max
    offset = boolean_string(args.offset)

    min_log_a = args.min_log_a
    max_log_a = args.max_log_a
    min_log_c_red_noise = args.min_log_c_red_noise
    min_log_c_qpo = args.min_log_c_qpo
    max_log_c_red_noise = args.max_log_c_red_noise
    max_log_c_qpo = args.max_log_c_qpo
    minimum_window_spacing = args.minimum_window_spacing

    injection_id = args.injection_id
    injection_mode = args.injection_mode
    injection_file_dir = args.injection_file_dir
    injection_likelihood_model = args.injection_likelihood_model
    base_injection_outdir = args.base_injection_outdir
    normalisation = boolean_string(args.normalisation)

    recovery_mode = args.recovery_mode
    likelihood_model = args.likelihood_model
    background_model = args.background_model
    n_components = args.n_components
    jitter_term = boolean_string(args.jitter_term)

    band_minimum = args.band_minimum
    band_maximum = args.band_maximum

    segment_length = args.segment_length
    segment_step = args.segment_step

    nlive = args.nlive
    sample = args.sample
    use_ratio = boolean_string(args.use_ratio)

    try_load = boolean_string(args.try_load)
    resume = boolean_string(args.resume)
    plot = boolean_string(args.plot)
    suffix = args.suffix
else:
    # matplotlib.use("Qt5Agg")

    data_source = "giant_flare"  # "magnetar_flare_binned"
    run_mode = "select_time"
    sampling_frequency = 64
    variance_stabilisation = False

    hares_and_hounds_id = "455290"
    hares_and_hounds_round = "HH2"

    solar_flare_folder = "goes"
    solar_flare_id = "go1520130512"
    # solar_flare_id = "go1520110314"
    grb_id = "090709A"
    grb_label = ""
    grb_binning = "1s"
    grb_detector = "swift"
    grb_energy_band = "all"

    magnetar_label = "SGR_0501"
    magnetar_tag = "080823478_lcobs"
    bin_size = 0.001
    magnetar_subtract_t0 = True
    magnetar_unbarycentred_time = False
    rebin_factor = 8

    start_time = 101.060 + 20.0
    end_time = 103.060 + 20.0
    # start_time = 138.915 - 0.3 + 20.378
    # end_time = 139.915 + 0.5 + 20.378
    # start_time = 132.3 - 0.5 + 20.0
    # end_time = 132.3 + 0.5 + 20.0
    # start_time = -4.0
    # end_time = 103.0
    # start_time = 88.775 + 20.378
    # end_time = 90.775 + 20.378
    # start_time = -20.0
    # end_time = 20.0
    # start_time = 0 * 1e-3
    # end_time = 5 * 1e-3

    period_number = 14
    run_id = 6

    candidate_id = 5

    injection_id = 1
    base_injection_outdir = "injections/injection"

    offset = False
    polynomial_max = 2
    amplitude_min = None
    amplitude_max = None
    offset_min = None
    offset_max = None
    sigma_min = None
    sigma_max = None
    t_0_min = None
    t_0_max = None

    min_log_a = None
    max_log_a = None
    min_log_c_red_noise = None
    min_log_c_qpo = None
    max_log_c_red_noise = None
    max_log_c_qpo = None
    minimum_window_spacing = 0

    injection_mode = "qpo_plus_red_noise"
    injection_file_dir = "injection_files_pop"
    injection_likelihood_model = "whittle"
    recovery_mode = "qpo_plus_red_noise"
    likelihood_model = "celerite_windowed"
    background_model = "skew_exponential"
    n_components = 1
    jitter_term = False
    normalisation = False

    band_minimum = None
    band_maximum = None
    segment_length = 3.5
    # segment_step = 0.945  # Requires 8 steps
    segment_step = 0.23625  # Requires 32 steps

    sample = "rslice"
    nlive = 1000
    use_ratio = False

    try_load = True
    resume = True
    plot = True

if variance_stabilisation:
    suffix = f"_variance_stabilised"
else:
    suffix = ""
suffix += f"_{n_components}_{background_model}s"

mean_prior_bound_dict = dict(
    amplitude_min=amplitude_min,
    amplitude_max=amplitude_max,
    offset_min=offset_min,
    offset_max=offset_max,
    sigma_min=sigma_min,
    sigma_max=sigma_max,
    t_0_min=t_0_min,
    t_0_max=t_0_max
)

band = f"{band_minimum}_{band_maximum}Hz"

truths = None

recovery_mode_str = recovery_mode
if jitter_term:
    recovery_mode_str += "_jitter"

times, y, yerr, outdir, label = get_data(
    data_source=data_source, band=band, segment_length=segment_length,
    sampling_frequency=sampling_frequency,
    period_number=period_number, run_id=run_id, segment_step=segment_step, start_time=start_time, end_time=end_time,
    run_mode=run_mode, recovery_mode=recovery_mode, recovery_mode_str=recovery_mode_str, likelihood_model=likelihood_model,
    magnetar_label=magnetar_label,  magnetar_tag=magnetar_tag, bin_size=bin_size,
    magnetar_subtract_t0=magnetar_subtract_t0, magnetar_unbarycentred_time=magnetar_unbarycentred_time,
    rebin_factor=rebin_factor, solar_flare_folder=solar_flare_folder, solar_flare_id=solar_flare_id,
    grb_id=grb_id, grb_binning=grb_binning, grb_detector=grb_detector, grb_label=grb_label, grb_energy_band=grb_energy_band,
    injection_file_dir=injection_file_dir, injection_mode=injection_mode, injection_id=injection_id,
    injection_likelihood_model=injection_likelihood_model, hares_and_hounds_id=hares_and_hounds_id,
    hares_and_hounds_round=hares_and_hounds_round, base_injection_outdir=base_injection_outdir
    )

if normalisation:
    y = (y - np.min(y))/(np.max(y) - np.min(y)) * 1
    yerr = yerr/(np.max(y) - np.min(y))

if plot:
    # plt.errorbar(times, y, yerr=yerr, fmt=".k", capsize=0, label="data")
    # plt.errorbar(times, y, yerr=yerr, capsize=0, label="data")
    plt.step(times, y, label="flux")
    # plt.xlabel("time [s]")
    # plt.ylabel("counts/sec/det")
    # plt.title("GRB 090709A Swift-BAT 15-350 keV")
    plt.show()
    plt.clf()

    fs = 1/(times[1] - times[0])

    from scipy.signal import periodogram
    freqs, powers = periodogram(y, fs=fs, window="hann")
    plt.loglog()
    plt.step(freqs[1:], powers[1:])
    # plt.axvline(1/8.1, color="black", linestyle="--", label="QPO?")
    plt.xlabel("frequency [Hz]")
    plt.ylabel("Power [arb. units]")
    plt.legend()
    plt.show()

priors = get_priors(times=times, y=y, yerr=yerr, likelihood_model=likelihood_model, kernel_type=recovery_mode,
                    min_log_a=min_log_a, max_log_a=max_log_a,
                    min_log_c_red_noise=min_log_c_red_noise, max_log_c_red_noise=max_log_c_red_noise,
                    min_log_c_qpo=min_log_c_qpo, max_log_c_qpo=max_log_c_qpo, band_minimum=band_minimum, band_maximum=band_maximum,
                    model_type=background_model, polynomial_max=polynomial_max, minimum_spacing=minimum_window_spacing,
                    n_components=n_components, offset=offset, jitter_term=jitter_term, **mean_prior_bound_dict)

# priors["kernel:terms[0]:log_f"] = bilby.core.prior.Uniform(minimum=np.log(3000), maximum=8.517193191416348, name="kernel:terms[0]:log_f", latex_label="kernel:terms[0]:log_f", unit=None, boundary="reflective")
# suffix += "restricted_freq"

mean_model = get_mean_model(model_type=background_model, n_components=n_components, y=y, offset=offset,
                            likelihood_model=likelihood_model)
kernel = get_kernel(kernel_type=recovery_mode, jitter_term=jitter_term)
likelihood = get_gp_likelihood(mean_model=mean_model, kernel=kernel, times=times, y=y, yerr=yerr,
                               likelihood_model=likelihood_model)

meta_data = dict(kernel_type=recovery_mode, mean_model=background_model, times=times,
                 y=y, yerr=yerr, likelihood_model=likelihood_model, truths=truths, n_components=n_components,
                 offset=offset, jitter_term=jitter_term)

label += suffix
result = None
if try_load:
    try:
        result = QPOEstimation.result.GPResult.from_json(outdir=f"{outdir}/results", label=label)
        result.outdir = f"{outdir}/results"
    except IOError:
        bilby.utils.logger.info("No result file found. Starting from scratch")
if result is None:
    Path(f"{outdir}/results").mkdir(parents=True, exist_ok=True)
    result = bilby.run_sampler(likelihood=likelihood, priors=priors, outdir=f"{outdir}/results",
                               label=label, sampler="dynesty", nlive=nlive, sample=sample,
                               resume=resume, use_ratio=use_ratio, result_class=QPOEstimation.result.GPResult,
                               meta_data=meta_data, save=True, gzip=False, nact=5)

if plot:
    result.plot_all(paper_style=True)

# clean up
for extension in ["_checkpoint_run.png", "_checkpoint_stats.png", "_checkpoint_trace.png", "_checkpoint_trace_unit.png",
                  "_dynesty.pickle", "_resume.pickle", "_result.json.old", "_samples.dat",
                  "_checkpoint_trace_unit.png"]:
    try:
        os.remove(f"{result.outdir}/{label}{extension}")
    except Exception:
        pass


# https://leetcode.com/contest/biweekly-contest-63/problems/kth-smallest-product-of-two-sorted-arrays/
from bisect import bisect_right,insort_left,bisect_left
class Solution(object):
    def kthSmallestProduct(self, nums1, nums2, k):
        """
        :type nums1: List[int]
        :type nums2: List[int]
        :type k: int
        :rtype: int
        """
        def verify(mid):
            cnt =0
            for a in nums1:
                if a > 0 :
                    k = bisect_right(nums2,mid/a)
                    cnt += k
                elif a <0:
                    k = bisect_left(nums2,mid/a)
                    cnt += len(nums2) -k
                else:
                    if mid >=0:
                        cnt += len(nums2)
            return cnt
        res =[]
        for i in nums1:
            res.append(i* nums2[0])
        for j in nums2:
            res.append(j * nums1[0])

        for i in nums1:
            res.append(i* nums2[-1])
        for j in nums2:
            res.append(j * nums1[-1])
        l = min(res)
        r =max(res)
        # l,r = -10**10,10**10 This setting will timeout
        while l < r :
            mid = (l+r)>>1
            if verify(mid) <k:
                l = mid +1
            else:
                r =mid
        return l

re = Solution().kthSmallestProduct(nums1 = [-2,-1,0,1,2], nums2 = [-3,-1,2,4,5], k = 3)
print(re)


import os
import shutil
from torchvision import transforms
import torchvision
import torch
import glob
from PIL import Image
import numpy as np
#import cupy as np
from tqdm import tqdm

def make_dir(path, del_before=False):
    if del_before and os.path.exists(path):
        shutil.rmtree(path)
    if not os.path.exists(path):
        os.mkdir(path)

def save_attack_img(imgs, fn, attack_method, model_name='resnet50', iterate_num=0, output_dir='test_out',
                    dataset='cifar10',device='cuda'):
    trans_image = transforms.Compose([
        transforms.ToPILImage(),
    ])
    if dataset == 'cifar10':
        mean, std = (0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010)
        t_mean = torch.FloatTensor(mean).view(3, 1, 1).expand(3, 32, 32)
        t_std = torch.FloatTensor(std).view(3, 1, 1).expand(3, 32, 32)
    elif dataset == 'mnist':
        mean, std = (0.1307,), (0.3081,)
        t_mean = torch.FloatTensor(mean).view(1, 1, 1).expand(1, 28, 28)
        t_std = torch.FloatTensor(std).view(1, 1, 1).expand(1, 28, 28)
    elif dataset == 'imagenet':
        mean, std = (0.485, 0.456, 0.406), (0.229, 0.224, 0.225)
        t_mean = torch.FloatTensor(mean).view(3, 1, 1).expand(3, 224, 224)
        t_std = torch.FloatTensor(std).view(3, 1, 1).expand(3, 224, 224)
    #t_mean,t_std = t_mean.to(device),t_std.to(device)
    # print(imgs)
    imgs=imgs.cpu()
    for i, image in enumerate(imgs):
        image = image * t_std + t_mean
        image = trans_image(image.cpu())
        if attack_method in ('mifgsm'):
            filename = '_'.join([fn[i], attack_method, model_name, str(iterate_num)]) + '.png'
        else:
            filename = '_'.join([fn[i], attack_method, model_name]) + '.png'
        image.save(os.path.join(output_dir, filename), format='PNG')

def get_dataset(dataset_name, is_train, dataset_dir='./dataset', transform=None):
    if dataset_name == 'cifar10':
        dataset = torchvision.datasets.CIFAR10(root=dataset_dir, download=True, train=is_train,
                                               transform=transform)
    elif dataset_name == 'mnist':
        dataset = torchvision.datasets.MNIST(root=dataset_dir, download=True, train=is_train,
                                             transform=transform)
    elif dataset_name == 'imagenet':
        path = os.path.join(dataset_dir,'imagenet','train' if is_train else 'val')
        dataset = torchvision.datasets.ImageFolder(path,transform=transform)
    return dataset

class OriDataset(torch.utils.data.Dataset):
    def __init__(self, dataset, data_name, transform, dataset_dir):
        self.data_name = data_name
        self.dataset = get_dataset(dataset_name=dataset,is_train=data_name=='train',dataset_dir=dataset_dir,
                                   transform=transform)

    def __getitem__(self, index):
        img = self.dataset[index][0]
        label = self.dataset[index][1]
        fn = '_'.join([self.data_name, str(index)])
        return img, label, fn

    def __len__(self):
        return len(self.dataset)

def get_orig_dataloader(batch_size, dataset='cifar10', dataset_dir='./dataset', is_tran=False,get_train=True):
    transform = get_transform(dataset)
    if get_train:
        trainset = OriDataset(dataset=dataset, data_name='train',
                         transform=get_transform(dataset, is_tran=True) if is_tran else transform,
                         dataset_dir=dataset_dir)
        trainloader = torch.utils.data.DataLoader(trainset, batch_size=batch_size, shuffle=True, num_workers=4)
    testset = OriDataset(dataset=dataset, data_name='test', transform=transform, dataset_dir=dataset_dir)
    testloader = torch.utils.data.DataLoader(testset, batch_size=batch_size, shuffle=False, num_workers=4)
    return (trainloader, testloader) if get_train else testloader

def get_transform(dataset='cifar10', is_tran=False):
    mean, std = None, None
    cifar10_mean, cifar10_std = (0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010)
    mnist_mean, mnist_std = (0.1307,), (0.3081,)
    imagenet_mean, imagenet_std = (0.485, 0.456, 0.406), (0.229, 0.224, 0.225)
    crop = {'mnist': 28, 'cifar10': 32, 'imagenet': 224}
    if dataset == 'cifar10':
        mean, std = cifar10_mean, cifar10_std
    elif dataset == 'mnist':
        mean, std = mnist_mean, mnist_std
    elif dataset == 'imagenet':
        mean, std = imagenet_mean, imagenet_std
    if not is_tran:
        transform = transforms.Compose([
            transforms.Resize((crop[dataset],crop[dataset])),
            transforms.ToTensor(),
            transforms.Normalize(mean, std),
        ])
    else:
        transform = transforms.Compose([
            transforms.Resize((crop[dataset], crop[dataset])),
            transforms.RandomCrop(crop[dataset]),
            transforms.RandomHorizontalFlip(),
            transforms.ToTensor(),
            transforms.Normalize(mean, std),
        ])
    return transform

class FolderDataset(torch.utils.data.Dataset):
    def __init__(self, dataset_folder, dataset, transform=None, root='./dataset', out_noise=False,select_category=-1):
        self.dataset = dataset
        #if dataset != 'imagenet':
        self.trainset = get_dataset(dataset, is_train=True)
        self.testset = get_dataset(dataset, is_train=False)
        #else:
        #    self.testset = get_dataset(dataset, is_train=False)
        imgs = [img_path for img_path in glob.glob(os.path.join(dataset_folder, '*.png'))]
        labels = [-1]*len(imgs)
        for i,img in enumerate(imgs):
            img_set, img_id = os.path.splitext(os.path.basename(img))[0].split('_')[:2]
            labels[i] = self.trainset.targets[int(img_id)] if img_set == 'train' else self.testset.targets[int(img_id)]
        if select_category==-1:
            self.imgs = imgs
            self.labels = labels
        else:
            length = labels.count(select_category)
            self.imgs = [''] * length
            self.labels= [select_category] * length
            l=0
            for i,img in enumerate(imgs):
                if labels[i] == select_category:
                    self.imgs[l]=img
                    l+=1
        self.transform = transform
        self.out_noise = out_noise

    def __getitem__(self, index):
        img_set, img_id = os.path.splitext(os.path.basename(self.imgs[index]))[0].split('_')[:2]
        img = Image.open(self.imgs[index]).convert('RGB' if self.dataset != 'mnist' else 'L')
        if self.out_noise:
            ori = self.trainset[int(img_id)][0] if img_set == 'train' else self.testset[int(img_id)][0]
            if self.dataset=='imagenet':
                ori = ori.resize((224,224),Image.ANTIALIAS)
            img = self.get_noise(img, ori)
        if self.transform:
            img = self.transform(img)

        return img, self.labels[index], os.path.basename(self.imgs[index])

    def get_noise(self, img, ori):
        noise = Image.fromarray(np.array(img) - np.array(ori))
        return noise

    def __len__(self):
        return len(self.imgs)

def get_folder_dataloader(dataset_folder, dataset='cifar10', batch_size=256, root='./dataset', out_noise=False,
                          select_category = -1):
    transform = get_transform(dataset=dataset)
    dataset = FolderDataset(dataset_folder, dataset=dataset, transform=transform, root=root, out_noise=out_noise,
                            select_category=select_category)
    dataloader = torch.utils.data.DataLoader(dataset, batch_size=batch_size, shuffle=False, num_workers=4)
    return dataloader
'''
class MultiDataset(torch.utils.data.Dataset):
    def __init__(self, dataset_folder, dataset='cifar10', transform=None, root='./dataset'):
        if dataset != 'imagenet':
            trainset = get_dataset(dataset,is_train=True)
            #testset = get_dataset(dataset,is_train=False)
        else:
            trainset = get_dataset(dataset,is_train=False)
        imgs_path = [img_path for img_path in glob.glob(os.path.join(dataset_folder, '*.png'))]
        imgs_info = [os.path.splitext(os.path.basename(ip))[0].split('_')[:2] for ip in imgs_path]
        try:
            with tqdm(imgs_path,ncols=64) as tq:
                self.imgs = [Image.open(x).convert('RGB' if dataset != 'mnist' else 'L') for x in tq]
        except KeyboardInterrupt:
            tq.close()
            raise
        tq.close()
        try:
            orig_imgs=[None]*len(trainset)
            orig_label = [0]*len(trainset)
            with tqdm(trainset, ncols=64) as tq:
                #self.imgs+=[t[0] for t in tq]  # + [t[0] for t in testset]
                for i,(img,label) in enumerate(tq):
                    orig_imgs[i]=img
                    orig_label[i]=label
        except KeyboardInterrupt:
            tq.close()
            raise
        tq.close()
        self.imgs+=orig_imgs
        print('imgs_done')
        self.labels = [orig_label[int(img_id)] for (img_set, img_id) in imgs_info] + orig_label
        print('labels done')
        self.fn = ['_'.join(info) for info in imgs_info] + ['_'.join(('train', str(i))) for i in
                                                            range(len(trainset))]  # \
        # +['_'.join(('test',str(i))) for i in range(len(testset))]
        self.transform = transform

    def __getitem__(self, index):
        img = self.imgs[index]
        label = self.labels[index]
        fn = self.fn[index]

        if self.transform:
            img = self.transform(img)
        return img, label, fn

    def __len__(self):
        return len(self.imgs)
'''

def multiple_dataloader(dataset_folder, batch_size=256, dataset='cifar10', is_tran=True, divid=True, root='./dataset'):
    transform = get_transform(dataset=dataset, is_tran=is_tran)
    adv_dataset = FolderDataset(dataset_folder=dataset_folder,dataset=dataset,root=root,out_noise=False,
                                transform=transform)
    ori_dataset = OriDataset(dataset=dataset,data_name='True' if is_tran==True else 'False',
                                        transform=transform,dataset_dir=root)
    mul_dataset = torch.utils.data.ConcatDataset((ori_dataset,adv_dataset))
    if divid:
        train_size = int(0.8 * len(mul_dataset))
        test_size = len(mul_dataset) - train_size
        train_set, test_set = torch.utils.data.random_split(mul_dataset, [train_size, test_size])
        trainloader = torch.utils.data.DataLoader(train_set, batch_size=batch_size, shuffle=True, num_workers=4)
        testloader = torch.utils.data.DataLoader(test_set, batch_size=batch_size, shuffle=False, num_workers=4)
        return trainloader, testloader
    else:
        dataloader = torch.utils.data.DataLoader(mul_dataset, batch_size=batch_size, shuffle=False, num_workers=4)
        return dataloader

class BlankNoiseDataset(torch.utils.data.Dataset):
    def __init__(self, data_name, transform, dataset_dir):
        self.data_name = data_name
        self.dataset = torchvision.datasets.CIFAR10(root=dataset_dir, download=True, train=(data_name == 'train'),
                                                    transform=transform)

    def __getitem__(self, index):
        img = self.dataset[index][0]
        label = self.dataset[index][1]
        fn = '_'.join([self.data_name, str(index)])
        return img, label, fn

    def __len__(self):
        return len(self.dataset)


# TUTORIAL
# https://www.youtube.com/watch?v=hDu8mcAlY4E

import pygame, sys

class Crosshair(pygame.sprite.Sprite):
    def __init__(self, picture_path):
        super().__init__()
        self.image = pygame.image.load(picture_path)
        self.rect = self.image.get_rect()
        self.gunshoot = pygame.mixer.Sound('./assets/Shot.wav')

    def shoot(self):
        self.gunshoot.play()

    def update(self):
        self.rect.center = pygame.mouse.get_pos()

# General Setup
pygame.init()
clock = pygame.time.Clock()

# Game Screen
screen_width = 1920 / 2
screen_height = 1080 / 2
screen = pygame.display.set_mode((screen_width, screen_height))
pygame.display.set_caption('Dianes')
background = pygame.image.load('./assets/space.png')
pygame.mouse.set_visible(False)

# Crosshair
crosshair = Crosshair('./assets/green.png')
crosshair_group = pygame.sprite.Group()
crosshair_group.add(crosshair)

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
        if event.type == pygame.MOUSEBUTTONDOWN:
            crosshair.shoot()

    screen.blit(background, (0,0))
    crosshair_group.draw(screen)
    crosshair_group.update()
    pygame.display.flip()
    clock.tick(60)


import datetime as dt
import OpenGL.GL as GL
import pygame as pg
import pygame.locals as co
from enum import Enum
from typing import Union, Optional
from contextlib import contextmanager
from easygl.structures import Vec4, Vec2
from .events import *

__all__ = [
    'BlendMode',
    'DisplayError',
    'GLWindow',
    'Multisamples',
    'Projection',
]

class DisplayError(Exception):
    pass

class Multisamples(Enum):
    none = 0
    double = 1
    triple = 2
    quad = 3

class BlendMode(Enum):
    none = 0
    add = 1
    alpha = 2
    multiply = 3

class Projection(Enum):
    custom = 0
    ortho_up = 1
    ortho_down = 2

class GLWindow(object):

    _current = None    # type: GLWindow

    def __init__(self, width, height, title, multisamples, blendmode, projection, **kwargs):
        # type: (int, int, str, Multisamples, BlendMode, Projection) -> None
        if self.__class__._current is not None:
            raise DisplayError("Display already initialized. Call reset() method to change settings.")

        color = kwargs.get('clear_color', (0., 0., 0., 1.))
        size = width, height
        flags = co.OPENGL

        flags |= co.RESIZABLE if kwargs.get('resizable', False) else 0
        flags |= co.DOUBLEBUF if kwargs.get('doublebuf', False) else 0
        flags |= co.FULLSCREEN if kwargs.get('fullscreen', False) else 0
        flags |= co.HWSURFACE if kwargs.get('hwsurface', False) else 0

        pg.init()
        if multisamples is not Multisamples.none:
            samples = {
                Multisamples.double: 2,
                Multisamples.triple: 3,
                Multisamples.quad: 4
            }.get(multisamples, 2)
            pg.display.gl_set_attribute(pg.GL_MULTISAMPLESAMPLES, samples)

        surface = pg.display.set_mode(size, flags)
        # print(surface)
        width, height = surface.get_size()
        pg.display.set_caption(title, title)

        if multisamples is not Multisamples.none:
            GL.glEnable(GL.GL_MULTISAMPLE)
        GL.glEnable(GL.GL_BLEND)
        GL.glClearColor(*color)
        GL.glViewport(0, 0, width, height)

        self._handling_input = False
        self._rendering = False
        self._close_request = False
        self._blend_mode = None
        self.blend_mode = blendmode
        self._projection = projection
        self._flip_time = 0
        self._input_time = 0
        self._render_time = 0
        self._delta = 1

    @property
    def projection(self):
        return self._projection

    @property
    def title(self):
        return pg.display.get_caption()

    @title.setter
    def title(self, value):
        pg.display.set_caption(repr(value), repr(value))

    @property
    def should_close(self):
        # type: () -> bool
        return self._close_request

    @property
    def resolution(self):
        # type: () -> tuple
        return pg.display.get_surface().get_size()

    @property
    def width(self):
        # type: () -> int
        return pg.display.get_surface().get_width()

    @property
    def height(self):
        # type: () -> int
        return pg.display.get_surface().get_height()

    @property
    def blend_mode(self):
        # type: () -> BlendMode
        return self._blend_mode

    @blend_mode.setter
    def blend_mode(self, value):
        # type: (BlendMode) -> None
        if value is not self._blend_mode:
            self._blend_mode = value
            if value is BlendMode.none:
                GL.glBlendFunc(GL.GL_ONE, GL.GL_ZERO)

            elif value is BlendMode.add:
                try:
                    GL.glBlendFuncSeparate(GL.GL_SRC_ALPHA, GL.GL_ONE, GL.GL_ONE, GL.GL_ONE)
                except (NameError, Exception):
                    GL.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE)

            elif value is BlendMode.alpha:
                try:
                    GL.glBlendFuncSeparate(
                        GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA, GL.GL_ONE, GL.GL_ONE_MINUS_SRC_ALPHA)
                except (NameError, Exception):
                    GL.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA)

            elif value is BlendMode.multiply:
                try:
                    GL.glBlendFuncSeparate(GL.GL_ALPHA, GL.GL_ONE, GL.GL_ONE, GL.GL_ONE)
                except (NameError, Exception):
                    GL.glBlendFunc(GL.GL_DST_COLOR, GL.GL_ZERO)

    @property
    def mouse_pos(self):
        # type: () -> Vec2
        x, y = pg.mouse.get_pos()
        if self._projection is Projection.ortho_up:
            y = pg.display.get_surface().get_height() - y
        return Vec2(x, y)

    @property
    def mouse_motion(self):
        # type: () -> Vec2
        x, y = pg.mouse.get_rel()
        if self._projection is Projection.ortho_up:
            y = -y
        return Vec2(x, y)

    @property
    def frame_delta(self):
        # type: () -> int
        return self._delta

    @contextmanager
    def input(self, raw=False):
        # type: () -> None
        if self._handling_input:
            raise RuntimeError("Can't nest input processing contexts.")
        self._handling_input = True
        time = pg.time.get_ticks()
        delta = time - self._input_time
        self._input_time = time
        if raw:
            yield delta, pg.event.get(), pg.key.get_pressed(), Vec2(*pg.mouse.get_pos()), Vec2(*pg.mouse.get_rel())
        else:
            events = []
            for event in pg.event.get():
                if event.type == co.ACTIVEEVENT:
                    events.append(Focus(event.gain, event.state, pg.time.get_ticks()))

                elif event.type == co.QUIT:
                    now = dt.datetime.now()
                    ms = pg.time.get_ticks()
                    self._close_request = True
                    events.append(CloseWindow(ms, now))

                elif event.type == co.KEYDOWN:
                    ctrl = event.mod & co.KMOD_ALT != 0
                    shift = event.mod & co.KMOD_SHIFT != 0
                    alt = event.mod & co.KMOD_ALT != 0
                    events.append(KeyDown(event.key, event.unicode, event.mod, ctrl, shift, alt))

                elif event.type == co.KEYUP:
                    ctrl = event.mod & co.KMOD_ALT != 0
                    shift = event.mod & co.KMOD_SHIFT != 0
                    alt = event.mod & co.KMOD_ALT != 0
                    events.append(KeyUp(event.key, event.mod, ctrl, shift, alt))

                elif event.type == co.MOUSEMOTION:
                    height = pg.display.get_surface().get_height()
                    x, y = event.pos
                    mx, my = event.rel
                    if self._projection is Projection.ortho_up:
                        y = height - y
                        my = -my
                    lbutton, mbutton, rbutton = event.buttons
                    events.append(MouseMotion(Vec2(x, y), Vec2(mx, my), lbutton, mbutton, rbutton))

                elif event.type == co.MOUSEBUTTONDOWN:
                    height = pg.display.get_surface().get_height()
                    x, y = event.pos
                    if self._projection is Projection.ortho_up:
                        y = height - y
                    if event.button == 1:
                        events.append(LeftButtonDown(Vec2(x, y), x, y))
                    elif event.button == 2:
                        events.append(MiddleButtonDown(Vec2(x, y), x, y))
                    elif event.button == 3:
                        events.append(RightButtonDown(Vec2(x, y), x, y))
                    elif event.button == 4:
                        events.append(MouseWheelUp(Vec2(x, y), x, y))
                    else:
                        events.append(MouseWheelDown(Vec2(x, y), x, y))

                elif event.type == co.MOUSEBUTTONUP:
                    height = pg.display.get_surface().get_height()
                    x, y = event.pos
                    if self._projection is Projection.ortho_up:
                        y = height - y
                    if event.button == 1:
                        events.append(LeftButtonUp(Vec2(x, y), x, y))
                    elif event.button == 2:
                        events.append(MiddleButtonUp(Vec2(x, y), x, y))
                    else:
                        events.append(RightButtonUp(Vec2(x, y), x, y))

                elif event.type == co.VIDEORESIZE:
                    events.append(VideoResize(event.w, event.h, event.size))

                elif event.type == co.VIDEOEXPOSE:
                    now = dt.datetime.now()
                    ms = pg.time.get_ticks()
                    events.append(VideoExpose(ms, now))

                elif event.type == co.JOYAXISMOTION:
                    events.append(JoyAxis(event.joy, event.axis, event.value))

                elif event.type == co.JOYBALLMOTION:
                    events.append(JoyBall(event.joy, event.ball, event.rel))

                elif event.type == co.JOYHATMOTION:
                    events.append(JoyHat(event.joy, event.hat, event.value))

                elif event.type == co.JOYBUTTONDOWN:
                    events.append(JoyButtonDown(event.joy, event.button))

                elif event.type == co.JOYBUTTONUP:
                    events.append(JoyButtonUp(event.joy, event.button))
            keys = pg.key.get_pressed()
            mouse_pos = Vec2(*pg.mouse.get_pos())
            mouse_rel = Vec2(*pg.mouse.get_rel())
            if self._projection is Projection.ortho_up:
                mouse_pos.y = self.height - mouse_pos.y
                mouse_rel.y = -mouse_rel.y
            yield delta, events, keys, mouse_pos, mouse_rel
        self._handling_input = False

    @contextmanager
    def rendering(self, clear_color=None):
        # type: (Optional[Union[Vec4, tuple, list]]) -> None
        if self._rendering:
            raise RuntimeError("Can't nest GLWindow rendering contexts.")
        self._rendering = True
        time = pg.time.get_ticks()
        delta = time - self._render_time
        self._render_time = time

        yield delta

        pg.display.flip()
        time = pg.time.get_ticks()
        self._delta = time - self._flip_time
        self._flip_time = time
        if clear_color is not None:
            GL.glClearColor(*clear_color)
        GL.glClear(GL.GL_COLOR_BUFFER_BIT)
        self._rendering = False

    def close(self):
        # type: () -> None
        self._close_request = True


import turtle as t

class DividingLine(t.Turtle):
    def __init__(self):
        super().__init__()
        self.hideturtle()
        self.color("white")
        self.penup()
        self.goto(0, 290)
        self.setheading(270)
        while self.ycor() > -290:
            self.fd(10)
            self.pendown()
            self.fd(10)
            self.penup()


import sys

n,m = map(int,sys.stdin.readline().split()) # m 바이트의 메모리를 확보해야한다.

a = list(map(int,sys.stdin.readline().split())) # 활성화 되어있는 앱의 메모리 사용량
# 30 10 20 35 40
b = list(map(int,sys.stdin.readline().split())) # 비활성화 시 발생비용
# 3 0 3 5 4

maximum = sum(b)+1 # 최고 비용에다가 1을 더해서 배열의 길이를 정해놓는다.

dp = [[0] *maximum for _ in range(n+1)] # dp배열을 만들어놓는다.
min = maximum

for i in range(1,n+1): # 첫번째 줄은 전부 0이고 그 뒤에줄부터 생각해야한다.
    for j in range(len(dp[0])): # 가로줄의 길이만큼 비교한다.
        if j < b[i-1]: # 현현재 앱을 비활성화할만큼 cost가 충분하지 않은 경우에
            dp[i][j] = dp[i-1][j]
        else: # 같은 비용 내에서 현재 앱을 끈 뒤와 끄지 않은 비용것을 비교한다.
            dp[i][j] = max(dp[i-1][j], dp[i-1][j-b[i-1]]+a[i-1])
        if dp[i][j] >= m and min > j: # 조건에 맞으면 출력한다.
            min = j

print(min)


#string variable
name = "Ruth Falomir"

#float variable
salary = 123.75

#integer variable
age = 20

#empty variable
message = ""

#boolean variable
isWeatherWarm = True

#print function + concatenation (adding more than one string together)
print("My name is " + name)

#str function (turns integers into strings)
print("My age is " + str(age))

name = "Ruth Falomir"
country = "Mexico"
age = 27
hourlyWage = 20
satisfied = True
dailyWage = hourlyWage * 8

print("My name is " + name)
print("My country is " + country)
print("My age is " + str(age))
print("I make " + str(hourlyWage) + " per hour.")
print("I make " + str(dailyWage) + " a day.")

#f string
print(f"My name is {name} and I am from {country}. I am {age} years old. I earn {hourlyWage} per hour and {dailyWage} a day.")

###LISTS

#create a list
myList = ["Ruth", "Raquel", "Rebeca", "Esther"]
print(myList)

#create empty list
emptyList = []

#add elements to list
myList.append("Mama")
print(myList)

#return the index of the first object with a matching value
print(myList.index("Rebeca"))

#change a specified element within a list at a given index
myList[0] = "Roberta"
print(myList)

#return length of the list
print(len(myList))

#remove a specified objetc from a list
myList.remove("Roberta")
print(myList)

####TUPLES (immutable -cant be changed)

#create a tuple
myTuple = ('Python', 100, 'VBA', False)
print(myTuple)

#print specified items in a tuple using indexing
print(myTuple[0])

#print the length of a tuple using len() function
print(len(myTuple))

####DICTIONARIES

#create a dictionary (key, value)
pacman = {
    'isAlive': True,
    'points': 380,
    'lives': 7
}

#create a dictionary that includes a LIST as one of the variables
actor = {
    "name": "Ana",
    "Age": 20,
    "movies":[
        "Rocky",
        "Rocky 2",
        "Rocky 3"]}
print(f'{actor["name"]} was in {actor["movies"][0]}')

#create a dictionary that contains another DICTIONARY
film = {
    "title":"Interstellar",
    "revenues": {
        "United States":360,
        "China":250,
        "United Kingdom":73
    }
}
print(f'{film["title"]} made {film["revenues"]["United States"]}'" in the US.")

#create a dictionary including a TUPLE
myTuple2 = ("1",99,"Alarm","Dell","Oracle")

myDictionary = {
    "brand":"IBM",
    "listTuple":myTuple2
}

print(myDictionary)


import webapp2
from google.appengine.api import users
from model import CssiUser

class MainHandler(webapp2.RequestHandler):
  def get(self):
    user = users.get_current_user()
    if user:
      signout_link_html = 'sign out' % (
                users.create_logout_url('/'))
      email_address = user.nickname()
      cssi_user = CssiUser.query().filter(CssiUser.email == email_address).get()
      if cssi_user:
        self.response.write(
          "Looks like you're registered. Thanks for using our site!")
      else:
        # Registration form for a first-time visitor:
        self.response.write('''
            Welcome to our site, %s!  Please sign up!

            <form method="post" action="/">
            <input type="text" name="first_name">
            <input type="text" name="last_name">
            <input type="submit">
            </form>
 %s

            ''' % (email_address, signout_link_html))

    else:
      # If the user isn't logged in...
      login_url = users.create_login_url('/')
      login_html_element = 'Sign in' % login_url
      self.response.write('Please log in.
' + login_html_element)
  def post(self):
    user = users.get_current_user()
    # Create a new CSSI user.
    cssi_user = CssiUser(
        first_name=self.request.get('first_name'),
        last_name=self.request.get('last_name'),
        email=user.nickname())
    # Store that Entity in Datastore.
    cssi_user.put()
    # Show confirmation to the user. Include a link back to the index.
    self.response.write('Thanks for signing up, %s!
Home' %
        cssi_user.first_name)

app = webapp2.WSGIApplication([
    ('/', MainHandler),
], debug=True)


import numpy as onp
import jax.numpy as np
from jax import random, jit, vmap, grad, lax, value_and_grad
from jax_md import space, smap, energy, minimize, quantity, simulate
from jax.config import config
config.update("jax_enable_x64", True)
# from jax_md.util import check_kwargs_time_dependence
# from jax.experimental import optimizers
from jax.example_libraries import optimizers
import argparse

INPUT = np.array([6.5, 18.5, 2.45, 1.83], dtype=float)
NUM_PARTICLES = 100
BOX_SIZE = 12.0
STEP_SIZE = 5e-5
TEMPERATURE = 0.1
INIT_STEPS = 30000
BROWNIAN_STEPS = 300
OPT_STEPS = 30
BATCH_SIZE = 9
SAVE_EVERY = 1

key = random.PRNGKey(0)

def get_honeycomb(a0=5.89, a1=17.9, a2=2.49, a3=1.823, a4=1.0, r_cut=1.0):
  """
  Args:
    dr: An ndarray of particle positions.
  Returns:
    Matrix of energies.
  """

  # Potential matching that of the original honeycomb paper
  def eng(r):
    return a4*(5.0*(r**(-12)) - a0*(r**(-10)) + a1*np.exp(-a2*r) - 0.4*np.exp(-40*(r - a3)**2))

  eng_deriv = grad(eng)
  eng_deriv_r_cut = eng_deriv(r_cut)
  eng_r_cut = eng(r_cut)

  def honeycomb(dr, **unused_kwargs):
    # check_kwargs_time_dependence(unused_kwargs)
    r = space.distance(dr)
    power = 1
    # need to flatten out the piece of the potential that blows up so the gradients don't get too large
    # return np.where(r < r_cut, eng_deriv_r_cut*(r - r_cut) + eng_r_cut, eng(r)) # linear for r < r_cut
    return np.where(r < r_cut, (1.0/power)*eng_deriv(r_cut)*(r**power - r_cut**power) + eng(r_cut), eng(r))

  return honeycomb

def honeycomb_pair(metric, species=None, a0=5.89, a1=17.9, a2=2.49, a3=1.823,a4=1.0, r_cut=1.0):
  """Convenience wrapper to compute the honeycomb lattice potential over a system."""

  honeycomb = get_honeycomb(a0=a0, a1=a1, a2=a2, a3=a3, a4=a4, r_cut=r_cut)
  return smap.pair(
      honeycomb,
      metric,
      species=species,
  )

# This is a function that returns a function that is set up for calculating psi_k
def get_psi_k_function(displacement_all, k):

  # return a weight
  def weight(r):
    sigma = 0.2 # 0.05 # CPG: The actual value here will probably need to be played with...
    mu = 1.0
    return np.where(r<1e-7, 0., np.exp(-(r - mu)**2/(2*sigma**2)))

  def weight_with_nnn(r):
    sigma = 0.2
    mu_1 = 1.0
    mu_2 = np.sqrt(3)
    return np.where(r<1e-7, 0., np.exp(-(r - mu_1)**2/(2*sigma**2))) + np.where(r<1e-7, 0., np.exp(-(r - mu_2)**2/(2*sigma**2)))

  # return the exponential part of the order parameter
  i_imaginary = complex(0,1)

  def order(dR_ij):
    epsilon = 0.0001 #avoids nan in derivative at x, y = [0, 0]
    theta_ij = np.arctan2(dR_ij[1] + epsilon, dR_ij[0] + epsilon)
    return np.exp(i_imaginary*k*theta_ij) #Note: for JAX reasons, I had to separate the i_imaginary

  # Map order onto a matrix
  order_all = vmap(vmap(order)) #order_all now applies to every vector in a matrix

  # return the complex psi_k calculated for each particle
  def psi_k_i(R):
    dR = displacement_all(R,R) #This returns a NxNx2 array of vectors between particles that respect periodic boundary conditions
    dRlen = space.distance(dR) #This is a NxN array of distances
    w = weight(dRlen)
    o = order_all(dR)
    wo = np.multiply(w,o)
    return np.sum(wo, axis=0)/np.sum(w,axis=0)
  return psi_k_i

def get_correlation_function(displacement_all, k):
  psi_k_i = get_psi_k_function(displacement_all, k) # length N vector

  def _diagonal_mask(X):
    """Sets the diagonal of a matrix to zero."""
    if X.shape[0] != X.shape[1]:
      raise ValueError(
          'Diagonal mask can only mask square matrices. Found {}x{}.'.format(
              X.shape[0], X.shape[1]))
    if len(X.shape) > 3:
      raise ValueError(
          ('Diagonal mask can only mask rank-2 or rank-3 tensors. '
           'Found {}.'.format(len(X.shape))))
    N = X.shape[0]

    X = np.nan_to_num(X)
    mask = np.float32(1.0) - np.eye(N, dtype=X.dtype)
    if len(X.shape) == 3:
      mask = np.reshape(mask, (N, N, 1))
    return mask * X

  def weight(r):
    sigma = 0.2 # 0.05 # Play with value of sigma
    mu=1.0
    return np.where(r<1e-7, 0., np.exp(-(r - mu)**2/(2*sigma**2)))

  def get_correlation(R):
    psiK = psi_k_i(R)
    corr = np.outer(psiK, np.conj(psiK))

    dR = displacement_all(R,R) # This returns a NxNx2 array of vectors between particles that respect periodic boundary conditions
    dRlen = space.distance(dR)
    w = weight(dRlen)
    w_corr = np.multiply(corr, w)
    return np.sum( _diagonal_mask(w_corr) )

  def corr(R):
    return np.real(get_correlation(R))

  return corr

print("got correlation fn")

def initial_min(a, key):
  '''
  Arguments:
    key: sets up random number generation
    a: vector containing (a0, a1, a2, a3, a4), the parameters of the honeycomb potential
  Returns:
    order_param: average local bond orientational order parameter for k = 3
  '''

  # Set up simulation parameters
  N = NUM_PARTICLES
  displacement, shift = space.periodic(BOX_SIZE)
  dimension = 2
  dt = STEP_SIZE
  T_schedule = TEMPERATURE
  num_steps = INIT_STEPS

  # Set a random initial state
  key, split = random.split(key)
  R = random.uniform(split, (N, dimension), minval=0.0, maxval=BOX_SIZE, dtype=np.float64)

  # Compile the dynamics
  energy_fn = jit(honeycomb_pair(displacement, a0=a[0], a1=a[1], a2=a[2], a3=a[3], r_cut=1.0))
  init, apply = simulate.brownian(energy_fn, shift, dt=dt, T_schedule=T_schedule)

  key, split = random.split(key)
  apply = jit(apply)
  state = init(split, R)

  # Run the brownian dynamics
  do_step = lambda state, t: (apply(state), t)
  sim_steps = np.arange(num_steps)
  state, _ = lax.scan(do_step, state, sim_steps)

  return state.position

def brownian(a, R, key):
  '''
  Arguments:
    key: sets up random number generation
    a: vector containing (a0, a1, a2, a3, a4), the parameters of the honeycomb potential
    batch_size: batch size
  Returns:
    order_param: average local bond orientational order parameter for k = 3
  '''

  # Set up simulation parameters
  N = NUM_PARTICLES
  displacement, shift = space.periodic(BOX_SIZE)
  dimension = 2
  dt = STEP_SIZE
  T_schedule = TEMPERATURE
  num_steps = BROWNIAN_STEPS

  # Compile the dynamics
  energy_fn = jit(honeycomb_pair(displacement, a0=a[0], a1=a[1], a2=a[2], a3=a[3], r_cut=1.0))
  init, apply = simulate.brownian(energy_fn, shift, dt=dt, T_schedule=T_schedule)

  key, split = random.split(key)
  apply = jit(apply)
  state = init(split, R)

  # Compute the order parameter
  displacement_all = vmap(vmap(displacement, (0, None), 0), (None, 0), 0)
  corr = get_correlation_function(displacement_all, 3)

  # Run the brownian dynamics
  def apply_and_measure(state, i):
    return apply(state), corr(state.position)

  sim_steps = np.arange(num_steps)
  state, losses = lax.scan(apply_and_measure, state, sim_steps)
  loss = np.mean(losses)
  return loss

v_init = vmap(initial_min, in_axes=(None, 0)) # vectorize over simulation keys
v_brownian = vmap(brownian, in_axes=(None, 0, None)) # vectorize over input R's
jv_init = jit(v_init)

def run(a, Rs, key):
  return np.mean(v_brownian(a, Rs, key))

vg_run = value_and_grad(run)
jvg_run = jit(value_and_grad(run))

print("jitted")

def optimize(init_params, opt_steps, batch_size, save_every):
  opt_init, opt_update, get_params = optimizers.rmsprop(step_size=1e-2, gamma=0.9, eps=1e-8)
  loss_file = '/loss.txt'
  param_file = '/params.txt'
  grad_file = '/grad.txt'

  def clip_gradient(g, clip=10.0):
    return np.array(np.where(np.abs(g) > clip, np.sign(g)*clip, g))

  def step(i, opt_state, save_every=10):

    params = get_params(opt_state)
    global key
    key, split = random.split(key)
    simulation_keys = random.split(split, batch_size)
    R_inits = jv_init(params, simulation_keys) #v_init(params, simulation_keys)
    loss, g = jvg_run(params, R_inits, split) #vg_run(params, R_init)
    g = clip_gradient(g, 20.0)

    if(i%save_every==0):
      if(i==save_every):
        cmd = "w"
      else:
        cmd = "a"

      with open(loss_file, cmd) as outfile1:
        outlist1 = onp.array(loss).tolist()
        outfile1.write("{}".format(loss)+'\n')

      with open(param_file, cmd) as outfile2:
        outlist2 = onp.array(params).tolist()
        separator=', '
        outfile2.write(separator.join(['{}'.format(temp) for temp in outlist2])+'\n')

      with open(grad_file, cmd) as outfile3:
        outlist3 = onp.array(g).tolist()
        separator=', '
        outfile3.write(separator.join(['{}'.format(temp) for temp in outlist3])+'\n')

      print("Loss: {}".format(loss))
      print("Parameters: {}".format(params))
      print("Gradient: {}".format(g))

    return opt_update(i, g, opt_state)

  opt_state = opt_init(init_params)
  iteration = 0
  i0 = iteration
  for _ in range(i0, i0 + opt_steps):
    iteration += 1
    params = get_params(opt_state)
    opt_state = step(iteration, opt_state, save_every=save_every)

optimize(INPUT, OPT_STEPS, BATCH_SIZE, SAVE_EVERY)


from os import uname

REAL = 0
SIM = 1
mode = REAL if uname().nodename == 'microbit' else SIM

if mode == REAL:
    import gc
    gc.collect()
    from microbit import i2c, pin1, pin2, pin8, pin12, pin13, pin14, sleep
    import machine
    delay = sleep
    _v = 50
    pin2.set_pull(pin2.NO_PULL)
else:
    from microbit import *
    from delay import delay
    _v = 60

_axe = 0.097
irLeft = pin13
irRight = pin14
ledLeft = pin8
ledRight = pin12
M_LEFT = 0
M_RIGHT = 2

# motor direction
D_FW = 0 if mode == REAL else 1
D_BW = 1 if mode == REAL else 2

def rotMot(side, d, s):
    i2c.write(0x10, bytearray([side, d, s]))

def stop():
    w(0, 0, 0, 0)

def rotateMotor(side, s):
    v = abs(s)
    d = D_BW if s < 0 else D_FW
    rotMot(side, d, v)

def dist_real():
    pin1.write_digital(1)
    pin1.write_digital(0)
    p = machine.time_pulse_us(pin2, 1, 50000)
    cm = int(p / 58.2 + 0.5)
    return cm if cm > 0 else 255

def dist_sim():
    return sim.robots[0].getDistance()

getDistance = dist_real if mode == REAL else dist_sim

def setLED(on):
    pin8.write_digital(on)
    pin12.write_digital(on)

class Motor:
    def __init__(self, id):
        self._id = 2 * id

    def rotate(self, s):
        v = abs(s)
        if s > 0:
            self._w(D_FW, v)
        elif s < 0:
            self._w(D_BW, v)
        else:
            self._w(D_FW, 0)

    def _w(self, d, s):
        try:
            i2c.write(0x10, bytearray([self._id, d, s]))
        except:
            print("Please switch on mbRobot!")
            while True:
                pass

motL = Motor(0)
motR = Motor(1)


"""
******************************************************************************
* Purpose: Commercial data processing using queue
*
* @author:  Ramnath Patro
* @version: 1.0
* @since:   29-3-2019
*
******************************************************************************
"""

from Data_Structure_Programs.Datastructure_Operations import queue_anagram
qe = queue_anagram()
import json

from oops.Commercial_data_processing import buy,sell

sell_call = sell
buy_call = buy

class information:
    def customer_company_file_read(file_name, mode):
        fr = open(file_name, mode)
        file_data = json.load(fr)
        fr.close()
        return file_data

    def customer_company_file_write(file_name, customer_details):
        # fw = open(file_name, mode)
        # update_data = json.dump(file_name, fw)
        # fw.close()
        with open(file_name, "w") as file:
            json.dump(customer_details, file)
        return customer_details

    def new_acc(self):
        # customer_details = []
        # company_details = []
        customer_details = information.customer_company_file_read("customer_details.json", "r")
        # company_details = information.customer_company_file_read("company_details.json", "r")

        for element in customer_details:
            qe.enqueue(element)

        while True:
            try:
                inp = int(input("Enter the ID"))
                break
            except:
                print("Invalid ID")
                continue
        while True:
            try:
                for itr in customer_details:
                    # print(itr["customer_id"])
                    if itr["customer_id"] == inp:
                        raise ValueError
                break
            except:
                print("ID present please enter another id")
                inp = input("Enter the another ID")

        inp_name = input("Enter your name")

        while True:
            try:
                inp_bal = int(input("Enter your balance"))
                break
            except:
                print("Invalid balance")
                continue

        new_user = {
            'customer_id': inp,
            'customer_name': inp_name,
            'balance': inp_bal
        }
        # customer_details.append(new_user)
        # customer_details = []
        data = []
        qe.enqueue(new_user)
        for i in range(len(customer_details ) + 1):
            data.append(qe.dequeue())
        customer_details = information.customer_company_file_write("customer_details.json", data)

class search():
    def ser(self):
        customer_details = information.customer_company_file_read("customer_details.json", "r")
        company_details = information.customer_company_file_read("company_details.json", "r")

        while True:
            x = 0
            try:
                inp = int(input("Enter the ID"))
                for itr in customer_details:
                    # print(itr["customer_id"])
                    if itr["customer_id"] == inp:
                        print("Valid ID")
                        x = 1
                        break
                    # if x == 0:
                    #     inp = int(input("Enter the another ID"))
                    # if inp not in itr["customer_id"] and x != 1:
                    #     print("+++++++++++qqqqqqqq")
                    #     raise ValueError
                break
            except:
                print("Invalid ID")
                continue
        print(inp)

        while True:
            try:
                companyname = input("Enter the company Name:").lower()
                if not companyname.isalpha():
                    raise ValueError
                x = 0
                for itr in company_details:
                    for com_name in itr:
                        # print(j)
                        if com_name == companyname:
                            print("Valid ID")
                            x = 1
                            break
                if x == 1:
                    break
            except:
                print("Invalid company name")
                continue
        return inp, companyname
class buy(search):
    def buy_shar(self):
        transaction_name, customer_id, company_name, number_of_share, time_details = buy_call.buy_shar(self)
        try:
            qe = queue_anagram()

            with open('queue_transaction.json', 'r') as myfile:
                details = json.load(myfile)

            for element in details:
                qe.enqueue(element)

            details1 = {"transaction_name ": transaction_name,
                        "customer_id": customer_id,
                        "company_name": company_name,
                        "number_of_share": number_of_share,
                        "time details": time_details
                        }

            qe.enqueue(details1)
            temp = []
            size = qe.size()
            for i in range(size):
                temp.append(qe.dequeue())
            with open('queue_transaction.json', 'w') as data:
                json.dump(temp, data)

        except IOError as e:
            print("File Not Found")
            print(e)
        except Exception as e:
            print(e)

class sell(search):

    def sell_shar(self):
        transaction_name, customer_id, company_name, number_of_share, time_details = sell_call.sell_shar(self)

        try:
            qe = queue_anagram()

            with open('queue_transaction.json', 'r') as myfile:
                details = json.load(myfile)

            for element in details:
                qe.enqueue(element)

            details1 = {"transaction_name ": transaction_name,
                        "customer_id": customer_id,
                        "company_name": company_name,
                        "number_of_share": number_of_share,
                        "time details": time_details
                        }

            qe.enqueue(details1)
            temp = []
            size = qe.size()
            for i in range(size):
                temp.append(qe.dequeue())
            with open('queue_transaction.json', 'w') as data:
                json.dump(temp, data)

        except IOError as e:
            print("File Not Found")
            print(e)
        except Exception as e:
            print(e)

if __name__ == '__main__':

    while True:
        print()
        print("1.create New Account")
        print("2.Buy the share")
        print("3.Sell the share")
        print("4.Exit the program")
        inp = input("Enter the option ")

        while not inp.isdigit():
            print("Invalid input")
            inp = input("Enter the option ")
        inp = int(inp)

        if inp == 1:
            print("create a new Account")
            i = information()
            i.new_acc()

        elif inp == 2:
            print("How much share you buy")
            b = buy()
            b.buy_shar()

        elif inp == 3:
            print("How much share you Sell")
            s = sell()
            s.sell_shar()

        elif inp == 4:
            print("Exit the program")
            exit()

        else:
            print("Invalid Input")