import logging
import time

from nats.aio.client import Client

from metropolis.core.utils import InterruptBumper

WORKER_STATE_CONNECTED = 'connected'
WORKER_STATE_DISCONNECTED = 'connected'
WORKER_STATE_ERROR = 'error'
WORKER_STATE_CLOSED = 'closed'

class NatsDriver(object):
    nats = None
    serializer = None
    state = None

    def __init__(self, urls, serializer):
        self.urls = urls
        self.serializer = serializer

    async def get_connection(self, loop):
        self.nats = Client()

        await self.nats.connect(
            servers=self.urls,
            loop=loop,
            io_loop=loop,
            error_cb=self.get_error_cb(),
            disconnected_cb=self.get_disconnected_cb(),
            closed_cb=self.get_closed_cb(),
            reconnected_cb=self.get_reconnected_cb()
        )

        self.state = WORKER_STATE_CONNECTED

        return self.nats

    def get_error_cb(self):
        async def on_error(exception):
            self.state = WORKER_STATE_ERROR
            logging.error(f'{exception} {self.urls}')

        return on_error

    def get_disconnected_cb(self):
        async def on_disconnected():
            self.state = WORKER_STATE_DISCONNECTED
            logging.info(f'disconnected')

        return on_disconnected

    def get_closed_cb(self):
        async def on_closed():
            self.state = WORKER_STATE_DISCONNECTED
            logging.info(f'closed')

        return on_closed

    def get_reconnected_cb(self):
        async def on_reconnected():
            self.state = WORKER_STATE_CONNECTED
            logging.info(f'reconnected')

        return on_reconnected

    async def execute(self, task_fn, msg):
        logging.info((
            'Received message. '
            f'[subject={msg.subject}][fn={task_fn.__name__}]'
            f'[from={msg.reply}]'
        ))

        now = time.perf_counter()
        data = self.serializer.deserialize(msg.data)

        try:
            ret = task_fn(**data)
            code = 200

        except Exception as e:
            ret = str(e)
            code = 500

        if msg.reply:
            response_data = self.serializer.serialize({
                'code': code,
                'data': ret
            })

            await self.nats.publish(msg.reply, response_data)

        elapsed = (time.perf_counter() - now) * 1000

        logging.info((
            'Task finished. '
            f'[subject={msg.subject}][fn={task_fn.__name__}]'
            f'[elapsed={elapsed:.3f}ms]'
        ))

    def create_task_simple(self, task_fn):
        logging.debug(f'Create task [task_fn={task_fn.__name__}]')

        async def run_task(msg):
            await self.execute(task_fn, msg)

        return run_task

    def create_task(self, task_fn):
        logging.debug(f'Create task [task_fn={task_fn.__name__}]')

        async def run_task(msg):
            if self.nats.is_draining:
                logging.debug('Connection is draining')
                raise Exception('draining')

            try:
                with InterruptBumper(attempts=3):
                    self.execute(task_fn, msg)

            except KeyboardInterrupt:
                await self.nats.publish(
                    msg.reply, 'KeyboardInterrupt'.encode())
                raise

        return run_task

    async def close(self):
        logging.debug('Drain subscriptions')

        await self.nats.flush()
        logging.debug('Flushed')

        await self.nats.drain()
        logging.debug('Drained')

        await self.nats.close()
        logging.debug('Closed')


import pandas as pd
from scipy.stats import gaussian_kde
from shapely.geometry import Point
import time
from math import floor
import numpy as np
import os
import random
# ____________________________________ choosing records based on interval & clustering records ________________________________________
files = range(0,10) ###### fixme warning: 0 is not in range because we have it but generally it should be
# interval = 60#todo: please enter the interval between snapData records
intervals = [60,300,600,900,1200,1500,1800,2100,2400,2700,3000,3300,3600]
startTime = time.time()
q=0
# __________________________ generating snapshot for the specified interval _________________________________________________
for interval in intervals:
    print("************** interval is {inin} sec ***************".format(inin=interval))
    for q in files: # 18.6min for each file60,13.53min 300,20min 600, 20min900,16.25min for1800
        # snapDataSplit = pd.read_csv("D:/ax/gis/completePLUdata_30sec/completePLUdata_30sec_{number}.csv".format(number = q)) #38.5 sec to load 4G data
        snapDataSplit = pd.read_csv("/data/zahraeftekhar/research_temporal/completePLUdata_30sec/completePLUdata_30sec_{number}.csv".format(number = q)) #38.5 sec to load 4G data
        snapDataSplit[['mzr_id', 'VEHICLE']] = snapDataSplit[['mzr_id', 'VEHICLE']].astype(int)
        snapDataSplit = snapDataSplit.sort_values(by=["VEHICLE","TIME"])
        vehicleIDs = snapDataSplit.VEHICLE.unique()
        snapDataSplit_intervalFixed = pd.DataFrame(columns=['mzr_id', 'VEHICLE', 'TIME', 'EASTING', 'NORTHING'])
        i=1
        mmm=1
        for i in range(len(vehicleIDs)):
            if i==mmm*100:
                print('{percentage} percent____{duration} sec'.format(percentage = i/len(vehicleIDs), duration = time.time()-startTime))
                mmm +=1
            testRecords = snapDataSplit[snapDataSplit.VEHICLE == vehicleIDs[i]]
            snapDataSplit = snapDataSplit.drop(index=range(len(testRecords)))
            snapDataSplit = snapDataSplit.reset_index(drop=True)
            num = floor(len(testRecords)/(interval/30))
            random.seed(101)
            initialJump = random.choice((range(int(interval/30))))
            testRecords2 = testRecords.loc[[initialJump+(interval/30)*j for j in range(num)],:] # fixme: does this work (correct?)
            snapDataSplit_intervalFixed = snapDataSplit_intervalFixed.append(testRecords2)
        snapDataSplit = snapDataSplit_intervalFixed
        del snapDataSplit_intervalFixed
        # snapDataSplit = snapDataSplit.reset_index(drop=True)
        # folderSave = "D:/ax/gis/completePLUdata_{inter}sec".format(inter=interval)
        folderSave = "/data/zahraeftekhar/research_temporal/completePLUdata_{inter}sec".format(inter=interval)
        path = 'path_to_my_folder'
        if not os.path.exists(folderSave):
            os.makedirs(folderSave)
        filename = 'completePLUdata_{inter}sec_{number}.csv'.format(number=q,inter=interval)
        filePathSave = os.path.join(folderSave,filename)
        snapDataSplit.to_csv(filePathSave, header=True, index=False)
        print('END of number{num}'.format(num = q))
       # # snapDataSplit.to_csv("D:/ax/gis/completePLUdata_{inter}sec/completePLUdata_{inter}sec_{number}.csv".format(number = q, inter = interval),header=True,index=False)
# # _______________________________________ clustering the records _________________________________________________
for interval in intervals:
    files = range(0,10) ###### fixme warning: 0 is not in range because we have it but generally it should be
    startTime = time.time()
    # q=0
    for q in files: #11 min for each file60...2.5min for interval300,1.4min for600, 1min for900, 0.5min1800
        # snapDataSplit=pd.read_csv("D:/ax/gis/completePLUdata_{inter}sec/completePLUdata_{inter}sec_{number}.csv".format(number=q, inter=interval))
        snapDataSplit=pd.read_csv("/data/zahraeftekhar/research_temporal/completePLUdata_{inter}sec/completePLUdata_{inter}sec_{number}.csv".format(number=q, inter=interval))
        snapDataSplit[['mzr_id', 'VEHICLE']] = snapDataSplit[['mzr_id', 'VEHICLE']].astype(int)
        snapDataSplit = snapDataSplit.sort_values(by=["VEHICLE","TIME"])
        vehicleIDs = snapDataSplit.VEHICLE.unique()
        clusterData = pd.DataFrame()
        mmm=1
        for i in (range(len(vehicleIDs)-1)):#len(vehicleIDs) #1962 sec for one file of 3200 user
            if i==mmm*100:
                print('{percentage} percent____{duration} sec'.format(percentage = i/len(vehicleIDs), duration = time.time()-startTime))
                mmm +=1
            # if q==7:
            #     if i==2372:
            #         print(i)
            testRecords = snapDataSplit[snapDataSplit.VEHICLE == vehicleIDs[i]]
            snapDataSplit = snapDataSplit.drop(index=range(len(testRecords)))
            snapDataSplit = snapDataSplit.reset_index(drop=True)
            clusIndex = [0]
            j = 0
            k = 1
            while k < len(testRecords):
                while round(testRecords['EASTING'][j]*10**9)/(10**9)==round(testRecords['EASTING'][k]*10**9)/(10**9):
                    if (round(testRecords['NORTHING'][j]*10**7)/(10**7)==round(testRecords['NORTHING'][k]*10**7)/(10**7)):
                        k+=1
                        if(k == len(testRecords)):
                            break

                clusIndex += [k]
                j=k
                k+=1
            newD = pd.DataFrame(index=range(len(clusIndex)-1), columns=testRecords.columns)
            newD ['duration(sec)'] = None
            l=0
            for l in range(len(clusIndex)-1):

                if l==len(clusIndex)-2:
                    newD.iloc[l, -1] = testRecords.TIME[clusIndex[l + 1]-1] - testRecords.TIME[clusIndex[l]]+interval
                else:
                    newD.iloc[l,-1] = testRecords.TIME[clusIndex[l+1]]-testRecords.TIME[clusIndex[l]]
                newD.iloc[l,0:-1]=testRecords.iloc[clusIndex[l],:]
            clusterData = clusterData.append(newD)
        print((int((time.time() - startTime)/60)), end=' min ____ end for file number {number}\n'.format(number=q))
        # folderSave = "D:/ax/gis/completePLUdata_{inter}sec/clusterPLU_{inter}sec".format(inter=interval)
        folderSave = "/data/zahraeftekhar/research_temporal/completePLUdata_{inter}sec/clusterPLU_{inter}sec".format(inter=interval)
        if not os.path.exists(folderSave):
            os.makedirs(folderSave)
        filename = 'clusterPLU_{inter}sec_{number}.CSV'.format(number=q, inter=interval)
        filePathSave = os.path.join(folderSave, filename)
        clusterData.to_csv(filePathSave, index=False, header=True)
     #****** _________________ modifying users in the boundry of files (splited records) _________________
    for s in range(0,9):
        # cluster0 = pd.read_csv('D:/ax/gis/completePLUdata_{inter}sec/clusterPLU_{inter}sec/clusterPLU_{inter}sec_{number}.CSV'.format(number=s,inter=interval))
        cluster0 = pd.read_csv('/data/zahraeftekhar/research_temporal/completePLUdata_{inter}sec/clusterPLU_{inter}sec/clusterPLU_{inter}sec_{number}.CSV'.format(number=s,inter=interval))
        bound0 = cluster0.loc[len(cluster0)-1, :]
        # cluster1 = pd.read_csv('D:/ax/gis/completePLUdata_{inter}sec/clusterPLU_{inter}sec/clusterPLU_{inter}sec_{number}.CSV'.format(number=s+1,inter=interval))
        cluster1 = pd.read_csv('/data/zahraeftekhar/research_temporal/completePLUdata_{inter}sec/clusterPLU_{inter}sec/clusterPLU_{inter}sec_{number}.CSV'.format(number=s+1,inter=interval))
        bound1 = cluster1.loc[0, :]
        rec0 = cluster0[cluster0.VEHICLE == bound0.VEHICLE]
        rec0 = rec0.reset_index(drop=True)
        rec1 = cluster1[cluster1.VEHICLE == bound1.VEHICLE]
        if bound0.EASTING==bound1.EASTING and bound0.NORTHING==bound1.NORTHING:
            rec0.loc[len(rec0)-1,'duration(sec)']+=rec1.loc[0,'duration(sec)']
            rec1 = rec1.loc[1:,:]
            cluster0 = cluster0.append(rec1,ignore_index=True)
            cluster1 = cluster1.loc[(len(rec1)+1):,:]
        else:
            cluster0 = cluster0.append(rec1, ignore_index=True)
            cluster1 = cluster1.loc[len(rec1):, :]
        # cluster0.to_csv('D:/ax/gis/completePLUdata_{inter}sec/clusterPLU_{inter}sec/clusterPLU_{inter}sec_{number}.CSV'.format(number=s,inter=interval), header=True,index=False)
        cluster0.to_csv('/data/zahraeftekhar/research_temporal/completePLUdata_{inter}sec/clusterPLU_{inter}sec/clusterPLU_{inter}sec_{number}.CSV'.format(number=s,inter=interval), header=True,index=False)
        # cluster1.to_csv('D:/ax/gis/completePLUdata_{inter}sec/clusterPLU_{inter}sec/clusterPLU_{inter}sec_{number}.CSV'.format(number=s+1,inter=interval), header=True,index=False)
        cluster1.to_csv(
            '/data/zahraeftekhar/research_temporal/completePLUdata_{inter}sec/clusterPLU_{inter}sec/clusterPLU_{inter}sec_{number}.CSV'.format(number=s + 1,
                                                                                inter=interval),
            header=True, index=False)
