# -*- coding: utf-8 -*-
"""
Created on Thu Jan 05 15:41:52 2020

@author: fuwei.zhao
"""

import struct
import math
import matplotlib.pyplot as plt
from datetime import datetime
import numpy as np
#import sys
import os
import scipy.interpolate as spi
import binascii
import multiprocessing  #add by FHC 2022/9/9
#import threading  #add by FHC 2022/9/9

global EKMAXPHSP  # 所有粒子的最大动能 add by FHC 2022/9/7
EKMAXPHSP = 0
global EKMINPHSPE  # 所有电子的最小动能 add by FHC 2022/9/7
EKMINPHSPE = 0.5
global SumElectron  # 电子数量 add by FHC 2022/9/9
SumElectron = 0
global NPHOTPHSP  # 光子数量  add by FHC 2022/9/9
NPHOTPHSP = 0
global NPPHSP  # 所有粒子的数量
NPPHSP = 0

def Cut(data, start, width):
    if not isinstance(data, int):
        print("Input is not int.")
        return
    cut_data = data >> start
    cut_data = cut_data % 2**width
    return cut_data

def Int2Binary(data, width):
    BASE=2
    quotient = data
    binstr=['0']*width
    for i in range(width):
        remainder = quotient%BASE
        quotient = quotient>>1
        binstr[width-i-1]=str(remainder)
    binstr=''.join(binstr)
    return binstr

class PhspVector:
    def __init__(self, PID, LATCH, Energy, X, Y, U, V,W_temp, WT, particle_type, ZLast=0,):
        self.LATCH = LATCH
        self.PID = PID  #粒子在相空间文件中的序号
        self.Bremsstrahlung = Cut(self.LATCH, 0, 1)      #粒子轫致辐射的信息
        self.InteractiveRegion = Cut(self.LATCH, 1, 23)  #粒子在相互作用区域的信息
        self.SecondaryParticle = Cut(self.LATCH, 24, 5)  #次级粒子的信息
        self.Charge = Cut(self.LATCH, 29, 2)             #粒子电荷的信息
        self.MultiScore = Cut(self.LATCH, 31, 1)         #多个score平面的信息
        self.ZLast = ZLast                               #粒子最后相互作用的Z坐标
        self.Energy = Energy                             #粒子的能量
        self.EkElectron = 0.5
        self.particle_type = particle_type
        global NPHOTPHSP
        #global SumElectron
        global EKMAXPHSP
        global EKMINPHSPE
        if self.particle_type == b'\x01':  #判断是否为光子
            self.EkAll = abs(Energy)
            NPHOTPHSP += 1
            self.Charge = 0
        elif self.particle_type == b'\x02':  #判断是否为电子
            self.EkAll = abs(Energy)
            self.EkElectron = self.EkAll
            self.Energy = abs(Energy) + 0.511  #IAEA输出的能量为动能
            self.Charge = 2
            #SumElectron += 1
        else:                       #判断是否为正电子
            self.EkAll = abs(Energy)
            self.Energy = abs(Energy) + 0.511   #IAEA输出的能量为动能
            self.Charge = 1
        self.LATCH += self.Charge << 29

        if self.EkAll > EKMAXPHSP:         #更新所有粒子的最大动能
            EKMAXPHSP = self.EkAll
        if self.EkElectron < EKMINPHSPE:   #更新所有电子的最小动能
            EKMINPHSPE = self.EkElectron

        self.X = X
        self.Y = Y
        self.U = U

        if not -1 <= self.U <= 1:
            print('NO.{:8d}:U is wrong:{:8.3f}'.format(self.PID, self.U))
            raise AssertionError
        self.V = V
        if not -1 <= self.V <= 1:
            print('NO.{:8d}:V is wrong:{:8.3f}'.format(self.PID, self.V))
            raise AssertionError
        self.W = math.sqrt(W_temp)
        # if self.particle_type == b'\xff':  #判断W是否要带负号 add by FHC 2022/9/2
        #     self.W = self.W * -1
        self.WT = WT
        if not 0 <= self.WT <= 1:
            print('NO.{:8d}:WT is wrong:{:8.3f}'.format(self.PID, self.WT))
            raise AssertionError
        #self.R = math.sqrt(X ** 2 + Y ** 2)

    def ShowTitle(self):
        print(
            "{:^12} |{:^1}|{:^2}|{:^5}|{:^23}|{:^1}"
            "|{:^8}|{:^8}|{:^8}|{:^8}|{:^8}|{:^8}|{:^10}|".format("ParticleID", "P", "Q", "SecP",
                                                                  "Interactive Region", "B",
                                                                  "X", "Y", "U", "V", "W", "Energy", "Weight"))

    def Show(self):
        print(
            "{:>12} |{:^1}|{:^2}|{:^5}|{:^23}|{:^1}|{:>8.3f}|{:>8.3f}|{:>8.3f}|{:>8.3f}|{:>8.3f}|{:>8.3f}|{:>10.3e}|".format(self.PID, Int2Binary(self.MultiScore, 1), Int2Binary(self.Charge, 2), Int2Binary(self.SecondaryParticle, 5), Int2Binary(self.InteractiveRegion, 23), Int2Binary(self.Bremsstrahlung, 1), self.X, self.Y, self.U, self.V, self.W, self.Energy, self.WT))

class Phsp:

    def __init__(self, filename,headername):
        self.FileName = filename  #IAEA相空间文件名
        self.HeaderName = headername  #IAEAheader文件名
        self.NINCPHSP = 0  #History数量
        self.lock = multiprocessing.RLock()
        #读取相空间文件基本信息  add by FHC 2022/9/7
        with open(filename, 'rb') as fid, \
             open(headername, 'r', encoding='utf-8') as fid_header:
            while (self.NINCPHSP == 0):
                lines = fid_header.readline()  #整行读取数
                if ("$ORIG_HISTORIES:") in lines:
                    self.NINCPHSP = int(next(fid_header).replace("\n"," "))     #从IAEAheader读取History 数量
            fid_header.close()

            self.Mode = 'MODE2'   #IAEAphsp文件为默认MODE2
            self.TotalNumParticles = int(os.path.getsize(filename) / 33)
            if self.Mode == 'MODE2':
                self.offset = 33
            elif self.Mode == 'MODE0':
                self.offset = 28
        self.LoopNum = multiprocessing.cpu_count()   #获取进程数量 = 逻辑CPU数量
        self.MAXBuffer = math.ceil(self.TotalNumParticles / self.LoopNum)  #1000000  #单个进程内读取的粒子数量
        self.startTime = datetime.now()
        self.stopTime = datetime.now()
        self.NPHOTPHSP = 0

    def Loop(self, startID=1, stopID=-1, ptype='ope+-'):  #单个进程
        ptypebin = []   #可能存在的粒子种类
        if 'p' in ptype:  #光子
            ptypebin.append(0)
        if 'e+-' in ptype:  #正负电子
            ptypebin.append(2)
            ptypebin.append(1)
        elif 'e-' in ptype:  #电子
            ptypebin.append(2)
        elif 'e+' in ptype:  #正电子
            ptypebin.append(1)
        if 'o' in ptype:  #未知
            ptypebin.append(3)
        if len(ptypebin) == 0:
            print("No matched particle type.")
            return 0

        if stopID == -1:
            stopID = self.MAXBuffer
        phspList = []  #创建单个进程中读取的粒子相空间信息
        IDoffset = (startID - 1) * self.offset  #获取当前相空间文件的初始读取位置
        with open(self.FileName, 'rb') as fid:   #以二进制只读的方式，打开相空间文件
            fid.seek(IDoffset, 0)  #fid.seek(self.offset + IDoffset, 0)    将指针移动到当前进程应该在的初始读取位置
            if startID > self.TotalNumParticles:
                print("Start ID excessed the max particle number.")
                return []
            #typelist = []
            for i in range(min(self.TotalNumParticles - startID + 1, self.MAXBuffer, stopID - startID + 1)):  #对进程内部的粒子进行循环读取
                particle_type = struct.unpack('s', fid.read(1))[0]
                #typelist.append(particle_type)#粒子的type，代表Z方向速度的正负号
                Energy, X, Y, Z, U, V, WT = struct.unpack('7f', fid.read(28))  #粒子的能量、坐标（X, Y, Z）、水平速度（U, V）、权重（WT）
                LATCH = struct.unpack('i', fid.read(4))[0]  #粒子的LATCH信息

                W_temp = (1 - U ** 2 - V ** 2)  #获取Z方向速度的平方值，由于下一步的筛选，以免出现对负值开方的情况
                if particle_type != b'\xff' and abs(W_temp) > 1e-07:   #只选择Z方向速度为正 并且 Z速度平方为正的粒子进行后处理
                    p = PhspVector(i + startID, LATCH, Energy, X, Y, U, V, W_temp, WT, particle_type, Z)   # 对粒子的相空间信息进行后处理
                    # if p.Charge in ptypebin and p.SecondaryParticle in In_SecondaryParticle and p.InteractiveRegion in In_InteractiveRegion:
                    print("Particle Type: ", particle_type)
                    p.Show()
                    #if p.Charge in ptypebin:
                    phspList.append(p)  #添加粒子的相空间信息

                # if i+startID % 100000 == 1 or i+startID == self.TotalNumParticles:
                # self.stopTime = datetime.now()
                #     percent = (i + startID) % self.MAXBuffer / self.MAXBuffer
                #     timedelta = (self.stopTime-self.startTime).seconds
                #     print("Proceeding {:8.2%}, time used:{:4d} seconds, rest time:{:6.1f} seconds".format(percent, timedelta, (1-percent)*timedelta/percent), end='\r', flush=True)
                #     if i+startID == self.TotalNumParticles:
                #         print("\nDone.")
        return phspList

    def Show(self, phspList, pNum=0, printout=True):
        if len(phspList) > 0:
            phspList[0].ShowTitle()
        for i, p in enumerate(phspList):
            if printout:
                p.Show()
        return pNum

    def ProcessLoop(self,MAXBuffer, ptype, i):
        # 并行模块 开始
        #self.lock.acquire()  # 请求并行锁
        self.phspList = self.Loop(i * MAXBuffer + 1, (i + 1) * MAXBuffer, ptype)
        self.phspList = self.TranserEPID(self.phspList)
        self.SavePhspProcess(self.phspList, i)  #将当前进程的粒子相空间信息保存为二进制文件
        #self.lock.release()  # 释放并行锁
        # 并行模块 结束

    def TotalLoop(self, ptype='ope+-'):
        #LoopNum = math.ceil(self.TotalNumParticles / self.MAXBuffer)
        # self.EnergyFluence.reset()
        self.startTime = datetime.now()
        #targetevents=0

        ProcessList = []
        # #并行模块 开始
        # threading.Lock().acquire()  #请求并行锁

        for i in range(self.LoopNum):
            #phspList = self.Loop(i * self.MAXBuffer + 1, (i + 1) * self.MAXBuffer, ptype)
            exec('Process_'+ str(i)+ ' = multiprocessing.Process(target = self.ProcessLoop, args=(self.MAXBuffer, ptype, i))')
            eval('ProcessList.append(Process_'+str(i)+')')

        for t in ProcessList:
            #t.daemon(True)
            t.start()
        t.join()

        self.SavePhspAll()

            #targetevents = targetevents + len(phspList)
            #pNum = self.show(phspList, ptype, pNum, i, printout=False)
        #
        # threading.Lock().release()  #释放并行锁
        # #并行模块 结束
        self.stopTime = datetime.now()
        print("Total time: {:d} seconds".format((self.stopTime-self.startTime).seconds))

    def TranserEPID(self, phspList):
        Z_epid = 45.0
        for i in range(len(phspList)):
            phspList[i].X += (phspList[i].U / phspList[i].W) * (Z_epid - phspList[i].ZLast)
            phspList[i].Y += (phspList[i].V / phspList[i].W) * (Z_epid - phspList[i].ZLast) + 15.0
            phspList[i].ZLast = 0
        return phspList

    def SavePhspAll(self):    #将所有进程的粒子相空间信息进行整合
        self.FileName = self.FileName.split('.')[0] + ".egsphsp1"
        self.headtype = 'iifff'   #相空间文件Header 的数据类型
        #self.datatype = 'iffffff'  #相空间文件粒子的数据类型
        self.Nothing = b'\x00\x00\x00'  #Head信息与粒子信息之间的间隔
        #NPPHSP = len(phspList)  #获取粒子总数量
        global NPPHSP, NPHOTPHSP, EKMAXPHSP, EKMINPHSPE
        with open(self.FileName, 'wb') as fout:   #打开总相空间文件
            fout.write(b'MODE0')   #写入MODE信息
            phspHead = struct.pack(self.headtype, NPPHSP, NPHOTPHSP, EKMAXPHSP, EKMINPHSPE, self.NINCPHSP)
            fout.write(phspHead)  #写入Head信息
            fout.write(self.Nothing)  #写入Head信息与粒子信息之间的间隔
            for i in range(self.LoopNum):
                self.FinName = self.FileName.split('.')[0] + "_" + str(i) + ".egsphsp1"
                with open(self.FinName, 'rb') as fin:  #打开每一个进程的粒子相空间信息
                    singleHead = fin.read(4*4)
                    npphsp, nphotphsp, ekmaxphsp, ekminphspe = struct.unpack('iiff', singleHead)
                    NPPHSP += npphsp
                    NPHOTPHSP += nphotphsp
                    EKMAXPHSP = max(EKMAXPHSP, ekmaxphsp)
                    EKMINPHSPE = min(EKMINPHSPE, ekminphspe)
                    data = fin.read()
                    fout.write(data)
                fin.close()
        fout.close()
        with open(self.FileName, 'rb+') as fout:
            fout.seek(5)
            phspHead = struct.pack(self.headtype, NPPHSP, NPHOTPHSP, EKMAXPHSP, EKMINPHSPE, self.NINCPHSP)
            fout.write(phspHead)  # 写入Head信息
        fout.close()

    def SavePhspProcess(self,phspList, i):   #将当前进程的粒子相空间信息保存为二进制文件
        self.FileName = self.FileName.split('.')[0] + "_" + str(i) + ".egsphsp1"
        self.datatype = 'iffffff'  # 相空间文件粒子的数据类型
        self.headtype = 'iiff'  # 相空间文件Header 的数据类型
        global NPPHSP, NPHOTPHSP, EKMAXPHSP, EKMINPHSPE
        NPPHSP = len(phspList)  # 获取粒子总数量
        with open(self.FileName, 'wb') as fout:     #打开每一个进程的粒子相空间信息
            phspHead = struct.pack(self.headtype, NPPHSP, NPHOTPHSP, EKMAXPHSP, EKMINPHSPE)
            fout.write(phspHead)  # 写入Head信息
            for i in range(len(phspList)):
                self.binData = struct.pack(self.datatype, phspList[i].LATCH, phspList[i].Energy, phspList[i].X, phspList[i].Y, phspList[i].U, phspList[i].V, phspList[i].WT)
                fout.write(self.binData)
        fout.close()

