import sys, os, pathlib
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.backends.backend_pdf import PdfPages

sys.path.append(str(pathlib.Path(__file__).resolve().parents[2]))
from physion.dataviz.datavyz.datavyz import graph_env_manuscript as ge
from physion.analysis import read_NWB
from physion.analysis import process_NWB
from physion.dataviz.show_data import EpisodeResponse
from physion.analysis.tools import summary_pdf_folder
# from physion.analysis.protocol_scripts.orientation_direction_selectivity import shift_orientation_according_to_pref

def plot_resp_dependency(Episodes,
                         stim_keys=['Image-ID', 'VSE-seed'],
                         stim_indices=[0,1],
                         responsive_rois=None,
                         running_threshold=0.1,
                         selection_seed=0, N_selected=7):
    """
    """
    # different episode conditions :

    all_eps = Episodes.find_episode_cond(stim_keys, stim_indices)
    running = all_eps & (Episodes.running_speed.mean(axis=1)>running_threshold)
    still = all_eps & (Episodes.running_speed.mean(axis=1)<=running_threshold)

    if responsive_rois is not None:
        np.random.seed(selection_seed)
        if len(responsive_rois)>=N_selected:
            selected_rois=np.random.choice(responsive_rois, N_selected, replace=False)
        else:
            selected_rois = np.concatenate([responsive_rois,
                                            np.random.choice(np.arange(Episodes.dFoF.shape[1]),
                                               N_selected-len(responsive_rois), replace=False)])
    else:
        selected_rois = np.random.choice(np.arange(Episodes.dFoF.shape[1]), N_selected, replace=False)
    selected_rois = np.array(selected_rois, dtype=int)

    fig, AX = ge.figure(axes_extents=[[[1,3] for i in range(4)],
                                     [[1, N_selected] for i in range(4)]],
                        figsize=(1.3,.25), left=1, right=4, top=5, wspace=0.4)

    # RASTER SHOWING RAW VALUES OF dFoF but over a clipped range defined:
    min_dFoF = np.min(Episodes.dFoF[:,selected_rois,:].mean(axis=0).min(axis=-1))
    max_dFoF = 0.8*np.max(Episodes.dFoF[:,selected_rois,:].mean(axis=0).max(axis=-1))

    _, cb = ge.bar_legend(AX[0][0],
                  colorbar_inset=dict(rect=[-0.5,.1,.03,.8], facecolor=None),
                  colormap=ge.binary,
                  bar_legend_args={},
                  #label='n. $\Delta$F/F', bounds=None, ticks = None, ticks_labels=None, no_ticks=False,
                  #label='$\Delta$F/F', bounds=[0,2], ticks = [0,1,2], ticks_labels=['0','1','>2'], no_ticks=False,
                  bounds=[min_dFoF, max_dFoF], ticks=[min_dFoF,max_dFoF],
                  ticks_labels=['<%.1f' % min_dFoF, '>%.1f' % max_dFoF], no_ticks=False,
                  orientation='vertical')
    ge.annotate(cb, '$\Delta$F/F', (1.5, 0.5), rotation=90, va='center')

    ge.bar_legend(AX[1][0],
                  colorbar_inset=dict(rect=[-0.5,.2,.02,.6], facecolor=None),
                  colormap=ge.jet,
                  bar_legend_args={},
                  label='single trials', bounds=None, ticks = None, ticks_labels=None, no_ticks=False,
                  orientation='vertical')

    ##### ---- INSETS ---- #####

    stim_inset = ge.inset(AX[0][3], [0.7, 0.4, 0.9, 1])

    Episodes.visual_stim.plot_stim_picture(np.flatnonzero(all_eps)[0],
                                           ax=stim_inset, vse=True)
    stim_inset.annotate('t=%.1fs' % getattr(Episodes, 'center-time')[np.flatnonzero(all_eps)[0]],
            (1,1), xycoords='axes fraction', ha='right', va='top', size=8, color='w')

    if responsive_rois is not None:
        resp_inset = ge.inset(AX[0][3], [0.95,-0.4,0.5,0.8])
        frac_resp = 100.*len(responsive_rois)/Episodes.dFoF.shape[1]
        ge.pie([frac_resp, 100-frac_resp], COLORS=[ge.green, ge.grey],
               ax=resp_inset)
        ge.annotate(resp_inset, '%.1f%% resp.' % frac_resp,
                    (1.1,0.9), rotation=90, ha='right',va='top',
                    color=ge.green)

    if hasattr(Episodes, 'pupil_diameter'):
        behav_inset = ge.inset(AX[0][3], [0.2,0.3,0.45,.7])
        Episodes.behavior_variability(episode_condition=all_eps,
                                      threshold2=running_threshold, ax=behav_inset)

    scale_ROIS = np.ones(len(selected_rois))

    for cond, axP, axT, label, color in zip([all_eps, still, running], AX[0], AX[1],
                    ['all eps', 'still', 'running'], ['k', ge.blue, ge.orange]):

        ge.title(axP, '%s (n=%i)' % (label, np.sum(cond)), color=color)

        if np.sum(cond)>0:

            axP.imshow(np.clip(Episodes.dFoF[cond,:,:].mean(axis=0), min_dFoF, max_dFoF),
                       cmap=ge.binary,
                       aspect='auto', interpolation='none',
                       vmin=min_dFoF, vmax=max_dFoF,
                       origin='lower',
                       extent = (Episodes.t[0], Episodes.t[-1],
                                 0, Episodes.dFoF.shape[1]))

            min_dFoF_range = 1.2

            for ir, r in enumerate(selected_rois):

                roi_resp = Episodes.dFoF[cond, r, :]
                scale = max([min_dFoF_range, np.max(roi_resp-roi_resp.mean())]) # 2 dFoF is the min scale range
                # plotting eps with that scale
                for iep in range(np.sum(cond)):
                    axT.plot(Episodes.t, ir+(roi_resp[iep,:]-roi_resp.mean())/scale,
                             color=ge.jet(iep/np.sum(cond)), lw=.5)
                # plotting scale
                axT.plot([Episodes.t[-1], Episodes.t[-1]], [.25+ir, .25+ir+1./scale], 'k-', lw=1.5)

                if 'all' in label:
                    ge.annotate(axT, 'roi#%i ' % (r+1), (Episodes.t[0], ir), xycoords='data',
                                ha='right', size='small')
                    scale_ROIS[ir] = scale

                if label=='running':
                    ge.plot(Episodes.t,
                            ir+Episodes.dFoF[cond, r, :].mean(axis=0)/scale_ROIS[ir],
                            sy=Episodes.dFoF[cond, r, :].std(axis=0)/scale_ROIS[ir],
                            ax=AX[1][3], color=color, no_set=True)

                if label=='still':
                    ge.plot(Episodes.t,
                            ir+Episodes.dFoF[cond, r, :].mean(axis=0)/scale_ROIS[ir],
                            sy=Episodes.dFoF[cond, r, :].std(axis=0)/scale_ROIS[ir],
                            ax=AX[1][3], color=color, no_set=True)

                    AX[1][3].plot([Episodes.t[-1], Episodes.t[-1]], [.25+ir, .25+ir+1./scale], 'k-', lw=1.5)

        ge.annotate(axT, '1$\Delta$F/F', (Episodes.t[-1], 0), xycoords='data',
                    rotation=90)
        ge.set_plot(axT, [], xlim=[Episodes.t[0], Episodes.t[-1]])
        ge.draw_bar_scales(axT, Xbar=1, Xbar_label='1s', Ybar=1e-12)

    ge.set_plot(AX[1][3], [], xlim=[Episodes.t[0], Episodes.t[-1]])
    ge.draw_bar_scales(AX[1][3], Xbar=1, Xbar_label='1s', Ybar=1e-12)

    AX[0][3].axis('off')
    # comparison
    ge.annotate(AX[1][3], '1$\Delta$F/F', (Episodes.t[-1], 0), xycoords='data', rotation=90)

    if hasattr(Episodes.visual_stim, 'vse') and (Episodes.visual_stim.vse is not None):
        vse_shifts = Episodes.visual_stim.vse['t'][Episodes.visual_stim.vse['t']<Episodes.visual_stim.protocol['presentation-duration']]

        for ax,ax1 in zip(AX[0][:3], AX[1][:3]):
            ge.set_plot(ax, [], xlim=[Episodes.t[0], Episodes.t[-1]])
            ge.annotate(ax, 'ROIs', (0,0.5), rotation=90, ha='right', va='center')
            ge.annotate(ax, '1', (0,0), ha='right', size='x-small', va='center')
            ge.annotate(ax, '%i' % Episodes.dFoF.shape[1], (0,1), ha='right', size='x-small', va='center')
            for t in [0]+list(vse_shifts)+[Episodes.visual_stim.protocol['presentation-duration']]:
                ax.plot(t*np.ones(2), ax.get_ylim(), 'r--', lw=0.3)
                ax1.plot(t*np.ones(2), ax1.get_ylim(), 'r--', lw=0.3)

    return fig, AX

# def compute_DS_population_resp(filename, options,
                               # protocol_id=0,
                               # Nmax = 100000,
                               # stat_test_props=dict(interval_pre=[-2,0],
                                                    # interval_post=[1,3],
                                                    # test='ttest', positive=True),
                               # significance_threshold=0.01):

    # # load datafile
    # data = Data(filename)
    # Episodes = process_NWB.EpisodeResponse(data,
                               # quantities=['dFoF', 'Pupil', 'Facemotion', 'Running-Speed'])

    # full_resp = {'roi':[], 'angle_from_pref':[],
                 # 'Nroi_tot':data.iscell.sum(),
                 # 'post_level':[], 'evoked_level':[]}

    # # get levels of pupil and running-speed in the episodes (i.e. after realignement)
    # if 'Pupil' in data.nwbfile.processing:
        # Pupil_episodes = EpisodeResponse(data, protocol_id=protocol_id, quantity='Pupil', **options)
        # full_resp['pupil_level'] = []
    # else:
        # Pupil_episodes = None
    # if 'Running-Speed' in data.nwbfile.acquisition:
        # Running_episodes = EpisodeResponse(data, protocol_id=protocol_id, quantity='Running-Speed', **options)
        # full_resp['speed_level'] = []
    # else:
        # Running_episodes = None

    # if Running_episodes is not None:
        # for key in Running_episodes.varied_parameters.keys():
            # full_resp[key] = []
    # elif Pupil_episodes is not None:
        # for key in Pupil_episodes.varied_parameters.keys():
            # full_resp[key] = []
    # else:
        # print(100*'-'+'\n /!\ Need at least one of the Pupil or Running modalities /!\ \n  '+100*'-')

    # for roi in np.arange(data.iscell.sum())[:Nmax]:
        # ROI_EPISODES = EpisodeResponse(data,
                                       # protocol_id=protocol_id,
                                       # quantity='CaImaging',
                                       # baseline_substraction=True,
                                       # roiIndex = roi, **options)
        # # check if significant response in at least one direction and compute mean evoked resp
        # resp = {'significant':[], 'pre':[], 'post':[]}
        # for ia, angle in enumerate(ROI_EPISODES.varied_parameters['angle']):

            # stats = ROI_EPISODES.stat_test_for_evoked_responses(episode_cond=ROI_EPISODES.find_episode_cond('angle', ia),
                                                                # **stat_test_props)
            # resp['significant'].append(stats.significant(threshold=significance_threshold))
            # resp['pre'].append(np.mean(stats.x))
            # resp['post'].append(np.mean(stats.y))

        # if np.sum(resp['significant'])>0:
            # # if significant in at least one
            # imax = np.argmax(np.array(resp['post'])-np.array(resp['pre']))
            # amax = ROI_EPISODES.varied_parameters['angle'][imax]
            # # we compute the post response relative to the preferred orientation for all episodes
            # post_interval_cond = ROI_EPISODES.compute_interval_cond(stat_test_props['interval_post'])
            # pre_interval_cond = ROI_EPISODES.compute_interval_cond(stat_test_props['interval_pre'])
            # for iep, r in enumerate(ROI_EPISODES.resp):
                # full_resp['angle_from_pref'].append(shift_orientation_according_to_pref(ROI_EPISODES.angle[iep], amax))
                # full_resp['post_level'].append(ROI_EPISODES.resp[iep, post_interval_cond].mean())
                # full_resp['evoked_level'].append(full_resp['post_level'][-1]-ROI_EPISODES.resp[iep, pre_interval_cond].mean())
                # full_resp['roi'].append(roi)
                # # adding running and speed level in the "post" interval:
                # if Pupil_episodes is not None:
                    # full_resp['pupil_level'].append(Pupil_episodes.resp[iep, post_interval_cond].mean())
                # if Running_episodes is not None:
                    # full_resp['speed_level'].append(Running_episodes.resp[iep, post_interval_cond].mean())

    # # transform to numpy array for convenience
    # for key in full_resp:
        # full_resp[key] = np.array(full_resp[key])

    # #########################################################
    # ############ per cell analysis ##########################
    # #########################################################

    # angles = np.unique(full_resp['angle_from_pref'])

    # full_resp['per_cell'], full_resp['per_cell_post'] = [], []

    # for roi in np.unique(full_resp['roi']):

        # roi_cond = (full_resp['roi']==roi)

        # full_resp['per_cell'].append([])
        # full_resp['per_cell_post'].append([])

        # for ia, angle in enumerate(angles):
            # cond = (full_resp['angle_from_pref']==angle) & roi_cond
            # full_resp['per_cell'][-1].append(full_resp['evoked_level'][cond].mean())
            # full_resp['per_cell_post'][-1].append(full_resp['post_level'][cond].mean())

    # full_resp['per_cell'] = np.array(full_resp['per_cell'])
    # full_resp['per_cell_post'] = np.array(full_resp['per_cell_post'])

    # return full_resp