# # # _____________________________________________________________________________________________________________________
#__________________________________ location type identification _____________________________________________________
startTime = time.time()
#intervals = [3600]
# from _5_GTAnalysis_userSampling import train_activityData, train_tripData, train_homeData, train_otherData,train_workData
for interval in intervals:
    print("************** interval is {inin} sec ***************".format(inin=interval))
    seeds = range(101,126)
    for seed in seeds:
        print("************** seed is {inin} sec ***************".format(inin=seed))
        # ________________________ reading data: Trainset _________________________
        # train_tripData = pd.read_csv(
        #     "C:/Users/zahraeftekhar/eclipse-workspace/matsim-code-examples/Results_AlbatrossAgentsCleaned_Stable_30secSnapShot/ITERS/it.1/train_tripStarts_seed{ss}.csv".format(
        #         ss=seed))
        # train_activityData = pd.read_csv(
        #     "C:/Users/zahraeftekhar/eclipse-workspace/matsim-code-examples/Results_AlbatrossAgentsCleaned_Stable_30secSnapShot/ITERS/it.1/train_activityStarts_seed{ss}.csv".format(
        #         ss=seed))
        # train_homeData = pd.read_csv(
        #     "C:/Users/zahraeftekhar/eclipse-workspace/matsim-code-examples/Results_AlbatrossAgentsCleaned_Stable_30secSnapShot/ITERS/it.1/train_homeStarts_seed{ss}.CSV".format(
        #         ss=seed))
        # train_workData = pd.read_csv(
        #     "C:/Users/zahraeftekhar/eclipse-workspace/matsim-code-examples/Results_AlbatrossAgentsCleaned_Stable_30secSnapShot/ITERS/it.1/train_workStarts_seed{ss}.CSV".format(
        #         ss=seed))
        # train_otherData = pd.read_csv(
        #     "C:/Users/zahraeftekhar/eclipse-workspace/matsim-code-examples/Results_AlbatrossAgentsCleaned_Stable_30secSnapShot/ITERS/it.1/train_otherStarts_seed{ss}.CSV".format(
        #         ss=seed))

        train_tripData = pd.read_csv(
            "/data/zahraeftekhar/research_temporal/GTanalysis/train_tripStarts_seed{ss}.csv".format(
                ss=seed))
        train_activityData = pd.read_csv(
            "/data/zahraeftekhar/research_temporal/GTanalysis/train_activityStarts_seed{ss}.csv".format(
                ss=seed))
        train_homeData = pd.read_csv(
            "/data/zahraeftekhar/research_temporal/GTanalysis/train_homeStarts_seed{ss}.CSV".format(
                ss=seed))
        train_workData = pd.read_csv(
            "/data/zahraeftekhar/research_temporal/GTanalysis/train_workStarts_seed{ss}.CSV".format(
                ss=seed))
        train_otherData = pd.read_csv(
            "/data/zahraeftekhar/research_temporal/GTanalysis/train_otherStarts_seed{ss}.CSV".format(
                ss=seed))
        # train_activityData = pd.read_csv('D:/ax/gis/completePLUdata_30sec/clusterPLU_30sec/train_activityData_0.01ratio.CSV')
        # train_tripData = pd.read_csv('D:/ax/gis/completePLUdata_30sec/clusterPLU_30sec/train_tripData_0.01ratio.CSV')
        # train_homeData = pd.read_csv('D:/ax/gis/completePLUdata_30sec/clusterPLU_30sec/train_homeData_0.01ratio.CSV')
        # train_workData = pd.read_csv('D:/ax/gis/completePLUdata_30sec/clusterPLU_30sec/train_workData_0.01ratio.CSV')
        # train_otherData = pd.read_csv('D:/ax/gis/completePLUdata_30sec/clusterPLU_30sec/train_otherData_0.01ratio.CSV')
        ntrip = len(train_tripData)
        nactivity = len(train_activityData)
        prior_activity = nactivity/(nactivity + ntrip)
        prior_trip = ntrip/(nactivity + ntrip)
        ### from groundTruthAnalysis_testBayesianForActivity import train_homeData, train_workData, train_otherData
        nHome = len(train_homeData)
        nWork = len(train_workData)
        nOther = len(train_otherData)
        prior_home = nHome/(nHome + nWork + nOther)
        prior_work = nWork/(nHome + nWork + nOther)
        prior_other = nOther/(nHome + nWork + nOther)
        files = range(0,10)
        # bw1 = 0.1
        # bw2 = 0.5
        # r=8
        for r in files: #4 min for each file60,2min for300, 1.8minfor600,1.7min for900,1min for1800
            # clusterData = pd.read_csv('D:/ax/gis/completePLUdata_{inter}sec/clusterPLU_{inter}sec/clusterPLU_{inter}sec_{number}.CSV'.format(number = r, inter=interval))
            clusterData = pd.read_csv('/data/zahraeftekhar/research_temporal/completePLUdata_{inter}sec/clusterPLU_{inter}sec/clusterPLU_{inter}sec_{number}.CSV'.format(number = r, inter=interval))
            clusterData['location type'] = None
            clusterData['activity type'] = None
            clusterData['stay'] = np.log(prior_activity)+np.log( gaussian_kde(train_activityData['Duration(hour)']).pdf((clusterData['duration(sec)'].astype(int))/3600))+np.log( gaussian_kde(train_activityData['start(hour)']).pdf((clusterData['TIME'].astype(int))/3600))
            clusterData['pass-by'] = np.log(prior_trip)+np.log( gaussian_kde(train_tripData['Duration(hour)']).pdf((clusterData['duration(sec)'].astype(int))/3600))+np.log( gaussian_kde(train_tripData['start(hour)']).pdf((clusterData['TIME'].astype(int))/3600))
            clusterData['location type']=clusterData[['stay','pass-by']].idxmax(axis=1)
            clusterData['home'] = None
            clusterData['work'] = None
            clusterData['other'] = None
            vehicleIDs = clusterData.VEHICLE.unique().astype(int)
            # from groundTruthAnalysis_testBayesianForActivity import train_otherData, train_homeData, train_workData,nOther,nWork,nHome
            # train_homeData.to_csv('D:/ax/gis/completePLUdata_30sec/clusterPLU_30sec/train_homeData_0.01ratio.CSV', index=False, header=True)
            # train_workData.to_csv('D:/ax/gis/completePLUdata_30sec/clusterPLU_30sec/train_workData_0.01ratio.CSV', index=False, header=True)
            # train_otherData.to_csv('D:/ax/gis/completePLUdata_30sec/clusterPLU_30sec/train_otherData_0.01ratio.CSV', index=False, header=True)
            anchorLocs = pd.DataFrame(columns=['VEHICLE','mzr_id','home','work', 'other','EASTING','NORTHING','start(sec)','duration(sec)'])
            i=0
            mmm=1
            for i in range(len(vehicleIDs)): #range(len(vehicleIDs)) # problem with id= '160047'and '164302' ... skip it (boundry error)
                if i==mmm*1000:
                    print('{percentage} percent____{duration} sec'.format(percentage = i/len(vehicleIDs), duration = time.time()-startTime))
                    mmm +=1
                tempData = clusterData[clusterData.VEHICLE == vehicleIDs[i]]
                stayIndex = tempData[tempData['location type']=='stay'].index
                if len(stayIndex)>1:
                    anchors = pd.DataFrame(index=stayIndex, columns=['VEHICLE','mzr_id','home','work', 'other','EASTING','NORTHING','start(sec)','duration(sec)'])
                    anchors.loc[:,'VEHICLE'] = tempData.loc[stayIndex[0],'VEHICLE']

                    for n in range(len(stayIndex)):

                        # _____________ to extend the algorithm for labeling _______________________
                        # if(n>0):
                        #     if clusterData.loc[stayIndex[n-1],'EASTING'] in anchors.loc[stayIndex[:], 'EASTING'].values:
                        #         if clusterData.loc[stayIndex[n-1],'NORTHING'] in anchors.loc[stayIndex[:], 'NORTHING'].values:
                        #             copiedvalues = (anchors[anchors.loc[stayIndex[:], 'EASTING'].isin([clusterData.loc[stayIndex[n - 1], 'EASTING']])][['home', 'work', 'other']])
                        #             clusterData.loc[stayIndex[n],['home', 'work', 'other']] = copiedvalues.values
                        #             clusterData.loc[stayIndex[n], ['activity type']] = clusterData.loc[stayIndex[n],['home', 'work', 'other']].idxmax()
                        # _______________________________________________________________________

                        clusterData.loc[stayIndex[n],['home']] = np.log(prior_home) + np.log(
                            gaussian_kde(train_homeData['Duration(hour)']).pdf((clusterData.loc[stayIndex[n],['duration(sec)']].astype(int))/3600)) + np.log(
                            gaussian_kde(train_homeData['start(hour)']).pdf((clusterData.loc[stayIndex[n],['TIME']].astype(int))/3600))
                        clusterData.loc[stayIndex[n],['work']] = np.log(prior_work) + np.log(
                            gaussian_kde(train_workData['Duration(hour)']).pdf((clusterData.loc[stayIndex[n],['duration(sec)']].astype(int))/3600)) + np.log(
                            gaussian_kde(train_workData['start(hour)']).pdf((clusterData.loc[stayIndex[n],['TIME']].astype(int))/3600))
                        clusterData.loc[stayIndex[n],['other']] = np.log(prior_other) + np.log(
                            gaussian_kde(train_otherData['Duration(hour)']).pdf((clusterData.loc[stayIndex[n],['duration(sec)']].astype(int))/3600)) + np.log(
                            gaussian_kde(train_otherData['start(hour)']).pdf((clusterData.loc[stayIndex[n],['TIME']].astype(int))/3600))
                        clusterData.loc[stayIndex[n],['activity type']] = pd.to_numeric(clusterData[['home', 'work','other']].iloc[stayIndex[n]]).idxmax(axis=1)
                        anchors.loc[stayIndex[n], 'EASTING'] = tempData.loc[stayIndex[n], 'EASTING']
                        anchors.loc[stayIndex[n], 'NORTHING'] = tempData.loc[stayIndex[n], 'NORTHING']
                        anchors.loc[stayIndex[n], 'mzr_id'] = tempData.loc[stayIndex[n], 'mzr_id']
                        anchors.loc[stayIndex[n], 'start(sec)'] = tempData.loc[stayIndex[n], 'TIME']
                        anchors.loc[stayIndex[n], 'duration(sec)'] = tempData.loc[stayIndex[n], 'duration(sec)']
                        if clusterData.loc[stayIndex[n],'activity type'] == 'home':
                            anchors.loc[stayIndex[n],'home'] = 1
                            anchors.loc[stayIndex[n], 'work'] = 0
                            anchors.loc[stayIndex[n], 'other'] = 0

                        elif clusterData.loc[stayIndex[n],'activity type'] == 'work':
                            anchors.loc[stayIndex[n],'home'] = 0
                            anchors.loc[stayIndex[n], 'work'] = 1
                            anchors.loc[stayIndex[n], 'other'] = 0
                        else:
                            anchors.loc[stayIndex[n],'home'] = 0
                            anchors.loc[stayIndex[n], 'work'] = 0
                            anchors.loc[stayIndex[n], 'other'] = 1
                    anchorLocs = anchorLocs.append(anchors)
            anchorLocs['activity'] = (anchorLocs[['home','work', 'other']]).astype(int).idxmax(axis=1)
            anchorLocs = anchorLocs.drop(columns = ['home','work', 'other'], axis = 1)
            print((int((time.time() - startTime) / 60)), end=' min ____ end for file number {number}\n'.format(number=r))
            # anchorLocs.to_csv('D:/ax/gis/completePLUdata_{inter}sec/clusterPLU_{inter}sec/anchorLocsPLU_{inter}sec_seed{ss}_{number}.CSV'.format(number=r, inter=interval,ss=seed), header=True,index=False)
            anchorLocs.to_csv('/data/zahraeftekhar/research_temporal/completePLUdata_{inter}sec/clusterPLU_{inter}sec/anchorLocsPLU_{inter}sec_seed{ss}_{number}.CSV'.format(number=r, inter=interval,ss=seed), header=True,index=False)
            # folderSave = "D:/ax/gis/completePLUdata_{inter}sec/clusterPLU_{inter}sec/identifiedClusters".format(inter=interval)
            folderSave = "/data/zahraeftekhar/research_temporal/completePLUdata_{inter}sec/clusterPLU_{inter}sec/identifiedClusters".format(inter=interval)
            if not os.path.exists(folderSave):
                os.makedirs(folderSave)
            filename = 'identified_clusterPLU_{inter}sec_seed{ss}_{number}.CSV'.format(number = r, inter=interval,ss=seed)
            filePathSave = os.path.join(folderSave, filename)
            clusterData.to_csv(filePathSave, index=False, header=True)
            # clusterData.to_csv('D:/ax/gis/completePLUdata_{inter}sec/clusterPLU_{inter}sec/identifiedClusters/identified_clusterPLU_{inter}sec_{number}.CSV'.format(number=r, inter=interval), header=True,index=False)