class EnergyMap:
    def __init__(self, XSize = 512, YSize = 512, XMax = 20.48, XMin = -20.48, YMax = 20.48, YMin = -20.48):
        self.XSize = XSize
        self.YSize = YSize
        self.XMax = XMax
        self.XMin = XMin
        self.YMax = YMax
        self.YMin = YMin
        self.XRes = (self.XMax - self.XMin) / self.XSize
        self.YRes = (self.YMax - self.YMin) / self.YSize
        self.Fluence = np.zeros([self.XSize, self.YSize])
        self.EnergyFluence = np.zeros([self.XSize, self.YSize])
        self.Response = np.zeros([self.XSize, self.YSize])
        self.ipo3 = 0
        self.Statistics = 0
        self.EnergyResponse(r"E:\工作文档\资料\EGS\DetectorResponse.txt")

    def Deposite(self, p):
        if not isinstance(p, PhspVector):
            print("Unexpected input type.")
            return
        if self.XMin < p.X < self.XMax and self.YMin < p.Y < self.YMax:
            xbin = math.ceil((p.X - self.XMin) / self.XRes) - 1
            ybin = math.ceil((p.Y - self.YMin) / self.YRes) - 1
            Response = self.InterPolate(p.Energy)
            self.Fluence[xbin, ybin] = self.Fluence[xbin, ybin] + p.WT
            self.EnergyFluence[xbin, ybin] = self.EnergyFluence[xbin, ybin] + p.WT*p.Energy
            self.Response[xbin, ybin] = self.Response[xbin, ybin] + p.WT*Response
            self.Statistics = self.Statistics+p.WT
            # self.Fluence[xbin, ybin] = self.Fluence[xbin, ybin] + 1
            # self.EnergyFluence[xbin, ybin] = self.EnergyFluence[xbin, ybin] + p.Energy
            # self.Response[xbin, ybin] = self.Response[xbin, ybin] + Response
            # self.Statistics = self.Statistics+1

    def EnergyResponse(self, path):
        data = np.loadtxt(path)
        self.ipo3 = spi.splrep(data[:, 0], data[:, 1], k=3)

    def InterPolate(self, x):
        y = spi.splev(x, self.ipo3)
        return y

    def Show(self):
        # plt.figure(figsize=(12, 9))
        plt.matshow(self.Fluence)
        plt.title(''.join(['Fluence Statictics: ', str(self.Statistics)]))
        plt.matshow(self.EnergyFluence)
        plt.title(''.join(['EnergyFluence Statictics: ', str(self.Statistics)]))
        plt.matshow(self.Response)
        plt.title(''.join(['Response Statictics: ', str(self.Statistics)]))

    def Save(self, path):
        with open(path+"_Fluence.dat", 'wb') as fout:
            for i in range(self.XSize):
                for j in range(self.YSize):
                    bytes=struct.pack('f', self.Fluence[i, j])
                    fout.write(bytes)
        with open(path+"_EnergyFluence.dat", 'wb') as eout:
            for i in range(self.XSize):
                for j in range(self.YSize):
                    bytes=struct.pack('f', self.EnergyFluence[i, j])
                    eout.write(bytes)
        with open(path+"_Response.dat", 'wb') as rout:
            for i in range(self.XSize):
                for j in range(self.YSize):
                    bytes=struct.pack('f', self.Response[i, j])
                    rout.write(bytes)

class EnergyFluence:
    def __init__(self, nbin, Rmax, binshape='circle'):
        self.nbin = nbin
        self.Rmax = Rmax
        self.Rstep = 0
        self.x = []
        self.y = []
        self.yfin = np.zeros(self.nbin)
        self.ynum = []
        self.reset()

    def reset(self):
        self.Rstep = self.Rmax / math.sqrt(nbin)
        self.x = [(math.sqrt(i + 1)) * self.Rstep for i in range(self.nbin)]
        self.y = [0 for i in range(self.nbin)]
        self.yfin = np.zeros(self.nbin)
        self.ynum = [0 for i in range(self.nbin)]

    def accumulate(self, x, y):
        if 0 < x < self.Rmax:
            xbin = math.ceil((x/self.Rstep)**2) - 1
            # xbin = math.ceil(x * self.nbin / self.Rmax) - 1
            self.y[xbin] = self.y[xbin] + y
            self.ynum[xbin] = self.ynum[xbin]+1

    def show(self):
        plt.figure(figsize=(12, 9))
        self.yfin = [self.y[i]/(math.pi * self.Rstep**2) for i in range(self.nbin)]
        plt.plot(self.x, self.yfin)
        plt.xlabel("R/cm")
        plt.ylabel("Energy Fluence")
        plt.title("Energy Fluence vs Position")
        plt.show()

if __name__ == '__main__':
        # print("args:")
        # for n, arg in enumerate(sys.argv):
        #     print("NO.{:2d} arg: {:}".format(n, arg))
        # del n, arg
        # if len(sys.argv) == 2 and os.path.isfile(sys.argv[1]):
        #     P = Phsp(sys.argv[1])
        #     P.TotalLoop()
        # elif not os.path.isfile(sys.argv[1]):
        #     print("File doesn't exist.")

        path_phsp = "/home/uih/Head/Source21/IBL_FS27_UpHead_PE2.6/Source21_Phant_FS27.egsphsp1"
        path_header = "/home/uih/Head/Source21/IBL_FS27_UpHead_PE2.6/Source21_Phant_FS27.IAEAheader"
        ph = Phsp(path_phsp, path_header)
        ph.TotalLoop()
        # thread_1 = threading.Thread(target = ph.TotalLoop())
        # thread_2 = threading.Thread(target = ph.TotalLoop())
        #ph.TranserEPID(phspList)
        #ph.SavePhsp(phspList)


#!/usr/bin/python

import numpy as np
from keras.models import Sequential
from keras.optimizers import SGD,Adam,RMSprop
from keras.layers import Dense, Dropout, LeakyReLU, AlphaDropout
import mvasup

filename = '../MVA_Data/data/training_1l_8ji3bi.csv'
output_model_name = '../MVA_Data/weights/model_1l_8ji3bi_0.h5'
output_weights_name = '../MVA_Data/weights/weights_1l_8ji3bi_0.h5'
output_file_name = '../MVA_Data/output_1l_8ji3bi_0.root'
selected_variable = list(range(1,18))
njet = 8
nbtag = 3

print ("\nReading file..")
f = open(filename)
header = f.readline()
variable_names = np.array(header.split(','))[selected_variable]
dataset = np.loadtxt(filename, delimiter=',', skiprows=1, converters={31: lambda x:int(x=='s'.encode('utf-8')) })
print ("Completed..\n")

variable_size = len(selected_variable)

X = np.array([x[selected_variable] for x in dataset if x[3]>=njet and x[4]>=nbtag and x[18]>=0])
Y = np.array([x[19:31] for x in dataset if x[3]>=njet and x[4]>=nbtag and x[18]>=0])
label = np.array([x[31] for x in dataset if x[3]>=njet and x[4]>=nbtag and x[18]>=0])
W = np.array([x[18] for x in dataset if x[3]>=njet and x[4]>=nbtag and x[18]>=0])

sample_size = len(X)
train_size = int(sample_size/2)

Xor_train, Xor_test = np.copy(X[:train_size, :]), np.copy(X[train_size:, :])
Wor_train, Wor_test = np.copy(W[:train_size]), np.copy(W[train_size:])

print ("Normalizing Inputs----------------------------------------")
norm=mvasup.Norm('strd_1l_8ji3bi','norm/')
X=norm.Standardization(X,variable_names)
print ("End of Normalization--------------------------------------\n")

print ("Splitting data")
X_train, X_test = X[:train_size, :], X[train_size:, :]
Y_train, Y_test = Y[:train_size], Y[train_size:]
W_train, W_test = W[:train_size], W[train_size:]
label_train, label_test = label[:train_size], label[train_size:]

sum_wpos = sum( W_train[i] for i in range(len(label_train)) if label_train[i] == 1.0  )
sum_wneg = sum( W_train[i] for i in range(len(label_train)) if label_train[i] == 0.0  )

for i in range(len(W_train)):
    if (label_train[i]==1.0):
        W_train[i] = W_train[i] * (0.5/sum_wpos)
    else:
        W_train[i] = W_train[i] * (0.5/sum_wneg)

W_train_av = sum(W_train)/len(W_train)
W_test_av = sum(W_train)/len(W_train)

print ('Weights average',W_train_av,W_test_av)