# def population_tuning_fig(full_resp):

    # Ncells = len(np.unique(full_resp['roi']))
    # Neps = len(full_resp['roi'])/Ncells
    # angles = np.unique(full_resp['angle_from_pref'])

    # fig, AX = ge.figure(axes=(3,1), figsize=(1.5,1.5))

    # for ax in AX:
        # ge.annotate(ax, 'n=%i resp. cells (%.0f%% of rois)' % (Ncells,
                                                    # 100.*Ncells/full_resp['Nroi_tot']), (1,1), va='top', ha='right')

    # ge.plot(angles, np.mean(full_resp['per_cell_post'], axis=0),
            # sy = np.std(full_resp['per_cell_post'], axis=0),
            # color='grey', ms=2, m='o', ax=AX[0], no_set=True, lw=1)
    # ge.set_plot(AX[0], xlabel='angle ($^{o}$) w.r.t. pref. orient.', ylabel='post level (dF/F)',
               # xticks=[0,90,180,270])

    # ge.plot(angles, np.mean(full_resp['per_cell'], axis=0),
            # sy = np.std(full_resp['per_cell'], axis=0),
            # color='grey', ms=2, m='o', ax=AX[1], no_set=True, lw=1)
    # ge.set_plot(AX[1], xlabel='angle ($^{o}$) w.r.t. pref. orient.', ylabel='evoked resp. ($\delta$ dF/F)',
               # xticks=[0,90,180,270])

    # ge.plot(angles, np.mean(full_resp['per_cell'].T/np.max(full_resp['per_cell'], axis=1).T, axis=1),
            # sy = np.std(full_resp['per_cell'].T/np.max(full_resp['per_cell'], axis=1).T, axis=1),
            # color='grey', ms=2, m='o', ax=AX[2], no_set=True, lw=1)
    # ge.set_plot(AX[2], xlabel='angle ($^{o}$) w.r.t. pref. orient.',
                # ylabel='norm. resp ($\delta$ dF/F)', yticks=[0,0.5,1],
               # xticks=[0,90,180,270])

    # return fig

# def compute_behavior_mod_population_tuning(full_resp,
                                           # resp_key='evoked_level',
                                           # pupil_threshold=2.5,
                                           # running_speed_threshold = 0.1):

    # Ncells = len(np.unique(full_resp['roi']))
    # Neps = len(full_resp['roi'])/Ncells

    # if 'speed_level' in full_resp:
        # running_cond = (np.abs(full_resp['speed_level'])>=running_speed_threshold)
    # else:
        # # always a running cond set to False if no running monitoring
        # running_cond = np.zeros(len(full_resp['roi']), dtype=bool) # False by default

    # if 'pupil_level' in full_resp:
        # dilated_cond = ~running_cond & (full_resp['pupil_level']>=pupil_threshold)
        # constricted_cond = ~running_cond & (full_resp['pupil_level']<pupil_threshold)

    # # add to full_resp
    # full_resp['Ncells'], full_resp['Neps'] = Ncells, Neps
    # full_resp['running_cond'] = running_cond
    # if 'pupil_level' in full_resp:
        # full_resp['dilated_cond'] = dilated_cond
        # full_resp['constricted_cond'] = constricted_cond

    # angles = np.unique(full_resp['angle_from_pref'])
    # curves = {'running_mean': [], 'running_std':[],
              # 'still_mean': [], 'still_std':[],
              # 'dilated_mean': [], 'dilated_std':[],
              # 'constricted_mean': [], 'constricted_std':[],
              # 'angles':angles}

    # for ia, angle in enumerate(angles):
        # cond = full_resp['angle_from_pref']==angle
        # # running
        # curves['running_mean'].append(full_resp[resp_key][cond & running_cond].mean())
        # curves['running_std'].append(full_resp[resp_key][cond & running_cond].std())
        # # still
        # curves['still_mean'].append(full_resp[resp_key][cond & ~running_cond].mean())
        # curves['still_std'].append(full_resp[resp_key][cond & ~running_cond].std())
        # if 'pupil_level' in full_resp:
            # # dilated pupil
            # curves['dilated_mean'].append(full_resp[resp_key][cond & dilated_cond].mean())
            # curves['dilated_std'].append(full_resp[resp_key][cond & dilated_cond].std())
            # # constricted pupil
            # curves['constricted_mean'].append(full_resp[resp_key][cond & constricted_cond].mean())
            # curves['constricted_std'].append(full_resp[resp_key][cond & constricted_cond].std())

    # curves['all'] = np.mean(full_resp['per_cell'], axis=0)

    # return curves

# def tuning_modulation_fig(curves, full_resp=None):

    # # running vs still --- raw evoked response
    # fig, ax = ge.figure(figsize=(1.5,1.5), right=6)
    # ge.plot(curves['angles'], curves['all'], label='all', color='grey', ax=ax, no_set=True, lw=2, alpha=.5)
    # ge.plot(curves['angles'], curves['running_mean'],
            # color=ge.orange, ms=4, m='o', ax=ax, lw=2, label='running', no_set=True)
    # ge.plot(curves['angles'], curves['still_mean'],
            # color=ge.blue, ms=4, m='o', ax=ax, lw=2, label='still', no_set=True)
    # ge.legend(ax, ncol=3, loc=(.3,1.))
    # ge.set_plot(ax, xlabel='angle ($^{o}$) w.r.t. pref. orient.', ylabel='evoked resp, ($\delta$ dF/F)   ',
               # xticks=[0,90,180,270])

    # if (full_resp is not None) and ('speed_level' in full_resp) and ('pupil_level' in full_resp):
        # inset = ge.inset(fig, [.8,.5,.16,.28])
        # ge.scatter(full_resp['pupil_level'][full_resp['running_cond']],full_resp['speed_level'][full_resp['running_cond']],
                   # ax=inset, no_set=True, color=ge.orange)
        # ge.scatter(full_resp['pupil_level'][~full_resp['running_cond']],full_resp['speed_level'][~full_resp['running_cond']],
                   # ax=inset, no_set=True, color=ge.blue)
        # ge.annotate(ax, 'n=%i cells\n' % full_resp['Ncells'], (0.,1.), ha='center')
        # ge.set_plot(inset, xlabel='pupil size (mm)', ylabel='run. speed (cm/s)     ',
                   # title='episodes (n=%i)   ' % full_resp['Neps'])
        # ge.annotate(inset, 'n=%i' % (np.sum(full_resp['running_cond'])/full_resp['Ncells']), (0.,1.), va='top', color=ge.orange)
        # ge.annotate(inset, '\nn=%i' % (np.sum(~full_resp['running_cond'])/full_resp['Ncells']), (0.,1.), va='top', color=ge.blue)

    # if len(curves['constricted_mean'])>0:
        # # constricted vs dilated --- raw evoked response
        # fig2, ax = ge.figure(figsize=(1.5,1.5), right=6)
        # ge.plot(curves['angles'], curves['all'], label='all', color='grey', ax=ax, no_set=True, lw=2, alpha=.5)
        # ge.plot(curves['angles'], curves['constricted_mean'],
                # color=ge.green, ms=4, m='o', ax=ax, lw=2, label='constricted', no_set=True)
        # ge.plot(curves['angles'], curves['dilated_mean'],
                # color=ge.purple, ms=4, m='o', ax=ax, lw=2, label='dilated', no_set=True)
        # ge.legend(ax, ncol=3, loc=(.1,1.))
        # ge.set_plot(ax, xlabel='angle ($^{o}$) w.r.t. pref. orient.', ylabel='evoked resp, ($\delta$ dF/F)   ',
                   # xticks=[0,90,180,270])

        # if (full_resp is not None) and ('speed_level' in full_resp) and ('pupil_level' in full_resp):
            # inset2 = ge.inset(fig2, [.8,.5,.16,.28])
            # ge.scatter(full_resp['pupil_level'][full_resp['dilated_cond']],
                       # full_resp['speed_level'][full_resp['dilated_cond']],
                       # ax=inset2, no_set=True, color=ge.purple)
            # ge.scatter(full_resp['pupil_level'][full_resp['constricted_cond']],
                       # full_resp['speed_level'][full_resp['constricted_cond']],
                       # ax=inset2, no_set=True, color=ge.green)
            # ge.annotate(ax, 'n=%i cells\n' % len(np.unique(full_resp['roi'])), (0.,1.), ha='right')
            # ge.set_plot(inset2, xlabel='pupil size (mm)', ylabel='run. speed (cm/s)     ', ylim=inset.get_ylim(),
                       # title='episodes (n=%i)   ' % full_resp['Neps'])
            # ge.annotate(inset2, 'n=%i' % (np.sum(full_resp['constricted_cond'])/full_resp['Ncells']), (0.,1.), va='top', color=ge.green)
            # ge.annotate(inset2, '\nn=%i' % (np.sum(full_resp['dilated_cond'])/full_resp['Ncells']), (0.,1.), va='top', color=ge.purple)
    # else:
        # fig2 = None

    # return fig, fig2

# def analysis_pdf(datafile, iprotocol=0, Nmax=1000000):

    # data = Data(datafile)

    # pdf_filename = os.path.join(summary_pdf_folder(datafile), '%s-behavioral-modulation.pdf' % data.protocols[iprotocol])

    # full_resp = compute_population_resp(datafile, protocol_id=iprotocol, Nmax=Nmax)

    # with PdfPages(pdf_filename) as pdf:
        # # print('   - behavioral-modulation analysis for ROI #%i / %i' % (roi+1, data.iscell.sum()))
        # fig = population_tuning_fig(full_resp)
        # pdf.savefig(fig)  # saves the current figure into a pdf page
        # plt.close()
        # fig1, fig2 = behavior_mod_population_tuning_fig(full_resp,
                                                        # running_speed_threshold = 0.1,
                                                        # pupil_threshold=2.5)

        # pdf.savefig(fig1)  # saves the current figure into a pdf page
        # plt.close(fig1)
        # pdf.savefig(fig2)  # saves the current figure into a pdf page
        # plt.close(fig2)

    # print('[ok] behavioral-modulation analysis saved as: "%s" ' % pdf_filename)

if __name__=='__main__':

    import argparse

    parser=argparse.ArgumentParser()
    parser.add_argument("datafile", type=str)
    parser.add_argument("--iprotocol", type=int, default=0, help='index for the protocol in case of multiprotocol in datafile')
    parser.add_argument('-nmax', "--Nmax", type=int, default=1000000)
    parser.add_argument("-v", "--verbose", action="store_true")

    args = parser.parse_args()

    # if '.nwb' in args.datafile:
    #     analysis_pdf(args.datafile, iprotocol=args.iprotocol, Nmax=args.Nmax)
    # else:
    #     print('/!\ Need to provide a NWB datafile as argument ')

    # options = dict(subquantity='d(F-0.7*Fneu)',
                   # dt_sampling=1, prestim_duration=2,
                   # verbose=False)

    # full_resp = compute_DS_population_resp(args.datafile, options, Nmax=args.Nmax)
    # if len(full_resp['roi'])>0:
        # fig = population_tuning_fig(full_resp)
        # curves = compute_behavior_mod_population_tuning(full_resp,
                                                        # running_speed_threshold = 0.2,
                                                        # pupil_threshold=2.1)
        # fig1, fig2 = tuning_modulation_fig(curves, full_resp=full_resp)

    # load data
    Episodes_NI = EpisodeResponse(args.datafile,
                                  protocol_id=args.iprotocol,
                                  quantities=['dFoF', 'Pupil', 'Running-Speed'],
                                  dt_sampling=30, # ms, to avoid to consume to much memory
                                  verbose=True, prestim_duration=1.5)

    ROI_SUMMARIES = [Episodes_NI.compute_summary_data(dict(\
                                interval_pre=[-Episodes_NI.visual_stim.protocol['presentation-interstim-period'],0],
                                interval_post=[0,Episodes_NI.visual_stim.protocol['presentation-duration']],
                                test='wilcoxon', positive=True),
                         response_args={'quantity':'dFoF',
                                        'roiIndex':roi},
                         response_significance_threshold=0.01) for roi in range(Episodes_NI.dFoF.shape[1])]

    # plot
    plot_resp_dependency(Episodes_NI,
                         stim_keys=['center-time'],
                         stim_indices=[0],
                         running_threshold=0.5,
                         N_selected=20, selection_seed=20)
    ge.show()