# _______________________reconsidering activity type based on home loc_________________
# intervals = [3600] #2100,1800,60,600,900,1200,300,2400,30,,1500,2700
startTime = time.time()
for interval in intervals:
    print("************** interval is {inin} sec ***************".format(inin=interval))
    seeds = range(101,126)
    for seed in seeds:
        print("************** interval:{inter}, seed is {inin} and time is {tt} min***************".format(inin=seed,inter=interval,tt=round((time.time()-startTime)/60)))
        anchorLocs = pd.DataFrame()
        for t in range(0,10):
            # anchor = pd.read_csv('D:/ax/gis/completePLUdata_{inter}sec/clusterPLU_{inter}sec/anchorLocsPLU_{inter}sec_seed{ss}_{number}.CSV'.format(number=t, inter=interval,ss=seed))
            anchor = pd.read_csv('/data/zahraeftekhar/research_temporal/completePLUdata_{inter}sec/clusterPLU_{inter}sec/anchorLocsPLU_{inter}sec_seed{ss}_{number}.CSV'.format(number=t, inter=interval,ss=seed))
            anchorLocs= anchorLocs.append(anchor,ignore_index=True)
        vehicleIDs = anchorLocs['VEHICLE'].unique()
        for i in range(len(vehicleIDs)): #range(len(vehicleIDs))
            # if i%5000==0:
            #     print("{perc}% of seed {ss} in interval {inter}___time is {tt} min ".format(perc= round(i/len(vehicleIDs)*100),ss=seed,inter=interval,tt=round((time.time()-startTime)/60)))
            temp = (anchorLocs[anchorLocs.VEHICLE == vehicleIDs[i]])
            if len(anchorLocs.loc[temp.index[temp['activity'] == 'home'],])>0:
                homeEASTING = anchorLocs.loc[temp.index[temp['activity'] == 'home'],'EASTING'].reset_index(drop=True)[len(anchorLocs.loc[temp.index[temp['activity'] == 'home'],'EASTING'])-1]
                homeNORTHING = anchorLocs.loc[temp.index[temp['activity'] == 'home'],'NORTHING'].reset_index(drop=True)[len(anchorLocs.loc[temp.index[temp['activity'] == 'home'],'NORTHING'])-1]
                for j in temp.index.drop(temp.index[temp['activity'] == 'home']):
                    if ((float(anchorLocs.loc[j,'EASTING'])-float(homeEASTING))**2+ (float(anchorLocs.loc[j,'NORTHING'])-float(homeNORTHING))**2)**0.5<300:
                        anchorLocs.loc[j,'activity'] = 'home'
        # anchorLocs.to_csv('D:/ax/gis/completePLUdata_{inter}sec/clusterPLU_{inter}sec/anchorLocsPLU_{inter}sec_seed{ss}.CSV'.format( inter=interval,ss=seed),header=True,index=False)
        anchorLocs.to_csv('/data/zahraeftekhar/research_temporal/completePLUdata_{inter}sec/clusterPLU_{inter}sec/anchorLocsPLU_{inter}sec_seed{ss}.CSV'.format( inter=interval,ss=seed),header=True,index=False)

# #
# #
# _____________________fixing start time of activities 2 min elapsed time for interval=60s________________________________________
# intervals=[3600]
for interval in intervals:
    print("************** interval is {inin} sec ***************".format(inin=interval))
    seeds = range(101,126)
    for seed in seeds:
        print("************** seed is {inin} sec ***************".format(inin=seed))
        anchorLocs = pd.DataFrame() #NOT NEEDED for interval less than 5min
        speed  = 50*1000/3600 #35:(0.43,0.53),33:(0.45,),30:(0.473,0.494),28:(0.485,0.485)
        # anchorLocs = pd.read_csv('D:/ax/gis/completePLUdata_{inter}sec/clusterPLU_{inter}sec/anchorLocsPLU_{inter}sec_seed{ss}.CSV'.format( inter=interval,ss=seed))
        anchorLocs = pd.read_csv('/data/zahraeftekhar/research_temporal/completePLUdata_{inter}sec/clusterPLU_{inter}sec/anchorLocsPLU_{inter}sec_seed{ss}.CSV'.format( inter=interval,ss=seed))
        anchorLocs = anchorLocs.sort_values('VEHICLE')
        # # GTtimeData=pd.read_csv("C:/Users/zahraeftekhar/eclipse-workspace/matsim-code-examples/Results_PlanWithOnlyCar_30secSnapShot/ITERS/it.1/1.trueTimes.csv")
        # GTtimeData=pd.read_csv("/data/zahraeftekhar/research_temporal/1.trueTimes.csv")#???????????????????? todo: what is TrueTimes
        # GTtimeData.VEHICLE = (GTtimeData.VEHICLE).astype(int)
        # GTtimeData = GTtimeData.sort_values('VEHICLE')
        # GTids = np.sort((GTtimeData['VEHICLE'].unique()).astype(int))
        anchorLocs_fixedStart = pd.DataFrame()
        # for i in range(len(GTids)):
        #     anchorLocsNogeneric = anchorLocsNogeneric.append(anchorLocs[anchorLocs['VEHICLE']==GTids[i]])
        vehicleIDs = anchorLocs['VEHICLE'].unique()
        anchorLocsNogeneric = anchorLocs
        del anchorLocs
        # vehicleIDs=GTids
        # i= 14623 #14619
        startTime = time.time()
        # mmm=1
        for i in range(len(vehicleIDs)):
            # if i==mmm*100:
            #     print('{percentage} percent____{duration} sec'.format(percentage = i/len(vehicleIDs), duration = time.time()-startTime))
            #     mmm +=1
            testRecords = anchorLocsNogeneric[anchorLocsNogeneric.VEHICLE == vehicleIDs[i]]
            testRecords = testRecords.reset_index(drop=True)
            testRecords2 = testRecords
            # testRecords.loc[0,'start(sec)'] = min((testRecords.loc[-1,'start(sec)']+testRecords.loc[-1,'duration(sec)']
            #                                        +(((testRecords.loc[-1,'EASTING']-testRecords.loc[0,'EASTING'])**2+(testRecords.loc[-1,'NORTHING']-testRecords.loc[0,'NORTHING'])**2)**(0.5))/speed),testRecords.loc[0,'start(sec)'])
            if len(testRecords2)>0:
                if (testRecords.loc[len(testRecords)-1,'start(sec)']+testRecords.loc[len(testRecords)-1,'duration(sec)']+(((testRecords.loc[len(testRecords)-1,'EASTING']-testRecords.loc[0,'EASTING'])**2+(testRecords.loc[len(testRecords)-1,'NORTHING']-testRecords.loc[0,'NORTHING'])**2)**(0.5))/speed)-24*3600< testRecords.loc[0,'start(sec)']:
                    if testRecords.loc[0, 'start(sec)']-(testRecords.loc[len(testRecords) - 1, 'start(sec)'] + testRecords.loc[len(testRecords) - 1, 'duration(sec)']+ (((testRecords.loc[len(testRecords) - 1, 'EASTING'] - testRecords.loc[0, 'EASTING']) ** 2 +(testRecords.loc[len(testRecords) - 1, 'NORTHING'] - testRecords.loc[0, 'NORTHING']) ** 2) ** (0.5)) / speed)+24*3600  < interval:
                        testRecords2.loc[0, 'duration(sec)'] += testRecords.loc[0,'start(sec)']-(testRecords.loc[len(testRecords)-1,'start(sec)']+testRecords.loc[len(testRecords)-1,'duration(sec)']+(((testRecords.loc[len(testRecords)-1,'EASTING']-testRecords.loc[0,'EASTING'])**2+(testRecords.loc[len(testRecords)-1,'NORTHING']-testRecords.loc[0,'NORTHING'])**2)**(0.5))/speed)+24*3600
                        testRecords2.loc[0, 'start(sec)'] = (testRecords.loc[len(testRecords)-1,'start(sec)']+testRecords.loc[len(testRecords)-1,'duration(sec)']+(((testRecords.loc[len(testRecords)-1,'EASTING']-testRecords.loc[0,'EASTING'])**2+(testRecords.loc[len(testRecords)-1,'NORTHING']-testRecords.loc[0,'NORTHING'])**2)**(0.5))/speed)-24*3600
                else:
                    testRecords2.loc[0, 'duration(sec)'] += interval
                    testRecords2.loc[0, 'start(sec)'] -= interval
                j=1
                for j in range(1,len(testRecords)):
                    if (testRecords.loc[j-1, 'start(sec)'] + testRecords.loc[j-1, 'duration(sec)']
                        + (((testRecords.loc[j-1, 'EASTING'] - testRecords.loc[j, 'EASTING']) ** 2 +
                            (testRecords.loc[j-1, 'NORTHING'] - testRecords.loc[j, 'NORTHING']) ** 2) ** (0.5)) / speed) < \
                            testRecords.loc[j, 'start(sec)']:
                        if  testRecords.loc[j, 'start(sec)']-(testRecords.loc[j-1, 'start(sec)'] + testRecords.loc[j-1, 'duration(sec)']
                                    + (((testRecords.loc[j-1, 'EASTING'] - testRecords.loc[j, 'EASTING']) ** 2 +
                                        (testRecords.loc[j-1, 'NORTHING'] - testRecords.loc[j, 'NORTHING']) ** 2) ** (0.5)) / speed)\
                                <interval:

                            testRecords2.loc[j, 'duration(sec)'] +=  testRecords.loc[j, 'start(sec)']-(testRecords.loc[j-1, 'start(sec)'] + testRecords.loc[j-1, 'duration(sec)']
                                        + (((testRecords.loc[j-1, 'EASTING'] - testRecords.loc[j, 'EASTING']) ** 2 +
                                            (testRecords.loc[j-1, 'NORTHING'] - testRecords.loc[j, 'NORTHING']) ** 2) ** (0.5)) / speed)\

                            testRecords2.loc[j, 'start(sec)'] = (
                                        testRecords.loc[j-1, 'start(sec)'] + testRecords.loc[j-1, 'duration(sec)']
                                        + (((testRecords.loc[j-1, 'EASTING'] - testRecords.loc[j, 'EASTING']) ** 2 +
                                            (testRecords.loc[j-1, 'NORTHING'] - testRecords.loc[j, 'NORTHING']) ** 2) ** (0.5)) / speed)
                        else:
                            testRecords2.loc[j, 'duration(sec)']+=interval
                            testRecords2.loc[j, 'start(sec)']-=(interval)
                anchorLocs_fixedStart = anchorLocs_fixedStart.append(testRecords2)
                # print(pd.to_timedelta(testRecords.loc[:, 'start(sec)'], unit='s'))
                # print(pd.to_timedelta(testRecords2.loc[:, 'start(sec)'], unit='s'))

        anchorLocs_fixedStart = anchorLocs_fixedStart.reset_index(drop=True)
        # anchorLocs_fixedStart.to_csv('D:/ax/gis/completePLUdata_{inter}sec/clusterPLU_{inter}sec/anchorLocs_fixedStart_{inter}sec_seed{ss}.CSV'.format(ss=seed,inter=interval),header=True,index=False)
        anchorLocs_fixedStart.to_csv(
            '/data/zahraeftekhar/research_temporal/completePLUdata_{inter}sec/clusterPLU_{inter}sec/anchorLocs_fixedStart_{inter}sec_seed{ss}.CSV'.format(
                ss=seed, inter=interval), header=True, index=False)
