from imports import *
import functions
from parameters import *
#import PAA_LISA
import NOISE_LISA as pack

# tele and PAA aim
class AIM():
    global LA
    LA = PAA_LISA.la()

    def __init__(self,wfe,**kwargs):
        print('Start calculating telescope and PAAM aim')

        self.PAAM_method = wfe.PAAM_control_method
        if self.PAAM_method =='SS_lim':
            self.FOV_control = kwargs.pop('FOV_control',1e-6)
        self.tele_method = wfe.tele_control
        self.offset_control = kwargs.pop('offset_control',False)
        self.compensation_tele = kwargs.pop('compensation_tele',True)
        global LA
        LA = PAA_LISA.la()
        import imports

        self.wfe = wfe
        self.noise = pack.Noise(wfe=wfe)
        self.PAAM_method = wfe.PAAM_control_method
        self.tele_method = wfe.tele_control

    def static_tele_angle(self,select,i,dt=False,side='l'):
        if select=='PAAM':
            if side=='l':
                #func = self.wfe.data.PAA_func['l_out']
                func = self.wfe.data.ang_out_l
                #func_y = self.wfe.data.PAA_func['l_out']
            elif side=='r':
                #func = self.wfe.data.PAA_func['r_out']
                func = self.wfe.data.ang_out_r
                #func_y = self.wfe.data.PAA_func['r_out']

        elif select=='tele':
            if side=='l':
                func = self.tele_ang_l_fc
            elif side=='r':
                func = self.tele_ang_r_fc

        t_all = self.wfe.data.t_all
        if dt==False:
            dt = t_all[1]-t_all[0]
        t_vec = np.linspace(t_all[0],t_all[-1],(t_all[1]-t_all[0])/dt)
        val=[]
        for t in t_vec:
            val.append(func(i,t))

        return np.mean(val)

    def do_static_tele_angle(self,select,dt=False):
        tele_ang_off_l = lambda i: self.static_tele_angle(select,i,dt=dt,side='l')
        tele_ang_off_r = lambda i: self.static_tele_angle(select,i,dt=dt,side='r')

        if select=='PAAM':
            self.offset_PAAM_l = tele_ang_off_l
            self.offset_PAAM_r = tele_ang_off_r
        elif select=='tele':
            self.offset_tele_l = tele_ang_off_l
            self.offset_tele_r = tele_ang_off_r

        return 0

    def tele_control_ang_fc_calc(self,i,t,side='l'):
        coor = functions.coor_SC(self.wfe,i,t)
        if side=='l':
            v = -self.wfe.data.u_l_func_tot(i,t)
        elif side=='r':
            v = -self.wfe.data.u_r_func_tot(i,t)

        if self.compensation_tele==True:
            v = LA.unit(v)*(np.linalg.norm(v)-self.wfe.L_tele)

        v_SC = LA.matmul(coor,v)

        #print(v_SC)
        import warnings
        warnings.simplefilter("error", RuntimeWarning)
        try:
            ang = np.arcsin(v_SC[2]/np.linalg.norm(v_SC[0])) # Angle betweed x and r component, whih is the optimal telescope pointing angle (inplane)
        except RuntimeWarning:
            print(v_SC[2],v_SC[0])
            print(i,t,v)
            ang = np.nan
            pass

        return ang

    def get_aim_accuracy(self,i,t,side):
        [i_self,i_left,i_right] = PAA_LISA.utils.i_slr(i)
        if side=='l':
            i_calc = i_left
            s_calc = 'r'
        elif side=='r':
            i_calc=i_right
            s_calc='l'

        ret =  self.wfe.aim0.get_received_beam_duration(i_calc,t,s_calc,ksi=[0,0])
        [z,y,x] = LA.matmul(ret['coor_end'],ret['beam_in'])

        angx = np.sign(x)*abs(np.arctan(x/z))
        angy = np.sign(y)*abs(np.arctan(y/z))

        delay = ret['L_r']

        return [angx,angy,delay]

    def tele_control_ang_fc(self):
        # Obtaines functions for optimal telescope pointing vector
        delay_l = lambda i,t: self.get_aim_accuracy(i,t,'l')[2]
        delay_r = lambda i,t: self.get_aim_accuracy(i,t,'r')[2]
        ang_tele_extra_l = lambda i,t: self.get_aim_accuracy(i,t,'l')[0]
        ang_tele_extra_r = lambda i,t: self.get_aim_accuracy(i,t,'r')[0]

        self.tele_ang_l_fc = lambda i,t: self.wfe.aim0.tele_l_ang(i,t)+ang_tele_extra_l(i,t+delay_l(i,t))
        self.tele_ang_r_fc = lambda i,t: self.wfe.aim0.tele_r_ang(i,t)+ang_tele_extra_r(i,t+delay_r(i,t))

        #self.tele_ang_l_fc = lambda i,t: self.tele_control_ang_fc_calc(i,t,side='l')
        #self.tele_ang_r_fc = lambda i,t: self.tele_control_ang_fc_calc(i,t,side='r')

        return 0

    def tele_aim(self,method=False,dt=3600*24*10,jitter=False,tau=3600*24*5,mode='overdamped',iteration=0,tele_ang_extra=False):

        self.tele_control_ang_fc()

        if method == False:
            method = self.tele_method
        else:
            self.tele_method = method

        print('The telescope control method is: '+method)
        print(' ')

        tele_l0 = self.tele_ang_l_fc
        tele_r0 = self.tele_ang_r_fc
        if iteration>0:
            print('Number of pointing iterations is '+str(iteration))
            tele_l_extr0=lambda i,t: 0
            tele_r_extr0=lambda i,t: 0
            step=0
            while step<iteration:
                tele_vec0 = self.tele_aim_vec([tele_l0,tele_r0])
                tele_l_extr1 = lambda i,t: self.iteration_tele_calc(i,t,'l',tele_vec0)
                tele_r_extr1 = lambda i,t: self.iteration_tele_calc(i,t,'r',tele_vec0)
                tele_l1 = lambda i,t: tele_l0(i,t)+tele_l_extr1(i,t)
                tele_r1 = lambda i,t: tele_r0(i,t)+tele_r_extr1(i,t)
                #del tele_l0, tele_r0, tele_l_extr0, tele_r_extr0,tele_vec0
                #tele_l0 = tele_l1
                #tele_r0 = tele_r1
                #tele_l_extr0 = tele_l_extr1
                #tele_r_extr0 = tele_r_extr1
                #del tele_vec0, tele_l_extr1, tele_r_extr1, tele_l1, tele_r1

                step=step+1
            tele_l = tele_l1
            tele_r = tele_r1
        else:
            tele_l = tele_l0
            tele_r = tele_r0

        # Calculating telescope angle for 'full control', 'no control' and 'SS' (step and stair)
        if method=='full control':
            tele_l = tele_l
            tele_r = tele_r

        elif method=='no control':
            #self.do_static_tele_angle('tele')
            if tele_ang_extra==False:
                offset_l = [0,0,0]
                offset_r = [0,0,0]
            else:
                [offset_l,offset_r] = tele_ang_extra

            tele_l = lambda i,t: np.radians(-30)+offset_l[i-1]*0.5
            tele_r = lambda i,t: np.radians(30)+offset_r[i-1]*0.5

        elif method=='SS': #After dt, the telescope is pointed again
            tele_l_SS = lambda i,t: self.tele_ang_l_fc(i,t-(t%dt))
            tele_r_SS = lambda i,t: self.tele_ang_r_fc(i,t-(t%dt))
            print('Taken '+mode+' step response for telescope SS control with tau='+str(tau)+'sec')
            tele_l = self.step_response(tele_l_SS,'tele',dt,tau=tau,mode=mode)
            tele_r = self.step_response(tele_r_SS,'tele',dt,tau=tau,mode=mode)
            self.tele_l_ang_SS = tele_l_SS
            self.tele_r_ang_SS = tele_r_SS

        else:
            raise ValueError('Please select a valid telescope pointing method')

        # Adding jitter
        if jitter!=False:
            self.tele_l_ang = lambda i,t: self.add_jitter(tele_l,i,t,1e-6,1e10,dt=0.1)
            self.tele_r_ang = lambda i,t: self.add_jitter(tele_r,i,t,1e-6,1e10,dt=0.1)
        else:
            self.tele_l_ang = tele_l
            self.tele_r_ang = tele_r

        # Calculating new pointing vectors and coordinate system
        self.tele_l_coor = lambda i,t: pack.functions.coor_tele(self.wfe,i,t,self.tele_l_ang(i,t))
        self.tele_r_coor = lambda i,t: pack.functions.coor_tele(self.wfe,i,t,self.tele_r_ang(i,t))
        self.tele_l_vec = lambda i,t: LA.unit(pack.functions.coor_tele(self.wfe,i,t,self.tele_l_ang(i,t))[0])*L_tele
        self.tele_r_vec = lambda i,t: LA.unit(pack.functions.coor_tele(self.wfe,i,t,self.tele_r_ang(i,t))[0])*L_tele

        return 0

    def tele_aim_vec(self,ang):
        tele_l_vec = lambda i,t: LA.unit(pack.functions.coor_tele(self.wfe,i,t,ang[0](i,t))[0])*L_tele
        tele_r_vec = lambda i,t: LA.unit(pack.functions.coor_tele(self.wfe,i,t,ang[1](i,t))[0])*L_tele

        return [tele_l_vec,tele_r_vec]

    def iteration_tele_calc(self,i,t,side,tele_vec):
        [i_self,i_left,i_right] = PAA_LISA.utils.i_slr(i)

        if side=='l':
            tele_send = tele_vec[0](i_self,t)
            i_next = i_left
            tdel = self.wfe.data.L_sl_func_tot(i_self,t)
            tele_rec = LA.unit(tele_vec[1](i_next,t+tdel))*self.wfe.L_tele
        elif side=='r':
            tele_send = tele_vec[1](i_self,t)
            i_next = i_right
            tdel = self.wfe.data.L_sr_func_tot(i_self,t)
            tele_rec = LA.unit(tele_vec[0](i_next,t+tdel))*self.wfe.L_tele

        tele_send = LA.unit(tele_send)*tdel*c
        n = self.wfe.data.n_func(i_self,t)
        v = tele_send-tele_rec
        ang_extr = LA.ang_in(v,n,tele_send)

        return ang_extr

    #def iteration_tele(self,ang0):
    #    self.ang_extr_l = lambda i,t:  self.iteration_tele_calc(i,t,'l')
    #    self.ang_extr_r = lambda i,t:  self.iteration_tele_calc(i,t,'r')
    #
    #    #Adjust telescope angle
    #    tele_l_ang_fc = ang0[0]
    #    tele_r_ang_fc = ang0[1]

    #    tele_pp_l_ang = lambda i,t: tele_l_ang_fc(i,t)+self.ang_extr_l(i,t)
    #    tele_pp_r_ang = lambda i,t: tele_l_ang_fc(i,t)+self.ang_extr_r(i,t)

    #    self.tele_l_ang_fc = lambda i,t: self.tele_l_ang_fc(i,t)+self.ang_extr_l(i,t)
    #    self.tele_r_ang_fc = lambda i,t: self.tele_r_ang_fc(i,t)+self.ang_extr_r(i,t)

    #    return [tele_pp_l_ang,tele_pp_r_ang]
    #
    #def tele_aim(self,method=False,dt=3600*24*10,jitter=False,tau=3600*24*5,mode='overdamped',iteration=1):
    #
    #    self.tele_control_ang_fc()
    #    ang_iter = [self.tele_ang_l_fc,self.tele_ang_r_fc]

    #    if method == False:
    #        method = self.tele_method
    #    else:
    #        self.tele_method = method

    #    if iteration>0 and method!='no control':
    #        for step in range(1,iteration+1):
    #            self.tele_aim_ang(method='full control',dt=dt,jitter=False,tau=tau,mode=mode)
    #            ang_iter = self.iteration_tele(ang_iter)
    #            self.tele_aim_vec(ang=ang_iter)
    #            print('Iteration: '+str(step))

    #    self.tele_aim_ang(method=method,dt=dt,jitter=jitter,tau=tau,mode=mode)
    #    self.tele_aim_vec()

    #    return 0

    def add_jitter(self,ang_func,i,scale_v,dt=3600,PSD=False,f0=1e-6,f_max=1e-3,N=4096,offset=1,scale_tot=1):
        t_stop = self.wfe.t_all[-2]
        if PSD==False:
            PSD = lambda f: 16*1e-9
        func_noise = self.noise.Noise_time(f0,f_max,N,PSD,t_stop)[1]

        offset = offset*scale_tot
        scale_v = scale_v*scale_tot

        # add position jitter
        # add velocity jitter
        v = lambda t: (ang_func(t) - ang_func(t-dt))/dt
        ret = lambda t: func_noise(t)*(offset+v(t)*scale_v)+ang_func(t)
        #return np.random.normal(ang_func(i,t),dang*(1+v*scale_v))#...adjust: make correlated errors
        return ret

    def SS_FOV_control(self,i,f_PAA,xlim=False,accuracy=3600,FOV=1e-6,step=False,step_response=False):
        wfe=self.wfe
        if xlim==False:
            xlim=[wfe.t_all[1],wfe.t_all[-2]]
        if step==False:
            step=0.5*FOV
        self.FOV_control = FOV

        x0=xlim[0]
        function=lambda t: f_PAA(i,t)

        steps = [(function(x0)-function(x0)%step)]
        PAAM = [steps[-1]]
        t_PAAM = [x0]
        x_list=[x0]
        while x0<=xlim[1]:
            fb = f_PAA(i,x0)
            if fb-steps[-1]>step:
                steps.append(steps[-1])
                steps.append(step+steps[-1])
                x_list.append(x0-10)
                x_list.append(x0)
                t_PAAM.append(x0)
                PAAM.append(steps[-1])
            elif fb-steps[-1]<-step:
                steps.append(steps[-1])
                steps.append(-step+steps[-1])
                x_list.append(x0-10)
                x_list.append(x0)
                t_PAAM.append(x0)
                PAAM.append(steps[-1])

            x0=x0+accuracy
        steps.append(steps[-1])
        x_list.append(x0)

        try:
            PAAM_func = pack.functions.interpolate(np.array(x_list),np.array(steps))
        except ValueError:
            PAAM_func = lambda t: 0
        else:
            ret=[t_PAAM,PAAM,PAAM_func]

        return ret

    def SS_control(self,function,i,t,dt=False,xlim=False,accuracy=3600,FOV=1e-6,step=False):
        if dt == False:
            ret = self.SS_FOV_control(i,function,xlim=xlim,accuracy=accuracy,FOV=FOV,step=step)

        else:
            t0 = t-(t%dt)
            if t0==0 or t0==self.wfe.data.t_all[-1]:
                ret = np.nan
            else:
                ret = function(i,t-(t%dt))

        return ret

    def PAAM_control_ang_fc(self):
        # Obtaines functions for optimal telescope pointing vector
        delay_l = lambda i,t: self.get_aim_accuracy(i,t,'l')[2]
        delay_r = lambda i,t: self.get_aim_accuracy(i,t,'r')[2]
        ang_PAAM_extra_l = lambda i,t: self.get_aim_accuracy(i,t,'l')[1]
        ang_PAAM_extra_r = lambda i,t: self.get_aim_accuracy(i,t,'r')[1]

        self.PAAM_ang_l_fc = lambda i,t: self.wfe.aim0.beam_l_ang(i,t)+ang_PAAM_extra_l(i,t+delay_l(i,t))
        self.PAAM_ang_r_fc = lambda i,t: self.wfe.aim0.beam_r_ang(i,t)+ang_PAAM_extra_r(i,t+delay_r(i,t))

    def PAAM_control(self,method=False,dt=3600*24,jitter=False,tau=1,mode='overdamped',PAAM_ang_extra=False):
        if method==False:
            method = self.PAAM_method
        else:
            self.PAAM_method = method

        print('The PAAM control method is: ' +method)
        print(' ')

        #ang_fc_l = lambda i,t: self.wfe.data.PAA_func['l_out'](i,t)
        #ang_fc_r = lambda i,t: self.wfe.data.PAA_func['r_out'](i,t)
        self.PAAM_control_ang_fc()
        ang_fc_l = lambda i,t: self.PAAM_ang_l_fc(i,t)
        ang_fc_r = lambda i,t: self.PAAM_ang_r_fc(i,t)

        self.PAAM_fc_ang_l = ang_fc_l
        self.PAAM_fc_ang_r = ang_fc_r

        # Obtaining PAAM angles for 'fc' (full control), 'nc' (no control) and 'SS' (step and stair)

        if method=='full control':
            ang_l = ang_fc_l
            ang_r = ang_fc_r
        elif method=='no control':
            self.do_static_tele_angle('PAAM')
            if PAAM_ang_extra==False:
                ang_l = lambda i,t: 0
                ang_r = lambda i,t: 0
            else:
                [offset_l,offset_r] = PAAM_ang_extra
                ang_l = lambda i,t: offset_l[i-1]*0.5
                ang_r = lambda i,t: offset_r[i-1]*0.5

        elif method=='SS':
            ang_l_SS = lambda i,t: ang_fc_l(i,t-(t%dt)) # Adjusting the pointing every dt seconds
            ang_r_SS = lambda i,t: ang_fc_r(i,t-(t%dt))
            print('Taken '+method+' step response for PAAM SS control with tau='+str(tau)+' sec')
            mode='overdamped'

        elif method=='SS_lim':
            ang_l_SS = lambda i: self.SS_control(ang_fc_l,i,False,dt=False,xlim=False,accuracy=3600,FOV=self.FOV_control,step=False)
            ang_r_SS = lambda i: self.SS_control(ang_fc_r,i,False,dt=False,xlim=False,accuracy=3600,FOV=self.FOV_control,step=False)
            print('Taken '+method+' step response for PAAM SS control with tau='+str(tau)+' sec and step limit='+str(self.FOV_control*1e6)+' radians')
            mode='not_damped' #...damped SS not implemented jet for SS_lim
        else:
            raise ValueError('Please select a valid PAAM pointing method')

        if 'SS' in method:
            ang_l = self.step_response(ang_l_SS,'PAAM',dt,tau=tau,mode=mode)
            ang_r = self.step_response(ang_r_SS,'PAAM',dt,tau=tau,mode=mode)
            f_noise_l = lambda i,t: (ang_l(i,t)-ang_l_SS(i,t))**2
            f_noise_r = lambda i,t: (ang_r(i,t)-ang_r_SS(i,t))**2
            self.PAAM_ang_l_SS = ang_l_SS
            self.PAAM_ang_r_SS = ang_r_SS
            self.PAAM_step = dt

        # Adding jitter
        if jitter!=False:
            self.beam_l_ang = lambda i,t: self.add_jitter(ang_l,i,t,1e-8,1e20,dt=3600)
            self.beam_r_ang = lambda i,t: self.add_jitter(ang_r,i,t,1e-8,1e20,dt=3600)
        else:
            self.beam_l_ang = ang_l
            self.beam_r_ang = ang_r

        #self.PAAM_l_ang = lambda i,t: self.beam_l_ang(i,t)*wfe.MAGNIFICATION
        #self.PAAM_r_ang = lambda i,t: self.beam_r_ang(i,t)*wfe.MAGNIFICATION

        # Calculating new pointing vectors and coordinate system
        self.beam_l_coor = lambda i,t: pack.functions.beam_coor_out(self.wfe,i,t,self.tele_l_ang(i,t),self.beam_l_ang(i,t))
        self.beam_r_coor = lambda i,t: pack.functions.beam_coor_out(self.wfe,i,t,self.tele_r_ang(i,t),self.beam_r_ang(i,t))

        # Calculating the Transmitted beam direction and position of the telescope aperture
        self.beam_l_direction = lambda i,t: self.beam_l_coor(i,t)[0]
        self.beam_r_direction = lambda i,t: self.beam_r_coor(i,t)[0]
        self.beam_l_start = lambda i,t: self.beam_l_direction(i,t)+np.array(self.wfe.data.LISA.putp(i,t))
        self.beam_r_start = lambda i,t: self.beam_r_direction(i,t)+np.array(self.wfe.data.LISA.putp(i,t))

        #self.beam_l_vec = lambda i,t: self.beam_l_coor(i,t)[0]*self.wfe.L_tele
        #self.beam_l_vec = lambda i,t: self.beam_l_coor(i,t)[0]*self.wfe.data.L_sl_func_tot(i,t)*c
        #self.beam_l_vec = lambda i,t: self.beam_l_coor(i,t)[0]*np.linalg.norm(self.wfe.data.v_l_func_tot(i,t))
        #self.beam_r_vec = lambda i,t: self.beam_r_coor(i,t)[0]*self.wfe.data.L_sr_func_tot(i,t)*c
        #self.beam_r_vec = lambda i,t: self.beam_l_coor(i,t)[0]*np.linalg.norm(self.wfe.data.v_r_func_tot(i,t))

        return 0

    def get_received_beam_duration(self,i,t,side,ksi=[0,0]):
        [i_self,i_left,i_right] = PAA_LISA.utils.i_slr(i)

        # Calculate new tdel
        #... code has to be adjusted for telescope length
        if side=='l':
            L_r = self.wfe.data.L_rl_func_tot(i_self,t)
            L_s = self.wfe.data.L_sl_func_tot(i_self,t)
        elif side=='r':
            L_r = self.wfe.data.L_rr_func_tot(i_self,t)
            L_s = self.wfe.data.L_sr_func_tot(i_self,t)

        # Received beams (Waluschka)
        if side=='l':
            coor_start = self.beam_r_coor(i_left,t-L_r)
            start =  self.beam_r_start(i_left,t-L_r)
            direction_in = self.beam_r_direction(i_left,t-L_r)
            if self.wfe.data.calc_method=='Abram':
                end = self.beam_l_start(i_self,t)
                #coor_end = self.beam_l_coor(i_self,t)
                coor_end = self.tele_l_coor(i_self,t)
                direction_out = self.beam_l_direction(i_self,t)
            else:
                end = self.beam_l_start(i_self,t-L_r)
                #coor_end = self.beam_l_coor(i_self,t-L_r)
                coor_end = self.tele_l_coor(i_self,t)
                direction_out = self.beam_l_direction(i_self,t+L_s)

        elif side=='r':
            coor_start = self.beam_l_coor(i_right,t-L_r)
            start =  self.beam_l_start(i_right,t-L_r)
            direction_in = self.beam_l_direction(i_right,t-L_r)
            if self.wfe.data.calc_method=='Abram':
                end = self.beam_r_start(i_self,t)
                #coor_end = self.beam_r_coor(i_self,t)
                coor_end = self.tele_r_coor(i_self,t)
                direction_out = self.beam_r_direction(i_self,t)
            else:
                end = self.beam_r_start(i_self,t-L_r)
                #coor_end = self.beam_r_coor(i_self,t)
                coor_end = self.tele_r_coor(i_self,t)
                direction_out = self.beam_r_direction(i_self,t+L_s)
        # ksi is in receiiving telescope frame so adapt ksi in beam send frame
        [ksix,ksiy]=ksi

        ksix_vec = coor_end[2]*ksiy
        ksiy_vec = coor_end[1]*ksiy
        end = end+ksix_vec+ksiy_vec
        target_pos = LA.matmul(coor_start,end-start)
        #target_direction = LA.matmul(coor_start,direction)

        ret={}
        ret['start'] = start
        ret['end'] = end
        ret['beam_out'] = direction_out
        ret['beam_in'] = direction_in
        ret['target_pos'] = target_pos
        #ret['target_direction'] = target_direction
        ret['coor_start'] = coor_start
        ret['coor_end'] = coor_end
        ret['L_s'] = L_s
        ret['L_r'] = L_r

        return ret

    def step_response_calc(self,function,i,t,dt,tau,mode='overdamped'):
        if mode=='overdamped':
            #if self.PAAM_method=='SS':
            t0 = t-(t%dt)
            t1 = t0+dt
            Y0 = function(i,t0)
            Y1 = function(i,t1)
            #elif self.PAAM_method=='SS_lim':
            #    [t_PAAM,PAAM] = function(i)
            #    k = NOISE_LISA.get_nearest_smaller_value(t_PAAM,t)
            #    t0 = t_PAAM[k]
            #    t1 = t_PAAM[k+1]
            #    Y0 = PAAM[k]
            #    Y1 = PAAM[k+1]
            if t<self.wfe.t_all[2] or t>self.wfe.t_all[-2]:
                return np.nan
            else:
                if t0==0:
                    Y0=Y1
                return Y1+(Y0-Y1)*np.exp(-(t-t0)/tau)
        elif mode==False:
            return function(i,t)

    def step_response(self,function,select,dt,tau=3600,mode='overdamped'):
        if select=='PAAM' and self.PAAM_method=='SS_lim':
            f = []
            for i in range(1,4):
                [t_PAAM,PAAM,func] = function(i)
                if mode=='overdamped':
                    ret=[]
                    for j in range(1,len(t_PAAM)):
                        t0 = t_PAAM[j-1]
                        t1 = t_PAAM[j]
                        Y0 = PAAM[j-1]
                        Y1 = PAAM[j]

                        ret.append(lambda t: Y1+(Y0-Y1)*np.exp(-(t-t0)/tau))

                    pos = lambda t: pack.functions.get_nearest_smaller_value(t_PAAM,t)
                    f.append(lambda t: ret[pos(t)])
                else:
                    func_ret = lambda t: pack.functions.make_nan(func,t,[t_PAAM[0],t_PAAM[-1]])
                    f.append(func_ret)

            return PAA_LISA.utils.func_over_sc(f)
        else:
            return lambda i,t: self.step_response_calc(function,i,t,dt,tau=tau,mode=mode)