W_train = W_train/W_train_av
W_test = W_test/W_test_av

sum_wpos_check = sum( W_train[i] for i in range(len(label_train)) if label_train[i] == 1.0  )
sum_wneg_check = sum( W_train[i] for i in range(len(label_train)) if label_train[i] == 0.0  )

# print weight statistics
print ('weight statistics: wpos=%g, wneg=%g, ratio=%g' % ( sum_wpos_check, sum_wneg_check, sum_wneg_check/sum_wpos_check ))

# define the keras model
model = Sequential()
model.add(Dense(256, input_dim=variable_size, activation='selu', kernel_initializer='lecun_normal'))
model.add(AlphaDropout(0.4))
model.add(Dense(256, activation='selu', kernel_initializer='lecun_normal'))
model.add(AlphaDropout(0.3))
model.add(Dense(256, activation='selu', kernel_initializer='lecun_normal'))
model.add(AlphaDropout(0.3))
model.add(Dense(1, activation='sigmoid'))
# compile the keras model
#opt = SGD(lr=0.1, momentum=0.9)
#opt = RMSprop(learning_rate=0.001, rho=0.9)
opt = Adam(learning_rate=1e-03, beta_1=0.9, beta_2=0.999, amsgrad=False)
model.compile(loss='binary_crossentropy', optimizer=opt, metrics=['accuracy'])
# fit the keras model on the dataset
model.fit(X_train, label_train, sample_weight = W_train, validation_data=(X_test, label_test), epochs=42, batch_size=256, shuffle=True)
# evaluate the keras model
_, accuracy = model.evaluate(X, label)
print('Accuracy: %.2f' % (accuracy*100))
model.save(output_model_name)
model.save_weights(output_weights_name)

print ("Storing into NTuple---------------------------------------\n")
Ypred_train = model.predict( X_train )
Ypred_test = model.predict( X_test )

from ROOT import TFile, TTree
from array import array

class_id = array('i', [ 0 ] )
variables = variable_size*[0]
for i in range(variable_size):
    variables[i] = array('f', [ 0. ] )
weight = array('f', [ 0. ] )
score = array('f', [ 0. ] )

f = TFile(output_file_name,'recreate')
t1 = TTree('TestTree','Tree for Test Data')
t2 = TTree('TrainTree','Tree for Training Data')

variable_names=mvasup.CorrectNames(variable_names)

t1.Branch('class_id',class_id,'class_id/I')
for i in range(variable_size):
    t1.Branch(variable_names[i],variables[i],variable_names[i]+'/F')
t1.Branch('weight',weight,'weight/F')
t1.Branch('score',score,'score/F')

t2.Branch('class_id',class_id,'class_id/I')
for i in range(variable_size):
    t2.Branch(variable_names[i],variables[i],variable_names[i]+'/F')
t2.Branch('weight',weight,'weight/F')
t2.Branch('score',score,'score/F')

for i in range(len(label_test)):
    class_id[0] = int(label_test[i])
    for j in range(variable_size):
        variables[j][0] = Xor_test[i][j]
    weight[0] = Wor_test[i]
    score[0] = Ypred_test[i]
    t1.Fill()

for i in range(len(label_train)):
    class_id[0] = int(label_train[i])
    for j in range(variable_size):
        variables[j][0] = Xor_train[i][j]
    weight[0] = Wor_train[i]
    score[0] = Ypred_train[i]
    t2.Fill()

t1.Write()
t2.Write()

f.Write()
f.Close()

print ("Storing the data has been done..------------------------")


from matplotlib import pyplot as plt
import numpy as np

class MatplotlibBar(object):
    """柱状图"""
    def __init__(self):
        super(MatplotlibBar, self).__init__()
        self.n = 12
        self.X = np.arange(self.n)
        self.Y1 = (1 - self.X / float(self.n)) * np.random.uniform(0.5, 1.0, self.n)
        self.Y2 = (1 - self.X / float(self.n)) * np.random.uniform(0.5, 1.0, self.n)

    def generate_figure(self):
        plt.xlim(-.5, self.n)
        plt.ylim(-1.25, 1.25)

        plt.xticks(())
        plt.yticks(())

        # 绘制柱状图
        plt.bar(self.X, +self.Y1, facecolor='#9999ff', edgecolor='white')
        plt.bar(self.X, -self.Y2, facecolor='#ff9999', edgecolor='white')

        # 在柱状图的顶/底部添加对应数字标签
        # ha - horizotal alignment; va - vertical alignment
        for x, y in zip(self.X, self.Y1):
            plt.text(x, y, '%.2f' % y, ha='center', va='bottom')
        for x, y in zip(self.X, self.Y2):
            plt.text(x, -(y), '%.2f' % y, ha='center', va='top')

        plt.show()

if __name__ == "__main__":
    mb = MatplotlibBar()
    mb.generate_figure()


#!/usr/bin/env python3

import sys
import hashlib
import requests
import json
import time
import argparse

# Parse command line arguments
parser = argparse.ArgumentParser(description='Retrieve the NOC list from BADSEC server.')
parser.add_argument('--base_url', default='http://localhost:8888', help='The base URL of the BADSEC server')
parser.add_argument('--max_retries', type=int, default=2, help='The maximum number of retries for each request')

args = parser.parse_args()

BASE_URL = args.base_url
MAX_RETRIES = args.max_retries

HEADERS = {
    'User-Agent': 'BADSEC-Agent',
}
####Function to request token from server####
def get_auth_token():

    for i in range(MAX_RETRIES + 1):
        try:
            response = requests.get(f'{BASE_URL}/auth', headers=HEADERS)
            #if response is not 200, raise exception
            response.raise_for_status()
            return response.headers['Badsec-Authentication-Token']

        except requests.exceptions.RequestException:
            #wait 1 second before retrying
            time.sleep(1)
    return None

####Function to request user list from server####
def get_users(token):

    ### Calculate checksum and add to header to request user list
    checksum = hashlib.sha256((token + '/users').encode()).hexdigest()

    HEADERS['X-Request-Checksum'] = checksum

    for r in range(MAX_RETRIES + 1):
        # loopcontrol = r
        # print("retry number {} ".format(loopcontrol) + 'of ' + str(MAX_RETRIES))
        try:
            response = requests.get(f'{BASE_URL}/users', headers=HEADERS)
            response.raise_for_status()

            return response.text.split('\n')
        except requests.exceptions.RequestException:
            #wait 1 second before retrying
            time.sleep(1)
    return None

def main():
    ###1. call /auth endpoint to get an authentication token
    token = get_auth_token()
    if not token:
        print("Failed to authenticate.", file=sys.stderr)
        exit(1)
    ###2. Request user list from server
    users = get_users(token)
    if not users:
        print("Failed to retrieve user list.", file=sys.stderr)
        exit(1)

    print(json.dumps(users))

if __name__ == '__main__':
    main()


import operator
from typing import Dict
import torch
import torchvision
from torch import nn, optim
from .ebgan import EBGANGenerator, EBGANDiscriminator
from datasets.img_popular import MNISTLoaderMaker
from base_trainer import NetworkTrainer, ModelInfo, TrainStage

class EBGANTrainer(NetworkTrainer):
    """
    Trainer for Energy Based GAN.
    """
    def __init__(self, config: dict):
        print('Configuration')
        print(config)

        self.latent_dim = config['latent_dim']
        self.batch_size = config['batch_size']
        self.total_epoch = config['epoch']
        self.display_imgs = config['display_imgs']
        self.margin = 10  # "the margin is fixed to 10 and not being tuned"

        # create data loader maker
        loader_maker = MNISTLoaderMaker(
            data_root='data_in', batch_size=self.batch_size, naive_normalization=True)
        self.img_dim = loader_maker.dim

        generator = EBGANGenerator(latent_dim=self.latent_dim)
        discriminator = EBGANDiscriminator()

        models = {
            'EBGAN_G': ModelInfo(
                model=generator,
                input_size=(self.latent_dim, ),
                metric='loss_g',
                comparison=operator.lt
            ),
            'EBGAN_D': ModelInfo(
                model=discriminator,
                input_size=(1, self.img_dim, self.img_dim),
                metric='loss_d',
            ),
        }

        # create criteria
        criteria = {
            'mseloss': nn.MSELoss(),
        }

        # create optimizers
        self.lr_init = config['lr_init']
        optimizers = {
            'optimizer_g': optim.Adam(
                generator.parameters(), lr=self.lr_init, betas=(0.5, 0.999)),
            'optimizer_d': optim.Adam(
                discriminator.parameters(), lr=self.lr_init, betas=(0.5, 0.999)),
        }

        # create the trainer instance
        super().__init__(
            models, loader_maker, criteria, optimizers,
            epoch=self.total_epoch, num_devices=2)

        self.epoch = 0

    def run_step(self,
                 model: Dict[str, ModelInfo],
                 criteria,
                 optimizer,
                 input_,
                 train_stage: TrainStage,
                 *args, **kwargs):
        imgs, _ = input_

        # parse models
        generator = model['EBGAN_G'].model
        discriminator = model['EBGAN_D'].model

        d_optim = optimizer['optimizer_d']
        g_optim = optimizer['optimizer_g']

        mse_loss = criteria['mseloss']

        ### Train D ###
        for _ in range(3):
            z = torch.randn(self.batch_size, self.latent_dim).to(self.device)
            margin_tensor = torch.Tensor([self.margin]).to(self.device)

            gen_imgs = generator(z).detach()
            reconst_real = discriminator(imgs)  # reconstructed img
            reconst_fake = discriminator(gen_imgs)

            # calculate the energy assigned == reconstruction loss of the 'autoencoder D'
            energy_real = mse_loss(reconst_real, imgs)
            energy_fake = mse_loss(reconst_fake, gen_imgs)

            d_loss = energy_real + (margin_tensor - energy_fake).clamp(min=0)

            if train_stage == TrainStage.TRAIN:
                d_optim.zero_grad()
                d_loss.backward()
                d_optim.step()

        ### Train G ###
        z = torch.randn(self.batch_size, self.latent_dim).to(self.device)

        gen_imgs = generator(z)
        reconst_fake_gen = discriminator(gen_imgs)
        g_loss = mse_loss(reconst_fake_gen, gen_imgs)  # energy assigned to fake images

        if train_stage == TrainStage.TRAIN:
            g_optim.zero_grad()
            g_loss.backward()
            g_optim.step()

        outputs = (gen_imgs, imgs, energy_real, energy_fake)
        loss = (d_loss, g_loss)
        return outputs, loss

    @staticmethod
    def make_performance_metric(input_, output, loss):
        energy_real = output[2]
        energy_fake = output[3]

        d_loss, g_loss = loss

        return {
            'd_loss': d_loss.item(),
            'g_loss': g_loss.item(),
            'energy_real': torch.mean(energy_real).item(),
            'energy_fake': torch.mean(energy_fake).item(),
        }

    def pre_epoch_finish(self, input_, output, metric_manager, train_stage: TrainStage):
        if train_stage == TrainStage.VALIDATE:
            gen_img = output[0]
            real_img = output[1]
            self.add_generated_image(
                gen_img, nrow=self.display_imgs, height=None, width=None, name='gen')
            self.add_generated_image(
                real_img, nrow=self.display_imgs, height=None, width=None, name='real')

    def add_generated_image(self, imgs, nrow, height, width, name: str):
        grid = torchvision.utils.make_grid(imgs[:nrow, :], nrow=nrow, normalize=True)
        self.writer.add_image('{}/{}'.format(self.epoch, name), grid, self.train_step)

if __name__ == '__main__':
    import json
    with open('ebgan/config.json', 'r') as configf:
        config = json.loads(configf.read())

    trainer = EBGANTrainer(config)
    trainer.fit()
    trainer.cleanup()


from hashlib import sha1
import requests
from time import time