# # print(len(anchorLocs_fixedStart[anchorLocs_fixedStart['start(sec)']==anchorLocsNogeneric['start(sec)']])/len(anchorLocs_fixedStart))
# # print(len(anchorLocs_fixedStart[anchorLocs_fixedStart['start(sec)']-anchorLocsNogeneric['start(sec)']==interval])/len(anchorLocs_fixedStart))
# # anchorLocs_fixedStart['end(sec)'] = anchorLocs['start(sec)']+anchorLocs['duration(sec)']
# # anchorLocs_fixedStart['start'] = pd.to_timedelta(anchorLocs_fixedStart['start(sec)'],unit='s')
# # anchorLocsNogeneric['start'] = pd.to_timedelta(anchorLocsNogeneric['start(sec)'],unit='s')
# # anchorLocs_fixedStart['duration'] = pd.to_timedelta(anchorLocs_fixedStart['duration(sec)'],unit='s')
# # anchorLocsNogeneric['duration'] = pd.to_timedelta(anchorLocsNogeneric['duration(sec)'],unit='s')
# anchorLocsNogeneric.to_csv('D:/ax/gis/completePLUdata_{inter}sec/clusterPLU_{inter}sec/anchorLocs_NoGeneric.CSV'.format(inter=interval),header=True,index=False)
# # # #  __________________________test accuracy of start fixing  ___________________________________
# # # # GTtimeData=pd.read_csv("C:/Users/zahraeftekhar/eclipse-workspace/matsim-code-examples"
# # # #                                "/Results_PlanWithOnlyCar_30secSnapShot/ITERS/it.1/1.trueTimes.csv") #3 min
# # # GTtimeData = GTtimeData.drop(columns = ['end'])
# # # GTtimeData['startPLU'] = None
# # # GTtimeData['durationPLU']=None
# # # GTtimeData['startFixed'] = None
# # # GTtimeData['durationFixed'] = None
# # for i in range(len(vehicleIDs)):
# #     if len(GTtimeData[GTtimeData.VEHICLE==vehicleIDs[i]])==len(anchorLocs_fixedStart[anchorLocs_fixedStart.VEHICLE==vehicleIDs[i]]):
# #         GTtimeData.loc[:,'startFixed'][GTtimeData.VEHICLE==vehicleIDs[i]] = ((anchorLocs_fixedStart.loc[:,'start(sec)'][anchorLocs_fixedStart.VEHICLE==vehicleIDs[i]])).values
# #         GTtimeData.loc[:,'durationFixed'][GTtimeData.VEHICLE==vehicleIDs[i]] = ((anchorLocs_fixedStart.loc[:,'duration(sec)'][anchorLocs_fixedStart.VEHICLE==vehicleIDs[i]])).values
# #         GTtimeData.loc[:,'startPLU'][GTtimeData.VEHICLE==vehicleIDs[i]] = ((anchorLocsNogeneric.loc[:,'start(sec)'][anchorLocsNogeneric.VEHICLE==vehicleIDs[i]])).values
# #         GTtimeData.loc[:,'durationPLU'][GTtimeData.VEHICLE==vehicleIDs[i]] = ((anchorLocsNogeneric.loc[:,'duration(sec)'][anchorLocsNogeneric.VEHICLE==vehicleIDs[i]])).values
# # GTtimeData['startPLU2'] = pd.to_timedelta(GTtimeData['startPLU'],unit='s')
# # GTtimeData['durationPLU2']=pd.to_timedelta(GTtimeData['durationPLU'],unit='s')
# # GTtimeData['startFixed2'] = pd.to_timedelta(GTtimeData['startFixed'],unit='s')
# # GTtimeData['durationFixed2'] = pd.to_timedelta(GTtimeData['durationFixed'],unit='s')
# # GTtimeData = GTtimeData.drop(columns=['startPLU', 'durationPLU','startFixed', 'durationFixed'])
# # test = GTtimeData[['VEHICLE','start','startPLU2','startFixed2']]
# # ___________________________GT Times _____________________________________________
# import xml.etree.ElementTree as etree
# start_time=time.time()
# itemlistExperienced= etree.parse("C:/Users/zahraeftekhar/eclipse-workspace/matsim-code-examples/Results_AlbatrossAgentsCleaned_Stable_30secSnapShot_final/ITERS/it.1/PlanWithOnlyCar_again_NoGeneric_NoZeroDuationActivity.xml").getroot().findall('person')
# GTtimeData = pd.DataFrame(columns=['VEHICLE','start','duration','type'])
# mmm = 1
# for m, person in enumerate(itemlistExperienced):
#     if m == mmm * 100:
#         print('{percentage} percent____{duration} sec'.format(percentage=m / len(itemlistExperienced) * 100,
#                                                               duration=time.time() - start_time))
#         mmm += 1
#     # legList = itemlistExperienced[m].findall('plan/leg/route')
#     activityList = itemlistExperienced[m].findall('plan/activity')
#     i = 0
#     for i in range(1,len(activityList)-1):
#         trueloc = pd.DataFrame(columns=['VEHICLE','start','end','type'])
#         trueloc.loc[i-1, 'VEHICLE'] = person.get('id')
#         trueloc.loc[i - 1, 'start'] = activityList[i].get('start_time')
#         trueloc.loc[i - 1, 'end'] = activityList[i].get('end_time')
#         trueloc.loc[i - 1, 'type'] = activityList[i].get('type')
#     i+=1
#     trueloc.loc[i - 1, 'VEHICLE'] = person.get('id')
#     trueloc.loc[i - 1, 'start'] = activityList[i].get('start_time')
#     trueloc.loc[i - 1, 'end'] = pd.to_timedelta(activityList[0].get('end_time'))+pd.to_timedelta('24:00:00')
#     trueloc.loc[i - 1, 'type'] = activityList[i].get('type')
#     GTtimeData = GTtimeData.append(trueloc)
# GTtimeData.duration = pd.to_timedelta(GTtimeData.end)-pd.to_timedelta(GTtimeData.start)
# GTtimeData.to_csv("C:/Users/zahraeftekhar/eclipse-workspace/matsim-code-examples"
#                                "/Results_PlanWithOnlyCar_30secSnapShot_final/ITERS/it.1/1.trueTimes.csv", header=True, index=False)
# # __________________________________________________________________________________
# #
# #
# __________ estimation OD matrix ___________  todo: put Amsterdam zoning map with data point on it in the report
# intervals = [2400]#1500,1800,2100,2400
for interval in intervals:
    print("************** interval is {inin} sec ***************".format(inin=interval))
    seeds = range(101, 126)
    for seed in seeds:
        # anchorLocs = pd.read_csv('D:/ax/gis/completePLUdata_{inter}sec/clusterPLU_{inter}sec/anchorLocs_fixedStart_{inter}sec_seed{ss}.CSV'.format(ss=seed,inter=interval), usecols=['VEHICLE', 'mzr_id', 'EASTING', 'NORTHING', 'start(sec)',
        #        'duration(sec)','activity'])
        anchorLocs = pd.read_csv('/data/zahraeftekhar/research_temporal/completePLUdata_{inter}sec/clusterPLU_{inter}sec/anchorLocs_fixedStart_{inter}sec_seed{ss}.CSV'.format(ss=seed,inter=interval), usecols=['VEHICLE', 'mzr_id', 'EASTING', 'NORTHING', 'start(sec)',
               'duration(sec)','activity'])
        print(min(anchorLocs['duration(sec)']))
        anchorLocs['end(sec)'] = anchorLocs['start(sec)']+anchorLocs['duration(sec)']
        # amsterdamMezuroZones = pd.read_csv('D:/ax/gis/locationMappingToMezuroZones/amsterdamMezuroZones.CSV', usecols=['mzr_id'])
        amsterdamMezuroZones = pd.read_csv('/data/zahraeftekhar/research_temporal/locationMappingToMezuroZones/amsterdamMezuroZones.CSV', usecols=['mzr_id'])
        tazNames = amsterdamMezuroZones['mzr_id'] #5333 is also included but not in amsterdam so '0' zone represent it
        zoneZero = pd.Series(0)
        matrixRowColNames = tuple(zoneZero.append(tazNames))
        odsize=len(matrixRowColNames)
        ODstart = "06:30:00"
        ODend = "09:30:00"
        startTime_OD = pd.to_timedelta(ODstart)
        endTime_OD = pd.to_timedelta(ODend)
        ODMatrix_df = pd.DataFrame(np.zeros((odsize, odsize), dtype=np.int32),
                                   columns=matrixRowColNames,
                                   index=matrixRowColNames)  # creating empty OD matrix
        ODMatrix_home = pd.DataFrame(np.zeros((odsize, odsize), dtype=np.int32),
                                   columns=matrixRowColNames,
                                   index=matrixRowColNames)
        ODMatrix_work = pd.DataFrame(np.zeros((odsize, odsize), dtype=np.int32),
                                   columns=matrixRowColNames,
                                   index=matrixRowColNames)
        ODMatrix_other = pd.DataFrame(np.zeros((odsize, odsize), dtype=np.int32),
                                   columns=matrixRowColNames,
                                   index=matrixRowColNames)
        vehicleIDs = anchorLocs.VEHICLE.unique().astype(int)
        start_time = time.time()
        m=0
        for m in range(len(vehicleIDs)): #range(len(vehicleIDs))
            activityList = anchorLocs[anchorLocs.VEHICLE == vehicleIDs[m]]

            activityList = activityList.reset_index(drop=True)
            j=1
            while j < len(activityList):
                if j==len(activityList)-1:
                    start_time1 = pd.to_timedelta(activityList.loc[j,'start(sec)'], unit='sec')
                    end_time1 = pd.to_timedelta(activityList.loc[j,'end(sec)'], unit='sec')
                    start_time2 = pd.to_timedelta(activityList.loc[0,'start(sec)'], unit='sec')+ pd.to_timedelta('24:00:00')
                    endActivity = end_time1
                    startNewActivity = start_time2
                    if pd.to_timedelta('23:59:59')>=pd.to_timedelta(startTime_OD)>=pd.to_timedelta(start_time1):
                        startTime_OD =ODstart
                    else:
                        startTime_OD = ODstart + pd.to_timedelta('24:00:00')
                    if pd.to_timedelta('23:59:59')>=pd.to_timedelta(endTime_OD)>=pd.to_timedelta(start_time1):
                        endTime_OD =ODend
                    else:
                        endTime_OD = ODend+ pd.to_timedelta('24:00:00')
                else:
                    start_time1 = pd.to_timedelta(activityList.loc[j,'start(sec)'], unit='sec')
                    end_time1 = pd.to_timedelta(activityList.loc[j,'end(sec)'], unit='sec')
                    start_time2 = pd.to_timedelta(activityList.loc[(j + 1),'start(sec)'], unit='sec')
                    endActivity = end_time1 # when using inconsistent timings : endActivity = min(end_time1, start_time2)
                    startNewActivity = start_time2 # when using inconsistent timings : startNewActivity = max(end_time1, start_time2)
                if pd.to_timedelta(start_time1) <= pd.to_timedelta(startTime_OD) < pd.to_timedelta(startNewActivity):
                    if endTime_OD <= endActivity:
                        break
                    else:
                        while endTime_OD > endActivity:
                            origin = activityList.loc[j,'mzr_id']
                            if j == len(activityList) - 1:
                                destination = activityList.loc[(0),'mzr_id']
                                if activityList.loc[(0),'activity']=='home':
                                    ODMatrix_home[origin][destination]=ODMatrix_home[origin][destination] + 1
                                elif activityList.loc[(0),'activity']== 'work':
                                    ODMatrix_work[origin][destination] = ODMatrix_work[origin][destination] + 1
                                else:
                                    ODMatrix_other[origin][destination] = ODMatrix_other[origin][destination] + 1

                            else:
                                destination = activityList.loc[(j+1), 'mzr_id']
                                if activityList.loc[(j+1),'activity']=='home':
                                    ODMatrix_home[origin][destination]=ODMatrix_home[origin][destination] + 1
                                elif activityList.loc[(j+1),'activity']== 'work':
                                    ODMatrix_work[origin][destination] = ODMatrix_work[origin][destination] + 1
                                else:
                                    ODMatrix_other[origin][destination] = ODMatrix_other[origin][destination] + 1
                            ODMatrix_df[origin][destination] = ODMatrix_df[origin][destination] + 1
                            j += 1
                            if j > len(activityList) - 1: break
                            end_time1 = pd.to_timedelta(activityList.loc[j,'end(sec)'], unit='sec')
                            endActivity = end_time1 # when using inconsistent timings :endActivity = min(end_time1, start_time2)
                        break
                    # continue

                j += 1
            # print(activityList.loc[0,'VEHICLE'], end='____')
        print(seed)
        print(np.sum(np.sum(ODMatrix_df, axis=0))) #13264 for 30sec interval
        # ODMatrix_df.to_csv('D:/ax/gis/completePLUdata_{inter}sec/OD({a}-{b}_{c}-{d})_seed{ss}.CSV'.
        #                    format(inter = interval,a=ODstart[0:2], b= ODstart[3:5], c = ODend[0:2], d=ODend[3:5],ss=seed),header=True, index=True)
        ODMatrix_df.to_csv('/data/zahraeftekhar/research_temporal/completePLUdata_{inter}sec/OD({a}-{b}_{c}-{d})_seed{ss}.CSV'.
                           format(inter = interval,a=ODstart[0:2], b= ODstart[3:5], c = ODend[0:2], d=ODend[3:5],ss=seed),header=True, index=True)
        # ODMatrix_home.to_csv('D:/ax/gis/completePLUdata_{inter}sec/OD({a}-{b}_{c}-{d})_home_seed{ss}.CSV'.
        #                    format(inter = interval,a=ODstart[0:2], b= ODstart[3:5], c = ODend[0:2], d=ODend[3:5],ss=seed),header=True, index=True)
        # ODMatrix_work.to_csv('D:/ax/gis/completePLUdata_{inter}sec/OD({a}-{b}_{c}-{d})_work_seed{ss}.CSV'.
        #                    format(inter = interval,a=ODstart[0:2], b= ODstart[3:5], c = ODend[0:2], d=ODend[3:5],ss=seed),header=True, index=True)
        # ODMatrix_other.to_csv('D:/ax/gis/completePLUdata_{inter}sec/OD({a}-{b}_{c}-{d})_other_seed{ss}.CSV'.
        #                    format(inter = interval,a=ODstart[0:2], b= ODstart[3:5], c = ODend[0:2], d=ODend[3:5],ss=seed),header=True, index=True)

        # ODoriginal = pd.read_csv('D:/ax/OD({a}-{b}_{c}-{d}).CSV'.
        #                    format(inter = interval,a=ODstart[0:2], b= ODstart[3:5], c = ODend[0:2], d=ODend[3:5]))
        ODoriginal = pd.read_csv('/data/zahraeftekhar/research_temporal/output_base/OD({a}-{b}_{c}-{d}).CSV'.
                           format(inter = interval,a=ODstart[0:2], b= ODstart[3:5], c = ODend[0:2], d=ODend[3:5]))
        ODoriginal = ODoriginal.set_index('Unnamed: 0')
        print(np.sum(np.sum(ODoriginal, axis=0))) #13353 ************