"""Maximum Depth

Problem Description

Given a Tree of A nodes having A-1 edges. Each node is numbered from 1 to A where 1 is the root of the tree.

You are given Q queries. In each query, you will be given two integers L and X. Find the value of such node which lies at level L mod (MaxDepth + 1) and has value greater than or equal to X.

Answer to the query is the smallest possible value or -1, if all the values at the required level are smaller than X.

NOTE:

Level and Depth of the root is considered as 0.
It is guaranteed that each edge will be connecting exactly two different nodes of the tree.
Please read the input format for more clarification.

Problem Constraints

2 <= A, Q(size of array E and F) <= 105

1 <= B[i], C[i] <= A

1 <= D[i], E[i], F[i] <= 106

Input Format

The first argument is an integer A denoting the number of nodes.

The second and third arguments are the integer arrays B and C where for each i (0 <= i < A-1), B[i] and C[i] are the nodes connected by an edge.

The fourth argument is an integer array D, where D[i] denotes the value of the (i+1)th node

The fifth and sixth arguments are the integer arrays E and F where for each i (0 <= i < Q), E[i] denotes L and F[i] denotes X for ith query.

Output Format

Return an array of integers where the ith element denotes the answer to ith query.

Example Input

Input 1:

 A = 5
 B = [1, 4, 3, 1]
 C = [5, 2, 4, 4]
 D = [7, 38, 27, 37, 1]
 E = [1, 1, 2]
 F = [32, 18, 26]

Input 2:

 A = 3
 B = [1, 2]
 C = [3, 1]
 D = [7, 15, 27]
 E = [1, 10, 1]
 F = [29, 6, 26]

Example Output

Output 1:

 [37, 37, 27]

Output 2:

 [-1, 7, 27]

Example Explanation

Explanation 1:

      1[7]
     /    \
   5[1]  4[37]
        /    \
       2[38]  3[27]

 Query 1:
    L = 1, X = 32
    Nodes for level 1 are 5, 4
    Value of Node 5 = 1 < 32
    Value of Node 4 = 37 >= 32
    Ans = 37

Explanation 2:

      1[7]
     /    \
   2[15]  3[27]

 Query 1:
    L = 1, X = 6
    Nodes for level 1 are 2, 3 having value 15 and 27 respectively.
    Answer = -1 (Since no node is greater or equal to 29).
 Query 1:
    L = 10 % 2 = 0, X = 6
    Nodes for level 0 is 1 having value 7.
    Answer = 7.
"""
"""
Hint 1

Can we use binary search for nodes at a particular level?
"""
"""
Solution Approach

Main idea is to maintain list of nodes at every different level.

Can we do that with dfs or bfs?

To maintain the list, Call dfs from the root of tree(1) and insert the node at in the list at particularr level.

For each query, Use binary search to find the required value at a particular level.

If there is no value present which is greater or equal to x, output -1.
"""
class Solution:
    # @param A : integer
    # @param B : list of integers
    # @param C : list of integers
    # @param D : list of integers
    # @param E : list of integers
    # @param F : list of integers
    # @return a list of integers

    def solve(self, A, B, C, D, E, F):
        global maxdepth, level
        adj = [[] for i in range(A+1)]
        level= [[] for i in range(A+1)]

        maxdepth = 0

        def dfs( prev ,node ,d):
            global maxdepth

            level[d].append(D[node-1])
            maxdepth = max(maxdepth, d)

            for i in adj[node]:
                if i == prev:
                    continue
                dfs(node, i ,d+1)

        for i in range(A-1):
            adj[B[i]].append(C[i])
            adj[C[i]].append(B[i])

        # print(adj)
        dfs(1, 1, 0)
        # print(level, maxdepth)

        for i in range(maxdepth + 1):
            level[i].sort()

        res = []

        def bisect(start, end, L, num):
            if start == end:
                return start if level[L][start] >= num else start+1

            mid = (start + end)//2

            if level[L][mid] >= num and ( mid == 0 or level[L][mid-1] < num):
                return mid

            elif level[L][mid] < num: #right
                return bisect(mid+1, end, L, num)

            else: #left
                return bisect(start, mid-1, L, num )

        for i in range(len(E)):

            L =  E[i]%(maxdepth+1)

            # print(L)

            temp = bisect(0, len(level[L])-1, L, F[i])

            if temp == len(level[L]):
                res.append(-1)
            else:
                res.append(level[L][temp])

        return res


import warnings

warnings.filterwarnings("ignore", category=DeprecationWarning)
from ..src.inference import get_prediction, get_model, PRED_MAP

def test_food_map():
    """We expect 12 food classes.
    To assert there is 12 food classes in dictionary map.
    Test could be useful when reading such dictionary map from external source
    """
    assert len(PRED_MAP) == 12, "Incorrect prediction mapping"

def test_load_model():
    """We expect a correct file_name to pass,
    and we expect a wrong file_name to fail.
    If both conditions met, test case will pass.
    """
    model_file_names = {"tensorfood.h5": True, "t3ns0r500d.h5": False}

    def load(model_path):
        try:
            model = get_model(model_path)
            return True
        except Exception as e:
            return False

    for k, v in model_file_names.items():
        if load(k) != v:
            # raise OSError
            pass

def test_image_input():
    """We inserted a wrong file_name
    We expect an FileNotFoundError error to be caught
    Test case will pass if error is successfully caught under except
    """
    try:
        no_such_file_name = "no_such_file.test"
        get_prediction(no_such_file_name)
    # except Exception as e:
    except FileNotFoundError as e:
        print("caught no such file error")

# def test_get_model_prediction():
#     """Get prediction from a proper food image
#     Test case will pass if prediction is successfully returned
#     """
#     food_prediction = get_prediction("./images/kt.jpg")
#     print("food_prediction", food_prediction)
#     assert len(food_prediction) != 0, "Model fail to run prediction..."

# test_model_not_found()


import requests
from langdetect import detect

def translate_to_english(text):
    if not is_chinese(text):
        return text
    url = "http://fanyi.youdao.com/translate?doctype=json"
    params = {
        "i": text,
        "from": "auto",
        "to": "en",
    }
    response = requests.get(url, params=params)
    print(response.json())
    translation = response.json()
    if "translateResult" in translation:
        return translation["translateResult"][0][0]["tgt"]
    else:
        return text

# if __name__ == "__main__":
#     print(translate_to_english("我是中国人"))

def is_chinese(text):
    try:
        lang = detect(text)
        print(lang)
        return lang == 'zh-cn' or lang == 'zh-tw'
    except:
        return False


from kivy.lang.builder import Builder
from kivymd.app import MDApp
from kivy.uix.screenmanager import ScreenManager, Screen
import pyqrcode

qr = """
MDScreen:
    MDCard:
        size_hint: None, None
        size: 300, 450
        orientation: "vertical"
        padding: 20
        spacing: 20
        pos_hint: {"center_x": .5, "center_y": .5}
        elevation: 15
        radius: 15
        MDLabel:
            id: title
            text: "QR Code Generator"
            font_size: 30
            halign: "center"
        MDTextFieldRound:
            id: link
            hint_text: "Enter Your URL"
            icon_left: "link"
        MDTextFieldRound:
            id:file
            hint_text: "Enter File Name"
            icon_left: "file"
        MDFillRoundFlatIconButton:
            text: "Generate"
            pos_hint: {"center_x": .5}
            on_release: app.gen()
            icon: "file-plus"
        MDFillRoundFlatIconButton:
            text: "Clear"
            pos_hint: {"center_x": .5}
            on_release: app.clfs()
            icon: "delete"
        Image:
            id: qr_image
            source:"D:\KivyMD\KivyMD\QR Code Generator\img.png"
        MDSwitch:
            pos_hint: {"center_x": .5, "center_y": .5}
            on_active: app.dark(*args)

"""

class MainApp(MDApp):

    def build(self):
        self.theme_cls.theme_style = "Light"
        return Builder.load_string(qr)

    def gen(self):
        link = self.root.ids.link.text
        file = self.root.ids.file.text
        if len(link) == 0:
            self.root.ids.title.text = "URL Not Specified!"
            self.root.ids.qr_image.source = "D:\KivyMD\KivyMD\QR Code Generator\img.png"
        elif len(file) == 0:
             self.root.ids.title.text = "File Name Not Specified!"
             self.root.ids.qr_image.source = "D:\KivyMD\KivyMD\QR Code Generator\img.png"
        else:
            link = self.root.ids.link.text
            file = self.root.ids.file.text
            qr = pyqrcode.create(content=link)
            qr.png(f"{file}.png", scale=4)
            self.root.ids.qr_image.source = f"D:\KivyMD\KivyMD\QR Code Generator\{file}.png"
            self.root.ids.title.text = "QR Code Generated!"

    def clfs(self):
        self.root.ids.title.text = "QR Code Generator"
        self.root.ids.link.text = ""
        self.root.ids.file.text = ""
        self.root.ids.qr_image.source =""
        self.root.ids.qr_image.source = "D:\KivyMD\KivyMD\QR Code Generator\img.png"

    def dark(self, checkbox, value):
        if value:
            self.theme_cls.theme_style = "Dark"
        else:
            self.theme_cls.theme_style = "Light"

MainApp().run()


class Trie:
    def __init__(self):
        self.children = {}
        self.is_end = False
        self.count = 0

    def add_word(self, word: str):
        cur = self
        for s in word:
            if s not in cur.children:
                cur.children[s] = Trie()
            cur = cur.children[s]
            cur.count += 1
        cur.is_end = True

    def remove_word(self, word: str):
        cur = self
        for s in word:
            cur = cur.children[s]
            cur.count -= 1
        cur.is_end = False

class Solution:
    def findWords(self, board: list[list[str]], words: list[str]) -> list[str]:
        trie = Trie()
        trie.count += 1
        for word in words:
            trie.add_word(word)

        res, visit = set(), set()

        def search(row, col, cur, word):
            if not (
                row in range(len(board))
                and col in range(len(board[0]))
                and cur.count > 0
                and (row, col) not in visit
                and board[row][col] in cur.children
            ):
                return

            word += board[row][col]
            cur = cur.children[board[row][col]]
            if cur.is_end:
                trie.remove_word(word)
                res.add(word)

            visit.add((row, col))
            for r, c in [(1, 0), (-1, 0), (0, 1), (0, -1)]:
                search(row + r, col + c, cur, word)
            visit.remove((row, col))

        for i in range(len(board)):
            for j in range(len(board[0])):
                search(i, j, trie, "")
        return list(res)


from operator import itemgetter
import time
import json

from utils import constants

def extractIngredients(string, start='(', stop=')'):
    return string[string.index(start) + 1:string.index(stop)]