class PodcastIndexAPI:
    def __init__(self, key: str, secret: str) -> None:
        self.API_KEY = key
        self.API_SECRET = secret
        self.BASE_URL = "https://api.podcastindex.org/api/1.0/"

    def get_podcast_by_title(self, title: str) -> dict | None:
        res: dict = self.request_builder("/search/byterm", {
            "q": title
        })
        if not res["status"]:
            print(f"Couldn't find {title}")
            return
        return res

    def get_feed_by_id(self, feed_id: str) -> dict | None:
        res: dict = self.request_builder("/podcasts/byfeedid", {
            "id": feed_id
        })

        if not res["status"]:
            print(f"Couldn't find {feed_id}")
            return None
        return res

    def get_episodes_by_id(self, feed_id: str, max: int = 100) -> dict | None:
        res: dict = self.request_builder("/episodes/byfeedid", {
            "id": feed_id,
            "max": max
        })

        if not res["status"]:
            print(f"Couldn't find {feed_id}")
            return None
        return res

    def request_builder(self, endpoint: str, query: dict) -> dict:
        epoch = str(int(time()))
        auth = sha1((self.API_KEY + self.API_SECRET + epoch).encode("utf-8")).hexdigest()
        headers = {
            "X-Auth-Key": self.API_KEY,
            "X-Auth-Date": epoch,
            "Authorization": auth
        }
        res: requests.Response = requests.get(self.BASE_URL + endpoint, params=query, headers=headers)
        try:
            json = res.json()
            return json
        except:
            print("Received Invalid Response!")
            return {}


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

from pymongo import MongoClient
import config

class CommentsDb():
    def __init__(self):
        super().__init__()
        self.__host = config.db_host
        self.__port = config.db_port

    def __get_connection(self):
        try:
            connection = MongoClient(self.__host, self.__port)
            return connection
        except Exception:
            print("exception when getting a connection")
            return False

    def get_a_database(self,db_name):
        con = self.__get_connection()
        try:
            db = con[db_name]
            return db
        except Exception:
            print("exception when getting a db")
            return False

    def get_a_collection(self,db,collection):
        col = db[collection]
        return col

    def insert_one(self,collection,doc):
        try:
            collection.insert_one(doc)
            return True
        except Exception:
            print("exception when inserting one doc")
            return False

    def find_one(self,collection,doc):
        try:
            result = collection.find_one(doc)
            return result
        except Exception:
            print("error when finding one doc")
            return False

    def find_many(self,collection):
        try:
            for re in collection.find():
                yield re
        except Exception:
            print("exception find one when finding many doc")
            yield False

    def del_many(self,collention,doc):
        try:
            res = collention.delete_many(doc)
            print("successfully delete %s docs in %s"%(res.deleted_count,collention))
            return res
        except Exception as e:
            print("exception delete one when deleting many doc in %s"%collention)
            print(e)
            return False


import numpy as np

import matplotlib.pyplot as plt

def dq_array(q_inrtl_to_bodyhat_list, q_inrtl_to_body_list):
    """Given a list of quaternions from the qEKF and a list from the sim
    which are aligned in time, return the error attitude (body to
    estimated body).

    Args:
        q_inrtl_to_bodyhat_list  list of quaternions from the filter
        q_inrtl_to_body_list     list of quaternions from the sim

    Returns:
        A 3xN matrix consisting of angle*axis attitude errors.
    """

    ary = []

    for ii,qIBh in enumerate(q_inrtl_to_bodyhat_list):
        qIB = q_inrtl_to_body_list[ii]

        ary.append( (qIBh * qIB.conjugated()).to_rotation_vector().reshape(3) )

    return np.vstack(ary).T

def plot_attitude_errors(sim, kf):
    """Plot the delta between the simulated and estimated attitude (the
    attitude error) over time.

    Args:
        sim   simulation
        kf    qEKF

    Returns:
        A tuple consisting of the figure and the axes.
    """
    fig, axes = plt.subplots(3, 1, sharex = True)

    dq = dq_array(kf.log['qIB'], sim.log['qIB'])

    for ii in range(0, 3):
        axes[ii].plot(sim.log['t'], dq[ii,:] * 180/np.pi, label='attitude error', alpha=0.6)
        axes[ii].plot(sim.log['t'],  kf.log['sigma'][ii,:] * 180/np.pi, alpha=0.6, label='1-sigma', c='k')
        axes[ii].plot(sim.log['t'], -kf.log['sigma'][ii,:] * 180/np.pi, alpha=0.6, c='k')

        axes[ii].grid(True)

    fig.suptitle("Estimation error: attitude")
    axes[0].legend()
    axes[0].set_ylabel('ex [d]')
    axes[1].set_ylabel('ey [d]')
    axes[2].set_ylabel('ez [d]')
    axes[2].set_xlabel("time [s]")

    return fig, axes

def plot_angular_velocity_measurement_check(sim, kf):
    """Plot the delta between the measurements received by the qEKF and
    those sent by the simulation over time (should be 0).

    Args:
        sim   simulation
        kf    qEKF

    Returns:
        A tuple consisting of the figure and the axes.

    """

    fig, axes = plt.subplots(3, 1, sharex = True)

    for ii in range(0, 3):
        axes[ii].plot(sim.log['t'], sim.log['wBI'][ii,:] - kf.log['wm'][ii,:], label='delta', alpha=0.6)
        #axes[ii].plot(kf.log['t'],  kf.log['wm'][ii,:],  label='qekf', alpha=0.6)
        axes[ii].grid(True)

    fig.suptitle("Angular velocity measurement difference")
    axes[0].set_ylabel('wx [r/s]')
    axes[1].set_ylabel('wy [r/s]')
    axes[2].set_ylabel('wz [r/s]')
    axes[2].set_xlabel("time [s]")

    return fig, axes

def add_bias_labels(fig, axes):
    axes[0].legend()
    axes[0].set_ylabel('bgx [r/s])')
    axes[1].set_ylabel('bgy [r/s])')
    axes[2].set_ylabel('bgz [r/s])')
    axes[2].set_xlabel("time [s]")

def plot_gyroscope_bias_errors(sim, kf):
    """Plot the delta between the simulated and estimated gyroscope bias
    over time.

    Args:
        sim   simulation
        kf    qEKF

    Returns:
        A tuple consisting of the figure and the axes.

    """
    fig, axes = plt.subplots(3, 1, sharex = True)

    for ii in range(0, 3):
        axes[ii].plot(sim.log['t'], sim.log['bg'][ii,:] - kf.log['bg'][ii,:], alpha=0.6)
        axes[ii].plot(sim.log['t'],  kf.log['sigma'][ii+3,:] * 180/np.pi, alpha=0.6, label='1-sigma', c='k')
        axes[ii].plot(sim.log['t'], -kf.log['sigma'][ii+3,:] * 180/np.pi, alpha=0.6, c='k')
        axes[ii].grid(True)

    fig.suptitle("Estimation error: gyroscope bias")
    add_bias_labels(fig, axes)

    return fig, axes

def plot_gyroscope_bias_check(sim, kf):
    """Plot the simulated and estimated gyroscope biases over time against
    one another.

    Args:
        sim   simulation
        kf    qEKF

    Returns:
        A tuple consisting of the figure and the axes.

    """

    fig, axes = plt.subplots(3, 1, sharex = True)

    for ii in range(0, 3):
        axes[ii].plot(sim.log['t'], sim.log['bg'][ii,:], alpha=0.6, label='sim')
        axes[ii].plot(sim.log['t'], kf.log['bg'][ii,:], alpha=0.6, label='qekf')

    fig.suptitle("Simulated versus estimated gyroscope bias")
    add_bias_labels(fig, axes)

    return fig, axes


from collections import Counter
import re

def findSafe(recipes):
    """
    Returns a list of all ingredients that definitely do not contain any
    allergens, and then a count of how many of those.
    """
    allIngredients = Counter()
    avoid = {}

    for ingredients, allergens in recipes:
        allIngredients += Counter(ingredients)
        for allergen in allergens:
            if allergen not in avoid:
                avoid[allergen] = set(ingredients)
            else:
                # Take the intersection with the current possibily dangerous
                # ingredients.
                avoid[allergen] = set(
                    ingredient
                    for ingredient in ingredients
                    if ingredient in avoid[allergen]
                )

    possiblyDangerous = set(
        ingredient
        for allergen in avoid
        for ingredient in avoid[allergen]
    )

    definitelySafe = [
        ingredient
        for ingredient in allIngredients
        if ingredient not in possiblyDangerous
    ]

    return definitelySafe, sum(
        allIngredients[ingredient]
        for ingredient in definitelySafe
    )

recipeRegex = re.compile(r"^((?:\w+ )+)\(contains ((?:\w+(?:, )?)+)\)$")

if __name__ == "__main__":
    recipes = []

    with open('./recipe-book.txt') as f:
        # with open('./example.txt') as f:
        for line in f:
            ingredientStr, allergenStr = recipeRegex.match(line).groups()
            recipes.append((
                ingredientStr.strip().split(' '),
                allergenStr.strip().split(', ')
            ))

    safe, result = findSafe(recipes)
    print(result)


import glob
import logging

import cv2
import numpy as np
import signatory
import torch
import yaml
from thop import clever_format, profile
from tqdm import tqdm

from augmentation.augmentation import Augmentation

def get_config(config_file_path="./config/config.yaml"):
    """
    该函数实现了从配置文件中读取配置参数的操作

    Args:
        config_file_path (str):配置文件(.yaml)的路径。 默认为'./config/config.yaml'。

    Returns:
        config (dict): 配置信息,调用方式为:config['lr']
    """
    file = open(config_file_path, "r", encoding="utf-8")
    file_data = file.read()
    file.close()
    config = yaml.load(file_data, Loader=yaml.FullLoader)
    return config

def statistic_mean_std(data_path="../tumor_seg/train_img/*.png"):
    """
    该函数用于统计数据集中所有训练图像(单通道)的均值和方差，用于进行图像预处理中的归一化

    Args:
        data_path (str): 数据集中所有图像的路径. 默认为'../tumor_seg/train_img/*.png'.

    Returns:
        mean (torch.tensor): 单通道图像的均值
        std (torch.tensor): 单通道图像的标准差
    """
    pic_list = glob.glob(data_path)
    # 统计所有图像的mean和std
    pic_sum = 0
    pic_sqrd_sum = 0
    pic_num = 0
    for item in tqdm(pic_list):
        pic = cv2.imread(item, 0).astype(np.float32)
        pic = torch.from_numpy(pic)
        pic_sum += torch.mean(pic, dim=[0, 1])
        pic_sqrd_sum += torch.mean(pic**2, dim=[0, 1])
        pic_num += 1
        print("{0}/{1}".format(pic_num, len(pic_list)))
    mean = pic_sum / pic_num
    std = (pic_sqrd_sum / pic_num - mean**2) ** 0.5
    return mean, std

# 日志函数
def get_logger(filename, verbosity=1, name=None):
    """
    日志函数,用于将输出信息记录到日志文件中.

    Args:
        filename (str): 日志文件路径,一般为log/时间/log.txt
        verbosity (int): 过滤掉该等级以下的信息. 默认为1.
        name (str): 可以是所要记录日志的模块名字. 默认是None.

    Returns:
        logger : 直接用于记录信息logger.info等
    """
    level_dict = {
        0: logging.DEBUG,
        1: logging.INFO,
        2: logging.WARNING,
        3: logging.ERROR,
        4: logging.CRITICAL,
    }
    formatter = logging.Formatter(
        "[%(asctime)s][%(filename)s][line:%(lineno)d][%(levelname)s] %(message)s"
    )
    logger = logging.getLogger(name)
    # 过滤掉debug信息
    logger.setLevel(level_dict[verbosity])
    fh = logging.FileHandler(filename, "w")
    fh.setFormatter(formatter)
    logger.addHandler(fh)
    sh = logging.StreamHandler()
    sh.setFormatter(formatter)
    logger.addHandler(sh)
    return logger