# # #
# # #
# # # # anchorrrrrLoc = anchorLocs
# # # # anchorrrrrLoc['start'] = pd.to_timedelta(anchorLocs.loc[:,'start(sec)'],unit='s')
# # # # anchorrrrrLoc['end'] = pd.to_timedelta(anchorLocs.loc[:,'end(sec)'],unit='s')
# # # # anchorrrrrLoc['ID'] = anchorrrrrLoc['VEHICLE']
# # # # anchorrrrrLoc['duration'] = pd.to_timedelta(anchorLocs.loc[:,'duration(sec)'],unit='s')
# # # # # _________________________ number of activities per user ______________________________
# # # # anchorLocs = pd.DataFrame()
# # # # for t in range(0,10):
# # # #     anchor = pd.read_csv('D:/ax/gis/completePLUdata_30sec/clusterPLU_30sec/anchorLocsPLU_30sec_{number}.CSV'.format(number = t))
# # # #     anchorLocs= anchorLocs.append(anchor,ignore_index=True)
# # # # anchorLocs['end(sec)'] = anchorLocs['start(sec)']+anchorLocs['duration(sec)']
# # # # from lxml import etree
# # # # parser = etree.XMLParser(ns_clean=True, collect_ids=False)
# # # # itemlistExperienced= etree.parse("C:/Users/zahraeftekhar/eclipse-workspace/matsim-code-examples"
# # # #                                "/Results_PlanWithOnlyCar_30secSnapShot/ITERS/it.1/1.experienced_plans_Nogeneric(all allowed).xml").getroot()
# # # # vehicleIDs = anchorLocs['VEHICLE'].unique()
# # # # i=0
# # # # nActivity = pd.DataFrame(columns=['VEHICLE', 'GT', 'PLU'])
# # # # # mmm=1
# # # # for i in range(len(vehicleIDs)):
# # # #     # if i==mmm*100:
# # # #     #     print('{percentage} percent____{duration} sec'.format(percentage = i/len(vehicleIDs), duration = time.time()-startTime))
# # # #     #     mmm +=1
# # # #     nActivity.loc[i,'VEHICLE'] = vehicleIDs[i]
# # # #     nActivity.loc[i,'PLU'] = len(anchorLocs.loc[anchorLocs.loc[:,'VEHICLE']==vehicleIDs[i],"VEHICLE"])
# # # #     nActivity.loc[i,'GT'] = len(itemlistExperienced.find('person[@id="{id}"]'.format(id=vehicleIDs[i].astype(int))).findall('plan/activity'))-1
# # # # nActivity['comparison'] = nActivity['PLU']==nActivity['GT']
# # # # sum(nActivity['comparison'])/len(nActivity)
# # # # sum(nActivity['PLU'])
# # # # sum(nActivity['GT'])
# # # # correctNActivity = nActivity[(nActivity['comparison']==1)].VEHICLE
# # # # correctNActivity = correctNActivity.reset_index(drop=True)
# # # # # # # _________________________________ activity type_________________________
# # # # # # activityType = pd.DataFrame(columns=['VEHICLE', 'PLU','GT'])
# # # # # #
# # # # # for i in range(len(correctNActivity)):
# # # # #     activityType.loc[i,'VEHICLE'] = correctNActivity[i]
# # # # #     testActivityPLU = []
# # # # #     for j in (anchorLocs.loc[anchorLocs.loc[:,'VEHICLE']==correctNActivity[i],"activity"]):
# # # # #         testActivityPLU+=[j]
# # # # #     activityType.at[i,'PLU'] = testActivityPLU
# # # # #     testActivityGT = []
# # # # #     for j in (((itemlistExperienced.find('person[@id="{id}"]'.format(id=correctNActivity[i].astype(int))).findall('plan/activity')[1:]))):
# # # # #         if j.get('type')!='home' and j.get('type')!='work':
# # # # #             testActivityGT += ['other']
# # # # #         else:
# # # # #             testActivityGT += [j.get('type')]
# # # # #     activityType.at[i, 'GT'] = testActivityGT
# # # # #
# # # # # activityType['comparison'] = activityType['PLU']==activityType['GT']
# # # # # sum(activityType['comparison'])/len(activityType)
# # # # ___________________________________________________________________
# # # activityType = pd.DataFrame(columns=['VEHICLE', 'PLU','GT'])
# # # testActivityGT = []
# # # testActivityPLU = []
# # # starts = []
# # # durations = []
# # # for i in range(len(correctNActivity)):
# # #     # activityType.loc[i,'VEHICLE'] = correctNActivity[i]
# # #     for j in (anchorLocs.loc[anchorLocs.loc[:,'VEHICLE']==correctNActivity[i],"activity"]):
# # #         testActivityPLU+=[j]
# # #     for l in range(len(anchorLocs.loc[anchorLocs.loc[:,'VEHICLE']==correctNActivity[i],"start(sec)"])):
# # #             starts+=[(anchorLocs.loc[anchorLocs.loc[:,'VEHICLE']==correctNActivity[i],"start(sec)"].reset_index(drop=True))[l]]
# # #             durations+=[anchorLocs.loc[anchorLocs.loc[:,'VEHICLE']==correctNActivity[i],"duration(sec)"].reset_index(drop=True)[l]]
# # #
# # #     # activityType.at[i,'PLU'] = testActivityPLU
# # #     for k in (((itemlistExperienced.find('person[@id="{id}"]'.format(id=correctNActivity[i].astype(int))).findall('plan/activity')[1:]))):
# # #         if k.get('type')!='home' and k.get('type')!='work':
# # #             testActivityGT += ['other']
# # #         else:
# # #             testActivityGT += [k.get('type')]
# # # activityType = pd.DataFrame(columns=['PLU','GT'])
# # # activityType['PLU'] = testActivityPLU
# # # activityType['GT'] = testActivityGT
# # # activityType['start(sec)'] = starts
# # # activityType['duration(sec)'] = durations
# # # activityType['comparison'] = activityType['PLU']==activityType['GT']
# # # # ________________________________________________________________________
# # # sum(activityType['comparison'])/len(activityType)
# # # wrongActivityPredictions = activityType[activityType.comparison==0]
# # # homeWrongActivityPredictions = wrongActivityPredictions[wrongActivityPredictions.GT=='home']
# # # workWrongActivityPredictions = wrongActivityPredictions[wrongActivityPredictions.GT=='work']
# # # otherWrongActivityPredictions = wrongActivityPredictions[wrongActivityPredictions.GT=='other']
# # # import matplotlib.pyplot as plt
# # # plt.rcParams['figure.figsize'] = (16.0, 12.0)
# # # plt.style.use('ggplot')
# # # # plt.figure(figsize=(12, 8))
# # # params = {'legend.fontsize': 'x-large',
# # #           'figure.figsize': (15, 5),
# # #          'axes.labelsize': 'x-large',
# # #          'axes.titlesize':'x-large',
# # #          'xtick.labelsize':'x-large',
# # #          'ytick.labelsize':'x-large'}
# # # plt.rcParams.update(params)
# # # # # __________________ HOME PredictionError_start______________
# # # # plt.xticks((np.arange(0, 24, step=1)))
# # # # ax1 = (homeWrongActivityPredictions['start(sec)']/3600).plot(kind='hist', bins=60, density=True, alpha=0.5, label='prediction error of home activity', legend=True)
# # # # ax1.set_xlabel(u'start (hour)')
# # # # ax1.set_title('home prediction error based on start of the activity ')
# # # # ax1.set_ylabel('error frequency')
# # # # plt.savefig("D:/progress meeting/17June2020(Hans&Adam)/homePredictionError_start.png",dpi = 300)
# # # # # ____________________WORK PredictionError_start _______________
# # # # plt.figure()
# # # # plt.xticks((np.arange(0, 24, step=1)))
# # # # ax1 = (workWrongActivityPredictions['start(sec)']/3600).plot(kind='hist', bins=60, density=True, alpha=0.5, label='prediction error of work activity', legend=True)
# # # # ax1.set_xlabel(u'start (hour)')
# # # # ax1.set_title(u'work prediction error based on start of the activity ')
# # # # ax1.set_ylabel(u'error frequency')
# # # # plt.savefig("D:/progress meeting/17June2020(Hans&Adam)/workPredictionError_start.png",dpi = 300)
# # # # ____________________OTHER PredictionError_start _______________
# # # plt.figure()
# # # plt.xticks((np.arange(0, 24, step=1)))
# # # ax1 = (otherWrongActivityPredictions['start(sec)']/3600).plot(kind='hist', bins=60, density=True, alpha=0.5, label='prediction error of other activity', legend=True)
# # # ax1.set_xlabel(u'start (hour)')
# # # ax1.set_title(u'other prediction error based on start of the activity ')
# # # ax1.set_ylabel(u'error frequency')
# # # plt.savefig("D:/progress meeting/17June2020(Hans&Adam)/otherPredictionError_start.png",dpi = 300)
# # # # ________________________________ STAY PredictionError_start___________________
# # # clusterData =
# # #
# # # # # ____________________________________________________________
# # # # testings:
# # # # # import matplotlib.pyplot as plt
# # # # # plt.rcParams['figure.figsize'] = (16.0, 12.0)
# # # # # plt.style.use('ggplot')
# # # # # plt.figure(figsize=(12, 8))
# # # # # plt.xticks((np.arange(0, 24, step=1)))
# # # # # (anchorrrrrLoc['duration(sec)']/3600).plot(kind='hist', bins=96, density=True, alpha=0.5, label='Gaussian Kernel Density Estimation', legend=True)
# # # # # not identified stay locations:
# # # # # id=173, end_time="18:48:19" link="7038258_0" start_time="18:17:33" type="leisure"
# # # # # id="17308", end_time="15:07:41" link="7400277_0" start_time="14:36:26" type="sozializing"
# # # #


import os
import subprocess
import sys
from EOM_integrate import Ncores_FE
# import time

"""
This script runs all the study of Langevin dynamics for the dislocation loops.
It start by initializing the dislocation loops, then computes the force acting
on the loop resulting from the presence of a surface. This force is added to
the interaction term in the overdamped coupled Langevin equations.
One time step after that, the process is reiterated.
"""
# t0 = time.time()

# Get the current working directory
dir = os.getcwd()

# Go into the folder where the Cast3m scripts are
os.chdir(dir + '/Cast3m')

# run the meshing
subprocess.call('castem19 meshing.dgibi', shell=True)
# Go in the python directory and back to compute the stress on the file_mesh_surface
#
os.chdir(dir)
# os.system('python stressBC.py ' + sys.argv[1] + ' ' + sys.argv[2] + ' ' + sys.argv[3])
subprocess.call('python stressBC.py {}'.format(sys.argv[2]), shell=True)
os.chdir(dir + '/Cast3m')
#

# Run the program
# os.system('castem19 solution.dgibi')
subprocess.call('castem19 solution_mod.dgibi', shell=True)

# Run the processing
if Ncores_FE > 0:
    os.environ['MPI_RUNCMD']='mpirun -np {}'.format(Ncores_FE)
subprocess.call('castem19 processing.dgibi', shell=True)
os.environ['MPI_RUNCMD']=''

# Go back in the python scripts directory
if (len(sys.argv) > 2):
    subprocess.run('cp DISPCORR ' + dir + '/Cast3m/OUTPUT/DISPCORR' + sys.argv[1], shell = True)
else:
    subprocess.run('cp DISPCORR ' + dir + '/Cast3m/OUTPUT/DISPCORR', shell = True)

os.chdir(dir)

# print('Total time : ', time.time() - t0)


from HPOlibConfigSpace.configuration_space import ConfigurationSpace
from HPOlibConfigSpace.hyperparameters import UniformIntegerHyperparameter, UniformFloatHyperparameter

from ParamSklearn.components.base import ParamSklearnPreprocessingAlgorithm
from ParamSklearn.implementations.gem import GEM as GEMImpl
from ParamSklearn.constants import *

class GEM(ParamSklearnPreprocessingAlgorithm):

    def __init__(self, N, precond, random_state=None):
        self.N = N
        self.precond = precond

    def fit(self, X, Y):
        self.preprocessor = GEMImpl(self.N, self.precond)
        self.preprocessor.fit(X, Y)
        return self

    def transform(self, X):
        return self.preprocessor.transform(X)

    @staticmethod
    def get_properties(dataset_properties=None):
        return {'shortname': 'GEM',
                'name': 'Generalized Eigenvector extraction',
                'handles_missing_values': False,
                'handles_nominal_values': False,
                'handles_numerical_features': True,
                'prefers_data_scaled': True,
                'prefers_data_normalized': True,
                'handles_regression': False,
                'handles_classification': True,
                'handles_multiclass': True,
                'handles_multilabel': False,
                'is_deterministic': True,
                'handles_sparse': False,
                'handles_dense': True,
                'input': (DENSE, UNSIGNED_DATA),
                'output': (INPUT, UNSIGNED_DATA),
                'preferred_dtype': None}

    @staticmethod
    def get_hyperparameter_search_space(dataset_properties=None):
        N = UniformIntegerHyperparameter("N", 5, 20, default=10)
        precond = UniformFloatHyperparameter("precond", 0, 0.5, default=0.1)
        cs = ConfigurationSpace()
        cs.add_hyperparameter(N)
        cs.add_hyperparameter(precond)
        return cs

    def __str__(self):
        name = self.get_properties()['name']
        return "ParamSklearn %s" % name


from transformers import AutoProcessor, BlipForConditionalGeneration
from torch.utils.data import DataLoader

import csv
from PIL import Image
from torchvision import transforms
import torch
from torch.utils.data import Dataset, DataLoader
from image_caption_dataset import ImageCaptioningDataset