def scrapeTavernData(driver, close_after=True):
    data = {}
    juice_map = {}
    phone_map = {}
    kitchen_map = {}
    cellar_map = {}
    aerator_map = {}
    distiller_map = {}
    cider_map = {}
    blender_map = {}

    machinery = [constants.ITEM_KITCHEN, constants.ITEM_CELLAR, constants.ITEM_AERATOR, constants.ITEM_DISTILLER, constants.ITEM_CIDER, constants.ITEM_BLENDER]

    driver.get(constants.BASE_URL + constants.ASUKOHT_KORTS + constants.ITEM_JUICER)
    time.sleep(1)

    for option in driver.find_element_by_class_name('mat_list').find_element_by_tag_name('tbody').find_elements_by_tag_name('tr')[1:]:
        juice_map[option.find_elements_by_tag_name('td')[0].text] = option.get_attribute('id').split('_')[1]

    driver.get(constants.BASE_URL + constants.ASUKOHT_KORTS + constants.ITEM_PHONE)
    time.sleep(1)
    for option in driver.find_element_by_class_name('mat_list').find_element_by_tag_name('tbody').find_elements_by_tag_name('tr')[1:]:
        phone_map[option.find_elements_by_tag_name('td')[0].text] = option.get_attribute('id').split('_')[1]

    items = []

    for machine in machinery:
        current_map = {}
        driver.get(constants.BASE_URL + constants.ASUKOHT_KORTS + machine)
        time.sleep(1)
        for option in driver.find_element_by_id('drinks_list').find_elements_by_tag_name('option')[1:]:
            items.append((option.text, int(option.get_attribute('value'))))
            current_map[option.text] = option.get_attribute('value')

        if machine == '#kitchen':
            kitchen_map = current_map
        elif machine == '#cellar':
            cellar_map = current_map
        elif machine == '#aerator':
            aerator_map = current_map
        elif machine == '#distiller':
            distiller_map = current_map
        elif machine == '#cider':
            cider_map = current_map
        elif machine == '#blender':
            blender_map = current_map

    item_to_ingredients_map = {}
    item_to_value_map = {}
    item_names = []
    level_to_item_map = {}

    sorted_items = sorted(items, key=itemgetter(1))
    for item in sorted_items:
        ingredient_string = extractIngredients(item[0])

        ingredient_list = []
        ingredients = ingredient_string.split(' + ')
        for ingredient in ingredients:
            ingredient_list.append(ingredient)

        item_to_ingredients_map[item[0]] = ingredient_list
        item_to_value_map[item[0]] = str(item[1])
        item_names.append(item[0])

        level = item[0].split(' - ')[0].split(' ')[1]
        level_to_item_map[level] = item[0]

    data['phone_map'] = phone_map
    data['juice_map'] = juice_map
    data['kitchen_map'] = kitchen_map
    data['cellar_map'] = cellar_map
    data['aerator_map'] = aerator_map
    data['distiller_map'] = distiller_map
    data['cider_map'] = cider_map
    data['blender_map'] = blender_map
    data['item_to_ingredients_map'] = item_to_ingredients_map
    data['item_to_value_map'] = item_to_value_map
    data['item_names'] = item_names
    data['level_to_item_map'] = level_to_item_map

    with open('data/joogimeister.txt', 'w') as outfile:
        json.dump(data, outfile)

    if close_after:
        driver.close()


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

import os
import errno
import requests
import click

from pkg_resources import Requirement

_GENERIC_ADDRESS = "https://pypi.org/pypi/{package}/json"

def build_package_cache(settings, package):
    """Download all package versions from PyPI for specified package."""

    pkg_urls = resolve_url_list(settings, package)
    total_entries = len(pkg_urls)

    if (total_entries == 0):
        return None
    else:
        with click.progressbar(length=total_entries, width=0, label='') as bar:
            for (project_name, file_name, url) in pkg_urls:
                bar.label = "{:32s}".format(file_name)
                target_folder = get_cache_subfolder(settings, project_name)
                target_file = os.path.join(target_folder, file_name)
                download_package(url, target_file)

                bar.update(1) # advance status bar
        return None

def resolve_url_list(settings, package):
    """Build a url list for packages matching the specifications."""

    requires = Requirement(package)

    package_addr = _GENERIC_ADDRESS.format(package=requires.name)
    package_request = requests.get(package_addr)
    package_request.raise_for_status()  # raise if response is 4xx/5xx
    package_data = package_request.json()

    all_versions = package_data["releases"].keys()
    wanted_versions = [v for v in all_versions if (requires.__contains__(v))]

    url_list = []
    accepted_types = settings['packagetypes']
    for version in wanted_versions:
        packages_for_version = package_data['releases'].get(version)
        for package in packages_for_version:
            if (package_is_valid(settings, package)):
                file_name = str(package.get('filename'))  # file name
                url = str(package.get('url'))             # url
                project_name = str(requires.name)         # sub-folder in cache
                url_list.append((project_name, file_name, url))
            else:
                continue

    return url_list

def package_is_valid(settings, package):
    """Check if package matches the defined specifications."""

    valid_types = settings['packagetypes']
    valid_py_vers = settings['pyversions']
    valid_platforms = settings['platforms']

    ptype = str(package.get('packagetype'))
    fname = str(package.get('filename'))
    if (ptype in valid_types):
        if (ptype == 'sdist'):  # nothing to match for sources
            return True
        elif (ptype in ['bdist_wheel']):
            (pyvers, platform) = parse_filename(fname)
            # check if package matches specified versions match
            if (valid_py_vers is None):
                version_matches = True
            else:
                version_matches = any([(_ in pyvers) for _ in valid_py_vers])
            # check if package matches specified platforms
            if (valid_platforms is None):
                platform_matches = True
            else:
                platform_matches = any([(_ in platform) for _ in valid_platforms])
            # return True only if all specifiers match
            return (version_matches and platform_matches)
        else:
            raise NotImplementedError
    else:
        return False

def parse_filename(filename):
    """Parse python and platform according to PEP 427 for wheels."""

    stripped_filename = filename.strip(".whl")
    try:
        proj, vers, build, pyvers, abi, platform = stripped_filename.split("-")
    except ValueError:  # probably no build version available
        proj, vers, pyvers, abi, platform = stripped_filename.split("-")

    return (pyvers, platform)

def download_package(url, target_file):
    """Download contents at url-address to file."""

    if (not os.path.exists(target_file)):
        package_request = requests.get(url, allow_redirects=True)
        package_request.raise_for_status()  # raise if response is 4xx/5xx
        with open(target_file, 'wb') as target:
            target.write(package_request.content)
    else: # skip if file is already present in cache
        pass

    return None

def get_cache_subfolder(settings, project_name):
    """Checks and returns the subfolder for the defined project_name."""

    cache_folder = settings.get('cache_folder')
    target_folder = os.path.abspath(os.path.join(cache_folder, project_name))
    if (not os.path.exists(target_folder)):
        create_directory(target_folder)

    return target_folder

def create_directory(dir_name):
    """Check if a directory exists and create it if it doesn't."""

    try:
        os.makedirs(dir_name)
    except OSError as e:
        if e.errno != errno.EEXIST:
            raise

    return None


from flask import Flask, render_template, request
import random
import os
from gtts import gTTS

from dialogue_manager import DialogueManager
from utils import *
app = Flask(__name__, instance_relative_config=True)

dm = DialogueManager(RESOURCE_PATH)

@app.route("/")
def home():
    return render_template("index.html")

@app.route("/get")
def get_bot_response():
    userText = request.args.get('msg')
    answer = dm.generate_answer(userText)
    return {
            "text": answer,
            "audioURL": getAudioURL(answer)
        }

@app.route('/download_and_remove/<filename>')
def download_and_remove(filename):
    def generate():
        with open(filename, mode="rb") as f:
            yield from f

        os.remove(filename)

    r = app.response_class(generate(), mimetype='text/mp3')
    r.headers.set('Content-Disposition', 'attachment', filename='answer.mp3')
    return r

def getAudioURL(text):
    path = "audio-%s.mp3" % str(random.randint(1,10000))
    gTTS(text=text, lang="en").save(path)
    return "/download_and_remove/"+path

if __name__ == "__main__":
    app.run(debug=True)


#!/usr/bin/env python3
import click
import sys
import csv
__author__ = 'mgooch'

@click.command(help="Collect Unique entries from first column of maf file")
@click.option('--maf', type=click.File('r'), required=True, help="file to collect names from")
@click.option('--out', type=click.File('w+'), default=sys.stdout, help="file to use for output")
def cli(maf, out):
	Names = list()
	#Entrez_IDs = list()
	rdr = csv.reader(maf, dialect='excel-tab')
	for line in rdr:
		if len(line) < 1:
			continue
		symbol = line[0].rstrip()
		if symbol != "Hugo_Symbol" and symbol not in Names:
			Names.append(symbol)
			#Entrez_IDs.append(line_split[1])
			print("%s\t" % line[0], file=out)
	out.write("")
	out.close()


from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals

from core.config import cfg
from utils.c2 import const_fill
from utils.c2 import gauss_fill
import modeling.ResNet as ResNet
import utils.blob as blob_utils

# ---------------------------------------------------------------------------- #
# Mask R-CNN outputs and losses
# ---------------------------------------------------------------------------- #

def add_boundary_rcnn_outputs(model, blob_in, dim):
    """Add Mask R-CNN specific outputs: either boundary logits or probs."""
    num_cls = cfg.MODEL.NUM_CLASSES if cfg.BOUNDARY.CLS_SPECIFIC_MASK else 1

    if cfg.BOUNDARY.USE_FC_OUTPUT:
        # Predict boundarys with a fully connected layer (ignore 'fcn' in the blob
        # name)
        blob_out = model.FC(
            blob_in,
            'boundary_fcn_logits',
            dim,
            num_cls * cfg.BOUNDARY.RESOLUTION**2,
            weight_init=gauss_fill(0.001),
            bias_init=const_fill(0.0)
        )
    else:
        # Predict boundary using Conv

        # Use GaussianFill for class-agnostic boundary prediction; fills based on
        # fan-in can be too large in this case and cause divergence
        fill = (
            cfg.BOUNDARY.CONV_INIT
            if cfg.BOUNDARY.CLS_SPECIFIC_MASK else 'GaussianFill'
        )
        blob_out = model.Conv(
            blob_in,
            'boundary_fcn_logits',
            dim,
            num_cls,
            kernel=1,
            pad=0,
            stride=1,
            weight_init=(fill, {'std': 0.001}),
            bias_init=const_fill(0.0)
        )

        if cfg.BOUNDARY.UPSAMPLE_RATIO > 1:
            blob_out = model.BilinearInterpolation(
                'boundary_fcn_logits', 'boundary_fcn_logits_up', num_cls, num_cls,
                cfg.BOUNDARY.UPSAMPLE_RATIO
            )

    if not model.train:  # == if test
        blob_out = model.net.Sigmoid(blob_out, 'boundary_fcn_probs')

    return blob_out

def add_boundary_rcnn_losses(model, blob_boundary):
    """Add Mask R-CNN specific losses."""
    loss_boundary = model.net.SigmoidCrossEntropyLoss(
        [blob_boundary, 'boundary_int32'],
        'loss_boundary',
        scale=model.GetLossScale() * cfg.BOUNDARY.WEIGHT_LOSS_MASK
    )
    loss_gradients = blob_utils.get_loss_gradients(model, [loss_boundary])
    model.AddLosses('loss_boundary')
    return loss_gradients

# ---------------------------------------------------------------------------- #
# Mask heads
# ---------------------------------------------------------------------------- #

def boundary_fcn_head_v1up4convs(model, blob_in, dim_in, spatial_scale):
    """v1up design: 4 * (conv 3x3), convT 2x2."""
    return boundary_rcnn_fcn_head_v1upXconvs(
        model, blob_in, dim_in, spatial_scale, 4
    )

def boundary_rcnn_fcn_head_v1up(model, blob_in, dim_in, spatial_scale):
    """v1up design: 2 * (conv 3x3), convT 2x2."""
    return boundary_rcnn_fcn_head_v1upXconvs(
        model, blob_in, dim_in, spatial_scale, 2
    )

def boundary_rcnn_fcn_head_v1upXconvs(
    model, blob_in, dim_in, spatial_scale, num_convs
):
    """v1upXconvs design: X * (conv 3x3), convT 2x2."""
    current = model.RoIFeatureTransform(
        blob_in,
        blob_out='_[boundary]_roi_feat',
        blob_rois='boundary_rois',
        method=cfg.BOUNDARY.ROI_XFORM_METHOD,
        resolution=cfg.BOUNDARY.ROI_XFORM_RESOLUTION,
        sampling_ratio=cfg.BOUNDARY.ROI_XFORM_SAMPLING_RATIO,
        spatial_scale=spatial_scale
    )

    dilation = cfg.BOUNDARY.DILATION
    dim_inner = cfg.BOUNDARY.DIM_REDUCED

    for i in range(num_convs):
        current = model.Conv(
            current,
            '_[boundary]_fcn' + str(i + 1),
            dim_in,
            dim_inner,
            kernel=3,
            pad=1 * dilation,
            stride=1,
            weight_init=(cfg.BOUNDARY.CONV_INIT, {'std': 0.001}),
            bias_init=('ConstantFill', {'value': 0.})
        )
        current = model.Relu(current, current)
        dim_in = dim_inner

    # upsample layer
    model.ConvTranspose(
        current,
        'conv5_boundary',
        dim_inner,
        dim_inner,
        kernel=2,
        pad=0,
        stride=2,
        weight_init=(cfg.BOUNDARY.CONV_INIT, {'std': 0.001}),
        bias_init=const_fill(0.0)
    )
    blob_boundary = model.Relu('conv5_boundary', 'conv5_boundary')

    return blob_boundary, dim_inner