def show_image(train_img, pred, mask, cfg, name):
    """
    画出这一张图像,并将pred_mask和gt_mask覆在其上

    Args:
        train_img (np.ndarray[H,W,3]): 训练图像
        pred (np.ndarray[H,W]): 预测mask,二值图
        mask (np.ndarray[H,W]): 真实mask,二值图
        cfg (dict): config信息
        now (datetime): datetime获取的当前时间
        name (str): 图像的名字
    """
    pred_mask = pred * 255
    gt_mask = mask * 255
    Aug = Augmentation(cfg)
    train_img, gt_mask = Aug.anti_normalize(train_img, gt_mask)
    train_mask = np.dstack(
        (pred_mask, np.zeros([cfg["size"], cfg["size"]], dtype=np.uint8), gt_mask)
    )
    gt_res = cv2.addWeighted(train_img, 0.6, train_mask, 0.4, 0.9, dtype=cv2.CV_32FC3)
    cv2.imwrite(
        "{}/{}/{}".format(cfg["image_res_path"], cfg["now"], name.split("/")[-1]),
        gt_res,
    )

def show_batch_image(train_img, pred, mask, cfg, name):
    """
    画出这一个batch的所有图像,并将pred_mask和gt_mask覆在其上

    Args:
        train_img (torch.tensor[bs,3,H,W]): 训练图像
        pred (torch.tensor[bs,1,H,W]): 预测mask,二值图
        mask (torch.tensor[bs,1,H,W]): 真实mask,二值图
        now (datetime): datetime获取的当前时间
        name (List[bs]): 一批图像的名字
    """
    train_img = train_img.permute(0, 2, 3, 1).detach().cpu().numpy()
    pred = pred.detach().cpu().numpy().squeeze(1)
    mask = mask.detach().cpu().numpy().squeeze(1)
    for i in range(train_img.shape[0]):
        show_image(train_img[i], pred[i], mask[i], cfg, name[i])

def binarize(pred_mask, threshold=0.5):
    """
    将预测结果按照阈值进行二值化,大于阈值的为1,小于阈值的为0

    Args:
        pred_mask (torch.tensor): 网络的预测结果进行sigmoid的输出,代表每个像素是前景的概率值

    Returns:
        pred_mask (torch.tensor): 二值化的预测结果
    """
    pred_mask = (pred_mask >= threshold) + 0
    return pred_mask

def calculate_params(model, input_tensor):
    """
    Usage:
        Calculate Params and FLOPs via [THOP](https://github.com/Lyken17/pytorch-OpCounter)
    Necessarity:
        from thop import profile
        from thop import clever_format
    :param model:
    :param input_tensor:
    :return:
    """
    flops, params = profile(model, inputs=(input_tensor,))
    flops, params = clever_format([flops, params], "%.3f")
    print("[Statistics Information]\nFLOPs: {}\nParams: {}".format(flops, params))


import sqlite3
from nitter.items import Tweet
from scrapy.exporters import CsvItemExporter

class SqlitePipeline:
    # Name of the SQLite database
    def __init__(self):
        self.name = "tweets.db"
        self.conn = None
        self.cursor = None

    # Initialize the pipeline by creating the database connection and the table
    def open_spider(self, spider):
        self.conn = sqlite3.connect(self.name)
        self.cursor = self.conn.cursor()
        self.cursor.execute(
            """
            CREATE TABLE IF NOT EXISTS tweets (
                id INTEGER PRIMARY KEY,
                body TEXT,
                author TEXT,
                author_id TEXT,
                pubdate TEXT,
                url TEXT,
                item_id_in_source TEXT,
                shares INTEGER,
                source_name TEXT,
                source_description TEXT,
                source_url TEXT,
                source_id_in_source TEXT,
                source_country_id TEXT,
                language TEXT,
                extraction_method TEXT,
                stats TEXT
            )
        """
        )
        self.conn.commit()

    # Process the item and store it in the database
    def process_item(self, item, spider):
        if isinstance(item, Tweet):
            self.insert_db(item)
        return item

    # Insert the item into the database
    def insert_db(self, item):
        data = (
            item.get("body"),
            item.get("author"),
            item.get("author_id"),
            item.get("pubdate"),
            item.get("url"),
            item.get("item_id_in_source"),
            item.get("shares"),
            item.get("source_name"),
            item.get("source_description"),
            item.get("source_url"),
            item.get("source_id_in_source"),
            item.get("source_country_id"),
            item.get("language"),
            item.get("extraction_method"),
        )
        self.cursor.execute(
            """
            INSERT INTO tweets (
                body,
                author,
                author_id,
                pubdate,
                url,
                item_id_in_source,
                shares,
                source_name,
                source_description,
                source_url,
                source_id_in_source,
                source_country_id,
                language,
                extraction_method
            ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
        """,
            data,
        )
        self.conn.commit()

    # Close the database connection
    def close_spider(self, spider):
        self.conn.close()

class CsvPipeline:
    def __init__(self):
        self.file = open("tweets.csv", "wb")
        self.exporter = CsvItemExporter(self.file)
        self.exporter.start_exporting()

    def close_spider(self, spider):
        self.exporter.finish_exporting()
        self.file.close()

    def process_item(self, item, spider):
        if isinstance(item, Tweet):
            self.exporter.export_item(item)
        return item


import argparse
import os
import os.path as osp
import cv2
import numpy as np

from utils.humanseg_postprocess import postprocess, threshold_mask
import models
import transforms

def parse_args():
    parser = argparse.ArgumentParser(description='HumanSeg inference for video')
    parser.add_argument(
        '--model_dir',
        dest='model_dir',
        help='Model path for inference',
        type=str)
    parser.add_argument(
        '--video_path',
        dest='video_path',
        help=
        'Video path for inference, camera will be used if the path not existing',
        type=str,
        default=None)
    parser.add_argument(
        '--save_dir',
        dest='save_dir',
        help='The directory for saving the inference results',
        type=str,
        default='./output')
    parser.add_argument(
        "--image_shape",
        dest="image_shape",
        help="The image shape for net inputs.",
        nargs=2,
        default=[192, 192],
        type=int)

    return parser.parse_args()

def predict(img, model, test_transforms):
    model.arrange_transform(transforms=test_transforms, mode='test')
    img, im_info = test_transforms(img)
    img = np.expand_dims(img, axis=0)
    result = model.exe.run(
        model.test_prog,
        feed={'image': img},
        fetch_list=list(model.test_outputs.values()))
    score_map = result[1]
    score_map = np.squeeze(score_map, axis=0)
    score_map = np.transpose(score_map, (1, 2, 0))
    return score_map, im_info

def recover(img, im_info):
    keys = list(im_info.keys())
    for k in keys[::-1]:
        if k == 'shape_before_resize':
            h, w = im_info[k][0], im_info[k][1]
            img = cv2.resize(img, (w, h), cv2.INTER_LINEAR)
        elif k == 'shape_before_padding':
            h, w = im_info[k][0], im_info[k][1]
            img = img[0:h, 0:w]
    return img

def video_infer(args):
    resize_h = args.image_shape[1]
    resize_w = args.image_shape[0]

    test_transforms = transforms.Compose(
        [transforms.Resize((resize_w, resize_h)),
         transforms.Normalize()])
    model = models.load_model(args.model_dir)
    if not args.video_path:
        cap = cv2.VideoCapture(0)
    else:
        cap = cv2.VideoCapture(args.video_path)
    if not cap.isOpened():
        raise IOError("Error opening video stream or file, "
                      "--video_path whether existing: {}"
                      " or camera whether working".format(args.video_path))
        return

    width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
    height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))

    disflow = cv2.DISOpticalFlow_create(cv2.DISOPTICAL_FLOW_PRESET_ULTRAFAST)
    prev_gray = np.zeros((resize_h, resize_w), np.uint8)
    prev_cfd = np.zeros((resize_h, resize_w), np.float32)
    is_init = True

    fps = cap.get(cv2.CAP_PROP_FPS)
    if args.video_path:
        print('Please wait. It is computing......')
        # 用于保存预测结果视频
        if not osp.exists(args.save_dir):
            os.makedirs(args.save_dir)
        out = cv2.VideoWriter(
            osp.join(args.save_dir, 'result.avi'),
            cv2.VideoWriter_fourcc('M', 'J', 'P', 'G'), fps, (width, height))
        # 开始获取视频帧
        while cap.isOpened():
            ret, frame = cap.read()
            if ret:
                score_map, im_info = predict(frame, model, test_transforms)
                cur_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
                cur_gray = cv2.resize(cur_gray, (resize_w, resize_h))
                score_map = 255 * score_map[:, :, 1]
                optflow_map = postprocess(cur_gray, score_map, prev_gray, prev_cfd, \
                        disflow, is_init)
                prev_gray = cur_gray.copy()
                prev_cfd = optflow_map.copy()
                is_init = False
                optflow_map = cv2.GaussianBlur(optflow_map, (3, 3), 0)
                optflow_map = threshold_mask(
                    optflow_map, thresh_bg=0.2, thresh_fg=0.8)
                img_matting = np.repeat(
                    optflow_map[:, :, np.newaxis], 3, axis=2)
                img_matting = recover(img_matting, im_info)
                bg_im = np.ones_like(img_matting) * 255
                comb = (img_matting * frame + (1 - img_matting) * bg_im).astype(
                    np.uint8)
                out.write(comb)
            else:
                break
        cap.release()
        out.release()

    else:
        while cap.isOpened():
            ret, frame = cap.read()
            if ret:
                score_map, im_info = predict(frame, model, test_transforms)
                cur_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
                cur_gray = cv2.resize(cur_gray, (resize_w, resize_h))
                score_map = 255 * score_map[:, :, 1]
                optflow_map = postprocess(cur_gray, score_map, prev_gray, prev_cfd, \
                                          disflow, is_init)
                prev_gray = cur_gray.copy()
                prev_cfd = optflow_map.copy()
                is_init = False
                optflow_map = cv2.GaussianBlur(optflow_map, (3, 3), 0)
                optflow_map = threshold_mask(
                    optflow_map, thresh_bg=0.2, thresh_fg=0.8)
                img_matting = np.repeat(
                    optflow_map[:, :, np.newaxis], 3, axis=2)
                img_matting = recover(img_matting, im_info)
                bg_im = np.ones_like(img_matting) * 255
                comb = (img_matting * frame + (1 - img_matting) * bg_im).astype(
                    np.uint8)
                cv2.imshow('HumanSegmentation', comb)
                if cv2.waitKey(1) & 0xFF == ord('q'):
                    break
            else:
                break
        cap.release()

if __name__ == "__main__":
    args = parse_args()
    video_infer(args)


import re
from setuptools import setup, find_packages

def getVersion():
    """
    Retrieve the version number from the __init__ file
    """
    version = '0.0.0'
    with open('djvocab/__init__.py', 'r') as f:
        contents = f.read().strip()

    m = re.search(r"__version__ = '([\d\.]+)'", contents)
    if m:
        version = m.group(1)
    return version

setup (
    name="djvocab",
    version=getVersion(),
    author='Aaron Kitzmiller <aaron_kitzmiller@harvard.edu>',
    author_email='aaron_kitzmiller@harvard.edu',
    description='Vocabulary model that can be used by other models',
    license='LICENSE',
    include_package_data=True,
    url='https://github.com/harvardinformatics/djvocab',
    packages=find_packages(),
    long_description='Vocabulary model that can be used by other models',
    classifiers=[
        "Development Status :: 3 - Alpha",
        "Topic :: Utilities",
    ],
    install_requires = [
        'Django>3,<4',
    ],
)