# Initialize processor and model
processor = AutoProcessor.from_pretrained("Salesforce/blip-image-captioning-base")
model = BlipForConditionalGeneration.from_pretrained("Salesforce/blip-image-captioning-base")

# Assuming 'dataset' is already defined or loaded
# Create an instance of your custom dataset
csv_file_path = "/Users/nero/Desktop/CaptionThis/data_sets/downloaded_images.csv"
transform = transforms.Compose([
    transforms.Resize((300, 300)),
    transforms.ToTensor(),
])
train_dataset = ImageCaptioningDataset(csv_file_path, transform, processor)

# Create a DataLoader for the training dataset
train_dataloader = DataLoader(train_dataset, shuffle=True, batch_size=2)

# Training setup (optimizer, device setup)
optimizer = torch.optim.AdamW(model.parameters(), lr=5e-5)
scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=10, gamma=0.1)  # Optional, if you want to use a scheduler

device = "cuda" if torch.cuda.is_available() else "cpu"
model.to(device)

# Training loop
TOTAL_EPOCHS = 10
for epoch in range(TOTAL_EPOCHS):
    print("Epoch:", epoch)
    model.train()

    total_loss = 0.0
    for idx, batch in enumerate(train_dataloader):
        optimizer.zero_grad()  # Reset gradients

        input_ids = batch["input_ids"].to(device)
        pixel_values = batch["pixel_values"].to(device)

        outputs = model(input_ids=input_ids, pixel_values=pixel_values, labels=input_ids)
        loss = outputs.loss

        if loss is not None:
            loss.backward()
            optimizer.step()

            total_loss += loss.item()
            print(f"Batch {idx} Loss: {loss.item()}")
        else:
            print(f"Batch {idx} Loss: None")

    scheduler.step()  # Adjust the learning rate

    # Save the model after each epoch (optional but recommended)
    torch.save(model.state_dict(), f'model_epoch_{epoch}.pth')

    # Print average loss
    avg_loss = total_loss / len(train_dataloader)
    print(f"Average Loss for Epoch {epoch}: {avg_loss}")


import RPi.GPIO as GPIO
import numpy as np
import cv2
import time
from time import sleep

GPIO.setmode(GPIO.BCM)

GPIO_TRIGGER1 = 27      #Left ultrasonic sensor
GPIO_ECHO1 = 17

GPIO_TRIGGER2 = 25      #Front ultrasonic sensor
GPIO_ECHO2 = 22

GPIO_TRIGGER3 = 24      #Right ultrasonic sensor
GPIO_ECHO3 = 23

MOTOR1B=6  #Left Motor
MOTOR1E=5
MOTOR2B=20  #Right Motor
MOTOR2E=21

GPIO.setwarnings(False)
GPIO.setup(GPIO_TRIGGER1,GPIO.OUT)  # Trigger
GPIO.setup(GPIO_ECHO1,GPIO.IN)      # Echo
GPIO.setup(GPIO_TRIGGER2,GPIO.OUT)  # Trigger
GPIO.setup(GPIO_ECHO2,GPIO.IN)      # Echo
GPIO.setup(GPIO_TRIGGER3,GPIO.OUT)  # Trigger
GPIO.setup(GPIO_ECHO3,GPIO.IN)      # Echo

# Set trigger to False (Low)
GPIO.output(GPIO_TRIGGER1, False)
GPIO.output(GPIO_TRIGGER2, False)
GPIO.output(GPIO_TRIGGER3, False)

GPIO.setup(MOTOR1B, GPIO.OUT)
GPIO.setup(MOTOR1E, GPIO.OUT)
GPIO.setup(MOTOR2B, GPIO.OUT)
GPIO.setup(MOTOR2E, GPIO.OUT)

#Define Robot Command
def reverse():
      GPIO.output(MOTOR1B, GPIO.HIGH)
      GPIO.output(MOTOR1E, GPIO.LOW)
      GPIO.output(MOTOR2B, GPIO.HIGH)
      GPIO.output(MOTOR2E, GPIO.LOW)

def forward():
      GPIO.output(MOTOR1B, GPIO.LOW)
      GPIO.output(MOTOR1E, GPIO.HIGH)
      GPIO.output(MOTOR2B, GPIO.LOW)
      GPIO.output(MOTOR2E, GPIO.HIGH)

def rightturn():
      GPIO.output(MOTOR1B,GPIO.LOW)
      GPIO.output(MOTOR1E,GPIO.HIGH)
      GPIO.output(MOTOR2B,GPIO.HIGH)
      GPIO.output(MOTOR2E,GPIO.LOW)

def leftturn():
      GPIO.output(MOTOR1B,GPIO.HIGH)
      GPIO.output(MOTOR1E,GPIO.LOW)
      GPIO.output(MOTOR2B,GPIO.LOW)
      GPIO.output(MOTOR2E,GPIO.HIGH)

def stop():
      GPIO.output(MOTOR1E,GPIO.LOW)
      GPIO.output(MOTOR1B,GPIO.LOW)
      GPIO.output(MOTOR2E,GPIO.LOW)
      GPIO.output(MOTOR2B,GPIO.LOW)

# Function For the distance between Utrasonic
def sonar(GPIO_TRIGGER,GPIO_ECHO):
      start=0
      stop=0
      # Set pins as output and input
      GPIO.setup(GPIO_TRIGGER,GPIO.OUT)  # Trigger
      GPIO.setup(GPIO_ECHO,GPIO.IN)      # Echo

      # Set trigger to False (Low)
      GPIO.output(GPIO_TRIGGER, False)

      # Allow module to settle
      time.sleep(0.01)

      #while distance > 5:
      #Send 10us pulse to trigger
      GPIO.output(GPIO_TRIGGER, True)
      time.sleep(0.00001)
      GPIO.output(GPIO_TRIGGER, False)
      begin = time.time()
      while GPIO.input(GPIO_ECHO)==0 and time.time()<begin+0.05:
            start = time.time()

      while GPIO.input(GPIO_ECHO)==1 and time.time()<begin+0.1:
            stop = time.time()

      # Calculate pulse length
      elapsed = stop-start
      distance = elapsed * 34000

      # That was the distance there and back so halve the value
      distance = distance / 2

      print("Distance : %.1f" % distance)
      # Reset GPIO settings
      return distance

#lower_and_upper = adaptive_hsv_filter.set_hsv_filter_object()
#print(lower_and_upper)
MIN_PIXEL_BALL = 700
MAX_PIXEL_BALL = 20000
min_pixel_found = False
car_near_ball = False

#Start
cap = cv2.VideoCapture(0)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)

while cap.isOpened():
    #distance coming from front ultrasonic sensor
    distanceC = sonar(GPIO_TRIGGER2,GPIO_ECHO2)
    #distance coming from right ultrasonic sensor
    distanceR = sonar(GPIO_TRIGGER3,GPIO_ECHO3)
    #distance coming from left ultrasonic sensor
    distanceL = sonar(GPIO_TRIGGER1,GPIO_ECHO1)
    ret, frame = cap.read()
    hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
    lower_red = np.array([0,50,50])
    upper_red = np.array([10,255,255])
    mask0 = cv2.inRange(hsv, lower_red, upper_red)
    lower_red = np.array([170,50,50])
    upper_red = np.array([180,255,255])
    mask1 = cv2.inRange(hsv, lower_red, upper_red)
    mask = mask0+mask1
    roi_left = mask[0:480,0:212]
    roi_center = mask[0:480,212:425]
    roi_right = mask[0:480,425:640]
    #cv2.imshow("roi_left", roi_left)
    #cv2.imshow("roi_center", roi_center)
    #cv2.imshow("roi_right", roi_right)
    #se la distanza dall'ultrasonic e maggiore di 15 la macchina riparte con la ricerca
    if distanceC > 15:
        car_near_ball = False
    #Dividiamo il frame il 3 porzioni Left Right e Central
    central_white_pixel = np.sum(roi_center == 255)
    left_white_pixel = np.sum(roi_left == 255)
    right_white_pixel = np.sum(roi_right == 255)
    print("left:" + str(left_white_pixel) + " center: " + str(central_white_pixel) + " right: " + str(right_white_pixel))

    if not car_near_ball:
        if central_white_pixel > MIN_PIXEL_BALL or left_white_pixel > MIN_PIXEL_BALL or right_white_pixel > MIN_PIXEL_BALL:
            min_pixel_found = True
        else:
            min_pixel_found = False

        if min_pixel_found:
            #se ci sono piu pixel bianchi nell frame centrale la macchina va avanti
            if central_white_pixel >= left_white_pixel and central_white_pixel >= right_white_pixel:
                print("go_on")
                forward()
                sleep(0.05)
                stop()
            #se ci sono piu pixel bianchi nell frame di destra la macchina va a destra
            elif right_white_pixel > central_white_pixel:
                print("go_right")
                rightturn()
                sleep(0.05)
                stop()
            #se ci sono piu pixel bianchi nell frame di sinistra la macchina va a sinistra
            elif left_white_pixel > central_white_pixel:
                print("car_left")
                leftturn()
                sleep(0.05)
                stop()
            #se la macchina si sta per scontrare / si è avvicinata all'oggetto rosso si ferma
            if distanceC < 15:
                car_near_ball = True

        else:
            #fase di ricerca della palla, gira a sinistra con pausa
            print("research")
            leftturn()
            sleep(0.1)
            print("stop_car")
            stop()
            sleep(0.1)

    if cv2.waitKey(1) == ord('q'):
        break
cap.release()
cv2.destroyAllWindows()


## CH05 - Backward Propagation
## 27th Sep 17'
# Apple shopping -

import numpy as np
from layer_naive import *

###############################################
# Example, a shopping for apples  only        #
###############################################
apple_price=100
apple_num=2
tax = 1.1

#Nodes for mul prepared,
mul_apple_node = MulLayer()
mul_tax_node = MulLayer()

#Forward Propagation
apple_total_price = mul_apple_node.forward(apple_price,apple_num)
total_price = mul_tax_node.forward(apple_total_price, tax)

#Backward Propagation
d_total_price = 1 #d means 'derivative'
d_apple_total_price, d_tax = mul_tax_node.backward(d_total_price)
d_apple_price, d_apple_num = mul_apple_node.backward(d_apple_total_price)

###############################################
# Example, a shopping for oranges and apples  #
###############################################

#initiations of variables
apple_num=2
apple_price=100
orange_num=3
orange_price=150
tax=1.1

# preparation of nodes
mul_apple_node = MulLayer()
mul_orange_node = MulLayer()
mul_tax_node = MulLayer()
add_fruit_node = AddLayer()

#forward propagation
apple_total_price = mul_apple_node.forward(apple_price,apple_num)
orange_total_price = mul_orange_node.forward(orange_price,orange_num)
total_price = add_fruit_node.forward(apple_total_price, orange_total_price)
taxed_total_price = mul_tax_node.forward(total_price,tax)

print('Price without Tax	', total_price)
print('price with Tax		', taxed_total_price)

#backward propagation
d_taxed_total_price = 1
d_total_price,d_tax =mul_tax_node.backward(d_taxed_total_price)
d_apple_total_price, d_orange_total_price = add_fruit_node.backward(d_total_price)
d_apple_price,d_apple_num = mul_apple_node.backward(d_apple_total_price)
d_orange_price,d_orange_num = mul_orange_node.backward(d_orange_total_price)

print('Derivative of orange price	',d_orange_price)
print('Derivative of orange num		',d_orange_num)
print('Derivative of apple price	',d_apple_price)
print('Derivative of apple num		',d_apple_num)


from .models import Cities, Cuisine, Kind, Cafe, Areaplace, Photo

kind_weight = 120
price_weight = 30
area_weight = 15
cuisine_weight = 15
parking_weight = 5

def transliterate(string):

    capital_letters = {u'А': u'A',
                       u'Б': u'B',
                       u'В': u'V',
                       u'Г': u'G',
                       u'Д': u'D',
                       u'Е': u'E',
                       u'Ё': u'E',
                       u'З': u'Z',
                       u'И': u'I',
                       u'Й': u'Y',
                       u'К': u'K',
                       u'Л': u'L',
                       u'М': u'M',
                       u'Н': u'N',
                       u'О': u'O',
                       u'П': u'P',
                       u'Р': u'R',
                       u'С': u'S',
                       u'Т': u'T',
                       u'У': u'U',
                       u'Ф': u'F',
                       u'Х': u'H',
                       u'Ъ': u'',
                       u'Ы': u'Y',
                       u'Ь': u'',
                       u'Э': u'E',}

    capital_letters_transliterated_to_multiple_letters = {u'Ж': u'Zh',
                                                          u'Ц': u'Ts',
                                                          u'Ч': u'Ch',
                                                          u'Ш': u'Sh',
                                                          u'Щ': u'Sch',
                                                          u'Ю': u'Yu',
                                                          u'Я': u'Ya',}

    lower_case_letters = {u'а': u'a',
                       u'б': u'b',
                       u'в': u'v',
                       u'г': u'g',
                       u'д': u'd',
                       u'е': u'e',
                       u'ё': u'e',
                       u'ж': u'zh',
                       u'з': u'z',
                       u'и': u'i',
                       u'й': u'y',
                       u'к': u'k',
                       u'л': u'l',
                       u'м': u'm',
                       u'н': u'n',
                       u'о': u'o',
                       u'п': u'p',
                       u'р': u'r',
                       u'с': u's',
                       u'т': u't',
                       u'у': u'u',
                       u'ф': u'f',
                       u'х': u'h',
                       u'ц': u'ts',
                       u'ч': u'ch',
                       u'ш': u'sh',
                       u'щ': u'sch',
                       u'ъ': u'',
                       u'ы': u'y',
                       u'ь': u'',
                       u'э': u'e',
                       u'ю': u'yu',
                       u'я': u'ya',}

    capital_and_lower_case_letter_pairs = {}

    for capital_letter, capital_letter_translit in capital_letters_transliterated_to_multiple_letters.items():
        for lowercase_letter, lowercase_letter_translit in lower_case_letters.items():
            capital_and_lower_case_letter_pairs[u"%s%s" % (capital_letter, lowercase_letter)] = u"%s%s" % (capital_letter_translit, lowercase_letter_translit)

    for dictionary in (capital_and_lower_case_letter_pairs, capital_letters, lower_case_letters):

        for cyrillic_string, latin_string in dictionary.items():
            string = string.replace(cyrillic_string, latin_string)

    for cyrillic_string, latin_string in capital_letters_transliterated_to_multiple_letters.items():
        string = string.replace(cyrillic_string, latin_string.upper())

    return string