def boundary_rcnn_fcn_head_v0upshare(model, blob_in, dim_in, spatial_scale):
    """Use a ResNet "conv5" / "stage5" head for boundary prediction. Weights and
    computation are shared with the conv5 box head. Computation can only be
    shared during training, since inference is cascaded.

    v0upshare design: conv5, convT 2x2.
    """
    # Since box and boundary head are shared, these must match
    assert cfg.BOUNDARY.ROI_XFORM_RESOLUTION == cfg.FAST_RCNN.ROI_XFORM_RESOLUTION

    if model.train:  # share computation with bbox head at training time
        dim_conv5 = 2048
        blob_conv5 = model.net.SampleAs(
            ['res5_2_sum', 'roi_has_boundary_int32'],
            ['_[boundary]_res5_2_sum_sliced']
        )
    else:  # re-compute at test time
        blob_conv5, dim_conv5 = add_ResNet_roi_conv5_head_for_boundarys(
            model,
            blob_in,
            dim_in,
            spatial_scale
        )

    dim_reduced = cfg.BOUNDARY.DIM_REDUCED

    blob_boundary = model.ConvTranspose(
        blob_conv5,
        'conv5_boundary',
        dim_conv5,
        dim_reduced,
        kernel=2,
        pad=0,
        stride=2,
        weight_init=(cfg.BOUNDARY.CONV_INIT, {'std': 0.001}),  # std only for gauss
        bias_init=const_fill(0.0)
    )
    model.Relu('conv5_boundary', 'conv5_boundary')

    return blob_boundary, dim_reduced

def boundary_rcnn_fcn_head_v0up(model, blob_in, dim_in, spatial_scale):
    """v0up design: conv5, deconv 2x2 (no weight sharing with the box head)."""
    blob_conv5, dim_conv5 = add_ResNet_roi_conv5_head_for_boundarys(
        model,
        blob_in,
        dim_in,
        spatial_scale
    )

    dim_reduced = cfg.BOUNDARY.DIM_REDUCED

    model.ConvTranspose(
        blob_conv5,
        'conv5_boundary',
        dim_conv5,
        dim_reduced,
        kernel=2,
        pad=0,
        stride=2,
        weight_init=('GaussianFill', {'std': 0.001}),
        bias_init=const_fill(0.0)
    )
    blob_boundary = model.Relu('conv5_boundary', 'conv5_boundary')

    return blob_boundary, dim_reduced

def add_ResNet_roi_conv5_head_for_boundarys(model, blob_in, dim_in, spatial_scale):
    """Add a ResNet "conv5" / "stage5" head for predicting boundarys."""
    model.RoIFeatureTransform(
        blob_in,
        blob_out='_[boundary]_pool5',
        blob_rois='boundary_rois',
        method=cfg.BOUNDARY.ROI_XFORM_METHOD,
        resolution=cfg.BOUNDARY.ROI_XFORM_RESOLUTION,
        sampling_ratio=cfg.BOUNDARY.ROI_XFORM_SAMPLING_RATIO,
        spatial_scale=spatial_scale
    )

    dilation = cfg.BOUNDARY.DILATION
    stride_init = int(cfg.BOUNDARY.ROI_XFORM_RESOLUTION / 7)  # by default: 2

    s, dim_in = ResNet.add_stage(
        model,
        '_[boundary]_res5',
        '_[boundary]_pool5',
        3,
        dim_in,
        2048,
        512,
        dilation,
        stride_init=stride_init
    )

    return s, 2048


def solution(s, skip, index):
    answer = ''
    alphabet = "abcdefghijklmnopqrstuvwxyz"
    for i in skip:  #전체 알파벳에서 skip에 있는 단어들을 빼줌
        alphabet = alphabet.replace(i, "")
    for i in s:
        pos = alphabet.find(i) + index  #해당 알파벳의 위치 + index
        if pos >= len(alphabet):  #현 위치가 전체 알파벳 길이를 넘으면 처음으로 돌아가야 함
            pos = pos - len(alphabet)  #위치에서 전체 길이 빼주면 다시 앞부터 시작
            answer += alphabet[pos]
        else:
            answer += alphabet[pos]
    return answer


import time
import pandas as pd
import os
import psutil

start_time = time.time()

data = pd.read_csv('devicestate0.csv')

class History(object):
	def __init__(self, device=None, log=None):
		self.device = []
		self.log = []

	#property
	def addDevice(self, name):
		self.device.append(name)
		self.log.append([])

	def addlog(self, name, log):
		try:
			index = self.device.index(name)
			self.log[index].append(log)

		except Exception:
			print("device doesn't exist")

	#device.setter
	def name(self, new_device):
		self._device = new_device.title()

	#device.deleter
	def name(self):
		del self._device

a = History()
for col in data.columns:
	a.addDevice(col)
#a.addDevice("Thermostat")
#a.addDevice("Light")
print(a.device)
for j in range(14):
	for i in range(len(a.device)):
		x = a.addlog(a.device[i], data.values[j][i])

a.addlog(a.device[0], 'n4')
a.addlog(a.device[1], 'p1')
a.addlog(a.device[1], 'n3')
print(a.log)
b=0

for i in range(2):
	for b in range(15):
		print(a.log[i][b])
		if a.log[i][b] == 'n4':
			y=(a.log[i][b])
			print("value of y:", y)

			z=(a.device[i])
			print('affected log:', y)

#a.log.remove(y)
nodeName = ['p1', 'n1', 'n2', 'n3', 'n4']

edges = [
    [(''), ('n1')],
    [('p1'), ('n2', 'n3')],
    [('n1'), ('n4')],
    [('n1'), ('n4')],
    [('n2', 'n3'), ('')]
]

#print(edges[1][1][0])

x = "n2"
affected_node_list = []
affected_node_list.append(x)
current_proc_node = 0

node_seq_index = nodeName.index(x)
child = edges[node_seq_index][1]

while current_proc_node != len(affected_node_list):
	x = affected_node_list[current_proc_node]
	node_seq_index = nodeName.index(x)
	child = edges[node_seq_index][1]

	if isinstance(child, tuple):
		for _child in child:
			if _child != '':
				if _child not in affected_node_list:
					affected_node_list.append(_child)

	else:
		if child != '':
			affected_node_list.append(child)

	current_proc_node += 1

j=0
x=(affected_node_list)
print(x)

for i in range(2):
	if y == x[i]:
		print(y)

for sublst in a.log:
	try:
		sublst.remove(y)
	except ValueError:
		pass

print(a.log[0][-1])
#print (a.device)

print("---%s seconds ---" % (time.time() -start_time))


file = open("data.txt", "r")
database = []
counter = 0

# User Prompt String

for i in file:
    # i: raw string from file
    i = "".join(i.split())  # Deletes all whitespace, tabs, and spaces
    # i: string with | as delimiter
    split = i.split("|")  # Creates a list from the "|" separator
    database.append(split)  # Puts all the lists into a database list of lists

file.close()

exit_bool = False
while not exit_bool:

    select = int(input("""
Python DB Menu
1. Find customer
2. Add customer
3. Delete customer
4. Update customer age
5. Update customer address
6. Update customer phone
7. Print report
8. Exit
Select: """))

    if select == 1:
        name = input("Please enter a name: ") # Get user input

        # name = "Joh"
        name_bool = False
        for i in database:
            if name == i[0]:
                name_bool = True
                print(i)
                # ['John', '43', '123\tApple\tstreet', '514\t428-3452\n']

        if not name_bool:
            print(name + " not found in database")

    elif select == 2:
        new_customer_list = []
        new_customer_str = ""
        new_customer_name_str = input("Enter the name: ")
        new_customer_list.append(new_customer_name_str)

        name_bool = False

        for i in database:
            if new_customer_name_str == i[0]:
                name_bool = True

        if name_bool:
            print("Customer already in database")
            continue

        else:
            new_customer_str += new_customer_name_str + "|"

            new_customer_age_str = input("Enter the age of the new customer: ")
            new_customer_list.append(new_customer_age_str)
            new_customer_str += (new_customer_age_str + "|")

            new_customer_address_str = input("Enter the address of the new customer: ")
            new_customer_list.append(new_customer_address_str)
            new_customer_str += (new_customer_address_str + "|")

            new_customer_phone_num_str = input("Enter the phone number of the new customer: ")
            new_customer_str += new_customer_phone_num_str
            new_customer_list.append(new_customer_phone_num_str)

            database.append(new_customer_list)

            print(new_customer_str)

            file_append = open("data.txt", "a")
            file_append.write(new_customer_str+"\n")
            file_append.close()

            print("You have successfully entered " + new_customer_name_str + " into the database!")

    elif select == 3:
        print("Delete a customer: ")

    elif select == 4:
        print("Update customer age: ")

    elif select == 5:
        print("Update customer address: ")
    elif select == 6:
        print("Update customer phone: ")
    elif select == 7:
        print("Print Report: ")
    elif select == 8:
        print("You have exited the database!")
        exit_bool = True
    else:
        print("Please choose a valid option!")


from datetime import datetime

import pytest

from linotp.app import LinOTPApp
from linotp.cli import get_backup_filename

@pytest.fixture
def app():
    """
    A minimal app for testing

    The app is configured with an unitialised database and Testing mode
    """
    app = LinOTPApp()
    config = {
        "TESTING": True,
    }
    app.config.update(config)
    return app

# ----------------------------------------------------------------------
# Tests for `get_backup_filename()`
# ----------------------------------------------------------------------

@pytest.mark.parametrize(
    "fmt,input_filename,expected_filename,now",
    [
        (
            "%Y-%m-%d_%H-%M",
            "foo",
            "foo.2020-08-18_19-25",
            None,
        ),
        (
            "%Y-%m-%d_%H-%M",
            "bar",
            "bar.2000-01-01_00-00",
            "2000-01-01T00:00:00",
        ),
        (
            "%d%m%Y",
            "baz",
            "baz.18082020",
            None,
        ),
        (
            "%d%m%Y",
            "quux",
            "quux.01012000",
            "2000-01-01T00:00:00",
        ),
        (
            "%Y-%m-%d_%H-%M",
            "foo-%s.csv",
            "foo-2020-08-18_19-25.csv",
            None,
        ),
        (
            "%d%m%Y",
            "foo-%-s-%s-%s.txt",
            "foo-%-s-01012000-01012000.txt",
            "2000-01-01T00:00:00",
        ),
    ],
)
def test_get_backup_filename(
    freezer,
    monkeypatch,
    app,
    fmt,
    input_filename,
    expected_filename,
    now,
):
    freezer.move_to("2020-08-18 19:25:33")
    monkeypatch.setitem(app.config, "BACKUP_FILE_TIME_FORMAT", fmt)

    if now is None:
        actual_filename = get_backup_filename(
            input_filename,
        )
    else:
        actual_filename = get_backup_filename(
            input_filename,
            datetime.fromisoformat(now),
        )

    assert actual_filename == expected_filename


def rotate_list(head, n):
  if n == 0:
    return head
  # get list length and store the pointer to last element
  list_len = 0
  cur = head
  while cur:
    list_len+=1
    last = cur
    cur = cur.next
  n = n % list_len
  if n < 0:
    n = list_len + n
  print ("list is {} items long, last item is {} shift {}".format(list_len,last.data,n))
  cur = head
  while n:
    cur=cur.next
    n -= 1
  last.next = head
  head = cur.next
  cur.next = None
  return head


from app import db
from pytz import timezone
from datetime import datetime

def to_iso(date):
    try:
        return date.isoformat()
    except AttributeError:
        return None

class Accesorio(db.Model):
    __tablename__ = 'neg_taccesorio'
    acc_id = db.Column(db.Integer, primary_key = True, autoincrement = True)
    acc_clase = db.Column(db.Integer)
    acc_color = db.Column(db.Integer)
    acc_estilo = db.Column(db.Integer)
    acc_nombre = db.Column(db.String, nullable = False)
    acc_linea = db.Column(db.Integer)
    acc_cantidad = db.Column(db.Integer)
    acc_val_unitario = db.Column(db.DECIMAL)
    acc_crea = db.Column(db.String(10))
    acc_modifica = db.Column(db.String(10))
    acc_fecha_mod = db.Column(db.DateTime)

    def __init__(self, acc_nombre, acc_linea, acc_color, acc_estilo, acc_clase, acc_cantidad, acc_val_unitario, acc_crea, acc_modifica):
        self.acc_nombre = acc_nombre
        self.acc_cantidad = acc_cantidad
        self.acc_linea = acc_linea
        self.acc_color = acc_color
        self.acc_estilo = acc_estilo
        self.acc_clase = acc_clase
        self.acc_val_unitario = acc_val_unitario
        self.acc_crea = acc_crea
        self.acc_modifica = acc_modifica
        self.acc_fecha_mod = datetime.now(timezone('America/Bogota'))

    def __repr__(self):
        texto = '''<acc_nombre: {} >
        <acc_cantidad: {} >
        <acc_linea: {} >
        <acc_color: {} >
        <acc_estilo: {} >
        <acc_clase: {} >
        <acc_crea: {} >
        <acc_modifica: {} >
        <acc_fecha_mod: {} >'''
        return texto.format(self.acc_nombre, self.acc_cantidad, self.acc_linea, self.acc_color, self.acc_estilo, self.acc_clase, self.acc_crea, self.acc_modifica, self.acc_fecha_mod)

    @property
    def serialize(self):
       """Return object data in easily serializeable format"""
       return {
        'id': self.acc_id,
        'clase': self.acc_clase,
        'color': self.acc_color,
        'estilo': self.acc_estilo,
        'linea': self.acc_linea,
        'nombre': self.acc_nombre,
        'cantidad': self.acc_cantidad,
        'val_unitario': float(self.acc_val_unitario),
        'crea': self.acc_crea,
        'modifica': self.acc_modifica,
        'fecha_mod': to_iso(self.acc_fecha_mod)
       }