import time

from app.DR_Classic.core.process import LootEvent
from app.DR_Classic.core.sector import (
    DialogueMixin,
    MultipleEntityProcess,
    SingleEntityProcess,
)
from app.DR_Classic.entities.apparel import HeavyThree, LightThree
from app.DR_Classic.entities.enemies import Boss, Minotaur, Rat, StoneGargoyle
from dungeonrun.sector import BaseSector, Dialogue, Route
from dungeonrun.utils import import_from_app

class Intro(DialogueMixin, BaseSector):
    route = Route("rooms.RoomOne")

    dialogue = [
        Dialogue("You wake up in a dark room.\n"),
        Dialogue("You see an unfamiliar roof.\n"),
        Dialogue("You try to get a grasp of your surrounding.\n"),
        Dialogue("Only to be startled by a rat hissing at you.\n", before=2),
    ]

    def execute(self) -> "BaseSector":
        self.APP.PROCESS_CLASS(self.APP.MAIN_ENTITY, Rat()).execute()

        return super().execute()

class RoomOne(DialogueMixin, SingleEntityProcess, BaseSector):
    route = [
        Route("rooms.RoomTwo", "go_east"),
        Route("rooms.RoomSix", "go_south"),
    ]

    dialogue = [
        Dialogue("You are standing in a brightly lit room.\n"),
        Dialogue(
            "With unidentifiable floating light source hanging from the ceiling.\n"
        ),
        Dialogue("You see a compass carved in the middle of the floor\n"),
    ]

    entities = [
        "enemies.Rat",
        "enemies.BlueSlime",
    ]

class RoomTwo(DialogueMixin, SingleEntityProcess, BaseSector):
    route = [
        Route("rooms.RoomFive", "go_south"),
        Route("rooms.RoomOne", "go_west"),
    ]

    dialogue = [
        Dialogue("You entered a hallway.\n"),
        Dialogue("With dimly lit torches illuminating the surrounding.\n"),
    ]

    entities = [
        "enemies.Rat",
        "enemies.Spider",
    ]

