import matplotlib.pyplot as plt
import numpy as np
import matplotlib.cm as cm
from matplotlib import colors
import random as rand

class IsingModel:
    '''a class to investigate the properties of the ising model'''
    def __init__(self, grid_type = 'square', dim = 10, J=[1], pbcs = True, Jrule = 'nn', temp=1, no_vacancies = 0, h = 0):

        self.grid_type = grid_type
        self.dim = dim
        self.pbcs = pbcs
        self.Jrule = Jrule #List of J values
        self.h = h #External Field

        self.neighbours = [] #List of neighbours

        #Below takes into account what type of grid it is and makes a list of nearest neighbours
        if Jrule == 'nn':
            if self.grid_type == 'BCC': #If you want a square lattice type square!
                self.BCC()
                self.num = 3

            if self.grid_type == 'square': #If you want a square lattice type square!
                self.create_square_grid()
                self.num = 2

            if self.grid_type == '1D': #If you want a 1D lattice
                self.create_1D_grid()
                self.num =1

            if self.grid_type == 'triangular': #If you want a triangular lattice
                self.create_triangular_grid()

            if self.grid_type == '3D': #If you want to be fancy and go 3d
                self.num = 3
                self.create_three_grid()

            #I created this self.num parameter as there was a wee bit of trouble in the code later on when working with 1d and 3d
            #It made life simpler to just define this function
            if self.grid_type != '3D' and self.grid_type != '1D' and self.grid_type != 'BCC':
                self.num = 2

        if Jrule == 'nnn' and self.grid_type == 'square': #next nearest neighbours
            self.extra_neighbours()
            self.num = 2

        if Jrule == 'nnn' and self.grid_type == 'BCC': #next nearest neighbours
            self.BCC()
            self.num = 3

        #Random Initial Moments are calculated
        self.init_moments = np.random.choice([-1, 1], self.X.shape) #Initial moments are calculated. They are randomised
        self.J = self.create_Jlist(J) #Creates list of J
        self.current_moments = np.copy(self.init_moments)
        self.magnetisation = self.current_moments.flatten().sum() #Calculates the magnetisation of the whole lattice
        self.maglist = [] #List for average magnetisation per site (will be used over range of temperatures)
        self.maglist.append(abs(self.magnetisation)/self.num_sites) #Calculates average magnetisation per site
        self.energy_list = []
        print(self.current_moments)
        self.current_energy =  self.grid_energy(self.current_moments) #Calculates the energy of the lattice
        self.energy_list.append(self.current_energy/self.num_sites) #Calculates the average energy per lattice site

        self.temp = temp #Temperature at which the Ising Model is investigated

    def reset(self):
        '''Resets the lattice, randomly giving each point a spin'''
        self.current_moments = np.random.choice([-1, 1], self.Y.shape)

    def extra_neighbours(self):
        '''Gives each point an additional neareat neighbours four neighbours'''
        x, y = np.linspace(0, self.dim-1, self.dim), np.linspace(0, self.dim-1, self.dim)
        X, Y = np.meshgrid(y, x)
        self.X, self.Y = X.flatten(), Y.flatten()
        self.num_sites = self.dim*self.dim

        for i, (x1, x2) in enumerate(zip(self.X, self.Y)):

            if self.pbcs == True:
                    templist = [[int((x1 - 1) % self.dim), x2] ,
                                [int((x1 + 1) % self.dim), x2] ,
                                [x1, int((x2 - 1) % self.dim) ],
                                [x1, int((x2 + 1) % self.dim)],
                                [int((x1 - 1) % self.dim), int((x2 - 1) % self.dim)] ,
                                [int((x1 + 1) % self.dim), int((x2 + 1) % self.dim)] ,
                                [int((x1 + 1) % self.dim),int((x2 - 1) % self.dim) ],
                                [int((x1 - 1) % self.dim), int((x2 + 1)%(self.dim))] ]
                    #print(templist)
                    reallist = [int(a[1]*self.dim + a[0]) for a in templist] #indices of nearest neighbour
                    self.neighbours.append(reallist)

    def create_1D_grid(self):
        '''Creates a square grid, which will then be used for the lattice investigated'''
        self.X = np.linspace(0, self.dim-1, self.dim)
        self.Y = np.zeros_like(self.X)
        self.num_sites = self.dim

        for i, (x1) in enumerate((self.X)):
            if self.pbcs == True:
                templist = [int((x1 - 1) % self.dim), int((x1 + 1) % self.dim) ]
                self.neighbours.append(templist)

    def BCC(self):
        '''creates a three dimensional lattice square lattice, also known as the simple cubic lattice'''
        x, y, z = np.linspace(0, (self.dim)-1, self.dim), np.linspace(0, (self.dim)-1, self.dim), np.linspace(0, (self.dim)-1, self.dim)
        X, Y, Z = np.meshgrid(y, x, z)
        self.X, self.Y, self.Z = X.flatten(), Y.flatten(), Z.flatten()
        self.num_sites = self.dim*self.dim*self.dim

        if self.Jrule == 'nn':

            for i, (x1, x2, x3) in enumerate(zip(self.X, self.Y, self.Z)):
                if self.pbcs == True:
                    templist = [[x1, x2, int((x3 - 1) % self.dim)] ,  #say atom on x1 plane
                                [x1, x2, int((x3 + 1) % self.dim)] ,
                                [x1, int((x2 + 1) % self.dim), int((x3 - 1) % self.dim)],
                                [x1, int((x2 + 1) % self.dim), int((x3 + 1) % self.dim)],
                                [int((x1 + 1) % self.dim), x2, int((x3 - 1) % self.dim)] ,  #say atom on x1 plane
                                [int((x1 + 1) % self.dim), x2, int((x3 + 1) % self.dim)] ,
                                [int((x1 + 1) % self.dim), int((x2 + 1) % self.dim), int((x3 - 1) % self.dim)],
                                [int((x1 + 1) % self.dim), int((x2 + 1) % self.dim), int((x3 + 1) % self.dim)]]

                    reallist = [int(a[0]*self.dim + a[1]*self.dim**2 + a[2]) for a in templist] #indices of nearest neighbour

                    self.neighbours.append(reallist)

        if self.Jrule == 'nnn':

            for i, (x1, x2, x3) in enumerate(zip(self.X, self.Y, self.Z)):
                if self.pbcs == True:
                    templist = [[x1, x2, int((x3 - 1) % self.dim)] ,  #say atom on x1 plane
                                [x1, x2, int((x3 + 1) % self.dim)] ,
                                [x1, int((x2 + 1) % self.dim), int((x3 - 1) % self.dim)],
                                [x1, int((x2 + 1) % self.dim), int((x3 + 1) % self.dim)],
                                [int((x1 + 1) % self.dim), x2, int((x3 - 1) % self.dim)] ,  #say atom on x1 plane
                                [int((x1 + 1) % self.dim), x2, int((x3 + 1) % self.dim)] ,
                                [int((x1 + 1) % self.dim), int((x2 + 1) % self.dim), int((x3 - 1) % self.dim)],
                                [int((x1 + 1) % self.dim), int((x2 + 1) % self.dim), int((x3 + 1) % self.dim)],
                                [x1, int((x2 + 1) % self.dim), x3], [x1, int((x2 - 1) % self.dim), x3],
                                [int((x1 + 1) % self.dim), x2, x3], [int((x1 - 1) % self.dim), x2, x3]]
                    #last four is next nearest neighbours

                    reallist = [int(a[0]*self.dim + a[1]*self.dim**2 + a[2]) for a in templist] #indices of nearest neighbour

                    self.neighbours.append(reallist)

    def create_square_grid(self):
        '''Creates a square grid, which will then be used for the lattice investigated. Non periodic boundary
        conditions can also be applied to the square grid lattice in this model'''
        x, y = np.linspace(0, self.dim-1, self.dim), np.linspace(0, self.dim-1, self.dim)
        X, Y = np.meshgrid(x, y)
        self.X, self.Y = X.flatten(), Y.flatten()
        self.num_sites = self.dim*self.dim

        for i, (x1, x2) in enumerate(zip(self.X, self.Y)):

            if self.pbcs == True:
                templist = [[int((x1 - 1) % self.dim), x2] , [int((x1 + 1) % self.dim), x2] , [x1,int((x2 - 1) % self.dim) ],
                            [x1, int((x2 + 1) % self.dim)] ]
                reallist = [int(a[1]*self.dim + a[0]) for a in templist]
                self.neighbours.append(reallist)

            elif self.pbcs == False: #This is when non periodic conditions are applied. Note that the number of neighbours is not equal
                templist = [[x1 - 1, x2] , [x1+1, x2] , [x1,x2-1],
                            [x1, x2+1] ] #list of the nearest neighbours
                ar = []
                for a in templist:

                    if a[0] >= 0 and a[1] >= 0 and a[0] < self.dim and a[1] < self.dim:
                        ar.append([a[0], a[1]])
                reallist = [int(c[1]*self.dim + c[0]) for c in ar]

                self.neighbours.append(reallist)

            elif self.pbcs == 'Cylindrical':
                templist = [[int((x1 - 1) % self.dim), x2] , [int((x1 + 1) % self.dim), x2] , [x1,x2-1],
                            [x1, x2+1] ] #list of the nearest neighbours
                ar = []
                for a in templist:
                    if a[1] >= 0 and a[1] < self.dim:
                        ar.append([a[0], a[1]])
                reallist = [int(c[1]*self.dim + c[0]) for c in ar]

                self.neighbours.append(reallist)

    def create_triangular_grid(self):
        '''creates a triangular lattice, where each point has six nearest neighbours in the lattice'''
        x, y = np.linspace(0, self.dim-1, self.dim), np.linspace(0, self.dim-1, self.dim)
        X, Y = np.meshgrid(y, x)
        self.X, self.Y = X.flatten(), Y.flatten()
        self.num_sites = self.dim*self.dim

        for i, (x1, x2) in enumerate(zip(self.X, self.Y)):
            if self.pbcs == True:
                templist = [[int((x1 - 1) % self.dim), x2] , [int((x1 + 1) % self.dim), x2] , [x1,int((x2 - 1) % self.dim) ],
                            [x1, int((x2 + 1) % self.dim)],[int((x1 + 1) % self.dim),int((x2 - 1) % self.dim) ],
                            [int((x1 - 1) % self.dim), int((x2 + 1) % self.dim)] ]
                reallist = [int(a[1]*self.dim + a[0]) for a in templist] #indices of nearest neighbour

                self.neighbours.append(reallist)

    def create_three_grid(self):
        '''creates a three dimensional lattice square lattice, also known as the simple cubic lattice'''
        x, y, z = np.linspace(0, (self.dim)-1, self.dim), np.linspace(0, (self.dim)-1, self.dim), np.linspace(0, (self.dim)-1, self.dim)
        X, Y, Z = np.meshgrid(y, x, z)
        self.X, self.Y, self.Z = X.flatten(), Y.flatten(), Z.flatten()
        self.num_sites = self.dim*self.dim*self.dim

        for i, (x1, x2, x3) in enumerate(zip(self.X, self.Y, self.Z)):
            if self.pbcs == True:
                templist = [[x1, x2, int((x3 - 1) % self.dim)] ,
                            [x1, x2, int((x3 + 1) % self.dim)] ,
                            [int((x1 + 1) % self.dim),x2 , x3],
                            [int((x1 - 1) % self.dim),x2 , x3],
                           [x1, int((x2 - 1) % self.dim),  x3] ,
                            [x1, int((x2 + 1) % self.dim), x3
                            ] ]

                reallist = [int(a[0]*self.dim + a[1]*self.dim**2 + a[2]) for a in templist] #indices of nearest neighbour

                self.neighbours.append(reallist)

    def grid_energy(self, moments):
        energy = 0
        '''Returns scalar for total energy for a given lattice configuration'''
        momentlist = self.current_moments
        for i in range((self.dim**self.num)): #Notice here how I am using self.num. When summing over the nieghbours for npbc it was helpful
            #print(self.J)
            energy += 0.5*momentlist[i]*np.sum(self.J[i]*momentlist[self.neighbours[i]])

            +self.h*np.sum(momentlist) #Note here that an external magnetic field can be applied
        return energy

    def create_Jlist(self, J):
        '''This function creates a list of the J value to be used when calculating the energy at each point. Notes that
        if there is more than one J value, this can only be done when the dimension of the lattice is even'''

        if len(J) ==1 and self.Jrule == 'nn': #if there is only one interaction energy
            return np.array([J[0] for i in range((self.dim**self.num))])

        if self.Jrule == 'nnn':
            if self.grid_type == 'square':
                '''First four will be 1, next four will be sqrt2 apart'''
                jlist = []
                #First create place for each point
                for i in range(self.dim*self.dim*self.dim): #each point
                    for j in range(4):
                        jlist.append(J[0]/np.sqrt(2))
                    for j in range(4):
                        jlist.append(J[0]/1)
                return jlist
            if self.grid_type == 'BCC':
                jlist = []
                #First create place for each point
                for i in range(self.dim*self.dim*self.dim): #each point
                    for j in range(8):
                        jlist.append(J[0]*np.sqrt(3)/2)
                    for j in range(4):
                        jlist.append(J[0]/1)
                return jlist

        #Please note: although this is not necessary, I still created this as I would have liked to look into how different interaction energies between points
        #can effect the curie temperature. Unfortunately I did not have enough time, but I would like to carry this out in the furture and this
        #J list would then be important as it will tell me the interaction energy between each neighbour

    def update_single(self, temp):
        '''Update by going through every point in the lattice'''
        self.current_energy =  self.grid_energy(self.current_moments) #Gets current energy
        newE = self.current_energy #This newE will be updated throughout the loop
        if self.Jrule =='nn' or self.Jrule =='nnn': #Checks what the Jrule is
            for q in range(self.dim**self.num):
                neigh = self.current_moments[self.neighbours[q]]
                neighsum = np.sum(self.J[q]*self.current_moments[q]*neigh)
                deltaE = 2*neighsum + 2*self.h*self.current_moments[q] #energy for a given lattice site
                deltaM = 0 #change in magnetisation
                #print(deltaE)
                if (deltaE <= 0):
                    newE += deltaE #update energy
                    self.current_moments[q] *= -1 #Flip
                    deltaM = 2*self.current_moments[q]
                else:
                    newE +=0
                    self.current_moments[q] = self.current_moments[q]
                    deltaM = 0

                if(deltaE>0): #Now it is defined according to boltzmann probability
                    random_num = float(rand.uniform(0, 1))
                    if (random_num < float(np.exp(-1*float(deltaE)/float(self.temp)))):
                        newE += deltaE #Update energy
                        self.current_moments[q] *= -1 #flip
                        deltaM = 2*self.current_moments[q] #change in magnetisation
                    else:
                        newE +=0
                        self.current_moments[q] = self.current_moments[q]
                        deltaM = 0

                self.magnetisation += deltaM #Update Magnetisation

        self.current_energy = newE #update energy

        self.energy_list.append(self.current_energy/self.num_sites) #average energy per site
        self.maglist.append(abs(self.magnetisation)/self.num_sites) #Absolute value used due to symmetry of hamiltonian

    def run(self, num_its=100, temp=-1):
        '''Performs multiple updates for a given temperature'''
        self.temp = temp
        for it in range(num_its):
            self.update_single(temp = self.temp)

    def grid_figure(self):
        '''This prints the lattice for a given configuration'''
        fig = plt.figure(figsize=(6,5))
        left, bottom, width, height = 0.1, 0.1, 0.8, 0.8
        ax = fig.add_axes([left, bottom, width, height])

        start, stop, n_values = 0, self.dim, self.dim

        x_vals = np.linspace(start, stop, n_values)
        y_vals = np.linspace(start, stop, n_values)
        X, Y = np.meshgrid(x_vals, y_vals)

        lattice = np.zeros((self.dim, self.dim))
        n = 0
        for i in range(self.dim):
            for j in range(self.dim):
                lattice[i, j] = self.current_moments[n]
                n +=1

        cp = plt.pcolormesh(X, Y, lattice)

        ax.set_title('100 x 100 Grid')
        plt.show()

    def print_equil(self, num_its= 300, temp = -1, to_print = 'all'):
        '''This runs the Ising Model and puts it into equilibrium and prints the average energy and magnetisation list'''
        self.run(temp = temp, num_its = num_its)

        if to_print == 'all' or to_print == 'energy':
            plt.plot(self.energy_list)
            plt.grid(linestyle= '-', linewidth=-.2)
            plt.ylabel('Number of Iterations')
            plt.xlabel('Average Energy')
            plt.show()

        if to_print == 'all' or to_print == 'magnetisation':
            plt.plot(self.maglist)
            plt.grid(linestyle= '-', linewidth=-.2)
            plt.ylabel('Number of Iterations')
            plt.xlabel('Average Energy')
            plt.show()

    def props_with_std(self, tempmin = 0.1, tempmax = 4, to_print = 'all'):
        '''This investigates the various properties of the Ising Model over a wide range of temperatures and prints the properties
        over a wide range of temperatures'''
        testruns, countruns = 100, 100
        self.run(temp = self.temp, num_its =3000)
        templist = np.linspace(tempmin,tempmax, 20) #Input range of temperatures here
        aveng, avmag, stdeng, stdmag = np.zeros(len(templist)), np.zeros(len(templist)), np.zeros(len(templist)), np.zeros(len(templist))
        heat_capacity, mag_suscept = np.zeros(20), np.zeros(20)
        list1, list2, list3, list4 = np.zeros((20, 20)), np.zeros((20, 20)), np.zeros((20, 20)), np.zeros((20, 20))
        for i, temp0 in enumerate(templist):
            for j in range(len(list1)):
                print(j, i)
                self.run(num_its = testruns + countruns, temp=temp0)
                aveng[i] = (np.mean(self.energy_list[-countruns:]))
                avmag[i] = (np.mean(self.maglist[-countruns:]))
                stdeng[i] =  (np.std(self.energy_list[-countruns:]))
                stdmag[i] = (np.std(self.maglist[-countruns:]))

                heat_capacity[i] = (stdeng[i]/(temp0**2))
                mag_suscept[i] = (stdmag[i]/(temp0))
                list1[i][j] = np.mean(self.energy_list[-countruns:]) #this repeats it many times and gets the list
                list2[i][j] = np.mean(self.maglist[-countruns:])
                list3[i][j] = heat_capacity[i] #Needed for magnetic susceptibility and heat capacity
                list4[i][j] = mag_suscept[i]

        stdE, stdM, stdH, stdS = [], [], [], []
        print(list1[0])
        for i in range(len(list1)):
            for j in range(len(list1)):

                if abs(list1[i][j] - list1[i][int((j - 1) % 20)]) > 0.2:
                    list1[i][j] = 0

        #now we have to get the standard deviation. Go through array and get each average for given ttemp
        #Now we have to create a list of each of the average of the averages
        for j in range(len(list1)):
            stdE.append(np.std(list1[j]))
            stdM.append(np.std(list2[j]))
            stdH.append(np.std(list3[j]))
            stdS.append(np.std(list4[j]))

        if to_print == 'all' or to_print =='magnetisation':
            plt.errorbar(templist[0:], avmag[0:], yerr = stdM,  marker='o', mfc='red', mec='green')
            plt.grid(linestyle= '-', linewidth=-.2)

            plt.xlabel('Temperature J/k')
            plt.show()

        if to_print == 'all' or to_print =='energy':
            #plt.plot(templist[0:], aveng[0:], 'ro')
            plt.errorbar(templist[0:], aveng[0:], yerr = stdE,  marker='o', mfc='red', mec='green')
            plt.grid(linestyle= '-', linewidth=-.2)
            plt.ylabel('Average Energy per Spin')
            plt.xlabel('Temperature J/k')
            plt.show()

        if to_print == 'all' or to_print =='heat capacity':
            plt.errorbar(templist[0:], heat_capacity[0:], yerr = stdH,  marker='o', mfc='red', mec='green')
            #plt.plot(templist[0:], heat_capacity[0:], 'ro')
            plt.grid(linestyle= '-', linewidth=-.2)
            plt.ylabel('Heat Capactity')
            plt.xlabel('Temperature J/k')
            plt.show()

        if to_print == 'all' or to_print =='magnetic susceptibility':
            #plt.plot(templist[0:], mag_suscept[0:], 'ro')
            plt.errorbar(templist[0:], mag_suscept[0:], yerr = stdS,  marker='o', mfc='red', mec='green', capthick = 2)
            plt.grid(linestyle= '-', linewidth=-.2)
            plt.ylabel('Magnetic Susceptibility')
            plt.xlabel('Temperature J/k')

            plt.show()

        return aveng, avmag,heat_capacity, mag_suscept

    def props(self, tempmin = 0.1, tempmax = 4, to_print = 'all'):
        '''This investigates the various properties of the Ising Model over a wide range of temperatures'''
        testruns, countruns = 100, 200
        templist = np.linspace(tempmin,tempmax, 20) #Input range of temperatures here
        aveng, avmag, stdeng, stdmag = np.zeros(len(templist)), np.zeros(len(templist)), np.zeros(len(templist)), np.zeros(len(templist))
        self.run(temp = self.temp, num_its =100)
        for i, temp0 in enumerate(templist):
            #self.reset()
            print(i)
            self.run(num_its = testruns + countruns, temp=temp0)
            aveng[i] = (np.mean(self.energy_list[-countruns:]))
            avmag[i] = (np.mean(self.maglist[-countruns:]))
            stdeng[i] =  (np.std(self.energy_list[-countruns:]))
            stdmag[i] = (np.std(self.maglist[-countruns:]))

        heat_capacity = stdeng/(templist**2)
        mag_suscept = stdmag/(templist)

        if to_print == 'all' or to_print =='energy':
            plt.plot(templist[0:], avmag[0:], 'ro')
            plt.grid(linestyle= '-', linewidth=-.2)
            plt.ylabel('Average Magnetisation per Spin')
            plt.xlabel('Temperature J/k')
            plt.show()

        if to_print == 'all' or to_print =='magnetisation':
            plt.plot(templist[0:], aveng[0:], 'ro')
            plt.grid(linestyle= '-', linewidth=-.2)
            plt.ylabel('Average Energy per Spin')
            plt.xlabel('Temperature J/k')
            plt.show()

        if to_print == 'all' or to_print =='heat capacity':
            plt.plot(templist[0:], heat_capacity[0:], 'ro')
            plt.grid(linestyle= '-', linewidth=-.2)
            plt.ylabel('Heat Capactity')
            plt.xlabel('Temperature J/k')
            plt.show()

        if to_print == 'all' or to_print =='magnetic susceptibility':
            plt.plot(templist[0:], mag_suscept[0:], 'ro')
            plt.grid(linestyle= '-', linewidth=-.2)
            plt.ylabel('Magnetic Susceptibility')
            plt.xlabel('Temperature J/k')
            plt.show()

        return aveng, avmag,heat_capacity, mag_suscept