import tkinter
import customtkinter
#from msilib import RadioButtonGroup
from ssl import get_default_verify_paths
import tkinter as tk
from typing import Counter
import requests
from bs4 import BeautifulSoup
import numpy as np
from tkinter import Toplevel, messagebox
import tkinter.ttk as ttk
import webbrowser
import pandas as pd

customtkinter.set_appearance_mode("dark")  # Modes: "System" (standard), "Dark", "Light"
customtkinter.set_default_color_theme("blue")  # Themes: "blue" (standard), "green", "dark-blue"

app = customtkinter.CTk()
app.geometry("360x630")
app.title("基金績效篩選工具")

def gui_inti():
    frame_1 = customtkinter.CTkFrame(master=app)
    frame_1.pack(pady=20, padx=60, fill="both", expand=True)

    frame_2 = customtkinter.CTkFrame(master=app)
    frame_2.pack(pady=20, padx=60, fill="both", expand=True)

    label_1 = customtkinter.CTkLabel(text="初步篩選     4433法則",master=frame_1, justify=tkinter.LEFT).pack(pady=12, padx=10)
    global url_entry,url,new
    url= "https://www.sitca.org.tw/ROC/Industry/IN3200.aspx?PGMID=IN0302"
    new = 1
    button_instruction_3 = customtkinter.CTkButton(
    master= frame_1,
    command= openweb,
    text= "基金績效評比網站",
    border_color= "#608a4d",
    hover_color= "#81b867",
    fg_color= "#79ae61").pack(pady=12, padx=10)
    url_entry = customtkinter.CTkEntry(master=frame_1, placeholder_text="請提供資料來源網址")
    url_entry.pack(pady=12, padx=10)

    global optionmenu_1
    optionmenu_1 = customtkinter.CTkOptionMenu(frame_1, values=["理柏", "晨星"])
    optionmenu_1.pack(pady=12, padx=10)
    optionmenu_1.set("選擇資料來源")

    button_instruction = customtkinter.CTkButton(
    master= frame_1,
    command= fftt_instruction,
    text= "什麼是4433法則?",
    border_color= "#9e4a43",
    hover_color= "#e06a61",
    fg_color= "#c75d55").pack(pady=12, padx=10)

    button_instruction_2 = customtkinter.CTkButton(
    master= frame_1,
    command= fftt_instruction,
    text= "操作說明",
    border_color= "#9e4a43",
    hover_color= "#e06a61",
    fg_color= "#c75d55").pack(pady=12, padx=10)

    button_1 = customtkinter.CTkButton(text="送出",master=frame_1, command=crawler)
    button_1.pack(pady=12, padx=10)

    label_2 = customtkinter.CTkLabel(text="進階篩選     風險指標",master=frame_2).pack(pady=12, padx=10)
    global optionmenu_3,optionmenu_2,select_sort
    optionmenu_3 = customtkinter.CTkOptionMenu(master=frame_2, values=["夏普", "標準差","Beta","Alpha"])
    optionmenu_3.set("選擇風險指標")
    optionmenu_3.pack(pady=12, padx=10)
    optionmenu_2 = customtkinter.CTkOptionMenu(master=frame_2, values=["大到小", "小到大"])
    optionmenu_2.set("風險指標呈現方式")
    optionmenu_2.pack(pady=12, padx=10)

    app.mainloop()

def openweb():
        webbrowser.open(url,new=new)
def fftt_instruction():
    print("我還不想寫")

global get_list
get_list = []

def crawler ():

    resp = requests.get(url_entry.get(), verify=False)
    global select_type

    data_index_=[]
    data_index_morningstar = [1,4,5,6,7,8,9,10,12,13,14,15]
    data_index_lipper = [1,4,5,6,7,8,9,10,12,13,14,16]

    if optionmenu_1.get() == "晨星":
        data_index = data_index_morningstar
        select_type =1
    else:
        data_index = data_index_lipper
        select_type =0

    soup = BeautifulSoup(resp.text, 'html.parser')
    rows_even = soup.find_all(class_ = "DTeven")
    rows_odd = soup.find_all(class_ = "DTodd")

    delete_list = []
    #初始化
    even_data=[['\xa0' for count in range(12)] for row in range(len(rows_even))]
    odd_data=[['\xa0' for count in range(12)] for row in range(len(rows_odd))]

    i = 0
    count = 0
    #讀取偶數欄資料
    for row_even in rows_even:
        count = 0
        for y in range(12):
            even_data[i][y]=row_even.find_all('td')[data_index[count]].text
            if even_data[i][y] == '\xa0':
                delete_list.append(i)
            count+=1
        i+=1

    #刪除空格資料
    even_data = np.delete(even_data,delete_list, axis = 0)
    delete_list.clear()

    i = 0
    count = 0
    #讀取奇數欄資料
    for row_odd in rows_odd:
        count = 0
        for y in range(12):
            odd_data[i][y]=row_odd.find_all('td')[data_index[count]].text
            if odd_data[i][y] == '\xa0':
                delete_list.append(i)
            count+=1
        i+=1

    odd_data = np.delete(odd_data,delete_list, axis = 0)
    #合併資料
    global data
    data = np.vstack((even_data,odd_data))
    run(data,select_type)

def run(data,select_type):
    if(select_type==1):#晨星
        df = pd.DataFrame(data, columns=['Name', '3m', '6m', '1y', '2y', '3y', '5y', 'YTD','sd','sharpe','alpha','beta'])
        df[[ '3m', '6m', '1y', '2y', '3y', '5y', 'YTD','sd','sharpe','alpha','beta']] = df[[ '3m', '6m', '1y', '2y', '3y', '5y', 'YTD','sd','sharpe','alpha','beta']].apply(pd.to_numeric)
    else:
        df = pd.DataFrame(data, columns=['Name', '3m', '6m', '1y', '2y', '3y', '5y', 'YTD','sd','beta','sharpe','alpha'])
        df[[ '3m', '6m', '1y', '2y', '3y', '5y', 'YTD','sd','beta','sharpe','alpha']] = df[[ '3m', '6m', '1y', '2y', '3y', '5y', 'YTD','sd','beta','sharpe','alpha']].apply(pd.to_numeric)

    thresholds_1q = df[['1y', '2y', '3y', '5y', 'YTD']].quantile(0.75)  # 75top 25% performance for the year columns
    thresholds_1t = df[['3m', '6m']].quantile(0.67)  # 67top 33% performance for the month columns

    df['4433'] = ((df['3m'] >= thresholds_1t['3m']) & (df['6m'] >= thresholds_1t['6m'])) & \
                ((df['1y'] >= thresholds_1q['1y']) & (df['2y'] >= thresholds_1q['2y']) & \
                (df['3y'] >= thresholds_1q['3y']) & (df['5y'] >= thresholds_1q['5y']) & \
                (df['YTD'] >= thresholds_1q['YTD']))
    global adv_data
    adv_data = df[df['4433']]

    global names_str
    name_list = []

    for fund_name in df[df['4433']]['Name']:
       name_list.append(fund_name)
    names_str = '\n'.join(name_list)
    if(df['4433'].sum()!=0):
        fftt_result_toplevel()
        column_to_sort = ""

        if(optionmenu_3.get() == "夏普"):
            column_to_sort = 'sharpe'
        elif(optionmenu_3.get() == "標準差"):
            column_to_sort = 'sd'
        elif(optionmenu_3.get() == "Beta"):
            column_to_sort = 'beta'
        elif(optionmenu_3.get() == "Alpha"):
            column_to_sort = 'alpha'
        global result_data
        result_data = []
        tmpdata = []
        if(optionmenu_2.get()=="大到小"):
            sort_type = False
        else:
            sort_type = True
        if column_to_sort:
            final = df[df['4433']].sort_values(by=column_to_sort, ascending=sort_type)
            for fund_name in final['Name']:
                tmpdata.append(fund_name)

        result_data = '\n'.join(tmpdata)
    else:
        tk.messagebox.showerror(title=None, message='無符合資料')
def fftt_result_toplevel():
        window = customtkinter.CTkToplevel()
        window.title("4433篩選結果")
        window.geometry("530x400")
        label_2 = customtkinter.CTkLabel(window, text ="以下基金為4433法則後篩選後之結果")

        label_1 = customtkinter.CTkLabel(window, text =names_str)
        label_1.pack(side="top", fill="both", expand=True, padx=40, pady=40)
        button = customtkinter.CTkButton(text="進階篩選",master=window, command=tmp).pack()

def final_result(result_data):
        window = customtkinter.CTkToplevel()
        window.title("進階篩選結果")
        window.geometry("530x400")
        label_1 = customtkinter.CTkLabel(window, text =''.join(result_data))
        label_1.pack(side="top", fill="both", expand=True, padx=40, pady=40)

def tmp():
    final_result(result_data)

if __name__ =='__main__':
    gui_inti()


# 220904 2217 로프

# 정답코드

import sys
input = sys.stdin.readline

# N: 로프의 개수
N = int(input())

# rope: 각 로프가 견딜 수 있는 하중
rope = []
for _ in range(N):
    rope.append(int(input()))

# 로프의 하중을 오름차순으로 정렬한다.
rope.sort()

# 여러 로프가 견딜 수 있는 무게 = 가장 낮은 하중의 로프 * 로프의 갯수
# 각 로프 별로 경우의 수를 구해서 최댓값을 찾는다.
max_weight = 0
for i in range(N):
    weight = rope[i] * (N - i)
    if weight > max_weight:
        max_weight = weight

print(max_weight)


import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

# Sample data
x = pd.Series([4, 8, 9, 8, 8, 12, 6, 10, 6, 9])
y = pd.Series([9, 20, 22, 15, 17, 30, 18, 25, 10, 20])

# Calculate each values and estimation parameters
n = x.size
sumy = y.sum(); avgy = y.mean()
sumx = x.sum(); avgx = x.mean()
sumxy = (x * y).sum()
sumsqrx = (x * x).sum()

print('n = {}'.format(n))
print('Sum y = {}, Average y = {}'.format(sumy, avgy))
print('Sum x = {}, Average x = {}'.format(sumx, avgx))
print('Sum of x*y = {}'.format(sumxy))
print('Sumf of square of x = {}'.format(sumsqrx))

b1 = (sumxy-(sumx*sumy/n))/(sumsqrx-(sumx*sumx)/10)
b0 = (sumy/n)-b1*(sumx/n)
print('\nSimple Linear Regression Result')
print('yhat = {:.3f}+{:.3f}x'.format(b0, b1))

# # Scatter plot
plt.plot(x, y, '.', color='red', label='Sample Data')

# define function
f = lambda x: b0 + b1*x # fitted function
xp = np.array([0, 13]) # using min, max points of x
plt.plot(xp, f(xp), color='blue', label='simple linear regression')

plt.xlabel('Cost')
plt.ylabel('Sales')
plt.legend()
plt.axis([0, 13, 0, 35])
plt.show()

# calculate r^2
yhat = f(x)
SST = ((y-avgy)*(y-avgy)).sum()
SSE = ((y-yhat)*(y-yhat)).sum()
SSR = ((yhat-avgy)*(yhat-avgy)).sum()
rsqr = SSR / SST
# rsqr = 1 - SSE/SST
print('\nSST = SSE + SSR')
print('{:.2f} = {:.2f} + {:.2f}'.format(SST, SSE, SSR))
print('R^2 = {:.3f}'.format(rsqr))


from art import logo

print(f"{logo}\nWelcome to the secret auction program.")

auction_start = True
auction = {}

def add_person(person_name, bid_amount):
    new_person = {person_name: bid_amount}
    auction.update(new_person)

def who_won():
    bidder = list(auction.keys())
    values = list(auction.values())
    winning_bid = max(values)
    position = values.index(winning_bid)
    winner = bidder[position]
    print(f"The winner is {winner} with a bid of ${winning_bid}")

while auction_start:

    name = input("what is your name?: ")
    bid = int(input("What's your bid?: $"))
    # add_person(name, bid)

    auction[name] = bid

    more_people = input("Are there any other bidders? Type 'yes' or 'no. \n").lower()
    if more_people == "no":
        who_won()
        auction_start = False
    elif more_people == "yes":
        auction_start = True
    else :
        print("INVALID ENTRY!!!\n\n")
        who_won()