class RoomThree(DialogueMixin, SingleEntityProcess, BaseSector):
    route = [
        Route("rooms.RoomNine", "go_south"),
        Route("rooms.RoomFive", "go_west"),
    ]

    dialogue = [
        Dialogue("The room is massive.\n"),
        Dialogue("A rusty chandelier is hanging from the ceiling.\n"),
    ]

    entities = [
        "enemies.Goblin",
        "enemies.Spider",
    ]

class RoomFour(DialogueMixin, SingleEntityProcess, BaseSector):
    route = [
        Route("rooms.RoomFive", "go_east"),
        Route("rooms.RoomSeven", "go_south"),
        Route("rooms.RoomSix", "go_west"),
    ]

    dialogue = [
        Dialogue("The air feels thick and heavy.\n"),
        Dialogue("Cracks can be seen across the wall.\n"),
    ]

    entities = [
        "enemies.Goblin",
        "enemies.Spider",
        "enemies.Rat",
    ]

class RoomFive(DialogueMixin, SingleEntityProcess, BaseSector):
    route = [
        Route("rooms.RoomTwo", "go_north"),
        Route("rooms.RoomThree", "go_east"),
        Route("rooms.RoomFour", "go_west"),
    ]

    dialogue = [
        Dialogue("Various markings can be seen on the wall.\n"),
        Dialogue("You have no idea what they are.\n"),
    ]

    entities = [
        "enemies.Rat",
        "enemies.Goblin",
    ]

class RoomSix(DialogueMixin, SingleEntityProcess, BaseSector):
    route = [
        Route("rooms.RoomOne", "go_north"),
        Route("rooms.RoomFour", "go_northeast"),
        Route("rooms.RoomSeven", "go_southeast"),
        Route("rooms.RoomTen", "go_south"),
    ]

    dialogue = [
        Dialogue("There are 4 passage available.\n"),
        Dialogue("Each marked with unknown symbol.\n"),
    ]

    entities = [
        "enemies.Goblin",
        "enemies.Rat",
        "enemies.Spider",
    ]

class RoomSeven(DialogueMixin, SingleEntityProcess, BaseSector):
    route = [
        Route("rooms.RoomFour", "go_north"),
        Route("rooms.RoomEight", "go_east"),
        Route("rooms.RoomTwelve", "go_south"),
        Route("rooms.RoomEleven", "go_southwest"),
        Route("rooms.RoomSix", "go_northwest"),
    ]

    dialogue = [
        Dialogue("You felt the wind coming from the ceiling.\n"),
        Dialogue(
            "Slimy substances can be seen along the walls and floors.\n"
        ),
    ]

    entities = [
        "enemies.RedSlime",
        "enemies.GreenSlime",
    ]

class RoomEight(DialogueMixin, SingleEntityProcess, BaseSector):
    route = [
        Route("rooms.RoomNine", "go_east"),
        Route("rooms.RoomTwelve", "go_south"),
        Route("rooms.RoomSeven", "go_west"),
    ]

    dialogue = [
        Dialogue("The wind from the nearby room picks up the dust\n"),
    ]

    entities = [
        "enemies.Skeleton",
        "enemies.GreenSlime",
    ]

class RoomNine(DialogueMixin, MultipleEntityProcess, BaseSector):
    route = [
        Route("rooms.RoomThree", "go_north"),
        Route(
            "rooms.RoomThirteen", "go_south", "Go South (MINIBOSS: Minotaur)"
        ),
        Route("rooms.RoomEight", "go_west"),
    ]

    dialogue = [
        Dialogue("Massive pillar can be seen supporting the ceiling.\n"),
        Dialogue("Piles of bones are scattered across the ground.\n"),
    ]

    entities = [
        "enemies.Skeleton",
        "enemies.Skeleton",
        "enemies.Skeleton",
    ]

class RoomTen(DialogueMixin, MultipleEntityProcess, BaseSector):
    route = [
        Route("rooms.RoomSix", "go_north"),
        Route("rooms.RoomFourteen", "go_south"),
    ]

    dialogue = [
        Dialogue("You entered a small halway\n"),
        Dialogue("There are cobwebs in the corners.\n"),
    ]

    entities = [
        "enemies.Spider",
        "enemies.Skeleton",
    ]

class RoomEleven(DialogueMixin, SingleEntityProcess, BaseSector):
    route = [
        Route("rooms.RoomSeven", "go_east"),
        Route("rooms.RoomFourteen", "go_south"),
    ]

    dialogue = [
        Dialogue("The room looks like an armory.\n"),
        Dialogue("Unfortunately all the equipments are broken.\n"),
    ]

    entities = [
        "enemies.Goblin",
        "enemies.Skeleton",
    ]

class RoomTwelve(DialogueMixin, MultipleEntityProcess, BaseSector):
    route = [
        Route("rooms.RoomSeven", "go_northwest"),
        Route("rooms.RoomEight", "go_northeast"),
        Route("rooms.RoomSeventeen", "go_south"),
        Route("rooms.RoomFourteen", "go_west"),
    ]

    dialogue = [
        Dialogue("Decaying corpses are piled in the middle of the room.\n"),
        Dialogue("The stench is unbearable.\n"),
    ]

    entities = [
        "enemies.Zombie",
        "enemies.Zombie",
        "enemies.Skeleton",
    ]

class RoomThirteen(DialogueMixin, SingleEntityProcess, BaseSector):
    route = [
        Route("rooms.RoomNine", "go_back"),
    ]

    dialogue = [
        Dialogue("A giant minotaur is sitting on a throne.\n"),
        Dialogue("It noticed your presence.\n"),
    ]

    def execute(self) -> "BaseSector":
        result = self.APP.PROCESS_CLASS(
            self.APP.MAIN_ENTITY, Minotaur()
        ).execute()

        if not result:
            return import_from_app(
                self.APP._APP_NAME, "sector.rooms.RoomNine"
            )
        else:
            self.APP.minotaur = 1
            print(f"{Minotaur.name.get()} dropped a {HeavyThree.name.get()}")
            LootEvent(self.APP.MAIN_ENTITY).handle_drop(HeavyThree)

        return super().execute()

class RoomFourteen(DialogueMixin, SingleEntityProcess, BaseSector):
    route = [
        Route("rooms.RoomTen", "go_northwest"),
        Route("rooms.RoomEleven", "go_northeast"),
        Route("rooms.RoomTwelve", "go_east"),
    ]

    dialogue = [
        Dialogue("The room is filled with overgrown vines.\n"),
    ]

    entities = [
        "enemies.GreenSlime",
        "enemies.Skeleton",
        "enemies.Spider",
    ]

class RoomFifteen(DialogueMixin, BaseSector):
    route = [
        Route("rooms.RoomSixteen", "go_back"),
    ]

    dialogue = [
        Dialogue("A room full of treasure greets your eyes.\n"),
        Dialogue("Winged statue encircles the room.\n"),
        Dialogue("One of them started moving.\n"),
    ]

    def execute(self) -> "BaseSector":
        result = self.APP.PROCESS_CLASS(
            self.APP.MAIN_ENTITY, StoneGargoyle()
        ).execute()

        if not result:
            return import_from_app(
                self.APP._APP_NAME, "sector.rooms.RoomSixteen"
            )
        else:
            self.APP.stone_gargoyle = 1
            print(
                f"{StoneGargoyle.name.get()} dropped a {LightThree.name.get()}"
            )
            LootEvent(self.APP.MAIN_ENTITY).handle_drop(LightThree)

        return super().execute()

class RoomSixteen(DialogueMixin, SingleEntityProcess, BaseSector):
    route = [
        Route("rooms.RoomSeventeen", "go_east"),
        Route("rooms.RoomEighteen", "go_south"),
        Route(
            "rooms.RoomFifteen",
            "go_west",
            "Go West (MINIBOSS: Stone Gargoyle)",
        ),
    ]

    dialogue = [
        Dialogue("Pieces of broken vases are scattered on the floor.\n"),
    ]

    entities = [
        "enemies.Zombie",
        "enemies.GreenSlime",
    ]

class RoomSeventeen(DialogueMixin, SingleEntityProcess, BaseSector):
    route = [
        Route("rooms.RoomTwelve", "go_north"),
        Route("rooms.RoomNineteen", "go_south"),
        Route("rooms.RoomSixteen", "go_west"),
    ]

    dialogue = [
        Dialogue("You entered a long hallway.\n"),
        Dialogue("Broken armor can be seen on their stand.\n"),
    ]

    entities = [
        "enemies.Zombie",
        "enemies.FallenPaladin",
    ]

class RoomEighteen(DialogueMixin, SingleEntityProcess, BaseSector):
    route = [
        Route("rooms.RoomSixteen", "go_north"),
        Route("rooms.RoomNineteen", "go_east"),
    ]

    dialogue = [
        Dialogue("Knight statues are standing in a circle.\n"),
        Dialogue("Unknown diagrams painted on the floor.\n"),
    ]

    entities = [
        "enemies.Zombie",
        "enemies.HollowKnight",
    ]

class RoomNineteen(DialogueMixin, SingleEntityProcess, BaseSector):
    route = [
        Route("rooms.RoomSeventeen", "go_north"),
        Route("rooms.RoomTwenty", "go_east", "Go East (FINAL BOSS)"),
        Route("rooms.RoomEighteen", "go_west"),
    ]

    dialogue = [
        Dialogue("A small statue display can be seen in the corner.\n"),
    ]

    entities = [
        "enemies.Zombie",
        "enemies.RedSlime",
    ]

class RoomTwenty(DialogueMixin, BaseSector):
    route = [
        Route("endings.One", "escape"),
        Route("endings.Two", "stay"),
    ]

    @property
    def dialogue(self):
        dialogue = [
            Dialogue("You come accross an eerie looking door.\n"),
            Dialogue("With two round orb implanted to each of its side.\n"),
        ]

        if not self.APP.minotaur and not self.APP.stone_gargoyle:
            dialogue.append(Dialogue("Both of them are blacked out.\n"))
        elif self.APP.minotaur and self.APP.stone_gargoyle:
            dialogue.append(Dialogue(f"Both of them are lit up\n"))
        else:
            dialogue.append(Dialogue("One of them is lit up.\n"))

        if not self.APP.minotaur or not self.APP.stone_gargoyle:
            dialogue.append(
                Dialogue("The door won't budge no mater how hard you try.\n")
            )
        else:
            dialogue.append(Dialogue("The door opened in your presence.\n"))
            dialogue.append(
                Dialogue(
                    "You are greeted with a shadowy figure guarding a door.\n",
                    1,
                )
            )
            dialogue.append(
                Dialogue(
                    "You feel a glimpse of hope coming from that door.\n", 1
                )
            )

        return dialogue

    def execute(self) -> "BaseSector":
        if self.APP.minotaur and self.APP.stone_gargoyle:
            result = self.APP.PROCESS_CLASS(
                self.APP.MAIN_ENTITY, Boss()
            ).execute()

            if not result:
                return import_from_app(
                    self.APP._APP_NAME, "sector.rooms.RoomNineteen"
                )
            else:
                self.APP.boss = 1
        else:
            time.sleep(2)
            return import_from_app(
                self.APP._APP_NAME, "sector.rooms.RoomNineteen"
            )

        return super().execute()


# Credits go to Sebastian Sjöberg
# # file for implementing bubblesort
# task 3 lab 2
from task1 import is_sorted

def bytintill(lista):
    switch = False
    for i in range(0, len(lista) - 1):
        if lista[i] > lista[i + 1]:
            lista[i], lista[i + 1] = lista[i + 1], lista[i]
            switch = True
    return switch

def bubblesort(arr):
    switch = True
    while switch:
        switch = bytintill(arr)

def test():
    arrays = [[1, 2, 3, 4, 5],
              [6, 7, 2, 4, 1, 8],
              [], [5, 0, 0, 0], [0]]
    for arr in arrays:
        bubblesort(arr)
        print(is_sorted(arr))

if __name__ == "__main__":
    test()


"""
Code example for publishing data to the Brewblox eventbus

Dependencies:
- pika
"""

import json
from random import random
from time import sleep

import pika

# 172.17.0.1 is the default IP address for the host running the Docker container
# Change this value if Brewblox is installed on a different computer
HOST = '172.17.0.1'

# This is a constant value. You never need to change it.
EXCHANGE = 'brewcast.history'

# This will be the top-level key in graphs / metrics
SERVICE = 'pubscript'

# Connect to the eventbus
connection = pika.BlockingConnection(pika.ConnectionParameters(host=HOST))
channel = connection.channel()

try:
    value = 20

    while True:
        # Replace this with actual data
        # See: https://brewblox.netlify.app/dev/reference/event_logging.html#history
        value += ((random() - 0.5) * 10)
        message = {'value[degC]': value}
        text = json.dumps(message)

        channel.basic_publish(exchange=EXCHANGE,
                              routing_key=SERVICE,
                              body=text)

        print(f'sent {message}')
        sleep(5)
finally:
    connection.close()


import unittest

from modelscope.pipelines import pipeline
from modelscope.utils.constant import Tasks
from modelscope.utils.test_utils import test_level

class Image2ImageTranslationTest(unittest.TestCase):

    @unittest.skipUnless(test_level() >= 2, 'skip test in current test level')
    def test_run_modelhub(self):
        r"""We provide three translation modes, i.e., uncropping, colorization and combination.
            You can pass the following parameters for different mode.
            1. Uncropping Mode:
            result = img2img_gen_pipeline(('data/test/images/img2img_input.jpg', 'left', 0, 'result.jpg'))
            2. Colorization Mode:
            result = img2img_gen_pipeline(('data/test/images/img2img_input.jpg', 1, 'result.jpg'))
            3. Combination Mode:
            just like the following code.
        """
        img2img_gen_pipeline = pipeline(
            Tasks.image_to_image_translation,
            model='damo/cv_latent_diffusion_image2image_translation')
        result = img2img_gen_pipeline(
            ('data/test/images/img2img_input_mask.png',
             'data/test/images/img2img_input_masked_img.png', 2,
             'result.jpg'))  # combination mode

        print(f'output: {result}.')

if __name__ == '__main__':
    unittest.main()