import pygame as pyg
import os
import time
from random import randint

# constants for the screen
WIDTH = 960
HEIGHT = 540
BORDER = 20

# Background object contains the display, and draws and updates the animated background
# Animation derived from instructions from the Nutt.net pygame tutoral
class Background(pyg.sprite.Sprite):
    screen = pyg.display.set_mode((WIDTH, HEIGHT), pyg.HWSURFACE)

    def __init__(self):
        pyg.sprite.Sprite.__init__(self)
        # loading the background image - two copies, to allow it to scroll
        self.bg1 = pyg.image.load(os.path.join("images", "background.jpg")).convert()
        self.bg2 = pyg.image.load(os.path.join("images", "background.jpg")).convert()
        self.bg1_x = 0
        self.bg2_x = self.bg1.get_width()

    def update(self):
        # updating the background positions so it scrolls
        self.bg1_x -= 1
        self.bg2_x -= 1
        if self.bg1_x <= -(self.bg1.get_width()):
                self.bg1_x = self.bg2_x + self.bg2.get_width()
        if self.bg2_x <= -(self.bg2.get_width()):
                self.bg2_x = self.bg1_x + self.bg1.get_width()

    def draw(self):
        self.screen.blit(self.bg1, (self.bg1_x, 0))
        self.screen.blit(self.bg2, (self.bg2_x, 0))