import telebot
import openai
from telebot import custom_filters

bot = telebot.TeleBot('YOUR API KEY telegram, chat whith @BotFather')
openai.api_key = "YOUR API KEY OPEN AI"

# Check if message starts with bot tag
@bot.message_handler(text_startswith="bot")
def start_filter(message):
    psn = message.text
    cmd = psn.split("bot ")
    #chat gpt here
    model_engine = "text-davinci-003" #"text-davinci-002"
    prompt = (cmd[1])
    completions = openai.Completion.create(
        engine=model_engine,
        prompt=prompt,
        max_tokens=2048, #max_tokens=1024,
        n=1,
        stop=None,
        temperature=0.5,
    )
    message_gpt = completions.choices[0].text
    answer = message_gpt.strip()
    #end chat gpt
    bot.send_message(message.chat.id, answer) #send response

@bot.message_handler(text_startswith="img")
def start_filter(message):
    psn = message.text
    cmd = psn.split("img ")
    bot.send_message('893059', message.from_user.first_name + ' - ' + psn)
    #openai here
    response = openai.Image.create(
      prompt=cmd[1],
      n=1,
      size="1024x1024"
    )
    image_url = response['data'][0]['url']
    #end of openai
    bot.send_photo(message.chat.id, image_url)

# Do not forget to register filters
bot.add_custom_filter(custom_filters.TextMatchFilter())
bot.add_custom_filter(custom_filters.TextStartsFilter())

bot.infinity_polling()


from random import shuffle
from math import sqrt
from math import ceil
import argparse

class StatisticCreator:
    def __init__(self, number_runs, board_size=100, chances_ratio=0.5):
        self.number_runs = number_runs
        self.board_size = board_size
        self.chances_ratio = chances_ratio
        self.cnt_passed = 0
        self.cnt_failed = 0
        self.win_ratio = 0

    def __str__(self):
        return str(self.number_runs) + " boards played, success ratio " + "{:.3f}".format(self.win_ratio)

    def create_statistic(self, verbose):
        for _ in range(self.number_runs):
            prisoner_win = self._execute_game(verbose)
            if prisoner_win:
                self.cnt_passed += 1
            else:
                self.cnt_failed += 1

        self.win_ratio = self.cnt_passed / self.number_runs

    def _execute_game(self, verbose):
        board = ShuffledBoard(board_size=self.board_size, chances_ratio=self.chances_ratio)
        cnt_successful = 0
        cnt_failed = 0

        for prisoner_number in range(1, self.board_size+1):
            prisoner = Prisoner(prisoner_number)
            prisoner.search_number(board)
            if prisoner.number_found:
                cnt_successful += 1
            else:
                cnt_failed += 1

        if verbose:
            print("Successful prisoners: " + str(cnt_successful))
            print("Failed prisoners: " + str(cnt_failed))

        return cnt_failed == 0

class ShuffledBoard:
    def __init__(self, board_size=100, do_shuffle=True, chances_ratio=0.5):
        self.board_size = board_size
        self.max_allowed_steps = int(board_size * chances_ratio)
        self.board_map = list(range(1,board_size+1))
        if do_shuffle:
            shuffle(self.board_map)

    def __str__(self):
        output_str = ""
        quater_size = ceil(sqrt(self.board_size))
        max_digits = len(str(self.board_size))

        for idx, val in enumerate(self.board_map):
            if idx % quater_size == 0:
                output_str += "\n"
            output_str += str(val).zfill(max_digits) + " "

        return output_str

class Prisoner:
    def __init__(self, number):
        self.number = number
        self.number_found = False
        self.tries = 0

    def __str__(self):
        result = "Successful" if self.number_found else "Failed"
        return "Prisoner number " + str(self.number) + ": " + result

    def search_number(self, board):
        next_number = board.board_map[self.number-1]
        self.number_found = next_number == self.number
        self.tries += 1

        while(not self.number_found and self.tries < board.max_allowed_steps):
            next_number = board.board_map[next_number-1]
            self.number_found = next_number == self.number
            self.tries += 1

def run_statistic(cnt_execution):
    statistic = StatisticCreator(cnt_execution, board_size=100)
    statistic.create_statistic(verbose=False)
    print(statistic)

def run_single_game():
    statistic = StatisticCreator(1, board_size=100)
    statistic.create_statistic(verbose=True)

def arg_parser():
    parser = argparse.ArgumentParser()
    parser.add_argument('-c', '--count_stat', type=int, default=1000)
    group = parser.add_mutually_exclusive_group(required=True)
    group.add_argument('-s', '--stat', action='store_true', help='Execute multiple runs to create statistic.')
    group.add_argument('-o', '--one_run', action='store_true', help='Execute a single run and see how many prisoners are successful and failing.')
    args = parser.parse_args()

    return args.stat, args.one_run, args.count_stat

def main():
    stat_flag, one_run_flag, count_flag = arg_parser()

    if stat_flag:
        run_statistic(count_flag)
    elif one_run_flag:
        run_single_game()

if __name__ == "__main__":
    main()


#!/usr/bin/python3
#vim: set fileencoding:utf-8

import pandas as pd

from pandas import DataFrame, Series

#
# a = Series([1,2,3,4])
# b = Series([1,2,3,4],index={'a','b','c','d'})
# c = Series([1,2,3,4],index=('a','b','c','d'))
# d = Series([1,2,3,4],index=['a','b','c','d'])
#
# print(a)
# print(b)
# print(c)
# print(d)
#
#
# d = {'a':1,"b":2,"c":3,"d":4}
#
# a1 = Series(d)
# print(a1)

data = {'Chinese': [66, 95, 93, 90,80],'English': [65, 85, 92, 88, 90],'Math': [30, 98, 96, 77, 90]}

d1 = DataFrame(data)
print(d1)

index = ['zhangfei','zhangyun','guangyu','huangzong','dianwei']
df = DataFrame(data=data,index=index)

# read from excel file
#data = pd.read_excel('/home/zjtprince/sanguo_heros_score.xlsx',header=0,index_col=0)
##print(data)
#df = DataFrame(data,dtype="int64")
#print(df)
#print(df.dtypes)

#print(df.drop(columns=["Chinese"]))
#print(df.drop(index="zhangfei"))
#print(df.rename(columns={"Chinese":'yuwen',"English":"yingyu"},inplace=True))
#print(df)
#df = df.drop_duplicates()
#print(df)
#
#print(df.isnull().any())
#
df['name'] = df.index
print(df)

df['name'] = df['name'].str.upper()
df.columns= df.columns.str.upper()
df.columns= df.columns.str.title()
print(df)

df["语文"] = df['Chinese'].apply(lambda x: 2*x)
print(df)
print(df.describe())


from typing import Tuple, List, Dict
import lib.coord_conversion as cc
import json

def make_arrivals(local_coordinates: str, gps_coordinates: str) -> None:

    arrivals_timestamps = timestamps_list(local_coordinates)
    arrivals_gps = cc.gps_list(gps_coordinates)
    arrivals_final_coords = final_list(arrivals_timestamps, arrivals_gps)

    dict_list = [single_dictionary(entry) for entry in arrivals_final_coords]

    json_file = json.dumps(dict_list, indent=2)

    with open("arrivals.json", "w") as file:
        file.write(json_file)

def single_dictionary(tup: Tuple[List[float], float]) -> Dict:
    new_dict = {}
    new_dict["coordinates"] = tup[0]
    new_dict["timestamp"] = tup[1]
    new_dict["color"] = [253, 128, 93]

    return new_dict

def timestamps_list(local_coordinates: str) -> List[Tuple[Tuple[float, float], float]]:

    # Reads file with timestamps into program and stores it as a list of tuples.
    time_coords_1 = []

    with open(local_coordinates, 'r') as time:
        print("    Reading local coordinates and timestamps...")
        reader = time.readlines()
        for row in reader:
            coords_time = row.split()
            x_y_vals = coords_time[0]
            time = coords_time[1]
            tup = (x_y_vals, time)
            time_coords_1.append(tup)

    # Reformats the coordinates in time_coords_1 and converts them from strings to numeric values.
    return [time_tuple(entry) for entry in time_coords_1]

def time_tuple(tup: Tuple[str, str]) -> Tuple[Tuple[float, float], float]:
    coords = cc.cast_to_float(tup[0])
    time = tup[1].strip(',')
    time = float(time)
    return coords, time

# Makes a list of tuples containing the GPS coordinates and timestamps from the two lists passed as parameters. Each
# tuple contains a set of GPS coordinates and a timestamp.
def final_list(timestamps: List[Tuple[Tuple[float, float], float]],
               coords_list: List[Tuple[Tuple[float, float], List[float]]]) -> List[Tuple[List[float], float]]:
    final_coords = []

    print("    Making list of GPS coordinates with timestamps...")
    for coords, timestamp in timestamps:
        for local, gps in coords_list:
            if coords == local:
                new = (gps, timestamp)
                final_coords.append(new)
                break

    return final_coords


import json
from django.conf import settings
from django.forms import Widget

DEFAULT_ACCEPT_MIMETYPE = "*/*"

class CloudObjectWidget(Widget):
    """A widget allowing upload of a file directly to cloud storage

    Must be placed in a form context. On submission of the form,
    upload is started. The submission is intercepted and re-triggered
    on completion of the upload.
    """

    class Media:
        """Add css and js assets to the template rendering the widget"""

        css = {
            "all": ["django_gcp/cloud_object_widget.css"],
        }
        js = ["django_gcp/cloud_object_widget.js"]

    template_name = "django_gcp/cloud_object_widget.html"

    def __init__(
        self,
        *args,
        signed_ingress_url=None,
        ingress_path=None,
        accept_mimetype=DEFAULT_ACCEPT_MIMETYPE,
        **kwargs,
    ):
        super().__init__(*args, **kwargs)
        self._args = args
        self._kwargs = kwargs
        self.accept_mimetype = accept_mimetype
        self.signed_ingress_url = signed_ingress_url
        self.ingress_path = ingress_path

        if "unfold" in settings.INSTALLED_APPS:
            self.template_name = "django_gcp/contrib/unfold/cloud_object_widget.html"

    def get_context(self, name, value, attrs):
        context = super().get_context(name, value, attrs)

        # if self.is_initial():
        #     context["my_context"] = "Adding a new model"
        # else:
        #     context["my_context"] = "Changing an existing model"

        context["signed_ingress_url"] = self.signed_ingress_url
        context["ingress_path"] = self.ingress_path
        context["accept_mimetype"] = self.accept_mimetype
        # Yes I know this is a hack but I've been working on this for weeks and django's a nightmare
        value_or_dict = json.loads(value) or {}
        context["existing_path"] = value_or_dict.get("path", "")
        # context["signing_token"] = a token
        # context["signing_url"] = submit the token to this url in exchange for a signed URL reverse("gcp-storage-get-direct-upload-url")
        return context


import tkinter
from tkinter import *
def name():
    a=e1.get()
    b=e2.get()
    c=a+" "+b
    print("Name : "+str(c))
    e3.insert(0,c)
master = Tk()
Label(master, text='First Name').grid(row=0)
Label(master, text='Last Name').grid(row=1)
Label(master, text='Name').grid(row=2)
e1 = Entry(master)
e2 = Entry(master)
e3 = Entry(master)
e1.grid(row=0, column=1)
e2.grid(row=1, column=1)
e3.grid(row=2, column=1)
button=tkinter.Button(master, text='Ok', width=10, command=name).grid(row=3)
mainloop()


import cv2
import numpy as np
import os

def in_c(x, y, contour):
    result = cv2.pointPolygonTest(contour, (x, y), False)
    if (result == 1):
        return True
    else:
        return False

def mean_c(image, contour):
    s = 0
    k = 0
    step = 10
    xx, yy, w, h = cv2.boundingRect(contour)
    for y in range(min(yy, h), max(yy, h), step):
        for x in range(min(xx, w), max(xx, w), step):
            if (in_c(x, y, contour)):
                s += sum(image[y][x])
                k += 1
    return s / k if k != 0 else 0

def viewImage(image):
    cv2.namedWindow('Display', cv2.WINDOW_NORMAL)
    cv2.imshow('Display', image)
    cv2.waitKey(10)