from re import X
import numpy as np
import pandas as pd
from pandas.core.arrays import categorical
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense

datasets = pd.read_csv('../data/winequality-white.csv', sep=';',
                        index_col=None, header=0)
#데이터가 ; 으로 분리 되어 있어서 sep 세퍼레이트 를 해준다..
# 데이터가 a열에 있었으므로 인덱스 컬럼은 없고 맨위의 행이 head기 때문에 0을 줌

# winequality-white
# ./ : 현재 폴더
# ../ : 상위폴더

# print(datasets)
print(datasets.shape) #(4898, 12)
print(datasets.info())
print(datasets.describe())

#1. 데이터 처리
datasets=np.array(datasets.values)
# print(datasets.shape)

x= datasets[:,:-1]
y= datasets[:,-1:]
print(x.shape, y.shape)

print(np.unique(y))

from sklearn.preprocessing import OneHotEncoder
en = OneHotEncoder()
y = en.fit_transform(y).toarray()

# from tensorflow.keras.utils import to_categorical
# y = to_categorical(y)

print(y.shape)
print(y[:5])

from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test =train_test_split(
    x,y, test_size=0.1, random_state=66)

from sklearn.preprocessing import StandardScaler,MinMaxScaler,QuantileTransformer, RobustScaler
# scaler =MinMaxScaler()
# scaler = StandardScaler()
# scaler =QuantileTransformer()
scaler = RobustScaler()
# scaler = QuantileTransformer()
scaler.fit(x_train)
x_train = scaler.transform(x_train)
x_test = scaler.transform(x_test)

#2. 모델 구성
model = Sequential()
model.add(Dense(240, input_shape=(11,)))
model.add(Dense(120, activation='relu'))
model.add(Dense(120, activation='relu'))
model.add(Dense(64, activation='relu'))
model.add(Dense(64, activation='relu'))
model.add(Dense(32, activation='relu'))
model.add(Dense(7, activation='softmax'))

#3. 컴파일 및 훈련
from tensorflow.keras.callbacks import EarlyStopping
# es = EarlyStopping(monitor='val_loss', patience= 100, mode= 'min', verbose=1)
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
model.fit(x_train,y_train, epochs=300,
 batch_size=50, validation_split=0.2,verbose=3)

#4. 예측 평가
loss = model.evaluate(x_test, y_test)
print('loss', loss[0])
print('accuracy', loss[1])

# # dataset 라벨 , 셋 자체에 대한 처리로 정확도 올릴 수 있음

# #다중분류
# #모델링하고
# #0.8 이상 완성!!
# #sklearn의 onehot 사용할것
# #4. y의 라벨을 확인할 것 np.unique(y)
# #5. y의 shape 확인 (4898,) -> (4898,7)


from email.utils import parsedate_to_datetime

from tweepy.mixins import HashableID

class Model:

    def __init__(self, api=None):
        self._api = api

    def __getstate__(self):
        pickle = self.__dict__.copy()
        pickle.pop('_api', None)
        return pickle

    @classmethod
    def parse(cls, api, json):
        """Parse a JSON object into a model instance."""
        raise NotImplementedError

    @classmethod
    def parse_list(cls, api, json_list):
        """
            Parse a list of JSON objects into
            a result set of model instances.
        """
        results = ResultSet()

        if isinstance(json_list, dict):
            # Handle map parameter for statuses/lookup
            if 'id' in json_list:
                for _id, obj in json_list['id'].items():
                    if obj:
                        results.append(cls.parse(api, obj))
                    else:
                        results.append(cls.parse(api, {'id': int(_id)}))
                return results
            # Handle premium search
            if 'results' in json_list:
                json_list = json_list['results']

        for obj in json_list:
            if obj:
                results.append(cls.parse(api, obj))
        return results

    def __repr__(self):
        state = [f'{k}={v!r}' for (k, v) in vars(self).items()]
        return f'{self.__class__.__name__}({", ".join(state)})'

class ResultSet(list):
    """A list like object that holds results from a Twitter API query."""

    def __init__(self, max_id=None, since_id=None):
        super().__init__()
        self._max_id = max_id
        self._since_id = since_id

    @property
    def max_id(self):
        if self._max_id:
            return self._max_id
        ids = self.ids()
        # Max_id is always set to the *smallest* id, minus one, in the set
        return (min(ids) - 1) if ids else None

    @property
    def since_id(self):
        if self._since_id:
            return self._since_id
        ids = self.ids()
        # Since_id is always set to the *greatest* id in the set
        return max(ids) if ids else None

    def ids(self):
        return [item.id for item in self if hasattr(item, 'id')]

class Media(Model):

    @classmethod
    def parse(cls, api, json):
        media = cls(api)
        for k, v in json.items():
            setattr(media, k, v)
        return media

class IDModel(Model):

    @classmethod
    def parse(cls, api, json):
        if isinstance(json, list):
            return json
        else:
            return json['ids']

class JSONModel(Model):

    @classmethod
    def parse(cls, api, json):
        return json

class WelcomeMessage(Model):

    @classmethod
    def parse(cls, api, json):
        if "welcome_message" in json.keys():
            json = json["welcome_message"]
        dm = cls(api)
        setattr(dm, '_json', json)
        for k, v in json.items():
            setattr(dm, k, v)
        return dm

    @classmethod
    def parse_list(cls, api, json_list):
        if isinstance(json_list["welcome_messages"], list):
            item_list = json_list["welcome_messages"]
        else:
            item_list = [json_list["welcome_message"]]

        results = ResultSet()
        for obj in item_list:
            results.append(cls.parse(api, obj))
        return results

class Rule(Model):

    @classmethod
    def parse(cls, api, json):

        if "welcome_message_rule" in json.keys():
            json = json["welcome_message_rule"]
        dm = cls(api)
        setattr(dm, '_json', json)
        for k, v in json.items():
            setattr(dm, k, v)
        return dm

    @classmethod
    def parse_list(cls, api, json_list):
        if not json_list:
            return json_list
        if isinstance(json_list["welcome_message_rules"], list):
            item_list = json_list["welcome_message_rules"]
        else:
            item_list = json_list

        results = ResultSet()
        for obj in item_list:
            results.append(cls.parse(api, obj))
        return results

class CustomModelFactory:
    """
    Used by parsers for creating instances
    of models. You may subclass this factory
    to add your own extended models.
    """
    welcome_message = WelcomeMessage
    rule = Rule


import matplotlib.pyplot as plt
import numpy as np

from brancher.variables import ProbabilisticModel
from brancher.stochastic_processes import MarkovProcess
from brancher.standard_variables import NormalVariable as Normal
from brancher.standard_variables import DeterministicVariable as Deterministic
from brancher.standard_variables import BetaVariable as Beta
from brancher.standard_variables import MultivariateNormalVariable as MultivariateNormal
import brancher.functions as BF

import pickle
from scipy.stats import zscore

path = "/home/luca/CurrencyData/exchange_file.pickle"

with open(path, 'rb') as file:
    exchange_df = pickle.load(file)

data = exchange_df.values[:, 1:].astype("float32")
indices = [True if t % 20 == 0 else False for t in range(data.shape[0])]
data = data[indices,:]
data = zscore(data)
plt.plot(data)
plt.show()

## Create time series model ##
T = sum(indices)
d = 3
nu = d + 1
a = Beta(15, 1, "a")
Id = Deterministic(0.1*np.identity(d), "Id")
U0 = Normal(np.zeros((d, 1, nu)), np.ones((d, 1, nu)), "U_0")
U = MarkovProcess(U0, lambda t, u: Normal(a*u, 0.1, "U_{}".format(t)))
Yt = [MultivariateNormal(np.zeros((d,)),
                         covariance_matrix=sum([BF.matmul(ut[:, :, k], BF.transpose(ut[:, :, k], 2, 1))
                                                for k in range(nu)]) + Id,
                         name="y_{}".format(t))
      for t, ut in enumerate(U(T).temporal_variables)]
model = ProbabilisticModel(Yt)

## Observe
[yt.observe(dt) for yt, dt in zip(Yt, data)]

#sample = model.get_sample(2) #TODO: bug

## Variational model
Qa = Beta(15, 1, "a", learnable=True)
QU = [Normal(np.zeros((d, 1, nu)), np.ones((d, 1, nu)), "U_0", learnable=True)]
Qlambda = []
Qalpha = []
cov = []
for t in range(T):
    Qlambda.append(Deterministic(0.1*np.ones((d, 1, nu)), "lambda_{}".format(t), learnable=True))
    Qalpha.append(Deterministic(0.05*np.ones((d, 1, nu)), "alpha_{}".format(t), learnable=True))
    if t > 0:
        QU.append(Normal(BF.sigmoid(Qlambda[-1])*Qa*QU[-1] + (1-BF.sigmoid(Qlambda[-1]))*Qalpha[-1],
                         0.1, "U_{}".format(t), learnable=True))
    cov.append(Deterministic(sum([BF.matmul(QU[-1][:, :, k], BF.transpose(QU[-1][:, :, k], 2, 1)) for k in range(nu)]) + Id,
                             name="cov_{}".format(t)))
model.set_posterior_model(ProbabilisticModel(QU + [Qa] + cov))
model.posterior_model.get_sample(1)

# Inference #
from brancher.inference import perform_inference
N_itr = 50
N_smpl = 1
optimizer = "SGD"
lr = 0.01
perform_inference(model,
                  number_iterations=N_itr,
                  number_samples=N_smpl,
                  optimizer=optimizer,
                  lr=lr)
loss = model.diagnostics["loss curve"]
plt.plot(loss)
plt.show()
## Inference ##

## Variationa model ##

sample = model.posterior_model.get_sample(1)

Y1_mean = 0.
Y2_mean = 0.
Y3_mean = 0.
X1_mean = 0.
N = 50
for n in range(N):
    Y1 = []
    Y2 = []
    Y3 = []
    X1 = []
    sample = model.posterior_model.get_sample(1)
    for t in range(T):
        s0 = sample["cov_{}".format(t)][0][0,0,0]
        s1 = sample["cov_{}".format(t)][0][0,1,1]
        s2 = sample["cov_{}".format(t)][0][0,2,2]
        X1.append(s1)
        Y1.append(sample["cov_{}".format(t)][0][0,1,2]/np.sqrt(s1*s2))
        Y2.append(sample["cov_{}".format(t)][0][0,0,1]/np.sqrt(s0*s1))
        Y3.append(sample["cov_{}".format(t)][0][0,0,2]/np.sqrt(s0*s2))
    Y1_mean += np.array(Y1)/float(N)
    Y2_mean += np.array(Y2)/float(N)
    Y3_mean += np.array(Y3)/float(N)
    X1_mean += np.array(X1)/float(N)
plt.plot(range(T), Y1_mean)
plt.plot(range(T), Y2_mean)
plt.plot(range(T), Y3_mean)
plt.show()

plt.plot(range(T), X1_mean)
plt.show()


# python3

def left_child_idx(i):
    return 2*i+1

def right_child_idx(i):
    return 2*i+2

def parent_idx(i):
    return i//2

def sift_down(heap, i, swaps):
    min_index = i
    size = len(heap)
    l_child = left_child_idx(i)
    if l_child < size and heap[l_child] < heap[min_index]:
        min_index = l_child
    r_child = right_child_idx(i)
    if r_child < size and heap[r_child] < heap[min_index]:
        min_index = r_child
    if min_index != i:
        swaps.append((i, min_index))
        heap[i], heap[min_index] = heap[min_index], heap[i]
        sift_down(heap, min_index, swaps)