#Equilibrium over various different temperatures
'''
ising1 = IsingModel(dim = 25, pbcs = True, temp = 1, J = [1], h = 0)
ising1.run(temp = 1, num_its = 100)

ising2 = IsingModel(dim = 25, pbcs = True, temp = 2, J = [1], h = 0)
ising2.run(temp = 2, num_its = 100)

ising3 = IsingModel(dim = 25, pbcs = True, temp = 10, J = [1], h = 0)
ising3.run( temp = 10, num_its = 100)

plt.plot(ising1.energy_list, label = 'T = 1')
plt.plot(ising2.energy_list, label = 'T = 2')
plt.plot(ising3.energy_list, label = 'T = 10')
plt.legend()
plt.title('Energy of lattice vs Number of Iterations')
plt.xlabel('Number of Iterations')
plt.ylabel('Average Energy per Site')
plt.show()
'''

#Investigate various properties of the Ising Model
'''
ising1 = IsingModel(dim = 10, pbcs = True, temp = 1, J = [1], h = 0)
ising1.print_equil(temp = 1, num_its = 100)

ising1.props_with_std()
'''

#Ising Model for different dimensions
'''
ising1 = IsingModel(dim = 10, pbcs = True, temp = 1, J = [1], h = 0, grid_type = '1D')
ising1.print_equil(temp = 1, num_its = 50)

ising1.props_with_std(tempmax = 6)

ising2 = IsingModel(dim = 10, pbcs = True, temp = 1, J = [1], h = 0, grid_type = 'square')
ising2.print_equil(temp = 1, num_its = 50)

ising2.props_with_std(tempmax = 6)

ising3 = IsingModel(dim = 10, pbcs = True, temp = 1, J = [1], h = 0, grid_type = '3D')
ising3.print_equil(temp = 1, num_its = 50)

ising3.props_with_std(tempmax = 6)
'''