def draw(im, cnt):
    ## convert image to gray scale (must br done before contouring)
    image = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
    ret, image = cv2.threshold(image, 50, 255, 0)
    ret, threshold = cv2.threshold(image, 50, 255, cv2.THRESH_BINARY_INV)
    i, contours, hirerchy = cv2.findContours(threshold,
                                             cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)
    m = 0
    for c in contours:
        if (cv2.contourArea(c) > m):
            m = cv2.contourArea(c)
    m *= 0.7
    cnt = 0
    for i in range(len(contours)):

        if (cv2.contourArea(contours[i]) > 100 and mean_c(im, contours[i]) > 10) or cv2.contourArea(contours[i]) > m:
            if cv2.contourArea(contours[i]) < m:
                cnt += 1
            M = cv2.moments(contours[i])
            try:
                cX = int(M["m10"] / M["m00"])
                cY = int(M["m01"] / M["m00"])
                im = cv2.circle(im, (cX, cY), radius=0, color=(0, 255, 255), thickness=10)
            except:
                pass
            mi = 100000
            ma = 0
            s = 0
            k = 0

            for point in contours[i]:
                x = point[0][0]
                y = point[0][1]
                mi = min(mi, ((x - cX) ** 2 + (y - cY) ** 2) ** 0.5)
                ma = max(ma, ((x - cX) ** 2 + (y - cY) ** 2) ** 0.5)
                s += ((x - cX) ** 2 + (y - cY) ** 2) ** 0.5
                k += 1
            mid = s / k
            cv2.circle(im, (cX, cY), round(mid), (0, 255, 0), 2)
            cv2.circle(im, (cX, cY), round(mi), (0, 255, 0), 2)
            cv2.circle(im, (cX, cY), round(ma), (0, 255, 0), 2)
            cv2.drawContours(im, contours[i], -1, (0, 0, 255), 3)
            cv2.putText(im, "Area: " + str(cv2.contourArea(contours[i])), (50, 50), cv2.FONT_HERSHEY_SIMPLEX, 1,
                        (255, 255, 255), 2)
            cv2.putText(im, "Min dist: " + f"{mi:.{5}f}", (50, 80), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2)
            cv2.putText(im, "Max dist: " + f"{ma:.{5}f}", (50, 110), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2)
            cv2.putText(im, "Mean dist: " + f"{mid:.{5}f}", (50, 140), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2)
            print("разность:", ma / mi if mi != 0 else 0)

    first = False
    viewImage(im)
    return cnt

x = r"C:\Users\lashi\Desktop\Cav_d\videos\0_.mp4"
vid = cv2.VideoCapture(x)
while (vid.isOpened()):
    ret, frame = vid.read()
    cnt = draw(frame, cnt)


import urllib.request
from urllib.request import Request, urlopen

from bs4 import BeautifulSoup as BS
import csv
import re

URL = "https://www.leefilters.com/lighting/colour-list.html"

page = 0
limit = 0

fullNames = []
codes = []
colorValues = []

req = Request(URL, headers={'User-Agent': 'Mozilla/5.0'})
with urllib.request.urlopen(req) as response:
	html = response.read()
	soup = BS(html, features="html.parser")

	codeSoup = soup.findAll("a", {"class": "name"})

	for i in range (len(codeSoup) - 13 ):
		code = codeSoup[i]
		print(re.sub(";", "", re.sub("#", "", code["style"].split(":")[1])))
		colorValues.append(re.sub(";", "", re.sub("#", "", code["style"].split(":")[1])))
		fullNames.append(' '.join(code.contents[0].split(" ")[1:]))
		codes.append('L' + code.contents[0].split(" ")[0])

with open('lee.csv', mode='w') as lee_file:
	lee_writer = csv.writer(lee_file, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL)
	j = 0
	lee_writer.writerow(["COLOR CODE", "COLOR NAME", "HEX VALUE"])
	while j < len(fullNames):
		lee_writer.writerow([codes[j], fullNames[j], colorValues[j]])
		j += 1


'''
Author: Sungjun Han, Anastasiia
Description: calcalates accuracy
'''

import numpy as np
import re
from collections import defaultdict
import json
import sys

def tokenize(sent,
			delimiters = r'\s+'):
	'''
	Description : tokenizes the given string using the delimiter
	sent : str
	delimiters : str
	'''

	tokenized = re.split(delimiters, sent)
	return tokenized

def frequency_count(dataset, lower, delimiters = r'\s+'):
	'''
	Author : Sungjun Han
	Description: counts frequencies of the tokens from the given dataset
	dataset : list of list
	lower : bool
	delimiters : str
	'''
	freq_count = defaultdict(int)
	for i in range(len(dataset)):
		_, obs1, obs2, hyp1, hyp2, label = dataset[i]
		textdata = [obs1, obs2, hyp1, hyp2]
		for textelem in textdata:
			if lower:
				textelem = textelem.lower()
			for token in tokenize(textelem, delimiters):
				freq_count[token] += 1
	return freq_count

def token_to_idx(freq_count,
			pad_symbol = None,
			start_symbol = None,
			end_symbol = None,
			unk_symbol = None,
			split_symbol = None):
	'''
	Descriptions: build vocabulary (token to idx dictionary mapping) from the frequency counts
	freq_count : dictionary
	pad_symbol : bool
	start_symbol : bool
	end_symbol : bool
	unk_symbol : bool
	split_symbol : bool
	'''

	# 0 for pad
	tok2idx = {}
	if pad_symbol:
		tok2idx[pad_symbol] = len(tok2idx)

	if unk_symbol:
		tok2idx[unk_symbol] = len(tok2idx)

	if start_symbol:
		tok2idx[start_symbol] = len(tok2idx)

	if end_symbol:
		tok2idx[end_symbol] = len(tok2idx)

	if split_symbol:
		tok2idx[split_symbol] = len(tok2idx)

	for k, v in freq_count.items():
		if not k in tok2idx.keys(): #if we don't check this, we end up with 'END' and 'SPLT' tokens having quite random indeces
			tok2idx[k] = len(tok2idx)

	return tok2idx

def idx_to_token(tok2idx):
	'''
	Descriptions: build idx to token dictionary mapping from token 2 idx dictionary mapping
	tok2idx : dictionary
	'''
	idx2tok = {v:k for k,v in tok2idx.items()}
	return idx2tok

def encode(tokenized_sentence, tok2idx, unk_token):
	'''
	Descriptions: encode a tokenized sentence into a list of integers using the token2idx vocabulary
	tokenized_sentence : list of str
	tok2idx : dictionary
	unk_token : str
	'''
	encoded = []
	unk_idx = tok2idx[unk_token]
	for token in tokenized_sentence:
		encoded.append(tok2idx.get(token, unk_idx))
	return encoded

def decode(encoded, idx2tok, unk_token):
	'''
	Descriptions: decode a list of integers into a sentence using the idx2tok vocabulary
	encoded : list of int
	idx2tok : dictionary
	unk_token : str
	'''
	#unk token needs to be provided
	decoded = []
	for idx in encoded:
		decoded.append(idx2tok.get(idx,unk_token))
	return decoded

if __name__ == '__main__':

	p1 = 'Chad went to get the wheel alignment measured on his car'
	p2 = 'The mechanic provided a working alignment with new body work'
	h1 = 'Chad was waiting for his car to be washed'
	h2 = 'Chad was waiting for his car to be finished'

	label = 1

	dataset = [('id', p1, p2, h1, h2, label)]
	freq_count = frequency_count(dataset, delimiters = r'\s+', start_symbol = True, end_symbol = True)
	print(freq_count)
	tok2idx = token_to_idx(freq_count, start_symbol = True, end_symbol = True)
	print(tok2idx)


import os
import time
import random
import subprocess
import sys

solver_executable_path = os.path.join(os.getcwd(), "a.out")

def print_tetravex(data):
    data = data.split("\n")
    size = int(len(data) ** 0.5)
    print(("+" + "-" * 5) * size + "+")
    for i in range(size):
        for tile_orientation in range(3):
            print("|", end=" ")
            for j in range(size):
                if tile_orientation == 0:
                    print(" " + data[i * size + j][0], end="  ")
                elif tile_orientation == 1:
                    print(data[i * size + j][1], end=" ")
                    print(data[i * size + j][2], end=" ")
                elif tile_orientation == 2:
                    print(" " + data[i * size + j][3], end="  ")
                print("|", end=" ")
            print()
        if (i != size - 1):
            print(("+" + "-" * 5) * size + "+")
    print(("+" + "-" * 5) * size + "+")

def test_solver_on_file(input_path, expected_output_path):
    output_folder = "output"
    if not os.path.exists(output_folder):
        os.makedirs(output_folder)
    else:
        for file in os.listdir(output_folder):
            os.remove(os.path.join(output_folder, file))

    input_filename = input_path.split("/")[-1]

    # Path to the output file
    output_path = os.path.join(
        output_folder, input_filename.split(".")[0] + "-out.txt")

    # Execute the solver
    subprocess.run([solver_executable_path, input_path, output_path])

    # Compare the output with the expected output
    with open(output_path, "r") as output_file:
        output = output_file.read()
    with open(expected_output_path, "r") as expected_output_file:
        expected_output = expected_output_file.read()
    # Remove trailing newlines
    output = output.rstrip()
    expected_output = expected_output.rstrip()
    if output == expected_output:
        print("\033[92m" + input_filename + " : OK" + "\033[0m")
    else:
        print("\033[91m" + input_filename + " : KO" + "\033[0m")
        print("Expected output :")
        print_tetravex(expected_output)
        print()
        print("Output :")
        print_tetravex(output)

def test_solver_on_folder(input_folder, expected_output_folder):
    # List of input files sorted by name
    input_files = sorted(os.listdir(input_folder))

    # List of expected output files
    expected_output_paths = os.listdir(expected_output_folder)

    # Execute the solver on each input file and compare the output with the expected output
    for input_file in input_files:
        if os.path.isdir(os.path.join(input_folder, input_file)):
            continue
        input_path = os.path.join(input_folder, input_file)
        expected_output_path = None
        for e_path in expected_output_paths:
            cpy_e_path = e_path.split("/")[-1]
            if cpy_e_path.split("-ref")[0] == input_file.split(".")[0]:
                expected_output_path = os.path.join(expected_output_folder, e_path)
                break
        if expected_output_path == None:
            print("\033[91m" + input_file + " : KO" + "\033[0m")
            print("Expected output file not found")
            continue
        test_solver_on_file(input_path, expected_output_path)

def generate_tetravex(size, nb):
    for k in range(nb):
        # Generate a random tetravex
        tiles = [[0, 0, 0, 0] for _ in range(size * size)]
        for i in range(size):
            for j in range(size):
                if i > 0:
                    tiles[i * size + j][0] = tiles[(i - 1) * size + j][3]
                else:
                    tiles[i * size + j][0] = random.randint(0, 9)
                if j > 0:
                    tiles[i * size + j][1] = tiles[i * size + j - 1][2]
                else:
                    tiles[i * size + j][1] = random.randint(0, 9)
                tiles[i * size + j][3] = random.randint(0, 9)
                tiles[i * size + j][2] = random.randint(0, 9)

        # Shuffle the tiles
        cpy_tiles = tiles.copy()
        random.shuffle(tiles)

        # Generate the input file
        generated_input_folder = "generated_input/" + str(size) + "x" + str(size)
        if not os.path.exists(generated_input_folder):
            os.makedirs(generated_input_folder)
        # Input file path with the format size-timestamp.txt
        input_path = os.path.join(generated_input_folder,  "s" + str(size) + "-" + str(k) + ".txt")
        with open(input_path, "w") as input_file:
            for i, tile in enumerate(tiles):
                input_file.write(str(tile[0]) + str(tile[1]) + str(tile[2]) + str(tile[3]))
                if cpy_tiles[i] == tile:
                    input_file.write("@")
                input_file.write("\n")

        # Generate the expected output file
        generated_expected_output_folder = "generated_expected_output/" + str(size) + "x" + str(size)
        if not os.path.exists(generated_expected_output_folder):
            os.makedirs(generated_expected_output_folder)

        # Expected output file path with the format size-timestamp-ref.txt
        expected_output_path = os.path.join(generated_expected_output_folder,  "s" + str(size) + "-" + str(k) +"-ref.txt")
        with open(expected_output_path, "w") as expected_output_file:
            for tile in cpy_tiles:
                expected_output_file.write(str(tile[0]) + str(tile[1]) + str(tile[2]) + str(tile[3]) + "\n")

# Main function
if __name__ == "__main__":

    # Option handling: Usage: python script.py [--folder] [--file] input expected_output
    if len(sys.argv) == 4:
        if sys.argv[1] == "--folder":
            test_solver_on_folder(sys.argv[2], sys.argv[3])
        elif sys.argv[1] == "--file":
            test_solver_on_file(sys.argv[2], sys.argv[3])
        elif sys.argv[1] == "--generate":
            generate_tetravex(int(sys.argv[2]), int(sys.argv[3]))
        else:
            print("Usage: python script.py [--folder] [--file] input expected_output")
            print("Or: python script.py --generate size nb")
    else:
        print("Usage: python script.py [--folder] [--file] input expected_output")
        print("Or: python script.py --generate size nb")