def common_elements(list1, list2):
    return list(set(list1) & set(list2))

def get_cafe(cafe_id):
    return Cafe.objects.get(id=cafe_id)

def get_cafe_list():
    return Cafe.objects.order_by('rating').reverse()

def get_latest_list():
    return Cafe.objects.order_by('created_date').reverse()[:4]

def get_cities_list():
    return Cities.objects.all()

def get_cuisines_list():
    return Cuisine.objects.all()

def get_areas_list():
    return Areaplace.objects.all()

def get_kinds_list():
    return Kind.objects.all()

def count_weight(cuisines, areas, kinds, parking, minbill, maxbill, cafe):
    current_cuisines = cafe.cuisines.values_list('id', flat=True)
    cuisines = list(map(int, cuisines))
    cuisineweight = len(common_elements(cuisines, current_cuisines)) * cuisine_weight
    print(len(common_elements(cuisines, current_cuisines)))
    current_area = cafe.areaplace_id
    if current_area in areas:
        areaweight = area_weight
    else:
        areaweight = 0
    current_kind = cafe.kind_id
    print(current_kind)
    print(kinds)
    if str(current_kind) in kinds:
        kindweight = kind_weight
    else:
        kindweight = 0
    try:
        if cafe.bill > int(minbill) and cafe.bill < int(maxbill):
            priceweight = price_weight
        else:
            priceweight = 0
    except:
        priceweight = 0
    return cuisineweight + areaweight + kindweight + priceweight


# -*- coding: utf-8 -*-
"""
Created on Wed Jul 26 14:30:25 2017

@author: leblanckh
"""

import pandas as pd
import numpy as np
from scipy import stats
import math
import os
import sys
import statsmodels.api as sm
import statsmodels.formula.api as smf
import matplotlib.pyplot as plt
from matplotlib.patches import Circle
from matplotlib.collections import PatchCollection
import plotly
import plotly.plotly as py
plotly.tools.set_credentials_file(username='kleblanc5909', api_key='MIzFQggygCgieJcytNTR')
import plotly.graph_objs as go
plt.style.use('ggplot')
dataFolder = "/Users/leblanckh/data"
os.chdir(dataFolder)

#==============================================================================
# make a whole library of small modular functions
# that let you answer given R1, R2, and D what is A
# given R1, R2, and D, what is Beta1 and Beta2 ?
# given R1, R2, and D what is Aisoc1 and Aisoc2 ?
#==============================================================================

#Set up a list of radii, a dictionary of areas of overlap, and a list of Circle names for
#4 circles based on the actual lab data
Radii = [1.784124,1.381976597885342,2.111004122822376,2.185096861184158]
AreaOverlap = {'AO01':1,'AO12':2,'AO23':7, 'AO03':0}
CircleNames = ['Approach \nIncrease,10', 'Consumption \nIncrease,6', 'Approach \nDecrease,14', 'Consumption \nDecrease,15', 'No Response,15']

def Distance_Circle_Center_to_Chord (RadiusBig,RadiusSmall,CCDist):
    """
    given the radii of the two intersecting circles and the distance between their center points,
    calculate the distance between the center of the large circle and the chord

    inputs: RadiusBig, RadiusSmall, CCDist (D)
    return: CenterChordDistance
    """

    CenterChordDist = ( CCDist**2 - RadiusSmall**2 + RadiusBig**2) / (2*CCDist)
    return CenterChordDist

def Half_Chord_Length_Cusp_to_Cusp (RadiusBig,RadiusSmall,CCDist):
    """
    given the radii of the two intersecting circles, the distance between their center points,
    calculate half the cord length of the Chord line
    """
    Xsolved = Distance_Circle_Center_to_Chord(RadiusBig, RadiusSmall, CCDist)
    HalfChordLength = math.sqrt( RadiusBig**2 - Xsolved**2)
    return HalfChordLength

def Area_of_Small_Triangle (RadiusBig,RadiusSmall,CCDist):
    """
    given the radii of the two intersecting circles, the distance between their center points,
    calculate the area of the triangle from the center point of the small circle to the chord
    """
    Xsolved = Distance_Circle_Center_to_Chord(RadiusBig, RadiusSmall, CCDist)
    Ysolved = Half_Chord_Length_Cusp_to_Cusp(RadiusBig, RadiusSmall, CCDist)
    ASmTri = Ysolved*(CCDist-Xsolved)
    return ASmTri

def Area_of_Large_Triangle (RadiusBig, RadiusSmall, CCDist):
    """
    given the radii of the two intersecting circles, the distance between their center points,
    calculate the area of the triangle from the center point of the large circle to the chord
    """
    Xsolved = Distance_Circle_Center_to_Chord(RadiusBig, RadiusSmall, CCDist)
    Ysolved = Half_Chord_Length_Cusp_to_Cusp(RadiusBig, RadiusSmall, CCDist)
    ALgTri = Xsolved * Ysolved
    return ALgTri

def Angle_of_Small_Triangle(RadiusBig, RadiusSmall, CCDist):
    """
    given the radii of the two intersecting circles, the distance between their center points,
    calculate the angle of the triangle from the center point of the small circle to the chord
    """
    Xsolved = Distance_Circle_Center_to_Chord(RadiusBig, RadiusSmall, CCDist)
    X2 = CCDist - Xsolved
    ratio = X2/RadiusSmall
    Beta1 = 2*(math.acos(ratio))
    return Beta1

def Angle_of_Large_Triangle(RadiusBig, RadiusSmall, CCDist):
    """
    given the radii of the two intersecting circles, the distance between their center points,
    calculate the angle of the triangle from the center point of the large circle to the chord
    """
    Xsolved = Distance_Circle_Center_to_Chord(RadiusBig, RadiusSmall, CCDist)
    Beta2 = 2*(math.acos(Xsolved/RadiusBig))
    return Beta2

def Area_of_Small_Sector (RadiusBig, RadiusSmall, CCDist):
    """
    given the radii of the two intersecting circles, the distance between their center points,
    calculate the area of the circle section from the center point of the small circle to the chord
    """
    AngleSm = Angle_of_Small_Triangle(RadiusBig, RadiusSmall, CCDist)
    AreaSmSect = (AngleSm/(2*math.pi))*math.pi*RadiusSmall**2
    return AreaSmSect

def Area_of_Large_Sector(RadiusBig, RadiusSmall, CCDist):
    """
    given the radii of the two intersecting circles, the distance between their center points,
    calculate the area of the circle section from the center point of the large circle to the chord
    """
    AngleLg = Angle_of_Large_Triangle(RadiusBig, RadiusSmall, CCDist)
    AreaLgSect = (AngleLg/(2*math.pi))*math.pi*RadiusBig**2
    return AreaLgSect

def Area_of_Small_Lens(RadiusBig, RadiusSmall, CCDist):
    """
    given the radii of the two intersecting circles, the distance between their center points,
    calculate the area of the small lens
    """
    AreaSmSect = Area_of_Small_Sector(RadiusBig, RadiusSmall, CCDist)
    AreaSmTri = Area_of_Small_Triangle(RadiusBig, RadiusSmall, CCDist)
    AreaSmLens = AreaSmSect-AreaSmTri
    return AreaSmLens

def Area_of_Large_Lens(RadiusBig, RadiusSmall, CCDist):
    """
    given the radii of the two intersecting circles, the distance between their center points,
    calculate the area of the small lens
    """
    AreaLgSect = Area_of_Large_Sector(RadiusBig, RadiusSmall, CCDist)
    AreaLgTri = Area_of_Large_Triangle(RadiusBig, RadiusSmall, CCDist)
    AreaLgLens = AreaLgSect - AreaLgTri
    return AreaLgLens

def Area_of_Overlap(RadiusBig, RadiusSmall, CCDist):
    """
    given the radii of the two intersecting circles, the distance between their center points,
    calculate the area of overlap of the two circles
    """
    AreaSmLens = Area_of_Small_Lens(RadiusBig, RadiusSmall, CCDist)
    AreaLgLens = Area_of_Large_Lens(RadiusBig, RadiusSmall, CCDist)
    AreaOverlap = AreaSmLens + AreaLgLens
    return AreaOverlap

def Calculate_Distance_for_Given_Overlap(RadiusBig,RadiusSmall,AOverlap):
    """
    guesses a default center to center distance and calculates the area of overlap given that distance
    then compares the calculated area to the desired area of overlap, and adjusts the distance accordingly
    """
    Tolerance = 0.0001
    Dmin = RadiusBig - RadiusSmall
    Dmax = RadiusBig + RadiusSmall
    if AOverlap <= 0:
        print ("There is no overlap between these circles.")
        Dguess = -1
    elif AOverlap >= math.pi*RadiusSmall**2:
        print("The smaller circle is completely encircled by the larger circle.")
        Dguess = 0
    else:
        Dguess = (Dmax+Dmin)/2
        print ('Dguess',Dguess)
        AOCalc = Area_of_Overlap(RadiusBig,RadiusSmall,Dguess)
        print('AoCalc',AOCalc)
        errorVal = AOverlap - AOCalc
        print('errorVal',errorVal)
        loopCounter = 0

        while (abs(errorVal)) > Tolerance:
            loopCounter +=1
            #adjust distance
            if errorVal > 0:
                Dmax = Dguess
                Dguess = (Dguess+Dmin)/2
                AOCalc = Area_of_Overlap(RadiusBig,RadiusSmall,Dguess)
                errorVal = AOverlap - AOCalc
            elif errorVal < 0:
                Dmin = Dguess
                Dguess = (Dmax+Dguess)/2
                AOCalc = Area_of_Overlap(RadiusBig,RadiusSmall,Dguess)
                errorVal = AOverlap - AOCalc
            else:
                return Dguess
    return Dguess

def Calculate_Translation(Bangle,Dist):
    """
    calculate the X and Y coordinates for the new circle center given
    the bearing angle (assuming a due north of 0 degrees) and the center to center distance
    """
    Xnew = Dist*math.sin(Bangle)
    Ynew = Dist*math.cos(Bangle)
    return Xnew,Ynew

def Get_New_Center(Xog, Yog, Bangle, Dist):
    Xnew, Ynew = Calculate_Translation(Bangle, Dist)
    Xans = Xog + Xnew
    Yans = Yog + Ynew
    return Xans, Yans

def Get_Corners (Xcenter,Ycenter,Radius):
    """
    given the radius and coordinates of the center of the circle,
    calculcate the coordinates of the lower left and upper right corners of a box that
    inscribes the circle perfectly, such that the length of the sides of the box
    are equal to the diameter of the circle

    inputs: Radius of new circle, X and Y coordinates of new center
    return: X and Y coordinates of lower left and upper right corners of the box
    """
    XLL = Xcenter - Radius
    YLL = Ycenter - Radius
    XUR = Xcenter + Radius
    YUR = Ycenter + Radius
    return XLL,YLL,XUR,YUR

def Convert_Area_Overlap_Key_to_Radius (dictKey, radiiList):
    """
    using the numerical portion of the dictionary key for the area of overlap,
    translates this key to the associated circle radii and returns them
    """
    radiusList = []
    for aChar in dictKey:
        if aChar.isdigit() :
            radiusList.append(radiiList[int(aChar)])
    radiusList.sort(reverse=True)
    return radiusList