def build_heap(data):
    swaps = []
    for i in range(len(data)//2, -1, -1):
        sift_down(data, i, swaps)
    return swaps

def main():
    n = int(input())
    data = list(map(int, input().split()))
    assert len(data) == n

    swaps = build_heap(data)

    print(len(swaps))
    for i, j in swaps:
        print(i, j)

if __name__ == "__main__":
    main()


# coding=utf8
"""sopel-norris

Chuck Norris joke plugin for Sopel IRC bots.
"""
from __future__ import unicode_literals, absolute_import, division, print_function

import random

import requests

from sopel import formatting, module
from sopel.tools import SopelMemory, get_logger, web

LOGGER = get_logger('norris')

class APIError(Exception):
    """Just a custom exception type to throw from API helpers."""
    pass

class InvalidQueryError(Exception):
    """The API likes to throw 400 Bad Request instead of returning JSON with an error message."""
    pass

class NoResultError(Exception):
    """Tin."""
    pass

def setup(bot):
    bot.memory['norris_cache'] = SopelMemory()

def shutdown(bot):
    try:
        del bot.memory['norris_cache']
    except KeyError:
        pass

@module.commands('norris', 'chucknorris')
@module.output_prefix('[CNJ] ')
def chuck_norris(bot, trigger):
    """Fetch a random Chuck Norris joke, with optional keyword search."""
    arg = trigger.group(2)
    if arg is not None and arg.strip():
        try:
            joke = fetch_results(bot, arg)
        except APIError:
            bot.reply(
                "Something went wrong. Try again later! "
                "(If this keeps happening, ask %s to check my error logs.)"
                % bot.config.core.owner
            )
            return
        except InvalidQueryError:
            bot.reply(
                "The query couldn't be processed. Make sure it's just a keyword "
                "or three, no punctuation."
            )
            return
        except NoResultError:
            bot.reply("No matching jokes.")
            return
    else:
        try:
            joke = fetch_random()
        except APIError:
            bot.reply(
                "Something went wrong. Try again later! "
                "(If this keeps happening, ask %s to check my error logs.)"
                % bot.config.core.owner)
            return

    bot.say(joke)

API_BASE = 'https://api.chucknorris.io/'
JOKES = API_BASE + 'jokes'
RANDOM = JOKES + '/random'
SEARCH = JOKES + '/search?query=%s'

def fetch_random():
    try:
        r = requests.get(RANDOM)
        data = r.json()
        joke = data['value']
    except Exception as err:
        # I'm tired of writing half a dozen cases all the time. Just log it.
        LOGGER.error("Couldn't fetch random Chuck Norris joke: %s", err)
        raise APIError

    return joke

def fetch_results(bot, query):
    query = formatting.plain(query.strip())
    cache = bot.memory['norris_cache'].get(query, [])

    if cache:
        return cache.pop()

    try:
        r = requests.get(SEARCH % web.quote(query))
        data = r.json()
    except Exception as err:
        # No case-by-case handling here. Just log it and give up.
        LOGGER.error("Couldn't search Chuck Norris jokes: %s", err)
        raise APIError

    if r.status_code == 400:
        raise InvalidQueryError

    jokes = [item['value'] for item in data['result']]
    random.shuffle(jokes)

    if not jokes:
        raise NoResultError

    # the list of matching jokes might be quite large; take one
    # and store the rest for later calls on the same query
    # since the chucknorris.io API doesn't support pages/limits
    bot.memory['norris_cache'][query] = jokes[1:]
    return jokes[0]


from dataclasses import dataclass, field
from typing import List, Optional, Union
from bindings.csw.null_enumeration_value import NullEnumerationValue

__NAMESPACE__ = "http://www.opengis.net/gml"

@dataclass
class MeasureOrNullListType:
    """List of numbers with a uniform scale.

    A member of the list may be a typed null. The value of uom (Units Of
    Measure) attribute is a reference to a Reference System for the
    amount, either a ratio or position scale.
    """

    value: List[Union[str, NullEnumerationValue]] = field(
        default_factory=list,
        metadata={
            "pattern": r"other:\w{2,}",
            "tokens": True,
        },
    )
    uom: Optional[str] = field(
        default=None,
        metadata={
            "type": "Attribute",
            "required": True,
        },
    )


#!/usr/bin/env python
# coding: utf-8

# In[1]:

# Simpli5ed Dynamics of Human and Mammalian Neocortical Neurons
# Surabhi S Nath
# 2016271

# In[2]:

import matplotlib.pyplot as plt
import numpy as np
from scipy.integrate import odeint
get_ipython().run_line_magic('matplotlib', 'inline')
from brian2 import *
import brian2
from IPython.display import Image
from scipy.optimize import *

# # Fig 1

# In[3]:

Image(filename="img/5.png")

# In[4]:

C = 1

g_K = 26

E_Na = 0.5
E_K = -0.95

tau = 2

# In[5]:

# Clearly R-nullcline is quadratic and not S-shaped sigmoidal
I = [0, 0.178]
fig, (ax1, ax2) = plt.subplots(2, 1, gridspec_kw={'right': 0.95, 'bottom': 0.00001}, figsize=(5, 10))

V = np.arange(-0.9, 1, 0.01)
ax1.plot(V, (0 - (17.8 + 47.6 * V + 33.8 * V * V) * (V - E_Na))/(g_K * (V - E_K)), label="V-nullcline")
ax1.plot(V, 1.24 + 3.7 * V + 3.2 * V * V, 'r--', label="R-nullcline")
ax1.set(xlim=(-1, 0.6), ylim=(0, 1), xlabel='V')
ax1.set_ylabel('R', rotation=90)
ax1.set_title("I = 0")
ax1.legend()

ax2.plot(V, (0.178 - (17.8 + 47.6 * V + 33.8 * V * V) * (V - E_Na))/(g_K * (V - E_K)), label="V-nullcline")
ax2.plot(V, 1.24 + 3.7 * V + 3.2 * V * V, 'r--', label="R-nullcline")
ax2.set(xlim=(-1, 0.6), ylim=(0, 1), xlabel='V')
ax2.set_ylabel('R', rotation=90)
ax2.set_title("I = 0.178, SN Bifurcation")
ax2.legend()

plt.show()

# # Regular Spiking and Fast Spiking Neurons

# # Fig 2b

# In[6]:

Image(filename="img/6.png")

# In[7]:

from sympy.interactive import printing
printing.init_printing(use_latex=True)
from sympy import *

# In[8]:

def dz_dt(z, t, I, tau, a, b):
    m_inf = 17.8 + 47.6 * z[0] + 33.8 * z[0] * z[0]
    R_inf = 1.24 + 3.7 * z[0] + 3.2 * z[0] * z[0]
    T_inf = 8 * (z[0] + 0.725) * (z[0] + 0.725)
    dV_dt = (I - m_inf * (z[0] - 0.5) - 26 * z[1] * (z[0] + 0.95) - a * z[2] * (z[0] - 1.2) - b * z[3] * (z[0] + 0.95)) / 1
    dR_dt = (R_inf - z[1]) / tau
    dT_dt = (T_inf - z[2]) / 14
    dH_dt = (3 * z[2] - z[3]) / 45
    return [dV_dt, dR_dt, dT_dt, dH_dt]

plt.figure(figsize=(4,5))
t = np.linspace(1, 3, 1000)
ret = odeint(dz_dt, [0.1, 0.1, 0.1, 0.1], t, args=(0, 4.2, 0.1, 5))
V = ret[:, 0]
plt.plot(t, V, color='b', label="RS")

t = np.linspace(1, 0.75, 500)
ret = odeint(dz_dt, [0.1, 0.1, 0.1, 0.1], t, args=(0, 4.2, 0.1, 5))
V = ret[:, 0]
plt.plot(t, V, color='b')

t = np.linspace(1, 3, 1000)
ret = odeint(dz_dt, [0.1, 0.1, 0.1, 0.1], t, args=(0, 1.5, 0.25, 0))
V = ret[:, 0]
plt.plot(t, V, 'r--', label="FS")

t = np.linspace(1, 0.75, 500)
ret = odeint(dz_dt, [0.1, 0.1, 0.1, 0.1], t, args=(0, 1.5,  0.25, 0))
V = ret[:, 0]
plt.plot(t, V, 'r--')

plt.xlabel("t")
plt.ylabel("V")
plt.legend()

# # Fig 2c

# In[9]:

Image(filename="img/7.png")

# In[10]:

def find_spikes(arr):
    peaks = np.where((arr[1:-1] > arr[0:-2]) * (arr[1:-1] > arr[2:]))[0] + 1
    return peaks

# In[11]:

def find_reciprocal_differences(arr):
    diffs = [x - arr[i - 1] for i, x in enumerate(arr)][1:]
    diffs = np.array(diffs, dtype=float)
    return np.reciprocal(diffs) * 1000

# In[12]:

def dz_dt(z, t, I, tau, a, b):
    m_inf = 17.8 + 47.6 * z[0] + 33.8 * z[0] * z[0]
    R_inf = 1.24 + 3.7 * z[0] + 3.2 * z[0] * z[0]
    T_inf = 8 * (z[0] + 0.725) * (z[0] + 0.725)
    dV_dt = (I - m_inf * (z[0] - 0.5) - 26 * z[1] * (z[0] + 0.95) - a * z[2] * (z[0] - 1.2) - b * z[3] * (z[0] + 0.95)) / 1
    dR_dt = (R_inf - z[1]) / tau
    dT_dt = (T_inf - z[2]) / 14
    dH_dt = (3 * z[2] - z[3]) / 45
    return [dV_dt, dR_dt, dT_dt, dH_dt]

# plt.figure(figsize=(10,5))
t = np.linspace(1, 200, 1000)
ret = odeint(dz_dt, [0.1, 0.1, 0.1, 0.1], t, args=(2.1, 4.2, 0.1, 5))
V = ret[:, 0]
spikes1 = find_spikes(V)
rec_diff1 = find_reciprocal_differences(t[spikes1])
times1 = t[spikes1]
times1 = times1[1:]
# plt.plot(t, V, 'b', label="RS")
# plt.scatter([t[spikes1]], [V[spikes1]])

t = np.linspace(1, 0.75, 500)
ret = odeint(dz_dt, [0.1, 0.1, 0.1, 0.1], t, args=(2.1, 4.2, 0.1, 5))
V = ret[:, 0]
# plt.plot(t, V, 'b')
# plt.xlabel("t")
# plt.ylabel("V")

#---------------------------

# plt.figure(figsize=(10,5))
t = np.linspace(1, 200, 1000)
ret = odeint(dz_dt, [0.1, 0.1, 0.1, 0.1], t, args=(2.1, 1.5, 0.25, 0)) # confusion with 1.5, 0.1, 5 and 4.2, 0.1, 5 and 4.2, 0.25, 0
V = ret[:, 0]
spikes2 = find_spikes(V)
rec_diff2 = find_reciprocal_differences(t[spikes2])
times2 = t[spikes2]
times2 = times2[1:]
# plt.plot(t, V, 'r', label="FS")
# plt.scatter([t[spikes2]], [V[spikes2]])

t = np.linspace(1, 0.75, 500)
ret = odeint(dz_dt, [0.1, 0.1, 0.1, 0.1], t, args=(2.1, 1.5, 0.25, 0))
V = ret[:, 0]
# plt.plot(t, V, 'r')
# plt.xlabel("t")
# plt.ylabel("V")

#--------------------------

plt.figure()
minlen = min(len(times1), len(times2))
plt.plot(times1, rec_diff1, 'b', label="RS")
plt.plot(times2, rec_diff2, 'r--', label="FS")
plt.xlabel("t")
plt.ylabel("Hz")
plt.legend()

# # Fig 3

# In[13]:

Image(filename="img/8.png")

# In[14]:

def dz_dt(z, t, I, tau, a, b):
    m_inf = 17.8 + 47.6 * z[0] + 33.8 * z[0] * z[0]
    R_inf = 1.24 + 3.7 * z[0] + 3.2 * z[0] * z[0]
    T_inf = 8 * (z[0] + 0.725) * (z[0] + 0.725)
    dV_dt = (I - m_inf * (z[0] - 0.5) - 26 * z[1] * (z[0] + 0.95) - a * z[2] * (z[0] - 1.2) - b * z[3] * (z[0] + 0.95)) / 1
    dR_dt = (R_inf - z[1]) / tau
    dT_dt = (T_inf - z[2]) / 14
    dH_dt = (3 * z[2] - z[3]) / 45
    return [dV_dt, dR_dt, dT_dt, dH_dt]

xx = [i.round(1) for i in arange(0.3, 2.2, 0.2)]
yy1init = []
yy1ss = []

for i in arange(0.3, 2.2, 0.2):
    i = i.round(1)
    t = np.linspace(1, 200, 1000)
    ret = odeint(dz_dt, [0.1, 0.1, 0.1, 0.1], t, args=(i, 4.2, 0.1, 5))
    V = ret[:, 0]
    spikes = find_spikes(V)
    rec_diff = find_reciprocal_differences(t[spikes])
    initfreq = rec_diff[0]
    yy1init.append(initfreq)
    ssfreq = rec_diff[-1]
    yy1ss.append(ssfreq)

plt.figure(figsize=(5,4))
plt.plot(xx, yy1init, 'b', label="RS Transient")
plt.plot(xx, yy1ss, 'b--', label="RS SS")
plt.legend()
plt.xlabel("I")
plt.ylabel("Hz")
plt.title("RS")
plt.show()
#---------------------------

xx = [i.round(1) for i in arange(0.25, 2.2, 0.2)]
yy2 = []

for i in arange(0.25, 2.2, 0.2):
    i = i.round(1)
    t = np.linspace(1, 200, 1000)
    ret = odeint(dz_dt, [0.1, 0.1, 0.1, 0.1], t, args=(i, 1.5, 0.25, 0))
    V = ret[:, 0]
    spikes = find_spikes(V)
    rec_diff = find_reciprocal_differences(t[spikes])
    freq = rec_diff[0]
    yy2.append(freq)

plt.figure(figsize=(5,4))
plt.plot(xx, yy2, 'r--', label="FS")
plt.legend()
plt.xlabel("I")
plt.ylabel("Hz")
plt.title("FS")
plt.show()

# # Continuous and Intrinsic Bursting Neurons

# # Fig 4

# In[15]:

Image(filename="img/9.png")

# In[16]:

def dz_dt(z, t):
    m_inf = 17.8 + 47.6 * z[0] + 33.8 * z[0] * z[0]
    R_inf = 1.24 + 3.7 * z[0] + 3.2 * z[0] * z[0]
    T_inf = 8 * (z[0] + 0.725) * (z[0] + 0.725)
    dV_dt = (0.85 - m_inf * (z[0] - 0.5) - 26 * z[1] * (z[0] + 0.95) - 2.25 * z[2] * (z[0] - 1.2) - 9.5 * z[3] * (z[0] + 0.95)) / 1
    dR_dt = (R_inf - z[1]) / 4.2
    dT_dt = (T_inf - z[2]) / 14
    dH_dt = (3 * z[2] - z[3]) / 45
    return [dV_dt, dR_dt, dT_dt, dH_dt]

plt.figure(figsize=(20,5))
t = np.linspace(1, 400, 1000)
ret = odeint(dz_dt, [0.1, 0.1, 0.1, 0.1], t)
V = ret[:, 0]
plt.plot(t, V, color='b')

t = np.linspace(1, 0.75, 500)
ret = odeint(dz_dt, [0.1, 0.1, 0.1, 0.1], t)
V = ret[:, 0]
plt.plot(t, V, color='b')

plt.xlabel("t")
plt.ylabel("V")

# # Fig 5

# In[17]:

Image(filename="img/10.png")

# In[18]:

def dz_dt(z, t):
    m_inf = 17.8 + 47.6 * z[0] + 33.8 * z[0] * z[0]
    R_inf = 1.24 + 3.7 * z[0] + 3.2 * z[0] * z[0]
    T_inf = 8 * (z[0] + 0.725) * (z[0] + 0.725)
    dV_dt = (0.85 - m_inf * (z[0] - 0.5) - 26 * z[1] * (z[0] + 0.95) - 0.8 * z[2] * (z[0] - 1.2) - 4 * z[3] * (z[0] + 0.95)) / 1
    dR_dt = (R_inf - z[1]) / 4.2
    dT_dt = (T_inf - z[2]) / 14
    dH_dt = (3 * z[2] - z[3]) / 45
    return [dV_dt, dR_dt, dT_dt, dH_dt]

plt.figure(figsize=(20,5))
t = np.linspace(1, 400, 1000)
ret = odeint(dz_dt, [0.1, 0.1, 0.1, 0.1], t)
V = ret[:, 0]
plt.plot(t, V, color='b')

spikes = find_spikes(V)
rec_diff = find_reciprocal_differences(t[spikes])
times = t[spikes]
times = times[1:]

t = np.linspace(1, 0.75, 500)
ret = odeint(dz_dt, [0.1, 0.1, 0.1, 0.1], t)
V = ret[:, 0]

plt.plot(t, V, color='b')
plt.xlabel("t")
plt.ylabel("V")

#-----------------------------------
plt.figure(figsize=(20,5))
plt.plot(times, rec_diff, 'b')
plt.xlabel("t")
plt.ylabel("Hz")
plt.show()

# # Fig 6

# In[19]:

Image(filename="img/11.png")

# In[20]:

def dz_dt(z, t):
    m_inf = 17.8 + 47.6 * z[0] + 33.8 * z[0] * z[0]
    R_inf = 1.24 + 3.7 * z[0] + 3.2 * z[0] * z[0]
    T_inf = 8 * (z[0] + 0.725) * (z[0] + 0.725)
    dV_dt = (0.85 - m_inf * (z[0] - 0.5) - 26 * z[1] * (z[0] + 0.95) - 1.2 * z[2] * (z[0] - 1.2) - 3.4 * z[3] * (z[0] + 0.95)) / 1
    dR_dt = (R_inf - z[1]) / 4.2
    dT_dt = (T_inf - z[2]) / 14
    dH_dt = (3 * z[2] - z[3]) / 45
    return [dV_dt, dR_dt, dT_dt, dH_dt]

plt.figure(figsize=(20,5))
t = np.linspace(1, 800, 1000)
ret = odeint(dz_dt, [0.1, 0.1, 0.1, 0.1], t)
V = ret[:, 0]
plt.plot(t, V, color='b')

spikes = find_spikes(V)
rec_diff = find_reciprocal_differences(t[spikes])
times = t[spikes]
times = times[1:]

t = np.linspace(1, 0.75, 500)
ret = odeint(dz_dt, [0.1, 0.1, 0.1, 0.1], t)
V = ret[:, 0]

plt.plot(t, V, color='b')
plt.xlabel("t")
plt.ylabel("V")

#-----------------------------------

plt.figure(figsize=(20,5))
plt.plot(times, rec_diff, 'b')
plt.xlabel("t")
plt.ylabel("Hz")
plt.show()

# # Synaptic Connections

# # Fig 7

# In[21]:

Image(filename="img/12.png")

# In[22]:

# Reciprocally excitatory RS neurons
def dz_dt(z, t):
    m_inf = 17.8 + 47.6 * z[0] + 33.8 * z[0] * z[0]
    R_inf = 1.24 + 3.7 * z[0] + 3.2 * z[0] * z[0]
    T_inf = 8 * (z[0] + 0.725) * (z[0] + 0.725)
    dV_dt = (0.5 - m_inf * (z[0] - 0.5) - 26 * z[1] * (z[0] + 0.95) - 0.1 * z[2] * (z[0] - 1.2) - 5 * z[3] * (z[0] + 0.95) - 20 * z[5] * (z[0] - 0)) / 1
    dR_dt = (R_inf - z[1]) / 4.2
    dT_dt = (T_inf - z[2]) / 14
    dH_dt = (3 * z[2] - z[3]) / 45
    if z[0] - (-0.1) > 0:
        H = 1
    else:
        H = 0
    df_dt = (H - z[4]) / 2
    dS_dt = (z[4] - z[5]) / 2
    return [dV_dt, dR_dt, dT_dt, dH_dt, df_dt, dS_dt]

plt.figure(figsize=(20,5))
t = np.linspace(1, 800, 1000)
ret = odeint(dz_dt, [0.1, 0.1, 0.1, 0.1, 0.1, 0.1], t)
V = ret[:, 0]
plt.plot(t, V, color='b')

t = np.linspace(1, 0.8, 500)
ret = odeint(dz_dt, [0.1, 0.1, 0.1, 0.1, 0.1, 0.1], t)
V = ret[:, 0]

plt.plot(t, V, color='b')
plt.xlabel("t")
plt.ylabel("V")

# # Fig 8

# In[23]:

Image(filename="img/13.png")

# In[24]:

# Reciprocally excitatory RS neurons with attenuated g_H resulting from stimulated neuromodulation
def dz_dt(z, t):
    m_inf = 17.8 + 47.6 * z[0] + 33.8 * z[0] * z[0]
    R_inf = 1.24 + 3.7 * z[0] + 3.2 * z[0] * z[0]
    T_inf = 8 * (z[0] + 0.725) * (z[0] + 0.725)
    dV_dt = (0.5 - m_inf * (z[0] - 0.5) - 26 * z[1] * (z[0] + 0.95) - 0.1 * z[2] * (z[0] - 1.2) - 0.4 * z[3] * (z[0] + 0.95) - 20 * z[5] * (z[0] - 0)) / 1
    dR_dt = (R_inf - z[1]) / 4.2
    dT_dt = (T_inf - z[2]) / 14
    dH_dt = (3 * z[2] - z[3]) / 45
    if z[0] - (-0.1) > 0:
        H = 1
    else:
        H = 0
    df_dt = (H - z[4]) / 2
    dS_dt = (z[4] - z[5]) / 2
    return [dV_dt, dR_dt, dT_dt, dH_dt, df_dt, dS_dt]

plt.figure(figsize=(20,5))
t = np.linspace(1, 800, 1000)
ret = odeint(dz_dt, [0.1, 0.1, 0.1, 0.1, 0.1, 0.1], t)
V = ret[:, 0]
plt.plot(t, V, color='b')

t = np.linspace(1, 0.85, 500)
ret = odeint(dz_dt, [0.1, 0.1, 0.1, 0.1, 0.1, 0.1], t)
V = ret[:, 0]

plt.plot(t, V, color='b')
plt.xlabel("t")
plt.ylabel("V")

# # Critical Points, Jacobian

# In[25]:

V, R, T, H, g_H, g_T, tau_R, I  = symbols('V, R, T, H, g_H, g_T, tau_R, I')

# In[26]:

Vdot = (I - (17.8 + 47.6 * V + 33.8 * V * V) * (V - 0.5) - 26 * (1.24 + 3.7 * V + 3.2 * V * V) * (V + 0.95) - g_T * (8 * (V + 0.725) * (V + 0.725)) * (V - 1.2) - g_H * (3 * (8 * (V + 0.725) * (V + 0.725))) * (V + 0.95)) / 1
Vnull = Eq(Vdot, 0)
print("I =", end=" ")
I1 = solve(Vnull, I)[0]
solve(Vnull, I)[0]

# In[27]:

# TTX Condition where m_inf = 1.1125
Vdot = (I - 1.1125 * (V - 0.5) - 26 * (1.24 + 3.7 * V + 3.2 * V * V) * (V + 0.95) - g_T * (8 * (V + 0.725) * (V + 0.725)) * (V - 1.2) - g_H * (3 * (8 * (V + 0.725) * (V + 0.725))) * (V + 0.95)) / 1
Vnull = Eq(Vdot, 0)
print("I =", end=" ")
I2 = solve(Vnull, I)[0]
solve(Vnull, I)[0]

# In[28]:

m_inf = 17.8 + 47.6 * V + 33.8 * V * V
R_inf = 1.24 + 3.7 * V + 3.2 * V * V
T_inf = 8 * (V + 0.725) * (V + 0.725)
dV_dt1 = (I1 - m_inf * (V - 0.5) - 26 * R * (V + 0.95) - g_T * T * (V - 1.2) - g_H * H * (V + 0.95)) / 1
dV_dt2 = (I2 - 1.1125 * (V - 0.5) - 26 * R * (V + 0.95) - g_T * T * (V - 1.2) - g_H * H * (V + 0.95)) / 1
# dV_dtconst1 = (I1 - (17.8 + 47.6 * V + 33.8 * V * V) * (V - 0.5) - 26 * (1.24 + 3.7 * V + 3.2 * V * V) * (V + 0.95) - g_T * (8 * (V + 0.725) * (V + 0.725)) * (V - 1.2) - g_H * (3 * (8 * (V + 0.725) * (V + 0.725))) * (V + 0.95)) / 1
# dV_dtconst2 = (I2 - 1.1125 * (V - 0.5) - 26 * (1.24 + 3.7 * V + 3.2 * V * V) * (V + 0.95) - g_T * (8 * (V + 0.725) * (V + 0.725)) * (V - 1.2) - g_H * (3 * (8 * (V + 0.725) * (V + 0.725))) * (V + 0.95)) / 1
dR_dt = (R_inf - R) / tau_R
dT_dt = (T_inf - T) / 14
dH_dt = (3 * T - H) / 45

a11 = diff(dV_dt1, V)
a12 = diff(dV_dt2, V)
b11 = diff(dV_dt1, R)
b12 = diff(dV_dt2, R)
c11 = diff(dV_dt1, T)
c12 = diff(dV_dt2, T)
d11 = diff(dV_dt1, H)
d12 = diff(dV_dt2, H)

a2 = diff(dR_dt, V)
b2 = diff(dR_dt, R)
c2 = diff(dR_dt, T)
d2 = diff(dR_dt, H)

a3 = diff(dT_dt, V)
b3 = diff(dT_dt, R)
c3 = diff(dT_dt, T)
d3 = diff(dT_dt, H)

a4 = diff(dH_dt, V)
b4 = diff(dH_dt, R)
c4 = diff(dH_dt, T)
d4 = diff(dH_dt, H)

# In[29]:

jacobian1 = Matrix([[a11, b11, c11, d11], [a2, b2, c2, d2], [a3, b3, c3, d3], [a4, b4, c4, d4]])
jacobian2 = Matrix([[a12, b12, c12, d12], [a2, b2, c2, d2], [a3, b3, c3, d3], [a4, b4, c4, d4]])

# In[30]:

jacobian1

# In[31]:

jacobian2

# # 2D Model

# In[32]:

Vdot = (I - (17.8 + 47.6 * V + 33.8 * V * V) * (V - 0.5) - 26 * R * (V + 0.95)) / 1
Rdot = ((1.24 + 3.7 * V + 3.2 * V * V) - R) / 4.2

# In[33]:

a = diff(Vdot, V)
aa = lambdify((V,R), a)
b = diff(Vdot, R)
bb = lambdify((V,R), b)
c = diff(Rdot, V)
cc = lambdify((V,R), c)
d = diff(Rdot, R)
dd = lambdify((V,R), d)

# In[34]:

#http://systems-sciences.uni-graz.at/etextbook/sw2/phpl_python.html
def eigenvalues(x,y):
    a11 = aa(x,y) # differentiated with respect to x
    a12 = bb(x,y) # differentiated with respect to y
    a21 = cc(x,y) # differentiated with respect to x
    a22 = dd(x,y) # differentiated with respect to y

    tr = a11 + a22
    det = a11*a22 - a12*a21

    if tr**2 >= 4*det:
        # Real
        lambda1 = (tr - sqrt(tr**2 - 4*det))/2
        lambda2 = (tr + sqrt(tr**2 - 4*det))/2

        print('Check the fixed point  %s, %s' % (x,y))
        print('The first eigenvalue is %s' % lambda1)
        print('The second eigenvalue is %s' % lambda2)

    else:
        lambda1 = tr/2
        lambda2 = tr/2

        print('Check the fixed point (%s, %s)' % (x,y))
        print('The real component of the first eigenvalue is %s' % lambda1)
        print('The real component of the second eigenvalue is %s' % lambda2)

    if (lambda1 < 0 and lambda2 < 0):
        print('The fixed point (%s, %s) is a sink. It is stable' % (x,y))
        return 1
    if (lambda1 > 0 and lambda2 > 0):
        print('The fixed point (%s, %s) is a source. It is unstable' % (x,y))
        return 0
    if (lambda1 > 0 and lambda2 < 0):
        print('The fixed point (%s, %s) is a saddle. It is unstable' % (x,y))
        return 0
    if (lambda1 < 0 and lambda2 > 0):
        print('The fixed point (%s, %s) is a saddle. It is unstable' % (x,y))
        return 0

# In[36]:

import cmath

def func(z):
    V = z[0]
    R = z[1]
    F = empty((2))
    F[0] = (i - (17.8 + 47.6 * V + 33.8 * V * V) * (V - E_Na))/(g_K * (V - E_K)) - R
    F[1] = (1.24 + 3.7 * V + 3.2 * V * V) - R

    return F

I = [-2, -1.5, -1, -0.5, 0, 0.178, 0.3, 0.5]
for i in I:
    print("I =", i)
    d = {}
    for init in [-1.5, -1, -0.9, -0.8, -0.7, -0.6, -0.5, -0.3, 0, 0.5]:
        criticalpoints = fsolve(func, [init, 0.5])
        x = int(np.round(criticalpoints[0]))
        y = np.round(criticalpoints[1], 1)
        if (x, y) not in d:
            d[(x, y)] = 0

    print("Number of Critical Points =", len(d))
    cnt = 1
    for item in d.keys():
        print("Critical Point", cnt, "=", item)
        cnt += 1
    print()
    for tup in d:
        xx = tup[0]
        yy = tup[1]
        stability = eigenvalues(xx, yy)
        if stability == 0:
            c = 'r'
        elif stability == 1:
            c = 'g'
        #plt.scatter(i, xx, c=c)
    print("\n\n")

# plt.xlabel("Applied Current I")
# plt.ylabel("Membrane Voltage V")
# plt.show()

# In[ ]:


import sc2
import random
from sc2 import run_game, maps, Race, Difficulty
from sc2.player import Bot, Computer
from sc2.constants import *

# ** See Notes in: README.txt **

class JustinBot(sc2.BotAI):  # see bot_ai.py to see inherited methods
    def __init__(self):
        self.ITERATIONS_PER_MINUTE = 165
        self.MAX_WORKERS = 65

    async def on_step(self, iteration):  # first thing game does on startup
        if iteration == 0:
            await self.chat_send("(JustinBot Wishes the Opponent Good Luck)")
        self.iteration = iteration

        await self.distribute_workers()
        await self.build_workers()
        await self.build_supplydepot()
        await self.build_assimilator()
        await self.expand()
        await self.offensive_force_buildings()
        await self.build_offensive_force()
        await self.attack()

    async def build_workers(self):
        if len(self.units(COMMANDCENTER)) * 16 > len(self.units(SCV)):
            if len(self.units(SCV)) < self.MAX_WORKERS:
                for nexus in self.units(COMMANDCENTER).ready.noqueue:  # COMMANDCENTER must be ready and not producing anything then:
                    if self.can_afford(SCV):  # if can afford a SCV...
                        await self.do(nexus.train(SCV))  # train the PROBE

    async def build_supplydepot(self):
        if self.supply_left < 5 and not self.already_pending(SUPPLYDEPOT):  # if pop. remaining is < x and SD not currently being built
            nexuses = self.units(COMMANDCENTER).ready  # a nexus tha already exists
            if nexuses.exists:
                if self.can_afford(SUPPLYDEPOT):  # if can afford the pylon
                    await self.build(SUPPLYDEPOT, near=nexuses.first)  # builds pylon close to nexus

    async def build_assimilator(self):
        for nexus in self.units(COMMANDCENTER).ready:  # for nexuses that are ready
            vaspenes = self.state.vespene_geyser.closer_than(15.0, nexus)  # looking for geysers that are closer than x units
            for vaspene in vaspenes:
                if not self.can_afford(REFINERY):  # if cant afford
                    break
                worker = self.select_build_worker(vaspene.position)  # finds worker close to the vaspene deposit
                if worker is None:  # if there is no worker near deposit
                    break
                if not self.units(REFINERY).closer_than(1.0, vaspene).exists:  # if not assimilator that exists near vaspene
                    await self.do(worker.build(REFINERY, vaspene))  # builds assimilator on top of found vaspene deposit

    async def expand(self):
        if self.units(COMMANDCENTER).amount < (self.iteration / self.ITERATIONS_PER_MINUTE) and self.can_afford(COMMANDCENTER):  # if number of nexuses is < x and can afford...
            await self.expand_now()  # goes and expands to another resource area

    async def offensive_force_buildings(self):
        # PATH OF PROGRESSION:
        # barracks --> factory --> starport
        #
        # ADD LOGIC TO: see what buildings can be upgrades...based on iteration/min determine whether or not to upgrade
        if self.units(SUPPLYDEPOT).ready.exists:  # as long as some pylon exists
            building_loc = self.units(SUPPLYDEPOT).ready.random  # picks random pylon

            # BUILD FACTORY/FACTORY TECH LAB
            if self.units(BARRACKS).ready.exists and not self.units(FACTORY):  # if have BARRACKS and is ready and exists
                if self.can_afford(FACTORY) and not self.already_pending(FACTORY):  # if can afford FACTORY and not already pending
                    await self.build(FACTORY, near=building_loc)  # builds FACTORY near the random SUPPLYDEPOT
                    # builds only ONE factory...can change in future
            if self.units(FACTORY).ready.exists and self.can_afford(FACTORYTECHLAB):  # checks if factory already exists and if can afford tech lab
                for ready_factories in self.units(FACTORY).ready:  # for each ready factory in factories
                    await self.do(ready_factories.build(FACTORYTECHLAB))  # build a tech lab on a given factory

            # BUILD BARRACKS/BARRACKS TECH LAB
            if len(self.units(BARRACKS)) < ((self.iteration / self.ITERATIONS_PER_MINUTE)/2):  # ~1 every minute
                if self.can_afford(BARRACKS) and not self.already_pending(BARRACKS):  # if can afford BARRACKS and not pending
                    await self.build(BARRACKS, near=building_loc)  # builds BARRACKS near random SUPPLYDEPOT from above
            if self.units(BARRACKS).ready.exists and self.can_afford(BARRACKSTECHLAB):  # checks if barracks exists and if can afford tech lab
                for ready_barracks in self.units(BARRACKS).ready:  # for each ready barracks in barracks list
                    await self.do(ready_barracks.build(BARRACKSTECHLAB))  # build a tech lab for the given barracks

            # if self.units(FACTORY).ready.exists:  # if FACTORY is ready and exists...
            #     if len(self.units(STARPORT)) < ((self.iteration / self.ITERATIONS_PER_MINUTE)/2):
            #         if self.can_afford(STARPORT) and not self.already_pending(STARPORT):  # if can afford a STARPORT and not already pending
            #             await self.build(STARPORT, near=building_loc)

    async def build_offensive_force(self):
        # BUILD BARRACKS UNITS
        for barr in self.units(BARRACKS).ready.noqueue:  # for each BARRACK in ready BARRACKS
            if self.units(BARRACKSTECHLAB).exists and self.can_afford(MARAUDER) and self.supply_left > 0:  # HIGHEST priority given to MARAUDERS over rest in scope of for-loop
                await self.do(barr.train(MARAUDER))  # train MARAUDER
            if self.can_afford(MARINE) and self.supply_left > 0:  # if can afford MARINE but not MARAUDER and supply left > 0
                await self.do(barr.train(MARINE))  # trains MARINE

        # BUILD FACTORY UNITS
        for fact in self.units(FACTORY).ready.noqueue:  # for each FACTORY in ready FACTORIES
            if self.units(FACTORYTECHLAB).exists and self.can_afford(SIEGETANK) and self.supply_left > 0:  # HIGHEST priority given to SIEGETANK over rest in scope of for-loop
                await self.do(fact.train(SIEGETANK))  # trains SIEGETANK
            if self.can_afford(HELLION) and self.supply_left > 0:  # if can afford HELLION but not SIEGETANK
                await self.do(fact.train(HELLION))  # trains HELLION

        # for st_pt in self.units(STARPORT).ready.noqueue:
        #     if self.can_afford(VIKING) and self.supply_left > 0:
        #         await self.do(st_pt.train(VIKING))

    def find_target(self, state):
        if len(self.known_enemy_units) > 0:  # if know about some enemy unit
            return random.choice(self.known_enemy_units)  # attack that target
        elif len(self.known_enemy_structures) > 0:  # if cant find any units and only structures
            return random.choice(self.known_enemy_structures)  # attack a random structure
        else:
            return self.enemy_start_locations[0]  # if don't know about anything, go seek them out at start loc.

    async def attack(self):
        # TO ADD - CLUMP IN GROUP BEFORE THEY GO AND ATTACK
        #
        # {UNIT: [n to search for a fight, n to defend]
        aggressive_units = {MARINE: [15, 4],
                            MARAUDER: [7, 3],
                            HELLION: [7, 2],
                            SIEGETANK: [4, 1]}

        for UNIT in aggressive_units:
            if self.units(UNIT).amount > aggressive_units[UNIT][0] and self.units(UNIT).amount > aggressive_units[UNIT][1]:
                for s in self.units(UNIT).idle:
                    await self.do(s.attack(self.find_target(self.state)))

            elif self.units(UNIT).amount > aggressive_units[UNIT][1]:
                if len(self.known_enemy_units) > 0:
                    for s in self.units(UNIT).idle:
                        await self.do(s.attack(random.choice(self.known_enemy_units)))

# Runs the game. can specify the map, who is playing, and game speed
run_game(maps.get("AbyssalReefLE"), [
    Bot(Race.Terran, JustinBot()),
    Computer(Race.Protoss, Difficulty.Easy)
    ], realtime=False)


import os
import pyperclip
import tkinter

from utils import notifier
from utils import uploader
from utils import files

class Window(tkinter.Tk):
    def __init__(self):
        super().__init__()
        self.title("Screenshot Uploader")
        self.geometry("450x250")
        self.resizable(False, False)

        self.create_widgets()
        self.create_loops()
        self.setup()

    def create_widgets(self):
        self.console = tkinter.Listbox(self, width=450, height=250)
        self.console.pack()

    def create_loops(self):
        self.after(1, self.check_screenshots)

    def setup(self):
        self.screenshot_dir_path = f"{os.path.expanduser('~')}/Pictures"
        self.uploader = uploader.Uploader(self)

        if not os.path.exists(os.path.join(self.screenshot_dir_path, "Screenshots")):
            os.makedirs(os.path.join(self.screenshot_dir_path, "Screenshots"))
            self.console.insert(tkinter.END, "ℹ Make sure to set your Cleanshot export directory to: " + self.screenshot_dir_path)

        notifier.send("Screenshot Uploader", "Uploader started in the background.")
        self.console.insert(tkinter.END, "🏞 Screenshot Uploader has started!")
        self.console.insert(tkinter.END, "\tℹ Take a screenshot and save it to pictures/screenshots and it will be uploaded to the image host set in data/uploader.json.")
        self.console.insert(tkinter.END, "\tℹ If you need to edit any settings, open data/uploader.json and edit the values.")
        self.console.insert(tkinter.END, "")

        self.screenshot_dir = os.path.join(self.screenshot_dir_path, "Screenshots")
        self.stored_files = os.listdir(self.screenshot_dir)

    def check_screenshots(self):
        newest_file = files.get_newest_file(self.screenshot_dir)
        newest_file_no_path = newest_file.split("/")[-1]

        if newest_file_no_path not in self.stored_files:
            url = self.uploader.upload_screenshot(newest_file)
            pyperclip.copy(url)
            self.stored_files.append(newest_file_no_path)

            self.console.insert(tkinter.END, f"\t✅ Copied to clipboard: {url}")
            self.console.insert(tkinter.END, "")
            notifier.send("Screenshot Uploader", "Screenshot copied to clipboard")

        self.after(1, self.check_screenshots)

    def run(self):
        self.mainloop()

if __name__ == "__main__":
    Window().run()


# Heap Sort
# Sort the array in increasing order
# T(n) = O(nlog(n))

'''
build_heap() call in heap_sort() will take O(n) times.
for loop in in heap_sort() calls max_heapify() O(n) times
each call takes O(log(n)) time
so total time: O(n) * O(log(n)) + O(n) = O(nlog(n))
'''

def max_heapify(arr, n, i = 0) :
    ''' fix the max heap property at one node '''

    max = i     # index of maximum element of node
    l = 2*i + 1     # left child
    r = 2*i + 2     # right child

    # change max to l if it is greater than max
    if l < n and arr[max] < arr[l] :
        max = l

    if r < n and arr[max] < arr[r] :
        max = r

    # if max is changed, swap the max for the new max
    if max != i :
        arr[max], arr[i] = arr[i], arr[max]
        # call to fix the max heap property of child node, if any
        max_heapify(arr, n, max)

def build_heap(arr, n) :
    ''' Builds a max heap from an array '''

    # only calls for nodes from index n/2 and above, because below that every element is a leaf
    for i in range(n//2, -1, -1) :
        max_heapify(arr, n, i)

def heap_sort(arr) :
    ''' Sort an unsorted array '''

    n = len(arr)
    # puts the largest element at index 0
    build_heap(arr, n)

    for i in range(n-1, 0, -1) :
        # move the largest element to the end
        arr[0], arr[i] = arr[i], arr[0]
        n -= 1
        # puts the next largest element at index 0
        max_heapify(arr, n, 0)

""" a = [10, 3, 4, 1, 5, 2, 7]
heap_sort(a)
print(a)
works fine, prints [1, 2, 3, 4, 5, 7, 10] """


def mathem (a, b, c):
 try:
  sum = a + b
  if sum > c:
   print ("the sum of the first and second arguments is greater than the third")
  elif sum <= c:
   print ("the sum of the first and second arguments is less than the third")
  else:
   print ("not valid Data")
 except:
  print("not valid Data")


from django.contrib import admin
from django.db.models import Count, Sum, Q
from django.template.response import TemplateResponse
from django.urls import path
from .models import User, Route, Bus, Ticket, Feedback, Schedule, Station, Province, Type, Tag, Organization
from django.utils.html import mark_safe
from django import forms
from ckeditor_uploader.widgets import CKEditorUploadingWidget
from django.db.models.functions import Extract
from  django.utils import timezone

# Register your models here.
class RouteAdmin(admin.ModelAdmin):
    list_display = ('id', 'active', 'departure_location', 'arrival_location')
    list_filter = ('id', 'departure_location', 'arrival_location')
    search_fields = ['departure_location__name', 'arrival_location__name']
    readonly_fields = ['image_view']

    def image_view(self, route):
        if route:
            return mark_safe(
                ''\
                    .format(url=route.image.url)
            )

    def get_urls(self):
        return [path('route-stats/', self.stat_view)] + super().get_urls()

    def stat_view(self, request):
        routes = Route.objects.filter(active=True).all()
        count = routes.count()

        my_month = timezone.now().month
        my_year = timezone.now().year
        my_quarter = 1
        quarter_checked = None
        stat_type = 'by_month'
        schedule_count_stats = []
        if request.method == 'POST':
            stat_type = request.POST.get('stat_type')
            if stat_type == 'by_month':
                month_input = request.POST.get('my_month')
                my_month = int(month_input.split("-")[1])
                my_year = int(month_input.split("-")[0])

            else:
                my_year = int(request.POST.get('my_year'))
                quarter_checked = request.POST.get('quarter_checked')
                if quarter_checked:
                    my_quarter = int(request.POST.get('my_quarter'))

        if stat_type == 'by_month':
            schedule_count_stats = routes.annotate(schedule_count=Count('my_schedule',
                filter = Q(my_schedule__departure_time__month=my_month, my_schedule__departure_time__year=my_year)))\
                .values('id', 'departure_location__name', 'arrival_location__name', 'schedule_count')

        else:
            if quarter_checked == None:
                schedule_count_stats = routes.annotate(schedule_count=Count('my_schedule',
                    filter = Q(my_schedule__departure_time__year=my_year)))\
                    .values('id', 'departure_location__name', 'arrival_location__name', 'schedule_count')
            else:
                schedule_count_stats = routes.annotate(schedule_count=Count('my_schedule',
                    filter = Q(my_schedule__departure_time__year=my_year, my_schedule__departure_time__quarter=my_quarter)))\
                    .values('id', 'departure_location__name', 'arrival_location__name', 'schedule_count')

        schedules_count = 0
        total_paid = [0.0] * count
        route_id = [0] * count

        for i in range(count):
            # schedules_count += routes[i].schedules2.count()
            route_id[i] = routes[i].id
            for s in routes[i].schedules2.all():
                if stat_type == 'by_month':
                    schedules_count += routes[i].schedules2.annotate(month=Extract('departure_time', 'month')) \
                        .filter(month=my_month).count()
                    tickets = s.tickets.annotate(month=Extract('updated_date', 'month'),
                                                 year=Extract('updated_date', 'year'))\
                        .filter(active=True, month=my_month, year=my_year).all()
                    for t in tickets:
                        total_paid[i] += t.paid
                else:
                    if quarter_checked == None:
                        schedules_count += routes[i].schedules2.annotate(year=Extract('departure_time', 'year')) \
                            .filter(year=my_year).count()
                        tickets = s.tickets.annotate(year=Extract('updated_date', 'year')) \
                            .filter(active=True, year=my_year).all()
                        for t in tickets:
                            total_paid[i] += t.paid
                    else:
                        schedules_count += routes[i].schedules2.annotate(year=Extract('departure_time', 'year'),
                                                                         quarter=Extract('departure_time', 'quarter')) \
                            .filter(year=my_year, quarter=my_quarter).count()
                        tickets = s.tickets.annotate(year=Extract('updated_date', 'year'),
                                                     quarter=Extract('updated_date', 'quarter')) \
                            .filter(active=True, year=my_year, quarter=my_quarter).all()
                        for t in tickets:
                            total_paid[i] += t.paid

        return TemplateResponse(request, 'admin/route-stats.html', {
            'count': count,
            'count_range': range(count),
            'schedule_count_stats': schedule_count_stats,
            'stats': zip(schedule_count_stats, total_paid),
            'schedules_count': schedules_count,
            'total_paid': zip(route_id, total_paid),
            'stat_type': stat_type,
            'my_month': my_month,
            'my_year': my_year,
            'my_quarter': my_quarter,
            'years': reversed(range(timezone.now().year-10, timezone.now().year+1)),
            'quarters': range(1, 4+1),
            'quarter_checked': quarter_checked
        })

class BusForm(forms.ModelForm):
    description = forms.CharField(widget=CKEditorUploadingWidget)

    class Meta:
        model = Bus
        fields = '__all__'

class BusAdmin(admin.ModelAdmin):
    form = BusForm
    readonly_fields = ['image_view']
    list_display = ('id', 'active', 'name', 'number_plate')
    list_filter = ('id', 'active', 'name', 'number_plate')

    def image_view(self, bus):
        if bus:
            return mark_safe(
                '' \
                    .format(url=bus.image.url)
            )

class ScheduleForm(forms.ModelForm):
    class Meta:
        model = Schedule
        fields = '__all__'

    def __init__(self, *args, **kwargs):
        super(ScheduleForm, self).__init__(*args, **kwargs)
        if self.instance.route:
            self.fields['departure_station'].queryset = Station.objects.filter(
                province_id=self.instance.route.departure_location_id)
            self.fields['arrival_station'].queryset = Station.objects.filter(
                province_id=self.instance.route.arrival_location_id)

class ScheduleAdmin(admin.ModelAdmin):
    form = ScheduleForm
    list_display = ('id', 'active', 'bus', 'user', 'departure_time')
    list_filter = ('id', 'active', 'bus', 'user', 'departure_time')
    search_fields = ['bus__name']

class UserForm(forms.ModelForm):
    def save(self, commit=True):
        user = super(UserForm, self).save(commit=False)

        user.set_password(self.cleaned_data["password"])
        if commit:
            user.save()
        return user

class UserAdmin(admin.ModelAdmin):
    form = UserForm
    list_display = ('id', 'is_active', 'username', 'role')
    list_filter = ('id', 'username', 'role')
    search_fields = ['username', 'role']
    readonly_fields = ['avatar_view']

    def avatar_view(self, user):
        if user:
            return mark_safe(
                '' \
                    .format(url=user.avatar.url)
            )

class TicketAdmin(admin.ModelAdmin):
    list_display = ('id', 'active', 'user', 'quantity')
    list_filter = ('id', 'active', 'user', 'quantity')

class FeedbackAdmin(admin.ModelAdmin):
    list_display = ('id', 'active', 'created_date')
    list_filter = ('id', 'created_date')

class OrganizationForm(forms.ModelForm):
    description = forms.CharField(widget=CKEditorUploadingWidget)

    class Meta:
        model = Organization
        fields = '__all__'

class OrganizationAdmin(admin.ModelAdmin):
    form = OrganizationForm
    list_display = ('id', 'active', 'name')
    list_filter = ('id', 'active', 'name')

admin.site.register(User, UserAdmin)
admin.site.register(Province)
admin.site.register(Route, RouteAdmin)
admin.site.register(Station)
admin.site.register(Bus, BusAdmin)
admin.site.register(Schedule, ScheduleAdmin)
admin.site.register(Ticket, TicketAdmin)
admin.site.register(Feedback, FeedbackAdmin)
admin.site.register(Type)
admin.site.register(Tag)
admin.site.register(Organization, OrganizationAdmin)


# -*- coding:utf-8 -*-
import numpy as np
import cv2 as cv
# from matplotlib import pyplot as plt
import time

'''
抽取关键点
kp  是一个list<关键点>。 关键点：特殊结构体，属性当中有坐标，方向、角度等等
des 是关键点的特征向量，为128维的向量
'''

def function_sift(image):
    sift = cv.SIFT_create()
    kp, des = sift.detectAndCompute(image, None)
    # 可以对关键点进行一些自定义的筛选。
    return kp, des

'''
匹配比较合适的关键点
使用K近邻（KNN）算法。
K近邻算法求取在空间中距离最近的K个数据点，并将这些数据点归为一类。
在进行特征点匹配时，一般使用KNN算法找到最近邻的两个数据点，
    如果最接近和次接近的比值大于一个既定的值，那么我们保留这个最接近的值，
    认为它和其匹配的点为good match（由Lowe在SIFT论文中提出）。
'''

def function_good_match(des1, des2, delta=0.5):
    bfm = cv.BFMatcher()
    matches = bfm.knnMatch(des1, des2, k=2)
    good_match = []
    for m1, m2 in matches:
        if m1.distance < delta * m2.distance:
            good_match.append(m1)
    return good_match

'''
根据img1将img2进行校准后重新输出，使得img2与img1能够得到较好的像素匹配
完全根据原始图像的大小来的，所以适合不太大的图像。
@imgOut 根据img1将img2进行配准后的图片
@H      单应矩阵
@status 使用状态。（基本无用）
'''

def function_Alignment(img1, img2):
    kp1, des1 = function_sift(img1)
    kp2, des2 = function_sift(img2)
    goodMatch = function_good_match(des1, des2)
    if len(goodMatch) > 4:
        ptsA = np.float32([kp1[m.queryIdx].pt for m in goodMatch]).reshape(-1, 1, 2)
        ptsB = np.float32([kp2[m.trainIdx].pt for m in goodMatch]).reshape(-1, 1, 2)
        ransacReprojThreshold = 4
        H, status = cv.findHomography(ptsA, ptsB, cv.RANSAC, ransacReprojThreshold)
        imgOut = cv.warpPerspective(img2, H, (img1.shape[1], img1.shape[0]),
                                    flags=cv.INTER_LINEAR + cv.WARP_INVERSE_MAP)
    return imgOut, H, status

'''
根据img1将img2进行校准后重新输出，使得img2与img1能够得到较好的像素匹配
适合比较大的图像，先将两幅图缩小到tSize大小，然后计算配准矩阵
'''

def function_Alignment2(img10, img20, tSize=(512, 512)):
    img1 = cv.resize(img10, tSize)
    img2 = cv.resize(img20, tSize)
    h, w = img10.shape[0], img10.shape[1]
    delta_h = h / tSize[0]
    delta_w = w / tSize[1]
    kp1, des1 = function_sift(img1)
    kp2, des2 = function_sift(img2)
    goodMatch = function_good_match(des1, des2)
    if len(goodMatch) > 4:
        ptsA = np.float32([kp1[m.queryIdx].pt for m in goodMatch]).reshape(-1, 1, 2)
        ptsB = np.float32([kp2[m.trainIdx].pt for m in goodMatch]).reshape(-1, 1, 2)
        ransacReprojThreshold = 4
        H, status = cv.findHomography(ptsA, ptsB, cv.RANSAC, ransacReprojThreshold)
        H[0, 2] *= delta_w
        H[1, 2] *= delta_h
        imgOut = cv.warpPerspective(img20, H, (img10.shape[1], img10.shape[0]),
                                    flags=cv.INTER_LINEAR + cv.WARP_INVERSE_MAP)
    return imgOut, H, status


from zad1ktesty import runtests

def divide(S,i,sum):
    if i == len(S) - 1:
        return sum

def haslo ( S ):
    n = len(S)
    # if ord(S[0]) != 48:
    #     result += 1
    F = [0 for _ in range(n)]
    if int(S[0]):
        F[0] = 1

    for i in range(1,n):
        F[i] = F[i-1]
        if int(S[i])== 0:
            if int(S[i-1]) != 1 and int(S[i-1]) != 2:
                F[i] = 0
                break
            elif i > 1:
                F[i] = F[i-2]
            else:
                F[i] = F[0]
        if int(S[i-1:i+1]) <= 26 and int(S[i-1:i+1]) >= 10 and int(S[i]) != 0 :
            if i > 1:
                F[i] += F[i-2]
            else:
                F[i] += 1

    print(S)
    return F[n-1]

runtests ( haslo )


from utils import Utils
import heapq

class DSP:
    def search(arena, start, end):
        graph = arena.world
        frontier = list()
        visited = dict()
        heapq.heappush(frontier, (0, start))
        last = None
        while len(frontier) != 0:
            cost, current = heapq.heappop(frontier)
            if current.equals(end):
                last = current
                break
            neighbors = Utils.remove_unsafe(arena, Utils.get_neighbours(arena, current))
            for next in neighbors:
                if next.position not in visited or next.cost < visited[next.position]:
                    visited[next.position] = next.cost
                    priority = next.cost
                    heapq.heappush(frontier, (priority, next))

        return last


import json

import requests

def get_document_details(doctype, docname):
	url = 'http://127.0.0.1:8080'

	docdata = requests.post(url, data={
		"cmd": "flows.flows.controller.ephesoft_integration.get_meta",
		"doc": json.dumps({
			"id": docname,
			"type": doctype
		})
	})

	if docdata.status_code != 200:
		return {}

	docdata = json.loads(docdata.json()['message'])

	if docdata['$bill_amended_from']:
		docdata['Bill Number'] = docdata['Bill Number'].rsplit('-', 1)[0]
	if docdata['$consignment_amended_from']:
		docdata['Consignment Name'] = docdata['Consignment Name'].rsplit('-', 1)[0]

	docdata.pop('$consignment_amended_from')
	docdata.pop('$bill_amended_from')

	return docdata


from test.vim_test_case import VimTestCase as _VimTest
from test.constant import *

import subprocess

def has_patch(version, executable):
    output = subprocess.check_output([executable, "--version"])
    patch = 1
    for line in output.decode('utf-8').split("\n"):
        if line.startswith("Included patches:"):
            patch = line.split('-')[1]

    return int(patch) >= version

def check_required_vim_version(test):
    if test.vim_flavor == 'neovim':
        return None
    if not has_patch(214, test.vim._vim_executable):
        return 'Vim newer than 7.4.214 is required'
    else:
        return None

class Autotrigger_CanMatchSimpleTrigger(_VimTest):
    skip_if = check_required_vim_version
    files = { 'us/all.snippets': r"""
        snippet a "desc" A
        autotriggered
        endsnippet
        """}
    keys = 'a'
    wanted = 'autotriggered'

class Autotrigger_CanMatchContext(_VimTest):
    skip_if = check_required_vim_version
    files = { 'us/all.snippets': r"""
        snippet a "desc" "snip.line == 2" Ae
        autotriggered
        endsnippet
        """}
    keys = 'a\na'
    wanted = 'autotriggered\na'

class Autotrigger_CanExpandOnTriggerWithLengthMoreThanOne(_VimTest):
    skip_if = check_required_vim_version
    files = { 'us/all.snippets': r"""
        snippet abc "desc" A
        autotriggered
        endsnippet
        """}
    keys = 'abc'
    wanted = 'autotriggered'

class Autotrigger_WillProduceNoExceptionWithVimLowerThan214(_VimTest):
    skip_if = lambda self: 'Vim older than 7.4.214 is required' \
        if has_patch(214, self.vim._vim_executable) else None

    files = { 'us/all.snippets': r"""
        snippet abc "desc" A
        autotriggered
        endsnippet
        """}
    keys = 'abc'
    wanted = 'abc'


# Initialize an empty list
my_list = []

# Read the number of commands
n = int(input())

# Iterate through each command
for _ in range(n):
    command = input().split()

    if command[0] == "insert":
        # Insert integer e at position i
        i, e = int(command[1]), int(command[2])
        my_list.insert(i, e)
    elif command[0] == "print":
        # Print the list
        print(my_list)
    elif command[0] == "remove":
        # Delete the first occurrence of integer e
        e = int(command[1])
        my_list.remove(e)
    elif command[0] == "append":
        # Insert integer e at the end of the list
        e = int(command[1])
        my_list.append(e)
    elif command[0] == "sort":
        # Sort the list
        my_list.sort()
    elif command[0] == "pop":
        # Pop the last element from the list
        my_list.pop()
    elif command[0] == "reverse":
        # Reverse the list
        my_list.reverse()

SGSITS College/Programming Practice/Python Assignment/Q8.py