#Include if you want to see how the size effects the Curie Temperature

ising_3 = IsingModel(dim = 3, pbcs = True, temp = 1, J = [1], h = 0)
m13 = ising_3.props(tempmax = 10)[1]

m3 = ising_3.maglist[0:]

ising_10 = IsingModel(dim = 10, pbcs = True, temp = 1, J = [1], h = 0)
m110 = ising_10.props(tempmax = 10)[1]

m10 = ising_10.maglist[0:]

ising_25 = IsingModel(dim = 25, pbcs = True, temp = 1, J = [1], h = 0)
m125 = ising_25.props(tempmax = 10)[1]

m25 = ising_25.maglist[0:]

templist = np.linspace(0.1, 10, 20)

plt.plot(templist[0:], m13[0:], 'ro', label = 'N = 3')
plt.plot(templist[0:], m110[0:], 'bo', label = 'N = 10')
plt.plot(templist[0:], m125[0:], 'go', label = 'N = 25')
plt.legend()
plt.xlabel('Temperature')
plt.ylabel('Magnetisation ')
plt.show()

#Include if you want to see how boundary conditions effect the Curie Temp
'''
ising_3 = IsingModel(dim = 10, pbcs = True, temp = 0.1, J = [1], h = 0)
m13 = ising_3.props(tempmax = 4)[1]

m3 = ising_3.maglist[0:]

ising_10 = IsingModel(dim = 10, pbcs = False, temp = 0.1, J = [1], h = 0)
m110 = ising_10.props(tempmax = 4)[1]

m10 = ising_10.maglist[0:]

ising_25 = IsingModel(dim = 10, pbcs = 'Cylindrical', temp = 0.1, J = [1], h = 0)
m125 = ising_25.props(tempmax = 4)[1]

m25 = ising_25.maglist[0:]

templist = np.linspace(0.1, 4, 20)

plt.plot(templist[0:], m13[0:], 'ro', label = 'Perioidic')
plt.plot(templist[0:], m110[0:], 'bo', label = 'Non-Periodic')
plt.plot(templist[0:], m125[0:], 'go', label = 'Cylindrical')
plt.legend()
plt.xlabel('Temperature')
plt.ylabel('Magnetisation ')
plt.show()
'''
#Include this is you want to determine the size of the lattice for pbc and nbc
'''
ising_3 = IsingModel(dim = 10, pbcs = True, temp = 1, J = [1], h = 0)
m13 = ising_3.props(tempmax = 4)[1]

m3 = ising_3.maglist[0:]

ising_10 = IsingModel(dim = 10, pbcs = False, temp = 1, J = [1], h = 0)
m110 = ising_10.props(tempmax = 4)[1]

m10 = ising_10.maglist[0:]

ising_25 = IsingModel(dim = 50, pbcs = False, temp = 1, J = [1], h = 0)
m125 = ising_25.props(tempmax = 4)[1]

m25 = ising_25.maglist[0:]

templist = np.linspace(0.1, 10, 20)

plt.plot(templist[0:], m13[0:], 'ro', label = 'PBC; N = 10')
plt.plot(templist[0:], m110[0:], 'bo', label = 'NPBC; N = 10')
plt.plot(templist[0:], m125[0:], 'go', label = 'NPBC; N = 50')
plt.legend()
plt.xlabel('Temperature J/k')
plt.ylabel('Magnetisation')
plt.show()
'''
'''
#Now we introduce how distsnce dependancy effects the Curie Temperature
#Expect fro larger distances the CT will decrease

ising_3 = IsingModel(dim = 10, pbcs = True, temp = 0.1, J = [1], h = 0)
m13 = ising_3.props(tempmax = 20)[1]

m3 = ising_3.maglist[0:]

ising_10 = IsingModel(dim = 10, pbcs = True, temp = 0.1, J = [2.5], h = 0)
m110 = ising_10.props(tempmax = 20)[1]

m10 = ising_10.maglist[0:]

ising_25 = IsingModel(dim = 10, pbcs = True, temp = 0.1, J = [5], h = 0)
m125 = ising_25.props(tempmax = 20)[1]

m25 = ising_25.maglist[0:]

templist = np.linspace(0.1, 10, 20)

plt.plot(templist[0:], m13[0:], 'ro', label = 'd = 5')
plt.plot(templist[0:], m110[0:], 'bo', label = 'd = 2')
plt.plot(templist[0:], m125[0:], 'go', label = 'd = 5' )
plt.legend()
plt.xlabel('Temperature')
plt.ylabel('Magnetisation')
plt.show()
'''

#Next we do the the dependence between neighest neighbours.
'''
ising_3 = IsingModel(dim = 10, pbcs = True, temp = 0.1, J = [1], h = 0)
m13 = ising_3.props(tempmax = 20)[1]

m3 = ising_3.maglist[0:]

ising_10 = IsingModel(dim = 10, pbcs = True, temp = 0.1, J = [1], h = 0, Jrule = 'nnn')
m110 = ising_10.props(tempmax = 20)[1]

plt.plot(templist[0:], m13[0:], 'ro', label = 'First NN')
plt.plot(templist[0:], m110[0:], 'bo', label = 'First and Second NN')
plt.xlabel('Temperature J/k')
plt.ylabel('Magnetisation')
plt.legend()
plt.show()
'''

#Now we investigate BCC vs Square
'''
ising_bcc = IsingModel(dim = 10, pbcs = True, temp = 1, J = [1], h = 0, Jrule = 'nnn', grid_type = 'BCC')
m13 = ising_bcc.props(tempmax = 20)[1]

ising_bcc2 = IsingModel(dim = 10, pbcs = True, temp = 1, J = [1], h = 0, Jrule = 'nn', grid_type = 'BCC')
m132 = ising_bcc2.props(tempmax = 20)[1]

ising_s = IsingModel(dim = 10, pbcs = True, temp = 1, J = [1], grid_type = '3D', Jrule = 'nn')
m110 = ising_s.props(tempmax = 20)[1]

plt.plot(templist[0:], m13[0:], 'ro', label = 'BCC with NNN')
plt.plot(templist[0:], m132[0:], 'go', label = 'BCC')
plt.plot(templist[0:], m110[0:], 'bo', label = 'Cubic')
plt.xlabel('Temperature J/k')
plt.ylabel('Magnetisation')
plt.legend()
plt.show()
'''

#Triangular 2d vs square 2d
'''
ising_3 = IsingModel(dim = 10, pbcs = True, temp = 0.1, J = [1], h = 0, grid_type = 'triangular')
m13 = ising_3.props(tempmax = 20)[1]

m3 = ising_3.maglist[0:]

ising_10 = IsingModel(dim = 10, pbcs = True, temp = 0.1, J = [1], h = 0)
m110 = ising_10.props(tempmax = 20)[1]

plt.plot(templist[0:], m13[0:], 'ro', label = 'Triangular 2D grid')
plt.plot(templist[0:], m110[0:], 'bo', label = 'Square 2D grid')
plt.xlabel('Temperature J/k')
plt.ylabel('Magnetisation')
plt.legend()
plt.show()
'''


#!/usr/bin/env python

try:
    from setuptools import setup
except ImportError:
    from distutils.core import setup

config = {
    'description': 'Computational Investments, Part 1 (coursera)',
    'author': 'Peter Suggitt',
    'url': '',
    'download_url': '',
    'author_email': 'me@suggs.org.uk',
    'version': '0.0.1',
    'install_requires': ['nose'],
    'packages': ['NAME'],
    'scripts': [],
    'name': 'Computational Investments'
}

setup(**config)


import pandas as pd