def find_All_Corners_in_Order_single_Overlap(theRadii, distances, bearingAngles):
    """
    Returns a list of all lower left (LL) and upper right (UR) corners for a
    set of circles based on their radii, distance between centers, and angle
    of bearings.  The first circle in the list of radii is assumed to be positioned
    such that its LL corner is at the origin.  The rest of the circles are assumed
    to be set up in a simple numbered fashion (i.e. 0 overlaps with 1, 1 overlaps
    with 2, etc).

    Inputs:
        theRadii - a list of all of the radii of each circle
        distances - a dictionary for the distance between each circle
        bearingAngles = a dictionary for the bearing angles between each circle
    Returns:
        corners - A list of LL and UR pairs for the cartesian coordinates of the
                  inscribing box for each of the circles
    """
    CenterX = []
    CenterY = []
    corners = []
    loopIdx = 0
    for radius in theRadii:
        print ("Current radius is ", radius)
        print ("The loopIdx is ", loopIdx)
        if loopIdx == 0:
            LL0 = (0, 0)
            UR0 = (2*theRadii[0], 2*theRadii[0])
            corners.append([LL0, UR0])
            Center0X, Center0Y = theRadii[0], theRadii[0]
            CenterX.append(Center0X)
            CenterY.append(Center0Y)
        else:
            #construct key
            prevIdx = loopIdx - 1
            curKey = 'AO' + str(prevIdx) + str(loopIdx)
            newCenterX, newCenterY = Get_New_Center(CenterX[prevIdx], CenterY[prevIdx], bearingAngles[curKey], distances[curKey])
            CenterX.append(newCenterX)
            CenterY.append(newCenterY)
            newXLL, newYLL, newXUR, newYUR = Get_Corners(newCenterX, newCenterY, theRadii[loopIdx])
            newCornerLL = (newXLL, newYLL)
            newCornerUR = (newXUR, newYUR)
            corners.append([newCornerLL, newCornerUR])
        loopIdx += 1

    return CenterX,CenterY,corners

    #A list to keep up with which radii still need their corners defined
    #unprocessedRadii = theRadii
#    everyKey = distances.keys()
#    radiiSets = []
#    radiiReverseDict = {}
#    for aKey in everyKey:
#        newSet = Convert_Area_Overlap_Key_to_Radius(aKey, theRadii)
#        radiiSets.append(newSet)
#        newTuple = tuple(newSet)
#        radiiReverseDict[newTuple] = aKey
#
#
#    unprocessedRadii.remove(theRadii)
#    knownRadii = [theRadii]
#
#    while (len(unprocessedRadii) > 0):
#        #look for keys with known radii
#        for aSet in radiiSets:
#            for known in knownRadii:
#                if known in aSet:
#                    #do all the processing and upkeep
#                    knownIdx = theRadii.index(known)
#                    theTuple = tuple(aSet)
#                    theKey = radiiReverseDict[theTuple]
#                    newCenterX, newCenterY = Get_New_Center()
#
#
#
#
#    for aDist in distances
#

RadList1 = Convert_Area_Overlap_Key_to_Radius('AO01', Radii)
print (RadList1)

DistanceAO = {}
OverlapKeys = AreaOverlap.keys()
for aKey in OverlapKeys:
    curAO = AreaOverlap.get(aKey)
    if curAO > 0:
        #need to calc distance between circles based on overlap
        #this process begins by determining how many radii are overlapping
        workingRadii = Convert_Area_Overlap_Key_to_Radius( aKey, Radii)
        numOverlap = len(workingRadii)
        if (numOverlap < 2):
            print ("Error with ", aKey, ", there must be at least 2 radii returned for an Overlap to occur,")
        elif (numOverlap == 2):
            #simple case of exactly 2 overlapping circles!
            currDistance = Calculate_Distance_for_Given_Overlap(workingRadii[0], workingRadii[1], curAO)
            DistanceAO[aKey] = currDistance
        else:
            #too many overlapping circles...
            print ("The number of radii overlapping is too large... ", numOverlap)

#Use previously defined Distance function to calculate the distance between circle centerpoints
Dist01 = Calculate_Distance_for_Given_Overlap(Radii[1], Radii[0], AreaOverlap['AO01'])
Dist12 = Calculate_Distance_for_Given_Overlap(Radii[2], Radii[1], AreaOverlap['AO12'])
Dist23 = Calculate_Distance_for_Given_Overlap(Radii[2], Radii[3], AreaOverlap['AO23'])
#Dist03 = Calculate_Distance_for_Given_Overlap(Radii[3], Radii[0], AreaOverlap['AO03'])
print (DistanceAO)
print (Dist01)
print (Dist12)
print (Dist23)
#print (Dist03)

#pick bearing angles to achieve desired figure shape
angle01 = math.pi * 7/6
angle12 = math.pi * 5/6
angle23 = math.pi * 1/2
#angle03 = math.pi * 2/3

theBearings = {'AO01':angle01, 'AO12':angle12, 'AO23':angle23}
#Now get the corners
allCenterXs,allCenterYs,allCornersDataSet01 = find_All_Corners_in_Order_single_Overlap(Radii, DistanceAO, theBearings)

print("Final answer:  ", allCenterXs, allCenterYs, allCornersDataSet01)

fig, ax = plt.subplots()
plt.axes()

circle1 = plt.Circle((allCenterXs[0],allCenterYs[0]),radius = Radii[0], color = 'g', alpha = .3)
circle2 = plt.Circle((allCenterXs[1],allCenterYs[1]),radius = Radii[1], color = 'b', alpha = .3)
circle3 = plt.Circle((allCenterXs[2],allCenterYs[2]),radius = Radii[2], color = 'r', alpha = .3)
circle4 = plt.Circle((allCenterXs[3],allCenterYs[3]),radius = Radii[3], color = 'y', alpha = .3)
circle5 = plt.Circle((6,2),radius = 2.185096861184158, color = 'k', alpha = .3)
plt.gca().add_patch(circle1)
plt.gca().add_patch(circle2)
plt.gca().add_patch(circle3)
plt.gca().add_patch(circle4)
plt.gca().add_patch(circle5)

plt.text(allCenterXs[0], allCenterYs[0],CircleNames[0], horizontalalignment='center', verticalalignment='center',multialignment='center')
plt.text(allCenterXs[1], allCenterYs[1],CircleNames[1], horizontalalignment='center', verticalalignment='center',multialignment='center')
plt.text(allCenterXs[2],allCenterYs[2],CircleNames[2], horizontalalignment='center', verticalalignment='center',multialignment='center')
plt.text(allCenterXs[3],allCenterYs[3],CircleNames[3], horizontalalignment='center', verticalalignment='center',multialignment='center')
plt.text(6,2,CircleNames[4], horizontalalignment='center', verticalalignment='center')
plt.text(1,0.5, AreaOverlap['AO01'], color = 'red')
plt.text(1,-1, AreaOverlap['AO12'], color = 'red')
plt.text(3,-3, AreaOverlap['AO23'], color = 'red')

plt.axis('scaled')
plt.savefig('ConsumptionApproach2.svg',format = "svg", transparent = True)

#trace0 = go.Scatter(
#    x = allCenterXs,
#    y= allCenterYs,
#    text=['$Consumption Increase$', '$Approach Increase$','$Consumption Decrease$','$Approach Decrease$'],
#    mode='text',
#    textfont=dict(
#        color='black',
#        size=18,
#        family='Arial',
#    )
#)
#
#data = [trace0]
#
#layout = {
#    'xaxis': {
#        'showticklabels': False,
#        'autotick': False,
#        'showgrid': False,
#        'zeroline': False,
#    },
#    'yaxis': {
#        'showticklabels': False,
#        'autotick': False,
#        'showgrid': False,
#        'zeroline': False,
#    },
#    'shapes': [
#        {
#            'opacity': 0.3,
#            'xref': 'x',
#            'yref': 'y',
#            'fillcolor': 'brown',
#            'x0': allCornersDataSet01[0][0][0],
#            'y0': allCornersDataSet01[0][0][1],
#            'x1': allCornersDataSet01[0][1][0],
#            'y1': allCornersDataSet01[0][1][1],
#            'type': 'circle',
#            'line': {
#                'color': 'brown',
#            },
#        },
#        {
#            'opacity': 0.3,
#            'xref': 'x',
#            'yref': 'y',
#            'fillcolor': 'green',
#            'x0': allCornersDataSet01[1][0][0],
#            'y0': allCornersDataSet01[1][0][1],
#            'x1': allCornersDataSet01[1][1][0],
#            'y1': allCornersDataSet01[1][1][1],
#            'type': 'circle',
#            'line': {
#                'color': 'green',
#            },
#        },
#        {
#            'opacity': 0.3,
#            'xref': 'x',
#            'yref': 'y',
#            'fillcolor': 'brown',
#            'x0': allCornersDataSet01[2][0][0],
#            'y0': allCornersDataSet01[2][0][1],
#            'x1': allCornersDataSet01[2][1][0],
#            'y1': allCornersDataSet01[2][1][1],
#            'type': 'circle',
#            'line': {
#                'color': 'brown',
#            },
#        },
#        {
#            'opacity': 0.3,
#            'xref': 'x',
#            'yref': 'y',
#            'fillcolor': 'green',
#            'x0': allCornersDataSet01[3][0][0],
#            'y0': allCornersDataSet01[3][0][1],
#            'x1': allCornersDataSet01[3][1][0],
#            'y1': allCornersDataSet01[3][1][1],
#            'type': 'circle',
#            'line': {
#                'color': 'green',
#            },
#        },
#    ],
#    'margin': {
#        'l': 20,
#        'r': 20,
#        'b': 100
#    },
#    'height': 800,
#    'width': 800,
#}
#fig = {
#    'data': data,
#    'layout': layout,
#}
#py.plot(fig, filename='EulerDiagram_ConsumptionApproach')

#if DistC2C>= RadSmall+RadLg:
#    print ("There is no overlap between these circles.")
#
#elif DistC2C <= RadLg - RadSmall:
#    print ("The smaller circle is completely encircled by the larger circle. Overlap = ", math.pi*RadSmall**2)
#else:
#
#    Overlap = Area_of_Overlap(RadLg,RadSmall,DistC2C)
#    CalcDistC2C = Calculate_Distance_for_Given_Overlap(RadLg,RadSmall,AreaOverlap)
#    NewCenterCircle = Get_New_Center(0,0,(3*math.pi)/2,CalcDistC2C)
#
#print(Overlap, CalcDistC2C, NewCenterCircle)


# -*- coding: utf-8 -*-
import random
import json
import cardsource
from bs4 import BeautifulSoup as bs

def pick_rand(vocab):
    if len(vocab) < 20:
        rand = vocab
    else:
        rand = random.sample(vocab, 20)
    return rand

def make_deck():
    vocab = {}
    card_source = [cardsource.BASIC, cardsource.ADVANCED] # Include source file

    list_name = ["basic", "advanced"]

    for n, source in enumerate(card_source):

        soup = bs(source, "html.parser")
        vocab_list = soup.find(class_='SetPage-termsList')

        for child in vocab_list:

            term = child.find(class_='SetPageTerm-wordText').find(class_='TermText').getText().strip()
            definition = child.find(class_='SetPageTerm-definitionText').find(class_='TermText').getText().strip()

            vocab[term] = {"def": definition, "learned": False, "list": list_name[n]}

    with open('test.json', 'w') as outfile:
        json.dump(vocab, outfile)

if __name__=='__main__':

    for n in range(0, 50):

        with open('vocab.json') as data_file:
            vocab = json.load(data_file)

        learned = {}

        word_list = []
        for word in vocab:
            word_list.append(word)
        random_list = pick_rand(word_list)

        for term in random_list:
            learned[term] = {"def": vocab[term]["def"], "list": vocab[term]["list"]}
            vocab.pop(term, None)
        filename = 'week/week%d.json' % n
        with open(filename, 'w') as outfile:

            json.dump(learned, outfile)

        with open('vocab.json', 'w') as outfile:
            json.dump(vocab, outfile)


from kuantum.kyber.utils.num_type import int16, int32, uint32
from kuantum.kyber.utils.constants import PARAMS_N, PARAMS_ETA_1, PARAMS_ETA_2, POLY_BYTES

def load24_bit(x):
    """
    load 3 bytes into a 32-bit integer needed for Kyber 512
    arg0: input byte array
    return:  32-bit unsigned integer
    """
    r = x[0] & 0xff
    r |= (x[1] & 0xff) << 8
    r |= (x[2] & 0xff) << 16
    return r

def load32_bit(x):
    """
    load 4 bytes into a 32-bit integer needed for Kyber 768
    and Kyber 1024

    arg0: input byte array
    return:  32-bit unsigned integer
    """
    r = x[0] & 0xff  # to mask negative values
    r |= (x[1] & 0xff) << 8
    r |= (x[2] & 0xff) << 16
    r |= (x[3] & 0xff) << 24
    return r

def gen_cbd_pol(buff, k):
    """
    compute polynomial with coefficients distributed according to
    a centered binomial distribution

    arg0: array of uniformly random bytes
    arg1: eta = 2 for Kyber 512 and eta = 3 Kyber 768 / Kyber 1024

    return: array with coefficients
    """
    r = [0 for _ in range(0, POLY_BYTES)]
    if k == 2:
        for i in range(0, PARAMS_N // 4):
            t = load24_bit(buff[3 * i:])
            d = t & 0x00249249
            d = d + ((t >> 1) & 0x00249249)
            d = d + ((t >> 2) & 0x00249249)
            for j in range(0, 4):
                a = ((d >> (6 * j + 0)) & 0x7)
                b = ((d >> (6 * j + PARAMS_ETA_1)) & 0x7)
                r[4 * i + j] = (a - b)
    else:
        for i in range(0, PARAMS_N // 8):
            t = load32_bit(buff[4 * i:])
            d = t & 0x55555555
            d = d + ((t >> 1) & 0x55555555)
            for j in range(0, 8):
                a = ((d >> (4 * j + 0)) & 0x3)
                b = ((d >> (4 * j + PARAMS_ETA_2)) & 0x3)
                r[8 * i + j] = (a - b)
    return r