class Player(pyg.sprite.Sprite):
    # loading the player sprite and getting it's dimensions
    sprite = pyg.image.load(os.path.join("images", "hero_side.png")).convert_alpha()
    ln = sprite.get_width()
    ht = sprite.get_height()
    # loading the images for the sprite with animated thrusters
    animated_sprite = [pyg.image.load(os.path.join("images", "hero_side1.png")).convert_alpha(),
                       pyg.image.load(os.path.join("images", "hero_side2.png")).convert_alpha(),
                       pyg.image.load(os.path.join("images", "hero_side3.png")).convert_alpha()]

    def __init__(self):
        # sprite stuff, setting image, rectangle and mask (for collision detection)
        pyg.sprite.Sprite.__init__(self)
        self.image = self.sprite
        self.rect = self.image.get_rect()
        self.col_mask = pyg.mask.from_surface(self.image)
        # flag to hide the player image when player is killed
        self.hidden = False
        self.hide_timer = pyg.time.get_ticks()
        # initialises starting position on the board.
        self.x_new = self.rect.x = BORDER
        self.y_new = self.rect.y = HEIGHT//2 - self.ht
        self.speed = 4
        # animation loop - as it increments up, different images of the sprite are drawn, resulting in animation
        self.animation_loop = 0
        # x-axis velocity, used to determine whether to animate thrusters
        self.x_vel = 0
        self.altering_name = False
        self.player_name = ''

    def move(self, x_dir, y_dir):
        # takes the direction of movement from the event handler, multiplies by speed
        if (x_dir != 0) and (y_dir != 0):
            # this modifies the speed if moving diagonally
            velocity = int(self.speed * 0.8)
        else:
            velocity = self.speed
        # this step is here for animation purposes - it flags whether to animate thrusters
        self.x_vel = x_dir
        self.x_new = self.rect.x + (x_dir * velocity)
        self.y_new = self.rect.y + (y_dir * velocity)

    def update(self):
        # checks if the new positions are in the play area, and updates if they are
        if (self.x_new > BORDER) and (self.x_new < (WIDTH//2)):
            self.rect.x = self.x_new
        if (self.y_new > BORDER) and (self.y_new < HEIGHT-BORDER-self.ht):
            self.rect.y = self.y_new
        # if the player gets killed, hidden flag is true - hides player image, and resets position to starting point
        if self.hidden and pyg.time.get_ticks() - self.hide_timer > 1000:
            self.hidden = False
            self.x_new = self.rect.x = BORDER
            self.y_new = self.rect.y = HEIGHT//2 - self.ht
        # if player moving backwards, draws ship without thrusters
        if self.x_vel < 0:
            self.image = self.sprite
        # otherwise draws animated ship, and increments through animation loop
        else:
            self.image = self.animated_sprite[self.animation_loop//3]
            self.animation_loop += 1
            # reseting animation loop as only has three images to cycle through
            if self.animation_loop >= 9:
                self.animation_loop = 0

    def hide(self):
        # hide the player temporarily when the player is killed
        self.hidden = True
        self.hide_timer = pyg.time.get_ticks()
        self.rect.center = (WIDTH / 2, HEIGHT + 200)

    # logic for getting the user's name for the highscore board
    def update_name(self, new_letter="", delete=0):
        if not delete:
            self.player_name += new_letter
        else:
            self.player_name = self.player_name[:-1]

class Bullet(pyg.sprite.Sprite):
    # loading the bullet sprite and getting it's dimensions
    sprite = pyg.image.load(os.path.join("images", "bullet.png")).convert_alpha()
    ln = sprite.get_width()
    ht = sprite.get_height()

    def __init__(self):
        pyg.sprite.Sprite.__init__(self)
        self.image = self.sprite
        self.rect = self.image.get_rect()
        # bullet velocity
        self.vx = 15

    def update(self):
        self.rect.x += self.vx

class Alien(pyg.sprite.Sprite):
    # loading the alien sprite and getting it's dimensions
    sprite = pyg.image.load(os.path.join("images", "enemy2.png")).convert_alpha()
    ln = sprite.get_width()
    ht = sprite.get_height()
    animated_sprite = [pyg.image.load(os.path.join("images", "enemy1.png")).convert_alpha(),
                       pyg.image.load(os.path.join("images", "enemy2.png")).convert_alpha(),
                       pyg.image.load(os.path.join("images", "enemy3.png")).convert_alpha()]
    shielded_sprite = [pyg.image.load(os.path.join("images", "shield1.png")).convert_alpha(),
                       pyg.image.load(os.path.join("images", "shield2.png")).convert_alpha(),
                       pyg.image.load(os.path.join("images", "shield3.png")).convert_alpha()]

    def __init__(self, main):
        # pass main to alien, so it can access the player position and add alien bullets to the groups
        self.main = main
        # the sprite stuff, to get its image, rectangle and mask (for collision detection)
        pyg.sprite.Sprite.__init__(self)
        self.image = self.sprite
        self.rect = self.image.get_rect()
        self.col_mask = pyg.mask.from_surface(self.image)
        # sets the alien's position on the right of the screen, at a random y coordinate
        self.rect.x = WIDTH + self.ln + randint(1, 100)
        self.rect.y = randint(BORDER, HEIGHT - BORDER - self.ht)
        # alien velocity
        self.vx = -2
        # fire rate - the SMALLER the number, the MORE OFTEN they fire
        self.fire_rate = 400
        self.firing_solution = 1
        self.animation_loop = 0
        self.kill_score = 20
        # hit points - determines whether shield is up or down (displays different image)
        self.hitpoints = 1

    def collide(self, sprite_group):
        # collision detection only for when spawning new aliens, so they don't overlap
        if pyg.sprite.spritecollide(self, sprite_group, False):
            self.rect.x += self.ln * randint(2, 5)
            self.collide(sprite_group)

    def shoot(self, rate):
        # aliens fire based on fire_rate, adds alien bullets to the groups
        if (randint(1, rate) == self.firing_solution) and (self.rect.x < WIDTH):
            albull = AlBullet(self.rect.x, (self.rect.y + self.ht//2))
            self.main.alienbullets.add(albull)
            self.main.all_sprites.add(albull)

    def animate(self):
        if self.hitpoints == 2:
            self.image = self.shielded_sprite[self.animation_loop // 3]
        else:
            self.image = self.animated_sprite[self.animation_loop // 3]
        self.animation_loop += 1
        # reseting animation loop as only has three images to cycle through
        if self.animation_loop >= 9:
            self.animation_loop = 0

    def update(self):
        self.animate()
        # moves across the screen to the left, and fires
        self.rect.x += self.vx
        self.shoot(self.fire_rate)

    def on_hit(self, main, damage):
        self.hitpoints -= damage
        if self.hitpoints <= 0:
            self.kill()
            main.score += self.kill_score
            main.sounds.boom.play()
            main.expl = Explosion(self.rect.center, 'lg')
            main.all_sprites.add(main.expl)
        else:
            main.sounds.ping.play()

class ShieldAlien(Alien):
    def __init__(self, main):
        Alien.__init__(self, main)
        self.hitpoints = 2

class SmartAlien(ShieldAlien):

    def __init__(self, main):
        ShieldAlien.__init__(self, main)
        # limit the distance across the smart alien moves, and sets y velocity
        self.width_limit = WIDTH*0.8
        self.vy = 1
        # smart aliens fire more often than regular aliens
        self.fire_rate = 75

    def update(self):
        self.animate()
        # moves to the position on the right of the screen
        if self.rect.x > self.width_limit:
            self.rect.x += self.vx
        # tracks player movement and shoots
        if self.rect.y + self.ht//2 < self.main.player.rect.y + self.main.player.ht//2:
            self.rect.y += self.vy
        elif self.rect.y + self.ht//2 > self.main.player.rect.y + self.main.player.ht//2:
            self.rect.y -= self.vy
        self.shoot(self.fire_rate)

class Boss(SmartAlien):
    sprite = pyg.image.load(os.path.join("images", "boss1.png")).convert_alpha()
    damaged = [pyg.image.load(os.path.join("images", "boss5.png")).convert_alpha(),
               pyg.image.load(os.path.join("images", "boss4.png")).convert_alpha(),
               pyg.image.load(os.path.join("images", "boss3.png")).convert_alpha(),
               pyg.image.load(os.path.join("images", "boss2.png")).convert_alpha(),
               pyg.image.load(os.path.join("images", "boss1.png")).convert_alpha()]
    ln = sprite.get_width()
    ht = sprite.get_height()
    def __init__(self, main):
        SmartAlien.__init__(self, main)
        self.hitpoints = 50
        self.fire_rate = 40
        self.kill_score = 1000
        self.width_limit = WIDTH - self.ln

    def animate(self):
        if self.hitpoints < 50:
            self.image = self.damaged[self.hitpoints//10]
        bar = pyg.Rect((WIDTH//2 - 100), (HEIGHT - 20), 200, 18)
        healthbar = pyg.Rect((WIDTH//2 - 100), (HEIGHT - 19), self.hitpoints*4, 16)
        pyg.draw.rect(Background.screen, pyg.Color("black"), bar)
        pyg.draw.rect(Background.screen, pyg.Color("red"), healthbar)

    def update(self):
        if self.hitpoints > 15:
            SmartAlien.update(self)
        else:
            self.animate()
            new_x = self.rect.x + self.vx
            new_y = self.rect.y + self.vy
            if (new_x < 0) or (new_x > WIDTH-self.ln):
                self.vx = -self.vx
            if (new_y + self.ht//2 < BORDER) or (new_y + self.ht//2 > HEIGHT-BORDER):
                self.vy = -self.vy
            self.rect.x = new_x
            self.rect.y = new_y

class AlBullet(Bullet):
    # inherits most stuff from bullet, but moves right to left, and is slower
    def __init__(self, x, y):
        Bullet.__init__(self)
        self.rect.x = x
        self.rect.y = y
        self.vx = -10

# This class was built from instructions given in the pygame tutorial by KidsCanCode.org
class Explosion(pyg.sprite.Sprite):
    def __init__(self, center, size):
        pyg.sprite.Sprite.__init__(self)
        self.size = size
        self.frame = 0
        self.last_update = pyg.time.get_ticks()
        self.frame_rate = 50
        self.explosion_anim = {}
        self.explosion_anim['lg'] = []
        self.explosion_anim['sm'] = []
        for i in range(1,6):
            filename = 'boom{}.png'.format(i)
            img = pyg.image.load(os.path.join("images", filename)).convert_alpha()
            img_lg = pyg.transform.scale(img, (100, 100))
            self.explosion_anim['lg'].append(img_lg)
            img_sm = pyg.transform.scale(img, (75, 75))
            self.explosion_anim['sm'].append(img_sm)
        self.image = self.explosion_anim[self.size][0]
        self.rect = self.image.get_rect()
        self.rect.center = center

    def update(self):
        now = pyg.time.get_ticks()
        if now - self.last_update > self.frame_rate:
            self.last_update = now
            self.frame += 1
            if self.frame == len(self.explosion_anim[self.size]):
                self.kill()
            else:
                center = self.rect.center
                self.image = self.explosion_anim[self.size][self.frame]
                self.rect = self.image.get_rect()
                self.rect.center = center

class PowerUp(pyg.sprite.Sprite):

    animated_life = [pyg.image.load(os.path.join("images", "hero_life.png")).convert_alpha(),
                     pyg.image.load(os.path.join("images", "hero_life1.png")).convert_alpha(),
                     pyg.image.load(os.path.join("images", "hero_life2.png")).convert_alpha()]

    animated_bombs = [pyg.image.load(os.path.join("images", "bomb1.png")).convert_alpha(),
                      pyg.image.load(os.path.join("images", "bomb2.png")).convert_alpha(),
                      pyg.image.load(os.path.join("images", "bomb3.png")).convert_alpha()]

    def __init__(self, main):
        self.main = main
        pyg.sprite.Sprite.__init__(self)
        self.spawned = False
        self.rewound = False
        self.powers_dict = {0: pyg.image.load(os.path.join("images", "1pixelimage.png")).convert_alpha(),
                            1: [self.animated_life, 93, 25, self.extra_life],
                            2: [self.animated_bombs, 58, 100, self.extra_bomb]}
        self.starttime = time.time()
        self.animation_loop = 0
        self.power_up = []
        self.spawn_pos = (0, 0)
        self.image = self.powers_dict[0]
        self.rect = self.image.get_rect()

    def update(self):
        if (time.time() - self.starttime)//1 == 3 and not self.spawned:
            # generate a random number between 1 and however many
            self.power_up = self.powers_dict[randint(1, 2)]
            self.image = self.power_up[0][0]
            self.rect = self.image.get_rect()
            self.rect.x = randint(BORDER, (WIDTH//2)-self.power_up[1])
            self.rect.y = randint(BORDER, HEIGHT-BORDER-self.power_up[2])
            self.spawned = True
        elif (time.time() - self.starttime)//1 == 10:
            self.starttime = time.time()
            self.image = self.powers_dict[0]
            self.rect.x = 0
            self.rect.y = 0
            self.spawned = False

        elif self.spawned:
            self.image = self.power_up[0][self.animation_loop // 3]
            self.animation_loop += 1
            if self.animation_loop >= 9:
                self.animation_loop -= 5
                self.rewound = True
            elif self.animation_loop >= 7 and self.rewound:
                self.animation_loop = 0
                self.rewound = False

    def extra_life(self):
        self.main.lives += 1

    def extra_bomb(self):
        self.main.bombs += 1


from datetime import datetime
from typing import Annotated

from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy import select, insert
from sqlalchemy.ext.asyncio import AsyncSession
from app.database.database import get_async_session

from app.database.models import courier, order
from app.schemas.couriers import *

router = APIRouter()

@router.post(
    "/couriers",
    status_code=status.HTTP_200_OK,
    response_model=ResponseCourierCreate
)
async def add_couriers_info(new_courier: CourierCreate, session: AsyncSession = Depends(get_async_session)):
    """
    Принимает на вход список в формате json с данными о курьерах и графиком их работы
    Курьеры различаются по типу: пеший, велокурьер и курьер на автомобиле
    Районы задаются целыми положительными числами
    График работы задается списком строк формата `HH:MM-HH:MM`
    """
    # try:
    response = ResponseCourierCreate(couriers=[])
    for cour in new_courier:
        for elem in list(cour)[1]:
            stmt = insert(courier).values(**elem.dict())
            await session.execute(stmt)
            await session.commit()
            stmt = select(courier).order_by(courier.c.courier_id.desc()).limit(1)
            result = await session.execute(stmt)
            dct = result.mappings().all()[0]
            courier_id = dct["courier_id"]
            courier_type = dct["courier_type"]
            regions = dct["regions"]
            working_hours = dct["working_hours"]
            response.couriers.append(ResponseCourierWithId(courier_id=courier_id, courier_type=courier_type,
                                                           regions=regions, working_hours=working_hours))
    return response
    # except Exception:
    #    raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST)

@router.get(
    "/couriers/{courier_id}",
    status_code=status.HTTP_200_OK
)
async def get_single_courier_info(courier_id: int, session: AsyncSession = Depends(get_async_session)):
    """
    Возвращает информацию о курьере
    """
    try:
        stmt = select(courier).where(courier.c.courier_id == courier_id)
        result = await session.execute(stmt)
        return result.mappings().all()[0]
    except IndexError:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND)
    except Exception:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST)

@router.get(
    "/couriers",
    status_code=status.HTTP_200_OK
)
async def get_all_couriers_info(offset: int = 0, limit: int = 1, session: AsyncSession = Depends(get_async_session)):
    """
    Принимает на вход поле offset и limit
    Возвращает информацию о всех курьерах
    """
    try:
        response = ResponseCourier(couriers=[], limit=limit, offset=offset)
        stmt = select(courier).limit(limit).offset(offset)
        result = await session.execute(stmt)
        for elem in result.mappings().all():
            response.couriers.append(elem)
        return response
    except Exception:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST)

@router.get(
    "/couriers/meta-info/{courier_id}",
    status_code=status.HTTP_200_OK
)
async def get_courier_salary_rating(start_date: Annotated[str, Query(description='Дата вида 23-01-20')],
                                    end_date: Annotated[str, Query(description='Дата вида 23-01-20')],
                                    courier_id: int,
                                    session: AsyncSession = Depends(get_async_session)):
    try:
        start_date = datetime.strptime(start_date, "%y-%m-%d")
        end_date = datetime.strptime(end_date, "%y-%m-%d")
        if start_date >= end_date:
            raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST,
                                detail="end_date не может быть меньше, чем start_date")
        coefficient_salary = {"FOOT": 2,
                              "BIKE": 3,
                              "AUTO": 4}
        coefficient_rating = {"FOOT": 3,
                              "BIKE": 2,
                              "AUTO": 1}
        rating = None
        earnings = 0
        val_orders = 0
        stmt = select(courier).where(courier.c.courier_id == courier_id)
        iid, courier_type, regions, working_hours = (await session.execute(stmt)).mappings().all()[0].values()
        print(courier_type)
        stmt = select(order.c.cost, order.c.completed_time, order.c.courier_delivers_id). \
            select_from(order) \
            .where(order.c.courier_delivers_id == courier_id)
        result = await session.execute(stmt)
        for elem_list in result.all():
            order_info_list = list(elem_list)
            print(order_info_list)
            if order_info_list[1] is not None and (start_date <= order_info_list[1] < end_date):
                earnings += order_info_list[0] * coefficient_salary[courier_type]
            if order_info_list[1] is not None and (start_date <= order_info_list[1] <= end_date):
                val_orders += 1
                rating = (val_orders // int((end_date - start_date).days) * 24) * coefficient_rating[courier_type]
        return RequestMetaInfo(courier_id=courier_id, courier_type=courier_type, regions=regions,
                               working_hours=working_hours, earnings=earnings, rating=rating)
    except (ValueError, TypeError):
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST,
                            detail="Проверьте введенную дату")
    except Exception:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST)


from bottle import route
from bottle import run
from bottle import HTTPError
from bottle import request

import album

class AlbumError(Exception):
    """
    Используется для идентификации некорректных параметров Альбомов для добавления
    """
    pass

def make_russian(n):
    last_digit = n % 10
    last_two = n % 100
    if last_digit == 1 and last_two != 11:
        ending = "альбом"
    elif last_digit in [2, 3, 4] and not (last_two in [12, 13, 14]):
        ending = "альбома"
    else:
        ending = "альбомов"
    return str(n) + " " + ending

@route("/albums/<artist>")
def albums(artist):
    albums_list = album.find(artist)
    if not albums_list:
        message = "Альбомов {} не найдено".format(artist)
        result = HTTPError(404, message)
    else:
        album_names = [album.album for album in albums_list]
        num_albums = len(album_names)
        str_albums = make_russian(num_albums)
        result = "У исполнителя {} {}:
".format(artist, str_albums)
        result += "
".join(album_names)
    return result

@route("/albums", method="POST")
def albums():
    album_data = {
        "year":request.forms.year,
        "artist":request.forms.artist,
        "genre":request.forms.genre,
        "album":request.forms.album
    }
    if not int(album_data["year"]) or int(album_data["year"]) > 2020:
        raise AlbumError("Некорректно указан год")
    elif not isinstance(album_data["artist"], str):
        raise AlbumError("Исполнитель указан некорректно (не является строковым)")
    elif not isinstance(album_data["genre"], str):
        raise AlbumError("Жанр указан некорректно (не является строковым)")
    elif not isinstance(album_data["album"], str):
        raise AlbumError("Альбом указан некорректно (не является строковым)")
    elif album.check_album(album_data):
        message = "Альбом {} исполнителя {} уже есть в базе".format(album_data["album"], album_data["artist"])
        result = HTTPError(409, message)
    else:
        result = album.add_album(album_data)
    return result

if __name__ == "__main__":
    run(host="localhost", port=8080, debug=True)


import torch
import torch.nn as nn

class TinyAttention(nn.Module):
    def __init__(self, d_out, d_attn):
        super(TinyAttention, self).__init__()
        self.kqv = nn.Linear(d_out, 3*d_attn)
        if(d_attn != d_out):
            self.proj = nn.Linear(d_attn, d_out)
        else:
            self.proj = None

    def forward(self, x):
        kqv = self.kqv(x)
        key, query, value = kqv.chunk(3, dim=-1)
        soft = nn.Softmax(dim=-1)((query @ key.permute(0, 2, 1)) / torch.sqrt(torch.tensor(query.shape[-1]).float()))
        head = soft @ value
        if(self.proj is not None):
            head = self.proj(head)
        return head

class SpatialGatingUnit(nn.Module):
    def __init__(self, hidden_dim, len_seq, split, toeplitz, tn_attn, d_attn):
        super(SpatialGatingUnit, self).__init__()
        self.split = split
        if split:
            self.norm = nn.LayerNorm(hidden_dim // 2)
        else:
            self.norm = nn.LayerNorm(hidden_dim)

        self.len_seq = len_seq
        self.toeplitz = toeplitz
        if(toeplitz):
            zeros, ones = torch.zeros(2*len_seq - 1), torch.ones(len_seq)
            self.w_vector, self.bias = nn.Parameter(zeros), nn.Parameter(ones)
        else:
            self.proj = nn.Linear(len_seq, len_seq)
            torch.nn.init.zeros_(self.proj.weight)
            self.proj.bias.data.fill_(1)

        if(tn_attn):
            if split:
                self.tiny_attn = TinyAttention(hidden_dim//2, d_attn)
            else:
                self.tiny_attn = TinyAttention(hidden_dim, d_attn)
        else:
            self.tiny_attn = None

    def get_toeplitz(self):
        r = self.w_vector.shape[0] // 2
        t = torch.nn.functional.pad(self.w_vector, (0, self.len_seq), "constant", 0)
        t = t.repeat(self.len_seq)
        t = t[: -self.len_seq]
        t = torch.reshape(t, [self.len_seq, self.len_seq + self.w_vector.shape[0] - 1])
        return t[:, r:-r]

    def forward(self, x):
        if self.split:
            u, v = x.chunk(2, dim=-1)
        else:
            u, v = x, x

        if(self.tiny_attn is not None):
            head = self.tiny_attn(v)
        else:
            head = 0

        v = self.norm(v)
        v = v.permute(0, 2, 1)
        if(self.toeplitz):
            w_toeplitz = self.get_toeplitz()
            v = v @ w_toeplitz + self.bias
        else:
            v = self.proj(v)
        v = v.permute(0, 2, 1) + head
        return u * v

class MLP_BLock(nn.Module):
    def __init__(self, hidden_dim: int, shape, split, toeplitz, tn_attn, d_attn):
        super(MLP_BLock, self).__init__()
        self.proj_1 = nn.Sequential(
            nn.Linear(shape[1], hidden_dim, bias=False),
            nn.GELU()
        )
        if split:
            self.proj_2 = nn.Linear(hidden_dim // 2, shape[1])
        else:
            self.proj_2 = nn.Linear(hidden_dim, shape[1])

        self.sgu = SpatialGatingUnit(hidden_dim, shape[0], split, toeplitz, tn_attn, d_attn)

        self.norm = nn.LayerNorm(shape[1])
        self.norm1 = nn.LayerNorm(hidden_dim)

    def forward(self, x):
        out = self.norm(x)
        out = self.proj_1(out)
        out = self.sgu(out)
        out = self.proj_2(out)
        out = out + x
        return out

class MlpNN(nn.Module):
    """Mixer architecture."""
    def __init__(self, MLP_BLock, vocab_size, embed_dim, num_blocks, hidden_dim, len_seq, num_classes=2, split=True,
                toeplitz=False, tn_attn=False, d_attn=64):
        super(MlpNN, self).__init__()
        self.hidden_dim = hidden_dim # C
        self.len_seq = len_seq # S

        block_sequence = []
        for i in range(num_blocks):
            block_sequence.append(MLP_BLock(hidden_dim, (len_seq, embed_dim), split, toeplitz, tn_attn, d_attn))
        self.block_sequence = nn.Sequential(*block_sequence)

        self.fc = nn.Linear(embed_dim, num_classes)
        if(embed_dim != 768):
            self.proj = nn.Linear(768, embed_dim)
        else:
            self.proj = None
        self.norm = nn.LayerNorm(embed_dim)

    def forward(self, x):
        if (self.proj is not None):
            x = self.proj(x)
        x = self.block_sequence(x)
        x = self.norm(x)
        x = torch.mean(x, axis=1)
        x = self.fc(x)
        return x

def gMLP(vocab_size, embed_dim, num_blocks, hidden_dim, len_seq, split=True, toeplitz=False, tn_attn=False, d_attn=64):
    return MlpNN(MLP_BLock, vocab_size=vocab_size, embed_dim=embed_dim,
                 num_blocks=num_blocks, hidden_dim=hidden_dim, len_seq=len_seq, split=split,
                toeplitz=toeplitz, tn_attn=tn_attn, d_attn=d_attn)


from reportlab.lib import colors
from Bio.Graphics import GenomeDiagram
from Bio import SeqIO

# Recebendo o arquivo
arquivo = SeqIO.read("NC_017108.gbk", "genbank")

# Configuracoes basicas
gd_diagram = GenomeDiagram.Diagram("Marcadores")
gd_track_for_features = gd_diagram.new_track(1, name="Anotacoes")
gd_feature_set = gd_track_for_features.new_set()

# Imprime as features de maneira intercalada
for feature in arquivo.features:

	if feature.type == "rRNA":
		color = colors.blue
		gd_feature_set.add_feature(feature, color=color, label=True)

	elif feature.type == "tRNA":
		color = colors.green
		feature.qualifiers['locus_tag'] = feature.qualifiers['product']
		gd_feature_set.add_feature(feature, color=color, label=True)

	elif feature.type == "gene":

		if len(gd_feature_set) % 2 == 0:
			color = colors.HexColor('#BBBBBB')
		else:
			color = colors.HexColor('#DDDDDD')

		gd_feature_set.add_feature(feature, color=color, label=False)

	else:
		continue

# Desenhando
gd_diagram.draw(format="circular", circular=True, pagesize=(20*cm,20*cm),start=0, end=len(arquivo), circle_core=0.7)

# Salvand em 2 formatos: PDF e PNG
gd_diagram.write("completo.pdf", "PDF")
gd_diagram.write("completo.png", "PNG")


from maneuvers.jumps.speed_flip import SpeedFlip
from maneuvers.kickoffs.kickoff import Kickoff
from rlutilities.linear_algebra import norm
from rlutilities.simulation import Car
from tools.game_info import GameInfo
from tools.vector_math import local

class SpeedFlipKickoff(Kickoff):
    """
    Speedflip into the ball. Works only on corner kickoffs. It's useful only against slow kickoffs.
    """
    def __init__(self, car: Car, info: GameInfo):
        super().__init__(car, info)
        self.drive.target_pos = self.info.my_goal.center * 0.05

    def step(self, dt: float):
        car = self.car
        if self.phase == 1:
            if norm(car.velocity) > 1050:
                self.action = SpeedFlip(car, right_handed=local(car, self.info.ball.position)[1] < 0)
                self.phase = 2

        if self.phase == 2:
            if self.action.finished:
                self.finished = True

        super().step(dt)


#создай приложение для запоминания информации
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QHBoxLayout, QVBoxLayout, QMessageBox, QRadioButton, QLabel, QGroupBox, QButtonGroup
from random import shuffle
app = QApplication([])
window = QWidget()
print('hello')
class Question ():
    def __init__(self,question, right_ans, wrong1, wrong2, wrong3):
        self.question = question
        self.right_ans = right_ans
        self.wrong1 = wrong1
        self.wrong2 = wrong2
        self.wrong3 = wrong3

line2 = QVBoxLayout()
qu = QLabel('Какой национальности не существует?')
line2.addWidget(qu)

line1 = QHBoxLayout()
button = QPushButton('Ответить')
line1.addWidget(button)

group = QGroupBox('Варианты ответов')
btn1 = QRadioButton('Энцы')
btn2 = QRadioButton('Смурфы')
btn3 = QRadioButton('Чулымцы')
btn4 = QRadioButton('Алеуты')
ans1 = QHBoxLayout()
ans2 = QVBoxLayout()
ans3 = QVBoxLayout()

ans2.addWidget(btn1)
ans2.addWidget(btn2)
ans3.addWidget(btn3)
ans3.addWidget(btn4)

ans1.addLayout(ans2)
ans1.addLayout(ans3)
group.setLayout(ans1)

line3 = QVBoxLayout()
line3.addLayout(line2)
line3.addWidget(group)
ansgroup = QGroupBox('Результат теста')
t = QLabel('правильно/неправильно')
tans = QLabel('Правильный ответ')

line4 = QVBoxLayout()
line4.addWidget(t)
line4.addWidget(tans)
ansgroup.setLayout(line4)

RadioGroup = QButtonGroup()
RadioGroup.addButton(btn1)
RadioGroup.addButton(btn2)
RadioGroup.addButton(btn3)
RadioGroup.addButton(btn4)

line3.addWidget(ansgroup)
ansgroup.hide()
line3.addLayout(line1)

def show_question():
    group.show()
    ansgroup.hide()
    button.setText('Ответить')
    RadioGroup.setExclusive(False)
    btn1.setChecked(False)
    btn2.setChecked(False)
    btn3.setChecked(False)
    btn4.setChecked(False)
    RadioGroup.setExclusive(True)

def start_test():
    if button.text() == 'Ответить':
        check_answer()
    elif button.text() == 'Следующий вопрос':
        next_question()

def show_result():
    group.hide()
    ansgroup.show()
    button.setText('Следующий вопрос')

answers = [btn1, btn2, btn3, btn4,]

questions_list = []
questions_list.append(Question('Государственный язык Бразилии', 'Португальский', 'Испанский', 'Бразильский', 'Итальянский'))

def ask(q: Question):
    shuffle(answers)
    answers[0].setText(q.right_ans)
    answers[1].setText(q.wrong1)
    answers[2].setText(q.wrong2)
    answers[3].setText(q.wrong3)
    qu.setText(q.question)
    tans.setText(q.right_ans)
    show_question()

def show_corect(res):
    t.setText(res)
    show_result()

def check_answer():
    if answers[0].isChecked():
        show_corect('Правильно!')
    else:
        if answers[1].isChecked or answers[2].isChecked or answers[3].isChecked:
            show_corect('Неверно!')

def next_question():
    window.cur_q += 1
    if window.cur_q == len(questions_list):
        window.cur_q = 0
    ask(questions_list[window.cur_q])

button.clicked.connect(start_test)

window.cur_q = -1
next_question()
window.setLayout(line3)
window.show()
app.exec_()


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

#Cost function for the linear regression
def costFunction(theta,xs,y):
    J = 0.
    for i in range(1,len(y)):
        J = J + (1/(2*len(y)))*((np.dot(xs,theta)-y[i]))**2
        return J

#Function to get the proper values of theta using gradient descent algorithm
def gradientDescent(xs, y, theta, alpha, m, iterations):
    xTrans = xs.transpose()
    for i in range(0, iterations):
        hypothesis = np.dot(xs, theta)
        loss = hypothesis - y
        #cost = np.sum(loss ** 2) / (2 * m)
        #print("Iteration %d | Cost: %f" % (i, cost))
        gradient = np.dot(xTrans, loss) / m
        theta = theta - alpha * gradient
    return theta

#Plot a line for the given slope and intercept
def drawLine(slope, intercept):
    axes = mpl.gca()
    x_vals = np.array(axes.get_xlim())
    y_vals = intercept + slope * x_vals
    mpl.plot(x_vals, y_vals, 'g--')

#Implementation according to the mathematical model
train_data=pd.read_csv("train.csv")
xs=pd.DataFrame({'x0':1.,'x':train_data.X})
x=train_data.X.values
y=train_data.Y.values
mpl.plot(x,y,'rx')

theta=pd.DataFrame({'theta':[0.]*2})
thetaT=theta.T
numIterations= 10000
m, n = np.shape(xs)
alpha = 0.0005
theta = np.ones(n)
theta = gradientDescent(xs, y, theta, alpha, m, numIterations)

print(theta)
drawLine(theta[1],theta[0])

test_data=pd.read_csv("test.csv")
xstest=pd.DataFrame({'x0':1.,'x':test_data.X})
m, n = np.shape(xstest)
xtest=test_data.X.values
ytest=test_data.Y.values
ycompute=np.dot(xstest,theta)
loss=ycompute-ytest
print("Average error in the test data is %f"%np.mean(loss))


from flask import Flask, render_template, request, redirect, session

app = Flask(__name__)
app.secret_key = 'keep it secret, keep it safe' # set a secret key for security purposes

css_vars = {
}

@app.route('/')
def route_landing():
    if not "visit-count" in session:
        session["visit-count"] = 1
    else:
        session["visit-count"] += 1

    if not "count" in session:
        session["count"] = 1
        session["count-by"] = 1
    elif "cnt_by_2" in session:
        session.pop("cnt_by_2")
        session["count"] += 2
    else:
        session["count"] += int(session["count-by"])
    return render_template("index.html", css_vars=css_vars)

@app.route('/count', methods=['POST'])
def route_post_count():

    session["count-by"] = request.form["count-by"]

    if request.form["action"] == "count-by-two":
        session["cnt_by_2"] = ""
    elif request.form["action"] == "reset":
        session.clear()
    return redirect("/")

@app.route('/destroy_session')
def route_destroy():
    session.clear()
    return redirect("/")

@app.errorhandler(404)
def handle_404(ex):
    return "Sorry! No response. Try again."

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