def parse_bloomberg_excel(filename, colnames_sheet, data_sheets, space=1,
                          colnames=None, **kwargs):
    """Parse .xlsx file constructed with Bloomberg Excel API.

    Parameters
    ----------
    data_sheets : list or string or None
        if None, all sheets are loaded
    colnames : list-like
    space : int
        number of empty columns between neighboring data series

    Returns
    -------
    this_data : pandas.DataFrame
        of data
    """
    if isinstance(data_sheets, str):
        data_sheets = [data_sheets, ]
        flag_single_input = True
    else:
        flag_single_input = False

    # converter for date
    def converter(x):
        try:
            res = pd.to_datetime(x)
        except Exception:
            res = pd.NaT
        return res

    # colnames_sheet
    if colnames is None:
        colnames = pd.read_excel(filename, sheet_name=colnames_sheet, header=0)
        colnames = colnames.columns

    # float converters
    float_conv = {
        k: float for k in list(range(1, len(colnames)*(2+space), 2+space))
    }

    # if data_sheets is None, read in all sheets
    if data_sheets is None:
        data_dict_full = pd.read_excel(filename, sheet_name=None,
                                       converters=float_conv, verbose=True,
                                       **kwargs)

        # remove the sheet with colnames from this dict
        data_dict_full.pop(colnames_sheet, None)

    else:
        data_dict_full = pd.read_excel(filename, sheet_name=data_sheets,
                                       converters=float_conv, verbose=True,
                                       **kwargs)

    # loop over sheetnames
    all_data = dict()

    for s, data_df in data_dict_full.items():
        # loop over triplets, map dates, extract
        new_data_df = []
        for p in range((data_df.shape[1]+1)//(space+2)):
            # this triplet
            this_piece = data_df.iloc[1:, p*(space+2):(p+1)*(space+2)-space]

            # map date
            this_piece.iloc[:, 0] = this_piece.iloc[:, 0].map(converter)

            # drop nans (with dates)
            this_piece = this_piece.dropna()

            # extract date as index
            this_piece = this_piece.set_index(this_piece.columns[0])

            # rename
            this_piece.columns = [colnames[p]]
            this_piece.index.name = "date"

            # drop duplicates from the index
            this_piece = this_piece.loc[
                ~this_piece.index.duplicated(keep='first'), :]

            # store
            new_data_df += [this_piece, ]

        # concat
        all_data[s] = pd.concat(new_data_df, axis=1, join="outer")

    # if only one sheet was asked for
    if flag_single_input:
        all_data = list(all_data.values())[0]

    return all_data


#!/usr/bin/python3
"""
This module contains the HBNBCommand class that implements
the command interpreter.
"""

import cmd
import shlex
from models.base_model import BaseModel
from models import storage
from models.user import User
from models.state import State
from models.city import City
from models.amenity import Amenity
from models.place import Place
from models.review import Review

class HBNBCommand(cmd.Cmd):
    """
    HBNBCommand class that implements the command interpreter.

    args:
    prompt: str that will be showed to the user

    Methods:
        do_quit(self, arg): Quit command to exit the program
        do_EOF(self, arg): Quit command to exit the program when receive EOF
        emptyline(self): Empty line + ENTER shouldn't execute anything
        help_quit(self): Help message for the quit command
        do_create(self, arg): Creates a new instance of any available model
        do_show(self, arg): Prints the string representation of an instance
        do_destroy(self, arg): Deletes an instance based on name and id
        do_all(self, arg): Prints all string representation of all instances
        do_update(self, arg): Updates an instance based on name and id
    """

    prompt = "(hbnb) "
    classes = {
        "BaseModel": BaseModel(),
        "User": User(),
        "State": State(),
        "City": City(),
        "Amenity": Amenity(),
        "Place": Place(),
        "Review": Review()
    }

    def do_quit(self, arg):
        """
        Quit command to exit the program
        """
        return True

    def do_EOF(self, arg):
        """
        Quit command to exit the program
        """
        print()
        return True

    def emptyline(self):
        """
        Empty line + ENTER shouldn't execute anything
        """
        pass

    def help_quit(self):
        """
        Help message for the quit command
        """
        print("Quit command to exit the program")

    def default(self, arg):
        """Handle any command that is not defined"""
        methods = {
            "all": self.do_all,
            "show": self.do_show,
            "destroy": self.do_destroy,
            "count": self.do_count,
            "update": self.do_update
        }
        if "." in arg:
            args = arg.split(".")
            class_name = args[0]
            method_name = args[1].split("(")[0]
            if class_name in self.classes and method_name in methods:
                if "(" in args[1] and ")" in args[1]:
                    id_arg = args[1].split("(")[1].split(")")[0]
                    methods[method_name](class_name + " " + id_arg)
                else:
                    methods[method_name](class_name)
            else:
                print("** Unknown syntax: {} **".format(arg))
        else:
            print("** Unknown syntax: {} **".format(arg))

    def do_create(self, arg):
        """
        Creates a new instance of any available model,
        and saves it (to the JSON file) and prints the id.
        """
        args = shlex.split(arg)
        if len(args) == 0:
            print("** class name missing **")
        elif args[0] not in self.classes:
            print("** class doesn't exist **")
        else:
            class_obj = self.classes[args[0]]
            class_obj.save()
            print(class_obj.id)

    def do_show(self, arg):
        """
        Prints the string representation of an instance based
        on the class name and id.
        """
        args = shlex.split(arg)
        if len(args) == 0:
            print("** class name missing **")
        elif args[0] not in self.classes:
            print("** class doesn't exist **")
        elif len(args) == 1:
            print("** instance id missing **")
        else:
            all_objs = storage.all()
            key = "{}.{}".format(args[0], args[1])
            if key in all_objs:
                print(all_objs[key])
            else:
                print("** no instance found **")

    def do_destroy(self, arg):
        """
        Deletes an instance based on the class name and id
        (save the change into the JSON file).
        """
        args = shlex.split(arg)
        if len(args) == 0:
            print("** class name missing **")
        elif args[0] not in self.classes:
            print("** class doesn't exist **")
        elif len(args) == 1:
            print("** instance id missing **")
        else:
            all_objs = storage.all()
            key = "{}.{}".format(args[0], args[1])
            if key in all_objs:
                del all_objs[key]
                storage.save()
            else:
                print("** no instance found **")

    def do_all(self, arg):
        """
        Prints all string representation of all instances based or not
        on the class name.
        """
        args = shlex.split(arg)
        all_objs = storage.all()
        if len(args) == 0:
            print([str(obj) for obj in all_objs.items()])
        elif args[0] not in self.classes:
            print("** class doesn't exist **")
        else:
            if arg[0].endswith('.all'):
                class_name = arg[0].split(".")[0]
                class_objs = [
                    value for key, value in all_objs.items()
                    if key.startswith(class_name)]
                strs = [str(obj) for obj in class_objs]
                print(strs)
            else:
                class_objs = [
                    value for key, value in all_objs.items()
                    if key.startswith(arg[0])]
                strs = [str(obj) for obj in class_objs]
                print(strs)

    def do_update(self, arg):
        """
        Updates an instance based on the class name and id by adding
        or updating attribute (save the change into the JSON file).
        """
        args = shlex.split(arg)
        if len(args) == 0:
            print("** class name missing **")
        elif args[0] not in self.classes:
            print("** class doesn't exist **")
        elif len(args) == 1:
            print("** instance id missing **")
        else:
            all_objs = storage.all()
            key = "{}.{}".format(args[0], args[1])
            if key not in all_objs:
                print("** no instance found **")
            elif len(args) == 2:
                print("** dictionary representation missing **")
            else:
                obj = all_objs[key]
                try:
                    data = eval(args[2])
                except (SyntaxError, NameError):
                    print("** invalid dictionary representation **")
                    return
                if isinstance(data, dict):
                    for k, v in data.items():
                        setattr(obj, k, v)
                    obj.save()
                else:
                    print("** invalid dictionary representation **")

    def do_count(self, arg):
        """
        Retrieves the number of instances of a class.
        """
        args = shlex.split(arg)
        if len(args) == 0:
            print("** class name missing **")
        elif args[0] not in self.classes:
            print("** class doesn't exist **")
        else:
            all_objs = storage.all()
            count = len(
                [obj for key, obj in all_objs.items()
                 if key.startswith(arg[0])]
                        )
            print(count)

if __name__ == '__main__':
    HBNBCommand().cmdloop()


class Student:
    age = 24
    eye_color = 'brown'
    #functions -
    def __init__(self,name,hobby,fav_food,age):
        self.name = name
        self.hobby = hobby
        self.fav_food = fav_food
        self.age = age

    def say_hello(self,name):
        print("Hello from "+ self.name.title())

    def run(self):
        print("Student is running ")

#object - an instance of the class (copy )
# Object oriented programming

#       Class -Template
#       Objects - features
#       name,hobby,fav_food,age

first_student = Student("Mercy","Swimming","chapati",20)

second_student = Student("Bob","driving","Ugali",40)

print("The first student is "+first_student.name.title())
print("The first student's favourite food is "+first_student.fav_food.title())

print("The second student's age is " +str(second_student.age))

second_student.run() #void function
second_student.say_hello(second_student.name)


from django.shortcuts import render
from home.models import Blogpost , Contect
from django.contrib import messages

# Create your views here.

def home(request):
    posts = Blogpost.objects.filter(publish=True)
    context = {'posts': posts}
    return render(request, "home.html", context)

def blog(request):
    posts = Blogpost.objects.filter(publish=True)
    context = {'posts': posts}
    return render(request, "blog.html", context)

def blogview(request, slug):
    posts = Blogpost.objects.filter(slug=slug).first()
    context = {'posts': posts}
    return render(request, "pview/blogview.html", context)

def contect(request):
    if request.method == 'POST':
        fname = request.POST['fname']
        Lname = request.POST['lname']
        mob = request.POST['mobile']
        email = request.POST['email']
        desc = request.POST['description']
        if len(fname) < 3 or len(Lname) < 3 or len(mob) < 10 or len(email) < 5 or len(desc) < 5:
            messages.error(request, 'Please fill the form correctly')
        else:
            contect = Contect(fname=fname, Lname=Lname , mob=mob,
                              email=email, desc=desc,)
            contect.save()
            messages.success(request, 'Your messages has Submited Successfuly')
    return render(request, "contect.html")

def about(request):
    return render(request, "about.html")


from __future__ import annotations
import os
import logging
import secrets
from typing import Any
from dataclasses import dataclass
from PyQt5.QtCore import QSettings

@dataclass
class DefaultSetting:
    """Default settings."""

    settings: QSettings
    name: str
    value: Any
    group_name: str = None

    def initialize_setting(self) -> DefaultSetting:
        """Initialize the default setting or pulls the current setting value."""
        if self.group_name:
            self.settings.beginGroup(self.group_name)

        if not self.settings.contains(self.name):
            self.settings.setValue(self.name, self.value)
        else:
            self.value = self.settings.value(self.name)

        if self.group_name:
            self.settings.endGroup()
        return self

    def save(self) -> DefaultSetting:
        """Save the default setting."""
        if self.group_name:
            self.settings.beginGroup(self.group_name)

        self.settings.setValue(self.name, self.value)

        if self.group_name:
            self.settings.endGroup()
        return self

COMPANY_NAME = "DF-Software"
PROGRAM_NAME = "Cut List Generator"
PROGRAM_VERSION = "1.0.7"
USER_HOME_FOLDER = os.path.expanduser("~")
COMPANY_FOLDER = os.path.join(USER_HOME_FOLDER, "Documents", COMPANY_NAME)
PROGRAM_FOLDER = os.path.join(COMPANY_FOLDER, PROGRAM_NAME)
LOG_FOLDER = os.path.join(PROGRAM_FOLDER, "Logs")
LOG_SQLALCHEMY_FOLDER = os.path.join(LOG_FOLDER, "SQLAlchemy")

settings = QSettings(COMPANY_NAME, PROGRAM_NAME)

# Program settings
DATE_TIME_FORMAT = "%m-%d-%Y %H:%M"
DATE_FORMAT = "%m-%d-%Y"
DEFAULT_DUE_DATE_PUSH_BACK_DAYS = 30

LAST_USERNAME = DefaultSetting(
    settings=settings, name="last_username", value=""
).initialize_setting()
DEBUG = (
    DefaultSetting(settings=settings, name="debug", value=False)
    .initialize_setting()
    .value
)
if DEBUG == "true":
    DEBUG = True
else:
    DEBUG = False

# Logging settings
LOG_FILE = "cutlistgenerator.log"
SQLALCHEMY_ENGINE_LOG_FILE = "sqlalchemy_engine.log"
SQLALCHEMY_POOL_LOG_FILE = "sqlalchemy_pool.log"
SQLALCHEMY_DIALECT_LOG_FILE = "sqlalchemy_dialect.log"
SQLALCHEMY_ORM_LOG_FILE = "sqlalchemy_orm.log"
MAX_LOG_SIZE_MB = (
    DefaultSetting(
        settings=settings, group_name="Logging", name="max_log_size_mb", value=5
    )
    .initialize_setting()
    .value
)
MAX_LOG_COUNT = (
    DefaultSetting(
        settings=settings, group_name="Logging", name="max_log_count", value=3
    )
    .initialize_setting()
    .value
)
LOG_LEVEL = (
    DefaultSetting(
        settings=settings, group_name="Logging", name="log_level", value=logging.INFO
    )
    .initialize_setting()
    .value
)
if DEBUG:
    LOG_LEVEL = logging.DEBUG

# Database settings
DATABASE_USER = (
    DefaultSetting(settings=settings, group_name="Database", name="user", value="root")
    .initialize_setting()
    .value
)
DATABASE_PASSWORD = (
    DefaultSetting(
        settings=settings, group_name="Database", name="password", value="Redpurple23"
    )
    .initialize_setting()
    .value
)
DATABASE_HOST = (
    DefaultSetting(
        settings=settings, group_name="Database", name="host", value="localhost"
    )
    .initialize_setting()
    .value
)
DATABASE_PORT = (
    DefaultSetting(settings=settings, group_name="Database", name="port", value="3306")
    .initialize_setting()
    .value
)
SCHEMA_NAME = (
    DefaultSetting(
        settings=settings,
        group_name="Database",
        name="schema",
        value="cutlistgenerator_new",
    )
    .initialize_setting()
    .value
)
SCHEMA_CREATE = f"CREATE SCHEMA IF NOT EXISTS {SCHEMA_NAME}"
DATABASE_URL_WITHOUT_SCHEMA = f"mysql+pymysql://{DATABASE_USER}:{DATABASE_PASSWORD}@{DATABASE_HOST}:{DATABASE_PORT}"
DATABASE_URL_WITH_SCHEMA = f"{DATABASE_URL_WITHOUT_SCHEMA}/{SCHEMA_NAME}"
FORCE_REBUILD_DATABASE = (
    DefaultSetting(
        settings=settings,
        group_name="Database",
        name="force_rebuild_database",
        value=False,
    )
    .initialize_setting()
    .value
)
if FORCE_REBUILD_DATABASE == "true":
    FORCE_REBUILD_DATABASE = True
else:
    FORCE_REBUILD_DATABASE = False

# Fishbowl settings
FISHBOWL_DATABASE_USER = (
    DefaultSetting(settings=settings, group_name="Fishbowl", name="user", value="gone")
    .initialize_setting()
    .value
)
FISHBOWL_DATABASE_PASSWORD = (
    DefaultSetting(
        settings=settings, group_name="Fishbowl", name="password", value="fishing"
    )
    .initialize_setting()
    .value
)
FISHBOWL_DATABASE_HOST = (
    DefaultSetting(
        settings=settings, group_name="Fishbowl", name="host", value="localhost"
    )
    .initialize_setting()
    .value
)
FISHBOWL_DATABASE_PORT = (
    DefaultSetting(settings=settings, group_name="Fishbowl", name="port", value="3305")
    .initialize_setting()
    .value
)
FISHBOWL_DATABASE_SCHEMA = (
    DefaultSetting(settings=settings, group_name="Fishbowl", name="schema", value="qes")
    .initialize_setting()
    .value
)
FISHBOWL_DATABASE_URL = f"mysql+pymysql://{FISHBOWL_DATABASE_USER}:{FISHBOWL_DATABASE_PASSWORD}@{FISHBOWL_DATABASE_HOST}:{FISHBOWL_DATABASE_PORT}/{FISHBOWL_DATABASE_SCHEMA}"

# Github settings
GITHUB_USERNAME = "dominickfau"
GITHUB_REPO_NAME = "CutListGenerator"

GITHUB_LATEST_RELEASE_ENDPOINT = (
    f"https://api.github.com/repos/{GITHUB_USERNAME}/{GITHUB_REPO_NAME}/releases/latest"
)

# Thread settings
THREAD_UPDATE_INTERVAL = 5  # seconds

# API settings
API_TOKEN_VALIDITY = 1  # days

FLASK_SECRET_KEY = (
    DefaultSetting(
        settings=settings,
        group_name="Flask",
        name="secret_key",
        value=secrets.token_urlsafe(64),
    )
    .initialize_setting()
    .value
)

if not os.path.exists(COMPANY_FOLDER):
    os.mkdir(COMPANY_FOLDER)

if not os.path.exists(PROGRAM_FOLDER):
    os.makedirs(PROGRAM_FOLDER)

if not os.path.exists(LOG_FOLDER):
    os.makedirs(LOG_FOLDER)

if not os.path.exists(LOG_SQLALCHEMY_FOLDER):
    os.makedirs(LOG_SQLALCHEMY_FOLDER)


import random
import os

print("THE RULES FOR THE TASK ARE AS FOLLOWS: \n"+"User has to choose any one options from the available three options and Based on the winning rules this app decides who will win\n"
                                +"ROCK VERSES PAPER----> PAPER WINS \n"
                                + "ROCK VERSES SCISSORS---->ROCK WINS \n"
                                +"PAPER VERSES SCISSORS----->SCISSORS WINS\n")

while True:

    print("Enter choice \n 1. Rock \n 2. paper \n 3. scissor \n")

    ch = int(input("ENTER YOUR MOVE:  "))

    while ch> 3 or ch< 1:
        ch = int(input("PLEASE ENTER VALID INPUT: "))

    if ch == 1:
        ch_name = 'Rock'
    elif ch == 2:
        ch_name = 'paper'
    else:
        ch_name = 'scissor'

    print("user choice is: " + ch_name)
    print("\nNow its computer turn.......")

    comp_choice = random.randint(1, 3)

    while comp_choice == ch:
        comp_choice = random.randint(1, 3)

    if comp_choice == 1:
        comp_choice_name = 'Rock'
    elif comp_choice == 2:
        comp_choice_name = 'paper'
    else:
        comp_choice_name = 'scissor'

    print("COMPUTER CHOICE IS: " + comp_choice_name)

    print(ch_name + " V/s " + comp_choice_name)

    if((ch == 1 and comp_choice == 2) or
      (ch == 2 and comp_choice ==1 )):
        print("paper wins => ", end = "")
        result = "paper"

    elif((ch== 1 and comp_choice == 3) or
        (ch == 3 and comp_choice == 1)):
        print("Rock wins =>", end = "")
        result = "Rock"
    else:
        print("scissor wins =>", end = "")
        result = "scissor"

    if result == ch_name:
        print("OPPONENT CHOICE  "+ch_name+"<== User wins ==>")
    else:
        print("COMPUTER CHOICE "+ch_name+"<== Computer wins ==>")

    print("DO YOU WANT TO CONTINUE? (Y/N)")
    ans = input()

    if ans == 'n' or ans == 'N':
        break
    clear = lambda: os.system('cls')
    clear()

print("\nThanks for playing")


N=int(input('digite um angulo'))
n=float(input("diga o valor do cateto 1 adjascente"))
s=float(input('diga o valor do cateto 2 oposto'))
z=(n**2)+(s**2)
x=z/2
print('hipotenusa{}'.format(x))
seno=s/x
cose=n/x
tangente=s/n
print('seno{}, cose{},tangente{}' .format(seno,cose,tangente))


import requests

from bs4 import BeautifulSoup

response = requests.get(input())

if response.status_code == 200:
    soup = BeautifulSoup(response.content, "html.parser")
    links = soup.find_all("a")
    filtered_links = list(filter(lambda x: len(x.text) > 1 and x.text.startswith("S") and (("entity" in x.get("href") or "topic" in x.get("href")) if x.get("href") is not None else True), links))
    print(list(map(lambda x: x.text, filtered_links)))
else:
    print("Error")

Topics/BeautifulSoup  working with HTML (3)/Health issues/main.py


# -*- coding: utf-8 -*-
from openerp.osv import osv
from openerp.osv import fields

class stock_delivery(osv.osv):
    _name = 'stock.picking'
    _inherit ='stock.picking'

    _columns = {
        'delivery_carrier_id': fields.many2one('stock.delivery.carrier', u'运输公司',select=True),
        'delivery_id': fields.related('delivery_carrier_id','delivery_id',type='many2one', relation="res.users", string=u"押运人", select=True),
    }

class stock_delivery_out(osv.osv):

    _inherit ='stock.picking.out'

    _columns = {
        'delivery_carrier_id': fields.many2one('stock.delivery.carrier', u'运输公司',select=True),
        'delivery_id': fields.related('delivery_carrier_id','delivery_id',type='many2one', relation="res.users", string=u"押运人", select=True),
    }

    def create(self, cr, uid, vals, context=None):
        ids = super(stock_delivery_out, self).create(cr, uid, vals, context=context)
        stock_obj = self.browse(cr,uid,ids)
        if stock_obj.delivery_carrier_id:
            stock_obj.delivery_carrier_id.write({'picking_id':ids})
        return ids

    def write(self, cr, uid, ids, vals, context=None):
        if isinstance(ids, (int,long)):
            ids = [ids]
        res = super(stock_delivery_out, self).write(cr, uid, ids, vals, context=context)
        stock_obj = self.browse(cr,uid,ids[0])
        if stock_obj.delivery_carrier_id:
            stock_obj.delivery_carrier_id.write({'picking_id':ids[0]})
        return res

class res_partner(osv.osv):

    _inherit = 'res.partner'

    _columns = {
        'delivery': fields.boolean(u'承运方'),
        'identity_card':fields.char(u'身份证'),
        'driving_number':fields.char(u'驾驶证'),
        'delivery_image': fields.binary(u'司机图片'),
    }


# from tkinter import Tk, Frame, Button, BOTTOM, LEFT, Y ,YES, TOP, RIGHT, W

from tkinter import *
langas = Tk()
langas.geometry("400x200")
# freimai
virsus = Frame(langas)
apacia = Frame(langas)

mygtukas1 = Button(virsus, text="Spausdinti", anchor=W)
mygtukas2 = Button(virsus, text="Apacia")
mygtukas3 = Button(virsus, text="Galas")

virsus.pack(side=TOP)
apacia.pack(side=BOTTOM)
mygtukas1.pack(side=LEFT)
mygtukas2.pack(side=LEFT)
mygtukas3.pack(side=RIGHT)

langas.mainloop()


'''
@author: Dallas Fraser
@author: 2019-03-13
@organization: MLSB API
@summary: Tests the schedule view api
'''
from api.helper import loads
from api.routes import Routes
from api.errors import LeagueDoesNotExist
from api.test.BaseTest import TestSetup, INVALID_ID
from api.test.advanced.mock_league import MockLeague
import datetime

class TestSchedule(TestSetup):

    def testEmptyYear(self):
        """Test schedule view for empty league"""
        rv = self.app.get(Routes['vschedule'] + "/2012" + "/1")
        expect = []
        self.output(loads(rv.data))
        self.output(expect)
        self.assertEqual(expect, loads(rv.data)['items'],
                         Routes['vschedule'] + "View: on 2012 year")

    def testLeagueDoesNotExist(self):
        """Test schedule view for empty league"""
        url = Routes['vschedule'] + "/2012" + "/" + str(INVALID_ID)
        rv = self.app.get(url)
        self.output(rv.status_code)
        self.output(LeagueDoesNotExist.status_code)
        self.assertEqual(rv.status_code, LeagueDoesNotExist.status_code,
                         Routes['vschedule'] + "View: on invalid league")

    def testMockLeague(self):
        """Test schedule view for mocked league"""
        league_id = MockLeague(self).league['league_id']
        year = datetime.datetime.now().year
        url = Routes['vschedule'] + "/" + str(year) + "/" + str(league_id)
        rv = self.app.get(url)
        game = {'away_team': 'Advanced Test Sponsor Test Team 2',
                'home_team': 'Advanced Test Sponsor Test Team',
                'score': '1-6'}
        expect = ["1-6", "0-0", ""]
        self.output(loads(rv.data))
        self.output(expect)
        for index, game in enumerate(loads(rv.data)['items']):
            self.assertEqual(expect[index], game['score'])


import csv
csvfile=file('/home/qz/svn/csvtest.csv','wb')
writer=csv.writer(csvfile)
writer.writerow(['id','url','key'])
data=[
	('1','python','org')
	('2','baidu','cn')
	('3','jd','com')
]
writer.writers(data)
csvfile.close()


#!/usr/bin/python

import os, sys, threading, smtplib
from email.MIMEText import MIMEText

def checkDevArea():
  os.system('ls /mvista/dev_area > /dev/null')

def main():
  thread = threading.Thread(target=checkDevArea)
  thread.start()
  thread.join(10)
  alive = thread.isAlive()
  if alive:
    #Issues with dumbo, send email
    smtpObject = smtplib.SMTP()
    mailMsg    = MIMEText('')
    mailMsg['From'] = "build@mvista.com"
    mailMsg['To'] = "9253374727@vtext.com"
    mailMsg['Subject'] = "/mvista/dev_area is down"
    #Send Message
    smtpObject.connect('mail.mvista.com')
    smtpObject.sendmail('cvanarsdall@mvista.com','9253374727@vtext.com', mailMsg.as_string())
    smtpObject.close()

  else:
    sys.exit(1)

if __name__ == "__main__":
  main()


import tensorflow as tf
from utils import Loader, Option_data
import pandas as pd
import numpy as np
import datetime
import QuantLib as ql
import matplotlib.pyplot as plt
from tensorflow.keras.layers import TimeDistributed
from tensorflow.python.client import device_lib

class DHGAN(Loader, Option_data):
    def __init__(self, symbol_list, settings, dh_settings, option_data, option_settings):
        Loader.__init__(self, symbol_list = symbol_list)
        Option_data.__init__(self, option_data ,option_settings)
        self.settings = settings
        self.dh_settings = dh_settings
        self.input_data = np.asarray(self.data)
        self.module = self.settings['module']
        self.hidden_dim = self.settings['hidden_dim']
        self.latent_dim = self.settings['latent_dim']
        self.num_layers = self.settings['num_layers']
        self.iterations = self.settings['iterations']
        self.batch_size = self.settings['batch_size']
        self.learning_rate = self.settings['learning_rate']
        self.no, self.seq_len, self.dim = self.input_data.shape
        # self.time, self.max_seq_len = extract_time(self.input_data)
        self.dh_sims = self.dh_settings['hedge_simulations']
        self.dh_features = self.dh_settings['hedge_features']
        self.dh_epochs = self.dh_settings['hedge_epochs']
        self.dh_batch_size = self.dh_settings['hedge_batch_size']
        self.dh_neurons = self.dh_settings['hedge_neurons']
        self.dh_learning_rate = self.dh_settings['hedge_learning_rate']
        self.dh_validation_proportion = self.dh_settings['hedge_validation_proportion']
        self.dh_test_proportion = self.dh_settings['hedge_test_proportion']
        self.dh_nb_test = int(self.dh_test_proportion * self.dh_sims)
        self.dh_nb_valid = int(self.dh_test_proportion * self.dh_sims)
        self.dh_nb_train = int(self.dh_sims - (self.dh_nb_test+ self.dh_nb_valid))
        self.alpha = self.dh_settings['alpha']
        self.epsilon = self.dh_settings['epsilon']
        self.K = self.dh_settings['strike']
        self.T = self.seq_len
        self.W_dim = self.dim
        # models
        self.Embedder = self.EmbedderNet()
        self.Embedder.summary()
        self.Embedder_optimizer = tf.keras.optimizers.Adam(self.learning_rate)
        self.Recovery = self.RecoveryNet()
        self.Recovery.summary()
        self.Recovery_optimizer = tf.keras.optimizers.Adam(self.learning_rate)
        self.Supervisor = self.SupervisorNet()
        self.Supervisor.summary()
        self.Supervisor_optimizer = tf.keras.optimizers.Adam(self.learning_rate)
        self.Generator = self.GeneratorNet()
        self.Generator.summary()
        self.Generator_optimizer = tf.keras.optimizers.Adam(self.learning_rate)
        self.Discriminator = self.DiscriminatorNet()
        self.Discriminator.summary()
        self.Discriminator_optimizer = tf.keras.optimizers.Adam(self.learning_rate)
        self.dhmodel = self.DeepHedgeNet()
        self.dhmodel_optimizer = tf.keras.optimizers.Adam(self.dh_learning_rate)
        self.dhmodel.summary()
        # Training datasets

        #renorm
        # self.dta = self.norm_data * self.max_val
        # self.dta = self.dta + self.min_val
        # self.dta = np.exp(self.dta)
        # print(self.dta[:, :,:] * np.asarray(self.starting_values))
        # print(self.starting_values)

    def BrownianMotion(self,nb_sims, timesteps, W_dim, dt = 1/365):
        W = np.zeros(shape = (nb_sims, timesteps, W_dim))
        for t in range(1, timesteps):
            W[:,t,:] = W[:,t-1,:] + np.random.randn(nb_sims, W_dim)* np.sqrt(dt)
        return W
    def EmbedderNet(self):
        '''
        Latent space map from function space X (bounded random processes F-adapted)
        to target latent space representation
        '''
        model = tf.keras.Sequential(name = 'EmbedderNet')
        if self.module == 'lstm':
            model.add(tf.keras.layers.LSTM(self.dim, input_shape = (self.T, self.dim), activation = 'tanh',return_sequences = True))
            for layer in range(self.num_layers):
                model.add(tf.keras.layers.LSTM(self.hidden_dim, activation = 'tanh', return_sequences = True))
        elif self.module == 'gru':
            model.add(tf.keras.layers.GRU(self.dim, input_shape = (self.T, self.dim), activation = 'tanh', return_sequences = True))
            for layer in range(self.num_layers):
                model.add(tf.keras.layers.GRU(self.hidden_dim, activation = 'tanh', return_sequences = True))
        else:
            raise AssertionError('Please Choose gru or lstm as module')
        model.add(TimeDistributed(tf.keras.layers.Dense(self.latent_dim, activation = 'sigmoid')))
        return model
    def RecoveryNet(self):
        '''
        Inverse map from latent (HxT) space representation to state space of bounded F-adapted random processes
        '''
        model = tf.keras.Sequential(name = 'RecoveryNet')
        if self.module == 'lstm':
            model.add(tf.keras.layers.LSTM(self.hidden_dim, input_shape = (self.T, self.latent_dim), activation = 'tanh', return_sequences = True))
            for layer in range(self.num_layers):
                model.add(tf.keras.layers.LSTM(self.hidden_dim, activation = 'tanh', return_sequences = True))
        elif self.module == 'gru':
            model.add(tf.keras.layers.GRU(self.hidden_dim, input_shape = (self.T, self.latent_dim), activation = 'tanh', return_sequences = True))
            for layer in range(self.num_layers):
                model.add(tf.keras.layers.GRU(self.hidden_dim, activation = 'tanh', return_sequences = True))
        model.add(TimeDistributed(tf.keras.layers.Dense(self.dim, activation = 'sigmoid')))
        return model
    def SupervisorNet(self):
        '''
        map from latent space (HxT)to latent space: Generate next sequence based on previous
        '''
        model = tf.keras.Sequential(name = 'SupervisorNet')
        if self.module == 'lstm':
            model.add(tf.keras.layers.LSTM(self.hidden_dim, input_shape = (self.T, self.latent_dim), activation = 'tanh', return_sequences = True))
            for layer in range(self.num_layers):
                model.add(tf.keras.layers.LSTM(self.hidden_dim, activation = 'tanh', return_sequences = True))
        elif self.module == 'gru':
            model.add(tf.keras.layers.GRU(self.hidden_dim, input_shape = (self.T, self.latent_dim), activation = 'tanh', return_sequences = True))
            for layer in range(self.num_layers):
                model.add(tf.keras.layers.GRU(self.hidden_dim, activation = 'tanh', return_sequences = True))
        model.add(TimeDistributed(tf.keras.layers.Dense(self.latent_dim, activation = 'sigmoid')))
        return model
    def GeneratorNet(self):
        '''
        Map from d dimensional Brownian motion (W(omega)xT) to latent space
        '''
        model = tf.keras.Sequential(name = 'GeneratorNet')
        if self.module == 'lstm':
            model.add(tf.keras.layers.LSTM(self.hidden_dim, input_shape = (self.T, self.dim), activation = 'tanh', return_sequences = True))
            for layer in range(self.num_layers):
                model.add(tf.keras.layers.LSTM(self.hidden_dim, activation = 'tanh', return_sequences = True))
        elif self.module == 'gru':
            model.add(tf.keras.layers.GRU(self.hidden_dim, input_shape = (self.T, self.dim), activation = 'tanh', return_sequences = True))
            for layer in range(self.num_layers):
                model.add(tf.keras.layers.GRU(self.hidden_dim, activation = 'tanh', return_sequences = True))
        model.add(TimeDistributed(tf.keras.layers.Dense(self.latent_dim, activation = 'sigmoid')))
        return model
    def DiscriminatorNet(self):
        '''
        Map from latent space (HxT) representation to [0,1] classification

        '''
        model = tf.keras.Sequential(name = 'DiscriminatorNet')
        if self.module == 'lstm':
            model.add(tf.keras.layers.LSTM(self.hidden_dim, input_shape = (self.T, self.latent_dim), activation = 'tanh', return_sequences = True))
            for layer in range(self.num_layers):
                model.add(tf.keras.layers.LSTM(self.hidden_dim, activation = 'tanh', return_sequences = True))
        elif self.module == 'gru':
            model.add(tf.keras.layers.GRU(self.hidden_dim, input_shape = (self.T, self.latent_dim), activation = 'tanh', return_sequences = True))
            for layer in range(self.num_layers):
                model.add(tf.keras.layers.GRU(self.hidden_dim, activation = 'tanh', return_sequences = True))
        model.add(TimeDistributed(tf.keras.layers.Dense(self.latent_dim, activation = 'linear')))
        return model
    def DeepHedgeNet(self):
        inp = tf.keras.layers.Input(shape = (self.seq_len, self.dim))
        if self.module == 'lstm':
            X = tf.keras.layers.LSTM(self.dh_neurons, return_sequences = False)(inp)
            X = tf.keras.layers.BatchNormalization()(X)
            T1 = tf.keras.layers.RepeatVector(self.maturities[0]-1)(X)
            T2 = tf.keras.layers.RepeatVector(self.maturities[1]-1)(X)
            T3 = tf.keras.layers.RepeatVector(self.maturities[2]-1)(X)
            T1 = tf.keras.layers.LSTM(self.dh_neurons, activation = 'elu', return_sequences = True)(T1)
            T2 = tf.keras.layers.LSTM(self.dh_neurons, activation = 'elu', return_sequences = True)(T2)
            T3 = tf.keras.layers.LSTM(self.dh_neurons, activation = 'elu', return_sequences = True)(T3)
        elif self.module == 'gru':
            X = tf.keras.layers.GRU(self.dh_neurons, return_sequences = False)(inp)
            X = tf.keras.layers.BatchNormalization()(X)
            T1 = tf.keras.layers.RepeatVector(self.maturities[0]-1)(X)
            T2 = tf.keras.layers.RepeatVector(self.maturities[1]-1)(X)
            T3 = tf.keras.layers.RepeatVector(self.maturities[2]-1)(X)
            T1 = tf.keras.layers.GRU(self.dh_neurons, activation = 'elu', return_sequences = True)(T1)
            T2 = tf.keras.layers.GRU(self.dh_neurons, activation = 'elu', return_sequences = True)(T2)
            T3 = tf.keras.layers.GRU(self.dh_neurons, activation = 'elu', return_sequences = True)(T3)
        T1 = tf.keras.layers.TimeDistributed(tf.keras.layers.Dense(self.dh_features * len(self.strikes), activation = 'linear'))(T1)
        T2 = tf.keras.layers.TimeDistributed(tf.keras.layers.Dense(self.dh_features * len(self.strikes), activation = 'linear'))(T2)
        T3 = tf.keras.layers.TimeDistributed(tf.keras.layers.Dense(self.dh_features * len(self.strikes), activation = 'linear'))(T3)
        model = tf.keras.Model(inputs = inp, outputs = [T1, T2, T3], name = 'DeepHedgeNet')
        return model
    @tf.function
    def EmbedderNetLosst0(self, X, X_tilde):
        E_loss_t0 = tf.compat.v1.losses.mean_squared_error(X, X_tilde)
        return E_loss_t0
    @tf.function
    def EmbedderNetLoss(self, X, X_tilde, G_loss_S):
        E_loss_t0 = self.EmbedderNetLosst0(X, X_tilde)
        E_loss_0 = 10*tf.sqrt(E_loss_t0)
        E_loss = E_loss0 + 0.1 * G_loss_S
        return E_loss_t0, E_loss_0, E_loss
    def RecoveryNetLoss(self):
        pass
    def SupervisorNetLoss(self):
        pass
    @tf.function
    def GeneratorNetLoss(self, y_fake, y_fake_e, H, H_hat_supervise, X_hat, X, gamma = 1):
        G_loss_U = tf.compat.v1.losses.sigmoid_cross_entropy(tf.ones_like(y_fake), y_fake)
        G_loss_U_e = tf.compat.v1.losses.sigmoid_cross_entropy(tf.ones_like(y_fake_e), y_fake_e)
        G_loss_S = self.GeneratorNet_SupervisedLoss(H, H_hat_supervise)
        G_loss_V1 = tf.reduce_mean(tf.abs(tf.sqrt(tf.nn.moments(X_hat,[0])[1] + 1e-6) - tf.sqrt(tf.nn.moments(X,[0])[1] + 1e-6)))
        G_loss_V2 = tf.reduce_mean(tf.abs((tf.nn.moments(X_hat,[0])[0]) - (tf.nn.moments(X,[0])[0])))
        G_loss_V = G_loss_V1 + G_loss_V2
        G_loss = G_loss_U + gamma * G_loss_U_e + 100 * tf.sqrt(G_loss_S) + 100 * G_loss_V
        return G_loss_U, G_loss_U_e, G_loss_S, G_loss_V1, G_loss_V2, G_loss_V, G_loss
    @tf.function
    def GeneratorNet_SupervisedLoss(self, H, H_hat_supervise):
        G_loss_S = tf.compat.v1.losses.mean_squared_error(H[:, 1:, :], H_hat_supervise[:, :-1, :])
        return G_loss_S
    @tf.function
    def DiscriminatorNetLoss(self, y_real,y_fake, y_fake_e, gamma = 1):
        D_loss_real = tf.compat.v1.losses.sigmoid_cross_entropy(tf.ones_like(y_real), y_real)
        D_loss_fake = tf.compat.v1.losses.sigmoid_cross_entropy(tf.zeros_like(y_fake), y_real)
        D_loss_fake_e = tf.compat.v1.losses.sigmoid_cross_entropy(tf.zeros_like(y_fake_e), y_fake_e)
        D_loss = D_loss_real + D_loss_fake + gamma * D_loss_fake_e
        return D_loss_real, D_loss_fake, D_loss_fake_e, D_loss
    @tf.function
    def ReplicationPortfolio(self, X, H):
        dX = X[:, 1:, :self.dh_features] - X[:, :-1, :self.dh_features]
        discrete_integral = tf.reduce_sum(tf.multiply(H, dX), axis = 1)
        trading_strategy = tf.reduce_sum(discrete_integral, axis = 1)
        return trading_strategy
    @tf.function
    def TransactionCosts(self, epsilon, X, H):
        X = X[:, :, :self.dh_features]
        zeros = tf.zeros(shape = (H.shape[0], 1, H.shape[2]))
        H = tf.concat([zeros, H, zeros], axis = 1)
        dH = H[:,1:,:]- H[:,:-1, :]
        dH = tf.abs(dH)
        transaction_costs = tf.multiply(tf.reduce_sum(tf.reduce_sum(tf.multiply(X, dH), axis = 1), axis = 1), epsilon)
        return transaction_costs
    @tf.function
    def DeepHedgeNetLoss1(self, y, trading_strategy, transaction_costs):
        loss,_ =tf.math.top_k(-(-tf.squeeze(y) + trading_strategy - transaction_costs), tf.cast(self.alpha * self.batch_size, tf.int32))
        loss = tf.reduce_mean(tf.abs(loss))
        return loss
    @tf.function
    def DeepHedgeNetLoss2(self, y, trading_strategy, transaction_costs):
        loss,_ =tf.math.top_k(-(-tf.squeeze(y) + trading_strategy - transaction_costs), tf.cast(self.alpha * self.batch_size, tf.int32))
        loss = tf.reduce_mean(loss)
        return loss
    @tf.function
    def DHTermStructureLoss(self, H, X, loss_type = 'type2'):
        L1, L2, L3 = [], [], []
        P01, P02, P03 = [], [], []
        H1 = H[0]
        H2 = H[1]
        H3 = H[2]
        strikes = self.price_array[:,0]
        HlistT1 = tf.split(H[0], len(self.strikes), axis = 2)
        HlistT2 = tf.split(H[1], len(self.strikes), axis = 2)
        HlistT3 = tf.split(H[2], len(self.strikes), axis = 2)
        HKT1 = zip(HlistT1, strikes)
        HKT2 = zip(HlistT2, strikes)
        HKT3 = zip(HlistT3, strikes)
        X1 = X[:,:self.maturities[0], :]
        X2 = X[:,:self.maturities[1], :]
        X3 = X[:,:self.maturities[2], :]
        for (H1, K1),(H2, K2),(H3, K3) in zip(HKT1, HKT2, HKT3):
            strategy1 = self.ReplicationPortfolio(X1, H1)
            cost1 = self.TransactionCosts(self.epsilon, X1, H1)
            Y1 = tf.math.maximum(X1[:,-1:, 0] - K1, 0)
            loss1 = self.DeepHedgeNetLoss1(Y1, strategy1, cost1)
            p01 = strategy1 - cost1
            P01.append(p01[0, 0])
            L1.append(loss1)

            strategy2 = self.ReplicationPortfolio(X2, H2)
            cost2 = self.TransactionCosts(self.epsilon, X2, H2)
            Y2 = tf.math.maximum(X2[:,-1:, 0] - K2, 0)
            loss2 = self.DeepHedgeNetLoss1(Y2, strategy2, cost2)
            p02 = strategy2 - cost2
            P02.append(p02[0, 0])
            L2.append(loss2)

            strategy3 = self.ReplicationPortfolio(X3, H3)
            cost3 = self.TransactionCosts(self.epsilon, X3, H3)
            Y3 = tf.math.maximum(X3[:,-1:, 0] - K3, 0)
            loss3 = self.DeepHedgeNetLoss1(Y3, strategy3, cost3)
            p03 = strategy3 - cost3
            P03.append(p03[0, 0])
            L3.append(loss3)
        P01 = tf.convert_to_tensor(P01, dtype = tf.float32)
        P02 = tf.convert_to_tensor(P02, dtype = tf.float32)
        P03 = tf.convert_to_tensor(P03, dtype = tf.float32)
        L1 = tf.convert_to_tensor(L1, dtype = tf.float32)
        L2 = tf.convert_to_tensor(L2, dtype = tf.float32)
        L3 = tf.convert_to_tensor(L3, dtype = tf.float32)
        market_prices = tf.cast(self.price_array[:, 2], dtype = tf.float32)
        if loss_type == 'type1':
            replication_prices = tf.concat([P01, P02, P03], axis = 0)
            replication_loss = tf.keras.losses.mse(replication_prices, market_prices)
            price_error = None
        elif loss_type == 'type2':
            replication_prices = tf.concat([L1, L2, L3], axis = 0)
            replication_loss = tf.keras.losses.mse(replication_prices, market_prices)
            price_error = None
        elif loss_type == 'type3':
            losses = tf.concat([L1, L2, L3], axis = 0)
            replication_loss = tf.reduce_mean(tf.square(losses))
            replication_prices = tf.concat([P01, P02, P03], axis = 0)
            price_error = tf.keras.losses.mse(replication_prices, market_prices)
        else:
            raise NotImplementedError
        return replication_loss, replication_prices, price_error
    @tf.function
    def Embedder_train_step(self, X):
        with tf.GradientTape() as tape:
            H = self.Embedder(X, training = True)
            X_tilde = self.Recovery(H, training = True)
            loss = self.EmbedderNetLosst0(X, X_tilde)
        grads = tape.gradient(loss, self.Embedder.trainable_variables + self.Recovery.trainable_variables)
        self.Embedder_optimizer.apply_gradients(zip(grads, self.Embedder.trainable_variables + self.Recovery.trainable_variables))
        return loss
    @tf.function
    def Supervised_Generator_train_step(self, X, W):
        with tf.GradientTape() as tape:
            E_hat = self.Generator(W)
            H = self.Embedder(X)
            H_hat_supervise = self.Supervisor(H)
            loss = self.GeneratorNet_SupervisedLoss(H, H_hat_supervise)
        grads = tape.gradient(loss, self.Supervisor.trainable_variables + self.Generator.trainable_variables)
        self.Supervisor_optimizer.apply_gradients(zip(grads, self.Supervisor.trainable_variables + self.Generator.trainable_variables))
        return loss
    @tf.function
    def Unsupervised_Generator_train_step(self, X1, W1):
        with tf.GradientTape(persistent = True) as tape:
            H = self.Embedder(X1)
            E_hat = self.Generator(W1, training = True)
            H_hat_supervise = self.Supervisor(H)
            H_hat = self.Supervisor(E_hat)
            X_hat = self.Recovery(H_hat)
            y_fake = self.Discriminator(H_hat)
            y_fake_e = self.Discriminator(E_hat)
            G_loss_U, _, G_loss_S, _, _, G_loss_V,G_loss = self.GeneratorNetLoss(y_fake, y_fake_e, H, H_hat_supervise, X_hat, X1)
            # Embedder training
            X_tilde = self.Recovery(H, training = True)
            embedder_loss = self.EmbedderNetLosst0(X1, X_tilde)
        generator_grads = tape.gradient(G_loss, self.Generator.trainable_variables + self.Supervisor.trainable_variables)
        self.Generator_optimizer.apply_gradients(zip(generator_grads, self.Generator.trainable_variables + self.Supervisor.trainable_variables))
        embedder_grads = tape.gradient(embedder_loss, self.Embedder.trainable_variables + self.Recovery.trainable_variables)
        self.Embedder_optimizer.apply_gradients(zip(embedder_grads, self.Embedder.trainable_variables + self.Recovery.trainable_variables))
        return G_loss_U, G_loss_S, G_loss_V, G_loss, embedder_loss
    @tf.function
    def Discriminator_train_step(self, X2, W2):
        with tf.GradientTape() as tape:
            H2 = self.Embedder(X2)
            E_hat2 = self.Generator(W2)
            H_hat2 = self.Supervisor(E_hat2)
            y_fake2 = self.Discriminator(H_hat2)
            y_real2 = self.Discriminator(H2)
            y_fake_e2 = self.Discriminator(E_hat2)
            _,_,_, discriminator_loss = self.DiscriminatorNetLoss(y_fake2, y_real2, y_fake_e2)
        if (discriminator_loss > 0.15):
            discriminator_grads = tape.gradient(discriminator_loss, self.Discriminator.trainable_variables)
            self.Discriminator_optimizer.apply_gradients(zip(discriminator_grads, self.Discriminator.trainable_variables))
        return discriminator_loss
    @tf.function
    def DH_train_step(self, W):
        with tf.GradientTape()  as tape:
            E_hat = self.Generator(W, training = True)
            H_hat = self.Supervisor(E_hat, training = True)
            X_hat = self.Recovery(H_hat, training = True)
            X_renorm = self.Renormalize_tf(X_hat)
            hedge_weights = self.dhmodel(X_renorm, training = True)
            termstructure_replication_loss,replication_prices, price_error  = self.DHTermStructureLoss(hedge_weights, X_renorm, loss_type = 'type3')
        dh_grads = tape.gradient(termstructure_replication_loss, self.dhmodel.trainable_variables)
        self.dhmodel_optimizer.apply_gradients(zip(dh_grads, self.dhmodel.trainable_variables))
        return termstructure_replication_loss, replication_prices, price_error
    @tf.function
    def DHGAN_train_step(self,X, W):
        with tf.GradientTape(persistent = True)  as tape:
            H = self.Embedder(X, training = True)
            E_hat = self.Generator(W, training = True)
            H_hat_supervise = self.Supervisor(H, training = True)
            H_hat = self.Supervisor(E_hat, training = True)
            X_hat = self.Recovery(H_hat, training = True)
            y_fake = self.Discriminator(H_hat, training = True)
            y_fake_e = self.Discriminator(E_hat, training = True)
            G_loss_U, _, G_loss_S, _, _, G_loss_V,G_loss = self.GeneratorNetLoss(y_fake, y_fake_e, H, H_hat_supervise, X_hat, X)
            X_tilde = self.Recovery(H, training = True)
            embedder_loss = self.EmbedderNetLosst0(X, X_tilde)
            X_renorm = self.Renormalize_tf(X_hat)
            # X_renorm = X_renorm[:,:,:self.dh_features]
            hedge_weights = self.dhmodel(X_renorm, training = True)
            termstructure_replication_loss,replication_prices ,price_error  = self.DHTermStructureLoss(hedge_weights, X_renorm, loss_type = 'type3')
        generator_grads = tape.gradient(G_loss, self.Generator.trainable_variables + self.Supervisor.trainable_variables)
        self.Generator_optimizer.apply_gradients(zip(generator_grads, self.Generator.trainable_variables + self.Supervisor.trainable_variables))
        embedder_grads = tape.gradient(embedder_loss, self.Embedder.trainable_variables + self.Recovery.trainable_variables)
        self.Embedder_optimizer.apply_gradients(zip(embedder_grads, self.Embedder.trainable_variables + self.Recovery.trainable_variables))
        dhvars = self.Generator.trainable_variables + self.Supervisor.trainable_variables + self.Recovery.trainable_variables + self.dhmodel.trainable_variables
        dh_grads = tape.gradient(termstructure_replication_loss,dhvars)
        self.dhmodel_optimizer.apply_gradients(zip(dh_grads, dhvars))
        return termstructure_replication_loss, replication_prices,price_error ,G_loss, embedder_loss

    def train(self, model_names = None, save = False):
        save_dir = 'model_saves/DHGAN'
        print('Initiating EmbedderNet Pre-training')
        for iteration in range(self.iterations):
            X_batch = self.sample_batch(self.norm_data)
            _embedder_loss = self.Embedder_train_step(X_batch)
            if iteration % 1000 == 0:
                print('Batch training (embedder) loss at iteration %d: %.4f'% (iteration, float(np.sqrt(_embedder_loss))))
                print('---------------------------------------------------------------')
        print('EmbedderNet Pre-training Complete')
        print('Initiating Generator Pre-training (Supervised Loss Only)')
        for iteration in range(self.iterations):
            X_batch = self.sample_batch(self.norm_data)
            W_batch = self.BrownianMotion(X_batch.shape[0],X_batch.shape[1], X_batch.shape[2])
            _generator_loss = self.Supervised_Generator_train_step(X_batch, W_batch)
            if iteration % 1000 == 0:
                print('Batch training supervised (generator) loss at iteration %d: %.4f'% (iteration, float(np.sqrt(_generator_loss))))
                print('---------------------------------------------------------------')
        print('GeneratorNet Pre-training Complete')
        print('Initiating Joint GAN Pre-Training')
        for iteration in range(self.iterations):
            for kk in range(2):
                X1 = self.sample_batch(self.norm_data)
                W1 = self.BrownianMotion(X1.shape[0], X1.shape[1], X1.shape[2])
                G_loss_U, G_loss_S, G_loss_V, generator_loss, embedder_loss = self.Unsupervised_Generator_train_step(X1, W1)
            X2 = self.sample_batch(self.norm_data)
            W2 = self.BrownianMotion(X2.shape[0], X2.shape[1], X2.shape[2])
            discriminator_loss = self.Discriminator_train_step(X2, W2)
            if iteration % 1000 == 0:
                print('---------------------------------------------------------------')
                print('Batch training discriminator loss at iteration %d: %.4f'% (iteration, float(discriminator_loss)))
                print('Batch training generator loss at iteration %d: %.4f'% (iteration, float(generator_loss)))
                print('Batch training unsupervised loss at iteration %d: %.4f'% (iteration, float(G_loss_U)))
                print('Batch training supervised loss at iteration %d: %.4f'% (iteration, float(np.sqrt(G_loss_S))))
                print('Batch training embedder loss at iteration %d: %.4f'% (iteration, float(np.sqrt(embedder_loss))))
                print('---------------------------------------------------------------')
        if save:
            model_dirs = [save_dir + '/{}'.format(model_name) for model_name in model_names]
            # print('Saving model to directory: {}'.format(model_name) for model name in model_names)
            self.Generator.save(model_dirs[0])
            self.Supervisor.save(model_dirs[1])
            self.Recovery.save(model_dirs[2])
        print('Joint GAN Pre-Training Complete')
        print('Initiating Deep Hedge Pre-Training')
        for iteration in range(self.iterations):
            W = self.BrownianMotion(self.batch_size, self.seq_len, self.W_dim)
            termstructure_replication_loss, replication_prices, price_error = self.DH_train_step(W)
            if iteration % 1000 == 0:
                print('---------------------------------------------------------------')
                print('Batch training termstructure replication loss at iteration %d: %.4f'% (iteration, float(termstructure_replication_loss)))
                print('Batch training pricing error at iteration %d: %.4f'% (iteration, float(price_error)))
                print('Batch training termstructure replication prices: {}'.format(replication_prices))
                print('---------------------------------------------------------------')
        if save:
            model_dirs = [save_dir + '/{}'.format(model_name) for model_name in model_names]
            self.dhmodel.save(model_dirs[3])
        print('Deep Hedge Pre-Training Complete')
        print('Initiating Joint DHGAN training')
        for iteration in range(self.iterations):
            for kk in range(2):
                X1 = self.sample_batch(self.norm_data)
                W1 = self.BrownianMotion(X1.shape[0], X1.shape[1], X1.shape[2])
                termstructure_replication_loss, replication_prices, price_error, generator_loss, embedder_loss = self.DHGAN_train_step(X1, W1)
            X2 = self.sample_batch(self.norm_data)
            W2 = self.BrownianMotion(X2.shape[0], X2.shape[1], X2.shape[2])
            discriminator_loss = self.Discriminator_train_step(X2, W2)
            if iteration % 1000 == 0:
                print('---------------------------------------------------------------')
                print('Batch training discriminator loss at iteration %d: %.4f'% (iteration, float(discriminator_loss)))
                print('Batch training generator loss at iteration %d: %.4f'% (iteration, float(generator_loss)))
                print('Batch training embedder loss at iteration %d: %.4f'% (iteration, float(np.sqrt(embedder_loss))))
                print('Batch training termstructure replication loss at iteration %d: %.4f'% (iteration, float(termstructure_replication_loss)))
                print('Batch training pricing error at iteration %d: %.4f'% (iteration, float(price_error)))
                print('Batch training termstructure replication prices: {}'.format(replication_prices))
                market_prices = tf.cast(self.price_array[:, 2], dtype = tf.float32)
                print('Actual Prices: {}'.format(market_prices))
                print('---------------------------------------------------------------')
        if save:
            model_dirs = [save_dir + '/{}'.format(model_name) for model_name in model_names]
            # print('Saving model to directory: {}'.format(model_name) for model name in model_names)
            self.Generator.save(model_dirs[0])
            self.Supervisor.save(model_dirs[1])
            self.Recovery.save(model_dirs[2])
            self.dhmodel.save(model_dirs[3])

    def sample_batch(self, data):
        idx = np.random.randint(low = 0, high = data.shape[0], size = self.batch_size)
        dta = data[idx, :, :]
        dta = tf.cast(dta, tf.float32)
        return dta
    def generate_data(self, W, generator, supervisor, recovery):
        E = generator(W, training = False)
        H = supervisor(E, training = False)
        X = recovery(H, training = False)
        return X
    def Renormalize(self, X):
        X = X * (self.max_val + 1e-7)
        X = X + self.min_val
        X = np.exp(X)
        X = X * np.asarray(self.starting_values)
        return X
    @tf.function
    def Renormalize_tf(self, X):
        max_val = tf.cast(self.max_val + 1e-7, tf.float32)
        min_val = tf.cast(self.min_val, tf.float32)
        X = X * max_val
        X = X + min_val
        X = tf.math.exp(X)
        X = X * tf.convert_to_tensor(np.asarray(self.starting_values), dtype = tf.float32)
        return X
    def Simulate_Hedge(self, W, generator, supervisor, recovery, dhmodel):
        X = self.generate_data(W, generator, supervisor, recovery)
        X = self.Renormalize(X)
        H = dhmodel(X)
        return X, H
    def Hedge_on_data(self, data):
        pass
    def Simulate_Data(self, W, generator, supervisor, recovery):
        X = self.generate_data(W, generator, supervisor, recovery)
        X = self.Renormalize(X)
        return X
    def restore_model(self, model_name):
        save_dir = 'model_saves/DHGAN'
        model = tf.keras.models.load_model(save_dir + '/{}'.format(model_name))
        return model
    def RestoreGAN(self, model_names):
        save_dir = 'model_saves/DHGAN'
        models = [tf.keras.models.load_model(save_dir + '/{}'.format(model_name)) for model_name in model_names]
        return models[0], models[1], models[2]
    def RestoreDHGAN(self, model_names):
        save_dir = 'model_saves/DHGAN'
        models = [tf.keras.models.load_model(save_dir + '/{}'.format(model_name)) for model_name in model_names]
        return models[0], models[1], models[2], models[3]
if __name__ == '__main__':
    print(device_lib.list_local_devices())
    print('Default GPU Device: {}'.format(tf.test.gpu_device_name()))
    symbol_list = ['^GSPC', '^VIX', '^NDX', '^RUT', '^DJI',
                '^FVX','^TNX', '^TYX', 'EURUSD=X','JPY=X']
    settings = {'module':'lstm',
                'hidden_dim':24,
                'latent_dim': 5,
                'num_layers': 3,
                'iterations': 30000,
                'batch_size': 100,
                'learning_rate':0.001}
    DH_settings = {'hedge_simulations': 1000000,
                    'hedge_features': 2,
                    'hedge_epochs': 2,
                    'hedge_batch_size': 1000,
                    'hedge_neurons': 70,
                    'hedge_learning_rate': 0.00001,
                    'hedge_validation_proportion':0.1,
                    'hedge_test_proportion':0.001,
                    'alpha':0.99,
                    'epsilon':0.0,
                    'strike':3200}
    datafolder_path = 'datafolder'
    filename = 'quotedata_SPX.csv'
    filepath = datafolder_path + '/' + filename
    option_data = pd.read_csv(filepath, sep = ';')
    calendar = ql.UnitedStates()
    Ks = [3000, 3100, 3200, 3300, 3400]
    ttms = [10, 21, 31]
    option_settings = {'start': datetime.date(2020,9,11),
                'day_count': ql.Actual365Fixed(),
                'calendar': ql.UnitedStates(),
                'strikes': Ks,
                'maturities':ttms}
    Model = DHGAN(symbol_list,settings, DH_settings, option_data ,option_settings)

    model_names = ['Generator', 'Supervisor', 'Recovery', 'dhmodel']
    Model.train(model_names, save = True)
    gen, sup, rec, dh = Model.RestoreDHGAN(model_names)
    W = Model.BrownianMotion(100, 31, 10)
    X, H = Model.Simulate_Hedge(W, gen, sup, rec, dh)
    print(X)
    print('aldkfjalskjfd')
    print(H)
    for i in range(15):
        plt.plot(X[i, :,0])
    plt.show()
    # Model.test(Model.Generator_data)


from flask import Flask
from graphene import ObjectType, String, Schema
from flask_graphql import GraphQLView

class Query(ObjectType):
    hello = String(description='Hello')
    def resolve_hello(self, args, info):
        return 'World'

app = Flask(__name__)
app.debug = True
app.add_url_rule('/', view_func=GraphQLView.as_view('graphql', schema=Schema(query=Query)))

if __name__ == '__main__':
    app.run()


from PIL import Image
import matplotlib.pyplot as plt
import torch
import torchvision.transforms as T
from settings import DEVICE, SIZE

# Image Transforms
loader = T.Compose([
  T.Resize(SIZE),
  T.CenterCrop(SIZE),
  T.ToTensor()
])

unloader = T.ToPILImage()

def load_image(path):
	image = loader(Image.open(path)).unsqueeze(0)
	return image.to(DEVICE, torch.float)

def save_image(tensor, path):
	image = unloader(tensor.cpu().clone().squeeze(0))
	image.save(path)


#Import relevant modules
import socket
import os
import sys
import htchirp
import csv
import time
import numpy as np
from pycbc.psd import aLIGOZeroDetHighPower
from pycbc.filter import match, sigmasq
from scipy.interpolate import griddata
from pycbc.waveform import get_td_waveform_from_fd
from pycbc.conversions import f_schwarzchild_isco, mass1_from_mchirp_eta, mass2_from_mchirp_eta, eta_from_q, lambda_tilde
from scipy.stats import loguniform
import matplotlib.pyplot as plt

#Renaming the execute scratch directory to point to .chirp_config file
os.environ['_CONDOR_SCRATCH_DIR']='/srv'
home_dir = os.environ['_CONDOR_SCRATCH_DIR']
chirp = htchirp.HTChirp()
cluster_process = os.environ['cluster_process_var']

f_low=15.0
delta_f=1/pow(2,5)

mchirp_lower=0.15
mchirp_upper=1.0

td1= loguniform.rvs(10, 8e6, size=10000)
td2= loguniform.rvs(10, 8e6, size=10000)
chirpmass=np.random.uniform(mchirp_lower,mchirp_upper,size=10000)
match_array=[]
eta=eta_from_q(1.0)
for i in range (0,10000):
    mass1=mass1_from_mchirp_eta(chirpmass[i],eta)
    mass2=mass2_from_mchirp_eta(chirpmass[i],eta)
    lmd_tilde=lambda_tilde(mass1,mass2,td1[i],td2[i])
    f_isco=f_schwarzchild_isco(mass1+mass2)
    hp, hc = get_td_waveform_from_fd(approximant = "TaylorF2",
                             mass1 = mass1,
                             mass2 = mass2,
                             f_lower=f_low,
                             f_final=f_isco,
                             delta_f=delta_f,
                             delta_t=1.0/(8192),
                             lambda1 = td1[i],
                             lambda2 = td2[i])
    delta_f=hp.delta_f
    psd = aLIGOZeroDetHighPower(len(hp), delta_f, f_low)
    #Normalization
    hp_norm = sigmasq(hp, psd = psd, low_frequency_cutoff = f_low,high_frequency_cutoff=f_isco)
    #BBH waveform
    sp, sc = get_td_waveform_from_fd(approximant = "TaylorF2",
                             mass1 = mass1,
                             mass2 = mass2,
                             f_lower=f_low,
                             f_final=f_isco,
                             delta_t=1.0/(8192),
                             delta_f=delta_f)
    #Normalization
    sp_norm = sigmasq(sp, psd = psd, low_frequency_cutoff = f_low,high_frequency_cutoff=f_isco)
    #Resizing the waveforms such that they are the same size
    wavelength = max(len(hp),len(sp))
    hp.resize(wavelength)
    sp.resize(wavelength)
    #Calculating the match between injection (hp) and template (sp)
    m, k = match(hp, sp, psd = psd,v1_norm = hp_norm, v2_norm =sp_norm,low_frequency_cutoff =
                 f_low)
    match_array.append(m)
    output_data = str(chirpmass[i])+' '+str(lmd_tilde)+' '+str(m)
    for a in range(5):

            try:

                chirp.connect()
                chirp.write(("{}\n".format(output_data)).encode(),'./overlap_data/overlap_mass_lmd_{}.txt'.format(cluster_process),'cwa')
                chirp.disconnect

                break

            except socket.timeout:

                time.sleep(5.)